Skip to content

Commit 1ca63b8

Browse files
authored
Merge pull request #15 from KyleRoss/automation
Adding automation for future releases
2 parents aace440 + eb4d9eb commit 1ca63b8

15 files changed

Lines changed: 773 additions & 198 deletions

.gitignore

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,45 @@
1+
# Logs
12
logs
23
*.log
34
npm-debug.log*
4-
node_modules
5+
yarn-debug.log*
6+
yarn-error.log*
7+
8+
# Runtime data
9+
pids
10+
*.pid
11+
*.seed
12+
*.pid.lock
13+
14+
# Directory for instrumented libs generated by jscoverage/JSCover
15+
lib-cov
16+
17+
# Coverage directory used by tools like istanbul
18+
coverage
19+
20+
# nyc test coverage
21+
.nyc_output
22+
23+
# Dependency directories
24+
node_modules/
25+
26+
# Optional npm cache directory
527
.npm
28+
29+
# Optional eslint cache
30+
.eslintcache
31+
32+
# Optional REPL history
33+
.node_repl_history
34+
35+
# Output of 'npm pack'
36+
*.tgz
37+
38+
# Yarn Integrity file
39+
.yarn-integrity
40+
41+
# dotenv environment variables file
42+
.env
43+
44+
# package-lock
645
package-lock.json

.releaserc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"plugins": [
3+
"@semantic-release/commit-analyzer",
4+
"@semantic-release/release-notes-generator",
5+
"@semantic-release/changelog",
6+
"@semantic-release/npm",
7+
["@semantic-release/git", {
8+
"assets": ["package.json", "CHANGELOG.md", "README.md"],
9+
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
10+
}],
11+
"@semantic-release/github"
12+
]
13+
}

