mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Logs Shared] Disable log view saved object registration for serverless (#165243)
## 📓 Summary Closes #165222 This work intends to avoid the registration of the log view saved object (`type: "infrastructure-monitoring-log-view"`) and the related endpoint to update a persisted log view. To achieve it, the `xpack.logs_shared.savedObjects.logView.enabled` configuration is introduced, which is configurable only in a serverless environment and defaults to `true` for the stateful Kibana version to keep the existing behaviour unchanged. To also guarantee the normal functioning of the consumers of the `<LogStream />` component in a serverless environment, we now set an internal view using the default configuration that will be used as a fallback when skipping the persisted log view lookup. ## 🧪 Testing ### Normal behaviour When Kibana is used as always, we want to keep the current behaviour and retrieve the persisted log view if exists or default to an internally defined one. - Launch the Kibana dev environment with `yarn start` - Navigate to APM/Fleet/Enterprise Search logs - Verify all the usages of the `<LogStream />` component work correctly retrieving the internal views set during the setup lifecycle of the related plugin. This means the LogStream should render the appropriate columns set for the default log view or apply the custom ones defined with an internal log view. ### Serverless behaviour When Kibana is used in serverless mode, we want to skip the lookup for the log view saved object and directly retrieve the log view from the internally defined ones. - Launch the Kibana dev environment with `yarn serverless-oblt` - Navigate to APM/Fleet/Enterprise Search logs - Verify all the usages of the `<LogStream />` component work correctly retrieving the internal views set during the setup lifecycle of the related plugin. --------- Co-authored-by: Marco Antonio Ghiani <marcoantonio.ghiani@elastic.co>
This commit is contained in:
parent
ca1df9ec4f
commit
f1ed91431a
11 changed files with 97 additions and 44 deletions
14
x-pack/plugins/logs_shared/common/plugin_config.ts
Normal file
14
x-pack/plugins/logs_shared/common/plugin_config.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export interface LogsSharedConfig {
|
||||
savedObjects: {
|
||||
logView: {
|
||||
enabled: boolean;
|
||||
};
|
||||
};
|
||||
}
|
29
x-pack/plugins/logs_shared/server/config.ts
Normal file
29
x-pack/plugins/logs_shared/server/config.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { schema, offeringBasedSchema } from '@kbn/config-schema';
|
||||
import { PluginConfigDescriptor } from '@kbn/core/server';
|
||||
import { LogsSharedConfig } from '../common/plugin_config';
|
||||
|
||||
export const configSchema = schema.object({
|
||||
savedObjects: schema.object({
|
||||
logView: schema.object({
|
||||
enabled: offeringBasedSchema({
|
||||
serverless: schema.boolean({
|
||||
defaultValue: false,
|
||||
}),
|
||||
options: {
|
||||
defaultValue: true,
|
||||
},
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
export const config: PluginConfigDescriptor<LogsSharedConfig> = {
|
||||
schema: configSchema,
|
||||
};
|
|
@ -14,6 +14,7 @@ export type {
|
|||
ILogsSharedLogEntriesDomain,
|
||||
} from './lib/domains/log_entries_domain';
|
||||
|
||||
export { config } from './config';
|
||||
export { logViewSavedObjectName } from './saved_objects';
|
||||
|
||||
export function plugin(context: PluginInitializerContext) {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import type { Logger } from '@kbn/logging';
|
||||
import type { IBasePath } from '@kbn/core/server';
|
||||
import { LogsSharedConfig } from '../../common/plugin_config';
|
||||
import type { LogsSharedPluginStartServicesAccessor, UsageCollector } from '../types';
|
||||
import type { KibanaFramework } from './adapters/framework/kibana_framework_adapter';
|
||||
import type { ILogsSharedLogEntriesDomain } from './domains/log_entries_domain';
|
||||
|
@ -17,8 +18,9 @@ export interface LogsSharedDomainLibs {
|
|||
|
||||
export interface LogsSharedBackendLibs extends LogsSharedDomainLibs {
|
||||
basePath: IBasePath;
|
||||
config: LogsSharedConfig;
|
||||
framework: KibanaFramework;
|
||||
getStartServices: LogsSharedPluginStartServicesAccessor;
|
||||
logger: Logger;
|
||||
getUsageCollector: () => UsageCollector;
|
||||
logger: Logger;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import { LogsSharedBackendLibs, LogsSharedDomainLibs } from './lib/logs_shared_t
|
|||
import { LogsSharedLogEntriesDomain } from './lib/domains/log_entries_domain';
|
||||
import { LogsSharedKibanaLogEntriesAdapter } from './lib/adapters/log_entries/kibana_log_entries_adapter';
|
||||
import { LogEntriesService } from './services/log_entries';
|
||||
import { LogsSharedConfig } from '../common/plugin_config';
|
||||
|
||||
export class LogsSharedPlugin
|
||||
implements
|
||||
|
@ -34,11 +35,13 @@ export class LogsSharedPlugin
|
|||
>
|
||||
{
|
||||
private readonly logger: Logger;
|
||||
private config: LogsSharedConfig;
|
||||
private libs!: LogsSharedBackendLibs;
|
||||
private logViews: LogViewsService;
|
||||
private usageCollector: UsageCollector;
|
||||
|
||||
constructor(context: PluginInitializerContext) {
|
||||
constructor(context: PluginInitializerContext<LogsSharedConfig>) {
|
||||
this.config = context.config.get();
|
||||
this.logger = context.logger.get();
|
||||
this.usageCollector = {};
|
||||
|
||||
|
@ -50,8 +53,13 @@ export class LogsSharedPlugin
|
|||
|
||||
const logViews = this.logViews.setup();
|
||||
|
||||
// Register saved objects
|
||||
core.savedObjects.registerType(logViewSavedObjectType);
|
||||
if (this.config.savedObjects.logView.enabled) {
|
||||
// Conditionally register log view saved objects
|
||||
core.savedObjects.registerType(logViewSavedObjectType);
|
||||
} else {
|
||||
// Register a static internal view to use as a fallback when the log view SO is not registered
|
||||
logViews.defineInternalLogView('default', {});
|
||||
}
|
||||
|
||||
const domainLibs: LogsSharedDomainLibs = {
|
||||
logEntries: new LogsSharedLogEntriesDomain(new LogsSharedKibanaLogEntriesAdapter(framework), {
|
||||
|
@ -63,10 +71,11 @@ export class LogsSharedPlugin
|
|||
this.libs = {
|
||||
...domainLibs,
|
||||
basePath: core.http.basePath,
|
||||
config: this.config,
|
||||
framework,
|
||||
getStartServices: () => core.getStartServices(),
|
||||
logger: this.logger,
|
||||
getUsageCollector: () => this.usageCollector,
|
||||
logger: this.logger,
|
||||
};
|
||||
|
||||
// Register server side APIs
|
||||
|
|
|
@ -8,16 +8,13 @@
|
|||
import { logViewsV1 } from '../../../common/http_api';
|
||||
import { LOG_VIEW_URL } from '../../../common/http_api/log_views';
|
||||
import { createValidationFunction } from '../../../common/runtime_types';
|
||||
import type { KibanaFramework } from '../../lib/adapters/framework/kibana_framework_adapter';
|
||||
import type { LogsSharedPluginStartServicesAccessor } from '../../types';
|
||||
import { LogsSharedBackendLibs } from '../../lib/logs_shared_types';
|
||||
|
||||
export const initGetLogViewRoute = ({
|
||||
config,
|
||||
framework,
|
||||
getStartServices,
|
||||
}: {
|
||||
framework: KibanaFramework;
|
||||
getStartServices: LogsSharedPluginStartServicesAccessor;
|
||||
}) => {
|
||||
}: LogsSharedBackendLibs) => {
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
|
@ -39,7 +36,14 @@ export const initGetLogViewRoute = ({
|
|||
const logViewsClient = logViews.getScopedClient(request);
|
||||
|
||||
try {
|
||||
const logView = await logViewsClient.getLogView(logViewId);
|
||||
/**
|
||||
* Two possible paths for retrieving the log view
|
||||
* - if the log view saved object is correctly registered, perform a lookup for retrieving it
|
||||
* - else, skip the saved object lookup and immediately get the internal log view if exists.
|
||||
*/
|
||||
const logView = config.savedObjects.logView.enabled
|
||||
? await logViewsClient.getLogView(logViewId)
|
||||
: await logViewsClient.getInternalLogView(logViewId);
|
||||
|
||||
return response.ok({
|
||||
body: logViewsV1.getLogViewResponsePayloadRT.encode({
|
||||
|
|
|
@ -4,16 +4,15 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { KibanaFramework } from '../../lib/adapters/framework/kibana_framework_adapter';
|
||||
import { LogsSharedPluginStartServicesAccessor } from '../../types';
|
||||
import { LogsSharedBackendLibs } from '../../lib/logs_shared_types';
|
||||
import { initGetLogViewRoute } from './get_log_view';
|
||||
import { initPutLogViewRoute } from './put_log_view';
|
||||
|
||||
export const initLogViewRoutes = (dependencies: {
|
||||
framework: KibanaFramework;
|
||||
getStartServices: LogsSharedPluginStartServicesAccessor;
|
||||
}) => {
|
||||
initGetLogViewRoute(dependencies);
|
||||
initPutLogViewRoute(dependencies);
|
||||
export const initLogViewRoutes = (libs: LogsSharedBackendLibs) => {
|
||||
initGetLogViewRoute(libs);
|
||||
|
||||
// Register the log view update endpoint only when the Saved object is correctly registered
|
||||
if (libs.config.savedObjects.logView.enabled) {
|
||||
initPutLogViewRoute(libs);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -8,16 +8,9 @@
|
|||
import { logViewsV1 } from '../../../common/http_api';
|
||||
import { LOG_VIEW_URL } from '../../../common/http_api/log_views';
|
||||
import { createValidationFunction } from '../../../common/runtime_types';
|
||||
import type { KibanaFramework } from '../../lib/adapters/framework/kibana_framework_adapter';
|
||||
import type { LogsSharedPluginStartServicesAccessor } from '../../types';
|
||||
import { LogsSharedBackendLibs } from '../../lib/logs_shared_types';
|
||||
|
||||
export const initPutLogViewRoute = ({
|
||||
framework,
|
||||
getStartServices,
|
||||
}: {
|
||||
framework: KibanaFramework;
|
||||
getStartServices: LogsSharedPluginStartServicesAccessor;
|
||||
}) => {
|
||||
export const initPutLogViewRoute = ({ framework, getStartServices }: LogsSharedBackendLibs) => {
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
|
|
|
@ -11,6 +11,7 @@ import type { ILogViewsClient } from './types';
|
|||
|
||||
export const createLogViewsClientMock = (): jest.Mocked<ILogViewsClient> => ({
|
||||
getLogView: jest.fn(),
|
||||
getInternalLogView: jest.fn(),
|
||||
getResolvedLogView: jest.fn((logViewReference: LogViewReference) =>
|
||||
Promise.resolve(createResolvedLogViewMock())
|
||||
),
|
||||
|
|
|
@ -64,6 +64,20 @@ export class LogViewsClient implements ILogViewsClient {
|
|||
);
|
||||
}
|
||||
|
||||
public async getInternalLogView(logViewId: string): Promise<LogView> {
|
||||
this.logger.debug(`Trying to load internal log view "${logViewId}"...`);
|
||||
|
||||
const internalLogView = this.internalLogViews.get(logViewId);
|
||||
|
||||
if (!internalLogView) {
|
||||
throw new NotFoundError(
|
||||
`Failed to load internal log view: no view with id "${logViewId}" found.`
|
||||
);
|
||||
}
|
||||
|
||||
return internalLogView;
|
||||
}
|
||||
|
||||
public async getResolvedLogView(logViewReference: LogViewReference): Promise<ResolvedLogView> {
|
||||
const logView = persistedLogViewReferenceRT.is(logViewReference)
|
||||
? await this.getLogView(logViewReference.logViewId)
|
||||
|
@ -125,20 +139,6 @@ export class LogViewsClient implements ILogViewsClient {
|
|||
return getLogViewFromSavedObject(savedObject);
|
||||
}
|
||||
|
||||
private async getInternalLogView(logViewId: string): Promise<LogView> {
|
||||
this.logger.debug(`Trying to load internal log view "${logViewId}"...`);
|
||||
|
||||
const internalLogView = this.internalLogViews.get(logViewId);
|
||||
|
||||
if (!internalLogView) {
|
||||
throw new NotFoundError(
|
||||
`Failed to load internal log view: no view with id "${logViewId}" found.`
|
||||
);
|
||||
}
|
||||
|
||||
return internalLogView;
|
||||
}
|
||||
|
||||
private async getLogViewFromLogsSharedSourceConfiguration(sourceId: string): Promise<LogView> {
|
||||
this.logger.debug(`Trying to load log view from fallback configuration "${sourceId}"...`);
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ export interface LogViewsServiceStart {
|
|||
|
||||
export interface ILogViewsClient {
|
||||
getLogView(logViewId: string): Promise<LogView>;
|
||||
getInternalLogView(logViewId: string): Promise<LogView>;
|
||||
getResolvedLogView(logView: LogViewReference): Promise<ResolvedLogView>;
|
||||
putLogView(logViewId: string, logViewAttributes: Partial<LogViewAttributes>): Promise<LogView>;
|
||||
resolveLogView(logViewId: string, logViewAttributes: LogViewAttributes): Promise<ResolvedLogView>;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue