Winston: How to implement java-like MDC for logging contextual information using winston logger.

Created on 28 May 2018  路  6Comments  路  Source: winstonjs/winston

I am using winston - 3.0.0-rc5 with operating system as Windows.

Using winston logger, I have formatted log statement to have timestamp, level and message.

    module.exports = {

    namespace: "",
    nodeID: null,
    logger: bindings => winston.createLogger({
        level: "debug",
        format: winston.format.combine(
            winston.format.timestamp(),
            winston.format.printf(log => {
                return `${log.timestamp} ${log.level} ------ ${log.message}`;
            })
        ),
        transports: [
            new (winston.transports.Console) ({
                    timestamp: true,
                    colorize: true,
                    prettyPrint: true,
            }) /*,
            new fluentTransport('xxx.xxxxxx', {
                host: 'xx.xx.xx.xxx',
                port: 'xxxx',
                timeout: 3.0,
                reconnectInterval: 60000
            })*/
        ]
    }),

On the same line, I need to know the way to implement java-like Mapped Diagnostic Context (MDC) for logging contextual information in a moleculer framework node js microservice using winston logger.
Eg.

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- Log message format -->
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} [%mdc] - %msg%n
            </pattern>
        </encoder>
    </appender>

Any help on this?

question

All 6 comments

Not familiar with Mapped Diagnostic Context, but will leave this open to see if anyone with more Java experience has insights for you. At first glance appears you need a custom format of some kind.

IIRC, MDC uses threadlocal in java, so it might be hard to replicate in js where you typically just have one thread. The best approximation that I've found to this so far is to have a context or metadata object that you pass around, and also pass to your log statement everytime you log. Definitely not as clean, and would be delighted to learn of a better way as well.

You can now use logger.child() for this or provide defaultMeta to the logger. See: https://github.com/winstonjs/winston#creating-child-loggers

This was added in [email protected]. Please let us know if this does not meet your needs.

@indexzero creating child loggers is not solving the issue of sharing a context (which probably varies per request, not per logger). Do you suggest a child logger be created with each change of context ?

@logic-1 Default meta feature is for static data. Child loggers are low-overhead solution that is well-suited for per-request cases.

This is a much-needed feature.
Meanwhile, we followed a similar approach as @breznik suggested. We pass requestMeta object from our controller to service and service to as an argument of every log statement. But this takes your ability to pass an object as a second argument.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Tonacatecuhtli picture Tonacatecuhtli  路  4Comments

greenhat616 picture greenhat616  路  3Comments

Buzut picture Buzut  路  3Comments

JaehyunLee-B2LiNK picture JaehyunLee-B2LiNK  路  3Comments

Nepoxx picture Nepoxx  路  4Comments