.travis.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
dist: trusty
2+
sudo: required
13
language: node_js
24
node_js:
35
- "11"
@@ -6,3 +8,25 @@ node_js:
68
- "8"
79
- "6"
810
- "6.10"
11+
after_success: 'npm run coveralls'
12+
13+
os:
14+
- linux
15+
16+
jobs:
17+
include:
18+
- stage: install
19+
script: npm install
20+
skip_cleanup: true
21+
- stage: test
22+
script: npm run test
23+
skip_cleanup: true
24+
- stage: release
25+
node_js: lts/*
26+
deploy:
27+
provider: script
28+
skip_cleanup: true
29+
script:
30+
- npm run docs
31+
- npx semantic-release
32+
if: branch = master AND type != pull_request

CHANGELOG.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
# LambdaLog Changelog
2-
31
## 2.1.0 (12/19/2018)
42
* **BREAKING:** Removed `stdoutStream` and `stderrStream` options.
53
* **NEW:** Added `logHandler` option which takes a `console`-like object to send logs through. (#11)

README.md

Lines changed: 229 additions & 138 deletions
Large diffs are not rendered by default.

build/README.hbs

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
# lambda-log
2+
[![npm](https://img.shields.io/npm/v/lambda-log.svg?style=for-the-badge)](https://www.npmjs.com/package/lambda-log) [![npm](https://img.shields.io/npm/dt/lambda-log.svg?style=for-the-badge)](https://www.npmjs.com/package/lambda-log) [![David](https://img.shields.io/david/KyleRoss/node-lambda-log.svg?style=for-the-badge)](https://david-dm.org/KyleRoss/node-lambda-log) [![Travis](https://img.shields.io/travis/KyleRoss/node-lambda-log/master.svg?style=for-the-badge)](https://travis-ci.org/KyleRoss/node-lambda-log) ![Coveralls github](https://img.shields.io/coveralls/github/KyleRoss/node-lambda-log.svg?style=for-the-badge) [![license](https://img.shields.io/github/license/KyleRoss/node-lambda-log.svg?style=for-the-badge)](https://github.com/KyleRoss/node-lambda-log/blob/master/LICENSE) [![Beerpay](https://img.shields.io/beerpay/KyleRoss/node-lambda-log.svg?style=for-the-badge)](https://beerpay.io/KyleRoss/node-lambda-log)
3+
4+
Basic logging mechanism for **Node 6.10+** Lambda Functions which properly formats various logs into JSON format for easier reading through Cloudwatch Logs. The module includes functionality to include custom metadata and tags for each log, allowing increased filtering capabilities within Cloudwatch.
5+
6+
> This module is not just for Lambda! You can use this is many different environments that support reading JSON from logs. While the name remains `lambda-log`, it's really a universal JSON logger.
7+
8+
**Why another lambda logger?**
9+
There are others out there, but seemed to be convoluted, included more functionality than needed, not maintained, or not configurable enough. I created lambda-log to include the important functionality from other loggers, but still keeping it simple and dependency-free.
10+
11+
### Features
12+
13+
* Global metadata and tags that are included with every log.
14+
* Pluggable by wrapping/extending the LambdaLog class.
15+
* Emits event on log to allow third-party integration.
16+
* Error and Error-like objects logged include stacktraces in the metadata automatically.
17+
* Pretty-printing of JSON object in [dev](#lambdalogconfig) mode.
18+
* Well-documented and commented source.
19+
* Small footprint!
20+
21+
#### New in Version 2.0.0
22+
* Dynamic metadata can be added to every log (ex. timestamp).
23+
* ~~Logs can be piped to a custom stream instead of stdout/stderr.~~
24+
* In 2.1.0, you can override the logging mechanism with a `console`-like object.
25+
* Log levels and their corresponding console method can be customized.
26+
* Logs are now an instance of a class with a simple API.
27+
* When logs are converted to JSON, you can customize/mask certain data using a replacer function.
28+
* And a bunch more...
29+
30+
There are a few breaking changes in version 2.0.0. If you are upgrading from the previous version, please read the Changelog and documentation to see how these changes could affect your implementation.
31+
32+
---
33+
34+
## Getting Started
35+
### Requirements
36+
Node v6.10+ is required. You need to ensure that your Lambda function is running with the correct Node version.
37+
38+
### Install
39+
Install via NPM:
40+
41+
```bash
42+
$ npm install lambda-log --save
43+
```
44+
45+
### Usage
46+
Here is a basic usage example, read the API documentation below to learn more.
47+
48+
```js
49+
const log = require('lambda-log');
50+
51+
exports.handler = function(event, context, callback) {
52+
// set some optional metadata to be included in all logs (this is an overkill example)
53+
log.options.meta.event = event;
54+
// add additional tags to all logs
55+
log.options.tags.push(event.env);
56+
57+
// Log info message
58+
log.info('my lambda function is running!');
59+
//=> { _logLevel: 'info' msg: 'my lambda function is running!', event:..., _tags: ['log', 'info', ...] }
60+
61+
if(somethingHappenedButNotFatal) {
62+
log.warn('something is missing, but it is OK');
63+
//=> { _logLevel: 'warn', msg: 'something is missing, but it is OK', event:..., _tags: ['log', 'warn', ...] }
64+
}
65+
66+
// Debug messages are not generated or displayed unless enabled in the config
67+
log.debug('some debug message');
68+
//=> false
69+
70+
// Enable debug messages
71+
log.options.debug = true;
72+
log.debug('some debug message again');
73+
//=> { _logLevel: 'debug', msg: 'some debug message again', event:..., _tags: ['log', 'debug', ...] }
74+
75+
someAsyncTask(function(err, results) {
76+
if(err) {
77+
log.error(err);
78+
//=> { _logLevel: 'error', msg: 'Error from someAsyncTask', stack: ..., event: ..., _tags: ['log', 'error', ...]}
79+
} else {
80+
log.info('someAsyncTask completed successfully!', { results });
81+
//=> { _logLevel: 'info', msg: 'someAsyncTask completed successfully!', results:..., event: ..., _tags: ['log', 'info', ...]}
82+
}
83+
});
84+
85+
// New in version 1.4.0 - assert
86+
someAsyncTask(function(err, results) {
87+
if(err) {
88+
log.error(err);
89+
//=> { _logLevel: 'error', msg: 'Error from someAsyncTask', stack: ..., event: ..., _tags: ['log', 'error', ...]}
90+
} else {
91+
// Will only log if no results are returned
92+
log.assert(results, 'No results returned from someAsyncTask');
93+
}
94+
});
95+
};
96+
```
97+
98+
---
99+
100+
# API Documentation
101+
{{#orphans ~}}
102+
{{>docs~}}
103+
{{/orphans~}}
104+
105+
---
106+
107+
### Log Output
108+
Each log generated is a custom object that has a set of properties containing all of the values of the log. This output is converted to JSON and logged to the console. Below are the properties included in the log.
109+
110+
#### Default Properties:
111+
* `_logLevel` _(String)_ - The log level (ex. error, warn, info, debug) _Since 1.3.0_
112+
* `msg` _(String)_ - The message of the log
113+
* `_tags` _(Array[String])_ - Array of tags applied to the log
114+
115+
#### Conditional Properties:
116+
* `*` _(Any)_ - Any metadata provided, dynamic metadata and global metadata as individual properties
117+
* `stack` _(String)_ - Stack trace of an error if an `Error` was provided
118+
119+
---
120+
121+
### Custom Log Levels
122+
New in version 2.0.0, the ability to customize log levels is now available. In order to customize the log levels, you must create a new instance of `LambdaLog` as any changes directly to a pre-existing instance will not function correctly. The custom log levels are manipulated by passing in an object to the `levels` argument of the LambdaLog constructor. The provided custom log levels object will override and extend the existing log levels.
123+
124+
Any custom log levels added will be available as shorthand methods on the LambdaLog instance.
125+
126+
#### Log Levels Object
127+
The log levels object is a simple object that should contain key/value pairs. The keys should be the log level and the values may be either a string or function. If a string is provided, it should be the corresponding `console` method name to use for the log (ex. `log` or `info`). If a function is provided, it must return either a string `console` method or `false` to prevent logging. The function will be called for every log with `message` ([LogMessage](#logmessage)) as the only parameter, allowing customizing the logging for certain messages.
128+
129+
```js
130+
const LambdaLog = require('lambda-log').LambdaLog;
131+
132+
const log = new LambdaLog({}, {
133+
fatal: 'error',
134+
poop: function(message) {
135+
// prepend an emoji to every message
136+
message.msg = '💩 ' + message.msg;
137+
138+
return 'log';
139+
},
140+
info: function() {
141+
// Make `log.info()` work like `log.debug()`
142+
if(this.options.debug) return false;
143+
return 'info';
144+
}
145+
});
146+
147+
log.poop('This is a test');
148+
//=> "💩 This is a test"
149+
```
150+
151+
---
152+
153+
### Dynamic Metadata
154+
New in version 2.0.0, lambda-log now has the ability to execute and include dynamic metadata for each log. Dynamic metadata is generated using a function (`log.options.dynamicMeta`) on the creation of each message and included into the metadata.
155+
156+
#### Dynamic Metadata Function
157+
The dynamic metadata function is included into `log.options` and will run for every log. The function is called with parameters `message` (the LogMessage instance) and `options` (`log.options` object). The function should return an object with metadata to inject into the log.
158+
159+
```js
160+
// Add timestamp to each log
161+
log.options.dynamicMeta = function(message) {
162+
return {
163+
timestamp: new Date().toISOString()
164+
};
165+
};
166+
```
167+
168+
---
169+
170+
### Log Handler
171+
New in version 2.1.0, you may now customize the methods used to log messages. By default, lambda-log uses the global `console` object, but you can override this with a custom instance of <code><a href="https://nodejs.org/docs/latest-v8.x/api/console.html#console_new_console_stdout_stderr">Console</a></code> or your own `console`-like object that implements, at minimum, the following functions:
172+
173+
* log
174+
* debug
175+
* info
176+
* error
177+
* warn
178+
179+
Keep in mind that custom implementations must be synchronus. If you need it to be asynchronus, you will need to use a custom <code><a href="https://nodejs.org/docs/latest-v8.x/api/console.html#console_new_console_stdout_stderr">Console</a></code> instance and implement utilizing streams.
180+
181+
```js
182+
const log = require('lambda-log');
183+
184+
// example using `Console` instance
185+
const { Console } = require('console');
186+
log.options.logHandler = new Console(myStdoutStream, myStderrStream);
187+
188+
// or with a console-like object
189+
const myConsole = {
190+
log(message) {
191+
// log `message` somewhere custom
192+
},
193+
error(message) {
194+
// ...
195+
},
196+
...
197+
};
198+
```
199+
200+
Note that this is a breaking change from version 2.0.0 as there were issues by always utlizing a custom `Console` instance for certain users.
201+
202+
---
203+
204+
## Tests
205+
Tests are written and provided as part of the module. It requires mocha to be installed which is included as a `devDependency`. You may run the tests by calling:
206+
207+
```bash
208+
$ npm run test
209+
```
210+
211+
## Contributing
212+
Feel free to submit a pull request if you find any issues or want to integrate a new feature. Keep in mind, this module should be lightweight and advanced functionality should be published to NPM as a wrapper around this module. Ensure to write and run the tests before submitting a pull request. The code should work without any special flags in Node 6.10.
213+
214+
## License
215+
MIT License. See [License](https://github.com/KyleRoss/node-lambda-log/blob/master/LICENSE) in the repository.

build/sig-link-parent.hbs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{{#if name}}{{#sig~}}
2+
{{{@depOpen}~}}
3+
{{#if (isEvent)}}Event: {{/if~}}[{{{@codeOpen}~}}
4+
{{#if @prefix}}{{@prefix}} {{/if~}}
5+
{{#if (isClassMember)}}{{@parent~}}{{/if~}}
6+
{{@accessSymbol}}{{#if (isEvent)}}{{{name}}}{{else}}{{{name}}}{{/if~}}
7+
{{~#if @methodSign}}{{#if (isEvent)}} {{@methodSign}}{{else}}{{@methodSign}}{{/if}}{{/if~}}
8+
{{{@codeClose}}}](#{{{anchorName}}})
9+
{{~#if @returnSymbol}} {{@returnSymbol}}{{/if~}}
10+
{{#if @returnTypes}} {{>linked-type-list types=@returnTypes delimiter=" \| " }}{{/if~}}
11+
{{#if @suffix}} {{@suffix}}{{/if~}}
12+
{{{@depClose}~}}
13+
{{~/sig}}{{/if~}}

build/sig-link.hbs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{{#if virtual}}*{{/if}}{{#with (parentObject)}}{{#if virtual}}*{{/if~}}{{/with~}}
2+
{{#if name}}{{#sig~}}
3+
{{{@depOpen}~}}
4+
[{{{@codeOpen}~}}
5+
{{#if @prefix}}{{@prefix}} {{/if~}}
6+
{{@accessSymbol}}{{#if (isEvent)}}{{{name}}}{{else}}{{{name}}}{{/if~}}
7+
{{~#if @methodSign}}{{#if (isEvent)}} {{@methodSign}}{{else}}{{@methodSign}}{{/if}}{{/if~}}
8+
{{{@codeClose}}}](#{{{anchorName}}})
9+
{{~#if @returnSymbol}} {{@returnSymbol}}{{/if~}}
10+
{{#if @returnTypes}} {{>linked-type-list types=@returnTypes delimiter=" \| " }}{{/if~}}
11+
{{#if @suffix}} {{@suffix}}{{/if~}}
12+
{{{@depClose}~}}
13+
{{~/sig}}{{/if~}}
14+
{{#if virtual}}*{{/if}}{{#with (parentObject)}}{{#if virtual}}*{{/if~}}{{/with~}}

build/sig-name.hbs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{{#if virtual}}*{{/if}}{{#with (parentObject)}}{{#if virtual}}*{{/if~}}{{/with~}}
2+
{{#if name}}{{#sig~}}
3+
{{{@depOpen}~}}
4+
{{{@codeOpen}~}}
5+
{{#if @prefix}}{{@prefix}} {{/if~}}
6+
{{@parent~}}
7+
{{@accessSymbol}}{{#if (isEvent)}}Event: {{{name}}}{{else}}{{{escape name}}}{{/if~}}
8+
{{#if @methodSign}}{{#if (isEvent)}} {{@methodSign}}{{else}}{{@methodSign}}{{/if}}{{/if~}}
9+
{{{@codeClose}~}}
10+
{{#if @returnSymbol}} {{@returnSymbol}}{{/if~}}
11+
{{#if @returnTypes}} {{>linked-type-list types=@returnTypes delimiter=" \| " }}{{/if~}}
12+
{{#if @suffix}} {{@suffix}}{{/if~}}
13+
{{{@depClose}~}}
14+
{{~/sig}}{{/if~}}
15+
{{#if virtual}}*{{/if}}{{#with (parentObject)}}{{#if virtual}}*{{/if~}}{{/with~}}

commitlint.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = { extends: ['@commitlint/config-conventional'] };

0 commit comments

Comments
 (0)