* align logging config with ES. rename kind to type. * rename file "path" to "fileName" * rename logger "context" to "name" * update audit log docs and tests * update docs * fix integration tests * update deprecations for audit appender * add tests for audit logging deprecations * fix eslint problem Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> # Conflicts: # x-pack/plugins/security/server/config_deprecations.ts
This commit is contained in:
parent
afaf615909
commit
6d7ab50074
51 changed files with 468 additions and 355 deletions
|
@ -34,7 +34,7 @@ Customize the configuration for the plugins.data.search context.
|
|||
core.logging.configure(
|
||||
of({
|
||||
appenders: new Map(),
|
||||
loggers: [{ context: 'search', appenders: ['default'] }]
|
||||
loggers: [{ name: 'search', appenders: ['default'] }]
|
||||
})
|
||||
)
|
||||
|
||||
|
|
|
@ -356,26 +356,26 @@ To enable the <<xpack-security-ecs-audit-logging, ECS audit logger>>, specify wh
|
|||
[source,yaml]
|
||||
----------------------------------------
|
||||
xpack.security.audit.appender:
|
||||
kind: rolling-file
|
||||
path: ./audit.log
|
||||
type: rolling-file
|
||||
fileName: ./audit.log
|
||||
policy:
|
||||
kind: time-interval
|
||||
type: time-interval
|
||||
interval: 24h <1>
|
||||
strategy:
|
||||
kind: numeric
|
||||
type: numeric
|
||||
max: 10 <2>
|
||||
layout:
|
||||
kind: json
|
||||
type: json
|
||||
----------------------------------------
|
||||
<1> Rotates log files every 24 hours.
|
||||
<2> Keeps maximum of 10 log files before deleting older ones.
|
||||
|
||||
| `xpack.security.audit.appender.kind`
|
||||
| `xpack.security.audit.appender.type`
|
||||
| Required. Specifies where audit logs should be written to. Allowed values are `console`, `file`, or `rolling-file`.
|
||||
|
||||
Refer to <<audit-logging-file-appender>> and <<audit-logging-rolling-file-appender>> for appender specific settings.
|
||||
|
||||
| `xpack.security.audit.appender.layout.kind`
|
||||
| `xpack.security.audit.appender.layout.type`
|
||||
| Required. Specifies how audit logs should be formatted. Allowed values are `json` or `pattern`.
|
||||
|
||||
Refer to <<audit-logging-pattern-layout>> for layout specific settings.
|
||||
|
@ -396,7 +396,7 @@ The `file` appender writes to a file and can be configured using the following s
|
|||
|
||||
[cols="2*<"]
|
||||
|======
|
||||
| `xpack.security.audit.appender.path`
|
||||
| `xpack.security.audit.appender.fileName`
|
||||
| Required. Full file path the log file should be written to.
|
||||
|======
|
||||
|
||||
|
@ -408,14 +408,14 @@ The `rolling-file` appender writes to a file and rotates it using a rolling stra
|
|||
|
||||
[cols="2*<"]
|
||||
|======
|
||||
| `xpack.security.audit.appender.path`
|
||||
| `xpack.security.audit.appender.fileName`
|
||||
| Required. Full file path the log file should be written to.
|
||||
|
||||
| `xpack.security.audit.appender.policy.kind`
|
||||
| `xpack.security.audit.appender.policy.type`
|
||||
| Specifies when a rollover should occur. Allowed values are `size-limit` and `time-interval`. *Default:* `time-interval`.
|
||||
|
||||
Refer to <<audit-logging-size-limit-policy>> and <<audit-logging-time-interval-policy>> for policy specific settings.
|
||||
| `xpack.security.audit.appender.strategy.kind`
|
||||
| `xpack.security.audit.appender.strategy.type`
|
||||
| Specifies how the rollover should occur. Only allowed value is currently `numeric`. *Default:* `numeric`
|
||||
|
||||
Refer to <<audit-logging-numeric-strategy>> for strategy specific settings.
|
||||
|
|
|
@ -68,10 +68,10 @@ exports[`#get correctly handles silent logging config. 1`] = `
|
|||
Object {
|
||||
"appenders": Object {
|
||||
"default": Object {
|
||||
"kind": "legacy-appender",
|
||||
"legacyLoggingConfig": Object {
|
||||
"silent": true,
|
||||
},
|
||||
"type": "legacy-appender",
|
||||
},
|
||||
},
|
||||
"loggers": undefined,
|
||||
|
@ -85,12 +85,12 @@ exports[`#get correctly handles verbose file logging config with json format. 1`
|
|||
Object {
|
||||
"appenders": Object {
|
||||
"default": Object {
|
||||
"kind": "legacy-appender",
|
||||
"legacyLoggingConfig": Object {
|
||||
"dest": "/some/path.log",
|
||||
"json": true,
|
||||
"verbose": true,
|
||||
},
|
||||
"type": "legacy-appender",
|
||||
},
|
||||
},
|
||||
"loggers": undefined,
|
||||
|
|
|
@ -44,7 +44,7 @@ export class LegacyObjectToConfigAdapter extends ObjectToConfigAdapter {
|
|||
const loggingConfig = {
|
||||
appenders: {
|
||||
...appenders,
|
||||
default: { kind: 'legacy-appender', legacyLoggingConfig },
|
||||
default: { type: 'legacy-appender', legacyLoggingConfig },
|
||||
},
|
||||
root: { level: 'info', ...root },
|
||||
loggers,
|
||||
|
|
|
@ -226,7 +226,7 @@ export class CoreUsageDataService implements CoreService<CoreUsageDataSetup, Cor
|
|||
logging: {
|
||||
appendersTypesUsed: Array.from(
|
||||
Array.from(this.loggingConfig?.appenders.values() ?? [])
|
||||
.reduce((acc, a) => acc.add(a.kind), new Set<string>())
|
||||
.reduce((acc, a) => acc.add(a.type), new Set<string>())
|
||||
.values()
|
||||
),
|
||||
loggersConfiguredCount: this.loggingConfig?.loggers.length ?? 0,
|
||||
|
|
|
@ -50,16 +50,16 @@ describe('request logging', () => {
|
|||
silent: true,
|
||||
appenders: {
|
||||
'test-console': {
|
||||
kind: 'console',
|
||||
type: 'console',
|
||||
layout: {
|
||||
kind: 'pattern',
|
||||
type: 'pattern',
|
||||
pattern: '%level|%logger|%message|%meta',
|
||||
},
|
||||
},
|
||||
},
|
||||
loggers: [
|
||||
{
|
||||
context: 'http.server.response',
|
||||
name: 'http.server.response',
|
||||
appenders: ['test-console'],
|
||||
level: 'debug',
|
||||
},
|
||||
|
@ -96,16 +96,16 @@ describe('request logging', () => {
|
|||
silent: true,
|
||||
appenders: {
|
||||
'test-console': {
|
||||
kind: 'console',
|
||||
type: 'console',
|
||||
layout: {
|
||||
kind: 'pattern',
|
||||
type: 'pattern',
|
||||
pattern: '%level|%logger|%message|%meta',
|
||||
},
|
||||
},
|
||||
},
|
||||
loggers: [
|
||||
{
|
||||
context: 'http.server.response',
|
||||
name: 'http.server.response',
|
||||
appenders: ['test-console'],
|
||||
level: 'debug',
|
||||
},
|
||||
|
|
|
@ -29,16 +29,16 @@ function createRoot(legacyLoggingConfig: LegacyLoggingConfig = {}) {
|
|||
// platform config
|
||||
appenders: {
|
||||
'test-console': {
|
||||
kind: 'console',
|
||||
type: 'console',
|
||||
layout: {
|
||||
highlight: false,
|
||||
kind: 'pattern',
|
||||
type: 'pattern',
|
||||
},
|
||||
},
|
||||
},
|
||||
loggers: [
|
||||
{
|
||||
context: 'test-file',
|
||||
name: 'test-file',
|
||||
appenders: ['test-console'],
|
||||
level: 'info',
|
||||
},
|
||||
|
|
|
@ -16,13 +16,13 @@ afterEach(() => (LegacyLoggingServer as any).mockClear());
|
|||
|
||||
test('`configSchema` creates correct schema.', () => {
|
||||
const appenderSchema = LegacyAppender.configSchema;
|
||||
const validConfig = { kind: 'legacy-appender', legacyLoggingConfig: { verbose: true } };
|
||||
const validConfig = { type: 'legacy-appender', legacyLoggingConfig: { verbose: true } };
|
||||
expect(appenderSchema.validate(validConfig)).toEqual({
|
||||
kind: 'legacy-appender',
|
||||
type: 'legacy-appender',
|
||||
legacyLoggingConfig: { verbose: true },
|
||||
});
|
||||
|
||||
const wrongConfig = { kind: 'not-legacy-appender' };
|
||||
const wrongConfig = { type: 'not-legacy-appender' };
|
||||
expect(() => appenderSchema.validate(wrongConfig)).toThrow();
|
||||
});
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ import { DisposableAppender, LogRecord } from '@kbn/logging';
|
|||
import { LegacyVars } from '../../types';
|
||||
|
||||
export interface LegacyAppenderConfig {
|
||||
kind: 'legacy-appender';
|
||||
type: 'legacy-appender';
|
||||
legacyLoggingConfig?: any;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ export interface LegacyAppenderConfig {
|
|||
*/
|
||||
export class LegacyAppender implements DisposableAppender {
|
||||
public static configSchema = schema.object({
|
||||
kind: schema.literal('legacy-appender'),
|
||||
type: schema.literal('legacy-appender'),
|
||||
legacyLoggingConfig: schema.any(),
|
||||
});
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ Kibana logging system has three main components: _loggers_, _appenders_ and _lay
|
|||
messages according to message type and level, and to control how these messages are formatted and where the final logs
|
||||
will be displayed or stored.
|
||||
|
||||
__Loggers__ define what logging settings should be applied at the particular context.
|
||||
__Loggers__ define what logging settings should be applied at the particular context name.
|
||||
|
||||
__Appenders__ define where log messages are displayed (eg. stdout or console) and stored (eg. file on the disk).
|
||||
|
||||
|
@ -33,17 +33,17 @@ __Layouts__ define how log messages are formatted and what type of information t
|
|||
|
||||
## Logger hierarchy
|
||||
|
||||
Every logger has its unique name or context that follows hierarchical naming rule. The logger is considered to be an
|
||||
Every logger has its unique context name that follows hierarchical naming rule. The logger is considered to be an
|
||||
ancestor of another logger if its name followed by a `.` is a prefix of the descendant logger name. For example logger
|
||||
with `a.b` context is an ancestor of logger with `a.b.c` context. All top-level loggers are descendants of special
|
||||
logger with `root` context that resides at the top of the logger hierarchy. This logger always exists and
|
||||
with `a.b` context name is an ancestor of logger with `a.b.c` context name. All top-level loggers are descendants of special
|
||||
logger with `root` context name that resides at the top of the logger hierarchy. This logger always exists and
|
||||
fully configured.
|
||||
|
||||
Developer can configure _log level_ and _appenders_ that should be used within particular context. If logger configuration
|
||||
Developer can configure _log level_ and _appenders_ that should be used within particular context name. If logger configuration
|
||||
specifies only _log level_ then _appenders_ configuration will be inherited from the ancestor logger.
|
||||
|
||||
__Note:__ in the current implementation log messages are only forwarded to appenders configured for a particular logger
|
||||
context or to appenders of the closest ancestor if current logger doesn't have any appenders configured. That means that
|
||||
context name or to appenders of the closest ancestor if current logger doesn't have any appenders configured. That means that
|
||||
we __don't support__ so called _appender additivity_ when log messages are forwarded to _every_ distinct appender within
|
||||
ancestor chain including `root`.
|
||||
|
||||
|
@ -55,7 +55,7 @@ A log record is being logged by the logger if its level is higher than or equal
|
|||
the log record is ignored.
|
||||
|
||||
The _all_ and _off_ levels can be used only in configuration and are just handy shortcuts that allow developer to log every
|
||||
log record or disable logging entirely for the specific context.
|
||||
log record or disable logging entirely for the specific context name.
|
||||
|
||||
## Layouts
|
||||
|
||||
|
@ -129,7 +129,7 @@ Example of `%date` output:
|
|||
Outputs the process ID.
|
||||
|
||||
### JSON layout
|
||||
With `json` layout log messages will be formatted as JSON strings that include timestamp, log level, context, message
|
||||
With `json` layout log messages will be formatted as JSON strings that include timestamp, log level, context name, message
|
||||
text and any other metadata that may be associated with the log message itself.
|
||||
|
||||
## Appenders
|
||||
|
@ -153,15 +153,15 @@ This policy will rotate the file when it reaches a predetermined size.
|
|||
logging:
|
||||
appenders:
|
||||
rolling-file:
|
||||
kind: rolling-file
|
||||
path: /var/logs/kibana.log
|
||||
type: rolling-file
|
||||
fileName: /var/logs/kibana.log
|
||||
policy:
|
||||
kind: size-limit
|
||||
type: size-limit
|
||||
size: 50mb
|
||||
strategy:
|
||||
//...
|
||||
layout:
|
||||
kind: pattern
|
||||
type: pattern
|
||||
```
|
||||
|
||||
The options are:
|
||||
|
@ -180,16 +180,16 @@ This policy will rotate the file every given interval of time.
|
|||
logging:
|
||||
appenders:
|
||||
rolling-file:
|
||||
kind: rolling-file
|
||||
path: /var/logs/kibana.log
|
||||
type: rolling-file
|
||||
fileName: /var/logs/kibana.log
|
||||
policy:
|
||||
kind: time-interval
|
||||
type: time-interval
|
||||
interval: 10s
|
||||
modulate: true
|
||||
strategy:
|
||||
//...
|
||||
layout:
|
||||
kind: pattern
|
||||
type: pattern
|
||||
```
|
||||
|
||||
The options are:
|
||||
|
@ -225,16 +225,16 @@ and will retains a fixed amount of rolled files.
|
|||
logging:
|
||||
appenders:
|
||||
rolling-file:
|
||||
kind: rolling-file
|
||||
path: /var/logs/kibana.log
|
||||
type: rolling-file
|
||||
fileName: /var/logs/kibana.log
|
||||
policy:
|
||||
// ...
|
||||
strategy:
|
||||
kind: numeric
|
||||
type: numeric
|
||||
pattern: '-%i'
|
||||
max: 2
|
||||
layout:
|
||||
kind: pattern
|
||||
type: pattern
|
||||
```
|
||||
|
||||
For example, with this configuration:
|
||||
|
@ -253,7 +253,7 @@ The options are:
|
|||
The suffix to append to the file path when rolling. Must include `%i`, as this is the value
|
||||
that will be converted to the file index.
|
||||
|
||||
for example, with `path: /var/logs/kibana.log` and `pattern: '-%i'`, the created rolling files
|
||||
for example, with `fileName: /var/logs/kibana.log` and `pattern: '-%i'`, the created rolling files
|
||||
will be `/var/logs/kibana-1.log`, `/var/logs/kibana-2.log`, and so on.
|
||||
|
||||
The default value is `-%i`
|
||||
|
@ -278,49 +278,49 @@ Here is the configuration example that can be used to configure _loggers_, _appe
|
|||
logging:
|
||||
appenders:
|
||||
console:
|
||||
kind: console
|
||||
type: console
|
||||
layout:
|
||||
kind: pattern
|
||||
type: pattern
|
||||
highlight: true
|
||||
file:
|
||||
kind: file
|
||||
path: /var/log/kibana.log
|
||||
type: file
|
||||
fileName: /var/log/kibana.log
|
||||
layout:
|
||||
kind: pattern
|
||||
type: pattern
|
||||
custom:
|
||||
kind: console
|
||||
type: console
|
||||
layout:
|
||||
kind: pattern
|
||||
type: pattern
|
||||
pattern: "[%date][%level] %message"
|
||||
json-file-appender:
|
||||
kind: file
|
||||
path: /var/log/kibana-json.log
|
||||
type: file
|
||||
fileName: /var/log/kibana-json.log
|
||||
|
||||
root:
|
||||
appenders: [console, file]
|
||||
level: error
|
||||
|
||||
loggers:
|
||||
- context: plugins
|
||||
- name: plugins
|
||||
appenders: [custom]
|
||||
level: warn
|
||||
- context: plugins.myPlugin
|
||||
- name: plugins.myPlugin
|
||||
level: info
|
||||
- context: server
|
||||
- name: server
|
||||
level: fatal
|
||||
- context: optimize
|
||||
- name: optimize
|
||||
appenders: [console]
|
||||
- context: telemetry
|
||||
- name: telemetry
|
||||
level: all
|
||||
appenders: [json-file-appender]
|
||||
- context: metrics.ops
|
||||
- name: metrics.ops
|
||||
level: debug
|
||||
appenders: [console]
|
||||
```
|
||||
|
||||
Here is what we get with the config above:
|
||||
|
||||
| Context | Appenders | Level |
|
||||
| Context name | Appenders | Level |
|
||||
| ---------------- |:------------------------:| -----:|
|
||||
| root | console, file | error |
|
||||
| plugins | custom | warn |
|
||||
|
@ -331,7 +331,7 @@ Here is what we get with the config above:
|
|||
| metrics.ops | console | debug |
|
||||
|
||||
|
||||
The `root` logger has a dedicated configuration node since this context is special and should always exist. By
|
||||
The `root` logger has a dedicated configuration node since this context name is special and should always exist. By
|
||||
default `root` is configured with `info` level and `default` appender that is also always available. This is the
|
||||
configuration that all custom loggers will use unless they're re-configured explicitly.
|
||||
|
||||
|
@ -391,7 +391,7 @@ The message contains some high-level information, and the corresponding log meta
|
|||
|
||||
## Usage
|
||||
|
||||
Usage is very straightforward, one should just get a logger for a specific context and use it to log messages with
|
||||
Usage is very straightforward, one should just get a logger for a specific context name and use it to log messages with
|
||||
different log level.
|
||||
|
||||
```typescript
|
||||
|
@ -409,7 +409,7 @@ loggerWithNestedContext.trace('Message with `trace` log level.');
|
|||
loggerWithNestedContext.debug('Message with `debug` log level.');
|
||||
```
|
||||
|
||||
And assuming logger for `server` context with `console` appender and `trace` level was used, console output will look like this:
|
||||
And assuming logger for `server` name with `console` appender and `trace` level was used, console output will look like this:
|
||||
```bash
|
||||
[2017-07-25T11:54:41.639-07:00][TRACE][server] Message with `trace` log level.
|
||||
[2017-07-25T11:54:41.639-07:00][DEBUG][server] Message with `debug` log level.
|
||||
|
@ -422,7 +422,7 @@ And assuming logger for `server` context with `console` appender and `trace` lev
|
|||
[2017-07-25T11:54:41.639-07:00][DEBUG][server.http] Message with `debug` log level.
|
||||
```
|
||||
|
||||
The log will be less verbose with `warn` level for the `server` context:
|
||||
The log will be less verbose with `warn` level for the `server` context name:
|
||||
```bash
|
||||
[2017-07-25T11:54:41.639-07:00][WARN ][server] Message with `warn` log level.
|
||||
[2017-07-25T11:54:41.639-07:00][ERROR][server] Message with `error` log level.
|
||||
|
@ -433,7 +433,7 @@ The log will be less verbose with `warn` level for the `server` context:
|
|||
Compatibility with the legacy logging system is assured until the end of the `v7` version.
|
||||
All log messages handled by `root` context are forwarded to the legacy logging service. If you re-write
|
||||
root appenders, make sure that it contains `default` appender to provide backward compatibility.
|
||||
**Note**: If you define an appender for a context, the log messages aren't handled by the
|
||||
**Note**: If you define an appender for a context name, the log messages aren't handled by the
|
||||
`root` context anymore and not forwarded to the legacy logging service.
|
||||
|
||||
#### logging.dest
|
||||
|
@ -442,21 +442,21 @@ define a custom one.
|
|||
```yaml
|
||||
logging:
|
||||
loggers:
|
||||
- context: plugins.myPlugin
|
||||
- name: plugins.myPlugin
|
||||
appenders: [console]
|
||||
```
|
||||
Logs in a *file* if given file path. You should define a custom appender with `kind: file`
|
||||
Logs in a *file* if given file path. You should define a custom appender with `type: file`
|
||||
```yaml
|
||||
|
||||
logging:
|
||||
appenders:
|
||||
file:
|
||||
kind: file
|
||||
path: /var/log/kibana.log
|
||||
type: file
|
||||
fileName: /var/log/kibana.log
|
||||
layout:
|
||||
kind: pattern
|
||||
type: pattern
|
||||
loggers:
|
||||
- context: plugins.myPlugin
|
||||
- name: plugins.myPlugin
|
||||
appenders: [file]
|
||||
```
|
||||
#### logging.json
|
||||
|
@ -468,7 +468,7 @@ Suppresses all logging output other than error messages. With new logging, confi
|
|||
with adjusting minimum required [logging level](#log-level).
|
||||
```yaml
|
||||
loggers:
|
||||
- context: plugins.myPlugin
|
||||
- name: plugins.myPlugin
|
||||
appenders: [console]
|
||||
level: error
|
||||
# or for all output
|
||||
|
@ -494,32 +494,32 @@ to [specify timezone](#date) for `layout: pattern`. Defaults to host timezone wh
|
|||
logging:
|
||||
appenders:
|
||||
custom-console:
|
||||
kind: console
|
||||
type: console
|
||||
layout:
|
||||
kind: pattern
|
||||
type: pattern
|
||||
highlight: true
|
||||
pattern: "[%level] [%date{ISO8601_TZ}{America/Los_Angeles}][%logger] %message"
|
||||
```
|
||||
|
||||
#### logging.events
|
||||
Define a custom logger for a specific context.
|
||||
Define a custom logger for a specific context name.
|
||||
|
||||
**`logging.events.ops`** outputs sample system and process information at a regular interval.
|
||||
With the new logging config, these are provided by a dedicated [context](#logger-hierarchy),
|
||||
With the new logging config, these are provided by a dedicated [context name](#logger-hierarchy),
|
||||
and you can enable them by adjusting the minimum required [logging level](#log-level) to `debug`:
|
||||
```yaml
|
||||
loggers:
|
||||
- context: metrics.ops
|
||||
- name: metrics.ops
|
||||
appenders: [console]
|
||||
level: debug
|
||||
```
|
||||
|
||||
**`logging.events.request` and `logging.events.response`** provide logs for each request handled
|
||||
by the http service. With the new logging config, these are provided by a dedicated [context](#logger-hierarchy),
|
||||
by the http service. With the new logging config, these are provided by a dedicated [context name](#logger-hierarchy),
|
||||
and you can enable them by adjusting the minimum required [logging level](#log-level) to `debug`:
|
||||
```yaml
|
||||
loggers:
|
||||
- context: http.server.response
|
||||
- name: http.server.response
|
||||
appenders: [console]
|
||||
level: debug
|
||||
```
|
||||
|
@ -532,7 +532,7 @@ TBD
|
|||
| Parameter | Platform log record in **pattern** format | Legacy Platform log record **text** format |
|
||||
| --------------- | ------------------------------------------ | ------------------------------------------ |
|
||||
| @timestamp | ISO8601_TZ `2012-01-31T23:33:22.011-05:00` | Absolute `23:33:22.011` |
|
||||
| context | `parent.child` | `['parent', 'child']` |
|
||||
| context name | `parent.child` | `['parent', 'child']` |
|
||||
| level | `DEBUG` | `['debug']` |
|
||||
| meta | stringified JSON object `{"to": "v8"}` | N/A |
|
||||
| pid | can be configured as `%pid` | N/A |
|
||||
|
@ -540,9 +540,9 @@ TBD
|
|||
| Parameter | Platform log record in **json** format | Legacy Platform log record **json** format |
|
||||
| --------------- | ------------------------------------------ | -------------------------------------------- |
|
||||
| @timestamp | ISO8601_TZ `2012-01-31T23:33:22.011-05:00` | ISO8601 `2012-01-31T23:33:22.011Z` |
|
||||
| context | `context: parent.child` | `tags: ['parent', 'child']` |
|
||||
| level | `level: DEBUG` | `tags: ['debug']` |
|
||||
| context name | `log.logger: parent.child` | `tags: ['parent', 'child']` |
|
||||
| level | `log.level: DEBUG` | `tags: ['debug']` |
|
||||
| meta | separate property `"meta": {"to": "v8"}` | merged in log record `{... "to": "v8"}` |
|
||||
| pid | `pid: 12345` | `pid: 12345` |
|
||||
| pid | `process.pid: 12345` | `pid: 12345` |
|
||||
| type | N/A | `type: log` |
|
||||
| error | `{ message, name, stack }` | `{ message, name, stack, code, signal }` |
|
||||
|
|
|
@ -84,7 +84,7 @@ Object {
|
|||
}
|
||||
`;
|
||||
|
||||
exports[`uses \`root\` logger if context is not specified. 1`] = `
|
||||
exports[`uses \`root\` logger if context name is not specified. 1`] = `
|
||||
Array [
|
||||
Array [
|
||||
"[2012-01-31T03:33:22.011-05:00][INFO ][root] This message goes to a root context.",
|
||||
|
|
|
@ -12,7 +12,7 @@ jest.mock('../layouts/layouts', () => {
|
|||
const { schema } = require('@kbn/config-schema');
|
||||
return {
|
||||
Layouts: {
|
||||
configSchema: schema.object({ kind: schema.literal('mock') }),
|
||||
configSchema: schema.object({ type: schema.literal('mock') }),
|
||||
create: mockCreateLayout,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -21,33 +21,33 @@ beforeEach(() => {
|
|||
|
||||
test('`configSchema` creates correct schema.', () => {
|
||||
const appendersSchema = Appenders.configSchema;
|
||||
const validConfig1 = { kind: 'file', layout: { kind: 'mock' }, path: 'path' };
|
||||
const validConfig1 = { type: 'file', layout: { type: 'mock' }, fileName: 'path' };
|
||||
expect(appendersSchema.validate(validConfig1)).toEqual({
|
||||
kind: 'file',
|
||||
layout: { kind: 'mock' },
|
||||
path: 'path',
|
||||
type: 'file',
|
||||
layout: { type: 'mock' },
|
||||
fileName: 'path',
|
||||
});
|
||||
|
||||
const validConfig2 = { kind: 'console', layout: { kind: 'mock' } };
|
||||
const validConfig2 = { type: 'console', layout: { type: 'mock' } };
|
||||
expect(appendersSchema.validate(validConfig2)).toEqual({
|
||||
kind: 'console',
|
||||
layout: { kind: 'mock' },
|
||||
type: 'console',
|
||||
layout: { type: 'mock' },
|
||||
});
|
||||
|
||||
const wrongConfig1 = {
|
||||
kind: 'console',
|
||||
layout: { kind: 'mock' },
|
||||
path: 'path',
|
||||
type: 'console',
|
||||
layout: { type: 'mock' },
|
||||
fileName: 'path',
|
||||
};
|
||||
expect(() => appendersSchema.validate(wrongConfig1)).toThrow();
|
||||
|
||||
const wrongConfig2 = { kind: 'file', layout: { kind: 'mock' } };
|
||||
const wrongConfig2 = { type: 'file', layout: { type: 'mock' } };
|
||||
expect(() => appendersSchema.validate(wrongConfig2)).toThrow();
|
||||
|
||||
const wrongConfig3 = {
|
||||
kind: 'console',
|
||||
layout: { kind: 'mock' },
|
||||
path: 'path',
|
||||
type: 'console',
|
||||
layout: { type: 'mock' },
|
||||
fileName: 'path',
|
||||
};
|
||||
expect(() => appendersSchema.validate(wrongConfig3)).toThrow();
|
||||
});
|
||||
|
@ -56,31 +56,31 @@ test('`create()` creates correct appender.', () => {
|
|||
mockCreateLayout.mockReturnValue({ format: () => '' });
|
||||
|
||||
const consoleAppender = Appenders.create({
|
||||
kind: 'console',
|
||||
layout: { highlight: true, kind: 'pattern', pattern: '' },
|
||||
type: 'console',
|
||||
layout: { highlight: true, type: 'pattern', pattern: '' },
|
||||
});
|
||||
expect(consoleAppender).toBeInstanceOf(ConsoleAppender);
|
||||
|
||||
const fileAppender = Appenders.create({
|
||||
kind: 'file',
|
||||
layout: { highlight: true, kind: 'pattern', pattern: '' },
|
||||
path: 'path',
|
||||
type: 'file',
|
||||
layout: { highlight: true, type: 'pattern', pattern: '' },
|
||||
fileName: 'path',
|
||||
});
|
||||
expect(fileAppender).toBeInstanceOf(FileAppender);
|
||||
|
||||
const legacyAppender = Appenders.create({
|
||||
kind: 'legacy-appender',
|
||||
type: 'legacy-appender',
|
||||
legacyLoggingConfig: { verbose: true },
|
||||
});
|
||||
|
||||
expect(legacyAppender).toBeInstanceOf(LegacyAppender);
|
||||
|
||||
const rollingFileAppender = Appenders.create({
|
||||
kind: 'rolling-file',
|
||||
path: 'path',
|
||||
layout: { highlight: true, kind: 'pattern', pattern: '' },
|
||||
strategy: { kind: 'numeric', max: 5, pattern: '%i' },
|
||||
policy: { kind: 'size-limit', size: ByteSizeValue.parse('15b') },
|
||||
type: 'rolling-file',
|
||||
fileName: 'path',
|
||||
layout: { highlight: true, type: 'pattern', pattern: '' },
|
||||
strategy: { type: 'numeric', max: 5, pattern: '%i' },
|
||||
policy: { type: 'size-limit', size: ByteSizeValue.parse('15b') },
|
||||
});
|
||||
expect(rollingFileAppender).toBeInstanceOf(RollingFileAppender);
|
||||
});
|
||||
|
|
|
@ -52,11 +52,11 @@ export class Appenders {
|
|||
* @returns Fully constructed `Appender` instance.
|
||||
*/
|
||||
public static create(config: AppenderConfigType): DisposableAppender {
|
||||
switch (config.kind) {
|
||||
switch (config.type) {
|
||||
case 'console':
|
||||
return new ConsoleAppender(Layouts.create(config.layout));
|
||||
case 'file':
|
||||
return new FileAppender(Layouts.create(config.layout), config.path);
|
||||
return new FileAppender(Layouts.create(config.layout), config.fileName);
|
||||
case 'rolling-file':
|
||||
return new RollingFileAppender(config);
|
||||
case 'legacy-appender':
|
||||
|
|
|
@ -12,7 +12,7 @@ jest.mock('../../layouts/layouts', () => {
|
|||
return {
|
||||
Layouts: {
|
||||
configSchema: schema.object({
|
||||
kind: schema.literal('mock'),
|
||||
type: schema.literal('mock'),
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
@ -23,16 +23,16 @@ import { ConsoleAppender } from './console_appender';
|
|||
|
||||
test('`configSchema` creates correct schema.', () => {
|
||||
const appenderSchema = ConsoleAppender.configSchema;
|
||||
const validConfig = { kind: 'console', layout: { kind: 'mock' } };
|
||||
const validConfig = { type: 'console', layout: { type: 'mock' } };
|
||||
expect(appenderSchema.validate(validConfig)).toEqual({
|
||||
kind: 'console',
|
||||
layout: { kind: 'mock' },
|
||||
type: 'console',
|
||||
layout: { type: 'mock' },
|
||||
});
|
||||
|
||||
const wrongConfig1 = { kind: 'not-console', layout: { kind: 'mock' } };
|
||||
const wrongConfig1 = { type: 'not-console', layout: { type: 'mock' } };
|
||||
expect(() => appenderSchema.validate(wrongConfig1)).toThrow();
|
||||
|
||||
const wrongConfig2 = { kind: 'file', layout: { kind: 'mock' }, path: 'path' };
|
||||
const wrongConfig2 = { type: 'file', layout: { type: 'mock' }, fileName: 'path' };
|
||||
expect(() => appenderSchema.validate(wrongConfig2)).toThrow();
|
||||
});
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ import { Layouts, LayoutConfigType } from '../../layouts/layouts';
|
|||
const { literal, object } = schema;
|
||||
|
||||
export interface ConsoleAppenderConfig {
|
||||
kind: 'console';
|
||||
type: 'console';
|
||||
layout: LayoutConfigType;
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ export interface ConsoleAppenderConfig {
|
|||
*/
|
||||
export class ConsoleAppender implements DisposableAppender {
|
||||
public static configSchema = object({
|
||||
kind: literal('console'),
|
||||
type: literal('console'),
|
||||
layout: Layouts.configSchema,
|
||||
});
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ jest.mock('../../layouts/layouts', () => {
|
|||
return {
|
||||
Layouts: {
|
||||
configSchema: schema.object({
|
||||
kind: schema.literal('mock'),
|
||||
type: schema.literal('mock'),
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
|
|
@ -20,24 +20,24 @@ beforeEach(() => {
|
|||
test('`createConfigSchema()` creates correct schema.', () => {
|
||||
const appenderSchema = FileAppender.configSchema;
|
||||
|
||||
const validConfig = { kind: 'file', layout: { kind: 'mock' }, path: 'path' };
|
||||
const validConfig = { type: 'file', layout: { type: 'mock' }, fileName: 'path' };
|
||||
expect(appenderSchema.validate(validConfig)).toEqual({
|
||||
kind: 'file',
|
||||
layout: { kind: 'mock' },
|
||||
path: 'path',
|
||||
type: 'file',
|
||||
layout: { type: 'mock' },
|
||||
fileName: 'path',
|
||||
});
|
||||
|
||||
const wrongConfig1 = {
|
||||
kind: 'not-file',
|
||||
layout: { kind: 'mock' },
|
||||
path: 'path',
|
||||
type: 'not-file',
|
||||
layout: { type: 'mock' },
|
||||
fileName: 'path',
|
||||
};
|
||||
expect(() => appenderSchema.validate(wrongConfig1)).toThrow();
|
||||
|
||||
const wrongConfig2 = { kind: 'file', layout: { kind: 'mock' } };
|
||||
const wrongConfig2 = { type: 'file', layout: { type: 'mock' } };
|
||||
expect(() => appenderSchema.validate(wrongConfig2)).toThrow();
|
||||
|
||||
const wrongConfig3 = { kind: 'console', layout: { kind: 'mock' } };
|
||||
const wrongConfig3 = { type: 'console', layout: { type: 'mock' } };
|
||||
expect(() => appenderSchema.validate(wrongConfig3)).toThrow();
|
||||
});
|
||||
|
||||
|
|
|
@ -13,9 +13,9 @@ import { createWriteStream, WriteStream } from 'fs';
|
|||
import { Layouts, LayoutConfigType } from '../../layouts/layouts';
|
||||
|
||||
export interface FileAppenderConfig {
|
||||
kind: 'file';
|
||||
type: 'file';
|
||||
layout: LayoutConfigType;
|
||||
path: string;
|
||||
fileName: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -24,9 +24,9 @@ export interface FileAppenderConfig {
|
|||
*/
|
||||
export class FileAppender implements DisposableAppender {
|
||||
public static configSchema = schema.object({
|
||||
kind: schema.literal('file'),
|
||||
type: schema.literal('file'),
|
||||
layout: Layouts.configSchema,
|
||||
path: schema.string(),
|
||||
fileName: schema.string(),
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
|
@ -34,7 +34,7 @@ export type TriggeringPolicyConfig =
|
|||
| TimeIntervalTriggeringPolicyConfig;
|
||||
|
||||
const defaultPolicy: TimeIntervalTriggeringPolicyConfig = {
|
||||
kind: 'time-interval',
|
||||
type: 'time-interval',
|
||||
interval: moment.duration(24, 'hour'),
|
||||
modulate: true,
|
||||
};
|
||||
|
@ -48,7 +48,7 @@ export const createTriggeringPolicy = (
|
|||
config: TriggeringPolicyConfig,
|
||||
context: RollingFileContext
|
||||
): TriggeringPolicy => {
|
||||
switch (config.kind) {
|
||||
switch (config.type) {
|
||||
case 'size-limit':
|
||||
return new SizeLimitTriggeringPolicy(config, context);
|
||||
case 'time-interval':
|
||||
|
|
|
@ -15,7 +15,7 @@ describe('SizeLimitTriggeringPolicy', () => {
|
|||
let context: RollingFileContext;
|
||||
|
||||
const createPolicy = (size: ByteSizeValue) =>
|
||||
new SizeLimitTriggeringPolicy({ kind: 'size-limit', size }, context);
|
||||
new SizeLimitTriggeringPolicy({ type: 'size-limit', size }, context);
|
||||
|
||||
const createLogRecord = (parts: Partial<LogRecord> = {}): LogRecord => ({
|
||||
timestamp: new Date(),
|
||||
|
|
|
@ -12,7 +12,7 @@ import { RollingFileContext } from '../../rolling_file_context';
|
|||
import { TriggeringPolicy } from '../policy';
|
||||
|
||||
export interface SizeLimitTriggeringPolicyConfig {
|
||||
kind: 'size-limit';
|
||||
type: 'size-limit';
|
||||
|
||||
/**
|
||||
* The minimum size the file must have to roll over.
|
||||
|
@ -21,7 +21,7 @@ export interface SizeLimitTriggeringPolicyConfig {
|
|||
}
|
||||
|
||||
export const sizeLimitTriggeringPolicyConfigSchema = schema.object({
|
||||
kind: schema.literal('size-limit'),
|
||||
type: schema.literal('size-limit'),
|
||||
size: schema.byteSize({ min: '1b', defaultValue: '100mb' }),
|
||||
});
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ describe('TimeIntervalTriggeringPolicy', () => {
|
|||
interval: string = '15m',
|
||||
modulate: boolean = false
|
||||
): TimeIntervalTriggeringPolicyConfig => ({
|
||||
kind: 'time-interval',
|
||||
type: 'time-interval',
|
||||
interval: schema.duration().validate(interval),
|
||||
modulate,
|
||||
});
|
||||
|
|
|
@ -15,7 +15,7 @@ import { getNextRollingTime } from './get_next_rolling_time';
|
|||
import { isValidRolloverInterval } from './utils';
|
||||
|
||||
export interface TimeIntervalTriggeringPolicyConfig {
|
||||
kind: 'time-interval';
|
||||
type: 'time-interval';
|
||||
|
||||
/**
|
||||
* How often a rollover should occur.
|
||||
|
@ -38,7 +38,7 @@ export interface TimeIntervalTriggeringPolicyConfig {
|
|||
}
|
||||
|
||||
export const timeIntervalTriggeringPolicyConfigSchema = schema.object({
|
||||
kind: schema.literal('time-interval'),
|
||||
type: schema.literal('time-interval'),
|
||||
interval: schema.duration({
|
||||
defaultValue: '24h',
|
||||
validate: (interval) => {
|
||||
|
|
|
@ -20,20 +20,20 @@ import { LogLevel, LogRecord } from '@kbn/logging';
|
|||
import { RollingFileAppender, RollingFileAppenderConfig } from './rolling_file_appender';
|
||||
|
||||
const config: RollingFileAppenderConfig = {
|
||||
kind: 'rolling-file',
|
||||
path: '/var/log/kibana.log',
|
||||
type: 'rolling-file',
|
||||
fileName: '/var/log/kibana.log',
|
||||
layout: {
|
||||
kind: 'pattern',
|
||||
type: 'pattern',
|
||||
pattern: '%message',
|
||||
highlight: false,
|
||||
},
|
||||
policy: {
|
||||
kind: 'time-interval',
|
||||
type: 'time-interval',
|
||||
interval: moment.duration(4, 'hour'),
|
||||
modulate: true,
|
||||
},
|
||||
strategy: {
|
||||
kind: 'numeric',
|
||||
type: 'numeric',
|
||||
max: 5,
|
||||
pattern: '-%i',
|
||||
},
|
||||
|
@ -99,7 +99,7 @@ describe('RollingFileAppender', () => {
|
|||
|
||||
it('constructs its delegates with the correct parameters', () => {
|
||||
expect(RollingFileContextMock).toHaveBeenCalledTimes(1);
|
||||
expect(RollingFileContextMock).toHaveBeenCalledWith(config.path);
|
||||
expect(RollingFileContextMock).toHaveBeenCalledWith(config.fileName);
|
||||
|
||||
expect(RollingFileManagerMock).toHaveBeenCalledTimes(1);
|
||||
expect(RollingFileManagerMock).toHaveBeenCalledWith(context);
|
||||
|
|
|
@ -26,7 +26,7 @@ import { RollingFileManager } from './rolling_file_manager';
|
|||
import { RollingFileContext } from './rolling_file_context';
|
||||
|
||||
export interface RollingFileAppenderConfig {
|
||||
kind: 'rolling-file';
|
||||
type: 'rolling-file';
|
||||
/**
|
||||
* The layout to use when writing log entries
|
||||
*/
|
||||
|
@ -34,7 +34,7 @@ export interface RollingFileAppenderConfig {
|
|||
/**
|
||||
* The absolute path of the file to write to.
|
||||
*/
|
||||
path: string;
|
||||
fileName: string;
|
||||
/**
|
||||
* The {@link TriggeringPolicy | policy} to use to determine if a rollover should occur.
|
||||
*/
|
||||
|
@ -51,9 +51,9 @@ export interface RollingFileAppenderConfig {
|
|||
*/
|
||||
export class RollingFileAppender implements DisposableAppender {
|
||||
public static configSchema = schema.object({
|
||||
kind: schema.literal('rolling-file'),
|
||||
type: schema.literal('rolling-file'),
|
||||
layout: Layouts.configSchema,
|
||||
path: schema.string(),
|
||||
fileName: schema.string(),
|
||||
policy: triggeringPolicyConfigSchema,
|
||||
strategy: rollingStrategyConfigSchema,
|
||||
});
|
||||
|
@ -70,7 +70,7 @@ export class RollingFileAppender implements DisposableAppender {
|
|||
private readonly buffer: BufferAppender;
|
||||
|
||||
constructor(config: RollingFileAppenderConfig) {
|
||||
this.context = new RollingFileContext(config.path);
|
||||
this.context = new RollingFileContext(config.fileName);
|
||||
this.context.refreshFileInfo();
|
||||
this.fileManager = new RollingFileManager(this.context);
|
||||
this.layout = Layouts.create(config.layout);
|
||||
|
|
|
@ -19,7 +19,7 @@ export { RollingStrategy } from './strategy';
|
|||
export type RollingStrategyConfig = NumericRollingStrategyConfig;
|
||||
|
||||
const defaultStrategy: NumericRollingStrategyConfig = {
|
||||
kind: 'numeric',
|
||||
type: 'numeric',
|
||||
pattern: '-%i',
|
||||
max: 7,
|
||||
};
|
||||
|
|
|
@ -27,8 +27,8 @@ describe('NumericRollingStrategy', () => {
|
|||
let context: ReturnType<typeof rollingFileAppenderMocks.createContext>;
|
||||
let strategy: NumericRollingStrategy;
|
||||
|
||||
const createStrategy = (config: Omit<NumericRollingStrategyConfig, 'kind'>) =>
|
||||
new NumericRollingStrategy({ ...config, kind: 'numeric' }, context);
|
||||
const createStrategy = (config: Omit<NumericRollingStrategyConfig, 'type'>) =>
|
||||
new NumericRollingStrategy({ ...config, type: 'numeric' }, context);
|
||||
|
||||
beforeEach(() => {
|
||||
context = rollingFileAppenderMocks.createContext(logFilePath);
|
||||
|
|
|
@ -19,10 +19,10 @@ import {
|
|||
} from './rolling_tasks';
|
||||
|
||||
export interface NumericRollingStrategyConfig {
|
||||
kind: 'numeric';
|
||||
type: 'numeric';
|
||||
/**
|
||||
* The suffix pattern to apply when renaming a file. The suffix will be applied
|
||||
* after the `appender.path` file name, but before the file extension.
|
||||
* after the `appender.fileName` file name, but before the file extension.
|
||||
*
|
||||
* Must include `%i`, as it is the value that will be converted to the file index
|
||||
*
|
||||
|
@ -31,8 +31,8 @@ export interface NumericRollingStrategyConfig {
|
|||
* logging:
|
||||
* appenders:
|
||||
* rolling-file:
|
||||
* kind: rolling-file
|
||||
* path: /var/logs/kibana.log
|
||||
* type: rolling-file
|
||||
* fileName: /var/logs/kibana.log
|
||||
* strategy:
|
||||
* type: default
|
||||
* pattern: "-%i"
|
||||
|
@ -52,7 +52,7 @@ export interface NumericRollingStrategyConfig {
|
|||
}
|
||||
|
||||
export const numericRollingStrategyConfigSchema = schema.object({
|
||||
kind: schema.literal('numeric'),
|
||||
type: schema.literal('numeric'),
|
||||
pattern: schema.string({
|
||||
defaultValue: '-%i',
|
||||
validate: (pattern) => {
|
||||
|
@ -73,8 +73,8 @@ export const numericRollingStrategyConfigSchema = schema.object({
|
|||
* logging:
|
||||
* appenders:
|
||||
* rolling-file:
|
||||
* kind: rolling-file
|
||||
* path: /kibana.log
|
||||
* type: rolling-file
|
||||
* fileName: /kibana.log
|
||||
* strategy:
|
||||
* type: numeric
|
||||
* pattern: "-%i"
|
||||
|
|
|
@ -17,22 +17,22 @@ function createRoot() {
|
|||
silent: true, // set "true" in kbnTestServer
|
||||
appenders: {
|
||||
'test-console': {
|
||||
kind: 'console',
|
||||
type: 'console',
|
||||
layout: {
|
||||
highlight: false,
|
||||
kind: 'pattern',
|
||||
type: 'pattern',
|
||||
pattern: '%level|%logger|%message',
|
||||
},
|
||||
},
|
||||
},
|
||||
loggers: [
|
||||
{
|
||||
context: 'parent',
|
||||
name: 'parent',
|
||||
appenders: ['test-console'],
|
||||
level: 'warn',
|
||||
},
|
||||
{
|
||||
context: 'parent.child',
|
||||
name: 'parent.child',
|
||||
appenders: ['test-console'],
|
||||
level: 'error',
|
||||
},
|
||||
|
@ -42,7 +42,7 @@ function createRoot() {
|
|||
}
|
||||
|
||||
describe('logging service', () => {
|
||||
describe('logs according to context hierarchy', () => {
|
||||
describe('logs according to context name hierarchy', () => {
|
||||
let root: ReturnType<typeof createRoot>;
|
||||
let mockConsoleLog: jest.SpyInstance;
|
||||
beforeAll(async () => {
|
||||
|
@ -61,7 +61,7 @@ describe('logging service', () => {
|
|||
await root.shutdown();
|
||||
});
|
||||
|
||||
it('uses the most specific context', () => {
|
||||
it('uses the most specific context name', () => {
|
||||
const logger = root.logger.get('parent.child');
|
||||
|
||||
logger.error('error from "parent.child" context');
|
||||
|
@ -74,7 +74,7 @@ describe('logging service', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('uses parent context', () => {
|
||||
it('uses parent context name', () => {
|
||||
const logger = root.logger.get('parent.another-child');
|
||||
|
||||
logger.error('error from "parent.another-child" context');
|
||||
|
@ -104,31 +104,31 @@ describe('logging service', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('custom context configuration', () => {
|
||||
describe('custom context name configuration', () => {
|
||||
const CUSTOM_LOGGING_CONFIG: LoggerContextConfigInput = {
|
||||
appenders: {
|
||||
customJsonConsole: {
|
||||
kind: 'console',
|
||||
type: 'console',
|
||||
layout: {
|
||||
kind: 'json',
|
||||
type: 'json',
|
||||
},
|
||||
},
|
||||
customPatternConsole: {
|
||||
kind: 'console',
|
||||
type: 'console',
|
||||
layout: {
|
||||
kind: 'pattern',
|
||||
type: 'pattern',
|
||||
pattern: 'CUSTOM - PATTERN [%logger][%level] %message',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
loggers: [
|
||||
{ context: 'debug_json', appenders: ['customJsonConsole'], level: 'debug' },
|
||||
{ context: 'debug_pattern', appenders: ['customPatternConsole'], level: 'debug' },
|
||||
{ context: 'info_json', appenders: ['customJsonConsole'], level: 'info' },
|
||||
{ context: 'info_pattern', appenders: ['customPatternConsole'], level: 'info' },
|
||||
{ name: 'debug_json', appenders: ['customJsonConsole'], level: 'debug' },
|
||||
{ name: 'debug_pattern', appenders: ['customPatternConsole'], level: 'debug' },
|
||||
{ name: 'info_json', appenders: ['customJsonConsole'], level: 'info' },
|
||||
{ name: 'info_pattern', appenders: ['customPatternConsole'], level: 'info' },
|
||||
{
|
||||
context: 'all',
|
||||
name: 'all',
|
||||
appenders: ['customJsonConsole', 'customPatternConsole'],
|
||||
level: 'debug',
|
||||
},
|
||||
|
|
|
@ -25,7 +25,7 @@ function createRoot(appenderConfig: any) {
|
|||
},
|
||||
loggers: [
|
||||
{
|
||||
context: 'test.rolling.file',
|
||||
name: 'test.rolling.file',
|
||||
appenders: ['rolling-file'],
|
||||
level: 'debug',
|
||||
},
|
||||
|
@ -63,18 +63,18 @@ describe('RollingFileAppender', () => {
|
|||
describe('`size-limit` policy with `numeric` strategy', () => {
|
||||
it('rolls the log file in the correct order', async () => {
|
||||
root = createRoot({
|
||||
kind: 'rolling-file',
|
||||
path: logFile,
|
||||
type: 'rolling-file',
|
||||
fileName: logFile,
|
||||
layout: {
|
||||
kind: 'pattern',
|
||||
type: 'pattern',
|
||||
pattern: '%message',
|
||||
},
|
||||
policy: {
|
||||
kind: 'size-limit',
|
||||
type: 'size-limit',
|
||||
size: '100b',
|
||||
},
|
||||
strategy: {
|
||||
kind: 'numeric',
|
||||
type: 'numeric',
|
||||
max: 5,
|
||||
pattern: '.%i',
|
||||
},
|
||||
|
@ -108,18 +108,18 @@ describe('RollingFileAppender', () => {
|
|||
|
||||
it('only keep the correct number of files', async () => {
|
||||
root = createRoot({
|
||||
kind: 'rolling-file',
|
||||
path: logFile,
|
||||
type: 'rolling-file',
|
||||
fileName: logFile,
|
||||
layout: {
|
||||
kind: 'pattern',
|
||||
type: 'pattern',
|
||||
pattern: '%message',
|
||||
},
|
||||
policy: {
|
||||
kind: 'size-limit',
|
||||
type: 'size-limit',
|
||||
size: '60b',
|
||||
},
|
||||
strategy: {
|
||||
kind: 'numeric',
|
||||
type: 'numeric',
|
||||
max: 2,
|
||||
pattern: '-%i',
|
||||
},
|
||||
|
@ -157,19 +157,19 @@ describe('RollingFileAppender', () => {
|
|||
describe('`time-interval` policy with `numeric` strategy', () => {
|
||||
it('rolls the log file at the given interval', async () => {
|
||||
root = createRoot({
|
||||
kind: 'rolling-file',
|
||||
path: logFile,
|
||||
type: 'rolling-file',
|
||||
fileName: logFile,
|
||||
layout: {
|
||||
kind: 'pattern',
|
||||
type: 'pattern',
|
||||
pattern: '%message',
|
||||
},
|
||||
policy: {
|
||||
kind: 'time-interval',
|
||||
type: 'time-interval',
|
||||
interval: '1s',
|
||||
modulate: true,
|
||||
},
|
||||
strategy: {
|
||||
kind: 'numeric',
|
||||
type: 'numeric',
|
||||
max: 2,
|
||||
pattern: '-%i',
|
||||
},
|
||||
|
|
|
@ -63,7 +63,7 @@ const records: LogRecord[] = [
|
|||
test('`createConfigSchema()` creates correct schema.', () => {
|
||||
const layoutSchema = JsonLayout.configSchema;
|
||||
|
||||
expect(layoutSchema.validate({ kind: 'json' })).toEqual({ kind: 'json' });
|
||||
expect(layoutSchema.validate({ type: 'json' })).toEqual({ type: 'json' });
|
||||
});
|
||||
|
||||
test('`format()` correctly formats record.', () => {
|
||||
|
|
|
@ -14,12 +14,12 @@ import { LogRecord, Layout } from '@kbn/logging';
|
|||
const { literal, object } = schema;
|
||||
|
||||
const jsonLayoutSchema = object({
|
||||
kind: literal('json'),
|
||||
type: literal('json'),
|
||||
});
|
||||
|
||||
/** @internal */
|
||||
export interface JsonLayoutConfigType {
|
||||
kind: 'json';
|
||||
type: 'json';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -12,43 +12,43 @@ import { PatternLayout } from './pattern_layout';
|
|||
|
||||
test('`configSchema` creates correct schema for `pattern` layout.', () => {
|
||||
const layoutsSchema = Layouts.configSchema;
|
||||
const validConfigWithOptional = { kind: 'pattern' };
|
||||
const validConfigWithOptional = { type: 'pattern' };
|
||||
expect(layoutsSchema.validate(validConfigWithOptional)).toEqual({
|
||||
highlight: undefined,
|
||||
kind: 'pattern',
|
||||
type: 'pattern',
|
||||
pattern: undefined,
|
||||
});
|
||||
|
||||
const validConfig = {
|
||||
highlight: true,
|
||||
kind: 'pattern',
|
||||
type: 'pattern',
|
||||
pattern: '%message',
|
||||
};
|
||||
expect(layoutsSchema.validate(validConfig)).toEqual({
|
||||
highlight: true,
|
||||
kind: 'pattern',
|
||||
type: 'pattern',
|
||||
pattern: '%message',
|
||||
});
|
||||
|
||||
const wrongConfig2 = { kind: 'pattern', pattern: 1 };
|
||||
const wrongConfig2 = { type: 'pattern', pattern: 1 };
|
||||
expect(() => layoutsSchema.validate(wrongConfig2)).toThrow();
|
||||
});
|
||||
|
||||
test('`createConfigSchema()` creates correct schema for `json` layout.', () => {
|
||||
const layoutsSchema = Layouts.configSchema;
|
||||
|
||||
const validConfig = { kind: 'json' };
|
||||
expect(layoutsSchema.validate(validConfig)).toEqual({ kind: 'json' });
|
||||
const validConfig = { type: 'json' };
|
||||
expect(layoutsSchema.validate(validConfig)).toEqual({ type: 'json' });
|
||||
});
|
||||
|
||||
test('`create()` creates correct layout.', () => {
|
||||
const patternLayout = Layouts.create({
|
||||
highlight: false,
|
||||
kind: 'pattern',
|
||||
type: 'pattern',
|
||||
pattern: '[%date][%level][%logger] %message',
|
||||
});
|
||||
expect(patternLayout).toBeInstanceOf(PatternLayout);
|
||||
|
||||
const jsonLayout = Layouts.create({ kind: 'json' });
|
||||
const jsonLayout = Layouts.create({ type: 'json' });
|
||||
expect(jsonLayout).toBeInstanceOf(JsonLayout);
|
||||
});
|
||||
|
|
|
@ -27,7 +27,7 @@ export class Layouts {
|
|||
* @returns Fully constructed `Layout` instance.
|
||||
*/
|
||||
public static create(config: LayoutConfigType): Layout {
|
||||
switch (config.kind) {
|
||||
switch (config.type) {
|
||||
case 'json':
|
||||
return new JsonLayout();
|
||||
|
||||
|
|
|
@ -66,28 +66,28 @@ expect.addSnapshotSerializer(stripAnsiSnapshotSerializer);
|
|||
test('`createConfigSchema()` creates correct schema.', () => {
|
||||
const layoutSchema = PatternLayout.configSchema;
|
||||
|
||||
const validConfigWithOptional = { kind: 'pattern' };
|
||||
const validConfigWithOptional = { type: 'pattern' };
|
||||
expect(layoutSchema.validate(validConfigWithOptional)).toEqual({
|
||||
highlight: undefined,
|
||||
kind: 'pattern',
|
||||
type: 'pattern',
|
||||
pattern: undefined,
|
||||
});
|
||||
|
||||
const validConfig = {
|
||||
highlight: true,
|
||||
kind: 'pattern',
|
||||
type: 'pattern',
|
||||
pattern: '%message',
|
||||
};
|
||||
expect(layoutSchema.validate(validConfig)).toEqual({
|
||||
highlight: true,
|
||||
kind: 'pattern',
|
||||
type: 'pattern',
|
||||
pattern: '%message',
|
||||
});
|
||||
|
||||
const wrongConfig1 = { kind: 'json' };
|
||||
const wrongConfig1 = { type: 'json' };
|
||||
expect(() => layoutSchema.validate(wrongConfig1)).toThrow();
|
||||
|
||||
const wrongConfig2 = { kind: 'pattern', pattern: 1 };
|
||||
const wrongConfig2 = { type: 'pattern', pattern: 1 };
|
||||
expect(() => layoutSchema.validate(wrongConfig2)).toThrow();
|
||||
});
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ export const patternSchema = schema.string({
|
|||
|
||||
const patternLayoutSchema = schema.object({
|
||||
highlight: schema.maybe(schema.boolean()),
|
||||
kind: schema.literal('pattern'),
|
||||
type: schema.literal('pattern'),
|
||||
pattern: schema.maybe(patternSchema),
|
||||
});
|
||||
|
||||
|
@ -47,7 +47,7 @@ const conversions: Conversion[] = [
|
|||
|
||||
/** @internal */
|
||||
export interface PatternLayoutConfigType {
|
||||
kind: 'pattern';
|
||||
type: 'pattern';
|
||||
highlight?: boolean;
|
||||
pattern?: string;
|
||||
}
|
||||
|
|
|
@ -51,12 +51,12 @@ test('correctly fills in default config.', () => {
|
|||
expect(configValue.appenders.size).toBe(2);
|
||||
|
||||
expect(configValue.appenders.get('default')).toEqual({
|
||||
kind: 'console',
|
||||
layout: { kind: 'pattern', highlight: true },
|
||||
type: 'console',
|
||||
layout: { type: 'pattern', highlight: true },
|
||||
});
|
||||
expect(configValue.appenders.get('console')).toEqual({
|
||||
kind: 'console',
|
||||
layout: { kind: 'pattern', highlight: true },
|
||||
type: 'console',
|
||||
layout: { type: 'pattern', highlight: true },
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -65,8 +65,8 @@ test('correctly fills in custom `appenders` config.', () => {
|
|||
config.schema.validate({
|
||||
appenders: {
|
||||
console: {
|
||||
kind: 'console',
|
||||
layout: { kind: 'pattern' },
|
||||
type: 'console',
|
||||
layout: { type: 'pattern' },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
@ -75,13 +75,13 @@ test('correctly fills in custom `appenders` config.', () => {
|
|||
expect(configValue.appenders.size).toBe(2);
|
||||
|
||||
expect(configValue.appenders.get('default')).toEqual({
|
||||
kind: 'console',
|
||||
layout: { kind: 'pattern', highlight: true },
|
||||
type: 'console',
|
||||
layout: { type: 'pattern', highlight: true },
|
||||
});
|
||||
|
||||
expect(configValue.appenders.get('console')).toEqual({
|
||||
kind: 'console',
|
||||
layout: { kind: 'pattern' },
|
||||
type: 'console',
|
||||
layout: { type: 'pattern' },
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -91,7 +91,7 @@ test('correctly fills in default `loggers` config.', () => {
|
|||
expect(configValue.loggers.size).toBe(1);
|
||||
expect(configValue.loggers.get('root')).toEqual({
|
||||
appenders: ['default'],
|
||||
context: 'root',
|
||||
name: 'root',
|
||||
level: 'info',
|
||||
});
|
||||
});
|
||||
|
@ -101,24 +101,24 @@ test('correctly fills in custom `loggers` config.', () => {
|
|||
config.schema.validate({
|
||||
appenders: {
|
||||
file: {
|
||||
kind: 'file',
|
||||
layout: { kind: 'pattern' },
|
||||
path: 'path',
|
||||
type: 'file',
|
||||
layout: { type: 'pattern' },
|
||||
fileName: 'path',
|
||||
},
|
||||
},
|
||||
loggers: [
|
||||
{
|
||||
appenders: ['file'],
|
||||
context: 'plugins',
|
||||
name: 'plugins',
|
||||
level: 'warn',
|
||||
},
|
||||
{
|
||||
context: 'plugins.pid',
|
||||
name: 'plugins.pid',
|
||||
level: 'trace',
|
||||
},
|
||||
{
|
||||
appenders: ['default'],
|
||||
context: 'http',
|
||||
name: 'http',
|
||||
level: 'error',
|
||||
},
|
||||
],
|
||||
|
@ -128,22 +128,22 @@ test('correctly fills in custom `loggers` config.', () => {
|
|||
expect(configValue.loggers.size).toBe(4);
|
||||
expect(configValue.loggers.get('root')).toEqual({
|
||||
appenders: ['default'],
|
||||
context: 'root',
|
||||
name: 'root',
|
||||
level: 'info',
|
||||
});
|
||||
expect(configValue.loggers.get('plugins')).toEqual({
|
||||
appenders: ['file'],
|
||||
context: 'plugins',
|
||||
name: 'plugins',
|
||||
level: 'warn',
|
||||
});
|
||||
expect(configValue.loggers.get('plugins.pid')).toEqual({
|
||||
appenders: ['file'],
|
||||
context: 'plugins.pid',
|
||||
name: 'plugins.pid',
|
||||
level: 'trace',
|
||||
});
|
||||
expect(configValue.loggers.get('http')).toEqual({
|
||||
appenders: ['default'],
|
||||
context: 'http',
|
||||
name: 'http',
|
||||
level: 'error',
|
||||
});
|
||||
});
|
||||
|
@ -153,7 +153,7 @@ test('fails if loggers use unknown appenders.', () => {
|
|||
loggers: [
|
||||
{
|
||||
appenders: ['unknown'],
|
||||
context: 'some.nested.context',
|
||||
name: 'some.nested.context',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
@ -167,9 +167,9 @@ describe('extend', () => {
|
|||
config.schema.validate({
|
||||
appenders: {
|
||||
file1: {
|
||||
kind: 'file',
|
||||
layout: { kind: 'pattern' },
|
||||
path: 'path',
|
||||
type: 'file',
|
||||
layout: { type: 'pattern' },
|
||||
fileName: 'path',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
@ -179,9 +179,9 @@ describe('extend', () => {
|
|||
config.schema.validate({
|
||||
appenders: {
|
||||
file2: {
|
||||
kind: 'file',
|
||||
layout: { kind: 'pattern' },
|
||||
path: 'path',
|
||||
type: 'file',
|
||||
layout: { type: 'pattern' },
|
||||
fileName: 'path',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
@ -200,9 +200,9 @@ describe('extend', () => {
|
|||
config.schema.validate({
|
||||
appenders: {
|
||||
file1: {
|
||||
kind: 'file',
|
||||
layout: { kind: 'pattern' },
|
||||
path: 'path',
|
||||
type: 'file',
|
||||
layout: { type: 'pattern' },
|
||||
fileName: 'path',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
@ -212,18 +212,18 @@ describe('extend', () => {
|
|||
config.schema.validate({
|
||||
appenders: {
|
||||
file1: {
|
||||
kind: 'file',
|
||||
layout: { kind: 'json' },
|
||||
path: 'updatedPath',
|
||||
type: 'file',
|
||||
layout: { type: 'json' },
|
||||
fileName: 'updatedPath',
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
expect(mergedConfigValue.appenders.get('file1')).toEqual({
|
||||
kind: 'file',
|
||||
layout: { kind: 'json' },
|
||||
path: 'updatedPath',
|
||||
type: 'file',
|
||||
layout: { type: 'json' },
|
||||
fileName: 'updatedPath',
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -232,7 +232,7 @@ describe('extend', () => {
|
|||
config.schema.validate({
|
||||
loggers: [
|
||||
{
|
||||
context: 'plugins',
|
||||
name: 'plugins',
|
||||
level: 'warn',
|
||||
},
|
||||
],
|
||||
|
@ -243,7 +243,7 @@ describe('extend', () => {
|
|||
config.schema.validate({
|
||||
loggers: [
|
||||
{
|
||||
context: 'plugins.pid',
|
||||
name: 'plugins.pid',
|
||||
level: 'trace',
|
||||
},
|
||||
],
|
||||
|
@ -258,7 +258,7 @@ describe('extend', () => {
|
|||
config.schema.validate({
|
||||
loggers: [
|
||||
{
|
||||
context: 'plugins',
|
||||
name: 'plugins',
|
||||
level: 'warn',
|
||||
},
|
||||
],
|
||||
|
@ -270,7 +270,7 @@ describe('extend', () => {
|
|||
loggers: [
|
||||
{
|
||||
appenders: ['console'],
|
||||
context: 'plugins',
|
||||
name: 'plugins',
|
||||
level: 'trace',
|
||||
},
|
||||
],
|
||||
|
@ -279,7 +279,7 @@ describe('extend', () => {
|
|||
|
||||
expect(mergedConfigValue.loggers.get('plugins')).toEqual({
|
||||
appenders: ['console'],
|
||||
context: 'plugins',
|
||||
name: 'plugins',
|
||||
level: 'trace',
|
||||
});
|
||||
});
|
||||
|
|
|
@ -51,7 +51,7 @@ const levelSchema = schema.oneOf(
|
|||
*/
|
||||
export const loggerSchema = schema.object({
|
||||
appenders: schema.arrayOf(schema.string(), { defaultValue: [] }),
|
||||
context: schema.string(),
|
||||
name: schema.string(),
|
||||
level: levelSchema,
|
||||
});
|
||||
|
||||
|
@ -148,15 +148,15 @@ export class LoggingConfig {
|
|||
[
|
||||
'default',
|
||||
{
|
||||
kind: 'console',
|
||||
layout: { kind: 'pattern', highlight: true },
|
||||
type: 'console',
|
||||
layout: { type: 'pattern', highlight: true },
|
||||
} as AppenderConfigType,
|
||||
],
|
||||
[
|
||||
'console',
|
||||
{
|
||||
kind: 'console',
|
||||
layout: { kind: 'pattern', highlight: true },
|
||||
type: 'console',
|
||||
layout: { type: 'pattern', highlight: true },
|
||||
} as AppenderConfigType,
|
||||
],
|
||||
]);
|
||||
|
@ -182,8 +182,8 @@ export class LoggingConfig {
|
|||
public extend(contextConfig: LoggerContextConfigType) {
|
||||
// Use a Map to de-dupe any loggers for the same context. contextConfig overrides existing config.
|
||||
const mergedLoggers = new Map<string, LoggerConfigType>([
|
||||
...this.configType.loggers.map((l) => [l.context, l] as [string, LoggerConfigType]),
|
||||
...contextConfig.loggers.map((l) => [l.context, l] as [string, LoggerConfigType]),
|
||||
...this.configType.loggers.map((l) => [l.name, l] as [string, LoggerConfigType]),
|
||||
...contextConfig.loggers.map((l) => [l.name, l] as [string, LoggerConfigType]),
|
||||
]);
|
||||
|
||||
const mergedConfig: LoggingConfigType = {
|
||||
|
@ -204,13 +204,10 @@ export class LoggingConfig {
|
|||
private fillLoggersConfig(loggingConfig: LoggingConfigType) {
|
||||
// Include `root` logger into common logger list so that it can easily be a part
|
||||
// of the logger hierarchy and put all the loggers in map for easier retrieval.
|
||||
const loggers = [
|
||||
{ context: ROOT_CONTEXT_NAME, ...loggingConfig.root },
|
||||
...loggingConfig.loggers,
|
||||
];
|
||||
const loggers = [{ name: ROOT_CONTEXT_NAME, ...loggingConfig.root }, ...loggingConfig.loggers];
|
||||
|
||||
const loggerConfigByContext = new Map(
|
||||
loggers.map((loggerConfig) => toTuple(loggerConfig.context, loggerConfig))
|
||||
loggers.map((loggerConfig) => toTuple(loggerConfig.name, loggerConfig))
|
||||
);
|
||||
|
||||
for (const [loggerContext, loggerConfig] of loggerConfigByContext) {
|
||||
|
@ -247,7 +244,7 @@ function getAppenders(
|
|||
loggerConfig: LoggerConfigType,
|
||||
loggerConfigByContext: Map<string, LoggerConfigType>
|
||||
) {
|
||||
let currentContext = loggerConfig.context;
|
||||
let currentContext = loggerConfig.name;
|
||||
let appenders = loggerConfig.appenders;
|
||||
|
||||
while (appenders.length === 0) {
|
||||
|
|
|
@ -30,11 +30,11 @@ describe('LoggingService', () => {
|
|||
it('forwards configuration changes to logging system', () => {
|
||||
const config1: LoggerContextConfigType = {
|
||||
appenders: new Map(),
|
||||
loggers: [{ context: 'subcontext', appenders: ['console'], level: 'warn' }],
|
||||
loggers: [{ name: 'subcontext', appenders: ['console'], level: 'warn' }],
|
||||
};
|
||||
const config2: LoggerContextConfigType = {
|
||||
appenders: new Map(),
|
||||
loggers: [{ context: 'subcontext', appenders: ['default'], level: 'all' }],
|
||||
loggers: [{ name: 'subcontext', appenders: ['default'], level: 'all' }],
|
||||
};
|
||||
|
||||
setup.configure(['test', 'context'], of(config1, config2));
|
||||
|
@ -54,11 +54,11 @@ describe('LoggingService', () => {
|
|||
const updates$ = new Subject<LoggerContextConfigType>();
|
||||
const config1: LoggerContextConfigType = {
|
||||
appenders: new Map(),
|
||||
loggers: [{ context: 'subcontext', appenders: ['console'], level: 'warn' }],
|
||||
loggers: [{ name: 'subcontext', appenders: ['console'], level: 'warn' }],
|
||||
};
|
||||
const config2: LoggerContextConfigType = {
|
||||
appenders: new Map(),
|
||||
loggers: [{ context: 'subcontext', appenders: ['default'], level: 'all' }],
|
||||
loggers: [{ name: 'subcontext', appenders: ['default'], level: 'all' }],
|
||||
};
|
||||
|
||||
setup.configure(['test', 'context'], updates$);
|
||||
|
@ -78,7 +78,7 @@ describe('LoggingService', () => {
|
|||
const updates$ = new Subject<LoggerContextConfigType>();
|
||||
const config1: LoggerContextConfigType = {
|
||||
appenders: new Map(),
|
||||
loggers: [{ context: 'subcontext', appenders: ['console'], level: 'warn' }],
|
||||
loggers: [{ name: 'subcontext', appenders: ['console'], level: 'warn' }],
|
||||
};
|
||||
|
||||
setup.configure(['test', 'context'], updates$);
|
||||
|
|
|
@ -31,7 +31,7 @@ export interface LoggingServiceSetup {
|
|||
* core.logging.configure(
|
||||
* of({
|
||||
* appenders: new Map(),
|
||||
* loggers: [{ context: 'search', appenders: ['default'] }]
|
||||
* loggers: [{ name: 'search', appenders: ['default'] }]
|
||||
* })
|
||||
* )
|
||||
* ```
|
||||
|
|
|
@ -46,7 +46,7 @@ test('uses default memory buffer logger until config is provided', () => {
|
|||
const logger = system.get('test', 'context');
|
||||
logger.trace('trace message');
|
||||
|
||||
// We shouldn't create new buffer appender for another context.
|
||||
// We shouldn't create new buffer appender for another context name.
|
||||
const anotherLogger = system.get('test', 'context2');
|
||||
anotherLogger.fatal('fatal message', { some: 'value' });
|
||||
|
||||
|
@ -69,7 +69,7 @@ test('flushes memory buffer logger and switches to real logger once config is pr
|
|||
// Switch to console appender with `info` level, so that `trace` message won't go through.
|
||||
await system.upgrade(
|
||||
config.schema.validate({
|
||||
appenders: { default: { kind: 'console', layout: { kind: 'json' } } },
|
||||
appenders: { default: { type: 'console', layout: { type: 'json' } } },
|
||||
root: { level: 'info' },
|
||||
})
|
||||
);
|
||||
|
@ -102,12 +102,12 @@ test('appends records via multiple appenders.', async () => {
|
|||
await system.upgrade(
|
||||
config.schema.validate({
|
||||
appenders: {
|
||||
default: { kind: 'console', layout: { kind: 'pattern' } },
|
||||
file: { kind: 'file', layout: { kind: 'pattern' }, path: 'path' },
|
||||
default: { type: 'console', layout: { type: 'pattern' } },
|
||||
file: { type: 'file', layout: { type: 'pattern' }, fileName: 'path' },
|
||||
},
|
||||
loggers: [
|
||||
{ appenders: ['file'], context: 'tests', level: 'warn' },
|
||||
{ context: 'tests.child', level: 'error' },
|
||||
{ appenders: ['file'], name: 'tests', level: 'warn' },
|
||||
{ name: 'tests.child', level: 'error' },
|
||||
],
|
||||
})
|
||||
);
|
||||
|
@ -121,10 +121,10 @@ test('appends records via multiple appenders.', async () => {
|
|||
expect(mockStreamWrite.mock.calls[1][0]).toMatchSnapshot('file logs');
|
||||
});
|
||||
|
||||
test('uses `root` logger if context is not specified.', async () => {
|
||||
test('uses `root` logger if context name is not specified.', async () => {
|
||||
await system.upgrade(
|
||||
config.schema.validate({
|
||||
appenders: { default: { kind: 'console', layout: { kind: 'pattern' } } },
|
||||
appenders: { default: { type: 'console', layout: { type: 'pattern' } } },
|
||||
})
|
||||
);
|
||||
|
||||
|
@ -137,7 +137,7 @@ test('uses `root` logger if context is not specified.', async () => {
|
|||
test('`stop()` disposes all appenders.', async () => {
|
||||
await system.upgrade(
|
||||
config.schema.validate({
|
||||
appenders: { default: { kind: 'console', layout: { kind: 'json' } } },
|
||||
appenders: { default: { type: 'console', layout: { type: 'json' } } },
|
||||
root: { level: 'info' },
|
||||
})
|
||||
);
|
||||
|
@ -156,7 +156,7 @@ test('asLoggerFactory() only allows to create new loggers.', async () => {
|
|||
|
||||
await system.upgrade(
|
||||
config.schema.validate({
|
||||
appenders: { default: { kind: 'console', layout: { kind: 'json' } } },
|
||||
appenders: { default: { type: 'console', layout: { type: 'json' } } },
|
||||
root: { level: 'all' },
|
||||
})
|
||||
);
|
||||
|
@ -180,7 +180,7 @@ test('setContextConfig() updates config with relative contexts', async () => {
|
|||
|
||||
await system.upgrade(
|
||||
config.schema.validate({
|
||||
appenders: { default: { kind: 'console', layout: { kind: 'json' } } },
|
||||
appenders: { default: { type: 'console', layout: { type: 'json' } } },
|
||||
root: { level: 'info' },
|
||||
})
|
||||
);
|
||||
|
@ -189,10 +189,10 @@ test('setContextConfig() updates config with relative contexts', async () => {
|
|||
appenders: new Map([
|
||||
[
|
||||
'custom',
|
||||
{ kind: 'console', layout: { kind: 'pattern', pattern: '[%level][%logger] %message' } },
|
||||
{ type: 'console', layout: { type: 'pattern', pattern: '[%level][%logger] %message' } },
|
||||
],
|
||||
]),
|
||||
loggers: [{ context: 'grandchild', appenders: ['default', 'custom'], level: 'debug' }],
|
||||
loggers: [{ name: 'grandchild', appenders: ['default', 'custom'], level: 'debug' }],
|
||||
});
|
||||
|
||||
testsLogger.warn('tests log to default!');
|
||||
|
@ -235,7 +235,7 @@ test('setContextConfig() updates config for a root context', async () => {
|
|||
|
||||
await system.upgrade(
|
||||
config.schema.validate({
|
||||
appenders: { default: { kind: 'console', layout: { kind: 'json' } } },
|
||||
appenders: { default: { type: 'console', layout: { type: 'json' } } },
|
||||
root: { level: 'info' },
|
||||
})
|
||||
);
|
||||
|
@ -244,10 +244,10 @@ test('setContextConfig() updates config for a root context', async () => {
|
|||
appenders: new Map([
|
||||
[
|
||||
'custom',
|
||||
{ kind: 'console', layout: { kind: 'pattern', pattern: '[%level][%logger] %message' } },
|
||||
{ type: 'console', layout: { type: 'pattern', pattern: '[%level][%logger] %message' } },
|
||||
],
|
||||
]),
|
||||
loggers: [{ context: '', appenders: ['custom'], level: 'debug' }],
|
||||
loggers: [{ name: '', appenders: ['custom'], level: 'debug' }],
|
||||
});
|
||||
|
||||
testsLogger.warn('tests log to default!');
|
||||
|
@ -273,21 +273,21 @@ test('setContextConfig() updates config for a root context', async () => {
|
|||
);
|
||||
});
|
||||
|
||||
test('custom context configs are applied on subsequent calls to update()', async () => {
|
||||
test('custom context name configs are applied on subsequent calls to update()', async () => {
|
||||
await system.setContextConfig(['tests', 'child'], {
|
||||
appenders: new Map([
|
||||
[
|
||||
'custom',
|
||||
{ kind: 'console', layout: { kind: 'pattern', pattern: '[%level][%logger] %message' } },
|
||||
{ type: 'console', layout: { type: 'pattern', pattern: '[%level][%logger] %message' } },
|
||||
],
|
||||
]),
|
||||
loggers: [{ context: 'grandchild', appenders: ['default', 'custom'], level: 'debug' }],
|
||||
loggers: [{ name: 'grandchild', appenders: ['default', 'custom'], level: 'debug' }],
|
||||
});
|
||||
|
||||
// Calling upgrade after setContextConfig should not throw away the context-specific config
|
||||
await system.upgrade(
|
||||
config.schema.validate({
|
||||
appenders: { default: { kind: 'console', layout: { kind: 'json' } } },
|
||||
appenders: { default: { type: 'console', layout: { type: 'json' } } },
|
||||
root: { level: 'info' },
|
||||
})
|
||||
);
|
||||
|
@ -310,10 +310,10 @@ test('custom context configs are applied on subsequent calls to update()', async
|
|||
);
|
||||
});
|
||||
|
||||
test('subsequent calls to setContextConfig() for the same context override the previous config', async () => {
|
||||
test('subsequent calls to setContextConfig() for the same context name override the previous config', async () => {
|
||||
await system.upgrade(
|
||||
config.schema.validate({
|
||||
appenders: { default: { kind: 'console', layout: { kind: 'json' } } },
|
||||
appenders: { default: { type: 'console', layout: { type: 'json' } } },
|
||||
root: { level: 'info' },
|
||||
})
|
||||
);
|
||||
|
@ -322,10 +322,10 @@ test('subsequent calls to setContextConfig() for the same context override the p
|
|||
appenders: new Map([
|
||||
[
|
||||
'custom',
|
||||
{ kind: 'console', layout: { kind: 'pattern', pattern: '[%level][%logger] %message' } },
|
||||
{ type: 'console', layout: { type: 'pattern', pattern: '[%level][%logger] %message' } },
|
||||
],
|
||||
]),
|
||||
loggers: [{ context: 'grandchild', appenders: ['default', 'custom'], level: 'debug' }],
|
||||
loggers: [{ name: 'grandchild', appenders: ['default', 'custom'], level: 'debug' }],
|
||||
});
|
||||
|
||||
// Call again, this time with level: 'warn' and a different pattern
|
||||
|
@ -334,12 +334,12 @@ test('subsequent calls to setContextConfig() for the same context override the p
|
|||
[
|
||||
'custom',
|
||||
{
|
||||
kind: 'console',
|
||||
layout: { kind: 'pattern', pattern: '[%level][%logger] second pattern! %message' },
|
||||
type: 'console',
|
||||
layout: { type: 'pattern', pattern: '[%level][%logger] second pattern! %message' },
|
||||
},
|
||||
],
|
||||
]),
|
||||
loggers: [{ context: 'grandchild', appenders: ['default', 'custom'], level: 'warn' }],
|
||||
loggers: [{ name: 'grandchild', appenders: ['default', 'custom'], level: 'warn' }],
|
||||
});
|
||||
|
||||
const logger = system.get('tests', 'child', 'grandchild');
|
||||
|
@ -360,10 +360,10 @@ test('subsequent calls to setContextConfig() for the same context override the p
|
|||
);
|
||||
});
|
||||
|
||||
test('subsequent calls to setContextConfig() for the same context can disable the previous config', async () => {
|
||||
test('subsequent calls to setContextConfig() for the same context name can disable the previous config', async () => {
|
||||
await system.upgrade(
|
||||
config.schema.validate({
|
||||
appenders: { default: { kind: 'console', layout: { kind: 'json' } } },
|
||||
appenders: { default: { type: 'console', layout: { type: 'json' } } },
|
||||
root: { level: 'info' },
|
||||
})
|
||||
);
|
||||
|
@ -372,10 +372,10 @@ test('subsequent calls to setContextConfig() for the same context can disable th
|
|||
appenders: new Map([
|
||||
[
|
||||
'custom',
|
||||
{ kind: 'console', layout: { kind: 'pattern', pattern: '[%level][%logger] %message' } },
|
||||
{ type: 'console', layout: { type: 'pattern', pattern: '[%level][%logger] %message' } },
|
||||
],
|
||||
]),
|
||||
loggers: [{ context: 'grandchild', appenders: ['default', 'custom'], level: 'debug' }],
|
||||
loggers: [{ name: 'grandchild', appenders: ['default', 'custom'], level: 'debug' }],
|
||||
});
|
||||
|
||||
// Call again, this time no customizations (effectively disabling)
|
||||
|
|
|
@ -79,7 +79,7 @@ export class LoggingSystem implements LoggerFactory {
|
|||
* loggingSystem.setContextConfig(
|
||||
* ['plugins', 'data'],
|
||||
* {
|
||||
* loggers: [{ context: 'search', appenders: ['default'] }]
|
||||
* loggers: [{ name: 'search', appenders: ['default'] }]
|
||||
* }
|
||||
* )
|
||||
* ```
|
||||
|
@ -95,9 +95,7 @@ export class LoggingSystem implements LoggerFactory {
|
|||
// Automatically prepend the base context to the logger sub-contexts
|
||||
loggers: contextConfig.loggers.map((l) => ({
|
||||
...l,
|
||||
context: LoggingConfig.getLoggerContext(
|
||||
l.context.length > 0 ? [context, l.context] : [context]
|
||||
),
|
||||
name: LoggingConfig.getLoggerContext(l.name.length > 0 ? [context, l.name] : [context]),
|
||||
})),
|
||||
});
|
||||
|
||||
|
|
|
@ -45,16 +45,16 @@ describe('migration v2', () => {
|
|||
logging: {
|
||||
appenders: {
|
||||
file: {
|
||||
kind: 'file',
|
||||
path: join(__dirname, 'migration_test_kibana.log'),
|
||||
type: 'file',
|
||||
fileName: join(__dirname, 'migration_test_kibana.log'),
|
||||
layout: {
|
||||
kind: 'json',
|
||||
type: 'json',
|
||||
},
|
||||
},
|
||||
},
|
||||
loggers: [
|
||||
{
|
||||
context: 'root',
|
||||
name: 'root',
|
||||
appenders: ['file'],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -47,16 +47,16 @@ describe.skip('migration from 7.7.2-xpack with 100k objects', () => {
|
|||
logging: {
|
||||
appenders: {
|
||||
file: {
|
||||
kind: 'file',
|
||||
path: join(__dirname, 'migration_test_kibana.log'),
|
||||
type: 'file',
|
||||
fileName: join(__dirname, 'migration_test_kibana.log'),
|
||||
layout: {
|
||||
kind: 'json',
|
||||
type: 'json',
|
||||
},
|
||||
},
|
||||
},
|
||||
loggers: [
|
||||
{
|
||||
context: 'root',
|
||||
name: 'root',
|
||||
appenders: ['file'],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -76,9 +76,9 @@ describe('#setup', () => {
|
|||
config: {
|
||||
enabled: true,
|
||||
appender: {
|
||||
kind: 'console',
|
||||
type: 'console',
|
||||
layout: {
|
||||
kind: 'pattern',
|
||||
type: 'pattern',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -102,9 +102,9 @@ describe('#setup', () => {
|
|||
config: {
|
||||
enabled: true,
|
||||
appender: {
|
||||
kind: 'console',
|
||||
type: 'console',
|
||||
layout: {
|
||||
kind: 'pattern',
|
||||
type: 'pattern',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -251,9 +251,9 @@ describe('#createLoggingConfig', () => {
|
|||
createLoggingConfig({
|
||||
enabled: true,
|
||||
appender: {
|
||||
kind: 'console',
|
||||
type: 'console',
|
||||
layout: {
|
||||
kind: 'pattern',
|
||||
type: 'pattern',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
@ -264,10 +264,10 @@ describe('#createLoggingConfig', () => {
|
|||
Object {
|
||||
"appenders": Object {
|
||||
"auditTrailAppender": Object {
|
||||
"kind": "console",
|
||||
"layout": Object {
|
||||
"kind": "pattern",
|
||||
"type": "pattern",
|
||||
},
|
||||
"type": "console",
|
||||
},
|
||||
},
|
||||
"loggers": Array [
|
||||
|
@ -275,8 +275,8 @@ describe('#createLoggingConfig', () => {
|
|||
"appenders": Array [
|
||||
"auditTrailAppender",
|
||||
],
|
||||
"context": "audit.ecs",
|
||||
"level": "info",
|
||||
"name": "audit.ecs",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
@ -293,9 +293,9 @@ describe('#createLoggingConfig', () => {
|
|||
createLoggingConfig({
|
||||
enabled: false,
|
||||
appender: {
|
||||
kind: 'console',
|
||||
type: 'console',
|
||||
layout: {
|
||||
kind: 'pattern',
|
||||
type: 'pattern',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
@ -331,9 +331,9 @@ describe('#createLoggingConfig', () => {
|
|||
createLoggingConfig({
|
||||
enabled: true,
|
||||
appender: {
|
||||
kind: 'console',
|
||||
type: 'console',
|
||||
layout: {
|
||||
kind: 'pattern',
|
||||
type: 'pattern',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
|
|
@ -224,16 +224,16 @@ export const createLoggingConfig = (config: ConfigType['audit']) =>
|
|||
map<Pick<SecurityLicenseFeatures, 'allowAuditLogging'>, LoggerContextConfigInput>((features) => ({
|
||||
appenders: {
|
||||
auditTrailAppender: config.appender ?? {
|
||||
kind: 'console',
|
||||
type: 'console',
|
||||
layout: {
|
||||
kind: 'pattern',
|
||||
type: 'pattern',
|
||||
highlight: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
loggers: [
|
||||
{
|
||||
context: 'audit.ecs',
|
||||
name: 'audit.ecs',
|
||||
level: config.enabled && config.appender && features.allowAuditLogging ? 'info' : 'off',
|
||||
appenders: ['auditTrailAppender'],
|
||||
},
|
||||
|
|
|
@ -1692,21 +1692,21 @@ describe('createConfig()', () => {
|
|||
ConfigSchema.validate({
|
||||
audit: {
|
||||
appender: {
|
||||
kind: 'file',
|
||||
path: '/path/to/file.txt',
|
||||
type: 'file',
|
||||
fileName: '/path/to/file.txt',
|
||||
layout: {
|
||||
kind: 'json',
|
||||
type: 'json',
|
||||
},
|
||||
},
|
||||
},
|
||||
}).audit.appender
|
||||
).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"kind": "file",
|
||||
"fileName": "/path/to/file.txt",
|
||||
"layout": Object {
|
||||
"kind": "json",
|
||||
"type": "json",
|
||||
},
|
||||
"path": "/path/to/file.txt",
|
||||
"type": "file",
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
@ -1717,12 +1717,12 @@ describe('createConfig()', () => {
|
|||
audit: {
|
||||
// no layout configured
|
||||
appender: {
|
||||
kind: 'file',
|
||||
type: 'file',
|
||||
path: '/path/to/file.txt',
|
||||
},
|
||||
},
|
||||
})
|
||||
).toThrow('[audit.appender.2.kind]: expected value to equal [legacy-appender]');
|
||||
).toThrow('[audit.appender.2.type]: expected value to equal [legacy-appender]');
|
||||
});
|
||||
|
||||
it('rejects an ignore_filter when no appender is configured', () => {
|
||||
|
|
|
@ -52,6 +52,117 @@ describe('Config Deprecations', () => {
|
|||
`);
|
||||
});
|
||||
|
||||
it('renames audit.appender.kind to audit.appender.type', () => {
|
||||
const config = {
|
||||
xpack: {
|
||||
security: {
|
||||
audit: {
|
||||
appender: {
|
||||
kind: 'console',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const { messages, migrated } = applyConfigDeprecations(cloneDeep(config));
|
||||
expect(migrated.xpack.security.audit.appender.kind).not.toBeDefined();
|
||||
expect(migrated.xpack.security.audit.appender.type).toEqual('console');
|
||||
expect(messages).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
"\\"xpack.security.audit.appender.kind\\" is deprecated and has been replaced by \\"xpack.security.audit.appender.type\\"",
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('renames audit.appender.layout.kind to audit.appender.layout.type', () => {
|
||||
const config = {
|
||||
xpack: {
|
||||
security: {
|
||||
audit: {
|
||||
appender: {
|
||||
layout: { kind: 'pattern' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const { messages, migrated } = applyConfigDeprecations(cloneDeep(config));
|
||||
expect(migrated.xpack.security.audit.appender.layout.kind).not.toBeDefined();
|
||||
expect(migrated.xpack.security.audit.appender.layout.type).toEqual('pattern');
|
||||
expect(messages).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
"\\"xpack.security.audit.appender.layout.kind\\" is deprecated and has been replaced by \\"xpack.security.audit.appender.layout.type\\"",
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('renames audit.appender.policy.kind to audit.appender.policy.type', () => {
|
||||
const config = {
|
||||
xpack: {
|
||||
security: {
|
||||
audit: {
|
||||
appender: {
|
||||
policy: { kind: 'time-interval' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const { messages, migrated } = applyConfigDeprecations(cloneDeep(config));
|
||||
expect(migrated.xpack.security.audit.appender.policy.kind).not.toBeDefined();
|
||||
expect(migrated.xpack.security.audit.appender.policy.type).toEqual('time-interval');
|
||||
expect(messages).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
"\\"xpack.security.audit.appender.policy.kind\\" is deprecated and has been replaced by \\"xpack.security.audit.appender.policy.type\\"",
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('renames audit.appender.strategy.kind to audit.appender.strategy.type', () => {
|
||||
const config = {
|
||||
xpack: {
|
||||
security: {
|
||||
audit: {
|
||||
appender: {
|
||||
strategy: { kind: 'numeric' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const { messages, migrated } = applyConfigDeprecations(cloneDeep(config));
|
||||
expect(migrated.xpack.security.audit.appender.strategy.kind).not.toBeDefined();
|
||||
expect(migrated.xpack.security.audit.appender.strategy.type).toEqual('numeric');
|
||||
expect(messages).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
"\\"xpack.security.audit.appender.strategy.kind\\" is deprecated and has been replaced by \\"xpack.security.audit.appender.strategy.type\\"",
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('renames audit.appender.path to audit.appender.fileName', () => {
|
||||
const config = {
|
||||
xpack: {
|
||||
security: {
|
||||
audit: {
|
||||
appender: {
|
||||
type: 'file',
|
||||
path: './audit.log',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const { messages, migrated } = applyConfigDeprecations(cloneDeep(config));
|
||||
expect(migrated.xpack.security.audit.appender.path).not.toBeDefined();
|
||||
expect(migrated.xpack.security.audit.appender.fileName).toEqual('./audit.log');
|
||||
expect(messages).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
"\\"xpack.security.audit.appender.path\\" is deprecated and has been replaced by \\"xpack.security.audit.appender.fileName\\"",
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it(`warns that 'authorization.legacyFallback.enabled' is unused`, () => {
|
||||
const config = {
|
||||
xpack: {
|
||||
|
|
|
@ -13,6 +13,13 @@ export const securityConfigDeprecationProvider: ConfigDeprecationProvider = ({
|
|||
}) => [
|
||||
rename('sessionTimeout', 'session.idleTimeout'),
|
||||
rename('authProviders', 'authc.providers'),
|
||||
|
||||
rename('audit.appender.kind', 'audit.appender.type'),
|
||||
rename('audit.appender.layout.kind', 'audit.appender.layout.type'),
|
||||
rename('audit.appender.policy.kind', 'audit.appender.policy.type'),
|
||||
rename('audit.appender.strategy.kind', 'audit.appender.strategy.type'),
|
||||
rename('audit.appender.path', 'audit.appender.fileName'),
|
||||
|
||||
unused('authorization.legacyFallback.enabled'),
|
||||
unused('authc.saml.maxRedirectURLSize'),
|
||||
// Deprecation warning for the old array-based format of `xpack.security.authc.providers`.
|
||||
|
|
|
@ -29,9 +29,9 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) {
|
|||
...xPackAPITestsConfig.get('kbnTestServer.serverArgs'),
|
||||
`--plugin-path=${auditLogPlugin}`,
|
||||
'--xpack.security.audit.enabled=true',
|
||||
'--xpack.security.audit.appender.kind=file',
|
||||
`--xpack.security.audit.appender.path=${auditLogPath}`,
|
||||
'--xpack.security.audit.appender.layout.kind=json',
|
||||
'--xpack.security.audit.appender.type=file',
|
||||
`--xpack.security.audit.appender.fileName=${auditLogPath}`,
|
||||
'--xpack.security.audit.appender.layout.type=json',
|
||||
],
|
||||
},
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue