Balmer

Untitled

Feb 14th, 2020
869
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. var AWS = require('aws-sdk');
  2. var LineStream = require('byline').LineStream;
  3. var parse = require('elb-log-parser');  // elb-log-parser  https://github.com/toshihirock/node-elb-log-parser
  4. var path = require('path');
  5. var stream = require('stream');
  6. var indexTimestamp = new Date().toISOString().replace(/\-/g, '.').replace(/T.+/, '');
  7.  
  8. /* Globals */
  9. var esDomain = {
  10.     endpoint: 'elastic-search-domain-fs12fdwrdq2ahilw4zbrcocmmy.eu-west-1.es.amazonaws.com',
  11.     region: 'eu-west-1',
  12.     index: 'elblogs-' + indexTimestamp, // adds a timestamp to index. Example: elblogs-2016.03.31
  13.     doctype: 'elb-access-logs'
  14. };
  15. var endpoint =  new AWS.Endpoint(esDomain.endpoint);
  16. var s3 = new AWS.S3();
  17. var totLogLines = 0;    // Total number of log lines in the file
  18. var numDocsAdded = 0;   // Number of log lines added to ES so far
  19.  
  20. /*
  21.  * The AWS credentials are picked up from the environment.
  22.  * They belong to the IAM role assigned to the Lambda function.
  23.  * Since the ES requests are signed using these credentials,
  24.  * make sure to apply a policy that permits ES domain operations
  25.  * to the role.
  26.  */
  27. var creds = new AWS.EnvironmentCredentials('AWS');
  28.  
  29. /*
  30.  * Get the log file from the given S3 bucket and key.  Parse it and add
  31.  * each log record to the ES domain.
  32.  */
  33. function s3LogsToES(bucket, key, context, lineStream, recordStream) {
  34.     // Note: The Lambda function should be configured to filter for .log files
  35.     // (as part of the Event Source "suffix" setting).
  36.  
  37.     var s3Stream = s3.getObject({Bucket: bucket, Key: key}).createReadStream();
  38.  
  39.     // Flow: S3 file stream -> Log Line stream -> Log Record stream -> ES
  40.     s3Stream
  41.       .pipe(lineStream)
  42.       .pipe(recordStream)
  43.       .on('data', function(parsedEntry) {
  44.             postDocumentToES(parsedEntry, context);
  45.       });
  46.  
  47.     s3Stream.on('error', function() {
  48.         console.log(
  49.             'Error getting object "' + key + '" from bucket "' + bucket + '".  ' +
  50.             'Make sure they exist and your bucket is in the same region as this function.');
  51.         context.fail();
  52.     });
  53. }
  54.  
  55. /*
  56.  * Add the given document to the ES domain.
  57.  * If all records are successfully added, indicate success to lambda
  58.  * (using the "context" parameter).
  59.  */
  60. function postDocumentToES(doc, context) {
  61.     var req = new AWS.HttpRequest(endpoint);
  62.  
  63.     req.method = 'POST';
  64.     req.path = path.join('/', esDomain.index, esDomain.doctype);
  65.     req.region = esDomain.region;
  66.     req.body = doc;
  67.     req.headers['presigned-expires'] = false;
  68.     req.headers['Host'] = endpoint.host;
  69.  
  70.     // Sign the request (Sigv4)
  71.     var signer = new AWS.Signers.V4(req, 'es');
  72.     signer.addAuthorization(creds, new Date());
  73.  
  74.     // Post document to ES
  75.     var send = new AWS.NodeHttpClient();
  76.     send.handleRequest(req, null, function(httpResp) {
  77.         var body = '';
  78.         httpResp.on('data', function (chunk) {
  79.             body += chunk;
  80.         });
  81.         httpResp.on('end', function (chunk) {
  82.             numDocsAdded ++;
  83.             if (numDocsAdded === totLogLines) {
  84.                 // Mark lambda success.  If not done so, it will be retried.
  85.                 console.log('All ' + numDocsAdded + ' log records added to ES.');
  86.                 context.succeed();
  87.             }
  88.         });
  89.     }, function(err) {
  90.         console.log('Error: ' + err);
  91.         console.log(numDocsAdded + 'of ' + totLogLines + ' log records added to ES.');
  92.         context.fail();
  93.     });
  94. }
  95.  
  96. /* Lambda "main": Execution starts here */
  97. exports.handler = function(event, context) {
  98.     console.log('Received event: ', JSON.stringify(event, null, 2));
  99.    
  100.     /* == Streams ==
  101.     * To avoid loading an entire (typically large) log file into memory,
  102.     * this is implemented as a pipeline of filters, streaming log data
  103.     * from S3 to ES.
  104.     * Flow: S3 file stream -> Log Line stream -> Log Record stream -> ES
  105.     */
  106.     var lineStream = new LineStream();
  107.     // A stream of log records, from parsing each log line
  108.     var recordStream = new stream.Transform({objectMode: true})
  109.     recordStream._transform = function(line, encoding, done) {
  110.         var logRecord = parse(line.toString());
  111.         var serializedRecord = JSON.stringify(logRecord);
  112.         this.push(serializedRecord);
  113.         totLogLines ++;
  114.         done();
  115.     }
  116.  
  117.     event.Records.forEach(function(record) {
  118.         var bucket = record.s3.bucket.name;
  119.         var objKey = decodeURIComponent(record.s3.object.key.replace(/\+/g, ' '));
  120.         s3LogsToES(bucket, objKey, context, lineStream, recordStream);
  121.     });
  122. }
Advertisement
Comments
  • User was banned
Add Comment
Please, Sign In to add comment