Is there a way to log every request in the console with restify?
Asked Answered
L

6

18

I'm using restify to build an API, and I'm used to express. Is there a way to have restify log every request in the console, like express does with app.use(express.logger('dev'))?

Lacielacing answered 17/12, 2013 at 5:18 Comment(0)
S
24

Here is a very bare bones Restify/Bunyan example that will log every request:

'use strict';

var Logger = require('bunyan'),
    restify = require('restify'),
    log = new Logger.createLogger({
        name: 'app-name',
        serializers: {
            req: Logger.stdSerializers.req
        }
    }),
    server = restify.createServer({
        name: 'app-name',
        version: '0.1.0',
        log: log
    });

server.pre(function (request, response, next) {
    request.log.info({ req: request }, 'REQUEST');
    next();
});

server.get('/', function (request, response, next) {
    response.send('It worked!');
    next();
});

server.listen(8080, function () {
    console.log('%s listening at %s', server.name, server.url);
});

The key to this is the server.pre() call.

Start it up in one terminal window and do a curl request in another terminal window. You will see the response that it worked, and a log entry for the request.

Assuming a few things:

  • You have a package.json file that will install bunyan and restify
  • You put the code above in a file named server.js

You would do/see the following:

Terminal Window 1

$ node server.js
app-name listening at http://0.0.0.0:8080
{"name":"app-name","hostname":"leeloo.local","pid":97387,"level":30,"req":{"method":"GET","url":"/","headers":{"user-agent":"curl/7.30.0","host":"localhost:8080","accept":"*/*"},"remoteAddress":"127.0.0.1","remotePort":60870},"msg":"REQUEST","time":"2014-04-21T17:55:52.487Z","v":0}

Terminal Window 2

$ curl localhost:8080/
"It worked!"

If anyone would like to see my package.json I can put all of this up in a gist.

Sharpie answered 21/4, 2014 at 18:0 Comment(1)
What if you wanted to edit the contents of request? Eg. if you wanted to remove some insecure information before logging it.Dorene
K
15

You could also use the Morgan logger middleware used in Express. Since Restify intentionally borrows heavily from Express, configure it is exactly the same.

This is how the Usage server example gets:

var restify = require('restify');
var logger  = require('morgan')

var server = restify.createServer({
  name: 'myapp',
  version: '1.0.0'
});

server.use(logger('dev'));
server.use(restify.acceptParser(server.acceptable));
server.use(restify.queryParser());
server.use(restify.bodyParser());

server.get('/echo/:name', function (req, res, next) {
  res.send(req.params);
  return next();
});

server.listen(8080, function () {
  console.log('%s listening at %s', server.name, server.url);
});

Getting like this:

enter image description here

Kowalski answered 9/3, 2016 at 22:5 Comment(0)
P
6

In reference to using RequestLogger, see this comment in the docs:

"This plugin does not log each individual request. Use the Audit Logging plugin or a custom middleware for that use."

Audit Logging (docs)

Audit logging is a special plugin, as you don't use it with .use(), but with the after event:

server.on('after', restify.auditLogger({
  log: bunyan.createLogger({
    name: 'audit',
    stream: process.stdout
  })
}));
Particle answered 8/12, 2015 at 23:33 Comment(1)
This is the way to go IMO. I would just add that you pass the body: true option to the auditLogger so you get to see the body of both the request and response in the logs. Very helpful. server.on('after', restify.auditLogger({ log: log.logger, body: true }));;Squeaky
S
1

There is a quick way to do it very quickly if you just want to have it for your development environment.

/**
 * Log requests.
 */
server.on('after', function(req, res, route, error) {
    console.log("------------------------")
    console.log(req.route.path)
    console.log(req.body)
});
Schatz answered 23/9, 2019 at 13:20 Comment(0)
M
0

By default restify uses Bunyan logger. From restify documentation

RequestLogger Sets up a child bunyan logger with the current request id filled in, along with any other parameters you define.

    server.use(restify.requestLogger({
        properties: {
            foo: 'bar'
        },
        serializers: {...}
    })); 

You can pass in no options to this, in which case only the request id will be appended, and no serializers appended (this is also the most performant); the logger created at server creation time will be used as the parent logger.

Mauricio answered 17/12, 2013 at 10:30 Comment(1)
It didn't seem very straight forward ... I probably missed something but never got to get it working yet. So I switched to express...Lacielacing
S
-5

I wrote something to do this. It's still being developed, but it seems to work so far. npm install restify-dev-logger, then

var logger = require("restify-dev-logger");
var restify = require("restify");
var srv = restify.createServer(...);
srv.use(logger.dev);

Or something like that. There's also logger.devbw, which doesn't have pretty terminal colors.

UPDATE: My package is broken (not sure why), but a workable replacement is here: https://groups.google.com/forum/?hl=en&fromgroups#!topic/restify/iLRiYz3Fko0

Suki answered 21/1, 2014 at 22:46 Comment(3)
Please be far more clear as to what you mean with "Or something like that."Journal
As in "Your code will probably be somewhat different." I really don't see how this is unclear, but ask away if you don't understand.Suki
Ignore this, it's brokenSuki

© 2022 - 2024 — McMap. All rights reserved.