loopbackio / loopback-next

LoopBack makes it easy to build modern API applications that require complex integrations.
https://loopback.io
Other
4.95k stars 1.07k forks source link

Logger is not found (@loopback/logging) #6973

Closed emiliobristech closed 3 years ago

emiliobristech commented 3 years ago

Hello! I'm trying to use logging features but I'm stuck because Logger is not found.

Steps to reproduce

1) Followed this documentation: https://loopback.io/doc/en/lb4/Logging.html 2) This is my import statement: import {LoggingBindings, Logger} from '@loopback/logging'; 3) Here is declaration: @inject(LoggingBindings.WINSTON_LOGGER) private logger: Logger;

Current Behavior

Got this error: { "resource": "/d:/DEV_BTC/GIT/application/microservices/servico-vault/src/services/vault.service.ts", "owner": "typescript", "code": "2305", "severity": 8, "message": "Module '\"../../node_modules/@loopback/logging/dist\"' has no exported member 'Logger'.", "source": "ts", "startLineNumber": 2, "startColumn": 26, "endLineNumber": 2, "endColumn": 32 }

Expected Behavior

Be able to use logging features from LB4.

Link to reproduction sandbox

dhmlau commented 3 years ago

@emiliobristech, looks like the code snippet from the docs is not up-to-date. Could you please try to use WinstonLogger instead of Logger in your step#3? (UPDATED: sorry that there was a typo). It's exported as WinstonLogger according to https://github.com/strongloop/loopback-next/blob/master/extensions/logging/src/winston.ts#L24-L29.

emiliobristech commented 3 years ago

Hello, thank you for your help, now it worked but before I had to configure Fluent:

this.configure(LoggingBindings.COMPONENT).to({
  enableFluent: false, // default to true
  enableHttpAccessLog: true, // default to true
});

this.configure(LoggingBindings.FLUENT_SENDER).to({
  host: process.env.FLUENTD_SERVICE_HOST ?? 'localhost',
  port: +(process.env.FLUENTD_SERVICE_PORT_TCP ?? 24224),
  timeout: 3.0,
  reconnectInterval: 600000, // 10 minutes
});

But now, I need to finish Fluentd configuration because I'm getting this error:

Fluentd error Error: connect ECONNREFUSED 127.0.0.1:24224
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16) {
  errno: 'ECONNREFUSED',
  code: 'ECONNREFUSED',
  syscall: 'connect',
  address: '127.0.0.1',
  port: 24224
}

How do I disable Fluentd to log only to filesystem?

When I try to run without Fluentd (removing LoggingBindings.FLUENT_SENDER config), I get this error: Error: Fluent is not configured. Please configure logging.winston.transports.fluent.

Thanks,

achrinza commented 3 years ago

Can you ensure that .configure() is called before .component()?

See #6930

emiliobristech commented 3 years ago

Can you ensure that .configure() is called before .component()?

See #6930

You're right, I changed the order and now it doesn't throw any error but it doesn't log anything to console. I suppose I need to configure this:

import {LoggingBindings} from '@loopback/logging';

ctx.configure<LoggerOptions>(LoggingBindings.WINSTON_LOGGER).to({
  level: 'info',
  format: format.json(),
  defaultMeta: {framework: 'LoopBack'},
});

But, how do I get ctx? And, in this configuration, where does log goes?

Thanks in advance,

raymondfeng commented 3 years ago

@emiliobristech this is the context for Application constrcutor.

I think you need to configure a transport - https://github.com/strongloop/loopback-next/blob/master/extensions/logging/src/winston.ts#L65

emiliobristech commented 3 years ago

@emiliobristech this is the context for Application constrcutor.

I think you need to configure a transport - https://github.com/strongloop/loopback-next/blob/master/extensions/logging/src/winston.ts#L65

Yeah, you're right. This is what I'm trying to figure out how. Here is my code:

this.configure(LoggingBindings.COMPONENT).to({
  enableFluent: false, // default to true
  enableHttpAccessLog: true, // default to true
});

const consoleTransport = new WinstonTransports.Console({
  level: 'info',
  format: format.combine(format.colorize(), format.simple()),
});
this
  .bind('logging.winston.transports.console')
  .to(consoleTransport)
  .apply(extensionFor(WINSTON_TRANSPORT));

this.component(LoggingComponent);

And here is the usage:

  @inject(LoggingBindings.WINSTON_LOGGER)
  private logger: WinstonLogger;

   this.logger.info('Creating new Secret.');

But there is no log in console. What could it be?

Thanks in advance,

dhmlau commented 3 years ago

From my understanding, there's some option you can set in the logger. I found this example: https://github.com/karannagupta/loopback4-express-with-logging/blob/e205a7809f4b7cf59c280d46883272989e426686/src/lib/logger/winstonLogger.ts.

emiliobristech commented 3 years ago

From my understanding, there's some option you can set in the logger. I found this example: https://github.com/karannagupta/loopback4-express-with-logging/blob/e205a7809f4b7cf59c280d46883272989e426686/src/lib/logger/winstonLogger.ts.

You're right but the problem here is that even minimal configuration where log output is in console is not working. According to what I've read and saw in code, this would be enough to output log to console:

this.configure(LoggingBindings.COMPONENT).to({
  enableFluent: false, // default to true
  enableHttpAccessLog: true, // default to true
});

this.configure<LoggerOptions>(LoggingBindings.WINSTON_LOGGER).to({
  level: 'debug',
  format: format.json(),
  defaultMeta: {framework: 'LoopBack'},
  transports: [new Console({
    format: winston.format.simple(),
  })]
});

this.component(LoggingComponent);

But there is no exception neither output message. What is going on? Does LB4 handles console in a specific way?

How others are handling logs? Are they just using console.*?

Thanks,

emiliobristech commented 3 years ago

OK, after researching how to do it in Express I found the solution. I running application through VSCode debug and to output logs in debug console, you must add following parameter to launch.json: "outputCapture": "std". PS: Add as latest parameter of configurations .

Besides, here is the final configuration that worked:

  1. Add this to constructor of application.ts

    this.configure(LoggingBindings.COMPONENT).to({
      enableFluent: false, // default to true
      enableHttpAccessLog: true, // default to true
    });
    
    this.configure<LoggerOptions>(LoggingBindings.WINSTON_LOGGER).to({
      level: 'info',
      format: format.json(),
      defaultMeta: {framework: 'LoopBack'},
    });
    
    this.component(LoggingComponent);
  2. Declare logger where you are going to use it:

     @inject(LoggingBindings.WINSTON_LOGGER)
      private logger: WinstonLogger;