Integrating Dapr JS SDK logging into NestJS
When we are working with a framework, we want to be able to pipe as much logging as we can to this framework. This ensures that we can process the logging without having to do much customization later on.
While working with the Dapr JS SDK, logging is implemented for us through a default service. Luckily however, we are able to adapt this logging implementation such that we can integrate it in the Nest.js framework its logging.
Creating a Dapr Module
First in nestjs we should create a Dapr Module. For this create a folder that looks like the below:
dapr/
dapr.logger.ts
dapr.module.ts
dapr.service.ts
Next, open the dapr.module.ts
file and add the module code
import { Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";
import { DaprService } from "./dapr.service";
@Module({
// List of imported modules
imports: [ ConfigModule ],
// List of controllers
controllers: [ ],
// Providers that will be instantiated by the Nest injector and that may be shared at least across this module
providers: [ DaprService ],
// which providers can be used in other modules?
exports: [ DaprService ]
})
export class DaprModule {}
And configure our app.module.ts
to utilize the module
import {
Module,
} from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import configuration from '../config/config';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { DaprModule } from './dapr/dapr.module';
@Module({
imports: [
ConfigModule.forRoot({
load: [configuration],
}),
DaprModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Implementing the Dapr Logger into Nestjs
As shown on the Dapr documentation we can integrate a logger by implementing the logger interface and passing it to the Dapr Client.
So in our dapr.logger.ts
file we can write
import { Logger } from '@nestjs/common';
import { LoggerService } from '@dapr/dapr';
export class DaprLogger implements LoggerService {
private readonly logger = new Logger(DaprLogger.name);
constructor() {}
error(message: any, ...optionalParams: any[]): void {
this.logger.error(message, ...optionalParams);
}
warn(message: any, ...optionalParams: any[]): void {
this.logger.warn(message, ...optionalParams);
}
info(message: any, ...optionalParams: any[]): void {
this.logger.log(message, ...optionalParams);
}
verbose(message: any, ...optionalParams: any[]): void {
this.logger.verbose(message, ...optionalParams);
}
debug(message: any, ...optionalParams: any[]): void {
this.logger.debug(message, ...optionalParams);
}
}
Which very easily implements each method and utilizes the @nestjs/common
logger to pipe its messages.
Configuring the Dapr JS SDK with the Logger
Finally, since we have a Logger implemented, we can now start up the Dapr Client with the implemented logger. Open up dapr.service.ts
and add the following code:
import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { DaprClient, CommunicationProtocolEnum, LogLevel } from '@dapr/dapr';
import { DaprLogger } from './dapr.logger';
@Injectable()
export class DaprService {
daprClient: DaprClient;
private readonly logger = new Logger(DaprService.name);
constructor(private readonly configService: ConfigService) {
const daprHost = this.configService.get<string>('third_party.dapr.host');
const daprPort = this.configService.get<string>('third_party.dapr.port');
this.logger.log(`Initializing DaprClient("${daprHost}", ${daprPort})`);
this.daprClient = new DaprClient(
daprHost,
daprPort,
CommunicationProtocolEnum.HTTP,
{
logger: {
level: LogLevel.Verbose,
service: new DaprLogger(),
},
},
);
}
}
The above will load the Dapr sidecar connection details and start a client using our custom logger
Summary
When we now start up our application, we will see the following
Show how beautiful the Dapr JS SDK has been integrated in Nest.js. All of this, taking just 5 minutes.
Member discussion