If condition to check the log 'level' not working

42 Views Asked by At

I have setup a basic Node.js application and I am using the winston package to send my logs to Logstash. I am not using filebeat. In the Elastic cloud deployment I want to keep the logs in separate indices and for that I tried to filter the data and assign index based on its 'level' (info,error). But the if else condition in the Logstash config file always goes to the else condition and logs the data into the index mentioned in the else condition. The first if condition to check if the 'message' is an object is working fine but the second condition always goes to else.

Logstash config file

input {
    tcp {
        port => 6000
    }
}

filter {
    if [message] =~ /^{.*}$/ {
        if [level] == 'info' {
            mutate {
                add_field => { "index" => "error-logs-%{+YYYY.MM.dd}" }
            }
        } else {
            mutate {
                add_field => { "index" => "api-logs-%{+YYYY.MM.dd}" }
            }
        }
    } else {
        drop {}
    }
}

output {
    elasticsearch { 
        cloud_id => "cloud_id" 
        cloud_auth => "credentials for cloud"
        index => "%{index}"
    }
    stdout { codec => rubydebug }
}

Node.js application file

const express = require('express');
const winston = require('winston');
const {ecsFormat} = require('@elastic/ecs-winston-format');
const {ElasticsearchTransport} = require('winston-elasticsearch');
const transports = require('winston-logstash');
const app = express();
app.use(express.json());

const api_logger = winston.createLogger({
    format: winston.format.json(),
    transports: [
        new ElasticsearchTransport({
            clientOpts: {node: 'http://localhost:6000'},
        })
    ]
});

const error_logger = winston.createLogger({
    format: winston.format.json(),
    transports: [
        new ElasticsearchTransport({
            clientOpts: {node: 'http://localhost:6000'},
        })
    ]
})

const signup = async function (req, res) {
    try {
        const { firstName, lastName, phoneNumber, emailId, password } = req.body;
        res.status(200).json({message: "Request successful!"});
        if (req.body) {api_logger.info('api-logs',{
                messsage: 'New signup request', 
                request_header: req.headers,
                request_body: req.body
            })
        }
    } catch (error) {
        console.log(error);
        error_logger.error(`Error,${error.message}`, {request_header : req.headers, request_body : req.body});
        res.status(500).json({ message: error.message });
    }
};

app.post("/new", signup);

app.listen(7000, console.log("Server is running on port 7000!"))
1

There are 1 best solutions below

0
Murat K. On

You may use @elastic/ecs-winston-format instead of using winston.format.json(). It is compatible with the ECS (Elastic Common Schema).

Npmjs link