Winston: Attempt to write logs with no transports.

Created on 17 May 2019  路  18Comments  路  Source: winstonjs/winston

Please tell us about your environment:

  • _winston version?_

    • [ ] winston@2

    • [x] winston@3

  • _node -v outputs:_
  • _Operating System? Linux
  • _Language? ES6/7

What is the problem?

Attempt to write logs with no transports on console.

[winston] Attempt to write logs with no transports {"message":"Hey man, I am here!","level":"debug"}
[winston] Attempt to write logs with no transports {"message":"App running on 3000","level":"info"}

What do you expect to happen instead?

Expect to write on console and combined.log and error.log files.

Other information

logger.js

import winston from 'winston'

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  transports: [
    //
    // - Write to all logs with level `info` and below to `combined.log` 
    // - Write all logs error (and below) to `error.log`.
    //
    new winston.transports.File({ filename: 'error.log', level: 'error' }),
    new winston.transports.File({ filename: 'combined.log' }),
    new winston.transports.Console({ format: winston.format.json() })
  ]
})

winston.info('Hey man, I am here!')

export default logger

Usage on index.js

require('./lib/logger.js')
winston.info(`App running on ${port}`)

Obeservation
error and combined.log has permission 777 event through is not the ideal.

Most helpful comment

@lukaswilkeer, Assuming that createLogger doesn't already add the logger/stream to winston, just merely construct the logger.

Based on your code snippet, adding winston.add(logger) after you create your logger should solve the problem.

You could also add more streams, loggers and once you require winston in any part of the application, it should return the configured logger.

All 18 comments

@lukaswilkeer have you found a work around?

Ain't no.

Up.

did you find the solution?

Managed a workaround by attaching the winston logger to the global window object. If you're upgrading from console.log this offers a nice refactor path that allows you to globally search/replace console.log( with logger.info( or logger.log("info",. The following needs to be done in the top most file of your client. Something like main.js. Works in submodules, imported packages, etc. etc. Not ideally functional and might introduce side effects, but seems to be working and at least it replaces console.log.

import { createLogger, format, transports } from 'winston';
import 'setimmediate';

// lets create a global logger
const logger = createLogger({
  level: 'info',
  format: format.json(),
  defaultMeta: { service: 'user-service' },
  transports: [
    new transports.Console({
      level: 'info',
      format: format.combine(
        format.colorize(),
        format.simple()
      )
    })
  ]
});

window.logger = global.logger = logger;

Happy that you encounter a solution to your context. On node setting a global variable doesn't solved my problem.

What is exactly causing this error haven't logged anything too

Sounds like winston are trying to create the transports, but is not created.

@lukaswilkeer, Assuming that createLogger doesn't already add the logger/stream to winston, just merely construct the logger.

Based on your code snippet, adding winston.add(logger) after you create your logger should solve the problem.

You could also add more streams, loggers and once you require winston in any part of the application, it should return the configured logger.

@lkashef in that case works fine, except that the errors doens't get logged on terminal or to the files.
Only a message:

{"level":"error"}
````

