mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
Add plugin API for customizing the logging configuration (#68704)
This commit is contained in:
parent
71d54c8cae
commit
200957bb63
149 changed files with 1956 additions and 685 deletions
|
@ -0,0 +1,12 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [AppenderConfigType](./kibana-plugin-core-server.appenderconfigtype.md)
|
||||
|
||||
## AppenderConfigType type
|
||||
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
export declare type AppenderConfigType = TypeOf<typeof appendersSchema>;
|
||||
```
|
|
@ -0,0 +1,13 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [CoreSetup](./kibana-plugin-core-server.coresetup.md) > [logging](./kibana-plugin-core-server.coresetup.logging.md)
|
||||
|
||||
## CoreSetup.logging property
|
||||
|
||||
[LoggingServiceSetup](./kibana-plugin-core-server.loggingservicesetup.md)
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
logging: LoggingServiceSetup;
|
||||
```
|
|
@ -21,6 +21,7 @@ export interface CoreSetup<TPluginsStart extends object = object, TStart = unkno
|
|||
| [elasticsearch](./kibana-plugin-core-server.coresetup.elasticsearch.md) | <code>ElasticsearchServiceSetup</code> | [ElasticsearchServiceSetup](./kibana-plugin-core-server.elasticsearchservicesetup.md) |
|
||||
| [getStartServices](./kibana-plugin-core-server.coresetup.getstartservices.md) | <code>StartServicesAccessor<TPluginsStart, TStart></code> | [StartServicesAccessor](./kibana-plugin-core-server.startservicesaccessor.md) |
|
||||
| [http](./kibana-plugin-core-server.coresetup.http.md) | <code>HttpServiceSetup & {</code><br/><code> resources: HttpResources;</code><br/><code> }</code> | [HttpServiceSetup](./kibana-plugin-core-server.httpservicesetup.md) |
|
||||
| [logging](./kibana-plugin-core-server.coresetup.logging.md) | <code>LoggingServiceSetup</code> | [LoggingServiceSetup](./kibana-plugin-core-server.loggingservicesetup.md) |
|
||||
| [metrics](./kibana-plugin-core-server.coresetup.metrics.md) | <code>MetricsServiceSetup</code> | [MetricsServiceSetup](./kibana-plugin-core-server.metricsservicesetup.md) |
|
||||
| [savedObjects](./kibana-plugin-core-server.coresetup.savedobjects.md) | <code>SavedObjectsServiceSetup</code> | [SavedObjectsServiceSetup](./kibana-plugin-core-server.savedobjectsservicesetup.md) |
|
||||
| [status](./kibana-plugin-core-server.coresetup.status.md) | <code>StatusServiceSetup</code> | [StatusServiceSetup](./kibana-plugin-core-server.statusservicesetup.md) |
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [LoggerConfigType](./kibana-plugin-core-server.loggerconfigtype.md)
|
||||
|
||||
## LoggerConfigType type
|
||||
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
export declare type LoggerConfigType = TypeOf<typeof loggerSchema>;
|
||||
```
|
|
@ -0,0 +1,11 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [LoggerContextConfigInput](./kibana-plugin-core-server.loggercontextconfiginput.md) > [appenders](./kibana-plugin-core-server.loggercontextconfiginput.appenders.md)
|
||||
|
||||
## LoggerContextConfigInput.appenders property
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
appenders?: Record<string, AppenderConfigType> | Map<string, AppenderConfigType>;
|
||||
```
|
|
@ -0,0 +1,11 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [LoggerContextConfigInput](./kibana-plugin-core-server.loggercontextconfiginput.md) > [loggers](./kibana-plugin-core-server.loggercontextconfiginput.loggers.md)
|
||||
|
||||
## LoggerContextConfigInput.loggers property
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
loggers?: LoggerConfigType[];
|
||||
```
|
|
@ -0,0 +1,20 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [LoggerContextConfigInput](./kibana-plugin-core-server.loggercontextconfiginput.md)
|
||||
|
||||
## LoggerContextConfigInput interface
|
||||
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
export interface LoggerContextConfigInput
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| [appenders](./kibana-plugin-core-server.loggercontextconfiginput.appenders.md) | <code>Record<string, AppenderConfigType> | Map<string, AppenderConfigType></code> | |
|
||||
| [loggers](./kibana-plugin-core-server.loggercontextconfiginput.loggers.md) | <code>LoggerConfigType[]</code> | |
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [LoggingServiceSetup](./kibana-plugin-core-server.loggingservicesetup.md) > [configure](./kibana-plugin-core-server.loggingservicesetup.configure.md)
|
||||
|
||||
## LoggingServiceSetup.configure() method
|
||||
|
||||
Customizes the logging config for the plugin's context.
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
configure(config$: Observable<LoggerContextConfigInput>): void;
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| config$ | <code>Observable<LoggerContextConfigInput></code> | |
|
||||
|
||||
<b>Returns:</b>
|
||||
|
||||
`void`
|
||||
|
||||
## Remarks
|
||||
|
||||
Assumes that that the `context` property of the individual `logger` items emitted by `config$` are relative to the plugin's logging context (defaults to `plugins.<plugin_id>`<!-- -->).
|
||||
|
||||
## Example
|
||||
|
||||
Customize the configuration for the plugins.data.search context.
|
||||
|
||||
```ts
|
||||
core.logging.configure(
|
||||
of({
|
||||
appenders: new Map(),
|
||||
loggers: [{ context: 'search', appenders: ['default'] }]
|
||||
})
|
||||
)
|
||||
|
||||
```
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [LoggingServiceSetup](./kibana-plugin-core-server.loggingservicesetup.md)
|
||||
|
||||
## LoggingServiceSetup interface
|
||||
|
||||
Provides APIs to plugins for customizing the plugin's logger.
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
export interface LoggingServiceSetup
|
||||
```
|
||||
|
||||
## Methods
|
||||
|
||||
| Method | Description |
|
||||
| --- | --- |
|
||||
| [configure(config$)](./kibana-plugin-core-server.loggingservicesetup.configure.md) | Customizes the logging config for the plugin's context. |
|
||||
|
|
@ -108,7 +108,9 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
|
|||
| [LegacyServiceSetupDeps](./kibana-plugin-core-server.legacyservicesetupdeps.md) | |
|
||||
| [LegacyServiceStartDeps](./kibana-plugin-core-server.legacyservicestartdeps.md) | |
|
||||
| [Logger](./kibana-plugin-core-server.logger.md) | Logger exposes all the necessary methods to log any type of information and this is the interface used by the logging consumers including plugins. |
|
||||
| [LoggerContextConfigInput](./kibana-plugin-core-server.loggercontextconfiginput.md) | |
|
||||
| [LoggerFactory](./kibana-plugin-core-server.loggerfactory.md) | The single purpose of <code>LoggerFactory</code> interface is to define a way to retrieve a context-based logger instance. |
|
||||
| [LoggingServiceSetup](./kibana-plugin-core-server.loggingservicesetup.md) | Provides APIs to plugins for customizing the plugin's logger. |
|
||||
| [LogMeta](./kibana-plugin-core-server.logmeta.md) | Contextual metadata |
|
||||
| [MetricsServiceSetup](./kibana-plugin-core-server.metricsservicesetup.md) | APIs to retrieves metrics gathered and exposed by the core platform. |
|
||||
| [NodesVersionCompatibility](./kibana-plugin-core-server.nodesversioncompatibility.md) | |
|
||||
|
@ -209,6 +211,7 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
|
|||
|
||||
| Type Alias | Description |
|
||||
| --- | --- |
|
||||
| [AppenderConfigType](./kibana-plugin-core-server.appenderconfigtype.md) | |
|
||||
| [AuthenticationHandler](./kibana-plugin-core-server.authenticationhandler.md) | See [AuthToolkit](./kibana-plugin-core-server.authtoolkit.md)<!-- -->. |
|
||||
| [AuthHeaders](./kibana-plugin-core-server.authheaders.md) | Auth Headers map |
|
||||
| [AuthResult](./kibana-plugin-core-server.authresult.md) | |
|
||||
|
@ -242,6 +245,7 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
|
|||
| [KibanaResponseFactory](./kibana-plugin-core-server.kibanaresponsefactory.md) | Creates an object containing request response payload, HTTP headers, error details, and other data transmitted to the client. |
|
||||
| [KnownHeaders](./kibana-plugin-core-server.knownheaders.md) | Set of well-known HTTP headers. |
|
||||
| [LifecycleResponseFactory](./kibana-plugin-core-server.lifecycleresponsefactory.md) | Creates an object containing redirection or error response with error details, HTTP headers, and other data transmitted to the client. |
|
||||
| [LoggerConfigType](./kibana-plugin-core-server.loggerconfigtype.md) | |
|
||||
| [MIGRATION\_ASSISTANCE\_INDEX\_ACTION](./kibana-plugin-core-server.migration_assistance_index_action.md) | |
|
||||
| [MIGRATION\_DEPRECATION\_LEVEL](./kibana-plugin-core-server.migration_deprecation_level.md) | |
|
||||
| [MutatingOperationRefreshSetting](./kibana-plugin-core-server.mutatingoperationrefreshsetting.md) | Elasticsearch Refresh setting for mutating operation |
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
import supertest from 'supertest';
|
||||
import { HttpService, InternalHttpServiceSetup } from '../../http';
|
||||
import { contextServiceMock } from '../../context/context_service.mock';
|
||||
import { loggingServiceMock } from '../../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../../logging/logging_system.mock';
|
||||
import { Env } from '../../config';
|
||||
import { getEnvOptions } from '../../config/__mocks__/env';
|
||||
import { CapabilitiesService, CapabilitiesSetup } from '..';
|
||||
|
@ -44,7 +44,7 @@ describe('CapabilitiesService', () => {
|
|||
service = new CapabilitiesService({
|
||||
coreId,
|
||||
env,
|
||||
logger: loggingServiceMock.create(),
|
||||
logger: loggingSystemMock.create(),
|
||||
configService: {} as any,
|
||||
});
|
||||
serviceSetup = await service.setup({ http: httpSetup });
|
||||
|
|
|
@ -28,12 +28,12 @@ import { rawConfigServiceMock } from './raw_config_service.mock';
|
|||
import { schema } from '@kbn/config-schema';
|
||||
|
||||
import { ConfigService, Env } from '.';
|
||||
import { loggingServiceMock } from '../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../logging/logging_system.mock';
|
||||
import { getEnvOptions } from './__mocks__/env';
|
||||
|
||||
const emptyArgv = getEnvOptions();
|
||||
const defaultEnv = new Env('/kibana', emptyArgv);
|
||||
const logger = loggingServiceMock.create();
|
||||
const logger = loggingSystemMock.create();
|
||||
|
||||
const getRawConfigProvider = (rawConfig: Record<string, any>) =>
|
||||
rawConfigServiceMock.create({ rawConfig });
|
||||
|
@ -443,9 +443,9 @@ test('logs deprecation warning during validation', async () => {
|
|||
return config;
|
||||
});
|
||||
|
||||
loggingServiceMock.clear(logger);
|
||||
loggingSystemMock.clear(logger);
|
||||
await configService.validate();
|
||||
expect(loggingServiceMock.collect(logger).warn).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).warn).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"some deprecation message",
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { loggingServiceMock } from '../../logging/logging_service.mock';
|
||||
export const mockLoggingService = loggingServiceMock.create();
|
||||
mockLoggingService.asLoggerFactory.mockImplementation(() => mockLoggingService);
|
||||
jest.doMock('../../logging/logging_service', () => ({
|
||||
LoggingService: jest.fn(() => mockLoggingService),
|
||||
import { loggingSystemMock } from '../../logging/logging_system.mock';
|
||||
export const mockLoggingSystem = loggingSystemMock.create();
|
||||
mockLoggingSystem.asLoggerFactory.mockImplementation(() => mockLoggingSystem);
|
||||
jest.doMock('../../logging/logging_system', () => ({
|
||||
LoggingSystem: jest.fn(() => mockLoggingSystem),
|
||||
}));
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { mockLoggingService } from './config_deprecation.test.mocks';
|
||||
import { loggingServiceMock } from '../../logging/logging_service.mock';
|
||||
import { mockLoggingSystem } from './config_deprecation.test.mocks';
|
||||
import { loggingSystemMock } from '../../logging/logging_system.mock';
|
||||
import * as kbnTestServer from '../../../../test_utils/kbn_server';
|
||||
|
||||
describe('configuration deprecations', () => {
|
||||
|
@ -35,7 +35,7 @@ describe('configuration deprecations', () => {
|
|||
|
||||
await root.setup();
|
||||
|
||||
const logs = loggingServiceMock.collect(mockLoggingService);
|
||||
const logs = loggingSystemMock.collect(mockLoggingSystem);
|
||||
const warnings = logs.warn.flatMap((i) => i);
|
||||
expect(warnings).not.toContain(
|
||||
'"optimize.lazy" is deprecated and has been replaced by "optimize.watch"'
|
||||
|
@ -55,7 +55,7 @@ describe('configuration deprecations', () => {
|
|||
|
||||
await root.setup();
|
||||
|
||||
const logs = loggingServiceMock.collect(mockLoggingService);
|
||||
const logs = loggingSystemMock.collect(mockLoggingSystem);
|
||||
const warnings = logs.warn.flatMap((i) => i);
|
||||
expect(warnings).toContain(
|
||||
'"optimize.lazy" is deprecated and has been replaced by "optimize.watch"'
|
||||
|
|
|
@ -20,17 +20,17 @@
|
|||
import { CoreContext } from './core_context';
|
||||
import { getEnvOptions } from './config/__mocks__/env';
|
||||
import { Env, IConfigService } from './config';
|
||||
import { loggingServiceMock } from './logging/logging_service.mock';
|
||||
import { loggingSystemMock } from './logging/logging_system.mock';
|
||||
import { configServiceMock } from './config/config_service.mock';
|
||||
import { ILoggingService } from './logging';
|
||||
import { ILoggingSystem } from './logging';
|
||||
|
||||
function create({
|
||||
env = Env.createDefault(getEnvOptions()),
|
||||
logger = loggingServiceMock.create(),
|
||||
logger = loggingSystemMock.create(),
|
||||
configService = configServiceMock.create(),
|
||||
}: {
|
||||
env?: Env;
|
||||
logger?: jest.Mocked<ILoggingService>;
|
||||
logger?: jest.Mocked<ILoggingSystem>;
|
||||
configService?: jest.Mocked<IConfigService>;
|
||||
} = {}): DeeplyMockedKeys<CoreContext> {
|
||||
return { coreId: Symbol(), env, logger, configService };
|
||||
|
|
|
@ -28,11 +28,11 @@ import {
|
|||
import { errors } from 'elasticsearch';
|
||||
import { get } from 'lodash';
|
||||
import { Logger } from '../logging';
|
||||
import { loggingServiceMock } from '../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../logging/logging_system.mock';
|
||||
import { httpServerMock } from '../http/http_server.mocks';
|
||||
import { ClusterClient } from './cluster_client';
|
||||
|
||||
const logger = loggingServiceMock.create();
|
||||
const logger = loggingSystemMock.create();
|
||||
afterEach(() => jest.clearAllMocks());
|
||||
|
||||
test('#constructor creates client with parsed config', () => {
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
*/
|
||||
|
||||
import { duration } from 'moment';
|
||||
import { loggingServiceMock } from '../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../logging/logging_system.mock';
|
||||
import {
|
||||
ElasticsearchClientConfig,
|
||||
parseElasticsearchClientConfig,
|
||||
} from './elasticsearch_client_config';
|
||||
const logger = loggingServiceMock.create();
|
||||
const logger = loggingSystemMock.create();
|
||||
afterEach(() => jest.clearAllMocks());
|
||||
|
||||
test('parses minimally specified config', () => {
|
||||
|
@ -360,7 +360,7 @@ describe('#log', () => {
|
|||
|
||||
expect(typeof esLogger.close).toBe('function');
|
||||
|
||||
expect(loggingServiceMock.collect(logger)).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger)).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"debug": Array [],
|
||||
"error": Array [
|
||||
|
@ -406,7 +406,7 @@ Object {
|
|||
|
||||
expect(typeof esLogger.close).toBe('function');
|
||||
|
||||
expect(loggingServiceMock.collect(logger)).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger)).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"debug": Array [
|
||||
Array [
|
||||
|
|
|
@ -26,7 +26,7 @@ import { Env } from '../config';
|
|||
import { getEnvOptions } from '../config/__mocks__/env';
|
||||
import { CoreContext } from '../core_context';
|
||||
import { configServiceMock } from '../config/config_service.mock';
|
||||
import { loggingServiceMock } from '../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../logging/logging_system.mock';
|
||||
import { httpServiceMock } from '../http/http_service.mock';
|
||||
import { ElasticsearchConfig } from './elasticsearch_config';
|
||||
import { ElasticsearchService } from './elasticsearch_service';
|
||||
|
@ -55,7 +55,7 @@ configService.atPath.mockReturnValue(
|
|||
|
||||
let env: Env;
|
||||
let coreContext: CoreContext;
|
||||
const logger = loggingServiceMock.create();
|
||||
const logger = loggingSystemMock.create();
|
||||
beforeEach(() => {
|
||||
env = Env.createDefault(getEnvOptions());
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
import * as legacyElasticsearch from 'elasticsearch';
|
||||
|
||||
import { retryCallCluster, migrationsRetryCallCluster } from './retry_call_cluster';
|
||||
import { loggingServiceMock } from '../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../logging/logging_system.mock';
|
||||
|
||||
describe('retryCallCluster', () => {
|
||||
it('retries ES API calls that rejects with NoConnections', () => {
|
||||
|
@ -69,10 +69,10 @@ describe('migrationsRetryCallCluster', () => {
|
|||
'Gone',
|
||||
];
|
||||
|
||||
const mockLogger = loggingServiceMock.create();
|
||||
const mockLogger = loggingSystemMock.create();
|
||||
|
||||
beforeEach(() => {
|
||||
loggingServiceMock.clear(mockLogger);
|
||||
loggingSystemMock.clear(mockLogger);
|
||||
});
|
||||
|
||||
errors.forEach((errorName) => {
|
||||
|
@ -133,7 +133,7 @@ describe('migrationsRetryCallCluster', () => {
|
|||
callEsApi.mockResolvedValueOnce('done');
|
||||
const retried = migrationsRetryCallCluster(callEsApi, mockLogger.get('mock log'), 1);
|
||||
await retried('endpoint');
|
||||
expect(loggingServiceMock.collect(mockLogger).warn).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(mockLogger).warn).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"Unable to connect to Elasticsearch. Error: No Living connections",
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
* under the License.
|
||||
*/
|
||||
import { mapNodesVersionCompatibility, pollEsNodesVersion, NodesInfo } from './ensure_es_version';
|
||||
import { loggingServiceMock } from '../../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../../logging/logging_system.mock';
|
||||
import { take, delay } from 'rxjs/operators';
|
||||
import { TestScheduler } from 'rxjs/testing';
|
||||
import { of } from 'rxjs';
|
||||
|
||||
const mockLoggerFactory = loggingServiceMock.create();
|
||||
const mockLoggerFactory = loggingSystemMock.create();
|
||||
const mockLogger = mockLoggerFactory.get('mock logger');
|
||||
|
||||
const KIBANA_VERSION = '5.1.0';
|
||||
|
|
|
@ -29,14 +29,14 @@ import { Env } from '../config';
|
|||
import { getEnvOptions } from '../config/__mocks__/env';
|
||||
import { configServiceMock } from '../config/config_service.mock';
|
||||
import { contextServiceMock } from '../context/context_service.mock';
|
||||
import { loggingServiceMock } from '../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../logging/logging_system.mock';
|
||||
|
||||
import { httpServerMock } from './http_server.mocks';
|
||||
import { createCookieSessionStorageFactory } from './cookie_session_storage';
|
||||
|
||||
let server: HttpService;
|
||||
|
||||
let logger: ReturnType<typeof loggingServiceMock.create>;
|
||||
let logger: ReturnType<typeof loggingSystemMock.create>;
|
||||
let env: Env;
|
||||
let coreContext: CoreContext;
|
||||
const configService = configServiceMock.create();
|
||||
|
@ -67,7 +67,7 @@ configService.atPath.mockReturnValue(
|
|||
);
|
||||
|
||||
beforeEach(() => {
|
||||
logger = loggingServiceMock.create();
|
||||
logger = loggingSystemMock.create();
|
||||
env = Env.createDefault(getEnvOptions());
|
||||
|
||||
coreContext = { coreId: Symbol(), env, logger, configService: configService as any };
|
||||
|
@ -324,7 +324,7 @@ describe('Cookie based SessionStorage', () => {
|
|||
expect(mockServer.auth.test).toBeCalledTimes(1);
|
||||
expect(mockServer.auth.test).toHaveBeenCalledWith('security-cookie', mockRequest);
|
||||
|
||||
expect(loggingServiceMock.collect(logger).warn).toEqual([
|
||||
expect(loggingSystemMock.collect(logger).warn).toEqual([
|
||||
['Found 2 auth sessions when we were only expecting 1.'],
|
||||
]);
|
||||
});
|
||||
|
@ -381,7 +381,7 @@ describe('Cookie based SessionStorage', () => {
|
|||
const session = await factory.asScoped(KibanaRequest.from(mockRequest)).get();
|
||||
expect(session).toBe(null);
|
||||
|
||||
expect(loggingServiceMock.collect(logger).debug).toEqual([['Error: Invalid cookie.']]);
|
||||
expect(loggingSystemMock.collect(logger).debug).toEqual([['Error: Invalid cookie.']]);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ import {
|
|||
RouteValidationResultFactory,
|
||||
RouteValidationFunction,
|
||||
} from './router';
|
||||
import { loggingServiceMock } from '../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../logging/logging_system.mock';
|
||||
import { HttpServer } from './http_server';
|
||||
import { Readable } from 'stream';
|
||||
import { RequestHandlerContext } from 'kibana/server';
|
||||
|
@ -48,7 +48,7 @@ let server: HttpServer;
|
|||
let config: HttpConfig;
|
||||
let configWithSSL: HttpConfig;
|
||||
|
||||
const loggingService = loggingServiceMock.create();
|
||||
const loggingService = loggingSystemMock.create();
|
||||
const logger = loggingService.get();
|
||||
const enhanceWithContext = (fn: (...args: any[]) => any) => fn.bind(null, {});
|
||||
|
||||
|
@ -97,7 +97,7 @@ test('log listening address after started', async () => {
|
|||
await server.start();
|
||||
|
||||
expect(server.isListening()).toBe(true);
|
||||
expect(loggingServiceMock.collect(loggingService).info).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(loggingService).info).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"http server running at http://127.0.0.1:10002",
|
||||
|
@ -113,7 +113,7 @@ test('log listening address after started when configured with BasePath and rewr
|
|||
await server.start();
|
||||
|
||||
expect(server.isListening()).toBe(true);
|
||||
expect(loggingServiceMock.collect(loggingService).info).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(loggingService).info).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"http server running at http://127.0.0.1:10002",
|
||||
|
@ -129,7 +129,7 @@ test('log listening address after started when configured with BasePath and rewr
|
|||
await server.start();
|
||||
|
||||
expect(server.isListening()).toBe(true);
|
||||
expect(loggingServiceMock.collect(loggingService).info).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(loggingService).info).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"http server running at http://127.0.0.1:10002/bar",
|
||||
|
|
|
@ -25,12 +25,12 @@ import { HttpService } from '.';
|
|||
import { HttpConfigType, config } from './http_config';
|
||||
import { httpServerMock } from './http_server.mocks';
|
||||
import { ConfigService, Env } from '../config';
|
||||
import { loggingServiceMock } from '../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../logging/logging_system.mock';
|
||||
import { contextServiceMock } from '../context/context_service.mock';
|
||||
import { getEnvOptions } from '../config/__mocks__/env';
|
||||
import { config as cspConfig } from '../csp';
|
||||
|
||||
const logger = loggingServiceMock.create();
|
||||
const logger = loggingSystemMock.create();
|
||||
const env = Env.createDefault(getEnvOptions());
|
||||
const coreId = Symbol();
|
||||
|
||||
|
@ -159,7 +159,7 @@ test('logs error if already set up', async () => {
|
|||
|
||||
await service.setup(setupDeps);
|
||||
|
||||
expect(loggingServiceMock.collect(logger).warn).toMatchSnapshot();
|
||||
expect(loggingSystemMock.collect(logger).warn).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('stops http server', async () => {
|
||||
|
|
|
@ -34,7 +34,7 @@ import { defaultValidationErrorHandler, HapiValidationError, getServerOptions }
|
|||
import { HttpServer } from './http_server';
|
||||
import { HttpConfig, config } from './http_config';
|
||||
import { Router } from './router';
|
||||
import { loggingServiceMock } from '../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../logging/logging_system.mock';
|
||||
import { ByteSizeValue } from '@kbn/config-schema';
|
||||
|
||||
const emptyOutput = {
|
||||
|
@ -77,7 +77,7 @@ describe('defaultValidationErrorHandler', () => {
|
|||
});
|
||||
|
||||
describe('timeouts', () => {
|
||||
const logger = loggingServiceMock.create();
|
||||
const logger = loggingSystemMock.create();
|
||||
const server = new HttpServer(logger, 'foo');
|
||||
const enhanceWithContext = (fn: (...args: any[]) => any) => fn.bind(null, {});
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ import supertest from 'supertest';
|
|||
|
||||
import { ByteSizeValue } from '@kbn/config-schema';
|
||||
import { HttpConfig } from '.';
|
||||
import { loggingServiceMock } from '../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../logging/logging_system.mock';
|
||||
import { HttpsRedirectServer } from './https_redirect_server';
|
||||
|
||||
const chance = new Chance();
|
||||
|
@ -50,7 +50,7 @@ beforeEach(() => {
|
|||
},
|
||||
} as HttpConfig;
|
||||
|
||||
server = new HttpsRedirectServer(loggingServiceMock.create().get());
|
||||
server = new HttpsRedirectServer(loggingSystemMock.create().get());
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
|
|
|
@ -24,12 +24,12 @@ import { ensureRawRequest } from '../router';
|
|||
import { HttpService } from '../http_service';
|
||||
|
||||
import { contextServiceMock } from '../../context/context_service.mock';
|
||||
import { loggingServiceMock } from '../../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../../logging/logging_system.mock';
|
||||
import { createHttpServer } from '../test_utils';
|
||||
|
||||
let server: HttpService;
|
||||
|
||||
let logger: ReturnType<typeof loggingServiceMock.create>;
|
||||
let logger: ReturnType<typeof loggingSystemMock.create>;
|
||||
|
||||
const contextSetup = contextServiceMock.createSetupContract();
|
||||
|
||||
|
@ -38,7 +38,7 @@ const setupDeps = {
|
|||
};
|
||||
|
||||
beforeEach(() => {
|
||||
logger = loggingServiceMock.create();
|
||||
logger = loggingSystemMock.create();
|
||||
server = createHttpServer({ logger });
|
||||
});
|
||||
|
||||
|
@ -167,7 +167,7 @@ describe('OnPreAuth', () => {
|
|||
const result = await supertest(innerServer.listener).get('/').expect(500);
|
||||
|
||||
expect(result.body.message).toBe('An internal server error occurred.');
|
||||
expect(loggingServiceMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
[Error: reason],
|
||||
|
@ -188,7 +188,7 @@ describe('OnPreAuth', () => {
|
|||
const result = await supertest(innerServer.listener).get('/').expect(500);
|
||||
|
||||
expect(result.body.message).toBe('An internal server error occurred.');
|
||||
expect(loggingServiceMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
[Error: Unexpected result from OnPreAuth. Expected OnPreAuthResult or KibanaResponse, but given: [object Object].],
|
||||
|
@ -301,7 +301,7 @@ describe('OnPostAuth', () => {
|
|||
const result = await supertest(innerServer.listener).get('/').expect(500);
|
||||
|
||||
expect(result.body.message).toBe('An internal server error occurred.');
|
||||
expect(loggingServiceMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
[Error: reason],
|
||||
|
@ -321,7 +321,7 @@ describe('OnPostAuth', () => {
|
|||
const result = await supertest(innerServer.listener).get('/').expect(500);
|
||||
|
||||
expect(result.body.message).toBe('An internal server error occurred.');
|
||||
expect(loggingServiceMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
[Error: Unexpected result from OnPostAuth. Expected OnPostAuthResult or KibanaResponse, but given: [object Object].],
|
||||
|
@ -506,7 +506,7 @@ describe('Auth', () => {
|
|||
const result = await supertest(innerServer.listener).get('/').expect(500);
|
||||
|
||||
expect(result.body.message).toBe('An internal server error occurred.');
|
||||
expect(loggingServiceMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
[Error: reason],
|
||||
|
@ -703,7 +703,7 @@ describe('Auth', () => {
|
|||
const response = await supertest(innerServer.listener).get('/').expect(200);
|
||||
|
||||
expect(response.header['www-authenticate']).toBe('from auth interceptor');
|
||||
expect(loggingServiceMock.collect(logger).warn).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).warn).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"onPreResponseHandler rewrote a response header [www-authenticate].",
|
||||
|
@ -736,7 +736,7 @@ describe('Auth', () => {
|
|||
const response = await supertest(innerServer.listener).get('/').expect(400);
|
||||
|
||||
expect(response.header['www-authenticate']).toBe('from auth interceptor');
|
||||
expect(loggingServiceMock.collect(logger).warn).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).warn).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"onPreResponseHandler rewrote a response header [www-authenticate].",
|
||||
|
@ -798,7 +798,7 @@ describe('Auth', () => {
|
|||
const result = await supertest(innerServer.listener).get('/').expect(500);
|
||||
|
||||
expect(result.body.message).toBe('An internal server error occurred.');
|
||||
expect(loggingServiceMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
[Error: reason],
|
||||
|
@ -818,7 +818,7 @@ describe('Auth', () => {
|
|||
const result = await supertest(innerServer.listener).get('/').expect(500);
|
||||
|
||||
expect(result.body.message).toBe('An internal server error occurred.');
|
||||
expect(loggingServiceMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
[Error: Unexpected result from OnPostAuth. Expected OnPostAuthResult or KibanaResponse, but given: [object Object].],
|
||||
|
@ -929,7 +929,7 @@ describe('OnPreResponse', () => {
|
|||
|
||||
await supertest(innerServer.listener).get('/').expect(200);
|
||||
|
||||
expect(loggingServiceMock.collect(logger).warn).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).warn).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"onPreResponseHandler rewrote a response header [x-kibana-header].",
|
||||
|
@ -953,7 +953,7 @@ describe('OnPreResponse', () => {
|
|||
const result = await supertest(innerServer.listener).get('/').expect(500);
|
||||
|
||||
expect(result.body.message).toBe('An internal server error occurred.');
|
||||
expect(loggingServiceMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
[Error: reason],
|
||||
|
@ -975,7 +975,7 @@ describe('OnPreResponse', () => {
|
|||
const result = await supertest(innerServer.listener).get('/').expect(500);
|
||||
|
||||
expect(result.body.message).toBe('An internal server error occurred.');
|
||||
expect(loggingServiceMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
[Error: Unexpected result from OnPreResponse. Expected OnPreResponseResult, but given: [object Object].],
|
||||
|
|
|
@ -21,12 +21,12 @@ import supertest from 'supertest';
|
|||
import { HttpService } from '../http_service';
|
||||
|
||||
import { contextServiceMock } from '../../context/context_service.mock';
|
||||
import { loggingServiceMock } from '../../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../../logging/logging_system.mock';
|
||||
import { createHttpServer } from '../test_utils';
|
||||
|
||||
let server: HttpService;
|
||||
|
||||
let logger: ReturnType<typeof loggingServiceMock.create>;
|
||||
let logger: ReturnType<typeof loggingSystemMock.create>;
|
||||
const contextSetup = contextServiceMock.createSetupContract();
|
||||
|
||||
const setupDeps = {
|
||||
|
@ -34,7 +34,7 @@ const setupDeps = {
|
|||
};
|
||||
|
||||
beforeEach(() => {
|
||||
logger = loggingServiceMock.create();
|
||||
logger = loggingSystemMock.create();
|
||||
|
||||
server = createHttpServer({ logger });
|
||||
});
|
||||
|
|
|
@ -24,12 +24,12 @@ import { schema } from '@kbn/config-schema';
|
|||
import { HttpService } from '../http_service';
|
||||
|
||||
import { contextServiceMock } from '../../context/context_service.mock';
|
||||
import { loggingServiceMock } from '../../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../../logging/logging_system.mock';
|
||||
import { createHttpServer } from '../test_utils';
|
||||
|
||||
let server: HttpService;
|
||||
|
||||
let logger: ReturnType<typeof loggingServiceMock.create>;
|
||||
let logger: ReturnType<typeof loggingSystemMock.create>;
|
||||
const contextSetup = contextServiceMock.createSetupContract();
|
||||
|
||||
const setupDeps = {
|
||||
|
@ -37,7 +37,7 @@ const setupDeps = {
|
|||
};
|
||||
|
||||
beforeEach(() => {
|
||||
logger = loggingServiceMock.create();
|
||||
logger = loggingSystemMock.create();
|
||||
|
||||
server = createHttpServer({ logger });
|
||||
});
|
||||
|
@ -347,7 +347,7 @@ describe('Handler', () => {
|
|||
const result = await supertest(innerServer.listener).get('/').expect(500);
|
||||
|
||||
expect(result.body.message).toBe('An internal server error occurred.');
|
||||
expect(loggingServiceMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
[Error: unexpected error],
|
||||
|
@ -368,7 +368,7 @@ describe('Handler', () => {
|
|||
const result = await supertest(innerServer.listener).get('/').expect(500);
|
||||
|
||||
expect(result.body.message).toBe('An internal server error occurred.');
|
||||
expect(loggingServiceMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
[Error: Unauthorized],
|
||||
|
@ -387,7 +387,7 @@ describe('Handler', () => {
|
|||
const result = await supertest(innerServer.listener).get('/').expect(500);
|
||||
|
||||
expect(result.body.message).toBe('An internal server error occurred.');
|
||||
expect(loggingServiceMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
[Error: Unexpected result from Route Handler. Expected KibanaResponse, but given: string.],
|
||||
|
@ -763,7 +763,7 @@ describe('Response factory', () => {
|
|||
await supertest(innerServer.listener).get('/').expect(500);
|
||||
|
||||
// error happens within hapi when route handler already finished execution.
|
||||
expect(loggingServiceMock.collect(logger).error).toHaveLength(0);
|
||||
expect(loggingSystemMock.collect(logger).error).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('200 OK with body', async () => {
|
||||
|
@ -855,7 +855,7 @@ describe('Response factory', () => {
|
|||
const result = await supertest(innerServer.listener).get('/').expect(500);
|
||||
|
||||
expect(result.body.message).toBe('An internal server error occurred.');
|
||||
expect(loggingServiceMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
[Error: expected 'location' header to be set],
|
||||
|
@ -1261,7 +1261,7 @@ describe('Response factory', () => {
|
|||
message: 'An internal server error occurred.',
|
||||
statusCode: 500,
|
||||
});
|
||||
expect(loggingServiceMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
[Error: Unexpected Http status code. Expected from 400 to 599, but given: 200],
|
||||
|
@ -1330,7 +1330,7 @@ describe('Response factory', () => {
|
|||
|
||||
await supertest(innerServer.listener).get('/').expect(500);
|
||||
|
||||
expect(loggingServiceMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
[Error: expected 'location' header to be set],
|
||||
|
@ -1445,7 +1445,7 @@ describe('Response factory', () => {
|
|||
const result = await supertest(innerServer.listener).get('/').expect(500);
|
||||
|
||||
expect(result.body.message).toBe('reason');
|
||||
expect(loggingServiceMock.collect(logger).error).toHaveLength(0);
|
||||
expect(loggingSystemMock.collect(logger).error).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('throws an error if not valid error is provided', async () => {
|
||||
|
@ -1464,7 +1464,7 @@ describe('Response factory', () => {
|
|||
const result = await supertest(innerServer.listener).get('/').expect(500);
|
||||
|
||||
expect(result.body.message).toBe('An internal server error occurred.');
|
||||
expect(loggingServiceMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
[Error: expected error message to be provided],
|
||||
|
@ -1488,7 +1488,7 @@ describe('Response factory', () => {
|
|||
const result = await supertest(innerServer.listener).get('/').expect(500);
|
||||
|
||||
expect(result.body.message).toBe('An internal server error occurred.');
|
||||
expect(loggingServiceMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
[Error: expected error message to be provided],
|
||||
|
@ -1511,7 +1511,7 @@ describe('Response factory', () => {
|
|||
const result = await supertest(innerServer.listener).get('/').expect(500);
|
||||
|
||||
expect(result.body.message).toBe('An internal server error occurred.');
|
||||
expect(loggingServiceMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
[Error: options.statusCode is expected to be set. given options: undefined],
|
||||
|
@ -1534,7 +1534,7 @@ describe('Response factory', () => {
|
|||
const result = await supertest(innerServer.listener).get('/').expect(500);
|
||||
|
||||
expect(result.body.message).toBe('An internal server error occurred.');
|
||||
expect(loggingServiceMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
[Error: Unexpected Http status code. Expected from 100 to 599, but given: 20.],
|
||||
|
|
|
@ -18,10 +18,10 @@
|
|||
*/
|
||||
|
||||
import { Router } from './router';
|
||||
import { loggingServiceMock } from '../../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../../logging/logging_system.mock';
|
||||
import { schema } from '@kbn/config-schema';
|
||||
|
||||
const logger = loggingServiceMock.create().get();
|
||||
const logger = loggingSystemMock.create().get();
|
||||
const enhanceWithContext = (fn: (...args: any[]) => any) => fn.bind(null, {});
|
||||
|
||||
describe('Router', () => {
|
||||
|
|
|
@ -24,12 +24,12 @@ import { getEnvOptions } from '../config/__mocks__/env';
|
|||
import { HttpService } from './http_service';
|
||||
import { CoreContext } from '../core_context';
|
||||
import { configServiceMock } from '../config/config_service.mock';
|
||||
import { loggingServiceMock } from '../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../logging/logging_system.mock';
|
||||
|
||||
const coreId = Symbol('core');
|
||||
const env = Env.createDefault(getEnvOptions());
|
||||
|
||||
const logger = loggingServiceMock.create();
|
||||
const logger = loggingSystemMock.create();
|
||||
|
||||
const configService = configServiceMock.create();
|
||||
configService.atPath.mockReturnValue(
|
||||
|
|
|
@ -62,6 +62,12 @@ import { CapabilitiesSetup, CapabilitiesStart } from './capabilities';
|
|||
import { UuidServiceSetup } from './uuid';
|
||||
import { MetricsServiceSetup } from './metrics';
|
||||
import { StatusServiceSetup } from './status';
|
||||
import {
|
||||
LoggingServiceSetup,
|
||||
appendersSchema,
|
||||
loggerContextConfigSchema,
|
||||
loggerSchema,
|
||||
} from './logging';
|
||||
|
||||
export { bootstrap } from './bootstrap';
|
||||
export { Capabilities, CapabilitiesProvider, CapabilitiesSwitcher } from './capabilities';
|
||||
|
@ -187,7 +193,17 @@ export {
|
|||
} from './http_resources';
|
||||
|
||||
export { IRenderOptions } from './rendering';
|
||||
export { Logger, LoggerFactory, LogMeta, LogRecord, LogLevel } from './logging';
|
||||
export {
|
||||
Logger,
|
||||
LoggerFactory,
|
||||
LogMeta,
|
||||
LogRecord,
|
||||
LogLevel,
|
||||
LoggingServiceSetup,
|
||||
LoggerContextConfigInput,
|
||||
LoggerConfigType,
|
||||
AppenderConfigType,
|
||||
} from './logging';
|
||||
|
||||
export {
|
||||
DiscoveredPlugin,
|
||||
|
@ -385,6 +401,8 @@ export interface CoreSetup<TPluginsStart extends object = object, TStart = unkno
|
|||
/** {@link HttpResources} */
|
||||
resources: HttpResources;
|
||||
};
|
||||
/** {@link LoggingServiceSetup} */
|
||||
logging: LoggingServiceSetup;
|
||||
/** {@link MetricsServiceSetup} */
|
||||
metrics: MetricsServiceSetup;
|
||||
/** {@link SavedObjectsServiceSetup} */
|
||||
|
@ -450,4 +468,9 @@ export const config = {
|
|||
elasticsearch: {
|
||||
schema: elasticsearchConfigSchema,
|
||||
},
|
||||
logging: {
|
||||
appenders: appendersSchema,
|
||||
loggers: loggerSchema,
|
||||
loggerContext: loggerContextConfigSchema,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -34,6 +34,7 @@ import { InternalMetricsServiceSetup } from './metrics';
|
|||
import { InternalRenderingServiceSetup } from './rendering';
|
||||
import { InternalHttpResourcesSetup } from './http_resources';
|
||||
import { InternalStatusServiceSetup } from './status';
|
||||
import { InternalLoggingServiceSetup } from './logging';
|
||||
|
||||
/** @internal */
|
||||
export interface InternalCoreSetup {
|
||||
|
@ -48,6 +49,7 @@ export interface InternalCoreSetup {
|
|||
uuid: UuidServiceSetup;
|
||||
rendering: InternalRenderingServiceSetup;
|
||||
httpResources: InternalHttpResourcesSetup;
|
||||
logging: InternalLoggingServiceSetup;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -38,7 +38,7 @@ import { BasePathProxyServer } from '../http';
|
|||
import { DiscoveredPlugin } from '../plugins';
|
||||
|
||||
import { configServiceMock } from '../config/config_service.mock';
|
||||
import { loggingServiceMock } from '../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../logging/logging_system.mock';
|
||||
import { contextServiceMock } from '../context/context_service.mock';
|
||||
import { httpServiceMock } from '../http/http_service.mock';
|
||||
import { uiSettingsServiceMock } from '../ui_settings/ui_settings_service.mock';
|
||||
|
@ -53,6 +53,7 @@ import { LegacyVars, LegacyServiceSetupDeps, LegacyServiceStartDeps } from './ty
|
|||
import { LegacyService } from './legacy_service';
|
||||
import { coreMock } from '../mocks';
|
||||
import { statusServiceMock } from '../status/status_service.mock';
|
||||
import { loggingServiceMock } from '../logging/logging_service.mock';
|
||||
|
||||
const MockKbnServer: jest.Mock<KbnServer> = KbnServer as any;
|
||||
|
||||
|
@ -64,7 +65,7 @@ let setupDeps: LegacyServiceSetupDeps;
|
|||
|
||||
let startDeps: LegacyServiceStartDeps;
|
||||
|
||||
const logger = loggingServiceMock.create();
|
||||
const logger = loggingSystemMock.create();
|
||||
let configService: ReturnType<typeof configServiceMock.create>;
|
||||
let uuidSetup: ReturnType<typeof uuidServiceMock.createSetupContract>;
|
||||
|
||||
|
@ -100,6 +101,7 @@ beforeEach(() => {
|
|||
metrics: metricsServiceMock.createInternalSetupContract(),
|
||||
uuid: uuidSetup,
|
||||
status: statusServiceMock.createInternalSetupContract(),
|
||||
logging: loggingServiceMock.createInternalSetupContract(),
|
||||
},
|
||||
plugins: { 'plugin-id': 'plugin-value' },
|
||||
uiPlugins: {
|
||||
|
@ -281,7 +283,7 @@ describe('once LegacyService is set up with connection info', () => {
|
|||
|
||||
const [mockKbnServer] = MockKbnServer.mock.instances as Array<jest.Mocked<KbnServer>>;
|
||||
expect(mockKbnServer.applyLoggingConfiguration).not.toHaveBeenCalled();
|
||||
expect(loggingServiceMock.collect(logger).error).toEqual([]);
|
||||
expect(loggingSystemMock.collect(logger).error).toEqual([]);
|
||||
|
||||
const configError = new Error('something went wrong');
|
||||
mockKbnServer.applyLoggingConfiguration.mockImplementation(() => {
|
||||
|
@ -290,7 +292,7 @@ describe('once LegacyService is set up with connection info', () => {
|
|||
|
||||
config$.next(new ObjectToConfigAdapter({ logging: { verbose: true } }));
|
||||
|
||||
expect(loggingServiceMock.collect(logger).error).toEqual([[configError]]);
|
||||
expect(loggingSystemMock.collect(logger).error).toEqual([[configError]]);
|
||||
});
|
||||
|
||||
test('logs error if config service fails.', async () => {
|
||||
|
@ -306,13 +308,13 @@ describe('once LegacyService is set up with connection info', () => {
|
|||
|
||||
const [mockKbnServer] = MockKbnServer.mock.instances;
|
||||
expect(mockKbnServer.applyLoggingConfiguration).not.toHaveBeenCalled();
|
||||
expect(loggingServiceMock.collect(logger).error).toEqual([]);
|
||||
expect(loggingSystemMock.collect(logger).error).toEqual([]);
|
||||
|
||||
const configError = new Error('something went wrong');
|
||||
config$.error(configError);
|
||||
|
||||
expect(mockKbnServer.applyLoggingConfiguration).not.toHaveBeenCalled();
|
||||
expect(loggingServiceMock.collect(logger).error).toEqual([[configError]]);
|
||||
expect(loggingSystemMock.collect(logger).error).toEqual([[configError]]);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -309,6 +309,9 @@ export class LegacyService implements CoreService {
|
|||
csp: setupDeps.core.http.csp,
|
||||
getServerInfo: setupDeps.core.http.getServerInfo,
|
||||
},
|
||||
logging: {
|
||||
configure: (config$) => setupDeps.core.logging.configure([], config$),
|
||||
},
|
||||
metrics: {
|
||||
getOpsMetrics$: setupDeps.core.metrics.getOpsMetrics$,
|
||||
},
|
||||
|
|
|
@ -26,13 +26,19 @@ import { LogRecord } from '../log_record';
|
|||
import { ConsoleAppender } from './console/console_appender';
|
||||
import { FileAppender } from './file/file_appender';
|
||||
|
||||
const appendersSchema = schema.oneOf([
|
||||
/**
|
||||
* Config schema for validting the shape of the `appenders` key in in {@link LoggerContextConfigType} or
|
||||
* {@link LoggingConfigType}.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const appendersSchema = schema.oneOf([
|
||||
ConsoleAppender.configSchema,
|
||||
FileAppender.configSchema,
|
||||
LegacyAppender.configSchema,
|
||||
]);
|
||||
|
||||
/** @internal */
|
||||
/** @public */
|
||||
export type AppenderConfigType = TypeOf<typeof appendersSchema>;
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,7 +21,18 @@ export { Logger, LogMeta } from './logger';
|
|||
export { LoggerFactory } from './logger_factory';
|
||||
export { LogRecord } from './log_record';
|
||||
export { LogLevel } from './log_level';
|
||||
/** @internal */
|
||||
export { config, LoggingConfigType } from './logging_config';
|
||||
/** @internal */
|
||||
export { LoggingService, ILoggingService } from './logging_service';
|
||||
export {
|
||||
config,
|
||||
LoggingConfigType,
|
||||
LoggerContextConfigInput,
|
||||
LoggerConfigType,
|
||||
loggerContextConfigSchema,
|
||||
loggerSchema,
|
||||
} from './logging_config';
|
||||
export { LoggingSystem, ILoggingSystem } from './logging_system';
|
||||
export {
|
||||
InternalLoggingServiceSetup,
|
||||
LoggingServiceSetup,
|
||||
LoggingService,
|
||||
} from './logging_service';
|
||||
export { appendersSchema, AppenderConfigType } from './appenders/appenders';
|
||||
|
|
|
@ -171,3 +171,127 @@ test('fails if loggers use unknown appenders.', () => {
|
|||
|
||||
expect(() => new LoggingConfig(validateConfig)).toThrowErrorMatchingSnapshot();
|
||||
});
|
||||
|
||||
describe('extend', () => {
|
||||
it('adds new appenders', () => {
|
||||
const configValue = new LoggingConfig(
|
||||
config.schema.validate({
|
||||
appenders: {
|
||||
file1: {
|
||||
kind: 'file',
|
||||
layout: { kind: 'pattern' },
|
||||
path: 'path',
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
const mergedConfigValue = configValue.extend(
|
||||
config.schema.validate({
|
||||
appenders: {
|
||||
file2: {
|
||||
kind: 'file',
|
||||
layout: { kind: 'pattern' },
|
||||
path: 'path',
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
expect([...mergedConfigValue.appenders.keys()]).toEqual([
|
||||
'default',
|
||||
'console',
|
||||
'file1',
|
||||
'file2',
|
||||
]);
|
||||
});
|
||||
|
||||
it('overrides appenders', () => {
|
||||
const configValue = new LoggingConfig(
|
||||
config.schema.validate({
|
||||
appenders: {
|
||||
file1: {
|
||||
kind: 'file',
|
||||
layout: { kind: 'pattern' },
|
||||
path: 'path',
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
const mergedConfigValue = configValue.extend(
|
||||
config.schema.validate({
|
||||
appenders: {
|
||||
file1: {
|
||||
kind: 'file',
|
||||
layout: { kind: 'json' },
|
||||
path: 'updatedPath',
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
expect(mergedConfigValue.appenders.get('file1')).toEqual({
|
||||
kind: 'file',
|
||||
layout: { kind: 'json' },
|
||||
path: 'updatedPath',
|
||||
});
|
||||
});
|
||||
|
||||
it('adds new loggers', () => {
|
||||
const configValue = new LoggingConfig(
|
||||
config.schema.validate({
|
||||
loggers: [
|
||||
{
|
||||
context: 'plugins',
|
||||
level: 'warn',
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
const mergedConfigValue = configValue.extend(
|
||||
config.schema.validate({
|
||||
loggers: [
|
||||
{
|
||||
context: 'plugins.pid',
|
||||
level: 'trace',
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
expect([...mergedConfigValue.loggers.keys()]).toEqual(['root', 'plugins', 'plugins.pid']);
|
||||
});
|
||||
|
||||
it('overrides loggers', () => {
|
||||
const configValue = new LoggingConfig(
|
||||
config.schema.validate({
|
||||
loggers: [
|
||||
{
|
||||
context: 'plugins',
|
||||
level: 'warn',
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
const mergedConfigValue = configValue.extend(
|
||||
config.schema.validate({
|
||||
loggers: [
|
||||
{
|
||||
appenders: ['console'],
|
||||
context: 'plugins',
|
||||
level: 'trace',
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
expect(mergedConfigValue.loggers.get('plugins')).toEqual({
|
||||
appenders: ['console'],
|
||||
context: 'plugins',
|
||||
level: 'trace',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -39,7 +39,7 @@ const ROOT_CONTEXT_NAME = 'root';
|
|||
*/
|
||||
const DEFAULT_APPENDER_NAME = 'default';
|
||||
|
||||
const createLevelSchema = schema.oneOf(
|
||||
const levelSchema = schema.oneOf(
|
||||
[
|
||||
schema.literal('all'),
|
||||
schema.literal('fatal'),
|
||||
|
@ -55,21 +55,26 @@ const createLevelSchema = schema.oneOf(
|
|||
}
|
||||
);
|
||||
|
||||
const createLoggerSchema = schema.object({
|
||||
/**
|
||||
* Config schema for validating the `loggers` key in {@link LoggerContextConfigType} or {@link LoggingConfigType}.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const loggerSchema = schema.object({
|
||||
appenders: schema.arrayOf(schema.string(), { defaultValue: [] }),
|
||||
context: schema.string(),
|
||||
level: createLevelSchema,
|
||||
level: levelSchema,
|
||||
});
|
||||
|
||||
/** @internal */
|
||||
export type LoggerConfigType = TypeOf<typeof createLoggerSchema>;
|
||||
/** @public */
|
||||
export type LoggerConfigType = TypeOf<typeof loggerSchema>;
|
||||
export const config = {
|
||||
path: 'logging',
|
||||
schema: schema.object({
|
||||
appenders: schema.mapOf(schema.string(), Appenders.configSchema, {
|
||||
defaultValue: new Map<string, AppenderConfigType>(),
|
||||
}),
|
||||
loggers: schema.arrayOf(createLoggerSchema, {
|
||||
loggers: schema.arrayOf(loggerSchema, {
|
||||
defaultValue: [],
|
||||
}),
|
||||
root: schema.object(
|
||||
|
@ -78,7 +83,7 @@ export const config = {
|
|||
defaultValue: [DEFAULT_APPENDER_NAME],
|
||||
minSize: 1,
|
||||
}),
|
||||
level: createLevelSchema,
|
||||
level: levelSchema,
|
||||
},
|
||||
{
|
||||
validate(rawConfig) {
|
||||
|
@ -93,6 +98,29 @@ export const config = {
|
|||
|
||||
export type LoggingConfigType = TypeOf<typeof config.schema>;
|
||||
|
||||
/**
|
||||
* Config schema for validating the inputs to the {@link LoggingServiceStart.configure} API.
|
||||
* See {@link LoggerContextConfigType}.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const loggerContextConfigSchema = schema.object({
|
||||
appenders: schema.mapOf(schema.string(), Appenders.configSchema, {
|
||||
defaultValue: new Map<string, AppenderConfigType>(),
|
||||
}),
|
||||
|
||||
loggers: schema.arrayOf(loggerSchema, { defaultValue: [] }),
|
||||
});
|
||||
|
||||
/** @public */
|
||||
export type LoggerContextConfigType = TypeOf<typeof loggerContextConfigSchema>;
|
||||
/** @public */
|
||||
export interface LoggerContextConfigInput {
|
||||
// config-schema knows how to handle either Maps or Records
|
||||
appenders?: Record<string, AppenderConfigType> | Map<string, AppenderConfigType>;
|
||||
loggers?: LoggerConfigType[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the config used to fully setup logging subsystem.
|
||||
* @internal
|
||||
|
@ -147,11 +175,35 @@ export class LoggingConfig {
|
|||
*/
|
||||
public readonly loggers: Map<string, LoggerConfigType> = new Map();
|
||||
|
||||
constructor(configType: LoggingConfigType) {
|
||||
constructor(private readonly configType: LoggingConfigType) {
|
||||
this.fillAppendersConfig(configType);
|
||||
this.fillLoggersConfig(configType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new LoggingConfig that merges the existing config with the specified config.
|
||||
*
|
||||
* @remarks
|
||||
* Does not support merging the `root` config property.
|
||||
*
|
||||
* @param contextConfig
|
||||
*/
|
||||
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]),
|
||||
]);
|
||||
|
||||
const mergedConfig: LoggingConfigType = {
|
||||
appenders: new Map([...this.configType.appenders, ...contextConfig.appenders]),
|
||||
loggers: [...mergedLoggers.values()],
|
||||
root: this.configType.root,
|
||||
};
|
||||
|
||||
return new LoggingConfig(mergedConfig);
|
||||
}
|
||||
|
||||
private fillAppendersConfig(loggingConfig: LoggingConfigType) {
|
||||
for (const [appenderKey, appenderSchema] of loggingConfig.appenders) {
|
||||
this.appenders.set(appenderKey, appenderSchema);
|
||||
|
|
|
@ -17,67 +17,35 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
// Test helpers to simplify mocking logs and collecting all their outputs
|
||||
import { ILoggingService } from './logging_service';
|
||||
import { LoggerFactory } from './logger_factory';
|
||||
import { loggerMock, MockedLogger } from './logger.mock';
|
||||
import {
|
||||
LoggingService,
|
||||
LoggingServiceSetup,
|
||||
InternalLoggingServiceSetup,
|
||||
} from './logging_service';
|
||||
|
||||
const createLoggingServiceMock = () => {
|
||||
const mockLog = loggerMock.create();
|
||||
const createInternalSetupMock = (): jest.Mocked<InternalLoggingServiceSetup> => ({
|
||||
configure: jest.fn(),
|
||||
});
|
||||
|
||||
mockLog.get.mockImplementation((...context) => ({
|
||||
...mockLog,
|
||||
context,
|
||||
}));
|
||||
const createSetupMock = (): jest.Mocked<LoggingServiceSetup> => ({
|
||||
configure: jest.fn(),
|
||||
});
|
||||
|
||||
const mocked: jest.Mocked<ILoggingService> = {
|
||||
get: jest.fn(),
|
||||
asLoggerFactory: jest.fn(),
|
||||
upgrade: jest.fn(),
|
||||
type LoggingServiceContract = PublicMethodsOf<LoggingService>;
|
||||
const createMock = (): jest.Mocked<LoggingServiceContract> => {
|
||||
const service: jest.Mocked<LoggingServiceContract> = {
|
||||
setup: jest.fn(),
|
||||
start: jest.fn(),
|
||||
stop: jest.fn(),
|
||||
};
|
||||
mocked.get.mockImplementation((...context) => ({
|
||||
...mockLog,
|
||||
context,
|
||||
}));
|
||||
mocked.asLoggerFactory.mockImplementation(() => mocked);
|
||||
mocked.stop.mockResolvedValue();
|
||||
return mocked;
|
||||
};
|
||||
|
||||
const collectLoggingServiceMock = (loggerFactory: LoggerFactory) => {
|
||||
const mockLog = loggerFactory.get() as MockedLogger;
|
||||
return {
|
||||
debug: mockLog.debug.mock.calls,
|
||||
error: mockLog.error.mock.calls,
|
||||
fatal: mockLog.fatal.mock.calls,
|
||||
info: mockLog.info.mock.calls,
|
||||
log: mockLog.log.mock.calls,
|
||||
trace: mockLog.trace.mock.calls,
|
||||
warn: mockLog.warn.mock.calls,
|
||||
};
|
||||
};
|
||||
service.setup.mockReturnValue(createInternalSetupMock());
|
||||
|
||||
const clearLoggingServiceMock = (loggerFactory: LoggerFactory) => {
|
||||
const mockedLoggerFactory = (loggerFactory as unknown) as jest.Mocked<ILoggingService>;
|
||||
mockedLoggerFactory.get.mockClear();
|
||||
mockedLoggerFactory.asLoggerFactory.mockClear();
|
||||
mockedLoggerFactory.upgrade.mockClear();
|
||||
mockedLoggerFactory.stop.mockClear();
|
||||
|
||||
const mockLog = loggerFactory.get() as MockedLogger;
|
||||
mockLog.debug.mockClear();
|
||||
mockLog.info.mockClear();
|
||||
mockLog.warn.mockClear();
|
||||
mockLog.error.mockClear();
|
||||
mockLog.trace.mockClear();
|
||||
mockLog.fatal.mockClear();
|
||||
mockLog.log.mockClear();
|
||||
return service;
|
||||
};
|
||||
|
||||
export const loggingServiceMock = {
|
||||
create: createLoggingServiceMock,
|
||||
collect: collectLoggingServiceMock,
|
||||
clear: clearLoggingServiceMock,
|
||||
createLogger: loggerMock.create,
|
||||
create: createMock,
|
||||
createSetupContract: createSetupMock,
|
||||
createInternalSetupContract: createInternalSetupMock,
|
||||
};
|
||||
|
|
|
@ -16,167 +16,85 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { of, Subject } from 'rxjs';
|
||||
|
||||
const mockStreamWrite = jest.fn();
|
||||
jest.mock('fs', () => ({
|
||||
constants: {},
|
||||
createWriteStream: jest.fn(() => ({ write: mockStreamWrite })),
|
||||
}));
|
||||
import { LoggingService, InternalLoggingServiceSetup } from './logging_service';
|
||||
import { loggingSystemMock } from './logging_system.mock';
|
||||
import { LoggerContextConfigType } from './logging_config';
|
||||
|
||||
const dynamicProps = { pid: expect.any(Number) };
|
||||
describe('LoggingService', () => {
|
||||
let loggingSystem: ReturnType<typeof loggingSystemMock.create>;
|
||||
let service: LoggingService;
|
||||
let setup: InternalLoggingServiceSetup;
|
||||
|
||||
jest.mock('../../../legacy/server/logging/rotate', () => ({
|
||||
setupLoggingRotate: jest.fn().mockImplementation(() => Promise.resolve({})),
|
||||
}));
|
||||
beforeEach(() => {
|
||||
loggingSystem = loggingSystemMock.create();
|
||||
service = new LoggingService({ logger: loggingSystem.asLoggerFactory() } as any);
|
||||
setup = service.setup({ loggingSystem });
|
||||
});
|
||||
afterEach(() => {
|
||||
service.stop();
|
||||
});
|
||||
|
||||
const timestamp = new Date(Date.UTC(2012, 1, 1, 14, 33, 22, 11));
|
||||
let mockConsoleLog: jest.SpyInstance;
|
||||
describe('setup', () => {
|
||||
it('forwards configuration changes to logging system', () => {
|
||||
const config1: LoggerContextConfigType = {
|
||||
appenders: new Map(),
|
||||
loggers: [{ context: 'subcontext', appenders: ['console'], level: 'warn' }],
|
||||
};
|
||||
const config2: LoggerContextConfigType = {
|
||||
appenders: new Map(),
|
||||
loggers: [{ context: 'subcontext', appenders: ['default'], level: 'all' }],
|
||||
};
|
||||
|
||||
import { createWriteStream } from 'fs';
|
||||
const mockCreateWriteStream = (createWriteStream as unknown) as jest.Mock<typeof createWriteStream>;
|
||||
setup.configure(['test', 'context'], of(config1, config2));
|
||||
expect(loggingSystem.setContextConfig).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
['test', 'context'],
|
||||
config1
|
||||
);
|
||||
expect(loggingSystem.setContextConfig).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
['test', 'context'],
|
||||
config2
|
||||
);
|
||||
});
|
||||
|
||||
import { LoggingService, config } from '.';
|
||||
it('stops forwarding first observable when called a second time', () => {
|
||||
const updates$ = new Subject<LoggerContextConfigType>();
|
||||
const config1: LoggerContextConfigType = {
|
||||
appenders: new Map(),
|
||||
loggers: [{ context: 'subcontext', appenders: ['console'], level: 'warn' }],
|
||||
};
|
||||
const config2: LoggerContextConfigType = {
|
||||
appenders: new Map(),
|
||||
loggers: [{ context: 'subcontext', appenders: ['default'], level: 'all' }],
|
||||
};
|
||||
|
||||
let service: LoggingService;
|
||||
beforeEach(() => {
|
||||
mockConsoleLog = jest.spyOn(global.console, 'log').mockReturnValue(undefined);
|
||||
jest.spyOn<any, any>(global, 'Date').mockImplementation(() => timestamp);
|
||||
service = new LoggingService();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
mockCreateWriteStream.mockClear();
|
||||
mockStreamWrite.mockClear();
|
||||
});
|
||||
|
||||
test('uses default memory buffer logger until config is provided', () => {
|
||||
const bufferAppendSpy = jest.spyOn((service as any).bufferAppender, 'append');
|
||||
|
||||
const logger = service.get('test', 'context');
|
||||
logger.trace('trace message');
|
||||
|
||||
// We shouldn't create new buffer appender for another context.
|
||||
const anotherLogger = service.get('test', 'context2');
|
||||
anotherLogger.fatal('fatal message', { some: 'value' });
|
||||
|
||||
expect(bufferAppendSpy).toHaveBeenCalledTimes(2);
|
||||
expect(bufferAppendSpy.mock.calls[0][0]).toMatchSnapshot(dynamicProps);
|
||||
expect(bufferAppendSpy.mock.calls[1][0]).toMatchSnapshot(dynamicProps);
|
||||
});
|
||||
|
||||
test('flushes memory buffer logger and switches to real logger once config is provided', () => {
|
||||
const logger = service.get('test', 'context');
|
||||
|
||||
logger.trace('buffered trace message');
|
||||
logger.info('buffered info message', { some: 'value' });
|
||||
logger.fatal('buffered fatal message');
|
||||
|
||||
const bufferAppendSpy = jest.spyOn((service as any).bufferAppender, 'append');
|
||||
|
||||
// Switch to console appender with `info` level, so that `trace` message won't go through.
|
||||
service.upgrade(
|
||||
config.schema.validate({
|
||||
appenders: { default: { kind: 'console', layout: { kind: 'json' } } },
|
||||
root: { level: 'info' },
|
||||
})
|
||||
);
|
||||
|
||||
expect(JSON.parse(mockConsoleLog.mock.calls[0][0])).toMatchSnapshot(
|
||||
dynamicProps,
|
||||
'buffered messages'
|
||||
);
|
||||
mockConsoleLog.mockClear();
|
||||
|
||||
// Now message should go straight to thew newly configured appender, not buffered one.
|
||||
logger.info('some new info message');
|
||||
expect(JSON.parse(mockConsoleLog.mock.calls[0][0])).toMatchSnapshot(dynamicProps, 'new messages');
|
||||
expect(bufferAppendSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('appends records via multiple appenders.', () => {
|
||||
const loggerWithoutConfig = service.get('some-context');
|
||||
const testsLogger = service.get('tests');
|
||||
const testsChildLogger = service.get('tests', 'child');
|
||||
|
||||
loggerWithoutConfig.info('You know, just for your info.');
|
||||
testsLogger.warn('Config is not ready!');
|
||||
testsChildLogger.error('Too bad that config is not ready :/');
|
||||
testsChildLogger.info('Just some info that should not be logged.');
|
||||
|
||||
expect(mockConsoleLog).not.toHaveBeenCalled();
|
||||
expect(mockCreateWriteStream).not.toHaveBeenCalled();
|
||||
|
||||
service.upgrade(
|
||||
config.schema.validate({
|
||||
appenders: {
|
||||
default: { kind: 'console', layout: { kind: 'pattern' } },
|
||||
file: { kind: 'file', layout: { kind: 'pattern' }, path: 'path' },
|
||||
},
|
||||
loggers: [
|
||||
{ appenders: ['file'], context: 'tests', level: 'warn' },
|
||||
{ context: 'tests.child', level: 'error' },
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
// Now all logs should added to configured appenders.
|
||||
expect(mockConsoleLog).toHaveBeenCalledTimes(1);
|
||||
expect(mockConsoleLog.mock.calls[0][0]).toMatchSnapshot('console logs');
|
||||
|
||||
expect(mockStreamWrite).toHaveBeenCalledTimes(2);
|
||||
expect(mockStreamWrite.mock.calls[0][0]).toMatchSnapshot('file logs');
|
||||
expect(mockStreamWrite.mock.calls[1][0]).toMatchSnapshot('file logs');
|
||||
});
|
||||
|
||||
test('uses `root` logger if context is not specified.', () => {
|
||||
service.upgrade(
|
||||
config.schema.validate({
|
||||
appenders: { default: { kind: 'console', layout: { kind: 'pattern' } } },
|
||||
})
|
||||
);
|
||||
|
||||
const rootLogger = service.get();
|
||||
rootLogger.info('This message goes to a root context.');
|
||||
|
||||
expect(mockConsoleLog.mock.calls).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('`stop()` disposes all appenders.', async () => {
|
||||
service.upgrade(
|
||||
config.schema.validate({
|
||||
appenders: { default: { kind: 'console', layout: { kind: 'json' } } },
|
||||
root: { level: 'info' },
|
||||
})
|
||||
);
|
||||
|
||||
const bufferDisposeSpy = jest.spyOn((service as any).bufferAppender, 'dispose');
|
||||
const consoleDisposeSpy = jest.spyOn((service as any).appenders.get('default'), 'dispose');
|
||||
|
||||
await service.stop();
|
||||
|
||||
expect(bufferDisposeSpy).toHaveBeenCalledTimes(1);
|
||||
expect(consoleDisposeSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('asLoggerFactory() only allows to create new loggers.', () => {
|
||||
const logger = service.asLoggerFactory().get('test', 'context');
|
||||
|
||||
service.upgrade(
|
||||
config.schema.validate({
|
||||
appenders: { default: { kind: 'console', layout: { kind: 'json' } } },
|
||||
root: { level: 'all' },
|
||||
})
|
||||
);
|
||||
|
||||
logger.trace('buffered trace message');
|
||||
logger.info('buffered info message', { some: 'value' });
|
||||
logger.fatal('buffered fatal message');
|
||||
|
||||
expect(Object.keys(service.asLoggerFactory())).toEqual(['get']);
|
||||
|
||||
expect(mockConsoleLog).toHaveBeenCalledTimes(3);
|
||||
expect(JSON.parse(mockConsoleLog.mock.calls[0][0])).toMatchSnapshot(dynamicProps);
|
||||
expect(JSON.parse(mockConsoleLog.mock.calls[1][0])).toMatchSnapshot(dynamicProps);
|
||||
expect(JSON.parse(mockConsoleLog.mock.calls[2][0])).toMatchSnapshot(dynamicProps);
|
||||
setup.configure(['test', 'context'], updates$);
|
||||
setup.configure(['test', 'context'], of(config1));
|
||||
updates$.next(config2);
|
||||
expect(loggingSystem.setContextConfig).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
['test', 'context'],
|
||||
config1
|
||||
);
|
||||
expect(loggingSystem.setContextConfig).not.toHaveBeenCalledWith(['test', 'context'], config2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('stop', () => {
|
||||
it('stops forwarding updates to logging system', () => {
|
||||
const updates$ = new Subject<LoggerContextConfigType>();
|
||||
const config1: LoggerContextConfigType = {
|
||||
appenders: new Map(),
|
||||
loggers: [{ context: 'subcontext', appenders: ['console'], level: 'warn' }],
|
||||
};
|
||||
|
||||
setup.configure(['test', 'context'], updates$);
|
||||
service.stop();
|
||||
updates$.next(config1);
|
||||
expect(loggingSystem.setContextConfig).not.toHaveBeenCalledWith(['test', 'context'], config1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -16,112 +16,88 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { Appenders, DisposableAppender } from './appenders/appenders';
|
||||
import { BufferAppender } from './appenders/buffer/buffer_appender';
|
||||
import { LogLevel } from './log_level';
|
||||
import { BaseLogger, Logger } from './logger';
|
||||
import { LoggerAdapter } from './logger_adapter';
|
||||
import { LoggerFactory } from './logger_factory';
|
||||
import { LoggingConfigType, LoggerConfigType, LoggingConfig } from './logging_config';
|
||||
|
||||
export type ILoggingService = PublicMethodsOf<LoggingService>;
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
import { CoreService } from '../../types';
|
||||
import { LoggingConfig, LoggerContextConfigInput } from './logging_config';
|
||||
import { ILoggingSystem } from './logging_system';
|
||||
import { Logger } from './logger';
|
||||
import { CoreContext } from '../core_context';
|
||||
|
||||
/**
|
||||
* Service that is responsible for maintaining loggers and logger appenders.
|
||||
* @internal
|
||||
* Provides APIs to plugins for customizing the plugin's logger.
|
||||
* @public
|
||||
*/
|
||||
export class LoggingService implements LoggerFactory {
|
||||
private config?: LoggingConfig;
|
||||
private readonly appenders: Map<string, DisposableAppender> = new Map();
|
||||
private readonly bufferAppender = new BufferAppender();
|
||||
private readonly loggers: Map<string, LoggerAdapter> = new Map();
|
||||
|
||||
public get(...contextParts: string[]): Logger {
|
||||
const context = LoggingConfig.getLoggerContext(contextParts);
|
||||
if (!this.loggers.has(context)) {
|
||||
this.loggers.set(context, new LoggerAdapter(this.createLogger(context, this.config)));
|
||||
}
|
||||
return this.loggers.get(context)!;
|
||||
}
|
||||
|
||||
export interface LoggingServiceSetup {
|
||||
/**
|
||||
* Safe wrapper that allows passing logging service as immutable LoggerFactory.
|
||||
* Customizes the logging config for the plugin's context.
|
||||
*
|
||||
* @remarks
|
||||
* Assumes that that the `context` property of the individual `logger` items emitted by `config$`
|
||||
* are relative to the plugin's logging context (defaults to `plugins.<plugin_id>`).
|
||||
*
|
||||
* @example
|
||||
* Customize the configuration for the plugins.data.search context.
|
||||
* ```ts
|
||||
* core.logging.configure(
|
||||
* of({
|
||||
* appenders: new Map(),
|
||||
* loggers: [{ context: 'search', appenders: ['default'] }]
|
||||
* })
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* @param config$
|
||||
*/
|
||||
public asLoggerFactory(): LoggerFactory {
|
||||
return { get: (...contextParts: string[]) => this.get(...contextParts) };
|
||||
configure(config$: Observable<LoggerContextConfigInput>): void;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface InternalLoggingServiceSetup {
|
||||
configure(contextParts: string[], config$: Observable<LoggerContextConfigInput>): void;
|
||||
}
|
||||
|
||||
interface SetupDeps {
|
||||
loggingSystem: ILoggingSystem;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export class LoggingService implements CoreService<InternalLoggingServiceSetup> {
|
||||
private readonly subscriptions = new Map<string, Subscription>();
|
||||
private readonly log: Logger;
|
||||
|
||||
constructor(coreContext: CoreContext) {
|
||||
this.log = coreContext.logger.get('logging');
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates all current active loggers with the new config values.
|
||||
* @param rawConfig New config instance.
|
||||
*/
|
||||
public upgrade(rawConfig: LoggingConfigType) {
|
||||
const config = new LoggingConfig(rawConfig);
|
||||
// Config update is asynchronous and may require some time to complete, so we should invalidate
|
||||
// config so that new loggers will be using BufferAppender until newly configured appenders are ready.
|
||||
this.config = undefined;
|
||||
public setup({ loggingSystem }: SetupDeps) {
|
||||
return {
|
||||
configure: (contextParts: string[], config$: Observable<LoggerContextConfigInput>) => {
|
||||
const contextName = LoggingConfig.getLoggerContext(contextParts);
|
||||
this.log.debug(`Setting custom config for context [${contextName}]`);
|
||||
|
||||
// Appenders must be reset, so we first dispose of the current ones, then
|
||||
// build up a new set of appenders.
|
||||
for (const appender of this.appenders.values()) {
|
||||
appender.dispose();
|
||||
}
|
||||
this.appenders.clear();
|
||||
const existingSubscription = this.subscriptions.get(contextName);
|
||||
if (existingSubscription) {
|
||||
existingSubscription.unsubscribe();
|
||||
}
|
||||
|
||||
for (const [appenderKey, appenderConfig] of config.appenders) {
|
||||
this.appenders.set(appenderKey, Appenders.create(appenderConfig));
|
||||
}
|
||||
|
||||
for (const [loggerKey, loggerAdapter] of this.loggers) {
|
||||
loggerAdapter.updateLogger(this.createLogger(loggerKey, config));
|
||||
}
|
||||
|
||||
this.config = config;
|
||||
|
||||
// Re-log all buffered log records with newly configured appenders.
|
||||
for (const logRecord of this.bufferAppender.flush()) {
|
||||
this.get(logRecord.context).log(logRecord);
|
||||
}
|
||||
// Might be fancier way to do this with rxjs, but this works and is simple to understand
|
||||
this.subscriptions.set(
|
||||
contextName,
|
||||
config$.subscribe((config) => {
|
||||
this.log.debug(`Updating logging config for context [${contextName}]`);
|
||||
loggingSystem.setContextConfig(contextParts, config);
|
||||
})
|
||||
);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Disposes all loggers (closes log files, clears buffers etc.). Service is not usable after
|
||||
* calling of this method until new config is provided via `upgrade` method.
|
||||
* @returns Promise that is resolved once all loggers are successfully disposed.
|
||||
*/
|
||||
public async stop() {
|
||||
for (const appender of this.appenders.values()) {
|
||||
await appender.dispose();
|
||||
public start() {}
|
||||
|
||||
public stop() {
|
||||
for (const [, subscription] of this.subscriptions) {
|
||||
subscription.unsubscribe();
|
||||
}
|
||||
|
||||
await this.bufferAppender.dispose();
|
||||
|
||||
this.appenders.clear();
|
||||
this.loggers.clear();
|
||||
}
|
||||
|
||||
private createLogger(context: string, config: LoggingConfig | undefined) {
|
||||
if (config === undefined) {
|
||||
// If we don't have config yet, use `buffered` appender that will store all logged messages in the memory
|
||||
// until the config is ready.
|
||||
return new BaseLogger(context, LogLevel.All, [this.bufferAppender], this.asLoggerFactory());
|
||||
}
|
||||
|
||||
const { level, appenders } = this.getLoggerConfigByContext(config, context);
|
||||
const loggerLevel = LogLevel.fromId(level);
|
||||
const loggerAppenders = appenders.map((appenderKey) => this.appenders.get(appenderKey)!);
|
||||
|
||||
return new BaseLogger(context, loggerLevel, loggerAppenders, this.asLoggerFactory());
|
||||
}
|
||||
|
||||
private getLoggerConfigByContext(config: LoggingConfig, context: string): LoggerConfigType {
|
||||
const loggerConfig = config.loggers.get(context);
|
||||
if (loggerConfig !== undefined) {
|
||||
return loggerConfig;
|
||||
}
|
||||
|
||||
// If we don't have configuration for the specified context and it's the "nested" one (eg. `foo.bar.baz`),
|
||||
// let's move up to the parent context (eg. `foo.bar`) and check if it has config we can rely on. Otherwise
|
||||
// we fallback to the `root` context that should always be defined (enforced by configuration schema).
|
||||
return this.getLoggerConfigByContext(config, LoggingConfig.getParentLoggerContext(context));
|
||||
}
|
||||
}
|
||||
|
|
84
src/core/server/logging/logging_system.mock.ts
Normal file
84
src/core/server/logging/logging_system.mock.ts
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// Test helpers to simplify mocking logs and collecting all their outputs
|
||||
import { ILoggingSystem } from './logging_system';
|
||||
import { LoggerFactory } from './logger_factory';
|
||||
import { loggerMock, MockedLogger } from './logger.mock';
|
||||
|
||||
const createLoggingSystemMock = () => {
|
||||
const mockLog = loggerMock.create();
|
||||
|
||||
mockLog.get.mockImplementation((...context) => ({
|
||||
...mockLog,
|
||||
context,
|
||||
}));
|
||||
|
||||
const mocked: jest.Mocked<ILoggingSystem> = {
|
||||
get: jest.fn(),
|
||||
asLoggerFactory: jest.fn(),
|
||||
setContextConfig: jest.fn(),
|
||||
upgrade: jest.fn(),
|
||||
stop: jest.fn(),
|
||||
};
|
||||
mocked.get.mockImplementation((...context) => ({
|
||||
...mockLog,
|
||||
context,
|
||||
}));
|
||||
mocked.asLoggerFactory.mockImplementation(() => mocked);
|
||||
mocked.stop.mockResolvedValue();
|
||||
return mocked;
|
||||
};
|
||||
|
||||
const collectLoggingSystemMock = (loggerFactory: LoggerFactory) => {
|
||||
const mockLog = loggerFactory.get() as MockedLogger;
|
||||
return {
|
||||
debug: mockLog.debug.mock.calls,
|
||||
error: mockLog.error.mock.calls,
|
||||
fatal: mockLog.fatal.mock.calls,
|
||||
info: mockLog.info.mock.calls,
|
||||
log: mockLog.log.mock.calls,
|
||||
trace: mockLog.trace.mock.calls,
|
||||
warn: mockLog.warn.mock.calls,
|
||||
};
|
||||
};
|
||||
|
||||
const clearLoggingSystemMock = (loggerFactory: LoggerFactory) => {
|
||||
const mockedLoggerFactory = (loggerFactory as unknown) as jest.Mocked<ILoggingSystem>;
|
||||
mockedLoggerFactory.get.mockClear();
|
||||
mockedLoggerFactory.asLoggerFactory.mockClear();
|
||||
mockedLoggerFactory.upgrade.mockClear();
|
||||
mockedLoggerFactory.stop.mockClear();
|
||||
|
||||
const mockLog = loggerFactory.get() as MockedLogger;
|
||||
mockLog.debug.mockClear();
|
||||
mockLog.info.mockClear();
|
||||
mockLog.warn.mockClear();
|
||||
mockLog.error.mockClear();
|
||||
mockLog.trace.mockClear();
|
||||
mockLog.fatal.mockClear();
|
||||
mockLog.log.mockClear();
|
||||
};
|
||||
|
||||
export const loggingSystemMock = {
|
||||
create: createLoggingSystemMock,
|
||||
collect: collectLoggingSystemMock,
|
||||
clear: clearLoggingSystemMock,
|
||||
createLogger: loggerMock.create,
|
||||
};
|
348
src/core/server/logging/logging_system.test.ts
Normal file
348
src/core/server/logging/logging_system.test.ts
Normal file
|
@ -0,0 +1,348 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
const mockStreamWrite = jest.fn();
|
||||
jest.mock('fs', () => ({
|
||||
constants: {},
|
||||
createWriteStream: jest.fn(() => ({ write: mockStreamWrite })),
|
||||
}));
|
||||
|
||||
const dynamicProps = { pid: expect.any(Number) };
|
||||
|
||||
jest.mock('../../../legacy/server/logging/rotate', () => ({
|
||||
setupLoggingRotate: jest.fn().mockImplementation(() => Promise.resolve({})),
|
||||
}));
|
||||
|
||||
const timestamp = new Date(Date.UTC(2012, 1, 1, 14, 33, 22, 11));
|
||||
let mockConsoleLog: jest.SpyInstance;
|
||||
|
||||
import { createWriteStream } from 'fs';
|
||||
const mockCreateWriteStream = (createWriteStream as unknown) as jest.Mock<typeof createWriteStream>;
|
||||
|
||||
import { LoggingSystem, config } from '.';
|
||||
|
||||
let system: LoggingSystem;
|
||||
beforeEach(() => {
|
||||
mockConsoleLog = jest.spyOn(global.console, 'log').mockReturnValue(undefined);
|
||||
jest.spyOn<any, any>(global, 'Date').mockImplementation(() => timestamp);
|
||||
system = new LoggingSystem();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
mockCreateWriteStream.mockClear();
|
||||
mockStreamWrite.mockClear();
|
||||
});
|
||||
|
||||
test('uses default memory buffer logger until config is provided', () => {
|
||||
const bufferAppendSpy = jest.spyOn((system as any).bufferAppender, 'append');
|
||||
|
||||
const logger = system.get('test', 'context');
|
||||
logger.trace('trace message');
|
||||
|
||||
// We shouldn't create new buffer appender for another context.
|
||||
const anotherLogger = system.get('test', 'context2');
|
||||
anotherLogger.fatal('fatal message', { some: 'value' });
|
||||
|
||||
expect(bufferAppendSpy).toHaveBeenCalledTimes(2);
|
||||
expect(bufferAppendSpy.mock.calls[0][0]).toMatchSnapshot(dynamicProps);
|
||||
expect(bufferAppendSpy.mock.calls[1][0]).toMatchSnapshot(dynamicProps);
|
||||
});
|
||||
|
||||
test('flushes memory buffer logger and switches to real logger once config is provided', () => {
|
||||
const logger = system.get('test', 'context');
|
||||
|
||||
logger.trace('buffered trace message');
|
||||
logger.info('buffered info message', { some: 'value' });
|
||||
logger.fatal('buffered fatal message');
|
||||
|
||||
const bufferAppendSpy = jest.spyOn((system as any).bufferAppender, 'append');
|
||||
|
||||
// Switch to console appender with `info` level, so that `trace` message won't go through.
|
||||
system.upgrade(
|
||||
config.schema.validate({
|
||||
appenders: { default: { kind: 'console', layout: { kind: 'json' } } },
|
||||
root: { level: 'info' },
|
||||
})
|
||||
);
|
||||
|
||||
expect(JSON.parse(mockConsoleLog.mock.calls[0][0])).toMatchSnapshot(
|
||||
dynamicProps,
|
||||
'buffered messages'
|
||||
);
|
||||
mockConsoleLog.mockClear();
|
||||
|
||||
// Now message should go straight to thew newly configured appender, not buffered one.
|
||||
logger.info('some new info message');
|
||||
expect(JSON.parse(mockConsoleLog.mock.calls[0][0])).toMatchSnapshot(dynamicProps, 'new messages');
|
||||
expect(bufferAppendSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('appends records via multiple appenders.', () => {
|
||||
const loggerWithoutConfig = system.get('some-context');
|
||||
const testsLogger = system.get('tests');
|
||||
const testsChildLogger = system.get('tests', 'child');
|
||||
|
||||
loggerWithoutConfig.info('You know, just for your info.');
|
||||
testsLogger.warn('Config is not ready!');
|
||||
testsChildLogger.error('Too bad that config is not ready :/');
|
||||
testsChildLogger.info('Just some info that should not be logged.');
|
||||
|
||||
expect(mockConsoleLog).not.toHaveBeenCalled();
|
||||
expect(mockCreateWriteStream).not.toHaveBeenCalled();
|
||||
|
||||
system.upgrade(
|
||||
config.schema.validate({
|
||||
appenders: {
|
||||
default: { kind: 'console', layout: { kind: 'pattern' } },
|
||||
file: { kind: 'file', layout: { kind: 'pattern' }, path: 'path' },
|
||||
},
|
||||
loggers: [
|
||||
{ appenders: ['file'], context: 'tests', level: 'warn' },
|
||||
{ context: 'tests.child', level: 'error' },
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
// Now all logs should added to configured appenders.
|
||||
expect(mockConsoleLog).toHaveBeenCalledTimes(1);
|
||||
expect(mockConsoleLog.mock.calls[0][0]).toMatchSnapshot('console logs');
|
||||
|
||||
expect(mockStreamWrite).toHaveBeenCalledTimes(2);
|
||||
expect(mockStreamWrite.mock.calls[0][0]).toMatchSnapshot('file logs');
|
||||
expect(mockStreamWrite.mock.calls[1][0]).toMatchSnapshot('file logs');
|
||||
});
|
||||
|
||||
test('uses `root` logger if context is not specified.', () => {
|
||||
system.upgrade(
|
||||
config.schema.validate({
|
||||
appenders: { default: { kind: 'console', layout: { kind: 'pattern' } } },
|
||||
})
|
||||
);
|
||||
|
||||
const rootLogger = system.get();
|
||||
rootLogger.info('This message goes to a root context.');
|
||||
|
||||
expect(mockConsoleLog.mock.calls).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('`stop()` disposes all appenders.', async () => {
|
||||
system.upgrade(
|
||||
config.schema.validate({
|
||||
appenders: { default: { kind: 'console', layout: { kind: 'json' } } },
|
||||
root: { level: 'info' },
|
||||
})
|
||||
);
|
||||
|
||||
const bufferDisposeSpy = jest.spyOn((system as any).bufferAppender, 'dispose');
|
||||
const consoleDisposeSpy = jest.spyOn((system as any).appenders.get('default'), 'dispose');
|
||||
|
||||
await system.stop();
|
||||
|
||||
expect(bufferDisposeSpy).toHaveBeenCalledTimes(1);
|
||||
expect(consoleDisposeSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('asLoggerFactory() only allows to create new loggers.', () => {
|
||||
const logger = system.asLoggerFactory().get('test', 'context');
|
||||
|
||||
system.upgrade(
|
||||
config.schema.validate({
|
||||
appenders: { default: { kind: 'console', layout: { kind: 'json' } } },
|
||||
root: { level: 'all' },
|
||||
})
|
||||
);
|
||||
|
||||
logger.trace('buffered trace message');
|
||||
logger.info('buffered info message', { some: 'value' });
|
||||
logger.fatal('buffered fatal message');
|
||||
|
||||
expect(Object.keys(system.asLoggerFactory())).toEqual(['get']);
|
||||
|
||||
expect(mockConsoleLog).toHaveBeenCalledTimes(3);
|
||||
expect(JSON.parse(mockConsoleLog.mock.calls[0][0])).toMatchSnapshot(dynamicProps);
|
||||
expect(JSON.parse(mockConsoleLog.mock.calls[1][0])).toMatchSnapshot(dynamicProps);
|
||||
expect(JSON.parse(mockConsoleLog.mock.calls[2][0])).toMatchSnapshot(dynamicProps);
|
||||
});
|
||||
|
||||
test('setContextConfig() updates config with relative contexts', () => {
|
||||
const testsLogger = system.get('tests');
|
||||
const testsChildLogger = system.get('tests', 'child');
|
||||
const testsGrandchildLogger = system.get('tests', 'child', 'grandchild');
|
||||
|
||||
system.upgrade(
|
||||
config.schema.validate({
|
||||
appenders: { default: { kind: 'console', layout: { kind: 'json' } } },
|
||||
root: { level: 'info' },
|
||||
})
|
||||
);
|
||||
|
||||
system.setContextConfig(['tests', 'child'], {
|
||||
appenders: new Map([
|
||||
[
|
||||
'custom',
|
||||
{ kind: 'console', layout: { kind: 'pattern', pattern: '[%level][%logger] %message' } },
|
||||
],
|
||||
]),
|
||||
loggers: [{ context: 'grandchild', appenders: ['default', 'custom'], level: 'debug' }],
|
||||
});
|
||||
|
||||
testsLogger.warn('tests log to default!');
|
||||
testsChildLogger.error('tests.child log to default!');
|
||||
testsGrandchildLogger.debug('tests.child.grandchild log to default and custom!');
|
||||
|
||||
expect(mockConsoleLog).toHaveBeenCalledTimes(4);
|
||||
// Parent contexts are unaffected
|
||||
expect(JSON.parse(mockConsoleLog.mock.calls[0][0])).toMatchObject({
|
||||
context: 'tests',
|
||||
message: 'tests log to default!',
|
||||
level: 'WARN',
|
||||
});
|
||||
expect(JSON.parse(mockConsoleLog.mock.calls[1][0])).toMatchObject({
|
||||
context: 'tests.child',
|
||||
message: 'tests.child log to default!',
|
||||
level: 'ERROR',
|
||||
});
|
||||
// Customized context is logged in both appender formats
|
||||
expect(JSON.parse(mockConsoleLog.mock.calls[2][0])).toMatchObject({
|
||||
context: 'tests.child.grandchild',
|
||||
message: 'tests.child.grandchild log to default and custom!',
|
||||
level: 'DEBUG',
|
||||
});
|
||||
expect(mockConsoleLog.mock.calls[3][0]).toMatchInlineSnapshot(
|
||||
`"[DEBUG][tests.child.grandchild] tests.child.grandchild log to default and custom!"`
|
||||
);
|
||||
});
|
||||
|
||||
test('custom context configs are applied on subsequent calls to update()', () => {
|
||||
system.setContextConfig(['tests', 'child'], {
|
||||
appenders: new Map([
|
||||
[
|
||||
'custom',
|
||||
{ kind: 'console', layout: { kind: 'pattern', pattern: '[%level][%logger] %message' } },
|
||||
],
|
||||
]),
|
||||
loggers: [{ context: 'grandchild', appenders: ['default', 'custom'], level: 'debug' }],
|
||||
});
|
||||
|
||||
// Calling upgrade after setContextConfig should not throw away the context-specific config
|
||||
system.upgrade(
|
||||
config.schema.validate({
|
||||
appenders: { default: { kind: 'console', layout: { kind: 'json' } } },
|
||||
root: { level: 'info' },
|
||||
})
|
||||
);
|
||||
|
||||
system
|
||||
.get('tests', 'child', 'grandchild')
|
||||
.debug('tests.child.grandchild log to default and custom!');
|
||||
|
||||
// Customized context is logged in both appender formats still
|
||||
expect(mockConsoleLog).toHaveBeenCalledTimes(2);
|
||||
expect(JSON.parse(mockConsoleLog.mock.calls[0][0])).toMatchObject({
|
||||
context: 'tests.child.grandchild',
|
||||
message: 'tests.child.grandchild log to default and custom!',
|
||||
level: 'DEBUG',
|
||||
});
|
||||
expect(mockConsoleLog.mock.calls[1][0]).toMatchInlineSnapshot(
|
||||
`"[DEBUG][tests.child.grandchild] tests.child.grandchild log to default and custom!"`
|
||||
);
|
||||
});
|
||||
|
||||
test('subsequent calls to setContextConfig() for the same context override the previous config', () => {
|
||||
system.upgrade(
|
||||
config.schema.validate({
|
||||
appenders: { default: { kind: 'console', layout: { kind: 'json' } } },
|
||||
root: { level: 'info' },
|
||||
})
|
||||
);
|
||||
|
||||
system.setContextConfig(['tests', 'child'], {
|
||||
appenders: new Map([
|
||||
[
|
||||
'custom',
|
||||
{ kind: 'console', layout: { kind: 'pattern', pattern: '[%level][%logger] %message' } },
|
||||
],
|
||||
]),
|
||||
loggers: [{ context: 'grandchild', appenders: ['default', 'custom'], level: 'debug' }],
|
||||
});
|
||||
|
||||
// Call again, this time with level: 'warn' and a different pattern
|
||||
system.setContextConfig(['tests', 'child'], {
|
||||
appenders: new Map([
|
||||
[
|
||||
'custom',
|
||||
{
|
||||
kind: 'console',
|
||||
layout: { kind: 'pattern', pattern: '[%level][%logger] second pattern! %message' },
|
||||
},
|
||||
],
|
||||
]),
|
||||
loggers: [{ context: 'grandchild', appenders: ['default', 'custom'], level: 'warn' }],
|
||||
});
|
||||
|
||||
const logger = system.get('tests', 'child', 'grandchild');
|
||||
logger.debug('this should not show anywhere!');
|
||||
logger.warn('tests.child.grandchild log to default and custom!');
|
||||
|
||||
// Only the warn log should have been logged
|
||||
expect(mockConsoleLog).toHaveBeenCalledTimes(2);
|
||||
expect(JSON.parse(mockConsoleLog.mock.calls[0][0])).toMatchObject({
|
||||
context: 'tests.child.grandchild',
|
||||
message: 'tests.child.grandchild log to default and custom!',
|
||||
level: 'WARN',
|
||||
});
|
||||
expect(mockConsoleLog.mock.calls[1][0]).toMatchInlineSnapshot(
|
||||
`"[WARN ][tests.child.grandchild] second pattern! tests.child.grandchild log to default and custom!"`
|
||||
);
|
||||
});
|
||||
|
||||
test('subsequent calls to setContextConfig() for the same context can disable the previous config', () => {
|
||||
system.upgrade(
|
||||
config.schema.validate({
|
||||
appenders: { default: { kind: 'console', layout: { kind: 'json' } } },
|
||||
root: { level: 'info' },
|
||||
})
|
||||
);
|
||||
|
||||
system.setContextConfig(['tests', 'child'], {
|
||||
appenders: new Map([
|
||||
[
|
||||
'custom',
|
||||
{ kind: 'console', layout: { kind: 'pattern', pattern: '[%level][%logger] %message' } },
|
||||
],
|
||||
]),
|
||||
loggers: [{ context: 'grandchild', appenders: ['default', 'custom'], level: 'debug' }],
|
||||
});
|
||||
|
||||
// Call again, this time no customizations (effectively disabling)
|
||||
system.setContextConfig(['tests', 'child'], {});
|
||||
|
||||
const logger = system.get('tests', 'child', 'grandchild');
|
||||
logger.debug('this should not show anywhere!');
|
||||
logger.warn('tests.child.grandchild log to default!');
|
||||
|
||||
// Only the warn log should have been logged once on the default appender
|
||||
expect(mockConsoleLog).toHaveBeenCalledTimes(1);
|
||||
expect(JSON.parse(mockConsoleLog.mock.calls[0][0])).toMatchObject({
|
||||
context: 'tests.child.grandchild',
|
||||
message: 'tests.child.grandchild log to default!',
|
||||
level: 'WARN',
|
||||
});
|
||||
});
|
185
src/core/server/logging/logging_system.ts
Normal file
185
src/core/server/logging/logging_system.ts
Normal file
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* 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 { Appenders, DisposableAppender } from './appenders/appenders';
|
||||
import { BufferAppender } from './appenders/buffer/buffer_appender';
|
||||
import { LogLevel } from './log_level';
|
||||
import { BaseLogger, Logger } from './logger';
|
||||
import { LoggerAdapter } from './logger_adapter';
|
||||
import { LoggerFactory } from './logger_factory';
|
||||
import {
|
||||
LoggingConfigType,
|
||||
LoggerConfigType,
|
||||
LoggingConfig,
|
||||
LoggerContextConfigType,
|
||||
LoggerContextConfigInput,
|
||||
loggerContextConfigSchema,
|
||||
} from './logging_config';
|
||||
|
||||
export type ILoggingSystem = PublicMethodsOf<LoggingSystem>;
|
||||
|
||||
/**
|
||||
* System that is responsible for maintaining loggers and logger appenders.
|
||||
* @internal
|
||||
*/
|
||||
export class LoggingSystem implements LoggerFactory {
|
||||
/** The configuration set by the user. */
|
||||
private baseConfig?: LoggingConfig;
|
||||
/** The fully computed configuration extended by context-specific configurations set programmatically */
|
||||
private computedConfig?: LoggingConfig;
|
||||
private readonly appenders: Map<string, DisposableAppender> = new Map();
|
||||
private readonly bufferAppender = new BufferAppender();
|
||||
private readonly loggers: Map<string, LoggerAdapter> = new Map();
|
||||
private readonly contextConfigs = new Map<string, LoggerContextConfigType>();
|
||||
|
||||
public get(...contextParts: string[]): Logger {
|
||||
const context = LoggingConfig.getLoggerContext(contextParts);
|
||||
if (!this.loggers.has(context)) {
|
||||
this.loggers.set(context, new LoggerAdapter(this.createLogger(context, this.computedConfig)));
|
||||
}
|
||||
return this.loggers.get(context)!;
|
||||
}
|
||||
|
||||
/**
|
||||
* Safe wrapper that allows passing logging service as immutable LoggerFactory.
|
||||
*/
|
||||
public asLoggerFactory(): LoggerFactory {
|
||||
return { get: (...contextParts: string[]) => this.get(...contextParts) };
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates all current active loggers with the new config values.
|
||||
* @param rawConfig New config instance.
|
||||
*/
|
||||
public upgrade(rawConfig: LoggingConfigType) {
|
||||
const config = new LoggingConfig(rawConfig)!;
|
||||
this.applyBaseConfig(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Customizes the logging config for a specific context.
|
||||
*
|
||||
* @remarks
|
||||
* Assumes that that the `context` property of the individual items in `rawConfig.loggers`
|
||||
* are relative to the `baseContextParts`.
|
||||
*
|
||||
* @example
|
||||
* Customize the configuration for the plugins.data.search context.
|
||||
* ```ts
|
||||
* loggingSystem.setContextConfig(
|
||||
* ['plugins', 'data'],
|
||||
* {
|
||||
* loggers: [{ context: 'search', appenders: ['default'] }]
|
||||
* }
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* @param baseContextParts
|
||||
* @param rawConfig
|
||||
*/
|
||||
public setContextConfig(baseContextParts: string[], rawConfig: LoggerContextConfigInput) {
|
||||
const context = LoggingConfig.getLoggerContext(baseContextParts);
|
||||
const contextConfig = loggerContextConfigSchema.validate(rawConfig);
|
||||
this.contextConfigs.set(context, {
|
||||
...contextConfig,
|
||||
// Automatically prepend the base context to the logger sub-contexts
|
||||
loggers: contextConfig.loggers.map((l) => ({
|
||||
...l,
|
||||
context: LoggingConfig.getLoggerContext([context, l.context]),
|
||||
})),
|
||||
});
|
||||
|
||||
// If we already have a base config, apply the config. If not, custom context configs
|
||||
// will be picked up on next call to `upgrade`.
|
||||
if (this.baseConfig) {
|
||||
this.applyBaseConfig(this.baseConfig);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disposes all loggers (closes log files, clears buffers etc.). Service is not usable after
|
||||
* calling of this method until new config is provided via `upgrade` method.
|
||||
* @returns Promise that is resolved once all loggers are successfully disposed.
|
||||
*/
|
||||
public async stop() {
|
||||
await Promise.all([...this.appenders.values()].map((a) => a.dispose()));
|
||||
|
||||
await this.bufferAppender.dispose();
|
||||
|
||||
this.appenders.clear();
|
||||
this.loggers.clear();
|
||||
}
|
||||
|
||||
private createLogger(context: string, config: LoggingConfig | undefined) {
|
||||
if (config === undefined) {
|
||||
// If we don't have config yet, use `buffered` appender that will store all logged messages in the memory
|
||||
// until the config is ready.
|
||||
return new BaseLogger(context, LogLevel.All, [this.bufferAppender], this.asLoggerFactory());
|
||||
}
|
||||
|
||||
const { level, appenders } = this.getLoggerConfigByContext(config, context);
|
||||
const loggerLevel = LogLevel.fromId(level);
|
||||
const loggerAppenders = appenders.map((appenderKey) => this.appenders.get(appenderKey)!);
|
||||
|
||||
return new BaseLogger(context, loggerLevel, loggerAppenders, this.asLoggerFactory());
|
||||
}
|
||||
|
||||
private getLoggerConfigByContext(config: LoggingConfig, context: string): LoggerConfigType {
|
||||
const loggerConfig = config.loggers.get(context);
|
||||
if (loggerConfig !== undefined) {
|
||||
return loggerConfig;
|
||||
}
|
||||
|
||||
// If we don't have configuration for the specified context and it's the "nested" one (eg. `foo.bar.baz`),
|
||||
// let's move up to the parent context (eg. `foo.bar`) and check if it has config we can rely on. Otherwise
|
||||
// we fallback to the `root` context that should always be defined (enforced by configuration schema).
|
||||
return this.getLoggerConfigByContext(config, LoggingConfig.getParentLoggerContext(context));
|
||||
}
|
||||
|
||||
private applyBaseConfig(newBaseConfig: LoggingConfig) {
|
||||
const computedConfig = [...this.contextConfigs.values()].reduce(
|
||||
(baseConfig, contextConfig) => baseConfig.extend(contextConfig),
|
||||
newBaseConfig
|
||||
);
|
||||
|
||||
// Appenders must be reset, so we first dispose of the current ones, then
|
||||
// build up a new set of appenders.
|
||||
for (const appender of this.appenders.values()) {
|
||||
appender.dispose();
|
||||
}
|
||||
this.appenders.clear();
|
||||
|
||||
for (const [appenderKey, appenderConfig] of computedConfig.appenders) {
|
||||
this.appenders.set(appenderKey, Appenders.create(appenderConfig));
|
||||
}
|
||||
|
||||
for (const [loggerKey, loggerAdapter] of this.loggers) {
|
||||
loggerAdapter.updateLogger(this.createLogger(loggerKey, computedConfig));
|
||||
}
|
||||
|
||||
// We keep a reference to the base config so we can properly extend it
|
||||
// on each config change.
|
||||
this.baseConfig = newBaseConfig;
|
||||
this.computedConfig = computedConfig;
|
||||
|
||||
// Re-log all buffered log records with newly configured appenders.
|
||||
for (const logRecord of this.bufferAppender.flush()) {
|
||||
this.get(logRecord.context).log(logRecord);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@
|
|||
import { of } from 'rxjs';
|
||||
import { duration } from 'moment';
|
||||
import { PluginInitializerContext, CoreSetup, CoreStart, StartServicesAccessor } from '.';
|
||||
import { loggingSystemMock } from './logging/logging_system.mock';
|
||||
import { loggingServiceMock } from './logging/logging_service.mock';
|
||||
import { elasticsearchServiceMock } from './elasticsearch/elasticsearch_service.mock';
|
||||
import { httpServiceMock } from './http/http_service.mock';
|
||||
|
@ -42,7 +43,7 @@ export { sessionStorageMock } from './http/cookie_session_storage.mocks';
|
|||
export { configServiceMock } from './config/config_service.mock';
|
||||
export { elasticsearchServiceMock } from './elasticsearch/elasticsearch_service.mock';
|
||||
export { httpServiceMock } from './http/http_service.mock';
|
||||
export { loggingServiceMock } from './logging/logging_service.mock';
|
||||
export { loggingSystemMock } from './logging/logging_system.mock';
|
||||
export { savedObjectsRepositoryMock } from './saved_objects/service/lib/repository.mock';
|
||||
export { savedObjectsServiceMock } from './saved_objects/saved_objects_service.mock';
|
||||
export { typeRegistryMock as savedObjectsTypeRegistryMock } from './saved_objects/saved_objects_type_registry.mock';
|
||||
|
@ -78,7 +79,7 @@ export function pluginInitializerContextConfigMock<T>(config: T) {
|
|||
function pluginInitializerContextMock<T>(config: T = {} as T) {
|
||||
const mock: PluginInitializerContext<T> = {
|
||||
opaqueId: Symbol(),
|
||||
logger: loggingServiceMock.create(),
|
||||
logger: loggingSystemMock.create(),
|
||||
env: {
|
||||
mode: {
|
||||
dev: true,
|
||||
|
@ -130,6 +131,7 @@ function createCoreSetupMock({
|
|||
metrics: metricsServiceMock.createSetupContract(),
|
||||
uiSettings: uiSettingsMock,
|
||||
uuid: uuidServiceMock.createSetupContract(),
|
||||
logging: loggingServiceMock.createSetupContract(),
|
||||
getStartServices: jest
|
||||
.fn<Promise<[ReturnType<typeof createCoreStartMock>, object, any]>, []>()
|
||||
.mockResolvedValue([createCoreStartMock(), pluginStartDeps, pluginStartContract]),
|
||||
|
@ -163,6 +165,7 @@ function createInternalCoreSetupMock() {
|
|||
httpResources: httpResourcesMock.createSetupContract(),
|
||||
rendering: renderingMock.createSetupContract(),
|
||||
uiSettings: uiSettingsServiceMock.createSetupContract(),
|
||||
logging: loggingServiceMock.createInternalSetupContract(),
|
||||
};
|
||||
return setupDeps;
|
||||
}
|
||||
|
|
|
@ -20,12 +20,12 @@
|
|||
import { PluginDiscoveryErrorType } from './plugin_discovery_error';
|
||||
|
||||
import { mockReadFile } from './plugin_manifest_parser.test.mocks';
|
||||
import { loggingServiceMock } from '../../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../../logging/logging_system.mock';
|
||||
|
||||
import { resolve } from 'path';
|
||||
import { parseManifest } from './plugin_manifest_parser';
|
||||
|
||||
const logger = loggingServiceMock.createLogger();
|
||||
const logger = loggingSystemMock.createLogger();
|
||||
const pluginPath = resolve('path', 'existent-dir');
|
||||
const pluginManifestPath = resolve(pluginPath, 'kibana.json');
|
||||
const packageInfo = {
|
||||
|
@ -105,9 +105,9 @@ test('logs warning if pluginId is not in camelCase format', async () => {
|
|||
cb(null, Buffer.from(JSON.stringify({ id: 'some_name', version: 'kibana', server: true })));
|
||||
});
|
||||
|
||||
expect(loggingServiceMock.collect(logger).warn).toHaveLength(0);
|
||||
expect(loggingSystemMock.collect(logger).warn).toHaveLength(0);
|
||||
await parseManifest(pluginPath, packageInfo, logger);
|
||||
expect(loggingServiceMock.collect(logger).warn).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).warn).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"Expect plugin \\"id\\" in camelCase, but found: some_name",
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
import { mockPackage, mockReaddir, mockReadFile, mockStat } from './plugins_discovery.test.mocks';
|
||||
import { rawConfigServiceMock } from '../../config/raw_config_service.mock';
|
||||
import { loggingServiceMock } from '../../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../../logging/logging_system.mock';
|
||||
|
||||
import { resolve } from 'path';
|
||||
import { first, map, toArray } from 'rxjs/operators';
|
||||
|
@ -37,7 +37,7 @@ const TEST_PLUGIN_SEARCH_PATHS = {
|
|||
};
|
||||
const TEST_EXTRA_PLUGIN_PATH = resolve(process.cwd(), 'my-extra-plugin');
|
||||
|
||||
const logger = loggingServiceMock.create();
|
||||
const logger = loggingSystemMock.create();
|
||||
|
||||
beforeEach(() => {
|
||||
mockReaddir.mockImplementation((path, cb) => {
|
||||
|
@ -221,7 +221,7 @@ test('logs a warning about --plugin-path when used in development', async () =>
|
|||
logger,
|
||||
});
|
||||
|
||||
expect(loggingServiceMock.collect(logger).warn).toEqual([
|
||||
expect(loggingSystemMock.collect(logger).warn).toEqual([
|
||||
[
|
||||
`Explicit plugin paths [${TEST_EXTRA_PLUGIN_PATH}] should only be used in development. Relative imports may not work properly in production.`,
|
||||
],
|
||||
|
@ -263,5 +263,5 @@ test('does not log a warning about --plugin-path when used in production', async
|
|||
logger,
|
||||
});
|
||||
|
||||
expect(loggingServiceMock.collect(logger).warn).toEqual([]);
|
||||
expect(loggingSystemMock.collect(logger).warn).toEqual([]);
|
||||
});
|
||||
|
|
|
@ -27,13 +27,13 @@ import { getEnvOptions } from '../../config/__mocks__/env';
|
|||
import { BehaviorSubject, from } from 'rxjs';
|
||||
import { rawConfigServiceMock } from '../../config/raw_config_service.mock';
|
||||
import { config } from '../plugins_config';
|
||||
import { loggingServiceMock } from '../../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../../logging/logging_system.mock';
|
||||
import { coreMock } from '../../mocks';
|
||||
import { Plugin } from '../types';
|
||||
import { PluginWrapper } from '../plugin';
|
||||
|
||||
describe('PluginsService', () => {
|
||||
const logger = loggingServiceMock.create();
|
||||
const logger = loggingSystemMock.create();
|
||||
let pluginsService: PluginsService;
|
||||
|
||||
const createPlugin = (
|
||||
|
|
|
@ -26,14 +26,14 @@ import { getEnvOptions } from '../config/__mocks__/env';
|
|||
import { CoreContext } from '../core_context';
|
||||
import { coreMock } from '../mocks';
|
||||
import { configServiceMock } from '../config/config_service.mock';
|
||||
import { loggingServiceMock } from '../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../logging/logging_system.mock';
|
||||
|
||||
import { PluginWrapper } from './plugin';
|
||||
import { PluginManifest } from './types';
|
||||
import { createPluginInitializerContext, createPluginSetupContext } from './plugin_context';
|
||||
|
||||
const mockPluginInitializer = jest.fn();
|
||||
const logger = loggingServiceMock.create();
|
||||
const logger = loggingSystemMock.create();
|
||||
jest.doMock(
|
||||
join('plugin-with-initializer-path', 'server'),
|
||||
() => ({ plugin: mockPluginInitializer }),
|
||||
|
|
|
@ -95,8 +95,6 @@ export class PluginWrapper<
|
|||
public async setup(setupContext: CoreSetup<TPluginsStart>, plugins: TPluginsSetup) {
|
||||
this.instance = this.createPluginInstance();
|
||||
|
||||
this.log.debug('Setting up plugin');
|
||||
|
||||
return this.instance.setup(setupContext, plugins);
|
||||
}
|
||||
|
||||
|
@ -112,8 +110,6 @@ export class PluginWrapper<
|
|||
throw new Error(`Plugin "${this.name}" can't be started since it isn't set up.`);
|
||||
}
|
||||
|
||||
this.log.debug('Starting plugin');
|
||||
|
||||
const startContract = await this.instance.start(startContext, plugins);
|
||||
this.startDependencies$.next([startContext, plugins, startContract]);
|
||||
return startContract;
|
||||
|
@ -127,8 +123,6 @@ export class PluginWrapper<
|
|||
throw new Error(`Plugin "${this.name}" can't be stopped since it isn't set up.`);
|
||||
}
|
||||
|
||||
this.log.info('Stopping plugin');
|
||||
|
||||
if (typeof this.instance.stop === 'function') {
|
||||
await this.instance.stop();
|
||||
}
|
||||
|
|
|
@ -22,14 +22,14 @@ import { first } from 'rxjs/operators';
|
|||
import { createPluginInitializerContext } from './plugin_context';
|
||||
import { CoreContext } from '../core_context';
|
||||
import { Env } from '../config';
|
||||
import { loggingServiceMock } from '../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../logging/logging_system.mock';
|
||||
import { rawConfigServiceMock } from '../config/raw_config_service.mock';
|
||||
import { getEnvOptions } from '../config/__mocks__/env';
|
||||
import { PluginManifest } from './types';
|
||||
import { Server } from '../server';
|
||||
import { fromRoot } from '../utils';
|
||||
|
||||
const logger = loggingServiceMock.create();
|
||||
const logger = loggingSystemMock.create();
|
||||
|
||||
let coreId: symbol;
|
||||
let env: Env;
|
||||
|
|
|
@ -166,6 +166,9 @@ export function createPluginSetupContext<TPlugin, TPluginDependencies>(
|
|||
csp: deps.http.csp,
|
||||
getServerInfo: deps.http.getServerInfo,
|
||||
},
|
||||
logging: {
|
||||
configure: (config$) => deps.logging.configure(['plugins', plugin.name], config$),
|
||||
},
|
||||
metrics: {
|
||||
getOpsMetrics$: deps.metrics.getOpsMetrics$,
|
||||
},
|
||||
|
|
|
@ -28,7 +28,7 @@ import { ConfigPath, ConfigService, Env } from '../config';
|
|||
import { rawConfigServiceMock } from '../config/raw_config_service.mock';
|
||||
import { getEnvOptions } from '../config/__mocks__/env';
|
||||
import { coreMock } from '../mocks';
|
||||
import { loggingServiceMock } from '../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../logging/logging_system.mock';
|
||||
import { PluginDiscoveryError } from './discovery';
|
||||
import { PluginWrapper } from './plugin';
|
||||
import { PluginsService } from './plugins_service';
|
||||
|
@ -47,7 +47,7 @@ let env: Env;
|
|||
let mockPluginSystem: jest.Mocked<PluginsSystem>;
|
||||
|
||||
const setupDeps = coreMock.createInternalSetup();
|
||||
const logger = loggingServiceMock.create();
|
||||
const logger = loggingSystemMock.create();
|
||||
|
||||
expect.addSnapshotSerializer(createAbsolutePathSerializer());
|
||||
|
||||
|
@ -138,7 +138,7 @@ describe('PluginsService', () => {
|
|||
[Error: Failed to initialize plugins:
|
||||
Invalid JSON (invalid-manifest, path-1)]
|
||||
`);
|
||||
expect(loggingServiceMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
[Error: Invalid JSON (invalid-manifest, path-1)],
|
||||
|
@ -159,7 +159,7 @@ describe('PluginsService', () => {
|
|||
[Error: Failed to initialize plugins:
|
||||
Incompatible version (incompatible-version, path-3)]
|
||||
`);
|
||||
expect(loggingServiceMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
[Error: Incompatible version (incompatible-version, path-3)],
|
||||
|
@ -238,7 +238,7 @@ describe('PluginsService', () => {
|
|||
expect(mockPluginSystem.setupPlugins).toHaveBeenCalledTimes(1);
|
||||
expect(mockPluginSystem.setupPlugins).toHaveBeenCalledWith(setupDeps);
|
||||
|
||||
expect(loggingServiceMock.collect(logger).info).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).info).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"Plugin \\"explicitly-disabled-plugin\\" is disabled.",
|
||||
|
@ -360,7 +360,7 @@ describe('PluginsService', () => {
|
|||
{ coreId, env, logger, configService }
|
||||
);
|
||||
|
||||
const logs = loggingServiceMock.collect(logger);
|
||||
const logs = loggingSystemMock.collect(logger);
|
||||
expect(logs.info).toHaveLength(0);
|
||||
expect(logs.error).toHaveLength(0);
|
||||
});
|
||||
|
|
|
@ -28,7 +28,7 @@ import { Env } from '../config';
|
|||
import { getEnvOptions } from '../config/__mocks__/env';
|
||||
import { CoreContext } from '../core_context';
|
||||
import { configServiceMock } from '../config/config_service.mock';
|
||||
import { loggingServiceMock } from '../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../logging/logging_system.mock';
|
||||
|
||||
import { PluginWrapper } from './plugin';
|
||||
import { PluginName } from './types';
|
||||
|
@ -36,7 +36,7 @@ import { PluginsSystem } from './plugins_system';
|
|||
import { coreMock } from '../mocks';
|
||||
import { Logger } from '../logging';
|
||||
|
||||
const logger = loggingServiceMock.create();
|
||||
const logger = loggingSystemMock.create();
|
||||
function createPlugin(
|
||||
id: string,
|
||||
{
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { loggingServiceMock } from '../logging/logging_service.mock';
|
||||
export const logger = loggingServiceMock.create();
|
||||
jest.doMock('../logging/logging_service', () => ({
|
||||
LoggingService: jest.fn(() => logger),
|
||||
import { loggingSystemMock } from '../logging/logging_system.mock';
|
||||
export const logger = loggingSystemMock.create();
|
||||
jest.doMock('../logging/logging_system', () => ({
|
||||
LoggingSystem: jest.fn(() => logger),
|
||||
}));
|
||||
|
||||
import { configServiceMock } from '../config/config_service.mock';
|
||||
|
|
|
@ -21,7 +21,7 @@ import { ConnectableObservable, Subscription } from 'rxjs';
|
|||
import { first, map, publishReplay, switchMap, tap } from 'rxjs/operators';
|
||||
|
||||
import { Env, RawConfigurationProvider } from '../config';
|
||||
import { Logger, LoggerFactory, LoggingConfigType, LoggingService } from '../logging';
|
||||
import { Logger, LoggerFactory, LoggingConfigType, LoggingSystem } from '../logging';
|
||||
import { Server } from '../server';
|
||||
|
||||
/**
|
||||
|
@ -30,7 +30,7 @@ import { Server } from '../server';
|
|||
export class Root {
|
||||
public readonly logger: LoggerFactory;
|
||||
private readonly log: Logger;
|
||||
private readonly loggingService: LoggingService;
|
||||
private readonly loggingSystem: LoggingSystem;
|
||||
private readonly server: Server;
|
||||
private loggingConfigSubscription?: Subscription;
|
||||
|
||||
|
@ -39,10 +39,10 @@ export class Root {
|
|||
env: Env,
|
||||
private readonly onShutdown?: (reason?: Error | string) => void
|
||||
) {
|
||||
this.loggingService = new LoggingService();
|
||||
this.logger = this.loggingService.asLoggerFactory();
|
||||
this.loggingSystem = new LoggingSystem();
|
||||
this.logger = this.loggingSystem.asLoggerFactory();
|
||||
this.log = this.logger.get('root');
|
||||
this.server = new Server(rawConfigProvider, env, this.logger);
|
||||
this.server = new Server(rawConfigProvider, env, this.loggingSystem);
|
||||
}
|
||||
|
||||
public async setup() {
|
||||
|
@ -86,7 +86,7 @@ export class Root {
|
|||
this.loggingConfigSubscription.unsubscribe();
|
||||
this.loggingConfigSubscription = undefined;
|
||||
}
|
||||
await this.loggingService.stop();
|
||||
await this.loggingSystem.stop();
|
||||
|
||||
if (this.onShutdown !== undefined) {
|
||||
this.onShutdown(reason);
|
||||
|
@ -99,7 +99,7 @@ export class Root {
|
|||
const update$ = configService.getConfig$().pipe(
|
||||
// always read the logging config when the underlying config object is re-read
|
||||
switchMap(() => configService.atPath<LoggingConfigType>('logging')),
|
||||
map((config) => this.loggingService.upgrade(config)),
|
||||
map((config) => this.loggingSystem.upgrade(config)),
|
||||
// This specifically console.logs because we were not able to configure the logger.
|
||||
// eslint-disable-next-line no-console
|
||||
tap({ error: (err) => console.error('Configuring logger failed:', err) }),
|
||||
|
|
|
@ -20,11 +20,11 @@
|
|||
import _ from 'lodash';
|
||||
import { SavedObjectUnsanitizedDoc } from '../../serialization';
|
||||
import { DocumentMigrator } from './document_migrator';
|
||||
import { loggingServiceMock } from '../../../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../../../logging/logging_system.mock';
|
||||
import { SavedObjectsType } from '../../types';
|
||||
import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry';
|
||||
|
||||
const mockLoggerFactory = loggingServiceMock.create();
|
||||
const mockLoggerFactory = loggingSystemMock.create();
|
||||
const mockLogger = mockLoggerFactory.get('mock logger');
|
||||
|
||||
const createRegistry = (...types: Array<Partial<SavedObjectsType>>) => {
|
||||
|
@ -572,7 +572,7 @@ describe('DocumentMigrator', () => {
|
|||
expect('Did not throw').toEqual('But it should have!');
|
||||
} catch (error) {
|
||||
expect(error.message).toMatch(/Dang diggity!/);
|
||||
const warning = loggingServiceMock.collect(mockLoggerFactory).warn[0][0];
|
||||
const warning = loggingSystemMock.collect(mockLoggerFactory).warn[0][0];
|
||||
expect(warning).toContain(JSON.stringify(failedDoc));
|
||||
expect(warning).toContain('dog:1.2.3');
|
||||
}
|
||||
|
@ -601,8 +601,8 @@ describe('DocumentMigrator', () => {
|
|||
migrationVersion: {},
|
||||
};
|
||||
migrator.migrate(doc);
|
||||
expect(loggingServiceMock.collect(mockLoggerFactory).info[0][0]).toEqual(logTestMsg);
|
||||
expect(loggingServiceMock.collect(mockLoggerFactory).warn[1][0]).toEqual(logTestMsg);
|
||||
expect(loggingSystemMock.collect(mockLoggerFactory).info[0][0]).toEqual(logTestMsg);
|
||||
expect(loggingSystemMock.collect(mockLoggerFactory).warn[1][0]).toEqual(logTestMsg);
|
||||
});
|
||||
|
||||
test('extracts the latest migration version info', () => {
|
||||
|
|
|
@ -21,7 +21,7 @@ import _ from 'lodash';
|
|||
import { SavedObjectUnsanitizedDoc, SavedObjectsSerializer } from '../../serialization';
|
||||
import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry';
|
||||
import { IndexMigrator } from './index_migrator';
|
||||
import { loggingServiceMock } from '../../../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../../../logging/logging_system.mock';
|
||||
|
||||
describe('IndexMigrator', () => {
|
||||
let testOpts: any;
|
||||
|
@ -31,7 +31,7 @@ describe('IndexMigrator', () => {
|
|||
batchSize: 10,
|
||||
callCluster: jest.fn(),
|
||||
index: '.kibana',
|
||||
log: loggingServiceMock.create().get(),
|
||||
log: loggingSystemMock.create().get(),
|
||||
mappingProperties: {},
|
||||
pollInterval: 1,
|
||||
scrollDuration: '1m',
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
import { take } from 'rxjs/operators';
|
||||
|
||||
import { KibanaMigratorOptions, KibanaMigrator } from './kibana_migrator';
|
||||
import { loggingServiceMock } from '../../../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../../../logging/logging_system.mock';
|
||||
import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry';
|
||||
import { SavedObjectsType } from '../../types';
|
||||
|
||||
|
@ -110,7 +110,7 @@ describe('KibanaMigrator', () => {
|
|||
function mockOptions(): KibanaMigratorOptions {
|
||||
const callCluster = jest.fn();
|
||||
return {
|
||||
logger: loggingServiceMock.create().get(),
|
||||
logger: loggingSystemMock.create().get(),
|
||||
kibanaVersion: '8.2.3',
|
||||
savedObjectValidations: {},
|
||||
typeRegistry: createRegistry([
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
import supertest from 'supertest';
|
||||
import { UnwrapPromise } from '@kbn/utility-types';
|
||||
import { registerLogLegacyImportRoute } from '../log_legacy_import';
|
||||
import { loggingServiceMock } from '../../../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../../../logging/logging_system.mock';
|
||||
import { setupServer } from '../test_utils';
|
||||
|
||||
type setupServerReturn = UnwrapPromise<ReturnType<typeof setupServer>>;
|
||||
|
@ -28,11 +28,11 @@ type setupServerReturn = UnwrapPromise<ReturnType<typeof setupServer>>;
|
|||
describe('POST /api/saved_objects/_log_legacy_import', () => {
|
||||
let server: setupServerReturn['server'];
|
||||
let httpSetup: setupServerReturn['httpSetup'];
|
||||
let logger: ReturnType<typeof loggingServiceMock.createLogger>;
|
||||
let logger: ReturnType<typeof loggingSystemMock.createLogger>;
|
||||
|
||||
beforeEach(async () => {
|
||||
({ server, httpSetup } = await setupServer());
|
||||
logger = loggingServiceMock.createLogger();
|
||||
logger = loggingSystemMock.createLogger();
|
||||
|
||||
const router = httpSetup.createRouter('/api/saved_objects/');
|
||||
registerLogLegacyImportRoute(router, logger);
|
||||
|
@ -50,7 +50,7 @@ describe('POST /api/saved_objects/_log_legacy_import', () => {
|
|||
.expect(200);
|
||||
|
||||
expect(result.body).toEqual({ success: true });
|
||||
expect(loggingServiceMock.collect(logger).warn).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).warn).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"Importing saved objects from a .json file has been deprecated",
|
||||
|
|
|
@ -388,6 +388,11 @@ export interface APICaller {
|
|||
<T = any>(endpoint: string, clientParams?: Record<string, any>, options?: CallAPIOptions): Promise<T>;
|
||||
}
|
||||
|
||||
// Warning: (ae-forgotten-export) The symbol "appendersSchema" needs to be exported by the entry point index.d.ts
|
||||
//
|
||||
// @public (undocumented)
|
||||
export type AppenderConfigType = TypeOf<typeof appendersSchema>;
|
||||
|
||||
// @public
|
||||
export function assertNever(x: never): never;
|
||||
|
||||
|
@ -574,6 +579,72 @@ export const config: {
|
|||
ignoreVersionMismatch: import("@kbn/config-schema/target/types/types").ConditionalType<false, boolean, boolean>;
|
||||
}>;
|
||||
};
|
||||
logging: {
|
||||
appenders: import("@kbn/config-schema").Type<Readonly<{} & {
|
||||
layout: Readonly<{} & {
|
||||
kind: "json";
|
||||
}> | Readonly<{
|
||||
pattern?: string | undefined;
|
||||
highlight?: boolean | undefined;
|
||||
} & {
|
||||
kind: "pattern";
|
||||
}>;
|
||||
kind: "console";
|
||||
}> | Readonly<{} & {
|
||||
path: string;
|
||||
layout: Readonly<{} & {
|
||||
kind: "json";
|
||||
}> | Readonly<{
|
||||
pattern?: string | undefined;
|
||||
highlight?: boolean | undefined;
|
||||
} & {
|
||||
kind: "pattern";
|
||||
}>;
|
||||
kind: "file";
|
||||
}> | Readonly<{
|
||||
legacyLoggingConfig?: any;
|
||||
} & {
|
||||
kind: "legacy-appender";
|
||||
}>>;
|
||||
loggers: import("@kbn/config-schema").ObjectType<{
|
||||
appenders: import("@kbn/config-schema").Type<string[]>;
|
||||
context: import("@kbn/config-schema").Type<string>;
|
||||
level: import("@kbn/config-schema").Type<import("./logging/log_level").LogLevelId>;
|
||||
}>;
|
||||
loggerContext: import("@kbn/config-schema").ObjectType<{
|
||||
appenders: import("@kbn/config-schema").Type<Map<string, Readonly<{} & {
|
||||
layout: Readonly<{} & {
|
||||
kind: "json";
|
||||
}> | Readonly<{
|
||||
pattern?: string | undefined;
|
||||
highlight?: boolean | undefined;
|
||||
} & {
|
||||
kind: "pattern";
|
||||
}>;
|
||||
kind: "console";
|
||||
}> | Readonly<{} & {
|
||||
path: string;
|
||||
layout: Readonly<{} & {
|
||||
kind: "json";
|
||||
}> | Readonly<{
|
||||
pattern?: string | undefined;
|
||||
highlight?: boolean | undefined;
|
||||
} & {
|
||||
kind: "pattern";
|
||||
}>;
|
||||
kind: "file";
|
||||
}> | Readonly<{
|
||||
legacyLoggingConfig?: any;
|
||||
} & {
|
||||
kind: "legacy-appender";
|
||||
}>>>;
|
||||
loggers: import("@kbn/config-schema").Type<Readonly<{} & {
|
||||
context: string;
|
||||
appenders: string[];
|
||||
level: import("./logging/log_level").LogLevelId;
|
||||
}>[]>;
|
||||
}>;
|
||||
};
|
||||
};
|
||||
|
||||
// @public
|
||||
|
@ -639,6 +710,8 @@ export interface CoreSetup<TPluginsStart extends object = object, TStart = unkno
|
|||
resources: HttpResources;
|
||||
};
|
||||
// (undocumented)
|
||||
logging: LoggingServiceSetup;
|
||||
// (undocumented)
|
||||
metrics: MetricsServiceSetup;
|
||||
// (undocumented)
|
||||
savedObjects: SavedObjectsServiceSetup;
|
||||
|
@ -1270,11 +1343,29 @@ export interface Logger {
|
|||
warn(errorOrMessage: string | Error, meta?: LogMeta): void;
|
||||
}
|
||||
|
||||
// Warning: (ae-forgotten-export) The symbol "loggerSchema" needs to be exported by the entry point index.d.ts
|
||||
//
|
||||
// @public (undocumented)
|
||||
export type LoggerConfigType = TypeOf<typeof loggerSchema>;
|
||||
|
||||
// @public (undocumented)
|
||||
export interface LoggerContextConfigInput {
|
||||
// (undocumented)
|
||||
appenders?: Record<string, AppenderConfigType> | Map<string, AppenderConfigType>;
|
||||
// (undocumented)
|
||||
loggers?: LoggerConfigType[];
|
||||
}
|
||||
|
||||
// @public
|
||||
export interface LoggerFactory {
|
||||
get(...contextParts: string[]): Logger;
|
||||
}
|
||||
|
||||
// @public
|
||||
export interface LoggingServiceSetup {
|
||||
configure(config$: Observable<LoggerContextConfigInput>): void;
|
||||
}
|
||||
|
||||
// @internal
|
||||
export class LogLevel {
|
||||
// (undocumented)
|
||||
|
|
|
@ -91,3 +91,9 @@ export const mockStatusService = statusServiceMock.create();
|
|||
jest.doMock('./status/status_service', () => ({
|
||||
StatusService: jest.fn(() => mockStatusService),
|
||||
}));
|
||||
|
||||
import { loggingServiceMock } from './logging/logging_service.mock';
|
||||
export const mockLoggingService = loggingServiceMock.create();
|
||||
jest.doMock('./logging/logging_service', () => ({
|
||||
LoggingService: jest.fn(() => mockLoggingService),
|
||||
}));
|
||||
|
|
|
@ -30,6 +30,7 @@ import {
|
|||
mockRenderingService,
|
||||
mockMetricsService,
|
||||
mockStatusService,
|
||||
mockLoggingService,
|
||||
} from './server.test.mocks';
|
||||
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
|
@ -37,11 +38,11 @@ import { Env } from './config';
|
|||
import { Server } from './server';
|
||||
|
||||
import { getEnvOptions } from './config/__mocks__/env';
|
||||
import { loggingServiceMock } from './logging/logging_service.mock';
|
||||
import { loggingSystemMock } from './logging/logging_system.mock';
|
||||
import { rawConfigServiceMock } from './config/raw_config_service.mock';
|
||||
|
||||
const env = new Env('.', getEnvOptions());
|
||||
const logger = loggingServiceMock.create();
|
||||
const logger = loggingSystemMock.create();
|
||||
const rawConfigService = rawConfigServiceMock.create({});
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -68,6 +69,7 @@ test('sets up services on "setup"', async () => {
|
|||
expect(mockRenderingService.setup).not.toHaveBeenCalled();
|
||||
expect(mockMetricsService.setup).not.toHaveBeenCalled();
|
||||
expect(mockStatusService.setup).not.toHaveBeenCalled();
|
||||
expect(mockLoggingService.setup).not.toHaveBeenCalled();
|
||||
|
||||
await server.setup();
|
||||
|
||||
|
@ -80,6 +82,7 @@ test('sets up services on "setup"', async () => {
|
|||
expect(mockRenderingService.setup).toHaveBeenCalledTimes(1);
|
||||
expect(mockMetricsService.setup).toHaveBeenCalledTimes(1);
|
||||
expect(mockStatusService.setup).toHaveBeenCalledTimes(1);
|
||||
expect(mockLoggingService.setup).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('injects legacy dependency to context#setup()', async () => {
|
||||
|
@ -151,6 +154,7 @@ test('stops services on "stop"', async () => {
|
|||
expect(mockUiSettingsService.stop).not.toHaveBeenCalled();
|
||||
expect(mockMetricsService.stop).not.toHaveBeenCalled();
|
||||
expect(mockStatusService.stop).not.toHaveBeenCalled();
|
||||
expect(mockLoggingService.stop).not.toHaveBeenCalled();
|
||||
|
||||
await server.stop();
|
||||
|
||||
|
@ -162,6 +166,7 @@ test('stops services on "stop"', async () => {
|
|||
expect(mockUiSettingsService.stop).toHaveBeenCalledTimes(1);
|
||||
expect(mockMetricsService.stop).toHaveBeenCalledTimes(1);
|
||||
expect(mockStatusService.stop).toHaveBeenCalledTimes(1);
|
||||
expect(mockLoggingService.stop).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test(`doesn't setup core services if config validation fails`, async () => {
|
||||
|
@ -179,6 +184,7 @@ test(`doesn't setup core services if config validation fails`, async () => {
|
|||
expect(mockRenderingService.setup).not.toHaveBeenCalled();
|
||||
expect(mockMetricsService.setup).not.toHaveBeenCalled();
|
||||
expect(mockStatusService.setup).not.toHaveBeenCalled();
|
||||
expect(mockLoggingService.setup).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test(`doesn't setup core services if legacy config validation fails`, async () => {
|
||||
|
@ -200,4 +206,5 @@ test(`doesn't setup core services if legacy config validation fails`, async () =
|
|||
expect(mockUiSettingsService.setup).not.toHaveBeenCalled();
|
||||
expect(mockMetricsService.setup).not.toHaveBeenCalled();
|
||||
expect(mockStatusService.setup).not.toHaveBeenCalled();
|
||||
expect(mockLoggingService.setup).not.toHaveBeenCalled();
|
||||
});
|
||||
|
|
|
@ -32,7 +32,7 @@ import { HttpService } from './http';
|
|||
import { HttpResourcesService } from './http_resources';
|
||||
import { RenderingService } from './rendering';
|
||||
import { LegacyService, ensureValidConfiguration } from './legacy';
|
||||
import { Logger, LoggerFactory } from './logging';
|
||||
import { Logger, LoggerFactory, LoggingService, ILoggingSystem } from './logging';
|
||||
import { UiSettingsService } from './ui_settings';
|
||||
import { PluginsService, config as pluginsConfig } from './plugins';
|
||||
import { SavedObjectsService } from '../server/saved_objects';
|
||||
|
@ -74,20 +74,23 @@ export class Server {
|
|||
private readonly metrics: MetricsService;
|
||||
private readonly httpResources: HttpResourcesService;
|
||||
private readonly status: StatusService;
|
||||
private readonly logging: LoggingService;
|
||||
private readonly coreApp: CoreApp;
|
||||
|
||||
#pluginsInitialized?: boolean;
|
||||
private coreStart?: InternalCoreStart;
|
||||
private readonly logger: LoggerFactory;
|
||||
|
||||
constructor(
|
||||
rawConfigProvider: RawConfigurationProvider,
|
||||
public readonly env: Env,
|
||||
private readonly logger: LoggerFactory
|
||||
private readonly loggingSystem: ILoggingSystem
|
||||
) {
|
||||
this.logger = this.loggingSystem.asLoggerFactory();
|
||||
this.log = this.logger.get('server');
|
||||
this.configService = new ConfigService(rawConfigProvider, env, logger);
|
||||
this.configService = new ConfigService(rawConfigProvider, env, this.logger);
|
||||
|
||||
const core = { coreId, configService: this.configService, env, logger };
|
||||
const core = { coreId, configService: this.configService, env, logger: this.logger };
|
||||
this.context = new ContextService(core);
|
||||
this.http = new HttpService(core);
|
||||
this.rendering = new RenderingService(core);
|
||||
|
@ -102,6 +105,7 @@ export class Server {
|
|||
this.status = new StatusService(core);
|
||||
this.coreApp = new CoreApp(core);
|
||||
this.httpResources = new HttpResourcesService(core);
|
||||
this.logging = new LoggingService(core);
|
||||
}
|
||||
|
||||
public async setup() {
|
||||
|
@ -164,6 +168,10 @@ export class Server {
|
|||
savedObjects: savedObjectsSetup,
|
||||
});
|
||||
|
||||
const loggingSetup = this.logging.setup({
|
||||
loggingSystem: this.loggingSystem,
|
||||
});
|
||||
|
||||
const coreSetup: InternalCoreSetup = {
|
||||
capabilities: capabilitiesSetup,
|
||||
context: contextServiceSetup,
|
||||
|
@ -176,6 +184,7 @@ export class Server {
|
|||
metrics: metricsSetup,
|
||||
rendering: renderingSetup,
|
||||
httpResources: httpResourcesSetup,
|
||||
logging: loggingSetup,
|
||||
};
|
||||
|
||||
const pluginsSetup = await this.plugins.setup(coreSetup);
|
||||
|
@ -244,6 +253,7 @@ export class Server {
|
|||
await this.rendering.stop();
|
||||
await this.metrics.stop();
|
||||
await this.status.stop();
|
||||
await this.logging.stop();
|
||||
}
|
||||
|
||||
private registerCoreContext(coreSetup: InternalCoreSetup) {
|
||||
|
|
|
@ -21,7 +21,7 @@ import Chance from 'chance';
|
|||
|
||||
import { SavedObjectsErrorHelpers } from '../../saved_objects';
|
||||
import { savedObjectsClientMock } from '../../saved_objects/service/saved_objects_client.mock';
|
||||
import { loggingServiceMock } from '../../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../../logging/logging_system.mock';
|
||||
import { getUpgradeableConfigMock } from './get_upgradeable_config.test.mock';
|
||||
|
||||
import { createOrUpgradeSavedConfig } from './create_or_upgrade_saved_config';
|
||||
|
@ -35,7 +35,7 @@ describe('uiSettings/createOrUpgradeSavedConfig', function () {
|
|||
const buildNum = chance.integer({ min: 1000, max: 5000 });
|
||||
|
||||
function setup() {
|
||||
const logger = loggingServiceMock.create();
|
||||
const logger = loggingSystemMock.create();
|
||||
const getUpgradeableConfig = getUpgradeableConfigMock;
|
||||
const savedObjectsClient = savedObjectsClientMock.create();
|
||||
savedObjectsClient.create.mockImplementation(
|
||||
|
@ -137,7 +137,7 @@ describe('uiSettings/createOrUpgradeSavedConfig', function () {
|
|||
});
|
||||
|
||||
await run();
|
||||
expect(loggingServiceMock.collect(logger).debug).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).debug).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"Upgrade config from 4.0.0 to 4.0.1",
|
||||
|
@ -169,7 +169,7 @@ describe('uiSettings/createOrUpgradeSavedConfig', function () {
|
|||
expect(error.message).toBe('foo');
|
||||
}
|
||||
|
||||
expect(loggingServiceMock.collect(logger).debug).toHaveLength(0);
|
||||
expect(loggingSystemMock.collect(logger).debug).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -26,10 +26,10 @@ import {
|
|||
TestUtils,
|
||||
} from '../../../../../test_utils/kbn_server';
|
||||
import { createOrUpgradeSavedConfig } from '../create_or_upgrade_saved_config';
|
||||
import { loggingServiceMock } from '../../../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../../../logging/logging_system.mock';
|
||||
import { httpServerMock } from '../../../http/http_server.mocks';
|
||||
|
||||
const logger = loggingServiceMock.create().get();
|
||||
const logger = loggingSystemMock.create().get();
|
||||
describe('createOrUpgradeSavedConfig()', () => {
|
||||
let savedObjectsClient: SavedObjectsClientContract;
|
||||
let servers: TestUtils;
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
import Chance from 'chance';
|
||||
import { schema } from '@kbn/config-schema';
|
||||
|
||||
import { loggingServiceMock } from '../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../logging/logging_system.mock';
|
||||
import { createOrUpgradeSavedConfigMock } from './create_or_upgrade_saved_config/create_or_upgrade_saved_config.test.mock';
|
||||
|
||||
import { SavedObjectsClient } from '../saved_objects';
|
||||
|
@ -28,7 +28,7 @@ import { savedObjectsClientMock } from '../saved_objects/service/saved_objects_c
|
|||
import { UiSettingsClient } from './ui_settings_client';
|
||||
import { CannotOverrideError } from './ui_settings_errors';
|
||||
|
||||
const logger = loggingServiceMock.create().get();
|
||||
const logger = loggingSystemMock.create().get();
|
||||
|
||||
const TYPE = 'config';
|
||||
const ID = 'kibana-version';
|
||||
|
@ -375,7 +375,7 @@ describe('ui settings', () => {
|
|||
},
|
||||
});
|
||||
|
||||
expect(loggingServiceMock.collect(logger).warn).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).warn).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"Ignore invalid UiSettings value. Error: [validation [id]]: expected value of type [number] but got [string].",
|
||||
|
@ -517,7 +517,7 @@ describe('ui settings', () => {
|
|||
user: 'foo',
|
||||
});
|
||||
|
||||
expect(loggingServiceMock.collect(logger).warn).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).warn).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"Ignore invalid UiSettings value. Error: [validation [id]]: expected value of type [number] but got [string].",
|
||||
|
@ -645,7 +645,7 @@ describe('ui settings', () => {
|
|||
|
||||
expect(await uiSettings.get('id')).toBe(42);
|
||||
|
||||
expect(loggingServiceMock.collect(logger).warn).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).warn).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"Ignore invalid UiSettings value. Error: [validation [id]]: expected value of type [number] but got [string].",
|
||||
|
|
|
@ -21,7 +21,7 @@ import { join } from 'path';
|
|||
import { readFile, writeFile } from './fs';
|
||||
import { resolveInstanceUuid, UUID_7_6_0_BUG } from './resolve_uuid';
|
||||
import { configServiceMock } from '../config/config_service.mock';
|
||||
import { loggingServiceMock } from '../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../logging/logging_system.mock';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { Logger } from '../logging';
|
||||
|
||||
|
@ -93,7 +93,7 @@ describe('resolveInstanceUuid', () => {
|
|||
mockReadFile({ uuid: DEFAULT_FILE_UUID });
|
||||
mockWriteFile();
|
||||
configService = getConfigService(DEFAULT_CONFIG_UUID);
|
||||
logger = loggingServiceMock.create().get() as any;
|
||||
logger = loggingSystemMock.create().get() as any;
|
||||
});
|
||||
|
||||
describe('when file is present and config property is set', () => {
|
||||
|
|
|
@ -21,7 +21,7 @@ import { UuidService } from './uuid_service';
|
|||
import { resolveInstanceUuid } from './resolve_uuid';
|
||||
import { CoreContext } from '../core_context';
|
||||
|
||||
import { loggingServiceMock } from '../logging/logging_service.mock';
|
||||
import { loggingSystemMock } from '../logging/logging_system.mock';
|
||||
import { mockCoreContext } from '../core_context.mock';
|
||||
import { Env } from '../config';
|
||||
import { getEnvOptions } from '../config/__mocks__/env';
|
||||
|
@ -31,12 +31,12 @@ jest.mock('./resolve_uuid', () => ({
|
|||
}));
|
||||
|
||||
describe('UuidService', () => {
|
||||
let logger: ReturnType<typeof loggingServiceMock.create>;
|
||||
let logger: ReturnType<typeof loggingSystemMock.create>;
|
||||
let coreContext: CoreContext;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
logger = loggingServiceMock.create();
|
||||
logger = loggingSystemMock.create();
|
||||
coreContext = mockCoreContext.create({ logger });
|
||||
});
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
import { shortUrlLookupProvider, ShortUrlLookupService, UrlAttributes } from './short_url_lookup';
|
||||
import { SavedObjectsClientContract, SavedObject } from 'kibana/server';
|
||||
|
||||
import { savedObjectsClientMock, loggingServiceMock } from '../../../../../core/server/mocks';
|
||||
import { savedObjectsClientMock, loggingSystemMock } from '../../../../../core/server/mocks';
|
||||
|
||||
describe('shortUrlLookupProvider', () => {
|
||||
const ID = 'bf00ad16941fc51420f91a93428b27a0';
|
||||
|
@ -35,7 +35,7 @@ describe('shortUrlLookupProvider', () => {
|
|||
savedObjects = savedObjectsClientMock.create();
|
||||
savedObjects.create.mockResolvedValue({ id: ID } as SavedObject<UrlAttributes>);
|
||||
deps = { savedObjects };
|
||||
shortUrl = shortUrlLookupProvider({ logger: loggingServiceMock.create().get() });
|
||||
shortUrl = shortUrlLookupProvider({ logger: loggingSystemMock.create().get() });
|
||||
});
|
||||
|
||||
describe('generateUrlId', () => {
|
||||
|
|
|
@ -21,9 +21,9 @@ import { noop } from 'lodash';
|
|||
import { Collector } from './collector';
|
||||
import { CollectorSet } from './collector_set';
|
||||
import { UsageCollector } from './usage_collector';
|
||||
import { loggingServiceMock } from '../../../../core/server/mocks';
|
||||
import { loggingSystemMock } from '../../../../core/server/mocks';
|
||||
|
||||
const logger = loggingServiceMock.createLogger();
|
||||
const logger = loggingSystemMock.createLogger();
|
||||
|
||||
const loggerSpies = {
|
||||
debug: jest.spyOn(logger, 'debug'),
|
||||
|
|
|
@ -17,14 +17,14 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { loggingServiceMock } from '../../../core/server/mocks';
|
||||
import { loggingSystemMock } from '../../../core/server/mocks';
|
||||
import { UsageCollectionSetup } from './plugin';
|
||||
import { CollectorSet } from './collector';
|
||||
|
||||
const createSetupContract = () => {
|
||||
return {
|
||||
...new CollectorSet({
|
||||
logger: loggingServiceMock.createLogger(),
|
||||
logger: loggingSystemMock.createLogger(),
|
||||
maximumWaitTimeForAllCollectorsInS: 1,
|
||||
}),
|
||||
} as UsageCollectionSetup;
|
||||
|
|
7
test/plugin_functional/plugins/core_logging/kibana.json
Normal file
7
test/plugin_functional/plugins/core_logging/kibana.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"id": "core_logging",
|
||||
"version": "0.0.1",
|
||||
"kibanaVersion": "kibana",
|
||||
"configPath": ["core_logging"],
|
||||
"server": true
|
||||
}
|
1
test/plugin_functional/plugins/core_logging/server/.gitignore
vendored
Normal file
1
test/plugin_functional/plugins/core_logging/server/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/*debug.log
|
23
test/plugin_functional/plugins/core_logging/server/index.ts
Normal file
23
test/plugin_functional/plugins/core_logging/server/index.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* 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 type { PluginInitializerContext } from '../../../../../src/core/server';
|
||||
import { CoreLoggingPlugin } from './plugin';
|
||||
|
||||
export const plugin = (init: PluginInitializerContext) => new CoreLoggingPlugin(init);
|
118
test/plugin_functional/plugins/core_logging/server/plugin.ts
Normal file
118
test/plugin_functional/plugins/core_logging/server/plugin.ts
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* 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 { resolve } from 'path';
|
||||
import { Subject } from 'rxjs';
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import type {
|
||||
PluginInitializerContext,
|
||||
Plugin,
|
||||
CoreSetup,
|
||||
LoggerContextConfigInput,
|
||||
Logger,
|
||||
} from '../../../../../src/core/server';
|
||||
|
||||
const CUSTOM_LOGGING_CONFIG: LoggerContextConfigInput = {
|
||||
appenders: {
|
||||
customJsonFile: {
|
||||
kind: 'file',
|
||||
path: resolve(__dirname, 'json_debug.log'), // use 'debug.log' suffix so file watcher does not restart server
|
||||
layout: {
|
||||
kind: 'json',
|
||||
},
|
||||
},
|
||||
customPatternFile: {
|
||||
kind: 'file',
|
||||
path: resolve(__dirname, 'pattern_debug.log'),
|
||||
layout: {
|
||||
kind: 'pattern',
|
||||
pattern: 'CUSTOM - PATTERN [%logger][%level] %message',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
loggers: [
|
||||
{ context: 'debug_json', appenders: ['customJsonFile'], level: 'debug' },
|
||||
{ context: 'debug_pattern', appenders: ['customPatternFile'], level: 'debug' },
|
||||
{ context: 'info_json', appenders: ['customJsonFile'], level: 'info' },
|
||||
{ context: 'info_pattern', appenders: ['customPatternFile'], level: 'info' },
|
||||
{ context: 'all', appenders: ['customJsonFile', 'customPatternFile'], level: 'debug' },
|
||||
],
|
||||
};
|
||||
|
||||
export class CoreLoggingPlugin implements Plugin {
|
||||
private readonly logger: Logger;
|
||||
|
||||
constructor(init: PluginInitializerContext) {
|
||||
this.logger = init.logger.get();
|
||||
}
|
||||
|
||||
public setup(core: CoreSetup) {
|
||||
const loggingConfig$ = new Subject<LoggerContextConfigInput>();
|
||||
core.logging.configure(loggingConfig$);
|
||||
|
||||
const router = core.http.createRouter();
|
||||
|
||||
// Expose a route that allows our test suite to write logs as this plugin
|
||||
router.post(
|
||||
{
|
||||
path: '/internal/core-logging/write-log',
|
||||
validate: {
|
||||
body: schema.object({
|
||||
level: schema.oneOf([schema.literal('debug'), schema.literal('info')]),
|
||||
message: schema.string(),
|
||||
context: schema.arrayOf(schema.string()),
|
||||
}),
|
||||
},
|
||||
},
|
||||
(ctx, req, res) => {
|
||||
const { level, message, context } = req.body;
|
||||
const logger = this.logger.get(...context);
|
||||
|
||||
if (level === 'debug') {
|
||||
logger.debug(message);
|
||||
} else if (level === 'info') {
|
||||
logger.info(message);
|
||||
}
|
||||
|
||||
return res.ok();
|
||||
}
|
||||
);
|
||||
|
||||
// Expose a route to toggle on and off the custom config
|
||||
router.post(
|
||||
{
|
||||
path: '/internal/core-logging/update-config',
|
||||
validate: { body: schema.object({ enableCustomConfig: schema.boolean() }) },
|
||||
},
|
||||
(ctx, req, res) => {
|
||||
if (req.body.enableCustomConfig) {
|
||||
loggingConfig$.next(CUSTOM_LOGGING_CONFIG);
|
||||
} else {
|
||||
loggingConfig$.next({});
|
||||
}
|
||||
|
||||
return res.ok({ body: `Updated config: ${req.body.enableCustomConfig}` });
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public start() {}
|
||||
public stop() {}
|
||||
}
|
13
test/plugin_functional/plugins/core_logging/tsconfig.json
Normal file
13
test/plugin_functional/plugins/core_logging/tsconfig.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"extends": "../../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./target",
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": [
|
||||
"index.ts",
|
||||
"server/**/*.ts",
|
||||
"../../../../typings/**/*",
|
||||
],
|
||||
"exclude": []
|
||||
}
|
|
@ -30,5 +30,6 @@ export default function ({ loadTestFile }: PluginFunctionalProviderContext) {
|
|||
loadTestFile(require.resolve('./application_leave_confirm'));
|
||||
loadTestFile(require.resolve('./application_status'));
|
||||
loadTestFile(require.resolve('./rendering'));
|
||||
loadTestFile(require.resolve('./logging'));
|
||||
});
|
||||
}
|
||||
|
|
146
test/plugin_functional/test_suites/core_plugins/logging.ts
Normal file
146
test/plugin_functional/test_suites/core_plugins/logging.ts
Normal file
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* 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 { resolve } from 'path';
|
||||
import fs from 'fs';
|
||||
import expect from '@kbn/expect';
|
||||
import { PluginFunctionalProviderContext } from '../../services';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function ({ getService }: PluginFunctionalProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
|
||||
describe('plugin logging', function describeIndexTests() {
|
||||
const LOG_FILE_DIRECTORY = resolve(__dirname, '..', '..', 'plugins', 'core_logging', 'server');
|
||||
const JSON_FILE_PATH = resolve(LOG_FILE_DIRECTORY, 'json_debug.log');
|
||||
const PATTERN_FILE_PATH = resolve(LOG_FILE_DIRECTORY, 'pattern_debug.log');
|
||||
|
||||
beforeEach(async () => {
|
||||
// "touch" each file to ensure it exists and is empty before each test
|
||||
await fs.promises.writeFile(JSON_FILE_PATH, '');
|
||||
await fs.promises.writeFile(PATTERN_FILE_PATH, '');
|
||||
});
|
||||
|
||||
async function readLines(path: string) {
|
||||
const contents = await fs.promises.readFile(path, { encoding: 'utf8' });
|
||||
return contents.trim().split('\n');
|
||||
}
|
||||
|
||||
async function readJsonLines() {
|
||||
return (await readLines(JSON_FILE_PATH))
|
||||
.filter((line) => line.length > 0)
|
||||
.map((line) => JSON.parse(line))
|
||||
.map(({ level, message, context }) => ({ level, message, context }));
|
||||
}
|
||||
|
||||
function writeLog(context: string[], level: string, message: string) {
|
||||
return supertest
|
||||
.post('/internal/core-logging/write-log')
|
||||
.set('kbn-xsrf', 'anything')
|
||||
.send({ context, level, message })
|
||||
.expect(200);
|
||||
}
|
||||
|
||||
function setContextConfig(enable: boolean) {
|
||||
return supertest
|
||||
.post('/internal/core-logging/update-config')
|
||||
.set('kbn-xsrf', 'anything')
|
||||
.send({ enableCustomConfig: enable })
|
||||
.expect(200);
|
||||
}
|
||||
|
||||
it('does not write to custom appenders when not configured', async () => {
|
||||
await setContextConfig(false);
|
||||
await writeLog(['debug_json'], 'info', 'i go to the default appender!');
|
||||
expect(await readJsonLines()).to.eql([]);
|
||||
});
|
||||
|
||||
it('writes debug_json context to custom JSON appender', async () => {
|
||||
await setContextConfig(true);
|
||||
await writeLog(['debug_json'], 'debug', 'log1');
|
||||
await writeLog(['debug_json'], 'info', 'log2');
|
||||
expect(await readJsonLines()).to.eql([
|
||||
{
|
||||
level: 'DEBUG',
|
||||
context: 'plugins.core_logging.debug_json',
|
||||
message: 'log1',
|
||||
},
|
||||
{
|
||||
level: 'INFO',
|
||||
context: 'plugins.core_logging.debug_json',
|
||||
message: 'log2',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('writes info_json context to custom JSON appender', async () => {
|
||||
await setContextConfig(true);
|
||||
await writeLog(['info_json'], 'debug', 'i should not be logged!');
|
||||
await writeLog(['info_json'], 'info', 'log2');
|
||||
expect(await readJsonLines()).to.eql([
|
||||
{
|
||||
level: 'INFO',
|
||||
context: 'plugins.core_logging.info_json',
|
||||
message: 'log2',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('writes debug_pattern context to custom pattern appender', async () => {
|
||||
await setContextConfig(true);
|
||||
await writeLog(['debug_pattern'], 'debug', 'log1');
|
||||
await writeLog(['debug_pattern'], 'info', 'log2');
|
||||
expect(await readLines(PATTERN_FILE_PATH)).to.eql([
|
||||
'CUSTOM - PATTERN [plugins.core_logging.debug_pattern][DEBUG] log1',
|
||||
'CUSTOM - PATTERN [plugins.core_logging.debug_pattern][INFO ] log2',
|
||||
]);
|
||||
});
|
||||
|
||||
it('writes info_pattern context to custom pattern appender', async () => {
|
||||
await setContextConfig(true);
|
||||
await writeLog(['info_pattern'], 'debug', 'i should not be logged!');
|
||||
await writeLog(['info_pattern'], 'info', 'log2');
|
||||
expect(await readLines(PATTERN_FILE_PATH)).to.eql([
|
||||
'CUSTOM - PATTERN [plugins.core_logging.info_pattern][INFO ] log2',
|
||||
]);
|
||||
});
|
||||
|
||||
it('writes all context to both appenders', async () => {
|
||||
await setContextConfig(true);
|
||||
await writeLog(['all'], 'debug', 'log1');
|
||||
await writeLog(['all'], 'info', 'log2');
|
||||
expect(await readJsonLines()).to.eql([
|
||||
{
|
||||
level: 'DEBUG',
|
||||
context: 'plugins.core_logging.all',
|
||||
message: 'log1',
|
||||
},
|
||||
{
|
||||
level: 'INFO',
|
||||
context: 'plugins.core_logging.all',
|
||||
message: 'log2',
|
||||
},
|
||||
]);
|
||||
expect(await readLines(PATTERN_FILE_PATH)).to.eql([
|
||||
'CUSTOM - PATTERN [plugins.core_logging.all][DEBUG] log1',
|
||||
'CUSTOM - PATTERN [plugins.core_logging.all][INFO ] log2',
|
||||
]);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -9,7 +9,7 @@ import { ActionTypeRegistry } from '../action_type_registry';
|
|||
import { taskManagerMock } from '../../../task_manager/server/task_manager.mock';
|
||||
import { registerBuiltInActionTypes } from './index';
|
||||
import { Logger } from '../../../../../src/core/server';
|
||||
import { loggingServiceMock } from '../../../../../src/core/server/mocks';
|
||||
import { loggingSystemMock } from '../../../../../src/core/server/mocks';
|
||||
import { actionsConfigMock } from '../actions_config.mock';
|
||||
import { licenseStateMock } from '../lib/license_state.mock';
|
||||
|
||||
|
@ -19,7 +19,7 @@ export function createActionTypeRegistry(): {
|
|||
logger: jest.Mocked<Logger>;
|
||||
actionTypeRegistry: ActionTypeRegistry;
|
||||
} {
|
||||
const logger = loggingServiceMock.create().get() as jest.Mocked<Logger>;
|
||||
const logger = loggingSystemMock.create().get() as jest.Mocked<Logger>;
|
||||
const actionTypeRegistry = new ActionTypeRegistry({
|
||||
taskManager: taskManagerMock.setup(),
|
||||
taskRunnerFactory: new TaskRunnerFactory(
|
||||
|
|
|
@ -10,14 +10,14 @@ jest.mock('nodemailer', () => ({
|
|||
|
||||
import { Logger } from '../../../../../../src/core/server';
|
||||
import { sendEmail } from './send_email';
|
||||
import { loggingServiceMock } from '../../../../../../src/core/server/mocks';
|
||||
import { loggingSystemMock } from '../../../../../../src/core/server/mocks';
|
||||
import nodemailer from 'nodemailer';
|
||||
|
||||
const createTransportMock = nodemailer.createTransport as jest.Mock;
|
||||
const sendMailMockResult = { result: 'does not matter' };
|
||||
const sendMailMock = jest.fn();
|
||||
|
||||
const mockLogger = loggingServiceMock.create().get() as jest.Mocked<Logger>;
|
||||
const mockLogger = loggingSystemMock.create().get() as jest.Mocked<Logger>;
|
||||
|
||||
describe('send_email module', () => {
|
||||
beforeEach(() => {
|
||||
|
|
|
@ -9,7 +9,7 @@ import { schema } from '@kbn/config-schema';
|
|||
import { ActionExecutor } from './action_executor';
|
||||
import { actionTypeRegistryMock } from '../action_type_registry.mock';
|
||||
import { encryptedSavedObjectsMock } from '../../../encrypted_saved_objects/server/mocks';
|
||||
import { loggingServiceMock, savedObjectsClientMock } from '../../../../../src/core/server/mocks';
|
||||
import { loggingSystemMock, savedObjectsClientMock } from '../../../../../src/core/server/mocks';
|
||||
import { eventLoggerMock } from '../../../event_log/server/mocks';
|
||||
import { spacesServiceMock } from '../../../spaces/server/spaces_service/spaces_service.mock';
|
||||
import { ActionType } from '../types';
|
||||
|
@ -31,7 +31,7 @@ const executeParams = {
|
|||
|
||||
const spacesMock = spacesServiceMock.createSetupContract();
|
||||
actionExecutor.initialize({
|
||||
logger: loggingServiceMock.create().get(),
|
||||
logger: loggingSystemMock.create().get(),
|
||||
spaces: spacesMock,
|
||||
getServices: () => services,
|
||||
getScopedSavedObjectsClient: () => savedObjectsClientWithHidden,
|
||||
|
@ -266,7 +266,7 @@ test('should not throws an error if actionType is preconfigured', async () => {
|
|||
test('throws an error when passing isESOUsingEphemeralEncryptionKey with value of true', async () => {
|
||||
const customActionExecutor = new ActionExecutor({ isESOUsingEphemeralEncryptionKey: true });
|
||||
customActionExecutor.initialize({
|
||||
logger: loggingServiceMock.create().get(),
|
||||
logger: loggingSystemMock.create().get(),
|
||||
spaces: spacesMock,
|
||||
getScopedSavedObjectsClient: () => savedObjectsClientWithHidden,
|
||||
getServices: () => services,
|
||||
|
|
|
@ -12,7 +12,7 @@ import { TaskRunnerFactory } from './task_runner_factory';
|
|||
import { actionTypeRegistryMock } from '../action_type_registry.mock';
|
||||
import { actionExecutorMock } from './action_executor.mock';
|
||||
import { encryptedSavedObjectsMock } from '../../../encrypted_saved_objects/server/mocks';
|
||||
import { savedObjectsClientMock, loggingServiceMock } from 'src/core/server/mocks';
|
||||
import { savedObjectsClientMock, loggingSystemMock } from 'src/core/server/mocks';
|
||||
import { eventLoggerMock } from '../../../event_log/server/mocks';
|
||||
import { ActionTypeDisabledError } from './errors';
|
||||
|
||||
|
@ -56,7 +56,7 @@ const services = {
|
|||
savedObjectsClient: savedObjectsClientMock.create(),
|
||||
};
|
||||
const actionExecutorInitializerParams = {
|
||||
logger: loggingServiceMock.create().get(),
|
||||
logger: loggingSystemMock.create().get(),
|
||||
getServices: jest.fn().mockReturnValue(services),
|
||||
actionTypeRegistry,
|
||||
getScopedSavedObjectsClient: () => savedObjectsClientMock.create(),
|
||||
|
@ -67,7 +67,7 @@ const actionExecutorInitializerParams = {
|
|||
const taskRunnerFactoryInitializerParams = {
|
||||
spaceIdToNamespace,
|
||||
actionTypeRegistry,
|
||||
logger: loggingServiceMock.create().get(),
|
||||
logger: loggingSystemMock.create().get(),
|
||||
encryptedSavedObjectsClient: mockedEncryptedSavedObjectsClient,
|
||||
getBasePath: jest.fn().mockReturnValue(undefined),
|
||||
getScopedSavedObjectsClient: jest.fn().mockReturnValue(services.savedObjectsClient),
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { loggingServiceMock } from '../../../../../../src/core/server/mocks';
|
||||
import { loggingSystemMock } from '../../../../../../src/core/server/mocks';
|
||||
import { getAlertType } from './alert_type';
|
||||
import { Params } from './alert_type_params';
|
||||
|
||||
|
@ -13,7 +13,7 @@ describe('alertType', () => {
|
|||
indexThreshold: {
|
||||
timeSeriesQuery: jest.fn(),
|
||||
},
|
||||
logger: loggingServiceMock.create().get(),
|
||||
logger: loggingSystemMock.create().get(),
|
||||
};
|
||||
|
||||
const alertType = getAlertType(service);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
// test error conditions of calling timeSeriesQuery - postive results tested in FT
|
||||
|
||||
import { loggingServiceMock } from '../../../../../../../src/core/server/mocks';
|
||||
import { loggingSystemMock } from '../../../../../../../src/core/server/mocks';
|
||||
import { coreMock } from '../../../../../../../src/core/server/mocks';
|
||||
import { AlertingBuiltinsPlugin } from '../../../plugin';
|
||||
import { TimeSeriesQueryParameters, TimeSeriesResult, TimeSeriesQuery } from './time_series_query';
|
||||
|
@ -44,7 +44,7 @@ describe('timeSeriesQuery', () => {
|
|||
|
||||
mockCallCluster.mockReset();
|
||||
params = {
|
||||
logger: loggingServiceMock.create().get(),
|
||||
logger: loggingSystemMock.create().get(),
|
||||
callCluster: mockCallCluster,
|
||||
query: DefaultQueryParams,
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import uuid from 'uuid';
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { AlertsClient, CreateOptions } from './alerts_client';
|
||||
import { savedObjectsClientMock, loggingServiceMock } from '../../../../src/core/server/mocks';
|
||||
import { savedObjectsClientMock, loggingSystemMock } from '../../../../src/core/server/mocks';
|
||||
import { taskManagerMock } from '../../task_manager/server/task_manager.mock';
|
||||
import { alertTypeRegistryMock } from './alert_type_registry.mock';
|
||||
import { TaskStatus } from '../../task_manager/server';
|
||||
|
@ -29,7 +29,7 @@ const alertsClientParams = {
|
|||
getUserName: jest.fn(),
|
||||
createAPIKey: jest.fn(),
|
||||
invalidateAPIKey: jest.fn(),
|
||||
logger: loggingServiceMock.create().get(),
|
||||
logger: loggingSystemMock.create().get(),
|
||||
encryptedSavedObjectsClient: encryptedSavedObjects,
|
||||
getActionsClient: jest.fn(),
|
||||
};
|
||||
|
|
|
@ -9,7 +9,7 @@ import { AlertsClientFactory, AlertsClientFactoryOpts } from './alerts_client_fa
|
|||
import { alertTypeRegistryMock } from './alert_type_registry.mock';
|
||||
import { taskManagerMock } from '../../task_manager/server/task_manager.mock';
|
||||
import { KibanaRequest } from '../../../../src/core/server';
|
||||
import { loggingServiceMock, savedObjectsClientMock } from '../../../../src/core/server/mocks';
|
||||
import { loggingSystemMock, savedObjectsClientMock } from '../../../../src/core/server/mocks';
|
||||
import { encryptedSavedObjectsMock } from '../../encrypted_saved_objects/server/mocks';
|
||||
import { AuthenticatedUser } from '../../../plugins/security/common/model';
|
||||
import { securityMock } from '../../security/server/mocks';
|
||||
|
@ -20,7 +20,7 @@ jest.mock('./alerts_client');
|
|||
const savedObjectsClient = savedObjectsClientMock.create();
|
||||
const securityPluginSetup = securityMock.createSetup();
|
||||
const alertsClientFactoryParams: jest.Mocked<AlertsClientFactoryOpts> = {
|
||||
logger: loggingServiceMock.create().get(),
|
||||
logger: loggingSystemMock.create().get(),
|
||||
taskManager: taskManagerMock.start(),
|
||||
alertTypeRegistry: alertTypeRegistryMock.create(),
|
||||
getSpaceId: jest.fn(),
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import { AlertType } from '../types';
|
||||
import { createExecutionHandler } from './create_execution_handler';
|
||||
import { loggingServiceMock } from '../../../../../src/core/server/mocks';
|
||||
import { loggingSystemMock } from '../../../../../src/core/server/mocks';
|
||||
import { actionsMock, actionsClientMock } from '../../../actions/server/mocks';
|
||||
import { eventLoggerMock } from '../../../event_log/server/event_logger.mock';
|
||||
import { KibanaRequest } from 'kibana/server';
|
||||
|
@ -34,7 +34,7 @@ const createExecutionHandlerParams = {
|
|||
spaceIdToNamespace: jest.fn().mockReturnValue(undefined),
|
||||
getBasePath: jest.fn().mockReturnValue(undefined),
|
||||
alertType,
|
||||
logger: loggingServiceMock.create().get(),
|
||||
logger: loggingSystemMock.create().get(),
|
||||
eventLogger: eventLoggerMock.create(),
|
||||
actions: [
|
||||
{
|
||||
|
|
|
@ -11,7 +11,7 @@ import { ConcreteTaskInstance, TaskStatus } from '../../../task_manager/server';
|
|||
import { TaskRunnerContext } from './task_runner_factory';
|
||||
import { TaskRunner } from './task_runner';
|
||||
import { encryptedSavedObjectsMock } from '../../../encrypted_saved_objects/server/mocks';
|
||||
import { loggingServiceMock } from '../../../../../src/core/server/mocks';
|
||||
import { loggingSystemMock } from '../../../../../src/core/server/mocks';
|
||||
import { PluginStartContract as ActionsPluginStart } from '../../../actions/server';
|
||||
import { actionsMock, actionsClientMock } from '../../../actions/server/mocks';
|
||||
import { alertsMock } from '../mocks';
|
||||
|
@ -66,7 +66,7 @@ describe('Task Runner', () => {
|
|||
getServices: jest.fn().mockReturnValue(services),
|
||||
actionsPlugin: actionsMock.createStart(),
|
||||
encryptedSavedObjectsClient,
|
||||
logger: loggingServiceMock.create().get(),
|
||||
logger: loggingSystemMock.create().get(),
|
||||
spaceIdToNamespace: jest.fn().mockReturnValue(undefined),
|
||||
getBasePath: jest.fn().mockReturnValue(undefined),
|
||||
eventLogger: eventLoggerMock.create(),
|
||||
|
|
|
@ -8,7 +8,7 @@ import sinon from 'sinon';
|
|||
import { ConcreteTaskInstance, TaskStatus } from '../../../task_manager/server';
|
||||
import { TaskRunnerContext, TaskRunnerFactory } from './task_runner_factory';
|
||||
import { encryptedSavedObjectsMock } from '../../../encrypted_saved_objects/server/mocks';
|
||||
import { loggingServiceMock } from '../../../../../src/core/server/mocks';
|
||||
import { loggingSystemMock } from '../../../../../src/core/server/mocks';
|
||||
import { actionsMock } from '../../../actions/server/mocks';
|
||||
import { alertsMock } from '../mocks';
|
||||
import { eventLoggerMock } from '../../../event_log/server/event_logger.mock';
|
||||
|
@ -57,7 +57,7 @@ describe('Task Runner Factory', () => {
|
|||
getServices: jest.fn().mockReturnValue(services),
|
||||
actionsPlugin: actionsMock.createStart(),
|
||||
encryptedSavedObjectsClient: encryptedSavedObjectsPlugin.getClient(),
|
||||
logger: loggingServiceMock.create().get(),
|
||||
logger: loggingSystemMock.create().get(),
|
||||
spaceIdToNamespace: jest.fn().mockReturnValue(undefined),
|
||||
getBasePath: jest.fn().mockReturnValue(undefined),
|
||||
eventLogger: eventLoggerMock.create(),
|
||||
|
|
|
@ -9,7 +9,7 @@ import {
|
|||
savedObjectsClientMock,
|
||||
httpServiceMock,
|
||||
httpServerMock,
|
||||
loggingServiceMock,
|
||||
loggingSystemMock,
|
||||
} from 'src/core/server/mocks';
|
||||
import { CUSTOM_ELEMENT_TYPE } from '../../../common/lib/constants';
|
||||
import { initializeCreateCustomElementRoute } from './create';
|
||||
|
@ -41,7 +41,7 @@ describe('POST custom element', () => {
|
|||
const router = httpService.createRouter();
|
||||
initializeCreateCustomElementRoute({
|
||||
router,
|
||||
logger: loggingServiceMock.create().get(),
|
||||
logger: loggingSystemMock.create().get(),
|
||||
});
|
||||
|
||||
routeHandler = router.post.mock.calls[0][1];
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
savedObjectsClientMock,
|
||||
httpServiceMock,
|
||||
httpServerMock,
|
||||
loggingServiceMock,
|
||||
loggingSystemMock,
|
||||
} from 'src/core/server/mocks';
|
||||
|
||||
const mockRouteContext = ({
|
||||
|
@ -30,7 +30,7 @@ describe('DELETE custom element', () => {
|
|||
const router = httpService.createRouter();
|
||||
initializeDeleteCustomElementRoute({
|
||||
router,
|
||||
logger: loggingServiceMock.create().get(),
|
||||
logger: loggingSystemMock.create().get(),
|
||||
});
|
||||
|
||||
routeHandler = router.delete.mock.calls[0][1];
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
savedObjectsClientMock,
|
||||
httpServiceMock,
|
||||
httpServerMock,
|
||||
loggingServiceMock,
|
||||
loggingSystemMock,
|
||||
} from 'src/core/server/mocks';
|
||||
|
||||
const mockRouteContext = ({
|
||||
|
@ -29,7 +29,7 @@ describe('Find custom element', () => {
|
|||
const router = httpService.createRouter();
|
||||
initializeFindCustomElementsRoute({
|
||||
router,
|
||||
logger: loggingServiceMock.create().get(),
|
||||
logger: loggingSystemMock.create().get(),
|
||||
});
|
||||
|
||||
routeHandler = router.get.mock.calls[0][1];
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
savedObjectsClientMock,
|
||||
httpServiceMock,
|
||||
httpServerMock,
|
||||
loggingServiceMock,
|
||||
loggingSystemMock,
|
||||
} from 'src/core/server/mocks';
|
||||
|
||||
const mockRouteContext = ({
|
||||
|
@ -30,7 +30,7 @@ describe('GET custom element', () => {
|
|||
const router = httpService.createRouter();
|
||||
initializeGetCustomElementRoute({
|
||||
router,
|
||||
logger: loggingServiceMock.create().get(),
|
||||
logger: loggingSystemMock.create().get(),
|
||||
});
|
||||
|
||||
routeHandler = router.get.mock.calls[0][1];
|
||||
|
|
|
@ -13,7 +13,7 @@ import {
|
|||
savedObjectsClientMock,
|
||||
httpServiceMock,
|
||||
httpServerMock,
|
||||
loggingServiceMock,
|
||||
loggingSystemMock,
|
||||
} from 'src/core/server/mocks';
|
||||
import { okResponse } from '../ok_response';
|
||||
|
||||
|
@ -55,7 +55,7 @@ describe('PUT custom element', () => {
|
|||
const router = httpService.createRouter();
|
||||
initializeUpdateCustomElementRoute({
|
||||
router,
|
||||
logger: loggingServiceMock.create().get(),
|
||||
logger: loggingSystemMock.create().get(),
|
||||
});
|
||||
|
||||
routeHandler = router.put.mock.calls[0][1];
|
||||
|
|
|
@ -9,7 +9,7 @@ import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from 'sr
|
|||
import {
|
||||
httpServiceMock,
|
||||
httpServerMock,
|
||||
loggingServiceMock,
|
||||
loggingSystemMock,
|
||||
elasticsearchServiceMock,
|
||||
} from 'src/core/server/mocks';
|
||||
|
||||
|
@ -29,7 +29,7 @@ describe('Retrieve ES Fields', () => {
|
|||
const router = httpService.createRouter();
|
||||
initializeESFieldsRoute({
|
||||
router,
|
||||
logger: loggingServiceMock.create().get(),
|
||||
logger: loggingSystemMock.create().get(),
|
||||
});
|
||||
|
||||
routeHandler = router.get.mock.calls[0][1];
|
||||
|
|
|
@ -8,7 +8,7 @@ jest.mock('fs');
|
|||
|
||||
import fs from 'fs';
|
||||
import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from 'src/core/server';
|
||||
import { httpServiceMock, httpServerMock, loggingServiceMock } from 'src/core/server/mocks';
|
||||
import { httpServiceMock, httpServerMock, loggingSystemMock } from 'src/core/server/mocks';
|
||||
import { initializeDownloadShareableWorkpadRoute } from './download';
|
||||
|
||||
const mockRouteContext = {} as RequestHandlerContext;
|
||||
|
@ -23,7 +23,7 @@ describe('Download Canvas shareables runtime', () => {
|
|||
const router = httpService.createRouter();
|
||||
initializeDownloadShareableWorkpadRoute({
|
||||
router,
|
||||
logger: loggingServiceMock.create().get(),
|
||||
logger: loggingSystemMock.create().get(),
|
||||
});
|
||||
|
||||
routeHandler = router.get.mock.calls[0][1];
|
||||
|
|
|
@ -8,7 +8,7 @@ jest.mock('archiver');
|
|||
|
||||
const archiver = require('archiver') as jest.Mock;
|
||||
import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from 'src/core/server';
|
||||
import { httpServiceMock, httpServerMock, loggingServiceMock } from 'src/core/server/mocks';
|
||||
import { httpServiceMock, httpServerMock, loggingSystemMock } from 'src/core/server/mocks';
|
||||
import { initializeZipShareableWorkpadRoute } from './zip';
|
||||
import { API_ROUTE_SHAREABLE_ZIP } from '../../../common/lib';
|
||||
import {
|
||||
|
@ -29,7 +29,7 @@ describe('Zips Canvas shareables runtime together with workpad', () => {
|
|||
const router = httpService.createRouter();
|
||||
initializeZipShareableWorkpadRoute({
|
||||
router,
|
||||
logger: loggingServiceMock.create().get(),
|
||||
logger: loggingSystemMock.create().get(),
|
||||
});
|
||||
|
||||
routeHandler = router.post.mock.calls[0][1];
|
||||
|
|
|
@ -9,7 +9,7 @@ import {
|
|||
savedObjectsClientMock,
|
||||
httpServiceMock,
|
||||
httpServerMock,
|
||||
loggingServiceMock,
|
||||
loggingSystemMock,
|
||||
} from 'src/core/server/mocks';
|
||||
import { CANVAS_TYPE } from '../../../common/lib/constants';
|
||||
import { initializeCreateWorkpadRoute } from './create';
|
||||
|
@ -41,7 +41,7 @@ describe('POST workpad', () => {
|
|||
const router = httpService.createRouter();
|
||||
initializeCreateWorkpadRoute({
|
||||
router,
|
||||
logger: loggingServiceMock.create().get(),
|
||||
logger: loggingSystemMock.create().get(),
|
||||
});
|
||||
|
||||
routeHandler = router.post.mock.calls[0][1];
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue