Skip to content

Commit

Permalink
Fixing metadata storing (#219)
Browse files Browse the repository at this point in the history
* adding dotenv

* fixing declaration

* fixing meta key

* rollback dts change

* fixing saving meta data

* filtering empty objects

* Update README.md

* fixing variable def

* accepting label from log entry

* label handled on transport level only
  • Loading branch information
sovcik authored Jul 10, 2023
1 parent 83f8d9c commit 9d81162
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 49 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules
npm-debug.log
.idea
.env
100 changes: 55 additions & 45 deletions README.md
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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.<br/>Defaults to `{poolSize: 2, autoReconnect: true, useNewUrlParser: true}`). |
| collection | The name of the collection you want to store log messages in.<br/>Defaults to `log`. |
| level | Level of messages that this transport should log.<br/>Defaults to `info`. |
| silent | Boolean flag indicating whether to suppress output.<br/>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.<br/>Defaults to `false`. |
| cappedSize | Size of logs capped collection in bytes.<br/>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.<br/>Defaults to `false`. |
| decolorize | Will remove color attributes from the log entry message.<br/>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.<br/>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.
Expand Down
2 changes: 1 addition & 1 deletion lib/winston-mongodb.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<any>)}
* @type {(string | Promise<object>)}
* @memberof MongoDBConnectionOptions
*/
db: string | Promise<any>;
Expand Down
14 changes: 11 additions & 3 deletions lib/winston-mongodb.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
19 changes: 19 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
1 change: 1 addition & 0 deletions test/winston-mongodb-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* @author [email protected] (Yurij Mikhalevich)
*/
'use strict';
require('dotenv').config();
const mongodb = require('mongodb');
const mongoose = require('mongoose');
const test_suite = require('abstract-winston-transport');
Expand Down

0 comments on commit 9d81162

Please sign in to comment.