Search code examples
loopbackjsloopback4

How to add morgan to Loopback 4 RestApplication?


I am simply trying to add morgan to log my http calls. The two methods I have tried are:

  1. Adding it to the MySequence class:
export class MySequence extends MiddlewareSequence {
 async handle(context: RequestContext) {
   const finished = await this.invokeMiddleware(context, [morgan()]);

   if (finished) {
     return;
   }

   await super.handle(context);
 }
}
  1. Adding it before calling the this.sequence(MySequence) in the application.ts file:
export class MyAppApiApplication extends BootMixin(
  ServiceMixin(RepositoryMixin(RestApplication)),
) {
  constructor(options: ApplicationConfig = {}) {
    super(options);

    this.expressMiddleware(
      morgan,
      {},
      {
        injectConfiguration: 'watch',
        key: 'middleware.morgan',
      }
    );
    this.sequence(MySequence);

    ...
}

The first method was working before I updated my loopback dependencies from:

"@loopback/boot": "^2.4.1",
"@loopback/core": "^2.9.3",
"@loopback/repository": "^2.11.0",
"@loopback/rest": "^6.0.0",
"@loopback/rest-explorer": "^2.2.8",
"@loopback/service-proxy": "^2.3.6",

to:

"@loopback/boot": "^3.0.1",
"@loopback/core": "^2.10.1",
"@loopback/repository": "^3.0.1",
"@loopback/rest": "^7.0.1",
"@loopback/rest-explorer": "^3.0.1",
"@loopback/service-proxy": "^3.0.1",

The update clearly did something that made it stop working but I can't figure out what.

Also, I have seen other methods in the docs like the one using Interceptors but it feels like an overkill when it should be something as easy as adding a middleware to an Express app.


Solution

  • I have used Raymond's example but had to remove the stream.write function from the config object to make it work. Using the example as is I could see the middleware was being registered but still could not see Morgan's logs.

    Just left the defaultConfig object empty:

    private setupLogging() {
        const morganFactory = (config?: morgan.Options<Request, Response>) => {
          this.debug('Morgan configuration', config);
          return morgan('combined', config);
        };
    
        const defaultConfig: morgan.Options<Request, Response> = {};
    
        this.expressMiddleware(morganFactory, defaultConfig, {
          injectConfiguration: 'watch',
          key: 'middleware.morgan',
        });
    }