|
2 | 2 | // Remember to change the hostname and path to match your collection API and specific HTTP-source endpoint |
3 | 3 | // See more at: https://help.sumologic.com/APIs/01Collector_Management_API |
4 | 4 | /////////////////////////////////////////////////////////////////////////////////////////////////////////// |
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(.*)/; |
6 | 10 |
|
7 | 11 | var https = require('https'); |
8 | 12 | var zlib = require('zlib'); |
9 | 13 | var url = require('url'); |
10 | 14 |
|
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; |
18 | 54 |
|
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 | + }; |
20 | 60 |
|
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 | + } |
23 | 96 |
|
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 | + }); |
80 | 115 | }; |
0 commit comments