API with NestJS #113. Logging with Prisma

JavaScript NestJS

This entry is part 113 of 121 in the API with NestJS

Using a debugger with an application running locally on our machine is a great way to troubleshoot. Unfortunately, we can’t do that with a deployed app. To be able to investigate any potential issues, we need to implement a logging functionality. In this article, we use the logger built into NestJS and integrate it with Prisma.

Logger provided by NestJS

Fortunately, NestJS provides logging functionalities that we can use. One of its crucial concepts is the log level. Sorted by severity, those are the log levels we can choose:

  1. error
  2. warn
  3. log
  4. debug
  5. verbose

Recently, the debug and verbose log levels switched places with this pull request.

To use them, we need to take advantage of the class. The most straightforward way of using it is simply importing it from the library.

posts.service.ts

While the above approach works, the official documentation suggests creating an instance of the logger inside each class that uses it.

posts.service.ts

Thanks to the above adjustment, NestJS prints the name of our service in square brackets. This makes our logs a lot easier to read.

Dealing with log levels

As mentioned before, the logs we produce are grouped by severity and assigned a log level. The more severe a particular log is, the more alarmed we should be. For example, a user trying to access a post that does not exist is probably not a reason to wake the development team at night. Because of that, we use the “warn” level instead of the “error”.

We can filter out certain levels to avoid cluttering our logs. One way of doing that is to disregard some of the logs in the production environment to see the potential issues more clearly.

main.ts

A thing that my surprise you is that providing turns on all log levels. Taking a look at the isLogLevelEnabled function reveals that NestJS searches for the highest severity included in the array and turns on the logs with the lower severity too. For the sake of readability, we provide the complete array.

Creating a logging interceptor

While manually covering all cases with logs can produce the best results, it can be pretty demanding. A good alternative is writing a NestJS interceptor that covers a particular endpoint with various logs.

logging.interceptor.ts

Above, we get the information about a particular HTTP request and wait for it to finish. Finally, we base the log level on the response’s status code.

There are a few ways to use our interceptor. First, we can decorate a particular method with it.

posts.controller.ts

Alternatively, we can use it to decorate the entire controller.

posts.controller.ts

Finally, we can use the method to apply the interceptor to all our controllers.

main.ts

Feel free to add more data into the above logs if you need, such as the POST request body.

Logging SQL queries with Prisma

Logging SQL queries that happen in our application can help us investigate what happens under the hood of Prisma and notice eventual bottlenecks. Fortunately, Prisma has logging functionalities built-in. To use them, let’s modify our .

prisma.service.ts

The downside of the above approach is that the logs produced by Prisma look different than those created by NestJS. We can deal with this problem using the built-in logger from NestJS with Prisma.

By default, Prisma prints the logs to the standard output. Instead, we can ask it to emit events whenever Prisma logs something by passing with the particular log level.

prisma.service.ts

An important thing above is that we are passing additional arguments to the generic type. To be able to subscribe to the , , , and event, we need to explicitly let TypeScript know that such events might be emitted using type.

Once we do the above, we can subscribe to the events.

Watch out, because there is an open issue right now on GitHub that indicates that there might be some issue with emitting the event.

Thanks to this approach, we can see the SQL queries logged using the NestJS logger.

Summary

In this article, we’ve gone through using the logger built into NestJS. We’ve covered using it both manually and through a custom interceptor that logs various messages automatically. On top of that, we learned how logging works with Prisma and how to incorporate the NestJS logger into it.

With a comprehensive approach to logging, we can have a much easier type investigating a problem in our application. Therefore, it is definitely worth learning and including in our stack.

Series Navigation<< API with NestJS #112. Serializing the response with PrismaAPI with NestJS #114. Modifying data using PUT and PATCH methods with Prisma >>
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments