diff --git a/.gitignore b/.gitignore index 05ade97..8f32610 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules npm-debug.log .idea +.env diff --git a/README.md b/README.md index 3353bb7..f7fa8ee 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -# winston +# winston-mongodb A MongoDB transport for [winston][0]. -Current version supports only mongodb driver version 3.x and winston 3.x. If you want to use -winston-mongodb with mongodb version 1.4.x use winston-mongodb <1.x. For mongodb 2.x use -winston-mongodb <3.x. +Current version supports only mongodb driver version 3.x and newer and winston 3.x and newer. +If you want to use winston-mongodb with mongodb version 1.4.x use winston-mongodb <1.x. +For mongodb 2.x use winston-mongodb <3.x. ## Motivation `tldr;?`: To break the [winston][0] codebase into small modules that work @@ -17,51 +17,61 @@ and a File is overkill. ## Usage ``` js - var winston = require('winston'); +const winston = require('winston'); +// Requiring `winston-mongodb` will expose winston.transports.MongoDB` +require('winston-mongodb'); - /** - * Requiring `winston-mongodb` will expose - * `winston.transports.MongoDB` - */ - require('winston-mongodb'); +const log = winston.createLogger({ + level: 'info', + transports: [ + // write errors to console too + new winston.transports.Console({format: winston.format.simple(), level:'error'}) + ], +}); + +// logging to console so far +log.info('Connecting to database...'); + +const MongoClient = require('mongodb').MongoClient; +const url = "mongodb://localhost:27017/mydb"; + +const client = new MongoClient(url); +await client.connect(); + +const transportOptions = { + db: await Promise.resolve(client), + collection: 'log' +}; + +log.add(new winston.transports.MongoDB(transportOptions)); + +// following entry should appear in log collection and will contain +// metadata JSON-property containing url field +log.info('Connected to database.',{url}); - winston.add(new winston.transports.MongoDB(options)); ``` -The MongoDB transport takes the following options. 'db' is required: - -* __level:__ Level of messages that this transport should log, defaults to -'info'. -* __silent:__ Boolean flag indicating whether to suppress output, defaults to -false. -* __db:__ MongoDB connection uri, pre-connected `MongoClient` object or promise -which resolves to a pre-connected `MongoClient` object. -* __dbName:__ The database name to connect to, defaults to DB name based on -connection URI if not provided, ignored if using a pre-connected mongoose connection. -* __options:__ MongoDB connection parameters (optional, defaults to -`{poolSize: 2, autoReconnect: true, useNewUrlParser: true}`). -* __collection__: The name of the collection you want to store log messages in, -defaults to 'log'. -* __storeHost:__ Boolean indicating if you want to store machine hostname in -logs entry, if set to true it populates MongoDB entry with 'hostname' field, -which stores os.hostname() value. -* __label:__ Label stored with entry object if defined. -* __name:__ Transport instance identifier. Useful if you need to create multiple -MongoDB transports. -* __capped:__ In case this property is true, winston-mongodb will try to create -new log collection as capped, defaults to false. -* __cappedSize:__ Size of logs capped collection in bytes, defaults to 10000000. -* __cappedMax:__ Size of logs capped collection in number of documents. -* __tryReconnect:__ Will try to reconnect to the database in case of fail during -initialization. Works only if __db__ is a string. Defaults to false. -* __decolorize:__ Will remove color attributes from the log entry message, -defaults to false. -* __leaveConnectionOpen:__ Will leave MongoClient connected after transport shut down. -* __metaKey:__ Configure which key is used to store metadata in the logged info object. -Defaults to `'metadata'` to remain compatible with the [metadata format](https://github.com/winstonjs/logform/blob/master/examples/metadata.js) -* __expireAfterSeconds:__ Seconds before the entry is removed. Works only if __capped__ is not set. - -*Metadata:* Logged as a native JSON object in 'meta' property. +The MongoDB transport takes the following options. Only option `db` is required: + +| Option | Description | +| ------ | :----------------------------------------------- | +| db | **REQUIRED**. MongoDB connection uri, pre-connected `MongoClient` object or promise which resolves to a pre-connected `MongoClient` object. | +| dbname | The database name to connect to, defaults to DB name based on connection URI if not provided, ignored if using a pre-connected connection. | +| options| MongoDB connection parameters.
Defaults to `{poolSize: 2, autoReconnect: true, useNewUrlParser: true}`). | +| collection | The name of the collection you want to store log messages in.
Defaults to `log`. | +| level | Level of messages that this transport should log.
Defaults to `info`. | +| silent | Boolean flag indicating whether to suppress output.
Defaults to `false`. | +| storeHost | Boolean indicating if you want to store machine hostname in logs entry, if set to true it populates MongoDB entry with 'hostname' field, which stores os.hostname() value. | +| label | If set to true, then label attribute content will be stored in `label` field, if detected in meta-data. | +| name | Transport instance identifier. Useful if you need to create multiple MongoDB transports. | +| capped | In case this property is true, winston-mongodb will try to create new log collection as capped.
Defaults to `false`. | +| cappedSize | Size of logs capped collection in bytes.
Defaults to 10,000,000. | +| cappedMax | Size of logs capped collection in number of documents. | +| tryReconnect | Will try to reconnect to the database in case of fail during initialization. Works only if __db__ is a string.
Defaults to `false`. | +| decolorize | Will remove color attributes from the log entry message.
Defaults to `false`. | +| leaveConnectionOpen| Will leave MongoClient connected after transport shuts down. | +| metaKey | Configure name of the field which is used to store metadata in the logged info object.
Defaults to `metadata` to remain compatible with the [metadata format](https://github.com/winstonjs/logform/blob/master/examples/metadata.js) | +| expireAfterSeconds |Seconds before the entry is removed. Works only if __capped__ is not set. | *Logging unhandled exceptions:* For logging unhandled exceptions specify winston-mongodb as `handleExceptions` logger according to winston documentation. diff --git a/lib/winston-mongodb.d.ts b/lib/winston-mongodb.d.ts index 4679f04..039966d 100644 --- a/lib/winston-mongodb.d.ts +++ b/lib/winston-mongodb.d.ts @@ -46,7 +46,7 @@ declare module 'winston-mongodb' { /** * MongoDB connection uri, pre-connected db object or promise object which will be resolved with pre-connected db object. * - * @type {(string | Promise)} + * @type {(string | Promise)} * @memberof MongoDBConnectionOptions */ db: string | Promise; diff --git a/lib/winston-mongodb.js b/lib/winston-mongodb.js index 0effeab..4b195bc 100644 --- a/lib/winston-mongodb.js +++ b/lib/winston-mongodb.js @@ -217,12 +217,20 @@ MongoDB.prototype.log = function(info, cb) { } const decolorizeRegex = new RegExp(/\u001b\[[0-9]{1,2}m/g); let entry = { timestamp: new Date(), level: (this.decolorize) ? info.level.replace(decolorizeRegex, '') : info.level }; - let message = util.format(info.message, ...(info.splat || [])); - entry.message = (this.decolorize) ? message.replace(decolorizeRegex, '') : message; - entry.meta = helpers.prepareMetaData(info[this.metaKey]); + let msg = util.format(info.message, ...(info.splat || [])); + entry.message = (this.decolorize) ? msg.replace(decolorizeRegex, '') : msg; + // get 'meta' object from info object - as per winston doc: Properties besides level and message are considered as "meta". + const {level, message, ...meta} = info; + // prepare meta object for storage + const metaData = helpers.prepareMetaData(meta); + // if metadata is not empty object add it to entry - makes no sense to store empty object + if (Object.keys(metaData).length > 0) { + entry[this.metaKey] = metaData; + } if (this.storeHost) { entry.hostname = this.hostname; } + if (this.label) { entry.label = this.label; } diff --git a/package-lock.json b/package-lock.json index 67f3c47..6e0fd77 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ }, "devDependencies": { "abstract-winston-transport": "~0.5.1", + "dotenv": "^16.1.4", "mocha": "^10.2.0", "mongoose": "^5.10.5", "winston": "^3.3.3" @@ -427,6 +428,18 @@ "node": ">=0.3.1" } }, + "node_modules/dotenv": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.1.4.tgz", + "integrity": "sha512-m55RtE8AsPeJBpOIFKihEmqUcoVncQIwo7x9U8ZwLEZw9ZpXboz2c+rvog+jUaJvVrZ5kBOeYQBX5+8Aa/OZQw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" + } + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -1828,6 +1841,12 @@ "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, + "dotenv": { + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.1.4.tgz", + "integrity": "sha512-m55RtE8AsPeJBpOIFKihEmqUcoVncQIwo7x9U8ZwLEZw9ZpXboz2c+rvog+jUaJvVrZ5kBOeYQBX5+8Aa/OZQw==", + "dev": true + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", diff --git a/package.json b/package.json index 2b85bff..0b1e175 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ }, "devDependencies": { "abstract-winston-transport": "~0.5.1", + "dotenv": "^16.1.4", "mocha": "^10.2.0", "mongoose": "^5.10.5", "winston": "^3.3.3" diff --git a/test/winston-mongodb-test.js b/test/winston-mongodb-test.js index 51f74ce..44d281e 100644 --- a/test/winston-mongodb-test.js +++ b/test/winston-mongodb-test.js @@ -6,6 +6,7 @@ * @author 0@39.yt (Yurij Mikhalevich) */ 'use strict'; +require('dotenv').config(); const mongodb = require('mongodb'); const mongoose = require('mongoose'); const test_suite = require('abstract-winston-transport');