question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Multiple loggers with same file transporter but with different labels

See original GitHub issue

Hello together,

I have several modules (call them module A and module B) and they should share the same file transporter because I only want one single log file e.g. called somefile.log. Writing the logs to a file is my only transporter. Now I want the content of my log file to look like this:

2017-05-03T06:44:15.300Z - info: [module A] foo
2017-05-03T06:44:15.300Z - info: [module B] bar

I don’t want the JSON style here. Can you please tell me how I can achieve this?

When I define the file transport for each logger but set the filename in both transporters to the same string I get an error that the transport is already defined and I should change the file name:

winston.loggers.add('module A', { file: {
    filename: 'somefile.log',
    level: 'silly',
    label: 'module A',
    maxsize: 8,
    maxFiles: 3,
    json: false,
    prettyPrint: true,
    tailable: true,
    zippedArchive: true,
    handleExceptions: true,
    humanReadableUnhandledException: true,
    exitOnError: false,
  } });
  winston.loggers.add('module B', { file: {
    filename: 'somefile.log',
    level: 'silly',
    label: 'module B',
    maxsize: 8,
    maxFiles: 3,
    json: false,
    prettyPrint: true,
    tailable: true,
    zippedArchive: true,
    handleExceptions: true,
    humanReadableUnhandledException: true,
    exitOnError: false,
  } });

  const moduleAlogger = winston.loggers.get('module A');
  const moduleBlogger = winston.loggers.get('module B');
  moduleAlogger.info('foo');
  moduleBlogger.info('bar');

results in:

2017-05-03T06:49:30.641Z - error: uncaughtException: Transport already attached: file, assign a different name 

I didn’t understand the idea behind the labels per transporter because this would be redundant information when I am not allowed to write to the same file with different labels.

e.g. when I have two file transporters to different files I have in one file

2017-05-03T06:44:15.300Z - info: [module A] foo
2017-05-03T06:44:15.300Z - info: [module A] bar
.....

and in the other

2017-05-03T06:44:15.300Z - info: [module B] foo
2017-05-03T06:44:15.300Z - info: [module B] bar
.....

The label is totally useless here. What haven’t I understood when using labels in file transporters?

Thanks for your help.

Stefan

Issue Analytics

  • State:open
  • Created 6 years ago
  • Reactions:25
  • Comments:5

github_iconTop GitHub Comments

14reactions
omerahacommented, Aug 14, 2019

So I see it is possible, but does winton handle well all the low-level details of multiple file handles writing to the same file? Does it sync to write calls, and make sure data is not overridden?

10reactions
IrisAmpcommented, Jan 1, 2019

Here is the solution I am using with v3.1.0. You can add the label format to the logger, and everything else you need to the transport.

In TypeScript:

import winston = require("winston");
import { resolve } from "path";

class Logger {
  public static getLogger(label: string): winston.Logger {
    if (!winston.loggers.has(label)) {
      winston.loggers.add(label, {
        transports: [Logger.consoleTransport, Logger.fileTransport],
        format: winston.format.label({ label }),
      });
    }
    return winston.loggers.get(label);
  }

  private static logFormatTemplate(i: { level: string, message: string, [key: string]: any }): string {
    return `${i.timestamp} ${i.level} [${i.label}] ${i.message}`;
  }

  private static readonly consoleTransport = new winston.transports.Console({
    format: winston.format.combine(
      winston.format.timestamp(),
      winston.format.cli(),
      winston.format.printf(Logger.logFormatTemplate),
    ),
  });

  private static readonly fileTransport = new winston.transports.File({
    format: winston.format.combine(
      winston.format.timestamp(),
      winston.format.printf(Logger.logFormatTemplate),
    ),
    filename: resolve("./myLogs.log"),
    level: "info"
  });
}

Logger.getLogger("A").info("Message with label: A");
Logger.getLogger("B").info("Message with label: B");

// 2019-01-01T20:20:57.845Z info [A] Message with label: A
// 2019-01-01T20:20:57.847Z info [B] Message with label: B

So you can pretty easily use this in all your different modules:

// ModuleA.ts
import { Logger } from "./Logger";
const log = Logger.getLogger("ModuleA");
log.info("Hello from ModuleA");
// ModuleB.ts
import { Logger } from "./Logger";
const log = Logger.getLogger("ModuleB");
log.info("Hello from ModuleB");
// myLogs.log
2019-01-01T20:35:58.855Z info [ModuleA] Hello from ModuleA
2019-01-01T20:35:58.884Z info [ModuleB] Hello from ModuleB
Read more comments on GitHub >

github_iconTop Results From Across the Web

Can multiple different Winston logger instances share the ...
I have multiple winston loggers (different instances created with createLogger() ), and I'd like all of them to write their logs to the...
Read more >
Complete Winston Logger Guide With Hands-on Examples
With Winston, you can save your logs to multiple destinations (such as ... and a file, you can output logs to several places...
Read more >
Logging with Winston and Node.js - Section.io
Winston allows you to implement multiple logging transports, i.e., a log can be recorded to a file, console, or database. The Logger ......
Read more >
3.2.1 - winston - npm
A multi-transport async logging library for Node.js. ... location (like a database), but all logs output to the console or a local file....
Read more >
Logging Node.js applications with Winston and Log4js
It should support multiple log channels, so that you can send logs to various destinations (console, files, database, etc.).
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found