Customizing the 1.6.x Logging agent to support custom multiline parsing for Node.js applications using Winston in orchestrated environments
This tutorial demonstrates how to configure the IBM® Cloud Logs Logging agent multiline log handling for a Node.js application using the customized Winston logging library. This configuration is for orchestrated environments, for example IBM Cloud Kubernetes Service and Red Hat OpenShift on IBM Cloud, and uses Helm. This configuration ensures that stack traces and multiline logs are grouped correctly in IBM Cloud Logs.
This tutorial requires the IBM Cloud Logs Logging agent 1.6.0 or later.
Before you begin
Before you begin using this tutorial, review the following information to understand Logging agent and multiline concepts.
This tutorial also assumes you have:
-
An IBM Cloud Logs instance provisioned and configured.
-
The Logging agent deployed in an orchestrated environment.
-
Kubernetes Service IBM Cloud Kubernetes Service
-
Red Hat OpenShift on IBM Cloud Red Hat OpenShift on IBM Cloud
-
Sample Winston configuration
Let's assume your Node.js application uses Winston and logs to the console in the following format:
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp({
format: 'ddd MMM DD YYYY HH:mm:ss.SSS'
}),
winston.format.errors({ stack: true }),
winston.format.printf(({ timestamp, level, message, stack }) => {
const levelUpper = level.toUpperCase();
const baseLog = `[${timestamp}] ${levelUpper} [Main] - ${message}`;
if (stack) {
return `${baseLog}\n${stack}`;
}
return baseLog;
})
),
transports: [
new winston.transports.Console()
]
});
This format produces log entries that start with a timestamp and level, and multiline logs, such as error stack traces, follow on subsequent lines without timestamps.
Winston typically logs all output, including error stack traces, as a single string so a multiline parser is often not required. However, this example demonstrates what to do if your formatter prints multiline logs, and it helps illustrate how to approach multiline parsing for any custom format.
This configuration is provided as an example to show how to handle multiline logs when using custom log formatting. If your application uses a different structure or logging library, use this as a reference to create your own multiline parser accordingly.
Configuring multiline parsing with Helm
If you are deploying the Logging agent using Helm, you can configure multiline parsing in the Helm values.yaml
file.
Enable multiline parsing
Set enableMultiline
to true
in your values.yaml
file to activate multiline processing:
enableMultiline: true
Define the multiline parser
Add a custom multiline parser under the additionalMultilineParsers
section in your values.yaml
file.
It is important for the pattern defined in the log4j.xml
file align with the regex in the multiline parser to ensure proper log grouping.
additionalMultilineParsers:
- name: multiline-nodejs-winston
type: regex
flush_timeout: 500
rules:
- state: start_state
regex: '/^\[[A-Z][a-z]{2} [A-Z][a-z]{2} \d{2} \d{4} \d{2}:\d{2}:\d{2}\.\d{3}\] .*$/'
next_state: cont
- state: cont
regex: '/^(?!\[[A-Z][a-z]{2} [A-Z][a-z]{2} \d{2} \d{4} \d{2}:\d{2}:\d{2}\.\d{3}\] ).*$/'
next_state: cont
The regex assumes that each new log line starts with a timestamp in the format ddd MMM DD YYYY HH:mm:ss.SSS
. The first rule captures starting lines with timestamps and moves to a continuation state. The second rule matches any line
not starting with a timestamp.
This approach is just an example to show you how to ensure multiline log lines are grouped as a single log entry before forwarding them to IBM Cloud Logs. There are different ways to achieve the same thing.
Apply the parser in a preprocessor
Configure a preprocessor under the multilinePreprocessor
section to apply the parser to your logs.
For example:
multilinePreprocessor:
- name: multiline
multiline.parser: multiline-nodejs-winston
multiline.key_content: log
Apply the changes.
If you have installed a previous version of the Logging agent and have updated the agent configuration by modifying the config map directly in the cluster, make a copy of your config map from the cluster before running the helm upgrade
command. When the Logging agent is updated, any changes made to the config map will be overwritten.
After updating the values.yaml
file, apply the changes by running the following on your deployment. This will regenerate the necessary configurations.
helm upgrade
Verify your multiline logs
Access your IBM Cloud Logs instance and confirm your multiline entries (for example, stack traces) are grouped correctly.
-
Using the Logs
view, verify that your multiline entries are grouped correctly.