Nick Chisiu 16aa6581ab fix #1854 - update npm devDependencies packages (#1879)
* fix #1854 - added latest version of eslint-config-airbnb-base package

* fix #1854 - added latest npm shrinkwrap scheme

* fix #1854 - added latest npm coveralls package

* fix #1854 - added latest npm eslint package

* fix #1854 - added latest npm eslint-config-airbnb package

* fix #1854 - added latest npm eslint-plugin-import package

* fix #1854 - added latest npm eslint-plugin-jsx-a11y package

* fix #1854 - added latest npm eslint-plugin-react package

* fix #1854 - fixed estlint new-parens errors for integration test

* fix #1854 - fixed estlint new-parens errors for yaml parsers tests

* fix #1854 - fixed estlint max-len errors for util tests

* fix #1854 - disabled no-extraneous-dependencies on eslintrc for NodeJS 4 incapability on this feature

* fix #1854 - fixed eslint new-parens errors for Service tests

* fix #1854 - fixed eslint new-parens errors for Serverless tests

* fix #1854 - fixed eslint new-parens errors for plugin manager tests

* fix #1854 - fixed eslint new-parens errors for plugin tracking tests

* fix #1854 - fixed eslint new-parens errors for plugin package zipService lib

* fix #1854 - fixed eslint new-parens errors for plugin package zipService tests

* fix #1854 - fixed eslint trailing spaces errors for plugin package zipService lib

* fix #1854 - fixed eslint new-parens errors for plugin package cleanup  tests

* fix #1854 - fixed eslint new-parens errors for plugin create tests

* fix #1854 - fixed eslint dot same line expectation error on plugin aws logs index

* fix #1854 - fixed eslint operator assignment error on plugin aws logs index

* fix #1854 - fixed eslint dot location error on plugin aws invoke tests

* fix #1854 - fixed eslint new-parens error on plugin aws invoke tests

* fix #1854 - fixed eslint new-parens error on plugin aws deployFunction tests

* fix #1854 - fixed eslint new-parens error on plugin aws deploy uploadDeploymentPackage tests

* fix #1854 - fixed eslint new-parens error on plugin aws deploy updateStack tests

* fix #1854 - fixed eslint new-parens error on plugin aws deploy createStack tests

* fix #1854 - fixed eslint new-parens error on plugin aws deploy apiGateway lib deployment

* fix #1854 - fixed eslint unary typeof whitespace req error on Serverless Service class

* fix #1854 - fixed eslint unary typeof whitespace req error on Serverless Service class ( second fix )

* fix #1854 - fixed eslint no-lonely-if req error on Serverless Service class

* fix #1854 - disabled react/require-extension on eslintrc because it's deprecated

* fix #1854 - AwsCompileApigEvents #constructor() should resolve if no functions are given:
                 Error: Resolution method is overspecified. Specify a callback *or* return a Promise; not both.

* fix #1854 - createStack #postCreate() should resolve:
                 Error: Resolution method is overspecified. Specify a callback *or* return a Promise; not both.

* fix #1854 - emptyS3Bucket #deleteObjects() should resolve if objectsInBucket is empty:
                 Error: Resolution method is overspecified. Specify a callback *or* return a Promise; not both.

* fix #1854 - AwsInvoke #extendedValidate() should resolve if path is not given:
                 Error: Resolution method is overspecified. Specify a callback *or* return a Promise; not both.

* fix #1854 - #cleanup() should resolve if the .serverless directory is not present:
                 Error: Resolution method is overspecified. Specify a callback *or* return a Promise; not both.

* fix #1854 -#validate() should resolve if servicePath is given:
                Error: Resolution method is overspecified. Specify a callback *or* return a Promise; not both.

* fix #1854 -  Service #load() should resolve if no servicePath is found:
                 Error: Resolution method is overspecified. Specify a callback *or* return a Promise; not both.

* fix #1854 - added latest mocha package

* fix #1854 - added latest sinon npm package

* fix #1854 - serverless/lib/plugins/aws/deploy/tests/createStack.js 136:48  error  Missing semicolon  semi

* fix #1854 - serverless/lib/plugins/package/tests/cleanup.js 35:7  error  Missing semicolon  semi

* fix #1854 - serverless/lib/plugins/package/tests/validate.js 22:49  error  Missing semicolon  semi

