forked from DataDog/datadog-serverless-functions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
163 lines (146 loc) · 4.95 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2019 Datadog, Inc.
var tls = require('tls');
const VERSION = '0.1.2';
const STRING = 'string'; // example: 'some message'
const STRING_ARRAY = 'string-array'; // example: ['one message', 'two message', ...]
const JSON_OBJECT = 'json-object'; // example: {"key": "value"}
const JSON_RECORDS = 'json-records'; // example: [{"records": [{}, {}, ...]}, {"records": [{}, {}, ...]}, ...]
const JSON_ARRAY = 'json-array'; // example: [{"key": "value"}, {"key": "value"}, ...]
const INVALID = 'invalid';
const DD_API_KEY = process.env.DD_API_KEY || '<DATADOG_API_KEY>';
const DD_SITE = process.env.DD_SITE || 'datadoghq.com';
const DD_URL = process.env.DD_URL || 'functions-intake.logs.' + DD_SITE;
const DD_PORT = process.env.DD_PORT || (DD_SITE === 'datadoghq.eu') ? 443 : 10516
const DD_TAGS = process.env.DD_TAGS || ''; // Replace '' by your comma-separated list of tags
const DD_SERVICE = process.env.DD_SERVICE || 'azure';
const DD_SOURCE = process.env.DD_SOURCE || 'azure';
const DD_SOURCE_CATEGORY = process.env.DD_SOURCE_CATEGORY || 'azure';
module.exports = function(context, blobContent) {
if (!DD_API_KEY || DD_API_KEY === '<DATADOG_API_KEY>') {
context.log.error(
'You must configure your API key before starting this function (see ## Parameters section)'
);
return;
}
var socket = getSocket(context);
var sender = tagger => record => {
record = tagger(record, context);
if (!send(socket, record)) {
// Retry once
socket = getSocket(context);
send(socket, record);
}
};
var logs;
if (typeof blobContent === 'string') {
logs = blobContent.trim().split('\n');
} else {
logs = JSON.stringify(blobContent).trim().split('\n');
}
logs.forEach(log => {
handleLogs(sender, log, context);
});
socket.end();
context.done();
};
function getSocket(context) {
var socket = tls.connect({ port: DD_PORT, host: DD_URL });
socket.on('error', err => {
context.log.error(err.toString());
socket.end();
});
return socket;
}
function send(socket, record) {
return socket.write(DD_API_KEY + ' ' + JSON.stringify(record) + '\n');
}
function handleLogs(sender, logs, context) {
var logsType = getLogFormat(logs);
switch (logsType) {
case STRING:
sender(addTagsToStringLog)(logs);
break;
case JSON_OBJECT:
sender(addTagsToJsonLog)(logs);
break;
case STRING_ARRAY:
logs.forEach(sender(addTagsToStringLog));
break;
case JSON_RECORDS:
logs.forEach(message => {
message.records.forEach(sender(addTagsToJsonLog));
});
break;
case JSON_ARRAY:
logs.forEach(sender(addTagsToJsonLog));
break;
case INVALID:
default:
context.log.warn('logs format is invalid');
break;
}
}
function getLogFormat(logs) {
if (typeof logs === 'string') {
return STRING;
}
if (!Array.isArray(logs) && typeof logs === 'object' && logs !== null) {
return JSON_OBJECT;
}
if (!Array.isArray(logs)) {
return INVALID;
}
if (typeof logs[0] === 'object') {
if (logs[0].records !== undefined) {
return JSON_RECORDS;
} else {
return JSON_ARRAY;
}
}
if (typeof logs[0] === 'string') {
return STRING_ARRAY;
}
return INVALID;
}
function addTagsToJsonLog(record, context) {
metadata = extractResourceId(record);
record['ddsource'] = metadata.source || DD_SOURCE;
record['ddsourcecategory'] = DD_SOURCE_CATEGORY;
record['service'] = DD_SERVICE;
record['ddtags'] = metadata.tags
.concat([
DD_TAGS,
'forwardername:' + context.executionContext.functionName
])
.filter(Boolean)
.join(',');
return record;
}
function addTagsToStringLog(stringLog, context) {
jsonLog = { message: stringLog };
return addTagsToJsonLog(jsonLog, context);
}
function extractResourceId(record) {
metadata = { tags: [], source: '' };
if (
record.resourceId === undefined ||
typeof record.resourceId !== 'string' ||
!record.resourceId.toLowerCase().startsWith('/subscriptions/')
) {
return metadata;
}
var resourceId = record.resourceId.toLowerCase().split('/');
if (resourceId.length > 2) {
metadata.tags.push('subscription_id:' + resourceId[2]);
}
if (resourceId.length > 4) {
metadata.tags.push('resource_group:' + resourceId[4]);
}
if (resourceId.length > 6 && resourceId[6]) {
metadata.source = resourceId[6].replace('microsoft.', 'azure.');
}
return metadata;
}