Comparing version 0.2.0 to 1.0.0-rc.1
@@ -5,35 +5,11 @@ 'use strict' | ||
const SimpleFormat = require('./SimpleFormat') | ||
const JsonFormat = require('./JsonFormat') | ||
const Transport = require('./Transport') | ||
const ConsoleTransport = require('./ConsoleTransport') | ||
const { | ||
addMethodsForLevelsSym, | ||
levelsArraySym, | ||
levelStringSym, | ||
levelSym, | ||
levelsSym, | ||
transportsSym, | ||
preparedMetasSym | ||
} = require('./Symbols') | ||
const { DEFAULT_LEVEL } = require('./Defaults') | ||
const defaultLevels = { | ||
TRACE: 0, | ||
DEBUG: 1, | ||
INFO: 2, | ||
WARN: 3, | ||
ERROR: 4, | ||
FATAL: 5 | ||
} | ||
function createLogger (options = {}) { | ||
const levels = options.levels || defaultLevels | ||
const levelString = options.level || 'INFO' | ||
const logger = new Logger() | ||
logger[transportsSym] = options.transports || [ getTransport(options) ] | ||
logger[levelsSym] = levels | ||
logger[levelStringSym] = levelString | ||
logger[levelSym] = levels[levelString] | ||
logger[levelsArraySym] = Object.keys(levels) | ||
logger[addMethodsForLevelsSym]() | ||
logger[preparedMetasSym] = [] | ||
return logger | ||
options.levelString = options.level || DEFAULT_LEVEL | ||
options.transports = options.transports || [ getTransport(options) ] | ||
return new Logger(options) | ||
} | ||
@@ -55,3 +31,4 @@ | ||
SimpleFormat, | ||
JsonFormat, | ||
ConsoleTransport | ||
} |
@@ -12,5 +12,3 @@ 'use strict' | ||
constructor (options) { | ||
super({ | ||
format: options.format | ||
}) | ||
super({ format: options.format }) | ||
this[stderrLevelsSym] = options.stderrLevels || { | ||
@@ -32,5 +30,5 @@ WARN: true, | ||
end (callback) { | ||
callback() | ||
end () { | ||
return Promise.resolve() | ||
} | ||
} |
'use strict' | ||
const eachAsync = require('async-each') | ||
const { | ||
addMethodsForLevelsSym, | ||
levelsArraySym, | ||
levelStringSym, | ||
levelSym, | ||
levelsSym, | ||
logSym, | ||
transportsSym, | ||
@@ -14,13 +12,20 @@ preparedMetasSym, | ||
} = require('./Symbols') | ||
const { DEFAULT_LEVELS } = require('./Defaults') | ||
module.exports = class Logger { | ||
constructor (options) { | ||
this[transportsSym] = options.transports | ||
this[levelsSym] = DEFAULT_LEVELS | ||
this[levelStringSym] = options.levelString | ||
this[levelSym] = DEFAULT_LEVELS[options.levelString] | ||
this[preparedMetasSym] = new Array(this[transportsSym].length) | ||
} | ||
child (meta) { | ||
const logger = new Logger() | ||
logger[transportsSym] = this[transportsSym] | ||
logger[levelsSym] = this[levelsSym] | ||
logger[levelStringSym] = this[levelStringSym] | ||
logger[levelSym] = this[levelSym] | ||
logger[levelsArraySym] = this[levelsArraySym] | ||
logger[addMethodsForLevelsSym]() | ||
logger[prepareMetaSym](meta) | ||
const logger = new Logger({ | ||
transports: this[transportsSym], | ||
levelString: this[levelStringSym], | ||
level: this[levelSym] | ||
}) | ||
logger[prepareMetaSym](meta, this[preparedMetasSym]) | ||
logger.end = end | ||
@@ -30,37 +35,87 @@ return logger | ||
log (level, message, ...args) { | ||
if (this[levelsSym][level] >= this[levelSym]) { | ||
for (let index = 0; index < this[transportsSym].length; index++) { | ||
const transport = this[transportsSym][index] | ||
transport.log(level, message, args, this[preparedMetasSym][index]) | ||
} | ||
end () { | ||
const promises = this[transportsSym].map(endTransport) | ||
return Promise.all(promises) | ||
} | ||
trace (message, ...args) { | ||
this[logSym]('TRACE', message, args) | ||
} | ||
debug (message, ...args) { | ||
this[logSym]('DEBUG', message, args) | ||
} | ||
info (message, ...args) { | ||
this[logSym]('INFO', message, args) | ||
} | ||
warn (message, ...args) { | ||
this[logSym]('WARN', message, args) | ||
} | ||
error (message, ...args) { | ||
this[logSym]('ERROR', message, args) | ||
} | ||
fatal (message, ...args) { | ||
this[logSym]('FATAL', message, args) | ||
} | ||
getLevel () { | ||
return this[levelStringSym] | ||
} | ||
setLevel (levelString) { | ||
const level = this[levelsSym][levelString] | ||
if (level === undefined) { | ||
const error = new Error('Unknown level: ' + levelString) | ||
error.code = 'APH_ERR_UNKNOWN_LEVEL' | ||
throw error | ||
} | ||
this[levelStringSym] = levelString | ||
this[levelSym] = level | ||
} | ||
end (callback) { | ||
eachAsync(this[transportsSym], (transport, cb) => { | ||
transport.end(cb) | ||
}, callback) | ||
isLevelEnabled (level) { | ||
return this[levelsSym][level] >= this[levelSym] | ||
} | ||
[prepareMetaSym] (meta) { | ||
const preparedMetas = new Array(this[transportsSym].length) | ||
addMetaData (key, value) { | ||
for (let index = 0; index < this[transportsSym].length; index++) { | ||
const transport = this[transportsSym][index] | ||
preparedMetas[index] = transport.prepareMeta(meta) | ||
this[preparedMetasSym][index] = (this[preparedMetasSym][index] || '') + transport.formatMetaData(key, value) | ||
} | ||
this[preparedMetasSym] = preparedMetas | ||
} | ||
[addMethodsForLevelsSym] () { | ||
for (const level of this[levelsArraySym]) { | ||
this[level.toLowerCase()] = (message, ...args) => { | ||
this.log(level, message, ...args) | ||
[logSym] (level, message, args) { | ||
if (!this.isLevelEnabled(level)) { | ||
return | ||
} | ||
for (let index = 0; index < this[transportsSym].length; index++) { | ||
const transport = this[transportsSym][index] | ||
transport.log(level, message, args, this[preparedMetasSym][index]) | ||
} | ||
} | ||
[prepareMetaSym] (meta, parentMeta) { | ||
const preparedMetas = new Array(this[transportsSym].length) | ||
for (let index = 0; index < this[transportsSym].length; index++) { | ||
const transport = this[transportsSym][index] | ||
if (!parentMeta[index]) { | ||
preparedMetas[index] = transport.formatMetaDataObject(meta) | ||
} else { | ||
preparedMetas[index] = parentMeta[index] + transport.formatMetaDataObject(meta) | ||
} | ||
} | ||
this[preparedMetasSym] = preparedMetas | ||
} | ||
} | ||
function end (callback) { | ||
callback() | ||
function end () { | ||
return Promise.resolve() | ||
} | ||
function endTransport (transport) { | ||
return transport.end() | ||
} |
@@ -9,3 +9,3 @@ 'use strict' | ||
dateFormat: options.dateFormat || 'YYYY-MM-DDTHH:mm:ss.SSS[Z]', | ||
cache: true | ||
cache: options.fastTimestamp | ||
}) | ||
@@ -19,2 +19,5 @@ } | ||
for (const arg of args) { | ||
if (!arg) { | ||
continue | ||
} | ||
if (arg.stack) { | ||
@@ -29,10 +32,17 @@ stack = '\n' + arg.stack | ||
prepareMeta (meta = {}) { | ||
formatMetaDataObject (meta = {}) { | ||
let result = '' | ||
for (const key in meta) { | ||
const value = meta[key] | ||
result += ` ${key}=${value}` | ||
result += this.formatMetaData(key, value) | ||
} | ||
return result | ||
} | ||
formatMetaData (key, value) { | ||
if (!value) { | ||
return '' | ||
} | ||
return ` ${key}=${value}` | ||
} | ||
} | ||
@@ -39,0 +49,0 @@ |
@@ -14,5 +14,8 @@ 'use strict' | ||
const formatSym = Symbol('apheleia.format') | ||
const logSym = Symbol('apheleia.log') | ||
const dateFormatterSym = Symbol('apheleia.dateFormatter') | ||
module.exports = { | ||
addMethodsForLevelsSym, | ||
dateFormatterSym, | ||
formatSym, | ||
@@ -23,2 +26,3 @@ levelsArraySym, | ||
levelsSym, | ||
logSym, | ||
transportsSym, | ||
@@ -25,0 +29,0 @@ preparedMetasSym, |
@@ -19,14 +19,16 @@ 'use strict' | ||
prepareMeta (meta) { | ||
if (this[formatSym].prepareMeta) { | ||
return this[formatSym].prepareMeta(meta) | ||
} else { | ||
return meta | ||
} | ||
formatMetaDataObject (meta) { | ||
return this[formatSym].formatMetaDataObject(meta) | ||
} | ||
end (callback) { | ||
this[streamSym].on('finish', callback) | ||
this[streamSym].end() | ||
formatMetaData (key, value) { | ||
return this[formatSym].formatMetaData(key, value) | ||
} | ||
end () { | ||
return new Promise((resolve) => { | ||
this[streamSym].on('finish', resolve) | ||
this[streamSym].end() | ||
}) | ||
} | ||
} |
{ | ||
"name": "apheleia", | ||
"version": "0.2.0", | ||
"description": "A simplistic logger.", | ||
"version": "1.0.0-rc.1", | ||
"description": "fast and simplistic logger.", | ||
"main": "lib/Apheleia.js", | ||
"scripts": { | ||
"unit": "tap test/*.test.js", | ||
"unit": "ava test/*Test.js", | ||
"test": "npm run lint && npm run unit", | ||
"lint": "standard DateFormatter.js lib/* test/* benchmark/*", | ||
"coveralls": "npm run unit -- --cov", | ||
"coverage": "npm run coveralls && tap --coverage-report=lcov", | ||
"benchmark": "node benchmark/benchmark.js" | ||
"coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls", | ||
"coverage": "nyc npm test && nyc report --reporter=html", | ||
"benchmark": "node benchmark/benchmarkSimpleFormat.js && node benchmark/benchmarkJsonFormat.js && node benchmark/benchmarkChildLogging.js && node benchmark/benchmarkChildCreation.js" | ||
}, | ||
@@ -17,13 +17,16 @@ "author": "Denis Fäcke", | ||
"dependencies": { | ||
"async-each": "^1.0.1", | ||
"fast-date-format": "^2.1.0" | ||
"fast-date-format": "^2.1.2", | ||
"json-escaping": "^1.0.1" | ||
}, | ||
"engines": { | ||
"node": ">= 8.0.0" | ||
}, | ||
"devDependencies": { | ||
"@clevernature/benchmark-regression": "^1.0.1", | ||
"benchmark": "^2.1.4", | ||
"ava": "^1.4.1", | ||
"coveralls": "^3.0.2", | ||
"daily-rotating-file-stream": "^1.0.0", | ||
"fast-file-rotate": "^1.0.1", | ||
"fastbench": "^1.0.1", | ||
"nyc": "^14.1.0", | ||
"pino": "^5.12.2", | ||
"sonic-boom": "^0.7.3", | ||
"standard": "^12.0.1", | ||
"tap": "^12.1.2", | ||
"winston": "^3.1.0" | ||
@@ -35,3 +38,5 @@ }, | ||
"logs", | ||
"stream" | ||
"stream", | ||
"json", | ||
"fast" | ||
], | ||
@@ -41,3 +46,4 @@ "repository": { | ||
"url": "git+https://github.com/SerayaEryn/apheleia.git" | ||
} | ||
}, | ||
"types": "./types.d.ts" | ||
} |
@@ -6,5 +6,5 @@ # apheleia | ||
[![NPM version](https://img.shields.io/npm/v/apheleia.svg?style=flat)](https://www.npmjs.com/package/apheleia) | ||
[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com) | ||
[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com) [![Greenkeeper badge](https://badges.greenkeeper.io/SerayaEryn/apheleia.svg)](https://greenkeeper.io/) | ||
A simplistic logger supporting any Writable stream and custom formats. | ||
Fast and simplistic logger supporting any Writable stream and custom formats. | ||
@@ -17,86 +17,28 @@ ## Installation | ||
## API | ||
## Usage | ||
### createLogger([options]) | ||
Creates a new Logger instance with a single transport. | ||
```js | ||
const { createLogger, SimpleFormat } = require('apheleia') | ||
const fs = require('fs') | ||
const { createLogger } = require('apheleia') | ||
const logger = createLogger({ | ||
stream: fs.createWriteStream(__dirname + '/app.log'), | ||
format: new SimpleFormat() | ||
}) | ||
const logger = createLogger() | ||
logger.info('hello world') | ||
``` | ||
#### stream (optional) | ||
A Writable stream. If undefined a `ConsoleTransport` will be used. | ||
#### format (optional) | ||
A format. Defaults to a instance of `SimpleFormat`.<br> | ||
Formats must implement the following interface: | ||
```ts | ||
interface Format { | ||
transform (level: string, message: string, args: any[], meta: object | undefined) | ||
} | ||
const child = logger.child({ requestId: 'abcd' }) | ||
child.info('hello world') | ||
``` | ||
#### levels (optional) | ||
The levels used by the logger. | ||
#### level (optional) | ||
Sets the log level of the logger. | ||
#### transports (optional) | ||
Allows to set the transport of the logger. | ||
### SimpleFormat([options]) | ||
### Logger | ||
#### Logger#end(callback) | ||
Ends the logger by calling `end()` on every transport and then calls the `callback`. | ||
#### Logger#trace(message, ...args) | ||
Writes a `TRACE` level log, if allowed by the `level` option. | ||
#### Logger#debug(message, ...args) | ||
Writes a `DEBUG` level log, if allowed by the `level` option. | ||
#### Logger#info(message, ...args) | ||
Writes a `INFO` level log, if allowed by the `level` option. | ||
#### Logger#warn(message, ...args) | ||
Writes a `WARN` level log, if allowed by the `level` option. | ||
#### Logger#error(message, ...args) | ||
Writes a `ERROR` level log, if allowed by the `level` option. | ||
#### Logger#fatal(message, ...args) | ||
Writes a `FATAL` level log, if allowed by the `level` option. | ||
### Transport(options) | ||
Creates a new Transport instance. | ||
```js | ||
new Transport({ | ||
stream: process.stdout, | ||
format: new SimpleFormat() | ||
} | ||
This logs the following lines: | ||
``` | ||
#### format | ||
2019-04-19T09:23:50.902Z INFO hello world | ||
2019-04-19T09:23:50.902Z INFO hello world requestId=abcd | ||
``` | ||
A format used to stringify the parameters passed to the loggers methods. | ||
## Documentation | ||
#### level | ||
Sets the log level of the logger. | ||
* [API](./docs/API.md) | ||
* [Benchmarks](./docs/Benchmarks.md) | ||
* [Transports & Formats](./docs/TransportsAndFormats.md) | ||
### ConsoleTransport(options) | ||
#### format | ||
A format used to stringify the parameters passed to the loggers methods. | ||
## License | ||
[MIT](./LICENSE) |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
41841
25
1060
42
6
+ Addedjson-escaping@^1.0.1
+ Addedjson-escaping@1.0.1(transitive)
- Removedasync-each@^1.0.1
- Removedasync-each@1.0.6(transitive)
Updatedfast-date-format@^2.1.2