* fix #1854 - added latest npm shrinkwrap

* fix #1854 - fixed no-extra-boolean-cast eslint error on aws deploy apiGateway methods

* fix #1854 - fixed  new-parens eslint error on serverless tests for Service class
2016-08-18 11:51:09 +02:00

158 lines
4.4 KiB
JavaScript

'use strict';
const BbPromise = require('bluebird');
const chalk = require('chalk');
const _ = require('lodash');
const SDK = require('../');
const os = require('os');
const moment = require('moment');
const validate = require('../lib/validate');
class AwsLogs {
constructor(serverless, options) {
this.serverless = serverless;
this.options = options || {};
this.provider = 'aws';
this.sdk = new SDK(serverless);
Object.assign(this, validate);
this.hooks = {
'logs:logs': () => BbPromise.bind(this)
.then(this.extendedValidate)
.then(this.getLogStreams)
.then(this.showLogs),
};
}
extendedValidate() {
this.validate();
// validate function exists in service
const lambdaName = this.serverless.service.getFunction(this.options.function).name;
this.options.interval = this.options.interval || 1000;
this.options.logGroupName = `/aws/lambda/${lambdaName}`;
return BbPromise.resolve();
}
getLogStreams() {
const params = {
logGroupName: this.options.logGroupName,
descending: true,
limit: 50,
orderBy: 'LastEventTime',
};
return this.sdk
.request('CloudWatchLogs',
'describeLogStreams',
params,
this.options.stage,
this.options.region)
.then(reply => {
if (!reply || reply.logStreams.length === 0) {
throw new this.serverless.classes
.Error('No existing streams for the function');
}
return _.chain(reply.logStreams)
.filter(stream => stream.logStreamName.includes('[$LATEST]'))
.map('logStreamName')
.value();
});
}
showLogs(logStreamNames) {
if (!logStreamNames || !logStreamNames.length) {
if (this.options.tail) {
return setTimeout((() => this.getLogStreams()
.then(nextLogStreamNames => this.showLogs(nextLogStreamNames))),
this.options.interval);
}
}
const formatLambdaLogEvent = (msgParam) => {
let msg = msgParam;
const dateFormat = 'YYYY-MM-DD HH:mm:ss.SSS (Z)';
if (msg.startsWith('REPORT')) {
msg += os.EOL;
}
if (msg.startsWith('START') || msg.startsWith('END') || msg.startsWith('REPORT')) {
return chalk.gray(msg);
} else if (msg.trim() === 'Process exited before completing request') {
return chalk.red(msg);
}
const splitted = msg.split('\t');
if (splitted.length < 3 || new Date(splitted[0]) === 'Invalid Date') {
return msg;
}
const reqId = splitted[1];
const time = chalk.green(moment(splitted[0]).format(dateFormat));
const text = msg.split(`${reqId}\t`)[1];
return `${time}\t${chalk.yellow(reqId)}\t${text}`;
};
const params = {
logGroupName: this.options.logGroupName,
interleaved: true,
logStreamNames,
startTime: this.options.startTime,
};
if (this.options.filter) params.filterPattern = this.options.filter;
if (this.options.nextToken) params.nextToken = this.options.nextToken;
if (this.options.startTime) {
const since = (['m', 'h', 'd']
.indexOf(this.options.startTime[this.options.startTime.length - 1]) !== -1);
if (since) {
params.startTime = moment().subtract(this.options
.startTime.replace(/\D/g, ''), this.options
.startTime.replace(/\d/g, '')).valueOf();
} else {
params.startTime = moment(this.options.startTime).valueOf();
}
}
return this.sdk
.request('CloudWatchLogs',
'filterLogEvents',
params,
this.options.stage,
this.options.region)
.then(results => {
if (results.events) {
results.events.forEach(e => {
process.stdout.write(formatLambdaLogEvent(e.message));
});
}
if (results.nextToken) {
this.options.nextToken = results.nextToken;
} else {
delete this.options.nextToken;
}
if (this.options.tail) {
if (results.events && results.events.length) {
this.options.startTime = _.last(results.events).timestamp + 1;
}
return setTimeout((() => this.getLogStreams()
.then(nextLogStreamNames => this.showLogs(nextLogStreamNames))),
this.options.interval);
}
return BbPromise.resolve();
});
}
}
module.exports = AwsLogs;