Skip to content

Commit

Permalink
feat(tags): Add option to add tags to all logs sent to ES
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-cottone committed Dec 6, 2018
1 parent e1b75a9 commit dda6837
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 4 deletions.
12 changes: 12 additions & 0 deletions README.md
Expand Up @@ -95,6 +95,18 @@ custom:
retentionInDays: 7
```

#### tags

(Optional) Custom tags that should be applied to every log message processed by this plugin and sent to elasticsearch as fields.

```yaml
custom:
esLogs:
tags:
some_tag: something
some_other_tag: something_else
```

[sls-image]:http://public.serverless.com/badges/v3.svg
[sls-url]:http://www.serverless.com
[npm-image]:https://img.shields.io/npm/v/serverless-es-logs.svg
Expand Down
14 changes: 11 additions & 3 deletions src/index.ts
Expand Up @@ -102,14 +102,18 @@ class ServerlessEsLogsPlugin {
throw new this.serverless.classes.Error(`ERROR: No configuration provided for serverless-es-logs!`);
}

const { endpoint, index } = esLogs;
const { endpoint, index, tags } = esLogs;
if (!endpoint) {
throw new this.serverless.classes.Error(`ERROR: Must define an endpoint for serverless-es-logs!`);
}

if (!index) {
throw new this.serverless.classes.Error(`ERROR: Must define an index for serverless-es-logs!`);
}

if (tags && !_.isPlainObject(tags)) {
throw new this.serverless.classes.Error(`ERROR: Tags must be an object! You provided '${tags}'.`);
}
}

private addApiGwCloudwatchSubscription(): void {
Expand All @@ -119,6 +123,7 @@ class ServerlessEsLogsPlugin {
const template = this.serverless.service.provider.compiledCloudFormationAliasTemplate;

// Check if API Gateway stage exists
/* istanbul ignore else */
if (template && template.Resources[apiGatewayStageLogicalId]) {
const { StageName, RestApiId } = template.Resources[apiGatewayStageLogicalId].Properties;
const subscriptionLogicalId = `${apiGatewayStageLogicalId}SubscriptionFilter`;
Expand Down Expand Up @@ -188,6 +193,7 @@ class ServerlessEsLogsPlugin {

// Add cloudwatch subscription for each function except log processer
functions.forEach((name: string) => {
/* istanbul ignore if */
if (name === this.logProcesserName) {
return;
}
Expand Down Expand Up @@ -251,7 +257,8 @@ class ServerlessEsLogsPlugin {
}

private addLogProcesser(): void {
const { index, endpoint } = this.custom.esLogs;
const { index, endpoint, tags } = this.custom.esLogs;
const tagsStringified = tags ? JSON.stringify(tags) : /* istanbul ignore next */ '';
const dirPath = path.join(this.serverless.config.servicePath, this.logProcesserDir);
const filePath = path.join(dirPath, 'index.js');
const handler = `${this.logProcesserDir}/index.handler`;
Expand All @@ -262,7 +269,8 @@ class ServerlessEsLogsPlugin {
description: 'Serverless ES Logs Plugin',
environment: {
ES_ENDPOINT: endpoint,
INDEX_PREFIX: index,
ES_INDEX_PREFIX: index,
ES_TAGS: tagsStringified,
},
events: [],
handler,
Expand Down
9 changes: 8 additions & 1 deletion templates/code/logsToEs.js
Expand Up @@ -4,7 +4,11 @@ var zlib = require('zlib');
var crypto = require('crypto');

var endpoint = process.env.ES_ENDPOINT;
var indexPrefix = process.env.INDEX_PREFIX;
var indexPrefix = process.env.ES_INDEX_PREFIX;
var tags = undefined;
try {
tags = JSON.parse(process.env.ES_TAGS);
} catch (_) {}

exports.handler = function(input, context) {
// decode input from base64
Expand Down Expand Up @@ -74,6 +78,9 @@ function transform(payload) {
source['@owner'] = payload.owner;
source['@log_group'] = payload.logGroup;
source['@log_stream'] = payload.logStream;
if (tags) {
source['@tags'] = tags;
}

var action = { "index": {} };
action.index._index = indexName;
Expand Down
21 changes: 21 additions & 0 deletions test/unit/plugin.test.ts
Expand Up @@ -16,6 +16,7 @@ describe('serverless-es-logs :: Plugin tests', () => {
esLogs: {
endpoint: 'some_endpoint',
index: 'some_index',
tags: {},
},
},
},
Expand Down Expand Up @@ -104,6 +105,26 @@ describe('serverless-es-logs :: Plugin tests', () => {
'ERROR: Must define an index for serverless-es-logs!',
);
});

it('should throw an error if \'tags\' are not an object', () => {
const opts = {
service: {
custom: {
esLogs: {
index: 'some_index',
endpoint: 'some_endpoint',
tags: 'bad_tags',
},
},
},
};
serverless = new ServerlessBuilder(opts).build();
plugin = new ServerlessEsLogsPlugin(serverless, options);
expect(plugin.hooks['after:package:initialize']).to.throw(
Error,
"ERROR: Tags must be an object! You provided 'bad_tags'.",
);
});
});

describe('#addLogProcesser()', () => {
Expand Down

0 comments on commit dda6837

Please sign in to comment.