Skip to content

Commit

Permalink
Now supports error logs.
Browse files Browse the repository at this point in the history
  • Loading branch information
smebberson committed Jun 11, 2021
1 parent b3b7464 commit abd3272
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 16 deletions.
4 changes: 4 additions & 0 deletions packages/log-structured/CHANGELOG.md
@@ -1,5 +1,9 @@
# @idearium/log-structured

## Unreleased

- Now supports error logs.

## v1.0.0

- First version of the package.
52 changes: 36 additions & 16 deletions packages/log-structured/index.js
Expand Up @@ -10,26 +10,42 @@ const write = (callback, line) => {
return callback(null, `${JSON.stringify(line)}\n`);
};

const createHttpRequest = (req, res) => ({
protocol: req.protocol,
referer: req.headers.referer || '',
remoteIp:
req.headers['x-forwarded-for'] ||
// This is for < v13
req.remoteIp ||
// This is for > v14
'',
requestMethod: req.method,
requestSize: req.headers['content-length'] || 0,
requestUrl: req.url,
responseSize: res.size || 0,
status: res.statusCode,
userAgent: req.headers['user-agent'] || ''
});

const transformErroredRequest = (log) => {
const { err, req, res } = log;

const updated = Object.assign({}, log, {
'@type': err['@type'],
'context': { httpRequest: createHttpRequest(req, res) },
'exception': err.message
});

delete updated.err;

return updated;
};

const transformRequest = (log) => {
const updated = Object.assign({}, log);
const { req, res } = updated;

updated.httpRequest = {
protocol: req.protocol,
referer: req.headers.referer || '',
remoteIp:
req.headers['x-forwarded-for'] ||
// This is for < v13
req.remoteIp ||
// This is for > v14
'',
requestMethod: req.method,
requestSize: req.headers['content-length'] || 0,
requestUrl: req.url,
responseSize: res.size || 0,
status: res.statusCode,
userAgent: req.headers['user-agent'] || ''
};
updated.httpRequest = createHttpRequest(req, res);

return updated;
};
Expand Down Expand Up @@ -60,6 +76,10 @@ module.exports = () => {
return write(callback, data);
}

if (line.err && line.req && line.res) {
return write(callback, transformErroredRequest(line));
}

return write(callback, transformRequest(line));
}
});
Expand Down
68 changes: 68 additions & 0 deletions packages/log-structured/tests/structured.test.js
Expand Up @@ -164,6 +164,45 @@ test('logs res when logging http requests', async (done) => {
get(server);
});

test('does not include error information when an error did not occur', async (done) => {
expect.assertions(1);

const stream = structured();
const log = middleware(stream);
const server = await setup(log);

once(stream, 'data').then((result) => {
const line = JSON.parse(result.toString());

expect(line).not.toHaveProperty('@type');

return done();
});

get(server);
});

test('logs err when an error occurs during http request/response lifecycle', async (done) => {
expect.assertions(2);

const stream = structured();
const log = middleware(stream);
const server = await setup(log);

once(stream, 'data').then((result) => {
const line = JSON.parse(result.toString());

expect(line).toHaveProperty('@type');
expect(line['@type']).toEqual(
'type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent'
);

return done();
});

get(server, '/error');
});

test('uses structured logging format when logging http requests', async (done) => {
expect.assertions(7);

Expand Down Expand Up @@ -379,3 +418,32 @@ test('http requests includes referer', async (done) => {

get(server);
});

test('uses structured error logging when an error occurs during http request/response lifecycle', async (done) => {
expect.assertions(10);

const stream = structured();
const log = middleware(stream);
const server = await setup(log);

once(stream, 'data').then((result) => {
const line = JSON.parse(result.toString());

expect(line).toHaveProperty('@type');
expect(line['@type']).toEqual(
'type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent'
);
expect(line).toHaveProperty('message');
expect(line.message).toBe('request errored');
expect(line).not.toHaveProperty('httpRequest');
expect(line).not.toHaveProperty('err');
expect(line).toHaveProperty('context');
expect(line.context).toHaveProperty('httpRequest');
expect(line).toHaveProperty('exception');
expect(line.exception).toContain('Testing errors...');

return done();
});

get(server, '/error');
});

0 comments on commit abd3272

Please sign in to comment.