googleapis / nodejs-logging-winston

Node.js client integration between Stackdriver Logging and Winston.
https://cloud.google.com/logging/
Apache License 2.0
106 stars 50 forks source link

Feature request: attach custom data to middleware logger #695

Open rubenvereecken opened 2 years ago

rubenvereecken commented 2 years ago

The use case is quite simple. I'd like to attach some custom data to request logs, such as which user is associated with this request. This data is available on the req object, so all I'd need is an optional makeData parameter for makeMiddleware. This function would be invoked for each request so that custom data could be set for each request.

hbiarge commented 2 years ago

Same here. I need to include custom data (userId) to the log. Any advance on this feature request? Or any alternative? Thanks in advance!

mbrevda commented 2 years ago

Here's an example of adding data dynamically:

let UserData

const winstonConfig = {
  level: 'info',
  format: winston.format.combine(
    winston.format.errors({stack: true}),
    winston.format.json()
  )
}

// UserData is not set yet, it will be set later
Object.defineProperty(winstonConfig.defaultMeta, 'user', {
  enumerable: true,
  get() {
    return UserData
  }
})
const log = winston.createLogger(winstonConfig)

later in the same file:


const myMiddleware = async (req, res, next) => {
  UserData = req.user
}

export {myMiddleware}
hbiarge commented 2 years ago

Hi @mbrevda! Thanks for the quick response. But I was looking for something similar but with the express middleware that this library provides:

GoogleWinston.express.makeMiddleware(logger, options);

I don't want to create my own middleware for this. Something like morgan do with custom tokens or so:

morgan.token("userId", function (req, res) {
            const userId = req["userId"] || "N/A";
            return userId;
        });
mbrevda commented 2 years ago

So was I. It doesn't seem that winston supports appending metadata post initialization.

Wazbat commented 2 years ago

I don't think this is a good fix, but wouldn't you in theory be able to create a child logger from the req.log at the start of your request handler wherever this data is available and just use that?

EDIT: Ah I think I'm mistaken. That'd work for the logs in your application, but the final log sent when the request is complete would not have that metadata. Rewriting req.log with your logger might work, but even then that feels like a hacky fix