Categories
JavaScript Nodejs

Add Logging to a Koa App with koa-logger

Spread the love

Koa doesn’t come with any logger built-in. Therefore, to see what’s happening with our app, we’ve to log them with a 3rd party logger.

One logger that’s compatible with the Koa framework is the koa-logger package.

Getting Started

To install it, we just run:

npm install koa-logger

and then we can use it by writing:

const logger = require('koa-logger')
const Koa = require('koa')

const app = new Koa()
app.use(logger())

app.use(async ctx => {
  ctx.body = 'Hello World';
});

app.listen(3000);

All we did is to call use with the return value of the logger middleware passed in, then we get logging automatically.

Now when we start our app, we some output logged.

If we run the code above, we get the following output:

Server {
  insecureHTTPParser: undefined,
  _events: [Object: null prototype] {
    request: [Function: handleRequest],
    connection: [Function: connectionListener]
  },
  _eventsCount: 2,
  _maxListeners: undefined,
  _connections: 0,
  _handle: TCP {
    reading: false,
    onconnection: [Function: onconnection],
    [Symbol(owner)]: [Circular]
  },
  _usingWorkers: false,
  _workers: [],
  _unref: false,
Hint: hit control+c anytime to enter REPL.
Server {
  insecureHTTPParser: undefined,
  _events: [Object: null prototype] {
    request: [Function: handleRequest],
    connection: [Function: connectionListener]
  },
  _eventsCount: 2,
  _maxListeners: undefined,
  _connections: 0,
  _handle: TCP {
    reading: false,
    onconnection: [Function: onconnection],
    [Symbol(owner)]: [Circular]
  },
  _usingWorkers: false,
  _workers: [],
  _unref: false,
  allowHalfOpen: true,
  pauseOnConnect: false,
  httpAllowHalfOpen: false,
  timeout: 120000,
  keepAliveTimeout: 5000,
  maxHeadersCount: null,
  headersTimeout: 40000,
  _connectionKey: '6::::3000',
  [Symbol(IncomingMessage)]: [Function: IncomingMessage],
  [Symbol(ServerResponse)]: [Function: ServerResponse],
  [Symbol(kCapture)]: false,
  [Symbol(asyncId)]: 6
}
  <-- GET / [
Hint: hit control+c anytime to enter REPL.
Server {
  insecureHTTPParser: undefined,
  _events: [Object: null prototype] {
    request: [Function: handleRequest],
    connection: [Function: connectionListener]
  },
  _eventsCount: 2,
  _maxListeners: undefined,
  _connections: 0,
  _handle: TCP {
    reading: false,
    onconnection: [Function: onconnection],
    [Symbol(owner)]: [Circular]
  },
  _usingWorkers: false,
  _workers: [],
  _unref: false,
  allowHalfOpen: true,
  pauseOnConnect: false,
  httpAllowHalfOpen: false,
  timeout: 120000,
  keepAliveTimeout: 5000,
  maxHeadersCount: null,
  headersTimeout: 40000,
  _connectionKey: '6::::3000',
  [Symbol(IncomingMessage)]: [Function: IncomingMessage],
  [Symbol(ServerResponse)]: [Function: ServerResponse],
  [Symbol(kCapture)]: false,
  [Symbol(asyncId)]: 6
}
  <-- GET /
  --> GET / 200 8ms 11b

Custom Logging

The logger middleware function can take an optional callback as an argument.

The callback has the str parameter with the logging output as a string.

args has extra information about the request that’s made, including response time and the size of the response.

We can customize the logging by writing:

const logger = require('koa-logger')
const Koa = require('koa')

const app = new Koa()
app.use(logger((str, args) => {
  console.log(str, args);
}))

app.use(async ctx => {
  ctx.body = 'Hello World';
});

app.listen(3000);

We have the callback:

(str, args) => {
  console.log(str, args);
}

Instead of nothing that we have in the previous example.

The result of this change is the following output:

Server {
  insecureHTTPParser: undefined,
  _events: [Object: null prototype] {
    request: [Function: handleRequest],
    connection: [Function: connectionListener]
  },
  _eventsCount: 2,
  _maxListeners: undefined,
  _connections: 0,
  _handle: TCP {
    reading: false,
    onconnection: [Function: onconnection],
    [Symbol(owner)]: [Circular]
  },
  _usingWorkers: false,
  _workers: [],
  _unref: false,
  allowHalfOpen: true,
  pauseOnConnect: false,
  httpAllowHalfOpen: false,
  timeout: 120000,
  keepAliveTimeout: 5000,
  maxHeadersCount: null,
  headersTimeout: 40000,
  _connectionKey: '6::::3000',
  [Symbol(IncomingMessage)]: [Function: IncomingMessage],
  [Symbol(ServerResponse)]: [Function: ServerResponse],
  [Symbol(kCapture)]: false,
  [Symbol(asyncId)]: 6
}
  <-- GET / [
  '  \u001b[90m<--\u001b[39m \u001b[1m%s\u001b[22m \u001b[90m%s\u001b[39m',
  'GET',
  '/'
]
  --> GET / 200 13ms 11b [
  '  \u001b[90m-->\u001b[39m \u001b[1m%s\u001b[22m \u001b[90m%s\u001b[39m \u001b[32m%s\u001b[39m \u001b[90m%s\u001b[39m \u001b[90m%s\u001b[39m',
  'GET',
  '/',
  200,
  '13ms',
  '11b'
]

We get extra information from the args object.

Alternatively, we can pass in an object with the transporter property to logger:

app.use(logger({
  transporter: (str, args) => {
    // ...
  }
}))

We can add logging to a Koa app with the koa-logger package, which is very simple to use.

With this, we don’t have to create our own logging solution.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *