Giter VIP home page Giter VIP logo

express-winston-middleware's Introduction

Winston Middleware for Express

Winston log wrappers and middleware for Express.

Usage

You can install express-winston-middleware using NPM:

$ npm install express-winston-middleware

From there, you can create a Log instance or use the request Express middleware.

Examples

See the examples directory for some basic use cases.

Logger

The Log logger class internally creates and wraps a Winston logger. You can create one with:

var winston = require("winston");
var Log = require("express-winston-middleware").Log;

// Create logger with Console transport and "foo" metadata item.
var log = new Log({
  transports: [
    new (winston.transports.Console)({ json: true })
  ]
}, {
  // Metadata to add to each log response.
  foo: "bar"
});

// Log something.
log.info("Hello World!");

which produces the following output:

{
  "date": "2013-12-01T23:29:48.035Z",
  "env": "development",
  "server": {
    "id": "m",
    "pid": 24638,
    "hostName": "titan.local"
  },
  "foo": "bar",
  "level": "info",
  "message": "Hello World!"
}

Express Middleware

The request middleware is added to your Express setup like:

var express = require("express");
var app = express(),
var winMid = require("express-winston-middleware");

/* ... */

// Same options and meta as for the `Log` class.
app.use(new winMid.request({
  transports: [
    new (winston.transports.Console)({ json: true })
  ]
}, {
  // Metadata to add to each log response.
  foo: "bar"
})));

and produces output for requests like:

{
  "date": "2013-12-01T23:32:54.759Z",
  "server": {
    "id": "m",
    "pid": 24653,
    "hostName": "titan.local"
  },
  "req": {
    "method": "GET",
    "host": "localhost:2000",
    "path": "/",
    "query": ""
  },
  "res": {
    "statusCode": 304
  },
  "foo": "bar",
  "level": "info",
  "message": "request"
}

The middleware attaches a logger to the response locals, available as res.locals._log, so that in addition to automatic request logging messages you can log extra messages with all of the current request metadata. E.g.:

app.get("/foo", function (req, res) {
  res.locals._log.info("This is an extra manual log message!", {
    extra: "metadata"
  });
  // Rest of your code here...
});

API

request(opts, baseMeta) - Express request middleware

Creates a middleware function using base metadata. Integration:

app.use(winMid.request({
  transports: [ new (winston.transports.Console)({ json: true }) ]
}, { foo: "bar" }));

Once integrated, a logger will be attached to the response locals, and available as res.locals._log. The logger will then be removed at the end of the request.

error(opts, baseMeta) - Express error middleware

Creates a middleware function for Express. Integration:

app.use(winMid.error({
  transports: [ new (winston.transports.Console)({ json: true }) ]
}, { foo: "bar" }));

uncaught(opts, baseMeta) - Global uncaught exception handler

Creates a handler function for any uncaught exception. Integration:

process.on("uncaughtException", winMid.uncaught({
  transports: [ new (winston.transports.Console)({ json: true }) ]
}, { foo: "bar" }));

Note: Terminates process at end.

Log(opts, baseMeta) - Logger class.

Wraps Winston logger with additional functionality.

var log = new winMid.Log({
  transports: [ new (winston.transports.Console)({ json: true }) ]
}, { foo: "bar" }));

Log.addMeta(meta)

Add arbitrary meta to all subsequent log statements.

Log.addReq(req)

Add request to meta.

Log.transformMeta(fn)

Set a delayed single transform function to mutate a copy of the metadata right before a logging event. You can only presently have one such function. And it is delayed so that for things like request end, you can effectively access all the metadata.

The transform is applied on each log call and passes a copy of the mutated metadata to the actual log call.

The function signature should be fn(existingMeta) and return mutated metadata.

Log.addRes(res)

Add response to meta.

Log.addError(err)

Add error to meta.

Contributions

Please see the Contributions Guide for how to help out with the plugin.

We test all changes with Travis CI. Here's our current build status:

Build Status

Licenses

All code is 2013-2016 Formidable Labs. Released under the MIT License.

express-winston-middleware's People

Contributors

ryan-roemer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

Forkers

zianwar cled

express-winston-middleware's Issues

wish: actually show the middleware in action

It would be helpful to show an actual example syntax of calling Winston through the Express middleware.

The docs get as far as saying that the logger will be attached to res.local._log.

So, I would call res.local._log.info("foo") wherever I wanted to log in my Express app?

It could also be useful to add a section explaining when one might use this over another solution.

In a very a simple app, console.log might do, and a more complex app might have layers, all of which don't have access to the res object. It would be helpful to better understand the use-case for this option.

BUG: Request logger instances hit maxListeners when highly concurrent.

May I'm wrong, but I would recommend to Review the lines arround 70 in the index.js file. If I'm not wrong, there is a bug that creates always a new loginstance on every request.

My proposal would be something with a singleton pattern.
Just an idea. inside of the request: function (opts, baseMeta) {

var staticLog;

return function (req, res, next) {
  // Create logger and attach to locals.
  if (staticLog == null) {
    staticLog =  new Log(opts, baseMeta);
  }

  var log = res.locals._log = staticLog;
  var _end = res.end;

// Add request

Problems trying to add additional request headers

I'm trying to add to our request logging the size of the request and the amount of time the request took. Our current logs look like this:

21:08:05 wedgies-api-staging-34 | GET /question/_id/123456 200 9ms - 5.1kb

I'm trying to add the last 2 sections (the 9ms and 5.1kb). I tried doing it like this to add the whole request:

var Log = require("express-winston-middleware").Log;
var log = new Log({
  transports: [
    new (winston.transports.Console)({ json: true })
  ]
});
var winMid = require("express-winston-middleware");
// Cut express stuff
 app.use(new winMid.request({
   transports: [
     new (winston.transports.Console)({ json: true })
   ]
 }));
 // Hoping this adds the whole request (which I don't want, I just want to add time and size)
// But this doesn't add anything either
log.addReq(req);

But that obviously won't work since it's not part of the request logging.

I assume there's a way to do it, but I don't understand the docs for this.

Add unit tests.

Lots of skeleton pending unit tests that need implementations.

404 crashes with a simple express app

I ran into an error when I accidentally typo-ed a URL.

The error is like so:

/Users/slooker/code/winston-test/node_modules/express-winston-middleware/index.js:263
      return this._log[level].apply(this._log, args);
                             ^
TypeError: Cannot read property 'apply' of undefined
    at self.(anonymous function) [as warning] (/Users/slooker/code/winston-test/node_modules/express-winston-middleware/index.js:263:30)
    at ServerResponse.res.end (/Users/slooker/code/winston-test/node_modules/express-winston-middleware/index.js:103:31)
    at Array.write (/Users/slooker/code/winston-test/node_modules/express/node_modules/finalhandler/index.js:137:9)
    at listener (/Users/slooker/code/winston-test/node_modules/express/node_modules/on-finished/index.js:169:15)
    at onFinish (/Users/slooker/code/winston-test/node_modules/express/node_modules/on-finished/index.js:100:5)
    at callback (/Users/slooker/code/winston-test/node_modules/express/node_modules/on-finished/node_modules/ee-first/index.js:55:10)
    at IncomingMessage.onevent (/Users/slooker/code/winston-test/node_modules/express/node_modules/on-finished/node_modules/ee-first/index.js:93:5)
    at IncomingMessage.emit (events.js:104:17)
    at _stream_readable.js:908:16
    at process._tickCallback (node.js:355:11)

I have a super simple demo that I put up on github that you can clone and see the demo if you hit any url OTHER than /

https://github.com/slooker/express-winston-middleware-error

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.