Node.js ORM written in TypeScript for type lovers.

View the Project on GitHub twinlogix/typetta

Logging

The possibility of having an accurate logging system is a very important feature for a library that manages the data access layer. Thanks to the logs, it is possible to investigate any correctness issues in the construction of the queries sent to the data source or regarding performance.

How to enable Logs

You can enable logging simply by setting the log: true parameter when creating the EntityManager.

new EntityManager({
  log: true,
})

Alternatively, you can specify which log levels should be enabled among those provided by the system: debug, query, warning and error. Note that the query level is the level at which the SQL and MongoDB queries that run on the respective databases are logged.

To explicitly specify the enabled levels, you must set an array in the log parameter:

new EntityManager({
  log: ['warning', 'error'],
})

The logs produced by the system have the following form:

[2022-01-30T14:44:40.120Z] (dao: user, op: findAll, driver: mongo): collection.find({}) [3 ms]

In this example, we see the log of a query containing:

Log long-running queries

If there are performance problems or there is simply the need to perform an analysis on the data access times, it is possible to enable the logging of all operations that take too long to be performed through the maxQueryExecutionTime parameter. Then configuring the EntityManager as follows:

new EntityManager({
  log: { maxQueryExecutionTime: 2000 },
})

All operations that take more than 2 seconds to be performed will be logged.

Custom logger

Typetta provides a default logger that writes logs of four different levels directly on the console. If you want to customise the destination of the logs, for example by sending them to a third-party service, or simply want to change the format by adding or deleting information with respect to the default, you can create a custom logger.

A custom logger is a function that the user can write and set to the log parameter and that is invoked at each event and for each log level. This function receives the following parameters:

Here is an example of a custom logger:

new EntityManager({
  log: async ({ raw }) => {
    console.log(`My custom log is: ${raw}`)
  },
})

Await async log

By default Typetta awaits the logger async operation. In order to skip the await you can set awaitLog to false. All the exceptions thrown by the logger are ignored either if the operations are awaited or not.

new EntityManager({
  log: async ({ raw }) => {
    await sendLogToKinesis(`[TYPETTA]: ${raw}`)
  },
  awaitLog: false
})