Skip to content

Commit

Permalink
add typing for legacy logging events
Browse files Browse the repository at this point in the history
  • Loading branch information
pgayvallet committed Nov 19, 2020
1 parent 294a05a commit f2766e5
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 17 deletions.
81 changes: 81 additions & 0 deletions packages/kbn-legacy-logging/src/log_events.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { EventData, isEventData } from './metadata';

export interface BaseEvent {
event: string;
timestamp: string;
pid: string;
tags?: string[];
}

export interface ResponseEvent extends BaseEvent {
event: 'response';
method: 'GET' | 'POST' | 'PUT' | 'DELETE';
statusCode: number;
path: string;
headers: Record<string, string | string[]>;
responsePayload: string;
responseTime: string;
query: Record<string, any>;
}

export interface OpsEvent extends BaseEvent {
event: 'ops';
pid: string;
os: {
load: string[];
};
proc: Record<string, any>;
load: string;
}

export interface ErrorEvent extends BaseEvent {
event: 'error';
error: Error;
url: string;
}

export interface UndeclaredErrorEvent extends BaseEvent {
error: Error;
}

export interface LogEvent extends BaseEvent {
data: EventData;
}

export interface UnkownEvent extends BaseEvent {
data: string | Record<string, any>;
}

export type AnyEvent =
| ResponseEvent
| OpsEvent
| ErrorEvent
| UndeclaredErrorEvent
| LogEvent
| UnkownEvent;

export const isResponseEvent = (e: AnyEvent): e is ResponseEvent => e.event === 'response';
export const isOpsEvent = (e: AnyEvent): e is OpsEvent => e.event === 'ops';
export const isErrorEvent = (e: AnyEvent): e is ErrorEvent => e.event === 'error';
export const isLogEvent = (e: AnyEvent): e is LogEvent => isEventData((e as LogEvent).data);
export const isUndeclaredErrorEvent = (e: AnyEvent): e is UndeclaredErrorEvent =>
(e as any).error instanceof Error;
40 changes: 24 additions & 16 deletions packages/kbn-legacy-logging/src/log_format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,16 @@ import stringify from 'json-stringify-safe';
import { inspect } from 'util';

import { applyFiltersToKeys } from './utils';
import { isLogEvent, getLogEventData } from './metadata';
import { getLogEventData } from './metadata';
import { LegacyLoggingConfig } from './schema';
import {
AnyEvent,
isResponseEvent,
isOpsEvent,
isErrorEvent,
isLogEvent,
isUndeclaredErrorEvent,
} from './log_events';

export type LogFormatConfig = Pick<LegacyLoggingConfig, 'json' | 'dest' | 'timezone' | 'filter'>;

Expand Down Expand Up @@ -67,7 +75,7 @@ export abstract class BaseLogFormat extends Stream.Transform {
return applyFiltersToKeys(data, this.config.filter);
}

_transform(event: any, enc: string, next: Stream.TransformCallback) {
_transform(event: AnyEvent, enc: string, next: Stream.TransformCallback) {
const data = this.filter(this.readEvent(event));
this.push(this.format(data) + '\n');
next();
Expand All @@ -82,15 +90,15 @@ export abstract class BaseLogFormat extends Stream.Transform {
return date.format(format);
}

readEvent(event: any) {
readEvent(event: AnyEvent) {
const data: Record<string, any> = {
type: event.event,
'@timestamp': event.timestamp,
tags: [].concat(event.tags || []),
tags: [...(event.tags ?? [])],
pid: event.pid,
};

if (data.type === 'response') {
if (isResponseEvent(event)) {
_.defaults(data, _.pick(event, ['method', 'statusCode']));

const source = _.get(event, 'source', {});
Expand All @@ -103,12 +111,10 @@ export abstract class BaseLogFormat extends Stream.Transform {
referer: source.referer,
};

let contentLength = 0;
if (typeof event.responsePayload === 'object') {
contentLength = stringify(event.responsePayload).length;
} else {
contentLength = String(event.responsePayload).length;
}
const contentLength =
event.responsePayload === 'object'
? stringify(event.responsePayload).length
: String(event.responsePayload).length;

data.res = {
statusCode: event.statusCode,
Expand All @@ -117,7 +123,9 @@ export abstract class BaseLogFormat extends Stream.Transform {
};

const query = queryString.stringify(event.query, { sort: false });
if (query) data.req.url += '?' + query;
if (query) {
data.req.url += '?' + query;
}

data.message = data.req.method.toUpperCase() + ' ';
data.message += data.req.url;
Expand All @@ -126,7 +134,7 @@ export abstract class BaseLogFormat extends Stream.Transform {
data.message += ' ';
data.message += chalk.gray(data.res.responseTime + 'ms');
data.message += chalk.gray(' - ' + numeral(contentLength).format('0.0b'));
} else if (data.type === 'ops') {
} else if (isOpsEvent(event)) {
_.defaults(data, _.pick(event, ['pid', 'os', 'proc', 'load']));
data.message = chalk.gray('memory: ');
data.message += numeral(_.get(data, 'proc.mem.heapUsed')).format('0.0b');
Expand All @@ -144,19 +152,19 @@ export abstract class BaseLogFormat extends Stream.Transform {
data.message += ' ';
data.message += chalk.gray('delay: ');
data.message += numeral(_.get(data, 'proc.delay')).format('0.000');
} else if (data.type === 'error') {
} else if (isErrorEvent(event)) {
data.level = 'error';
data.error = serializeError(event.error);
data.url = event.url;
const message = _.get(event, 'error.message');
data.message = message || 'Unknown error (no message)';
} else if (event.error instanceof Error) {
} else if (isUndeclaredErrorEvent(event)) {
data.type = 'error';
data.level = _.includes(event.tags, 'fatal') ? 'fatal' : 'error';
data.error = serializeError(event.error);
const message = _.get(event, 'error.message');
data.message = message || 'Unknown error object (no message)';
} else if (isLogEvent(event.data)) {
} else if (isLogEvent(event)) {
_.assign(data, getLogEventData(event.data));
} else {
data.message = _.isString(event.data) ? event.data : inspect(event.data);
Expand Down
2 changes: 1 addition & 1 deletion packages/kbn-legacy-logging/src/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export interface EventMetadata {
metadata: Record<string, any>;
}

export const isLogEvent = (eventData: EventData) => {
export const isEventData = (eventData: EventData) => {
return Boolean(isPlainObject(eventData) && eventData[metadataSymbol]);
};

Expand Down

0 comments on commit f2766e5

Please sign in to comment.