Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NP] Add meta-data and timestamp formatting for Log Record #56982

Merged
merged 11 commits into from
Feb 12, 2020

Conversation

mshustov
Copy link
Contributor

@mshustov mshustov commented Feb 6, 2020

Summary

Meta

pattern: 'layout':

PR introduces {meta} conversion. meta data logged (if present) as a result of JSON stringified:

[2012-02-01T00:00:00.000Z][DEBUG][context-meta][{"from":"v7","to":"v8"}] message-meta

pattern: 'json'

continues logging meta-data as a separate field to prevent property overlapping.
This is different from LP format and elasticsearch format, where meta data allowed to override log record fields!

"@timestamp": "2012-02-01T00:00:00.000Z",
"context": "context-with-meta",
"level": "DEBUG",
"message": "message-with-meta",
"meta":{
  "from":"v7",
  "to":"v8
"},
"pid":5355

Timestamp

pattern: 'layout'

PR introduces additional config fields for timestamp: date format and timezone. Declared similarly to log4j format: {timestamp{FORMAT}{TIMEZONE}}.

I'm a bit hesitant to allow users to specify any custom date format since it introduces an implicit dependency on moment, so I added only 5 predefined formats for now:

  • ISO8601 : 2020-02-01T10:00:00.000
  • ISO801_WITH_TZ: 2020-02-01T10:00:00.000+01:00
  • ABSOLUTE: 10:00:00.000
  • UNIX: 1580899135
  • UNIX_MILLIS: 1580899154504

We can allow custom formats later if see that it's required.

Compat with legacy: LP provides timestamp configuration only and always logs in format of HH:mm:ss.SSS.

pattern: 'json'

The current format is identical to elasticsearch ESJsonLayout yyyy-MM-dd'T'HH:mm:ss,SSSZZ, but uses . separator to be closer to moment().toISOString()
https://github.com/elastic/elasticsearch/blob/a4a79670f85d5c135c1ad668c387808fffd733f7/server/src/main/java/org/elasticsearch/common/logging/ESJsonLayout.java#L91

{"type": "server", "timestamp": "2020-02-05T09:52:52,861+01:00",  ..... }

LP @timestamp format for json layout: YYYY-MM-DDTHH:mm:ssZZ

{ "@timestamp":"2020-02-09T12:46:42+01:00", ...}

users cannot specify a different format.

Checklist

Delete any items that are not applicable to this PR.

For maintainers

@mshustov mshustov added Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc Feature:New Platform v8.0.0 release_note:skip Skip the PR/issue when compiling release notes v7.7.0 labels Feb 6, 2020
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-platform (Team:Platform)

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

@elastic elastic deleted a comment from kibanamachine Feb 7, 2020
@elasticmachine
Copy link
Contributor

💔 Build Failed


Test Failures

Kibana Pipeline / kibana-intake-agent / Jest Tests.src/core/server/logging/layouts.format timestamp supports specifying a predefined format ABSOLUTE

Link to Jenkins

Standard Out

Failed Tests Reporter:
  - Test has not failed recently on tracked branches


Stack Trace

Error: expect(received).toBe(expected) // Object.is equality

Expected: "[01:00:00,000][context]"
Received: "[00:00:00,000][context]"
    at Object.it (/var/lib/jenkins/workspace/elastic+kibana+pipeline-pull-request/kibana/src/core/server/logging/layouts/pattern_layout.test.ts:226:39)
    at Object.asyncJestTest (/var/lib/jenkins/workspace/elastic+kibana+pipeline-pull-request/kibana/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:102:37)
    at resolve (/var/lib/jenkins/workspace/elastic+kibana+pipeline-pull-request/kibana/node_modules/jest-jasmine2/build/queueRunner.js:43:12)
    at new Promise (<anonymous>)
    at mapper (/var/lib/jenkins/workspace/elastic+kibana+pipeline-pull-request/kibana/node_modules/jest-jasmine2/build/queueRunner.js:26:19)
    at promise.then (/var/lib/jenkins/workspace/elastic+kibana+pipeline-pull-request/kibana/node_modules/jest-jasmine2/build/queueRunner.js:73:41)
    at process._tickCallback (internal/process/next_tick.js:68:7)

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

@mshustov mshustov changed the title [NP] Log record meta data [NP] Add meta-data and timestamp formatting for Log Record Feb 7, 2020
@@ -45,6 +45,7 @@ jest.mock('moment-timezone', () => {
// timezone in all tests.
const moment = jest.requireActual('moment-timezone');
moment.tz.guess = () => 'America/New_York';
moment.tz.setDefault('America/New_York');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unifying timezone across all the tests. Should be compatible with the guess result.

@mshustov mshustov marked this pull request as ready for review February 10, 2020 08:52
@mshustov mshustov requested review from a team as code owners February 10, 2020 08:52
Copy link
Member

@dgieselaar dgieselaar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

APM changes LGTM! Thanks

@kibanamachine
Copy link
Contributor

💚 Build Succeeded

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

@joshdover
Copy link
Contributor

Just to be clear, these differences only affect appenders configured with the new logging config, correct? The legacy logging functionality is untouched?

import { Conversion } from './type';
import { LogRecord } from '../../log_record';

const timestampRegExp = /{timestamp({(?<format>[^}]+)})?({(?<timezone>[^}]+)})?}/gi;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think maybe my last comment here was missed: #41956 (comment)

Is there a reason we can't support the same syntax as log4j? Eg. %timestamp{options} instead of {timestamp{options}}?

Copy link
Contributor Author

@mshustov mshustov Feb 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my bad, I forgot to answer: agree, we can switch to log4h-like syntax, but I will do it in a separate PR since it affects all the tests. added to #41956

Copy link
Contributor

@pgayvallet pgayvallet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please ignore the personal NIT if you feel like it.

The only (minor) thing that bothers me is regarding colorization. With current implementation, level/context will not colorize their outer []. This make sense technically, as the [] are manually specified around the {level} parts in the format, but I wonder if we should find a way to allow to colorize that.

My point being that with, say
pattern = "[{timestamp}][{level}][{context}]{meta} {message}";, I think the user might want to be able to have the whole [WARN] colorized instead of uncolorized('[')colorized('WARN')uncolorized(']') ?

pattern: /{message}/gi,
formatter(record: LogRecord) {
// Error stack is much more useful than just the message.
return (record.error && record.error.stack) || record.message;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case of errors, can we have both error and message on the record?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, but record.message === record.error.message. I suspect it was done in this way to simplify typings

message: errorOrMessage.message,

@mshustov
Copy link
Contributor Author

Just to be clear, these differences only affect appenders configured with the new logging config, correct? The legacy logging functionality is untouched?

The LP logging shouldn't be affected.

The only (minor) thing that bothers me is regarding colorization. With current implementation, level/context will not colorize their outer []. This make sense technically, as the [] are manually specified around the {level} parts in the format, but I wonder if we should find a way to allow to colorize that.

[ and ] are part of a template. We shouldn't make assumptions about the conversion position in the template, nor should we affect any user-defined template by our colorization.
Elasticsearch output, for comparison:
2020-02-11_14-12-03
Probably in the future we add log4j colorization conversion support to allow users to specify a custom color for any parts of layout pattern %blue{[%level]}.

Copy link
Contributor

@joshdover joshdover left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally, worked as expected 👍

pid: 5355,
meta: {},
})
).toBe('[2012-02-01T14:30:22.011Z][DEBUG][context-meta][{}] message-meta');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it useful to include meta in the layout if it's an empty object?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

