This is going to give your applications an extra level of awesome: advanced logging.
Application showing an unidentified error? Tired of ssh
'ing into your server to debug it? Instead of cosole.log
and console.err
, you should be using a logger like winston
to send your logs somewhere more convenient. Here, I'll show you how to send them to AWS CloudWatch for easy access and monitoring. You can even set up CloudWatch to notify you by email of certain errors.
The Logger
We're going to need two node modules: winston
, and winston-aws-cloudwatch
. With these installed, you can use the following code as a basic implementation of our logger:
var winston = require('winston'),
CloudWatchTransport = require('winston-aws-cloudwatch');
var NODE_ENV = process.env.NODE_ENV || 'development';
const logger = new winston.Logger({
transports: [
new (winston.transports.Console)({
timestamp: true,
colorize: true,
})
]
});
var config = {
logGroupName: 'my-log-group',
logStreamName: NODE_ENV,
createLogGroup: false,
createLogStream: true,
awsConfig: {
accessKeyId: process.env.CLOUDWATCH_ACCESS_KEY_ID,
secretAccessKey: process.env.CLOUDWATCH_SECRET_ACCESS_KEY,
region: process.env.CLOUDWATCH_REGION
},
formatLog: function (item) {
return item.level + ': ' + item.message + ' ' + JSON.stringify(item.meta)
}
}
if (NODE_ENV != 'development') logger.add(CloudWatchTransport, config);
logger.level = process.env.LOG_LEVEL || "silly";
logger.stream = {
write: function(message, encoding) {
logger.info(message);
}
};
module.exports = logger;
Up the top we create a Logger
with a single transport, then we add another transport, but only if we're not in development. You might prefer to only add the logger if you are in production/staging. Look here for more information about winston's log levels.
CloudWatch
Clearly we need to set up CloudWatch. We need to create a log group, and a programmatic IAM with the correct permissions.
On the AWS console, under CloudWatch > Logs create a log group called my-log-group like above (or whatever):
Now for the IAM user. Navigate to the IAM users dashboard and hit Add User:
Give the user a meaningful name (maybe cloudwatch-full-access), and an Access Type of Programmatic Access.
Attach an existing policy: CloudWatchFullAccess and create the user. You should ideally figure out how to edit the policy to only allow this user access to the specific log group.
Create the user, and store its secret keys in a secure environment file. With this information, you can now define all the environment variables our logger is relying on, and it is now usable!
Usage
var logger = require('../services/logger'),
logger.log('info', "[STARTUP] Connecting to DB...", {tags: 'startup,mongo'});
// -> Connect to DB
It's that easy. You should now be able to see any logs under the log group on your CloudWatch dashboard. If you want to query for a specific tag, use:
{$.tags = "*tag*"}