Welcome to @beerush/logger - where consistency in logging across Libraries, Frameworks, and Applications becomes a reality. This versatile logger, free of dependencies, is designed to standardize logging, offering a range of adaptable adapters tailored to different environments. Embrace a unified approach to all levels of logging with @beerush/logger. Start simplifying your logging process today!
The Javascript ecosystem is remarkably rich with a vast selection of libraries and frameworks. However, managing the display and distribution of logs can pose a significant challenge.
Within a development environment, it might be preferable to log everything. However, in production, logging may need to be limited to errors only. It is particularly important to streamline this process when you are deploying your project to a serverless environment or any other cloud service where debugging can be complicated.
The straightforward console.log might suffice for your project, but it does not offer control over logging for the library or framework in use. Our library aims to address this by providing a simple, user-friendly logger that can be employed across various environments.
Every library, framework, and application can utilize the same logger for consistency and efficiency. Moreover, this allows for control over the log level and the destination of the logs.
You can install the package via package manager such as bun, npm, or yarn.
bun add @beerush/logger
You can use it in your typescript files like shown below:
Initialization in ./logger.ts
import { createLogger, LogLevel } from '@beerush/logger';
import { consoleAdapter } from '@beerush/logger/console';
// Create a new logger instance and export it for use in other modules.
export const logger = createLogger();
// Use the console adapter to log to the console.
logger.use(consoleAdapter());
logger.info('Hello, World!'); // Logs an informational message.
📜 [5/9/2024, 2:07:14 PM] Hello, World!
You can also reuse the logger in your application. For instance, in your app.ts file:
Logging in ./app.ts
import { logger } from './logger.ts';
logger.info('Hello, World! App is running on port 3000.'); // Logs an informational message.
📜 [5/9/2024, 2:07:14 PM] Hello, World! App is running on port 3000.
Adapter is a function that receives a log and handles it in a specific way. For example, an adapter might send the log to a remote server, write it to a file, or log it to the console.
Each adapter can have its own severity level and options. For example, the Console adapter will capture all logs in development, but nothing in production, and the Sentry adapter will capture WARNING and ERROR in production, but nothing in development.
You can add an adapter to a logger using the use
method of the logger.
Adapters are applied in the order they are added, and shared across all loggers created from the same logger.
Using the same adapter multiple times will overwrite the previous one.
Example:
import { logger } from './logger.ts';
import { consoleAdapter } from '@beerush/logger/console';
import { fileAdapter } from '@beerush/logger/adapters/file';
logger.use(consoleAdapter({ level: LogLevel.DEBUG })); // Register a console adapter.
logger.info('Hello, World!'); // Logs an informational message to the console.
logger.verbose('Detailed information!'); // Ignored because the log level is DEBUG.
logger.use(fileAdapter({ location: './logs', level: LogLevel.ERROR })); // Register a file adapter.
logger.error('An error occurred!'); // Logs an error message to the console and to a file.
logger.info('Hello, World!'); // Logs to the console, and logs to a file is ignored because the log level is ERROR.
The logger supports various log levels, each with its own significance. The log levels are as follows:
- ERROR: This level is used for error messages. These logs represent errors that might have allowed the application to continue running, but with unexpected behavior.
- WARN: This level is used for potentially harmful situations. These logs might lead to an error.
- INFO: This level is used for informational messages. These logs represent the progress of the application.
- DEBUG: This level is used for general debugging information. These logs are usually only needed for debugging.
- VERBOSE: This level is used for detailed debugging information. These logs are usually only needed for debugging.
The logger will log all logs with a level greater than or equal to the log level of the logger. For example, setting the adapter level to INFO will log all logs with a level of INFO, WARN, or ERROR, but not DEBUG or VERBOSE.
The logger supports tracking logs. Tracking logs are useful for tracking the execution of a specific part of the code.
This is useful for debugging and analytics. You can track logs using the track
method of the logger.
Tracking logs are not logged to the console by default. You can use specific adapters to log tracking logs.
Example:
import { logger } from './logger.ts';
logger.track('User logged in', { userId: 1 }); // Track a user login.
The console adapter uses different colors for different log levels when logging to the console. The colors are as follows:
- VERBOSE: Purple
- DEBUG: Blue
- INFO: Green
- WARN: Yellow
- ERROR: Red
The logger formats the logs in a specific way when logging to the console. The format is as follows:
- If the log message is a string, it is prefixed with a specific emoji based on the log level.
- If the log message is not a string, it is logged as is.
- If the log has an error, it is logged after the message.
- If the log has extra information, it is logged after the error (if any).
The logger supports tagging logs. Tags are useful for categorizing logs. For example, you might want to tag logs with
the name of the module they are coming from. You can create a new logger with specific tags using the create
method of
an existing logger.
Example:
import { logger } from './logger.ts';
const moduleLogger = logger.create({ tags: ['module'] });
moduleLogger.info('Hello, World!'); // Logs an informational message with the tag 'module'.
📜 [module][5/9/2024, 2:07:14 PM] Hello, World!
You may want to adjust the log level based on your environment. For example, in your Hono app, you might want to disable console logging in production. You can create a middleware that adjusts the log level based on the environment as shown below:
import { logger } from './logger.ts';
import type { Context } from 'hono';
export default async function loggerMiddleware(ctx: Context, next: () => void) {
// Override the logger level based on the environment.
if (ctx.env.PRODUCTION) {
logger.use(consoleAdapter({ level: LogLevel.OFF }));
} else {
logger.use(consoleAdapter({ level: LogLevel.DEBUG }));
}
ctx.set('logger', logger);
await next();
}
In case you want to log your data to an external service which is not supported by the built-in adapters, you can create
a custom adapter. A custom adapter is an object with a name
and an emit
method. The emit
method is called with the
log object when a log is emitted. You can create a custom adapter as shown below:
import type { Log } from '@beerush/logger';
import { logger } from './logger.ts';
logger.use({
name: 'custom-adapter',
emit: async (log: Log) => {
await fetch('https://example.com/log', {
method: 'POST',
body: JSON.stringify(log),
headers: {
'Content-Type': 'application/json'
}
});
}
});
logger.info('Hello, World!'); // This will log the message to the external service.
- Logger module.
- Console adapter
- Webhook adapter.
- File adapter.
- Sentry adapter.
- Mixpanel adapter.
- Slack adapter.
- Discord adapter.
The @beerush/logger
is licensed under the MIT License, ensuring a wide range of opportunities for open source use and
further development.