Reputation: 3049
I have some node.js based Lambdas that are logging data.
In order to properly query and filter the data etc, I want to log as pure JSON data from my Lambdas.
However, when I do a regular console.log
it makes an ordinary string of the data.
console.log({a:1,b:2,x:"xxx"})
Results in this:
2020-04-29T14:46:45.722Z 3f64c499-fbae-4a84-996c-5e5f0cb5302c INFO { a: 1, b: 2, x: 'xxx' }
The logged line above does not seem to be searchable as JSON using the various filter matching options in CloudWatch.
I've tried to call the AWS.CloudWatchLogs
API directly but since I'm using lambda I cannot maintain a token between invocations of the functions, so I'm not sure that's the way to go.
Have anyone else had success in logging raw JSON from a Javascript Lambda?
Upvotes: 9
Views: 6347
Reputation: 10785
The trick is to use the correct delimiter before the JSON data.
In your example, there is no delimiter before JSON data:
console.log({a:1,b:2,x:"xxx"})
// {a:1,b:2,x:"xxx"}
The official documentation AWS Lambda function logging in Node. js is adding a newline \n
character before the data. An example for your code snippet:
console.log('\n%j', {a:1,b:2,x:"xxx"})
// \n{a:1,b:2,x:"xxx"}
That does not work either as of July 2022.
The solution is to use the tab character \t
as the delimiter between the message and the data.
console.log('\t%j', {a:1,b:2,x:"xxx"})
// \t{a:1,b:2,x:"xxx"}
An example of building a formatted message and adding structured data:
const name = 'world';
console.log('hello %s\t%j', name, {a:1,b:2,x:"xxx"})
// hello world\t{a:1,b:2,x:"xxx"}
Upvotes: 2
Reputation: 4486
The problem is that console.log()
does not go directly to stdout/stderr. You can see that using this Lambda:
const process = require('process');
exports.handler = async (event) => {
console.log("message 1");
process.stdout.write("message 2\n");
};
If you invoke that, you will see output like this:
START RequestId: 6942bebc-1997-42cd-90c2-d76b44c637283 Version: $LATEST
2020-04-29T17:06:07.303Z 6935bebc-1d97-42cd-90c2-d76b4a637683 INFO message 1
message 2
END RequestId: 6942bebc-1997-42cd-90c2-d76b44c637283
So to get the output you want you could either redefine console.log
to go to stderr, or write to stdout/stderr directly.
Or you could use a logging framework that writes to stdout/stderr, which may give you more flexibility on how your messages are written. I don't do Node development, but I've heard that Winston is the standard logging framework.
Upvotes: 13