Skip to content

Commit ba6efb1

Browse files
authored
Merge pull request #18 from stevezau/refactor
[WIP] - Refactor Lambda
2 parents 5b08095 + f20073a commit ba6efb1

File tree

1 file changed

+102
-67
lines changed

1 file changed

+102
-67
lines changed

cloudwatchlogs/node.js/cloudwatchlogs_lambda.js

Lines changed: 102 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -2,79 +2,114 @@
22
// Remember to change the hostname and path to match your collection API and specific HTTP-source endpoint
33
// See more at: https://help.sumologic.com/APIs/01Collector_Management_API
44
///////////////////////////////////////////////////////////////////////////////////////////////////////////
5-
var sumoEndpoint = 'https://collectors.sumologic.com/receiver/v1/http/<XXX>'
5+
var sumoEndpoint = 'https://collectors.sumologic.com/receiver/v1/http/<XXX>';
6+
7+
// Format used to parse out log formats
8+
// Example: 2016-11-10T23:11:54.523Z 108af3bb-a79b-11e6-8bd7-91c363cc05d9 some message
9+
var consoleFormatRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z\t(\w+?-\w+?-\w+?-\w+?-\w+)\t(.*)/;
610

711
var https = require('https');
812
var zlib = require('zlib');
913
var url = require('url');
1014

11-
exports.handler = function(event, context) {
12-
var urlObject = url.parse(sumoEndpoint);
13-
14-
var options = { 'hostname': urlObject.hostname,
15-
'path': urlObject.pathname,
16-
'method': 'POST'
17-
};
15+
exports.handler = function (event, context) {
16+
var urlObject = url.parse(sumoEndpoint);
17+
18+
var options = {
19+
'hostname': urlObject.hostname,
20+
'path': urlObject.pathname,
21+
'method': 'POST'
22+
};
23+
24+
var zippedInput = new Buffer(event.awslogs.data, 'base64');
25+
26+
zlib.gunzip(zippedInput, function (e, buffer) {
27+
if (e) {
28+
context.fail(e);
29+
}
30+
31+
var awslogsData = JSON.parse(buffer.toString('ascii'));
32+
33+
if (awslogsData.messageType === "CONTROL_MESSAGE") {
34+
console.log("Control message");
35+
context.succeed("Success");
36+
}
37+
38+
var requestsSent = 0;
39+
var requestsFailed = 0;
40+
var finalizeContext = function () {
41+
var tot = requestsSent + requestsFailed;
42+
if (tot == awslogsData.logEvents.length) {
43+
if (requestsFailed > 0) {
44+
context.fail(requestsFailed + " / " + tot + " events failed");
45+
} else {
46+
context.succeed(requestsSent + " requests sent");
47+
}
48+
}
49+
};
50+
51+
// Used to extract RequestID
52+
var requestIdRegex = /(?:RequestId:|Z)\s+([\w\d\-]+)/;
53+
var lastRequestID = null;
1854

19-
var zippedInput = new Buffer(event.awslogs.data, 'base64');
55+
awslogsData.logEvents.forEach(function (val, idx, arr) {
56+
options.headers = {
57+
'X-Sumo-Name': awslogsData.logStream,
58+
'X-Sumo-Host': awslogsData.logGroup
59+
};
2060

21-
zlib.gunzip(zippedInput, function(e, buffer) {
22-
if (e) { context.fail(e); }
61+
var req = https.request(options, function (res) {
62+
var body = '';
63+
console.log('Status:', res.statusCode);
64+
res.setEncoding('utf8');
65+
res.on('data', function (chunk) {
66+
body += chunk;
67+
});
68+
res.on('end', function () {
69+
console.log('Successfully processed HTTPS response');
70+
requestsSent++;
71+
finalizeContext();
72+
});
73+
});
74+
75+
req.on('error', function (e) {
76+
console.log(e.message);
77+
requestsFailed++;
78+
finalizeContext();
79+
});
80+
81+
// Remove trailing \n
82+
val.message = val.message.replace(/\n$/, '');
83+
84+
// Try extract requestID
85+
var requestId = requestIdRegex.exec(val.message);
86+
if (requestId !== null) {
87+
lastRequestID = requestId[1];
88+
}
89+
90+
// Attempt to detect console log and auto extract requestID and message
91+
var consoleLog = consoleFormatRegex.exec(val.message);
92+
if (consoleLog !== null) {
93+
lastRequestID = consoleLog[1];
94+
val.message = consoleLog[2].trim();
95+
}
2396

24-
var awslogsData = JSON.parse(buffer.toString('ascii'));
25-
26-
console.log(awslogsData);
27-
28-
if (awslogsData.messageType === "CONTROL_MESSAGE") {
29-
console.log("Control message");
30-
context.succeed("Success");
31-
}
32-
33-
var requestsSent = 0;
34-
var requestsFailed = 0;
35-
var finalizeContext = function() {
36-
var tot = requestsSent + requestsFailed;
37-
if (tot == awslogsData.logEvents.length) {
38-
if (requestsFailed > 0) {
39-
context.fail(requestsFailed + " / " + tot + " events failed");
40-
} else {
41-
context.succeed(requestsSent + " requests sent");
42-
}
43-
}
44-
};
45-
46-
var re = new RegExp(/(?:RequestId:|Z)\s+([\w\d\-]+)/);
47-
var lastRequestID = null;
48-
awslogsData.logEvents.forEach(function(val, idx, arr) {
49-
var req = https.request(options, function(res) {
50-
var body = '';
51-
console.log('Status:', res.statusCode);
52-
res.setEncoding('utf8');
53-
res.on('data', function(chunk) { body += chunk; });
54-
res.on('end', function() {
55-
console.log('Successfully processed HTTPS response');
56-
requestsSent++;
57-
finalizeContext();
58-
});
59-
});
60-
61-
req.on('error', function(e) {
62-
console.log(e.message)
63-
requestsFailed++;
64-
finalizeContext();
65-
});
66-
67-
var stream=awslogsData.logStream;
68-
var group=awslogsData.logGroup;
69-
var rs = re.exec(val.message);
70-
if (rs!==null) {
71-
lastRequestID = rs[1];
72-
}
73-
val.requestID = lastRequestID;
74-
val.logStream = stream;
75-
val.logGroup = group;
76-
req.end(JSON.stringify(val));
77-
});
78-
79-
});
97+
// Auto detect if message is json
98+
try {
99+
val.message = JSON.parse(val.message);
100+
} catch (err) {
101+
// Do nothing, leave as text
102+
val.message.trim()
103+
}
104+
105+
// delete id as it's not very useful
106+
delete val.id;
107+
108+
val.logStream = awslogsData.logStream;
109+
val.logGroup = awslogsData.logGroup;
110+
val.requestID = lastRequestID;
111+
req.end(JSON.stringify(val));
112+
});
113+
114+
});
80115
};

0 commit comments

Comments
 (0)