-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[core.logging] Add ops logs to the KP logging system (#88070)
Co-authored-by: Kibana Machine <[email protected]>
- Loading branch information
1 parent
8250b07
commit c6cfdee
Showing
12 changed files
with
482 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* and the Server Side Public License, v 1; you may not use this file except in | ||
* compliance with, at your election, the Elastic License or the Server Side | ||
* Public License, v 1. | ||
*/ | ||
|
||
/** | ||
* Typings for some ECS fields which core uses internally. | ||
* These are not a complete set of ECS typings and should not | ||
* be used externally; the only types included here are ones | ||
* currently used in core. | ||
* | ||
* @internal | ||
*/ | ||
|
||
export interface EcsOpsMetricsEvent { | ||
/** | ||
* These typings were written as of ECS 1.7.0. | ||
* Don't change this value without checking the rest | ||
* of the types to conform to that ECS version. | ||
* | ||
* https://www.elastic.co/guide/en/ecs/1.7/index.html | ||
*/ | ||
ecs: { version: '1.7.0' }; | ||
|
||
// base fields | ||
['@timestamp']?: string; | ||
labels?: Record<string, unknown>; | ||
message?: string; | ||
tags?: string[]; | ||
// other fields | ||
process?: EcsProcessField; | ||
event?: EcsEventField; | ||
} | ||
|
||
interface EcsProcessField { | ||
uptime?: number; | ||
} | ||
|
||
export interface EcsEventField { | ||
kind?: EcsEventKind; | ||
category?: EcsEventCategory[]; | ||
type?: EcsEventType; | ||
} | ||
|
||
export enum EcsEventKind { | ||
ALERT = 'alert', | ||
EVENT = 'event', | ||
METRIC = 'metric', | ||
STATE = 'state', | ||
PIPELINE_ERROR = 'pipeline_error', | ||
SIGNAL = 'signal', | ||
} | ||
|
||
export enum EcsEventCategory { | ||
AUTHENTICATION = 'authentication', | ||
CONFIGURATION = 'configuration', | ||
DATABASE = 'database', | ||
DRIVER = 'driver', | ||
FILE = 'file', | ||
HOST = 'host', | ||
IAM = 'iam', | ||
INTRUSION_DETECTION = 'intrusion_detection', | ||
MALWARE = 'malware', | ||
NETWORK = 'network', | ||
PACKAGE = 'package', | ||
PROCESS = 'process', | ||
WEB = 'web', | ||
} | ||
|
||
export enum EcsEventType { | ||
ACCESS = 'access', | ||
ADMIN = 'admin', | ||
ALLOWED = 'allowed', | ||
CHANGE = 'change', | ||
CONNECTION = 'connection', | ||
CREATION = 'creation', | ||
DELETION = 'deletion', | ||
DENIED = 'denied', | ||
END = 'end', | ||
ERROR = 'error', | ||
GROUP = 'group', | ||
INFO = 'info', | ||
INSTALLATION = 'installation', | ||
PROTOCOL = 'protocol', | ||
START = 'start', | ||
USER = 'user', | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
132 changes: 132 additions & 0 deletions
132
src/core/server/metrics/logging/get_ops_metrics_log.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* and the Server Side Public License, v 1; you may not use this file except in | ||
* compliance with, at your election, the Elastic License or the Server Side | ||
* Public License, v 1. | ||
*/ | ||
|
||
import { OpsMetrics } from '..'; | ||
import { getEcsOpsMetricsLog } from './get_ops_metrics_log'; | ||
|
||
function createBaseOpsMetrics(): OpsMetrics { | ||
return { | ||
collected_at: new Date('2020-01-01 01:00:00'), | ||
process: { | ||
memory: { | ||
heap: { total_in_bytes: 1, used_in_bytes: 1, size_limit: 1 }, | ||
resident_set_size_in_bytes: 1, | ||
}, | ||
event_loop_delay: 1, | ||
pid: 1, | ||
uptime_in_millis: 1, | ||
}, | ||
os: { | ||
platform: 'darwin' as const, | ||
platformRelease: 'test', | ||
load: { '1m': 1, '5m': 1, '15m': 1 }, | ||
memory: { total_in_bytes: 1, free_in_bytes: 1, used_in_bytes: 1 }, | ||
uptime_in_millis: 1, | ||
}, | ||
response_times: { avg_in_millis: 1, max_in_millis: 1 }, | ||
requests: { disconnects: 1, total: 1, statusCodes: { '200': 1 } }, | ||
concurrent_connections: 1, | ||
}; | ||
} | ||
|
||
function createMockOpsMetrics(testMetrics: Partial<OpsMetrics>): OpsMetrics { | ||
const base = createBaseOpsMetrics(); | ||
return { | ||
...base, | ||
...testMetrics, | ||
}; | ||
} | ||
const testMetrics = ({ | ||
process: { | ||
memory: { heap: { used_in_bytes: 100 } }, | ||
uptime_in_millis: 1500, | ||
event_loop_delay: 50, | ||
}, | ||
os: { | ||
load: { | ||
'1m': 10, | ||
'5m': 20, | ||
'15m': 30, | ||
}, | ||
}, | ||
} as unknown) as Partial<OpsMetrics>; | ||
|
||
describe('getEcsOpsMetricsLog', () => { | ||
it('provides correctly formatted message', () => { | ||
const result = getEcsOpsMetricsLog(createMockOpsMetrics(testMetrics)); | ||
expect(result.message).toMatchInlineSnapshot( | ||
`"memory: 100.0B uptime: 0:00:01 load: [10.00,20.00,30.00] delay: 50.000"` | ||
); | ||
}); | ||
|
||
it('correctly formats process uptime', () => { | ||
const logMeta = getEcsOpsMetricsLog(createMockOpsMetrics(testMetrics)); | ||
expect(logMeta.process!.uptime).toEqual(1); | ||
}); | ||
|
||
it('excludes values from the message if unavailable', () => { | ||
const baseMetrics = createBaseOpsMetrics(); | ||
const missingMetrics = ({ | ||
...baseMetrics, | ||
process: {}, | ||
os: {}, | ||
} as unknown) as OpsMetrics; | ||
const logMeta = getEcsOpsMetricsLog(missingMetrics); | ||
expect(logMeta.message).toMatchInlineSnapshot(`""`); | ||
}); | ||
|
||
it('specifies correct ECS version', () => { | ||
const logMeta = getEcsOpsMetricsLog(createBaseOpsMetrics()); | ||
expect(logMeta.ecs.version).toBe('1.7.0'); | ||
}); | ||
|
||
it('provides an ECS-compatible response', () => { | ||
const logMeta = getEcsOpsMetricsLog(createBaseOpsMetrics()); | ||
expect(logMeta).toMatchInlineSnapshot(` | ||
Object { | ||
"ecs": Object { | ||
"version": "1.7.0", | ||
}, | ||
"event": Object { | ||
"category": Array [ | ||
"process", | ||
"host", | ||
], | ||
"kind": "metric", | ||
"type": "info", | ||
}, | ||
"host": Object { | ||
"os": Object { | ||
"load": Object { | ||
"15m": 1, | ||
"1m": 1, | ||
"5m": 1, | ||
}, | ||
}, | ||
}, | ||
"message": "memory: 1.0B load: [1.00,1.00,1.00] delay: 1.000", | ||
"process": Object { | ||
"eventLoopDelay": 1, | ||
"memory": Object { | ||
"heap": Object { | ||
"usedInBytes": 1, | ||
}, | ||
}, | ||
"uptime": 0, | ||
}, | ||
} | ||
`); | ||
}); | ||
|
||
it('logs ECS fields in the log meta', () => { | ||
const logMeta = getEcsOpsMetricsLog(createBaseOpsMetrics()); | ||
expect(logMeta.event!.kind).toBe('metric'); | ||
expect(logMeta.event!.category).toEqual(expect.arrayContaining(['process', 'host'])); | ||
expect(logMeta.event!.type).toBe('info'); | ||
}); | ||
}); |
Oops, something went wrong.