Search code examples
node.jsdatadog

NodeJS not posting POST body to DataDog logs


I'm trying to integrate DataDog with my NodeJS/Express application, however it appears that when a POST request is sent to my app the body of the POST is not being passed along to datadog, how can I fix this?

I have a file called Winston.js which looks like so:

let appRoot = require('app-root-path');
let winston = require('winston');

// define the custom settings for each transport (file, console)
let options = {
    file: {
        level: 'info',
        filename: `${appRoot}/logs/app.log`,
        handleExceptions: true,
        json: true,
        maxsize: 52428800,
    },
    console: {
        level: 'debug',
        handleExceptions: true,
        json: false,
        colorize: true,
    },
};

// instantiate a new Winston Logger with the settings defined above
let logger = winston.createLogger({
    transports: [
        new winston.transports.File(options.file),
        new winston.transports.Console(options.console)
    ],
    exitOnError: false, // do not exit on handled exceptions
});

// create a stream object with a 'write' function that will be used by `morgan`
logger.stream = {
    write: function(message, encoding) {
        // use the 'info' log level so the output will be picked up by both transports (file and console)
        logger.info(message);
    },
};

module.exports = logger;

And then I'm attaching them to my app using the following:

app.use(morgan('combined', { stream: winston.stream }));

Currently my logs in DataDog look like this: enter image description here


Solution

  • It looks from the above snippets that the combined Morgan format is sent directly sent to Winston, and then parsed within a log pipeline in Datadog. Since the combined format doesn't include the body and there is no built-in token for it, you would have to use a custom format with your own tokens and then update your pipeline accordingly.

    For example, to create a custom format in Morgan that includes the status code and the body:

    morgan((tokens, req, res) => [
      tokens.status(req, res),
      req.body // assuming body-parser middleware is used
    ].join(' '))
    

    You can also create a token to achieve the same result with a simpler format definition:

    morgan.token('body', (req, res) => req.body
    morgan(':status :body')
    

    You can find the documentation for custom Morgan formats here, creating tokens here, and Datadog log pipeline parsing here.

    Hope this helps!