# Short guide for Logging in JavaScript
# Introduction
Logging is a crucial part of software development. It plays a big role in debugging and monitoring applications. Good logging lets developers understand how their applications behave and helps them troubleshoot issues quickly.
In the JavaScript world, Pino and Winston are popular logging libraries. This guide will walk you through using Pino and Winston for logging and show you how to implement structured logging in Node.js.
## Logging with Pino Logger in JavaScript
Pino is a fast and lightweight logging library for Node.js applications. It's designed to be simple yet powerful, making it an excellent choice for logging in production environments.
### Setting Up Pino
To get started with Pino, install it via npm:
```
npm install pino
```
### Basic logging with Pino
Here's a basic example of how to use Pino:
```
const pino = require('pino');
const logger = pino();
logger.info('This is an info message');
logger.error('This is an error message');
logger.debug('This is a debug message'); // Won't be logged by default
```
By default, Pino logs messages in JSON format, which makes it easy to parse and analyze.
### Advance Features of Pino
Pino offers various advanced features such as custom serializers, child loggers, and integration with other tools.
#### Custom Serializers
Custom serializers allow you to control how objects are logged:
```
const logger = pino({
serializers: {
user: (user) => ({ id: user.id, name: user.name })
}
});
logger.info({ user: { id: 1, name: 'John Doe', password: 'secret' } }, 'User info');
```
#### Child Loggers
Child Loggers inherit properties from their parent logger, making it easy to add context-specific logging:
```
const childLogger = logger.child({ module: 'user-service' });
childLogger.info('This message will include module info');
```
#### Integration with Express
Pino can be integrated with Express to log HTTP requests and responses:
```
const express = require('express');
const pino = require('pino-http');
const app = express();
app.use(pino());
app.get('/', (req, res) => {
req.log.info('Handling request');
res.send('Hello, world!');
});
app.listen(3000);
```
## Logging with Winston in JS
Winston is another popular logging library for Node.js, known for its flexibility and rich feature set.
### Setting Up Winston
To get started with Winsotn, install it via npm:
```
npm install winston
```
### Basic Logging with Winston
Here's basic example of how to use Winston:
```
const { createLogger, format, transports } = require('winston');
const logger = createLogger({
level: 'info',
format: format.json(),
transports: [
new transports.Console()
]
});
logger.info('This is an info message');
logger.error('This is an error message');
```
### Advance Features of Winston
Winston supports various advanced features such as multiple transports, custom formats, and log levels.
#### Multiple Transports
You can log to multiple destinations(e.g., console, file, HTTP) using transports:
```
const logger = createLogger({
level: 'info',
format: format.combine(
format.timestamp(),
format.json()
),
transports: [
new transports.Console(),
new transports.File({ filename: 'combined.log' })
]
});
```
#### Custom Formats
Winston allows you to define custom formats for log messages:
```
const customFormat = format.printf(({ level, message, timestamp }) => {
return `${timestamp} [${level}]: ${message}`;
});
const logger = createLogger({
format: format.combine(
format.timestamp(),
customFormat
),
transports: [
new transports.Console()
]
});
```
#### Log Levels
You can define custom log levels and colors:
```
const logger = createLogger({
levels: {
error: 0,
warn: 1,
info: 2,
http: 3,
debug: 4
},
format: format.combine(
format.colorize(),
format.simple()
),
transports: [
new transports.Console()
]
});
logger.http('This is an HTTP log message');
```
## Complete Guide to Implementing Structured Logging in Node.js
Structured logging involves logging in a consistent, predictable format, typically JSON. This allows logs to be easily parsed and analyzed by log management tools.
### Why Structured Logging?
- **Improved Readability**: Logs are structured in a standard format, making them easier to read and understand.
- **Enhanced Filtering**: Structured logs can be easily filtered and queried based on specific fields.
- **Better Integration**: Structured logs integrate well with log management and analysis tools like ELK stack, Splunk, etc.
### Implementing Structured Logging
Implementing structured logging in Node.js involves choosing a library(Pino or Winston), configuring it to log in JSON format, and adding relevant context to log messages.
#### Using Pino for Structured Logging
```
const pino = require('pino');
const logger = pino({ prettyPrint: false });
logger.info({ user: { id: 1, name: 'John Doe' } }, 'User logged in');
```
#### Using Winston for Structured Logging
```
const { createLogger, format, transports } = require('winston');
const logger = createLogger({
format: format.combine(
format.timestamp(),
format.json()
),
transports: [
new transports.Console()
]
});
logger.info({ user: { id: 1, name: 'John Doe' } }, 'User logged in');
```
### Best Practices for Structured Logging
1. **Include Contextual Information:** Add relevant context to each log message(e.g., user ID, request ID).
2. **Use Log Levels Appropriately:** Ensure that log levels(e.g., info, warn, error) are used consistently.
3. **Avoid Logging Sensitive Information:** Be cautious about logging sensitive data(e.g., passwords, credit card numbers).
4. **Ensure Log Consistency:** Use a consistent structure for all log messages.
5. **Integrate with Monitoring Tools:** Use log management tools to aggregate, visualize, and analyze logs.
## Conclusion
Logging is an essential practice in software developmentfor monitoring and debugging applications. Pino and Winston are two powerful logging libraries in JavaScript that offer a range of features for basic and advanced logging. Structured logging enhances the readability and analysis of logs, making it a best practice for production environments.
### Key Takeways
- **Pino:** Fast and low-overhead logging library, great for production.
- **Winston:** Flexible and featue-rich logging library, supports multiple transports and custom formats.
- **Structured Logging:** Log in a consistent format(typically JSON) for better readability and analysis.
- **Best Practices:** Include contextual information, use appropriate log levels, avoid logging sensitive data, and integrate with monitoring tools.