PS: The code running the error is a catch block, like:
```js
await promise.catch(winston.error)

@lukaswilkeer if the error doesn't get logged into neither files nor terminals, where do you see the {"level":"error"}? Also without getting much into the specifications, could try logging something basic like winston.error("error", "error message") and winston.info("info", "just info")?

Try it in the same file that you require winston and configure winston the first time, make sure that you are getting the different logs as expected and that the message is showing as expected, the next step if this works, to move the two test log statements to a file that is being executed after winston has been called and configured the first time.

If both tests work then you are good to go and it's just a code problem that would be present anyway using any logging tool including console and it's not winston related.


Here is working snippet, it doesn't even use createLogger and it doesn't need to export the logger.

    if (process.env.LOG_CONSOLE_TRANSPORT === 'true') {
        const myFormat = printf(formatLogMessage);

        winston.add(new transports.Console({
            level: process.env.LOG_CONSOLE_TRANSPORT_LEVEL,
            format: combine(colorize(), myFormat)
        }));
    }
    if(process.env.LOG_FILE_TRANSPORT === 'true') {
        winston.add(new transports.File({
            level: process.env.LOG_FILE_TRANSPORT_LEVEL,
            format: format.json(),
            filename: 'combined.log'
        }));

        winston.add(new transports.File({
            level: process.env.LOG_FILE_TRANSPORT_LEVEL,
            format: format.json(),
            filename: 'combined.log'
        }));    
    }

Using the previous version, with some modifications on name functions, doesn't work.

Winston throws an error on Console transports.

No transform function found on format. Did you create a format instance?.
On that case is for console transport.

Removing it,

Error: Cannot log to file without filename or stream.

Code:

winston.add(new transports.Console({
  level: 'info',
  format: winston.format.combine(winston.format.colorize(), winston.format.json)
}))

winston.add(new transports.File({
  level: 'info',
  format: winston.format.json,
  file: 'combined.log'
}))

winston.add(new transports.File({
  level: 'error',
  format: winston.format.json,
  filename: 'error.log'
}))

@lukaswilkeer

This was just an example for a simple implementation, it was correct to remove the myFormat custom function.

1) Try creating these files manually, it might be a permission issue.

2) For context, this is the important statements, to make sure that you are importing the correct modules for winston and transports.

const winston = require('winston');
const { format, transports} = winston;
const { combine, printf, colorize } = format;

3) Also I am using "winston": "3.2.1", so make sure you have the same version, at least to understand if this is working or not.

4) If non of the above is working, I would suggest you make sure you install the latest winston and follow the official example, then do test and refractor to reach to the current implementation you need, when it breaks from one test to another, you will be able to see where does it break exactly and maybe this will help us figure why it's behaving that way.

  1. It's not a permission issue, actually I give the 777 to combined and error.log to be sure.
  2. Imports are correctly.
  3. Winston is up-to-date.
  4. I'm following the official example.

I created a repro script and winston works correctly. The problem where Uncaught errors inside the application. (Not reported or proper winston error). Don't know the root cause. In this case, winston.add(logger) solved the problem of transports.

Closed issue.

I get this error occasionally on a freshly pulled project, I do a combination of multiple npm i, deleting node modules folder and once I opened up task manager and there were 7 or so node processes running which I killed .

@matale this is not a best pratice to maintain a project on a webhost or vm. You i'll need to ssh every time to clean up the node_modules and this will surprise you, therefore there's no notification about it. If you see it. On dev on i'll see a lot and and will ramble what's the cause.

On that case, the winston.add(logger), solved my problem for a long running application and further projects. This is not an error to see.

@lkashef what solved my issue is that I'm creating transports and not an logger. So, my actual code looks pretty simple from the previous version with a major change.

import winston from 'winston'
import { format } from 'winston'

const loggerFormat = format.combine(
  format.errors({ stack: true }),
  format.timestamp(),
  format.metadata(),
  format.json()
)

const consoleFormat = {
  format: format.combine(
    format.splat(),
    format.simple(),
    format.errors({ stack: true })
  ),
  level: 'info',
  handleExceptions: true,
  json: false,
  colorize: true
}

const logger = winston.createLogger({
  level: 'info',
  format: loggerFormat,
  transports: [
    //
    // - Write to all logs with level `info` and below to `combined.log` 
    // - Write all logs error (and below) to `error.log`.
    //
    new winston.transports.File({ filename: 'error.log', level: 'error' }),
    new winston.transports.File({ filename: 'combined.log' }),
    new winston.transports.Console(consoleFormat)
  ]
})

winston.add(logger)
winston.debug('Hey man, I am here!')

export default logger

For future readers, since I spent too much time on this this morning.

I ran into this error, and at least in my case, it related to my module imports. For context, I am currently working on incrementally converting a CommonJS project to TypeScript (eg ECMAScript module imports).

A formatter was defined in a CommonJS export like so:

// myFormat.js
const { format } = require('winston');
module.exports = { myFormat }

and in the primary logger definition, was defined like so:

// logger.ts
import { format } from 'winston';
import myFormat from './myFormat.js'

I alternately also tried

// logger.ts
import * as winston from 'winston';
const { format } = winston;

and

// logger.ts
import winston from 'winston';
const { format } = winston;

and

// logger.ts
import winston from 'winston';
winston.format.combine(/*etc*/);

I didn't get any of these to work as you would expect.

Note that this wasn't a problem consistently, and I think it ultimately depended on the order in which modules were resolved. I made my problem go away by converting myFormat.js to myFormat.ts

I too wasted two hours on this issue in a TypeScript codebasw without any success.

If anyone manages to fix it please let me know. I tried just Console and just File transports or various combinations of both.

Tries both 3.3.3 and 3.3.2.

Was this page helpful?
0 / 5 - 0 ratings