[server/logger] downgrade EPIPE errors to debug level (#9041)

Backports PR #9023

**Commit 1:**
[server/logger] downgrade EPIPE errors to debug level

* Original sha: 4703b367aa
* Authored by spalger <email@spalger.com> on 2016-11-09T23:48:48Z

**Commit 2:**
fix variable naming

* Original sha: fd272c5b3b
* Authored by spalger <email@spalger.com> on 2016-11-11T01:06:55Z
This commit is contained in:
jasper 2016-11-15 03:39:04 -05:00 committed by Spencer
parent 379abee09b
commit 1cce23cbd9
3 changed files with 40 additions and 6 deletions

View file

@ -2,9 +2,9 @@ import expect from 'expect.js';
import { LogInterceptor } from '../log_interceptor';
function stubEconnresetEvent() {
function stubClientErrorEvent(errno) {
const error = new Error();
error.errno = 'ECONNRESET';
error.errno = errno;
return {
event: 'error',
@ -15,6 +15,9 @@ function stubEconnresetEvent() {
};
}
const stubEconnresetEvent = () => stubClientErrorEvent('ECONNRESET');
const stubEpipeEvent = () => stubClientErrorEvent('EPIPE');
function assertDowngraded(transformed) {
expect(!!transformed).to.be(true);
expect(transformed).to.have.property('event', 'log');
@ -30,6 +33,12 @@ describe('server logging LogInterceptor', () => {
assertDowngraded(interceptor.downgradeIfEconnreset(event));
});
it('transforms EPIPE events', () => {
const interceptor = new LogInterceptor();
const event = stubEpipeEvent();
assertDowngraded(interceptor.downgradeIfEpipe(event));
});
it('does not match if the tags are not in order', () => {
const interceptor = new LogInterceptor();
const event = stubEconnresetEvent();
@ -39,8 +48,7 @@ describe('server logging LogInterceptor', () => {
it('ignores non ECONNRESET events', () => {
const interceptor = new LogInterceptor();
const event = stubEconnresetEvent();
event.data.errno = 'not ECONNRESET';
const event = stubClientErrorEvent('not ECONNRESET');
expect(interceptor.downgradeIfEconnreset(event)).to.be(null);
});

View file

@ -38,8 +38,33 @@ export class LogInterceptor extends Stream.Transform {
};
}
/**
* Since the upgrade to hapi 14, any socket write
* error is surfaced as a generic "client error"
* but "EPIPE" specifically is not useful for the
* logs unless you are trying to debug edge-case behaviors.
*
* For that reason, we downgrade this from error to debug level
*
* @param {object} - log event
*/
downgradeIfEpipe(event) {
const isClientError = doTagsMatch(event, ['connection', 'client', 'error']);
const isEpipe = isClientError && get(event, 'data.errno') === 'EPIPE';
if (!isEpipe) return null;
return {
event: 'log',
pid: event.pid,
timestamp: event.timestamp,
tags: ['debug', 'connection', 'epipe'],
data: 'EPIPE: Socket was closed by the client (probably the browser) before the response could be completed'
};
}
_transform(event, enc, next) {
const downgraded = this.downgradeIfEconnreset(event);
const downgraded = this.downgradeIfEconnreset(event) || this.downgradeIfEpipe(event);
this.push(downgraded || event);
next();

View file

@ -13,7 +13,8 @@ module.exports = {
'test/**/__tests__/**/*.js',
'src/**/__tests__/**/*.js',
'test/fixtures/__tests__/*.js',
'!src/**/public/**'
'!src/**/public/**',
'!**/_*.js'
]
}
};