apex / up

Deploy infinitely scalable serverless apps, apis, and sites in seconds to AWS.
https://up.docs.apex.sh
MIT License
8.79k stars 377 forks source link

Logs missing contextual information #799

Open stephenmathieson opened 4 years ago

stephenmathieson commented 4 years ago

Prerequisites

Description

Logs do not contain contextual information unless wrapped in a fields object.

Steps to Reproduce

Log something like this:

console.log(JSON.stringify({ message: "Hello", foo: "bar" }))

Then do up logs after deploying.

I would expect to see a log similiar to:

{ "message": "Hello", "foo": "bar" }

However, what is being logged is:

{ "message": "Hello" }

If foo: "bar" is wrapped in a fields object, the additional entire log is outputted:

console.log(JSON.stringify({ message: "Hello", fields{ foo: "bar" } }))

This is not documented at https://apex.sh/docs/up/.

tj commented 4 years ago

ahhh it's a bit tricky to find but here's the relevant docs: https://apex.sh/docs/up/guides/#mastering_logging.json_structured_logs — it would be possible to just accept arbitrary JSON, but for now it's a pretty deliberate "shape"

stephenmathieson commented 4 years ago

I saw that, but the docs don't explicitly state that properties that aren't level, message or fields will be dropped. That's really what this issue is about (maybe I should just open a PR in /docs and close this?).

It's not a huge deal on my end (I ended up just wrapping my logger with something like the snippet below), but it was unexpected. We deployed a bunch of logging updates to an old Lambda that was misbehaving in attempt to debug and made it worse by using structured logs that didn't contain any context.

Previously we had:

console.error('Unexpected error: %s', error.message)

Which worked just fine, but made searching tedious. However, using structured logs like:

var logger = winston.createLogger({ ... })
logger.error('Unexpected error', { message: error.message, stack: error.stack })

Made it impossible to get anything useful out. We just had tons of "Unexpected error" logs that held no value.

Since standard Node.js logging solutions (winston, pino, bunyan, ...) don't add fields: {} and instead just allow you to pass arbitrary JSON, this is something I'd expect to be able to utilize in my Lambdas.


My hacky fix for now:

var info = logger.info
logger.info = function (message, stuff) {
  info.call(this, message, { fields: stuff })
}
tj commented 4 years ago

gotcha! Yeah it'd probably be fine to just pass everything else through as fields, sounds reasonable to me