Skip to content

Commit

Permalink
[server/logging] Allow opting out of UTC (#14705)
Browse files Browse the repository at this point in the history
* [server/logging] make use of UTC configurable

* [server/logging/tests] try removing TZ from moment

* [server/log/formatJson] use strict equality checks

* [server/log/format] note in method name that time is extracted

(cherry picked from commit b79ba98)
  • Loading branch information
spalger committed Nov 8, 2017
1 parent ff02816 commit abab9fc
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 5 deletions.
4 changes: 3 additions & 1 deletion src/server/config/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ export default () => Joi.object({
is: 'stdout',
then: Joi.default(!process.stdout.isTTY),
otherwise: Joi.default(true)
})
}),

useUTC: Joi.boolean().default(true),
})
.default(),

Expand Down
49 changes: 49 additions & 0 deletions src/server/logging/__tests__/log_format_json.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import moment from 'moment';
import expect from 'expect.js';

import {
createListStream,
createPromiseFromStreams,
} from '../../../utils';

import KbnLoggerJsonFormat from '../log_format_json';

const time = +moment('2010-01-01T05:15:59Z', moment.ISO_8601);

const makeEvent = () => ({
event: 'log',
timestamp: time,
tags: ['tag'],
pid: 1,
data: 'my log message'
});

describe('KbnLoggerJsonFormat', () => {
it('logs in UTC when useUTC is true', async () => {
const format = new KbnLoggerJsonFormat({
useUTC: true
});

const result = await createPromiseFromStreams([
createListStream([makeEvent()]),
format
]);

const { '@timestamp': timestamp } = JSON.parse(result);
expect(timestamp).to.be(moment.utc(time).format());
});

it('logs in local timezone when useUTC is false', async () => {
const format = new KbnLoggerJsonFormat({
useUTC: false
});

const result = await createPromiseFromStreams([
createListStream([makeEvent()]),
format
]);

const { '@timestamp': timestamp } = JSON.parse(result);
expect(timestamp).to.be(moment(time).format());
});
});
49 changes: 49 additions & 0 deletions src/server/logging/__tests__/log_format_string.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import moment from 'moment';
import expect from 'expect.js';

import {
createListStream,
createPromiseFromStreams,
} from '../../../utils';

import KbnLoggerStringFormat from '../log_format_string';

const time = +moment('2010-01-01T05:15:59Z', moment.ISO_8601);

const makeEvent = () => ({
event: 'log',
timestamp: time,
tags: ['tag'],
pid: 1,
data: 'my log message'
});

describe('KbnLoggerStringFormat', () => {
it('logs in UTC when useUTC is true', async () => {
const format = new KbnLoggerStringFormat({
useUTC: true
});

const result = await createPromiseFromStreams([
createListStream([makeEvent()]),
format
]);

expect(String(result))
.to.contain(moment.utc(time).format('HH:mm:ss.SSS'));
});

it('logs in local timezone when useUTC is false', async () => {
const format = new KbnLoggerStringFormat({
useUTC: false
});

const result = await createPromiseFromStreams([
createListStream([makeEvent()]),
format
]);

expect(String(result)).to
.contain(moment(time).format('HH:mm:ss.SSS'));
});
});
2 changes: 2 additions & 0 deletions src/server/logging/configuration.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ export default function loggingConfiguration(config) {
config: {
json: config.get('logging.json'),
dest: config.get('logging.dest'),
useUTC: config.get('logging.useUTC'),

// I'm adding the default here because if you add another filter
// using the commandline it will remove authorization. I want users
// to have to explicitly set --logging.filter.authorization=none or
Expand Down
11 changes: 10 additions & 1 deletion src/server/logging/log_format.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,19 @@ export default class TransformObjStream extends Stream.Transform {
next();
}

extractAndFormatTimestamp(data, format) {
const { useUTC } = this.config;
const date = moment(data['@timestamp']);
if (useUTC) {
date.utc();
}
return date.format(format);
}

readEvent(event) {
const data = {
type: event.event,
'@timestamp': moment.utc(event.timestamp).format(),
'@timestamp': event.timestamp,
tags: [].concat(event.tags || []),
pid: event.pid
};
Expand Down
1 change: 1 addition & 0 deletions src/server/logging/log_format_json.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const stripColors = function (string) {
export default class KbnLoggerJsonFormat extends LogFormat {
format(data) {
data.message = stripColors(data.message);
data['@timestamp'] = this.extractAndFormatTimestamp(data);
return stringify(data);
}
}
5 changes: 2 additions & 3 deletions src/server/logging/log_format_string.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import _ from 'lodash';
import ansicolors from 'ansicolors';
import moment from 'moment';

import LogFormat from './log_format';

Expand Down Expand Up @@ -44,9 +43,9 @@ const type = _.memoize(function (t) {

const workerType = process.env.kbnWorkerType ? `${type(process.env.kbnWorkerType)} ` : '';

export default class KbnLoggerJsonFormat extends LogFormat {
export default class KbnLoggerStringFormat extends LogFormat {
format(data) {
const time = color('time')(moment(data.timestamp).utc().format('HH:mm:ss.SSS'));
const time = color('time')(this.extractAndFormatTimestamp(data, 'HH:mm:ss.SSS'));
const msg = data.error ? color('error')(data.error.stack) : color('message')(data.message);

const tags = _(data.tags)
Expand Down

0 comments on commit abab9fc

Please sign in to comment.