an object could be empty or stringified to an empty object. In this case, I'd rather show it explicitly in logs. Otherwise, we will have complaints on
meta-object disappearing from the logs.

let something = undefined;
// ....
log('message', { something }); // absence from the log since stringified to an empty object

export const LevelConversion: Conversion = {
pattern: /{level}/gi,
formatter(record: LogRecord, highlight: boolean) {
let message = record.level.id.toUpperCase().padEnd(5);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL about the padEnd and padStart methods.

}

export const TimestampConversion: Conversion = {
pattern: timestampRegExp,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some of the more complex regexes, what do you think about testing them directly? It's sort of covered in the tests on PatternLayout, but it could be useful to test the edge cases of the regex explicitly. Maybe would make sense to do after changing to the log4j syntax.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could move tests here, but I think it's more important to test conversion compatibility. That would be especially important when we introduce nested patterns (like from example with colorization) %blue{[%level]}

@mshustov mshustov merged commit 2abc3f5 into elastic:master Feb 12, 2020
@mshustov mshustov deleted the log-record-meta branch February 12, 2020 08:04
mshustov added a commit to mshustov/kibana that referenced this pull request Feb 12, 2020
…6982)

* log meta in pattern layout

* address pgayvallet comment

* add conversion patterns for timestamp

* use comparison instead of inline snapshots

* logs. use elasticsearch and LP compatible timezone format in json layout

* use regexp groups and dot separator for ms. as in default iso format

* use America/New_York timezone as default as it set in guess anyway

* fix APM tests. they need to reset timezone locally and restore it after

* fix logging tests
@mshustov
Copy link
Contributor Author

@pgayvallet I fixed your nits, but didn't push changes. will do in the following PR

mshustov added a commit that referenced this pull request Feb 12, 2020
…57419)

* log meta in pattern layout

* address pgayvallet comment

* add conversion patterns for timestamp

* use comparison instead of inline snapshots

* logs. use elasticsearch and LP compatible timezone format in json layout

* use regexp groups and dot separator for ms. as in default iso format

* use America/New_York timezone as default as it set in guess anyway

* fix APM tests. they need to reset timezone locally and restore it after

* fix logging tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backported Feature:New Platform release_note:skip Skip the PR/issue when compiling release notes Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v7.7.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants