Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add custom token data to @elastic/ecs-morgan-format #125

Open
sanhardik opened this issue May 28, 2022 · 5 comments
Open

Add custom token data to @elastic/ecs-morgan-format #125

sanhardik opened this issue May 28, 2022 · 5 comments
Labels
agent-nodejs Make available for APM Agents project planning. community help wanted Extra attention is needed

Comments

@sanhardik
Copy link

Hello,
I would like to add custom data so that it gets added to the final formatter for @elastic/ecs-morgan-format

Is it possible ?

@github-actions github-actions bot added agent-nodejs Make available for APM Agents project planning. community triage labels May 28, 2022
@trentm
Copy link
Member

trentm commented May 30, 2022

@sanhardik It isn't possible with the current implementation. Is the data you want to add static? I.e. it doesn't change for the lifetime of the app process? If so we could possibly add a feature so that something like this would work:

const app = require('express')()
const morgan = require('morgan')
const ecsFormat = require('@elastic/ecs-morgan-format')

app.use(morgan(ecsFormat({
  fields: {foo: 'bar'}
})))

to add foo: 'bar' to every log record.

@trentm trentm removed the triage label May 30, 2022
@sanhardik
Copy link
Author

@trentm Thanks for the reply.
The data wont be static.
The information that I am thinking, is adding more details about the request.
In my case, I am dealing with API calls about devices (Edit,Operate etc)

I want to add information about the device whose resources are being accessed.

I was thinking of extending the request or the response object and then passing that on.
May if I could pass a "Morgan Token" in, to be used in final JSON string

const app = require('express')()
const morgan = require('morgan')
const ecsFormat = require('@elastic/ecs-morgan-format')

morgan.token('device', function (req, res) { return req.device })

app.use(morgan(ecsFormat({
  tokens: ['device']
})))

@trentm
Copy link
Member

trentm commented May 31, 2022

I think something like that would be reasonable to implement. I haven't played with using morgan tokens, so I don't know for sure.

I most likely won't have time soon to play with this. Would you be willing to try making a patch for this?

@trentm trentm added the help wanted Extra attention is needed label Oct 30, 2023
@jpage-godaddy
Copy link

I have a pull request proposal for allowing calculated custom fields to be injected.

#179

@SokolovAlexanderV
Copy link

Hello.
I've found a way to add custom field to ECS formatted log data without @elastic/ecs-morgan-format.
The trick is to use Morgan "custom format function" which does not return format string but logs request and response with Winston logger which uses ECS format.
It's a bit more complex than sanhardik's code but it solves the problem.

const express = require('express');
const morgan = require('morgan');
const winston = require('winston');
const ecsFormat = require('@elastic/ecs-winston-format');

const app = express();

/*
    Create Winston logger
    either attach it to app to use within request callbacks or
    define a constant: const logger = ...
*/
app.logger = winston.createLogger({
    format: ecsFormat({
        convertReqRes: true // this option is IMPORTANT
    }),
    transports: [ new winston.transports.Console({
        level: 'debug' // this is IMPORTANT if you want debug level
    }) ],
});

/* Configure Morgan middleware but DO NOT RETURN value */
const accessLogMiddleware = morgan((tokens, req, res) => {

    /* Works finne with convertReqRes option set to true */
    let params = { req, res };

    /* Here is "device" field */
    params.device = req.device || 'No device';

    /* Log formatted message with extra params instead of returning format string */
    const level = res.statusCode < 500 ? 'info' : 'error';
    const msg = morgan.compile(morgan['combined'])(tokens, req, res);
    app.logger.log(level, msg, params);
});

app.use(accessLogMiddleware);

/* Some body data can be also used to log with request  */
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

app.get('/', (req, res) => {
    req.app.logger.log('debug', 'GET request');
    res.send('Get request, no body');
});

app.post('/', (req, res) => {
    req.app.logger.log('debug', 'POST request', {extra: 'data'});
    res.send('Post request, has body');
});

app.listen(8080, () => {
    app.logger.info('Express application is listening on port http://127.0.0.1:8080 ...');
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
agent-nodejs Make available for APM Agents project planning. community help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

4 participants