From 7f33f3b55471002663a4b94e97adc4c4f0753557 Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Tue, 21 Feb 2023 16:39:43 +0000 Subject: [PATCH 01/29] Server changes --- .../inventory_metric_threshold_executor.ts | 5 ++++- .../log_threshold/log_threshold_executor.ts | 2 +- .../log_entries_domain/log_entries_domain.ts | 19 ++++++++++--------- .../lib/log_analysis/log_entry_anomalies.ts | 12 ++++++------ .../log_entry_categories_analysis.ts | 6 +++--- .../routes/log_alerts/chart_preview_data.ts | 4 ++-- .../results/log_entry_category_examples.ts | 6 +++--- .../results/log_entry_examples.ts | 6 +++--- .../server/routes/log_entries/highlights.ts | 6 +++--- .../routes/log_entries/summary_highlights.ts | 4 ++-- .../infra/server/routes/snapshot/index.ts | 5 ++++- .../services/log_views/log_views_client.ts | 8 ++++++-- .../infra/server/services/log_views/types.ts | 3 ++- 13 files changed, 49 insertions(+), 37 deletions(-) diff --git a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts index ffd0a7e56333..f6395ffb6191 100644 --- a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts +++ b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts @@ -150,7 +150,10 @@ export const createInventoryMetricThresholdExecutor = (libs: InfraBackendLibs) = const [, , { logViews }] = await libs.getStartServices(); const logQueryFields: LogQueryFields | undefined = await logViews .getClient(savedObjectsClient, esClient) - .getResolvedLogView(sourceId) + .getResolvedLogView({ + type: 'log-view-reference', + logViewId: sourceId, + }) .then( ({ indices }) => ({ indexPattern: indices }), () => undefined diff --git a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts index 37eb4698ff08..1d0470c244fd 100644 --- a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts +++ b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts @@ -188,7 +188,7 @@ export const createLogThresholdExecutor = (libs: InfraBackendLibs) => const { indices, timestampField, runtimeMappings } = await logViews .getClient(savedObjectsClient, scopedClusterClient.asCurrentUser) - .getResolvedLogView(validatedParams.logView.logViewId); + .getResolvedLogView(validatedParams.logView); if (!isRatioRuleParams(validatedParams)) { await executeAlert( diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts index 1e0daad376a1..fcda9b30b0da 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts @@ -15,6 +15,7 @@ import { LogColumn, LogEntry, LogEntryCursor } from '../../../../common/log_entr import { LogViewColumnConfiguration, logViewFieldColumnConfigurationRT, + LogViewReference, ResolvedLogView, } from '../../../../common/log_views'; import { decodeOrThrow } from '../../../../common/runtime_types'; @@ -66,7 +67,7 @@ export class InfraLogEntriesDomain { public async getLogEntriesAround( requestContext: InfraPluginRequestHandlerContext, - sourceId: string, + logView: LogViewReference, params: LogEntriesAroundParams, columnOverrides?: LogViewColumnConfiguration[] ): Promise<{ entries: LogEntry[]; hasMoreBefore?: boolean; hasMoreAfter?: boolean }> { @@ -84,7 +85,7 @@ export class InfraLogEntriesDomain { const { entries: entriesBefore, hasMoreBefore } = await this.getLogEntries( requestContext, - sourceId, + logView, { startTimestamp, endTimestamp, @@ -110,7 +111,7 @@ export class InfraLogEntriesDomain { const { entries: entriesAfter, hasMoreAfter } = await this.getLogEntries( requestContext, - sourceId, + logView, { startTimestamp, endTimestamp, @@ -126,7 +127,7 @@ export class InfraLogEntriesDomain { public async getLogEntries( requestContext: InfraPluginRequestHandlerContext, - sourceId: string, + logView: LogViewReference, params: LogEntriesParams, columnOverrides?: LogViewColumnConfiguration[] ): Promise<{ entries: LogEntry[]; hasMoreBefore?: boolean; hasMoreAfter?: boolean }> { @@ -134,7 +135,7 @@ export class InfraLogEntriesDomain { const { savedObjects, elasticsearch } = await requestContext.core; const resolvedLogView = await logViews .getClient(savedObjects.client, elasticsearch.client.asCurrentUser) - .getResolvedLogView(sourceId); + .getResolvedLogView(logView); const columnDefinitions = columnOverrides ?? resolvedLogView.columns; const messageFormattingRules = compileFormattingRules( @@ -184,7 +185,7 @@ export class InfraLogEntriesDomain { public async getLogSummaryBucketsBetween( requestContext: InfraPluginRequestHandlerContext, - sourceId: string, + logView: LogViewReference, start: number, end: number, bucketSize: number, @@ -194,7 +195,7 @@ export class InfraLogEntriesDomain { const { savedObjects, elasticsearch } = await requestContext.core; const resolvedLogView = await logViews .getClient(savedObjects.client, elasticsearch.client.asCurrentUser) - .getResolvedLogView(sourceId); + .getResolvedLogView(logView); const dateRangeBuckets = await this.adapter.getContainedLogSummaryBuckets( requestContext, resolvedLogView, @@ -208,7 +209,7 @@ export class InfraLogEntriesDomain { public async getLogSummaryHighlightBucketsBetween( requestContext: InfraPluginRequestHandlerContext, - sourceId: string, + logView: LogViewReference, startTimestamp: number, endTimestamp: number, bucketSize: number, @@ -219,7 +220,7 @@ export class InfraLogEntriesDomain { const { savedObjects, elasticsearch } = await requestContext.core; const resolvedLogView = await logViews .getClient(savedObjects.client, elasticsearch.client.asCurrentUser) - .getResolvedLogView(sourceId); + .getResolvedLogView(logView); const messageFormattingRules = compileFormattingRules( getBuiltinRules(resolvedLogView.messageField) ); diff --git a/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts b/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts index 22bf5466ee3b..5ef734a530de 100644 --- a/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts +++ b/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts @@ -16,7 +16,7 @@ import { logEntryRateJobTypes, Pagination, } from '../../../common/log_analysis'; -import { ResolvedLogView } from '../../../common/log_views'; +import { PersistedLogViewReference, ResolvedLogView } from '../../../common/log_views'; import { startTracingSpan, TracingSpan } from '../../../common/performance_tracing'; import { decodeOrThrow } from '../../../common/runtime_types'; import type { @@ -331,7 +331,7 @@ export async function getLogEntryExamples( context: InfraPluginRequestHandlerContext & { infra: Promise>; }, - sourceId: string, + logView: PersistedLogViewReference, startTime: number, endTime: number, dataset: string, @@ -345,7 +345,7 @@ export async function getLogEntryExamples( const jobId = getJobId( infraContext.spaceId, - sourceId, + logView.logViewId, categoryId != null ? logEntryCategoriesJobTypes[0] : logEntryRateJobTypes[0] ); @@ -370,7 +370,7 @@ export async function getLogEntryExamples( timing: { spans: fetchLogEntryExamplesSpans }, } = await fetchLogEntryExamples( context, - sourceId, + logView, indices, runtimeMappings, timestampField, @@ -397,7 +397,7 @@ export async function fetchLogEntryExamples( context: InfraPluginRequestHandlerContext & { infra: Promise>; }, - sourceId: string, + logView: PersistedLogViewReference, indices: string, runtimeMappings: estypes.MappingRuntimeFields, timestampField: string, @@ -420,7 +420,7 @@ export async function fetchLogEntryExamples( const logEntryCategoriesCountJobId = getJobId( infraContext.spaceId, - sourceId, + logView.logViewId, logEntryCategoriesJobTypes[0] ); diff --git a/x-pack/plugins/infra/server/lib/log_analysis/log_entry_categories_analysis.ts b/x-pack/plugins/infra/server/lib/log_analysis/log_entry_categories_analysis.ts index 9152945002e2..97140f41a1ff 100644 --- a/x-pack/plugins/infra/server/lib/log_analysis/log_entry_categories_analysis.ts +++ b/x-pack/plugins/infra/server/lib/log_analysis/log_entry_categories_analysis.ts @@ -15,7 +15,7 @@ import { logEntryCategoriesJobTypes, } from '../../../common/log_analysis'; import { LogEntryContext } from '../../../common/log_entry'; -import { ResolvedLogView } from '../../../common/log_views'; +import { PersistedLogViewReference, ResolvedLogView } from '../../../common/log_views'; import { startTracingSpan } from '../../../common/performance_tracing'; import { decodeOrThrow } from '../../../common/runtime_types'; import type { MlAnomalyDetectors, MlSystem } from '../../types'; @@ -143,7 +143,7 @@ export async function getLogEntryCategoryExamples( spaceId: string; }; }, - sourceId: string, + logView: PersistedLogViewReference, startTime: number, endTime: number, categoryId: number, @@ -154,7 +154,7 @@ export async function getLogEntryCategoryExamples( const logEntryCategoriesCountJobId = getJobId( context.infra.spaceId, - sourceId, + logView.logViewId, logEntryCategoriesJobTypes[0] ); diff --git a/x-pack/plugins/infra/server/routes/log_alerts/chart_preview_data.ts b/x-pack/plugins/infra/server/routes/log_alerts/chart_preview_data.ts index 95b0c8320559..fbc530397f4e 100644 --- a/x-pack/plugins/infra/server/routes/log_alerts/chart_preview_data.ts +++ b/x-pack/plugins/infra/server/routes/log_alerts/chart_preview_data.ts @@ -29,11 +29,11 @@ export const initGetLogAlertsChartPreviewDataRoute = ({ }, framework.router.handleLegacyErrors(async (requestContext, request, response) => { const { - data: { sourceId, buckets, alertParams }, + data: { logView, buckets, alertParams }, } = request.body; const [, , { logViews }] = await getStartServices(); - const resolvedLogView = await logViews.getScopedClient(request).getResolvedLogView(sourceId); + const resolvedLogView = await logViews.getScopedClient(request).getResolvedLogView(logView); try { const { series } = await getChartPreviewData( diff --git a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_examples.ts b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_examples.ts index b51aed45b7e1..40de491c1673 100644 --- a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_examples.ts +++ b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_examples.ts @@ -34,20 +34,20 @@ export const initGetLogEntryCategoryExamplesRoute = ({ data: { categoryId, exampleCount, - sourceId, + logView, timeRange: { startTime, endTime }, }, } = request.body; const [, , { logViews }] = await getStartServices(); - const resolvedLogView = await logViews.getScopedClient(request).getResolvedLogView(sourceId); + const resolvedLogView = await logViews.getScopedClient(request).getResolvedLogView(logView); try { const infraMlContext = await assertHasInfraMlPlugins(requestContext); const { data: logEntryCategoryExamples, timing } = await getLogEntryCategoryExamples( { infra: await infraMlContext.infra, core: await infraMlContext.core }, - sourceId, + logView, startTime, endTime, categoryId, diff --git a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_examples.ts b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_examples.ts index fb82a2cd90df..23ba1072a60f 100644 --- a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_examples.ts +++ b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_examples.ts @@ -34,21 +34,21 @@ export const initGetLogEntryExamplesRoute = ({ data: { dataset, exampleCount, - sourceId, + logView, timeRange: { startTime, endTime }, categoryId, }, } = request.body; const [, , { logViews }] = await getStartServices(); - const resolvedLogView = await logViews.getScopedClient(request).getResolvedLogView(sourceId); + const resolvedLogView = await logViews.getScopedClient(request).getResolvedLogView(logView); try { const infraMlContext = await assertHasInfraMlPlugins(requestContext); const { data: logEntryExamples, timing } = await getLogEntryExamples( infraMlContext, - sourceId, + logView, startTime, endTime, dataset, diff --git a/x-pack/plugins/infra/server/routes/log_entries/highlights.ts b/x-pack/plugins/infra/server/routes/log_entries/highlights.ts index bb7c615358c0..aa8876951ee6 100644 --- a/x-pack/plugins/infra/server/routes/log_entries/highlights.ts +++ b/x-pack/plugins/infra/server/routes/log_entries/highlights.ts @@ -38,14 +38,14 @@ export const initLogEntriesHighlightsRoute = ({ framework, logEntries }: InfraBa fold(throwErrors(Boom.badRequest), identity) ); - const { startTimestamp, endTimestamp, sourceId, query, size, highlightTerms } = payload; + const { startTimestamp, endTimestamp, logView, query, size, highlightTerms } = payload; let entriesPerHighlightTerm; if ('center' in payload) { entriesPerHighlightTerm = await Promise.all( highlightTerms.map((highlightTerm) => - logEntries.getLogEntriesAround(requestContext, sourceId, { + logEntries.getLogEntriesAround(requestContext, logView, { startTimestamp, endTimestamp, query: parseFilterQuery(query), @@ -65,7 +65,7 @@ export const initLogEntriesHighlightsRoute = ({ framework, logEntries }: InfraBa entriesPerHighlightTerm = await Promise.all( highlightTerms.map((highlightTerm) => - logEntries.getLogEntries(requestContext, sourceId, { + logEntries.getLogEntries(requestContext, logView, { startTimestamp, endTimestamp, query: parseFilterQuery(query), diff --git a/x-pack/plugins/infra/server/routes/log_entries/summary_highlights.ts b/x-pack/plugins/infra/server/routes/log_entries/summary_highlights.ts index ca219cac41e2..206e02bc5727 100644 --- a/x-pack/plugins/infra/server/routes/log_entries/summary_highlights.ts +++ b/x-pack/plugins/infra/server/routes/log_entries/summary_highlights.ts @@ -39,11 +39,11 @@ export const initLogEntriesSummaryHighlightsRoute = ({ logEntriesSummaryHighlightsRequestRT.decode(request.body), fold(throwErrors(Boom.badRequest), identity) ); - const { sourceId, startTimestamp, endTimestamp, bucketSize, query, highlightTerms } = payload; + const { logView, startTimestamp, endTimestamp, bucketSize, query, highlightTerms } = payload; const bucketsPerHighlightTerm = await logEntries.getLogSummaryHighlightBucketsBetween( requestContext, - sourceId, + logView, startTimestamp, endTimestamp, bucketSize, diff --git a/x-pack/plugins/infra/server/routes/snapshot/index.ts b/x-pack/plugins/infra/server/routes/snapshot/index.ts index 27c49032c03f..0c893171b5b6 100644 --- a/x-pack/plugins/infra/server/routes/snapshot/index.ts +++ b/x-pack/plugins/infra/server/routes/snapshot/index.ts @@ -43,7 +43,10 @@ export const initSnapshotRoute = (libs: InfraBackendLibs) => { const [, , { logViews }] = await libs.getStartServices(); const logQueryFields: LogQueryFields | undefined = await logViews .getScopedClient(request) - .getResolvedLogView(snapshotRequest.sourceId) + .getResolvedLogView({ + type: 'log-view-reference', + logViewId: snapshotRequest.sourceId, + }) .then( ({ indices }) => ({ indexPattern: indices }), () => undefined diff --git a/x-pack/plugins/infra/server/services/log_views/log_views_client.ts b/x-pack/plugins/infra/server/services/log_views/log_views_client.ts index 9f43cee871f7..3f832c677071 100644 --- a/x-pack/plugins/infra/server/services/log_views/log_views_client.ts +++ b/x-pack/plugins/infra/server/services/log_views/log_views_client.ts @@ -19,7 +19,9 @@ import { LogIndexReference, LogView, LogViewAttributes, + LogViewReference, LogViewsStaticConfig, + persistedLogViewReferenceRT, ResolvedLogView, resolveLogView, } from '../../../common/log_views'; @@ -65,8 +67,10 @@ export class LogViewsClient implements ILogViewsClient { ); } - public async getResolvedLogView(logViewId: string): Promise { - const logView = await this.getLogView(logViewId); + public async getResolvedLogView(logViewReference: LogViewReference): Promise { + const logView = persistedLogViewReferenceRT.is(logViewReference) + ? await this.getLogView(logViewReference.logViewId) + : logViewReference; const resolvedLogView = await this.resolveLogView(logView.id, logView.attributes); return resolvedLogView; } diff --git a/x-pack/plugins/infra/server/services/log_views/types.ts b/x-pack/plugins/infra/server/services/log_views/types.ts index 50b4e65cf754..b5f91cb3587b 100644 --- a/x-pack/plugins/infra/server/services/log_views/types.ts +++ b/x-pack/plugins/infra/server/services/log_views/types.ts @@ -16,6 +16,7 @@ import { PluginStart as DataViewsServerPluginStart } from '@kbn/data-views-plugi import { LogView, LogViewAttributes, + LogViewReference, LogViewsStaticConfig, ResolvedLogView, } from '../../../common/log_views'; @@ -44,7 +45,7 @@ export interface LogViewsServiceStart { export interface ILogViewsClient { getLogView(logViewId: string): Promise; - getResolvedLogView(logViewId: string): Promise; + getResolvedLogView(logView: LogViewReference): Promise; putLogView(logViewId: string, logViewAttributes: Partial): Promise; resolveLogView(logViewId: string, logViewAttributes: LogViewAttributes): Promise; } From 1869634e76d3ee8c9815a89195c8172adf123a42 Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Tue, 21 Feb 2023 16:40:57 +0000 Subject: [PATCH 02/29] Common changes --- .../common/alerting/logs/log_threshold/types.ts | 4 ++-- .../common/http_api/log_alerts/chart_preview_data.ts | 3 ++- .../log_analysis/results/log_entry_categories.ts | 5 +++-- .../results/log_entry_category_datasets.ts | 6 +++--- .../results/log_entry_category_examples.ts | 5 +++-- .../log_analysis/results/log_entry_examples.ts | 5 +++-- .../infra/common/http_api/log_entries/highlights.ts | 3 ++- .../infra/common/http_api/log_entries/summary.ts | 3 ++- x-pack/plugins/infra/common/log_views/types.ts | 12 +++++++++++- .../search_strategies/log_entries/log_entry.ts | 3 ++- 10 files changed, 33 insertions(+), 16 deletions(-) diff --git a/x-pack/plugins/infra/common/alerting/logs/log_threshold/types.ts b/x-pack/plugins/infra/common/alerting/logs/log_threshold/types.ts index d697770d24a0..c0ad0af7e69f 100644 --- a/x-pack/plugins/infra/common/alerting/logs/log_threshold/types.ts +++ b/x-pack/plugins/infra/common/alerting/logs/log_threshold/types.ts @@ -7,7 +7,7 @@ import { i18n } from '@kbn/i18n'; import * as rt from 'io-ts'; -import { logViewReferenceRT } from '../../../log_views'; +import { persistedLogViewReferenceRT } from '../../../log_views'; import { commonSearchSuccessResponseFieldsRT } from '../../../utils/elasticsearch_runtime_types'; export const LOG_DOCUMENT_COUNT_RULE_TYPE_ID = 'logs.alert.document.count'; @@ -181,7 +181,7 @@ const RequiredRuleParamsRT = rt.type({ count: ThresholdRT, timeUnit: timeUnitRT, timeSize: timeSizeRT, - logView: logViewReferenceRT, // In future, this should be a union of logViewReferenceRT and inlineLogViewRT + logView: persistedLogViewReferenceRT, // Alerts are only compatible with persisted Log Views }); const partialRequiredRuleParamsRT = rt.partial(RequiredRuleParamsRT.props); diff --git a/x-pack/plugins/infra/common/http_api/log_alerts/chart_preview_data.ts b/x-pack/plugins/infra/common/http_api/log_alerts/chart_preview_data.ts index 5f488dd53228..15f0df5222e7 100644 --- a/x-pack/plugins/infra/common/http_api/log_alerts/chart_preview_data.ts +++ b/x-pack/plugins/infra/common/http_api/log_alerts/chart_preview_data.ts @@ -13,6 +13,7 @@ import { timeSizeRT, groupByRT, } from '../../alerting/logs/log_threshold/types'; +import { persistedLogViewReferenceRT } from '../../log_views'; export const LOG_ALERTS_CHART_PREVIEW_DATA_PATH = '/api/infra/log_alerts/chart_preview_data'; @@ -81,7 +82,7 @@ export type GetLogAlertsChartPreviewDataAlertParamsSubset = rt.TypeOf< export const getLogAlertsChartPreviewDataRequestPayloadRT = rt.type({ data: rt.type({ - sourceId: rt.string, + logView: persistedLogViewReferenceRT, alertParams: getLogAlertsChartPreviewDataAlertParamsSubsetRT, buckets: rt.number, }), diff --git a/x-pack/plugins/infra/common/http_api/log_analysis/results/log_entry_categories.ts b/x-pack/plugins/infra/common/http_api/log_analysis/results/log_entry_categories.ts index 308ee41f39d1..85829b7ebb00 100644 --- a/x-pack/plugins/infra/common/http_api/log_analysis/results/log_entry_categories.ts +++ b/x-pack/plugins/infra/common/http_api/log_analysis/results/log_entry_categories.ts @@ -7,6 +7,7 @@ import * as rt from 'io-ts'; +import { persistedLogViewReferenceRT } from '../../../log_views'; import { badRequestErrorRT, forbiddenErrorRT, @@ -38,8 +39,8 @@ export const getLogEntryCategoriesRequestPayloadRT = rt.type({ rt.type({ // the number of categories to fetch categoryCount: rt.number, - // the id of the source configuration - sourceId: rt.string, + // log view + logView: persistedLogViewReferenceRT, // the time range to fetch the categories from timeRange: timeRangeRT, // a list of histograms to create diff --git a/x-pack/plugins/infra/common/http_api/log_analysis/results/log_entry_category_datasets.ts b/x-pack/plugins/infra/common/http_api/log_analysis/results/log_entry_category_datasets.ts index afeda0c1fff2..cb3ad4363f24 100644 --- a/x-pack/plugins/infra/common/http_api/log_analysis/results/log_entry_category_datasets.ts +++ b/x-pack/plugins/infra/common/http_api/log_analysis/results/log_entry_category_datasets.ts @@ -13,7 +13,7 @@ import { timeRangeRT, routeTimingMetadataRT, } from '../../shared'; - +import { persistedLogViewReferenceRT } from '../../../log_views'; export const LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORY_DATASETS_PATH = '/api/infra/log_analysis/results/log_entry_category_datasets'; @@ -23,8 +23,8 @@ export const LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORY_DATASETS_PATH = export const getLogEntryCategoryDatasetsRequestPayloadRT = rt.type({ data: rt.type({ - // the id of the source configuration - sourceId: rt.string, + // log view + logView: persistedLogViewReferenceRT, // the time range to fetch the category datasets from timeRange: timeRangeRT, }), diff --git a/x-pack/plugins/infra/common/http_api/log_analysis/results/log_entry_category_examples.ts b/x-pack/plugins/infra/common/http_api/log_analysis/results/log_entry_category_examples.ts index 256dc4fb97bf..c6c349830e83 100644 --- a/x-pack/plugins/infra/common/http_api/log_analysis/results/log_entry_category_examples.ts +++ b/x-pack/plugins/infra/common/http_api/log_analysis/results/log_entry_category_examples.ts @@ -7,6 +7,7 @@ import * as rt from 'io-ts'; +import { persistedLogViewReferenceRT } from '../../../log_views'; import { badRequestErrorRT, forbiddenErrorRT, @@ -28,8 +29,8 @@ export const getLogEntryCategoryExamplesRequestPayloadRT = rt.type({ categoryId: rt.number, // the number of examples to fetch exampleCount: rt.number, - // the id of the source configuration - sourceId: rt.string, + // log view + logView: persistedLogViewReferenceRT, // the time range to fetch the category examples from timeRange: timeRangeRT, }), diff --git a/x-pack/plugins/infra/common/http_api/log_analysis/results/log_entry_examples.ts b/x-pack/plugins/infra/common/http_api/log_analysis/results/log_entry_examples.ts index 2879991e1857..3aeba9605890 100644 --- a/x-pack/plugins/infra/common/http_api/log_analysis/results/log_entry_examples.ts +++ b/x-pack/plugins/infra/common/http_api/log_analysis/results/log_entry_examples.ts @@ -6,6 +6,7 @@ */ import * as rt from 'io-ts'; +import { persistedLogViewReferenceRT } from '../../../log_views'; import { logEntryExampleRT } from '../../../log_analysis'; import { badRequestErrorRT, @@ -28,8 +29,8 @@ export const getLogEntryExamplesRequestPayloadRT = rt.type({ dataset: rt.string, // the number of examples to fetch exampleCount: rt.number, - // the id of the source configuration - sourceId: rt.string, + // logView + logView: persistedLogViewReferenceRT, // the time range to fetch the log rate examples from timeRange: timeRangeRT, }), diff --git a/x-pack/plugins/infra/common/http_api/log_entries/highlights.ts b/x-pack/plugins/infra/common/http_api/log_entries/highlights.ts index ec3a6b8a2d2e..a863d35d5b49 100644 --- a/x-pack/plugins/infra/common/http_api/log_entries/highlights.ts +++ b/x-pack/plugins/infra/common/http_api/log_entries/highlights.ts @@ -8,12 +8,13 @@ import * as rt from 'io-ts'; import { logEntryCursorRT, logEntryRT } from '../../log_entry'; import { logViewColumnConfigurationRT } from '../../log_views'; +import { logViewReferenceRT } from '../../log_views'; export const LOG_ENTRIES_HIGHLIGHTS_PATH = '/api/log_entries/highlights'; export const logEntriesHighlightsBaseRequestRT = rt.intersection([ rt.type({ - sourceId: rt.string, + logView: logViewReferenceRT, startTimestamp: rt.number, endTimestamp: rt.number, highlightTerms: rt.array(rt.string), diff --git a/x-pack/plugins/infra/common/http_api/log_entries/summary.ts b/x-pack/plugins/infra/common/http_api/log_entries/summary.ts index 64b40004230d..6303c06ac369 100644 --- a/x-pack/plugins/infra/common/http_api/log_entries/summary.ts +++ b/x-pack/plugins/infra/common/http_api/log_entries/summary.ts @@ -6,11 +6,12 @@ */ import * as rt from 'io-ts'; +import { logViewReferenceRT } from '../../log_views'; export const LOG_ENTRIES_SUMMARY_PATH = '/api/log_entries/summary'; export const logEntriesSummaryRequestRT = rt.type({ - sourceId: rt.string, + logView: logViewReferenceRT, startTimestamp: rt.number, endTimestamp: rt.number, bucketSize: rt.number, diff --git a/x-pack/plugins/infra/common/log_views/types.ts b/x-pack/plugins/infra/common/log_views/types.ts index ed42fe82862b..5bf9585bb1c2 100644 --- a/x-pack/plugins/infra/common/log_views/types.ts +++ b/x-pack/plugins/infra/common/log_views/types.ts @@ -103,9 +103,19 @@ export const logViewStatusRT = rt.strict({ }); export type LogViewStatus = rt.TypeOf; -export const logViewReferenceRT = rt.type({ +export const persistedLogViewReferenceRT = rt.type({ logViewId: rt.string, type: rt.literal('log-view-reference'), }); +export type PersistedLogViewReference = rt.TypeOf; + +export const inlineLogViewReferenceRT = rt.type({ + type: rt.literal('log-view-inline'), + id: rt.string, + attributes: logViewAttributesRT, +}); + +export const logViewReferenceRT = rt.union([persistedLogViewReferenceRT, inlineLogViewReferenceRT]); + export type LogViewReference = rt.TypeOf; diff --git a/x-pack/plugins/infra/common/search_strategies/log_entries/log_entry.ts b/x-pack/plugins/infra/common/search_strategies/log_entries/log_entry.ts index 2dc182c4ba0e..6d2a7891264d 100644 --- a/x-pack/plugins/infra/common/search_strategies/log_entries/log_entry.ts +++ b/x-pack/plugins/infra/common/search_strategies/log_entries/log_entry.ts @@ -7,12 +7,13 @@ import * as rt from 'io-ts'; import { logEntryCursorRT, logEntryFieldRT } from '../../log_entry'; +import { logViewReferenceRT } from '../../log_views'; import { searchStrategyErrorRT } from '../common/errors'; export const LOG_ENTRY_SEARCH_STRATEGY = 'infra-log-entry'; export const logEntrySearchRequestParamsRT = rt.type({ - sourceId: rt.string, + logView: logViewReferenceRT, logEntryId: rt.string, }); From 7b58fc9bbda7f4330257311c62a056c162c64b83 Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Tue, 21 Feb 2023 17:18:21 +0000 Subject: [PATCH 03/29] Alter reference at the closest edge to the server --- .../search_strategies/log_entries/log_entries.ts | 4 ++-- .../components/expression_editor/editor.tsx | 8 ++++---- .../hooks/use_chart_preview_data.tsx | 2 +- .../infra/public/containers/logs/log_entry.ts | 5 ++++- .../logs/log_highlights/log_entry_highlights.tsx | 2 +- .../logs/log_highlights/log_summary_highlights.ts | 2 +- .../log_stream/use_fetch_log_entries_after.ts | 2 +- .../log_stream/use_fetch_log_entries_before.ts | 2 +- .../containers/logs/log_summary/log_summary.tsx | 2 +- .../get_log_entry_category_datasets.ts | 2 +- .../get_log_entry_category_examples.ts | 2 +- .../service_calls/get_top_log_entry_categories.ts | 2 +- .../service_calls/get_log_entry_examples.ts | 2 +- .../log_analysis/log_entry_categories_analysis.ts | 8 ++++---- .../log_analysis/results/log_entry_categories.ts | 4 ++-- .../results/log_entry_category_datasets.ts | 4 ++-- .../infra/server/routes/log_entries/summary.ts | 4 ++-- .../log_entries_search_strategy.test.ts | 6 +++--- .../log_entries/log_entries_search_strategy.ts | 2 +- .../log_entries/log_entry_search_strategy.test.ts | 15 ++++++++++++--- .../log_entries/log_entry_search_strategy.ts | 2 +- 21 files changed, 47 insertions(+), 35 deletions(-) diff --git a/x-pack/plugins/infra/common/search_strategies/log_entries/log_entries.ts b/x-pack/plugins/infra/common/search_strategies/log_entries/log_entries.ts index 65bcec8c98e6..f8daaa1b9227 100644 --- a/x-pack/plugins/infra/common/search_strategies/log_entries/log_entries.ts +++ b/x-pack/plugins/infra/common/search_strategies/log_entries/log_entries.ts @@ -13,7 +13,7 @@ import { logEntryCursorRT, logEntryRT, } from '../../log_entry'; -import { logViewColumnConfigurationRT } from '../../log_views'; +import { logViewColumnConfigurationRT, logViewReferenceRT } from '../../log_views'; import { jsonObjectRT } from '../../typed_json'; import { searchStrategyErrorRT } from '../common/errors'; @@ -21,7 +21,7 @@ export const LOG_ENTRIES_SEARCH_STRATEGY = 'infra-log-entries'; const logEntriesBaseSearchRequestParamsRT = rt.intersection([ rt.type({ - sourceId: rt.string, + logView: logViewReferenceRT, startTimestamp: rt.number, endTimestamp: rt.number, size: rt.number, diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx index c6b18bebc98b..73aa5aacb896 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx @@ -13,7 +13,7 @@ import { ForLastExpression, RuleTypeParamsExpressionProps, } from '@kbn/triggers-actions-ui-plugin/public'; -import { LogViewReference, ResolvedLogViewField } from '../../../../../common/log_views'; +import { PersistedLogViewReference, ResolvedLogViewField } from '../../../../../common/log_views'; import { Comparator, isOptimizableGroupedThreshold, @@ -54,7 +54,7 @@ const DEFAULT_BASE_EXPRESSION = { const DEFAULT_FIELD = 'log.level'; -const createLogViewReference = (logViewId: string): LogViewReference => ({ +const createLogViewReference = (logViewId: string): PersistedLogViewReference => ({ logViewId, type: 'log-view-reference', }); @@ -69,7 +69,7 @@ const createDefaultCriterion = ( const createDefaultCountRuleParams = ( availableFields: ResolvedLogViewField[], - logView: LogViewReference + logView: PersistedLogViewReference ): PartialCountRuleParams => ({ ...DEFAULT_BASE_EXPRESSION, logView, @@ -82,7 +82,7 @@ const createDefaultCountRuleParams = ( const createDefaultRatioRuleParams = ( availableFields: ResolvedLogViewField[], - logView: LogViewReference + logView: PersistedLogViewReference ): PartialRatioRuleParams => ({ ...DEFAULT_BASE_EXPRESSION, logView, diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/hooks/use_chart_preview_data.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/hooks/use_chart_preview_data.tsx index 9b9dc501e159..0b99cea2fd7c 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/hooks/use_chart_preview_data.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/hooks/use_chart_preview_data.tsx @@ -73,7 +73,7 @@ export const callGetChartPreviewDataAPI = async ( body: JSON.stringify( getLogAlertsChartPreviewDataRequestPayloadRT.encode({ data: { - sourceId, + logView: { type: 'log-view-reference', logViewId: sourceId }, alertParams, buckets, }, diff --git a/x-pack/plugins/infra/public/containers/logs/log_entry.ts b/x-pack/plugins/infra/public/containers/logs/log_entry.ts index b9f95f3db6ab..958097fc3baa 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_entry.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_entry.ts @@ -30,7 +30,10 @@ export const useLogEntry = ({ return !!logEntryId && !!sourceId ? { request: { - params: logEntrySearchRequestParamsRT.encode({ sourceId, logEntryId }), + params: logEntrySearchRequestParamsRT.encode({ + logView: { type: 'log-view-reference', logViewId: sourceId }, + logEntryId, + }), }, options: { strategy: LOG_ENTRY_SEARCH_STRATEGY }, } diff --git a/x-pack/plugins/infra/public/containers/logs/log_highlights/log_entry_highlights.tsx b/x-pack/plugins/infra/public/containers/logs/log_highlights/log_entry_highlights.tsx index fc1026243a7e..d9f7ab078ae0 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_highlights/log_entry_highlights.tsx +++ b/x-pack/plugins/infra/public/containers/logs/log_highlights/log_entry_highlights.tsx @@ -37,7 +37,7 @@ export const useLogEntryHighlights = ( return await fetchLogEntriesHighlights( { - sourceId, + logView: { type: 'log-view-reference', logViewId: sourceId }, startTimestamp, endTimestamp, center: centerPoint, diff --git a/x-pack/plugins/infra/public/containers/logs/log_highlights/log_summary_highlights.ts b/x-pack/plugins/infra/public/containers/logs/log_highlights/log_summary_highlights.ts index 59abb716f6cb..e994e2a013bb 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_highlights/log_summary_highlights.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_highlights/log_summary_highlights.ts @@ -39,7 +39,7 @@ export const useLogSummaryHighlights = ( return await fetchLogSummaryHighlights( { - sourceId, + logView: { type: 'log-view-reference', logViewId: sourceId }, startTimestamp, endTimestamp, bucketSize, diff --git a/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_after.ts b/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_after.ts index 1e9e1dd48a47..3ee39fbda3d4 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_after.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_after.ts @@ -58,7 +58,7 @@ export const useLogEntriesAfterRequest = ({ highlightPhrase, query: query as JsonObject, size: params.size, - sourceId, + logView: { type: 'log-view-reference', logViewId: sourceId }, startTimestamp, }), }, diff --git a/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_before.ts b/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_before.ts index 6e72fce5a1d2..581d31a28a8c 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_before.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_before.ts @@ -58,7 +58,7 @@ export const useLogEntriesBeforeRequest = ({ highlightPhrase, query: query as JsonObject, size: params.size, - sourceId, + logView: { type: 'log-view-reference', logViewId: sourceId }, startTimestamp: params.extendTo ?? startTimestamp, }), }, diff --git a/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.tsx b/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.tsx index b3e7f8235ace..c4b933ab04cd 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.tsx +++ b/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.tsx @@ -35,7 +35,7 @@ export const useLogSummary = ( pushLogSummaryBucketsArgs([ { - sourceId, + logView: { type: 'log-view-reference', logViewId: sourceId }, startTimestamp, endTimestamp, bucketSize, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_datasets.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_datasets.ts index 51d4a69ada29..34358b983e12 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_datasets.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_datasets.ts @@ -31,7 +31,7 @@ export const callGetLogEntryCategoryDatasetsAPI = async ( body: JSON.stringify( getLogEntryCategoryDatasetsRequestPayloadRT.encode({ data: { - sourceId, + logView: { type: 'log-view-reference', logViewId: sourceId }, timeRange: { startTime, endTime, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_examples.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_examples.ts index 90727fd6f085..e3b99750af71 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_examples.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_examples.ts @@ -35,7 +35,7 @@ export const callGetLogEntryCategoryExamplesAPI = async ( data: { categoryId, exampleCount, - sourceId, + logView: { type: 'log-view-reference', logViewId: sourceId }, timeRange: { startTime, endTime, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_top_log_entry_categories.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_top_log_entry_categories.ts index 9472991e15c6..93e9daf0b9cb 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_top_log_entry_categories.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_top_log_entry_categories.ts @@ -36,7 +36,7 @@ export const callGetTopLogEntryCategoriesAPI = async ( body: JSON.stringify( getLogEntryCategoriesRequestPayloadRT.encode({ data: { - sourceId, + logView: { type: 'log-view-reference', logViewId: sourceId }, timeRange: { startTime, endTime, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_examples.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_examples.ts index 5844e00ebfe4..0e44e5b02feb 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_examples.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_examples.ts @@ -32,7 +32,7 @@ export const callGetLogEntryExamplesAPI = async (requestArgs: RequestArgs, fetch data: { dataset, exampleCount, - sourceId, + logView: { type: 'log-view-reference', logViewId: sourceId }, timeRange: { startTime, endTime, diff --git a/x-pack/plugins/infra/server/lib/log_analysis/log_entry_categories_analysis.ts b/x-pack/plugins/infra/server/lib/log_analysis/log_entry_categories_analysis.ts index 97140f41a1ff..d8eb18e4890b 100644 --- a/x-pack/plugins/infra/server/lib/log_analysis/log_entry_categories_analysis.ts +++ b/x-pack/plugins/infra/server/lib/log_analysis/log_entry_categories_analysis.ts @@ -47,7 +47,7 @@ export async function getTopLogEntryCategories( spaceId: string; }; }, - sourceId: string, + logView: PersistedLogViewReference, startTime: number, endTime: number, categoryCount: number, @@ -59,7 +59,7 @@ export async function getTopLogEntryCategories( const logEntryCategoriesCountJobId = getJobId( context.infra.spaceId, - sourceId, + logView.logViewId, logEntryCategoriesJobTypes[0] ); @@ -119,13 +119,13 @@ export async function getLogEntryCategoryDatasets( spaceId: string; }; }, - sourceId: string, + logView: PersistedLogViewReference, startTime: number, endTime: number ) { const logEntryCategoriesCountJobId = getJobId( context.infra.spaceId, - sourceId, + logView.logViewId, logEntryCategoriesJobTypes[0] ); diff --git a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_categories.ts b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_categories.ts index 6e2e8e8a6c2a..1a484a0662e0 100644 --- a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_categories.ts +++ b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_categories.ts @@ -31,7 +31,7 @@ export const initGetLogEntryCategoriesRoute = ({ framework }: InfraBackendLibs) data: { categoryCount, histograms, - sourceId, + logView, timeRange: { startTime, endTime }, datasets, sort, @@ -43,7 +43,7 @@ export const initGetLogEntryCategoriesRoute = ({ framework }: InfraBackendLibs) const { data: topLogEntryCategories, timing } = await getTopLogEntryCategories( { infra: await infraMlContext.infra }, - sourceId, + logView, startTime, endTime, categoryCount, diff --git a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_datasets.ts b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_datasets.ts index de5ac9dac4b0..92f0cd576a0f 100644 --- a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_datasets.ts +++ b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_datasets.ts @@ -29,7 +29,7 @@ export const initGetLogEntryCategoryDatasetsRoute = ({ framework }: InfraBackend framework.router.handleLegacyErrors(async (requestContext, request, response) => { const { data: { - sourceId, + logView, timeRange: { startTime, endTime }, }, } = request.body; @@ -39,7 +39,7 @@ export const initGetLogEntryCategoryDatasetsRoute = ({ framework }: InfraBackend const { data: logEntryCategoryDatasets, timing } = await getLogEntryCategoryDatasets( { infra: await infraMlContext.infra }, - sourceId, + logView, startTime, endTime ); diff --git a/x-pack/plugins/infra/server/routes/log_entries/summary.ts b/x-pack/plugins/infra/server/routes/log_entries/summary.ts index 3ff0ded8a7c2..dd48c21a590a 100644 --- a/x-pack/plugins/infra/server/routes/log_entries/summary.ts +++ b/x-pack/plugins/infra/server/routes/log_entries/summary.ts @@ -37,11 +37,11 @@ export const initLogEntriesSummaryRoute = ({ framework, logEntries }: InfraBacke logEntriesSummaryRequestRT.decode(request.body), fold(throwErrors(Boom.badRequest), identity) ); - const { sourceId, startTimestamp, endTimestamp, bucketSize, query } = payload; + const { logView, startTimestamp, endTimestamp, bucketSize, query } = payload; const buckets = await logEntries.getLogSummaryBucketsBetween( requestContext, - sourceId, + logView, startTimestamp, endTimestamp, bucketSize, diff --git a/x-pack/plugins/infra/server/services/log_entries/log_entries_search_strategy.test.ts b/x-pack/plugins/infra/server/services/log_entries/log_entries_search_strategy.test.ts index 99579c5a588c..bb21053cfe9d 100644 --- a/x-pack/plugins/infra/server/services/log_entries/log_entries_search_strategy.test.ts +++ b/x-pack/plugins/infra/server/services/log_entries/log_entries_search_strategy.test.ts @@ -57,7 +57,7 @@ describe('LogEntries search strategy', () => { logEntriesSearchStrategy.search( { params: { - sourceId: 'SOURCE_ID', + logView: { type: 'log-view-reference', logViewId: 'SOURCE_ID' }, startTimestamp: 100, endTimestamp: 200, size: 3, @@ -143,7 +143,7 @@ describe('LogEntries search strategy', () => { { id: requestId, params: { - sourceId: 'SOURCE_ID', + logView: { type: 'log-view-reference', logViewId: 'SOURCE_ID' }, startTimestamp: 100, endTimestamp: 200, size: 3, @@ -223,7 +223,7 @@ describe('LogEntries search strategy', () => { { id: logEntriesSearchRequestStateRT.encode({ esRequestId: 'UNKNOWN_ID' }), params: { - sourceId: 'SOURCE_ID', + logView: { type: 'log-view-reference', logViewId: 'SOURCE_ID' }, startTimestamp: 100, endTimestamp: 200, size: 3, diff --git a/x-pack/plugins/infra/server/services/log_entries/log_entries_search_strategy.ts b/x-pack/plugins/infra/server/services/log_entries/log_entries_search_strategy.ts index 81ef319828be..f0f5c6304d61 100644 --- a/x-pack/plugins/infra/server/services/log_entries/log_entries_search_strategy.ts +++ b/x-pack/plugins/infra/server/services/log_entries/log_entries_search_strategy.ts @@ -72,7 +72,7 @@ export const logEntriesSearchStrategyProvider = ({ const request = decodeOrThrow(asyncRequestRT)(rawRequest); const resolvedLogView$ = defer(() => - logViews.getScopedClient(dependencies.request).getResolvedLogView(request.params.sourceId) + logViews.getScopedClient(dependencies.request).getResolvedLogView(request.params.logView) ).pipe(take(1), shareReplay(1)); const messageFormattingRules$ = defer(() => diff --git a/x-pack/plugins/infra/server/services/log_entries/log_entry_search_strategy.test.ts b/x-pack/plugins/infra/server/services/log_entries/log_entry_search_strategy.test.ts index d2d28174490c..19d534512237 100644 --- a/x-pack/plugins/infra/server/services/log_entries/log_entry_search_strategy.test.ts +++ b/x-pack/plugins/infra/server/services/log_entries/log_entry_search_strategy.test.ts @@ -56,7 +56,10 @@ describe('LogEntry search strategy', () => { const response = await lastValueFrom( logEntrySearchStrategy.search( { - params: { sourceId: 'SOURCE_ID', logEntryId: 'LOG_ENTRY_ID' }, + params: { + logView: { type: 'log-view-reference', logViewId: 'SOURCE_ID' }, + logEntryId: 'LOG_ENTRY_ID', + }, }, {}, mockDependencies @@ -141,7 +144,10 @@ describe('LogEntry search strategy', () => { logEntrySearchStrategy.search( { id: requestId, - params: { sourceId: 'SOURCE_ID', logEntryId: 'LOG_ENTRY_ID' }, + params: { + logView: { type: 'log-view-reference', logViewId: 'SOURCE_ID' }, + logEntryId: 'LOG_ENTRY_ID', + }, }, {}, mockDependencies @@ -193,7 +199,10 @@ describe('LogEntry search strategy', () => { const response = logEntrySearchStrategy.search( { id: logEntrySearchRequestStateRT.encode({ esRequestId: 'UNKNOWN_ID' }), - params: { sourceId: 'SOURCE_ID', logEntryId: 'LOG_ENTRY_ID' }, + params: { + logView: { type: 'log-view-reference', logViewId: 'SOURCE_ID' }, + logEntryId: 'LOG_ENTRY_ID', + }, }, {}, mockDependencies diff --git a/x-pack/plugins/infra/server/services/log_entries/log_entry_search_strategy.ts b/x-pack/plugins/infra/server/services/log_entries/log_entry_search_strategy.ts index 714e0b792c61..1d558094e351 100644 --- a/x-pack/plugins/infra/server/services/log_entries/log_entry_search_strategy.ts +++ b/x-pack/plugins/infra/server/services/log_entries/log_entry_search_strategy.ts @@ -48,7 +48,7 @@ export const logEntrySearchStrategyProvider = ({ const request = decodeOrThrow(asyncRequestRT)(rawRequest); const resolvedLogView$ = defer(() => - logViews.getScopedClient(dependencies.request).getResolvedLogView(request.params.sourceId) + logViews.getScopedClient(dependencies.request).getResolvedLogView(request.params.logView) ).pipe(take(1), shareReplay(1)); const recoveredRequest$ = of(request).pipe( From 64ebf99a8317826b0ea07b7503c0aaef63618d91 Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Wed, 22 Feb 2023 00:35:36 +0000 Subject: [PATCH 04/29] Correct spelling --- .../components/expression_editor/editor.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx index 73aa5aacb896..1c38dca829ae 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx @@ -226,11 +226,11 @@ export const Editor: React.FC createLogViewReference(logViewId), [logViewId]); + const logViewReference = useMemo(() => createLogViewReference(logViewId), [logViewId]); const defaultCountAlertParams = useMemo( - () => createDefaultCountRuleParams(supportedFields, logViewReferemnce), - [supportedFields, logViewReferemnce] + () => createDefaultCountRuleParams(supportedFields, logViewReference), + [supportedFields, logViewReference] ); const updateType = useCallback( @@ -238,12 +238,12 @@ export const Editor: React.FC { From fc62aa91d3f3d31ddd1ae5295beb65ac7f7511e9 Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Wed, 22 Feb 2023 01:12:09 +0000 Subject: [PATCH 05/29] Amend further references --- .../log_analysis/results/log_entry_anomalies.ts | 5 +++-- .../results/log_entry_anomalies_datasets.ts | 5 +++-- .../service_calls/get_log_entry_anomalies.ts | 2 +- .../get_log_entry_anomalies_datasets.ts | 2 +- .../lib/log_analysis/log_entry_anomalies.ts | 16 ++++++++-------- .../lib/log_analysis/log_entry_rate_analysis.ts | 4 ++-- .../log_analysis/results/log_entry_anomalies.ts | 4 ++-- .../results/log_entry_anomalies_datasets.ts | 4 ++-- .../apis/metrics_ui/log_entry_highlights.ts | 8 ++++---- .../apis/metrics_ui/log_summary.ts | 2 +- 10 files changed, 27 insertions(+), 25 deletions(-) diff --git a/x-pack/plugins/infra/common/http_api/log_analysis/results/log_entry_anomalies.ts b/x-pack/plugins/infra/common/http_api/log_analysis/results/log_entry_anomalies.ts index b48e5dc3c6d8..b8b39197e5ac 100644 --- a/x-pack/plugins/infra/common/http_api/log_analysis/results/log_entry_anomalies.ts +++ b/x-pack/plugins/infra/common/http_api/log_analysis/results/log_entry_anomalies.ts @@ -7,6 +7,7 @@ import * as rt from 'io-ts'; +import { persistedLogViewReferenceRT } from '../../../log_views'; import { timeRangeRT, routeTimingMetadataRT } from '../../shared'; import { logEntryAnomalyRT, @@ -51,8 +52,8 @@ export type GetLogEntryAnomaliesSuccessResponsePayload = rt.TypeOf< export const getLogEntryAnomaliesRequestPayloadRT = rt.type({ data: rt.intersection([ rt.type({ - // the ID of the source configuration - sourceId: rt.string, + // log view + logView: persistedLogViewReferenceRT, // the time range to fetch the log entry anomalies from timeRange: timeRangeRT, }), diff --git a/x-pack/plugins/infra/common/http_api/log_analysis/results/log_entry_anomalies_datasets.ts b/x-pack/plugins/infra/common/http_api/log_analysis/results/log_entry_anomalies_datasets.ts index 397e0ac936ec..94d1b25e4d9c 100644 --- a/x-pack/plugins/infra/common/http_api/log_analysis/results/log_entry_anomalies_datasets.ts +++ b/x-pack/plugins/infra/common/http_api/log_analysis/results/log_entry_anomalies_datasets.ts @@ -6,6 +6,7 @@ */ import * as rt from 'io-ts'; +import { persistedLogViewReferenceRT } from '../../../log_views'; import { badRequestErrorRT, @@ -23,8 +24,8 @@ export const LOG_ANALYSIS_GET_LOG_ENTRY_ANOMALIES_DATASETS_PATH = export const getLogEntryAnomaliesDatasetsRequestPayloadRT = rt.type({ data: rt.type({ - // the id of the source configuration - sourceId: rt.string, + // log view + logView: persistedLogViewReferenceRT, // the time range to fetch the anomalies datasets from timeRange: timeRangeRT, }), diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies.ts index 5f0f95a3e797..7916cad0f1e0 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies.ts @@ -30,7 +30,7 @@ export const callGetLogEntryAnomaliesAPI = async (requestArgs: RequestArgs, fetc body: JSON.stringify( getLogEntryAnomaliesRequestPayloadRT.encode({ data: { - sourceId, + logView: { type: 'log-view-reference', logViewId: sourceId }, timeRange: { startTime, endTime, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies_datasets.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies_datasets.ts index 9b560845186f..16a8092f290f 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies_datasets.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies_datasets.ts @@ -29,7 +29,7 @@ export const callGetLogEntryAnomaliesDatasetsAPI = async ( body: JSON.stringify( getLogEntryAnomaliesDatasetsRequestPayloadRT.encode({ data: { - sourceId, + logView: { type: 'log-view-reference', logViewId: sourceId }, timeRange: { startTime, endTime, diff --git a/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts b/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts index 5ef734a530de..b17afa68d2d4 100644 --- a/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts +++ b/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts @@ -54,11 +54,11 @@ interface MappedAnomalyHit { async function getCompatibleAnomaliesJobIds( spaceId: string, - sourceId: string, + logViewId: string, mlAnomalyDetectors: MlAnomalyDetectors ) { - const logRateJobId = getJobId(spaceId, sourceId, logEntryRateJobTypes[0]); - const logCategoriesJobId = getJobId(spaceId, sourceId, logEntryCategoriesJobTypes[0]); + const logRateJobId = getJobId(spaceId, logViewId, logEntryRateJobTypes[0]); + const logCategoriesJobId = getJobId(spaceId, logViewId, logEntryCategoriesJobTypes[0]); const jobIds: string[] = []; let jobSpans: TracingSpan[] = []; @@ -99,7 +99,7 @@ export async function getLogEntryAnomalies( context: InfraPluginRequestHandlerContext & { infra: Promise>; }, - sourceId: string, + logView: PersistedLogViewReference, startTime: number, endTime: number, sort: AnomaliesSort, @@ -114,7 +114,7 @@ export async function getLogEntryAnomalies( timing: { spans: jobSpans }, } = await getCompatibleAnomaliesJobIds( infraContext.spaceId, - sourceId, + logView.logViewId, infraContext.mlAnomalyDetectors ); @@ -155,7 +155,7 @@ export async function getLogEntryAnomalies( const logEntryCategoriesCountJobId = getJobId( infraContext.spaceId, - sourceId, + logView.logViewId, logEntryCategoriesJobTypes[0] ); @@ -483,7 +483,7 @@ export async function getLogEntryAnomaliesDatasets( spaceId: string; }; }, - sourceId: string, + logView: PersistedLogViewReference, startTime: number, endTime: number ) { @@ -492,7 +492,7 @@ export async function getLogEntryAnomaliesDatasets( timing: { spans: jobSpans }, } = await getCompatibleAnomaliesJobIds( context.infra.spaceId, - sourceId, + logView.logViewId, context.infra.mlAnomalyDetectors ); diff --git a/x-pack/plugins/infra/server/lib/log_analysis/log_entry_rate_analysis.ts b/x-pack/plugins/infra/server/lib/log_analysis/log_entry_rate_analysis.ts index 7da6298fff76..1e043fed0986 100644 --- a/x-pack/plugins/infra/server/lib/log_analysis/log_entry_rate_analysis.ts +++ b/x-pack/plugins/infra/server/lib/log_analysis/log_entry_rate_analysis.ts @@ -24,13 +24,13 @@ export async function getLogEntryRateBuckets( spaceId: string; }; }, - sourceId: string, + logViewId: string, startTime: number, endTime: number, bucketDuration: number, datasets?: string[] ) { - const logRateJobId = getJobId(context.infra.spaceId, sourceId, 'log-entry-rate'); + const logRateJobId = getJobId(context.infra.spaceId, logViewId, 'log-entry-rate'); let mlModelPlotBuckets: LogRateModelPlotBucket[] = []; let afterLatestBatchKey: CompositeTimestampPartitionKey | undefined; diff --git a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_anomalies.ts b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_anomalies.ts index dd6254cf560e..13df82f8fe34 100644 --- a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_anomalies.ts +++ b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_anomalies.ts @@ -31,7 +31,7 @@ export const initGetLogEntryAnomaliesRoute = ({ framework }: InfraBackendLibs) = framework.router.handleLegacyErrors(async (requestContext, request, response) => { const { data: { - sourceId, + logView, timeRange: { startTime, endTime }, sort: sortParam, pagination: paginationParam, @@ -51,7 +51,7 @@ export const initGetLogEntryAnomaliesRoute = ({ framework }: InfraBackendLibs) = timing, } = await getLogEntryAnomalies( infraMlContext, - sourceId, + logView, startTime, endTime, sort, diff --git a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_anomalies_datasets.ts b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_anomalies_datasets.ts index 1d1f620063b2..5f7aec90376a 100644 --- a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_anomalies_datasets.ts +++ b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_anomalies_datasets.ts @@ -29,7 +29,7 @@ export const initGetLogEntryAnomaliesDatasetsRoute = ({ framework }: InfraBacken framework.router.handleLegacyErrors(async (requestContext, request, response) => { const { data: { - sourceId, + logView, timeRange: { startTime, endTime }, }, } = request.body; @@ -39,7 +39,7 @@ export const initGetLogEntryAnomaliesDatasetsRoute = ({ framework }: InfraBacken const { datasets, timing } = await getLogEntryAnomaliesDatasets( { infra: await infraMlContext.infra }, - sourceId, + logView, startTime, endTime ); diff --git a/x-pack/test/api_integration/apis/metrics_ui/log_entry_highlights.ts b/x-pack/test/api_integration/apis/metrics_ui/log_entry_highlights.ts index aba182274c9a..2e328e91f8c2 100644 --- a/x-pack/test/api_integration/apis/metrics_ui/log_entry_highlights.ts +++ b/x-pack/test/api_integration/apis/metrics_ui/log_entry_highlights.ts @@ -54,7 +54,7 @@ export default function ({ getService }: FtrProviderContext) { .set(COMMON_HEADERS) .send( logEntriesHighlightsRequestRT.encode({ - sourceId: 'default', + logView: { type: 'log-view-reference', logViewId: 'default' }, startTimestamp: KEY_BEFORE_START.time, endTimestamp: KEY_AFTER_END.time, highlightTerms: ['some string that does not exist'], @@ -82,7 +82,7 @@ export default function ({ getService }: FtrProviderContext) { .set(COMMON_HEADERS) .send( logEntriesHighlightsRequestRT.encode({ - sourceId: 'default', + logView: { type: 'log-view-reference', logViewId: 'default' }, startTimestamp: KEY_BEFORE_START.time, endTimestamp: KEY_AFTER_END.time, highlightTerms: ['message of document 0'], @@ -130,7 +130,7 @@ export default function ({ getService }: FtrProviderContext) { .set(COMMON_HEADERS) .send( logEntriesHighlightsRequestRT.encode({ - sourceId: 'default', + logView: { type: 'log-view-reference', logViewId: 'default' }, startTimestamp: KEY_BEFORE_START.time, endTimestamp: KEY_AFTER_END.time, highlightTerms: ['generate_test_data/simple_logs'], @@ -166,7 +166,7 @@ export default function ({ getService }: FtrProviderContext) { .set(COMMON_HEADERS) .send( logEntriesHighlightsRequestRT.encode({ - sourceId: 'default', + logView: { type: 'log-view-reference', logViewId: 'default' }, startTimestamp: KEY_BEFORE_START.time, endTimestamp: KEY_AFTER_END.time, query: JSON.stringify({ diff --git a/x-pack/test/api_integration/apis/metrics_ui/log_summary.ts b/x-pack/test/api_integration/apis/metrics_ui/log_summary.ts index 4ac098f95764..3ccfc4c267c7 100644 --- a/x-pack/test/api_integration/apis/metrics_ui/log_summary.ts +++ b/x-pack/test/api_integration/apis/metrics_ui/log_summary.ts @@ -49,7 +49,7 @@ export default function ({ getService }: FtrProviderContext) { .set(COMMON_HEADERS) .send( logEntriesSummaryRequestRT.encode({ - sourceId: 'default', + logView: { type: 'log-view-reference', logViewId: 'default' }, startTimestamp, endTimestamp, bucketSize, From 9f1ababda196141b5eff749996cf44d407770e83 Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Wed, 22 Feb 2023 01:22:07 +0000 Subject: [PATCH 06/29] Amend Jest tests --- .../public/containers/logs/log_summary/log_summary.test.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.test.tsx b/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.test.tsx index 25e02101984f..fe02367e4b1f 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.test.tsx +++ b/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.test.tsx @@ -62,7 +62,7 @@ describe('useLogSummary hook', () => { expect(fetchLogSummaryMock).toHaveBeenCalledTimes(1); expect(fetchLogSummaryMock).toHaveBeenLastCalledWith( expect.objectContaining({ - sourceId: 'INITIAL_SOURCE_ID', + logView: { logViewId: 'INITIAL_SOURCE_ID', type: 'log-view-reference' }, }), expect.anything() ); @@ -74,7 +74,7 @@ describe('useLogSummary hook', () => { expect(fetchLogSummaryMock).toHaveBeenCalledTimes(2); expect(fetchLogSummaryMock).toHaveBeenLastCalledWith( expect.objectContaining({ - sourceId: 'CHANGED_SOURCE_ID', + logView: { logViewId: 'CHANGED_SOURCE_ID', type: 'log-view-reference' }, }), expect.anything() ); From 108d9f85970ecb921d4add278152f980953dbc53 Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Thu, 23 Feb 2023 17:58:03 +0000 Subject: [PATCH 07/29] WIP: Adding URL handling to machine --- .../infra/public/hooks/use_log_view.ts | 15 ++- .../log_view_state/src/defaults.ts | 8 ++ .../log_view_state/src/index.ts | 2 + .../log_view_state/src/state_machine.ts | 21 ++++- .../log_view_state/src/types.ts | 5 + .../src/url_state_storage_service.ts | 92 +++++++++++++++++++ 6 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 x-pack/plugins/infra/public/observability_logs/log_view_state/src/defaults.ts create mode 100644 x-pack/plugins/infra/public/observability_logs/log_view_state/src/url_state_storage_service.ts diff --git a/x-pack/plugins/infra/public/hooks/use_log_view.ts b/x-pack/plugins/infra/public/hooks/use_log_view.ts index 8afc517dbfca..c01b96955717 100644 --- a/x-pack/plugins/infra/public/hooks/use_log_view.ts +++ b/x-pack/plugins/infra/public/hooks/use_log_view.ts @@ -13,9 +13,12 @@ import { LogViewAttributes } from '../../common/log_views'; import { createLogViewNotificationChannel, createLogViewStateMachine, + DEFAULT_LOG_VIEW, } from '../observability_logs/log_view_state'; import type { ILogViewsClient } from '../services/log_views'; import { isDevMode } from '../utils/dev_mode'; +import { useKbnUrlStateStorageFromRouterContext } from '../utils/kbn_url_state_context'; +import { useKibanaContextForPlugin } from './use_kibana'; export const useLogView = ({ logViewId, @@ -26,16 +29,26 @@ export const useLogView = ({ logViews: ILogViewsClient; useDevTools?: boolean; }) => { + const { + services: { + notifications: { toasts: toastsService }, + }, + } = useKibanaContextForPlugin(); + + const urlStateStorage = useKbnUrlStateStorageFromRouterContext(); + const [logViewStateNotifications] = useState(() => createLogViewNotificationChannel()); const logViewStateService = useInterpret( () => createLogViewStateMachine({ initialContext: { - logViewId, + logView: DEFAULT_LOG_VIEW, }, logViews, notificationChannel: logViewStateNotifications, + toastsService, + urlStateStorage, }), { devTools: useDevTools, diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/defaults.ts b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/defaults.ts new file mode 100644 index 000000000000..e19864398fa9 --- /dev/null +++ b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/defaults.ts @@ -0,0 +1,8 @@ +/* + * 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 const DEFAULT_LOG_VIEW = { type: 'log-view-reference', logViewId: 'default' }; diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/index.ts b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/index.ts index 82e7b9fbd279..5dcfedc6faa4 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/index.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/index.ts @@ -8,3 +8,5 @@ export { createLogViewNotificationChannel, type LogViewNotificationEvent } from './notifications'; export * from './state_machine'; export * from './types'; +export * from './defaults'; +export * from './url_state_storage_service'; diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts index aa94ebcce6a0..a83c619dde68 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts @@ -5,6 +5,8 @@ * 2.0. */ +import { IToasts } from '@kbn/core/public'; +import { IKbnUrlStateStorage } from '@kbn/kibana-utils-plugin/public'; import { catchError, from, map, of, throwError } from 'rxjs'; import { createMachine, actions, assign } from 'xstate'; import { ILogViewsClient } from '../../../services/log_views'; @@ -20,6 +22,7 @@ import { LogViewEvent, LogViewTypestate, } from './types'; +import { initializeFromUrl } from './url_state_storage_service'; export const createPureLogViewStateMachine = (initialContext: LogViewContextWithId) => /** @xstate-layout N4IgpgJg5mDOIC5QBkD2UBqBLMB3AxMgPIDiA+hgJICiA6mZQCJkDCAEgIIByJ1jA2gAYAuolAAHVLCwAXLKgB2YkAA9EAFkEBmAHQAmAGwB2dQYAcAVkGmAjGYMAaEAE9EAWi3qjO9WcGCLIzMbLWMLAE4AX0inNEwcAgBVAAVGDgAVaiFRJBBJaTlFZTUEG20DfUEDLUtwg3CbdXUtJ1cEDz11HSMLTzMagwtjAOjY9Gw8HQBXBSxZuQBDABssAC9IfGzlfNl5JVySz3CdGwMwrRsbCK0a1sQyiqNDCMEjcK09QT8LUZA4idwOiWqAWEDmUEIRA4jEoPDIAGVEiwWNQ+HwtrkdoV9qASkZPDoLnpwmZniTgmY7ghSTorP5fFo6lorHobL9-gkgSCwQoIcRobDyAAxDiUZDokTbKS7IoHRBWMzdT4vCxDPQ3PRUvTqnThcL+OoWVmdU7qdnjTkAJzgqCWADdwfgAErUeFEZCJdKUIhcMgisUSnISaXY4qIcm0y6XJ5mdR6Iw2IxanV6g2DY3qRPm+KTa2wW0O3nO13uz3e32I5GoxiBqUFPZh0ra7z9S6CBo9G4tFyIGl06z9JlWOzZgE6ADGAAswOOANbg+EyBYyKawfDsagsADSgoR6QyiXhftF4oEksxIYbctKFhCOksxjsF3CQSTPYQ2t0qfb6ZsJqMo6clOM7zryi7Lqu65sJuO5wvC+7pIeCJIiiaJnkGeSXrKuL3K+3RnJ8eqGPGgRUm8PjEvq5jBKE6oATEfwWrmNr2hsLr8swxDkFQdAYsG9bYao9x6BYXSkjcBrqp8RiOO+Hg6NUAzhEM6gkvUNRmgxHKTMCoLgkKCxYEsbHUOkToAJp8ZhAk4kJCCMl0MlPKqoS+O2b5tJ0jynGc+KCHowR1HogHMfmSxTNiBlGSZZmWee-EyrZJT6jYCkfARVxaDJsZaqY3Q+cYWj+YFBghYCwFzguS4rrAUXGRAxaxVZWJXjhpSZt4ng2O84Qie2njdp5eUJmchXFd1BjBVpTGAlM4gQMujopGkXpwv6p7NVhSXCV43SqfU2qqYYWVUm42rHAOcb1L12gsmV0zzYtRbLRku6VqhNboXWiWNi+3j6spfSDB84TqKdZjHAY-kRE05hfMSbLTTms2PXIvJ1SZHFkFxFA0LQm02Y2xiKsyJJNPqNxQ5Scl-hYOgBEVt6fsYqn0QxCioBAcDKNpuDfaG14hIq9T2FcjSWEEgync0XQkv4k1ZQYjQRD8SNjjMcy7MsayQPzrV2XYFQi0rt6+IE9gWFSZR09qZzNN1fRDFEaucrpPJQHrgklF4ej0yJInKRDpIeYg5hKoMZhvGUbxFfRYzIzoeYFuCnvbQgcs+Gb+oib4x1UsE4e9PYZzWLe90VaBUDgTVqeNmLF1GlU9S+FDRpkcLKkhO8Vwkqr8djknrEQLX16spcCl0poRoGE0NztxP1QvmLARPM7-eu9y+mGfVI9tV4RuXOqgSJsSIlUrRJyr8fdT+FUfeMQng8RXsGPDxehPXkvlTVAmQy9Le59JqX2JPiF8gxMyR3LtOSqYFqqrlfrvA2jcfAWH6IYGePtwjnwiCcYqHxbCqk0Jpdekw5oLTRh7d+P1P5nAUp8Dq6hRJeFVKdTovtSR2CaD+TMTQzD3TIU9KACCqECzauLOmYtiZZRqAOVhxJ7ysljCEGSTQ4xs0iEAA */ @@ -33,7 +36,18 @@ export const createPureLogViewStateMachine = (initialContext: LogViewContextWith states: { uninitialized: { always: { - target: 'loading', + target: 'initializingFromUrl', + }, + }, + initializingFromUrl: { + on: { + INITIALIZED_FROM_URL: { + target: 'loading', + actions: ['storeLogViewReference'], + }, + }, + invoke: { + src: 'initializeFromUrl', }, }, loading: { @@ -202,12 +216,16 @@ export interface LogViewStateMachineDependencies { initialContext: LogViewContextWithId; logViews: ILogViewsClient; notificationChannel?: NotificationChannel; + toastsService: IToasts; + urlStateStorage: IKbnUrlStateStorage; } export const createLogViewStateMachine = ({ initialContext, logViews, notificationChannel, + toastsService, + urlStateStorage, }: LogViewStateMachineDependencies) => createPureLogViewStateMachine(initialContext).withConfig({ actions: @@ -225,6 +243,7 @@ export const createLogViewStateMachine = ({ } : {}, services: { + initializeFromUrl: initializeFromUrl({ toastsService, urlStateStorage }), loadLogView: (context) => from( 'logViewId' in context diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/types.ts b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/types.ts index 3a997748c5c3..445345d668da 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/types.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/types.ts @@ -9,6 +9,7 @@ import type { ActorRef } from 'xstate'; import type { LogView, LogViewAttributes, + LogViewReference, LogViewStatus, ResolvedLogView, } from '../../../../common/log_views'; @@ -89,6 +90,10 @@ export type LogViewEvent = type: 'LOG_VIEW_ID_CHANGED'; logViewId: string; } + | { + type: 'INITIALIZED_FROM_URL'; + logView: LogViewReference | null; + } | { type: 'LOADING_SUCCEEDED'; logView: LogView; diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/url_state_storage_service.ts b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/url_state_storage_service.ts new file mode 100644 index 000000000000..705901f6081e --- /dev/null +++ b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/url_state_storage_service.ts @@ -0,0 +1,92 @@ +/* + * 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 * as rt from 'io-ts'; +import { IToasts } from '@kbn/core/public'; +import { IKbnUrlStateStorage, withNotifyOnErrors } from '@kbn/kibana-utils-plugin/public'; +import { InvokeCreator } from 'xstate'; +import * as Either from 'fp-ts/lib/Either'; +import { identity, pipe } from 'fp-ts/lib/function'; +import { createPlainError, formatErrors } from '../../../../common/runtime_types'; +import { logViewReferenceRT, PersistedLogViewReference } from '../../../../common/log_views'; +import { LogViewContext, LogViewEvent } from './types'; + +const defaultLogViewKey = 'logView'; +const defaultLegacySourceIdKey = 'sourceId'; + +interface LogViewUrlStateDependencies { + logViewKey?: string; + sourceIdKey?: string; + savedQueryIdKey?: string; + toastsService: IToasts; + urlStateStorage: IKbnUrlStateStorage; +} + +export const initializeFromUrl = + ({ + logViewKey = defaultLogViewKey, + sourceIdKey = defaultLegacySourceIdKey, + toastsService, + urlStateStorage, + }: LogViewUrlStateDependencies): InvokeCreator => + (_context, _event) => + (send) => { + const logViewQueryValueFromUrl = urlStateStorage.get(logViewKey); + const logViewQueryE = decodeLogViewQueryValueFromUrl(logViewQueryValueFromUrl); + + const legacySourceIdQueryValueFromUrl = urlStateStorage.get(sourceIdKey); + const sourceIdQueryE = decodeSourceIdQueryValueFromUrl(legacySourceIdQueryValueFromUrl); + + if (Either.isLeft(logViewQueryE) || Either.isLeft(sourceIdQueryE)) { + withNotifyOnErrors(toastsService).onGetError( + createPlainError( + formatErrors([ + ...(Either.isLeft(logViewQueryE) ? logViewQueryE.left : []), + ...(Either.isLeft(sourceIdQueryE) ? sourceIdQueryE.left : []), + ]) + ) + ); + + send({ + type: 'INITIALIZED_FROM_URL', + logView: null, + }); + } else { + send({ + type: 'INITIALIZED_FROM_URL', + logView: pipe( + // Via the legacy sourceId key + pipe( + sourceIdQueryE.right, + Either.fromNullable(null), + Either.map(convertSourceIdToReference) + ), + // Via the logView key + Either.alt(() => pipe(logViewQueryE.right, Either.fromNullable(null))), + Either.fold(identity, identity) + ), + }); + } + }; + +const logViewStateInUrlRT = rt.union([logViewReferenceRT, rt.undefined]); +const sourceIdStateInUrl = rt.union([rt.string, rt.undefined]); + +const decodeLogViewQueryValueFromUrl = (queryValueFromUrl: unknown) => { + return logViewStateInUrlRT.decode(queryValueFromUrl); +}; + +const decodeSourceIdQueryValueFromUrl = (queryValueFromUrl: unknown) => { + return sourceIdStateInUrl.decode(queryValueFromUrl); +}; + +const convertSourceIdToReference = (sourceId: string): PersistedLogViewReference => { + return { + type: 'log-view-reference' as const, + logViewId: sourceId, + }; +}; From 2cef2d4efbf455554482d68e379bf7529d8e8ab3 Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Wed, 1 Mar 2023 16:17:30 +0000 Subject: [PATCH 08/29] WIP: Amending UI code --- .../plugins/infra/common/log_views/types.ts | 1 + .../infra/public/hooks/use_log_view.ts | 2 +- .../log_view_state/src/defaults.ts | 2 +- .../log_view_state/src/state_machine.ts | 20 ++++++------- .../log_view_state/src/types.ts | 28 ++++++++++--------- .../src/url_state_storage_service.ts | 8 +++--- .../services/log_views/log_views_client.ts | 16 +++++++++-- .../infra/public/services/log_views/types.ts | 5 ++-- 8 files changed, 48 insertions(+), 34 deletions(-) diff --git a/x-pack/plugins/infra/common/log_views/types.ts b/x-pack/plugins/infra/common/log_views/types.ts index 5bf9585bb1c2..ca6dd95330f8 100644 --- a/x-pack/plugins/infra/common/log_views/types.ts +++ b/x-pack/plugins/infra/common/log_views/types.ts @@ -14,6 +14,7 @@ export interface LogViewsStaticConfig { export const logViewOriginRT = rt.keyof({ stored: null, internal: null, + inline: null, 'infra-source-stored': null, 'infra-source-internal': null, 'infra-source-fallback': null, diff --git a/x-pack/plugins/infra/public/hooks/use_log_view.ts b/x-pack/plugins/infra/public/hooks/use_log_view.ts index c01b96955717..7f65a60f6965 100644 --- a/x-pack/plugins/infra/public/hooks/use_log_view.ts +++ b/x-pack/plugins/infra/public/hooks/use_log_view.ts @@ -43,7 +43,7 @@ export const useLogView = ({ () => createLogViewStateMachine({ initialContext: { - logView: DEFAULT_LOG_VIEW, + logViewReference: DEFAULT_LOG_VIEW, }, logViews, notificationChannel: logViewStateNotifications, diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/defaults.ts b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/defaults.ts index e19864398fa9..6f00c40a214b 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/defaults.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/defaults.ts @@ -5,4 +5,4 @@ * 2.0. */ -export const DEFAULT_LOG_VIEW = { type: 'log-view-reference', logViewId: 'default' }; +export const DEFAULT_LOG_VIEW = { type: 'log-view-reference' as const, logViewId: 'default' }; diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts index a83c619dde68..e64c9a963fcd 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts @@ -15,8 +15,8 @@ import { LogViewNotificationEvent, logViewNotificationEventSelectors } from './n import { LogViewContext, LogViewContextWithError, - LogViewContextWithId, LogViewContextWithLogView, + LogViewContextWithReference, LogViewContextWithResolvedLogView, LogViewContextWithStatus, LogViewEvent, @@ -24,7 +24,7 @@ import { } from './types'; import { initializeFromUrl } from './url_state_storage_service'; -export const createPureLogViewStateMachine = (initialContext: LogViewContextWithId) => +export const createPureLogViewStateMachine = (initialContext: LogViewContextWithReference) => /** @xstate-layout N4IgpgJg5mDOIC5QBkD2UBqBLMB3AxMgPIDiA+hgJICiA6mZQCJkDCAEgIIByJ1jA2gAYAuolAAHVLCwAXLKgB2YkAA9EAFkEBmAHQAmAGwB2dQYAcAVkGmAjGYMAaEAE9EAWi3qjO9WcGCLIzMbLWMLAE4AX0inNEwcAgBVAAVGDgAVaiFRJBBJaTlFZTUEG20DfUEDLUtwg3CbdXUtJ1cEDz11HSMLTzMagwtjAOjY9Gw8HQBXBSxZuQBDABssAC9IfGzlfNl5JVySz3CdGwMwrRsbCK0a1sQyiqNDCMEjcK09QT8LUZA4idwOiWqAWEDmUEIRA4jEoPDIAGVEiwWNQ+HwtrkdoV9qASkZPDoLnpwmZniTgmY7ghSTorP5fFo6lorHobL9-gkgSCwQoIcRobDyAAxDiUZDokTbKS7IoHRBWMzdT4vCxDPQ3PRUvTqnThcL+OoWVmdU7qdnjTkAJzgqCWADdwfgAErUeFEZCJdKUIhcMgisUSnISaXY4qIcm0y6XJ5mdR6Iw2IxanV6g2DY3qRPm+KTa2wW0O3nO13uz3e32I5GoxiBqUFPZh0ra7z9S6CBo9G4tFyIGl06z9JlWOzZgE6ADGAAswOOANbg+EyBYyKawfDsagsADSgoR6QyiXhftF4oEksxIYbctKFhCOksxjsF3CQSTPYQ2t0qfb6ZsJqMo6clOM7zryi7Lqu65sJuO5wvC+7pIeCJIiiaJnkGeSXrKuL3K+3RnJ8eqGPGgRUm8PjEvq5jBKE6oATEfwWrmNr2hsLr8swxDkFQdAYsG9bYao9x6BYXSkjcBrqp8RiOO+Hg6NUAzhEM6gkvUNRmgxHKTMCoLgkKCxYEsbHUOkToAJp8ZhAk4kJCCMl0MlPKqoS+O2b5tJ0jynGc+KCHowR1HogHMfmSxTNiBlGSZZmWee-EyrZJT6jYCkfARVxaDJsZaqY3Q+cYWj+YFBghYCwFzguS4rrAUXGRAxaxVZWJXjhpSZt4ng2O84Qie2njdp5eUJmchXFd1BjBVpTGAlM4gQMujopGkXpwv6p7NVhSXCV43SqfU2qqYYWVUm42rHAOcb1L12gsmV0zzYtRbLRku6VqhNboXWiWNi+3j6spfSDB84TqKdZjHAY-kRE05hfMSbLTTms2PXIvJ1SZHFkFxFA0LQm02Y2xiKsyJJNPqNxQ5Scl-hYOgBEVt6fsYqn0QxCioBAcDKNpuDfaG14hIq9T2FcjSWEEgync0XQkv4k1ZQYjQRD8SNjjMcy7MsayQPzrV2XYFQi0rt6+IE9gWFSZR09qZzNN1fRDFEaucrpPJQHrgklF4ej0yJInKRDpIeYg5hKoMZhvGUbxFfRYzIzoeYFuCnvbQgcs+Gb+oib4x1UsE4e9PYZzWLe90VaBUDgTVqeNmLF1GlU9S+FDRpkcLKkhO8Vwkqr8djknrEQLX16spcCl0poRoGE0NztxP1QvmLARPM7-eu9y+mGfVI9tV4RuXOqgSJsSIlUrRJyr8fdT+FUfeMQng8RXsGPDxehPXkvlTVAmQy9Le59JqX2JPiF8gxMyR3LtOSqYFqqrlfrvA2jcfAWH6IYGePtwjnwiCcYqHxbCqk0Jpdekw5oLTRh7d+P1P5nAUp8Dq6hRJeFVKdTovtSR2CaD+TMTQzD3TIU9KACCqECzauLOmYtiZZRqAOVhxJ7ysljCEGSTQ4xs0iEAA */ createMachine( { @@ -169,11 +169,11 @@ export const createPureLogViewStateMachine = (initialContext: LogViewContextWith notifyLoadingStarted: actions.pure(() => undefined), notifyLoadingSucceeded: actions.pure(() => undefined), notifyLoadingFailed: actions.pure(() => undefined), - storeLogViewId: assign((context, event) => - 'logViewId' in event + storeLogViewReference: assign((context, event) => + 'logViewReference' in event && event.logViewReference !== null ? ({ - logViewId: event.logViewId, - } as LogViewContextWithId) + logViewReference: event.logViewReference, + } as LogViewContextWithReference) : {} ), storeLogView: assign((context, event) => @@ -213,7 +213,7 @@ export const createPureLogViewStateMachine = (initialContext: LogViewContextWith ); export interface LogViewStateMachineDependencies { - initialContext: LogViewContextWithId; + initialContext: LogViewContextWithReference; logViews: ILogViewsClient; notificationChannel?: NotificationChannel; toastsService: IToasts; @@ -246,9 +246,9 @@ export const createLogViewStateMachine = ({ initializeFromUrl: initializeFromUrl({ toastsService, urlStateStorage }), loadLogView: (context) => from( - 'logViewId' in context - ? logViews.getLogView(context.logViewId) - : throwError(() => new Error('Failed to load log view: No id found in context.')) + 'logViewReference' in context + ? logViews.getLogView(context.logViewReference) + : throwError(() => new Error('Failed to load log view')) ).pipe( map( (logView): LogViewEvent => ({ diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/types.ts b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/types.ts index 445345d668da..16d298532a26 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/types.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/types.ts @@ -16,8 +16,8 @@ import type { import { type NotificationChannel } from '../../xstate_helpers'; import { type LogViewNotificationEvent } from './notifications'; -export interface LogViewContextWithId { - logViewId: string; +export interface LogViewContextWithReference { + logViewReference: LogViewReference; } export interface LogViewContextWithLogView { @@ -39,46 +39,48 @@ export interface LogViewContextWithError { export type LogViewTypestate = | { value: 'uninitialized'; - context: LogViewContextWithId; + context: LogViewContextWithReference; } | { value: 'loading'; - context: LogViewContextWithId; + context: LogViewContextWithReference; } | { value: 'resolving'; - context: LogViewContextWithId & LogViewContextWithLogView; + context: LogViewContextWithReference & LogViewContextWithLogView; } | { value: 'checkingStatus'; - context: LogViewContextWithId & LogViewContextWithLogView & LogViewContextWithResolvedLogView; + context: LogViewContextWithReference & + LogViewContextWithLogView & + LogViewContextWithResolvedLogView; } | { value: 'resolved'; - context: LogViewContextWithId & + context: LogViewContextWithReference & LogViewContextWithLogView & LogViewContextWithResolvedLogView & LogViewContextWithStatus; } | { value: 'updating'; - context: LogViewContextWithId; + context: LogViewContextWithReference; } | { value: 'loadingFailed'; - context: LogViewContextWithId & LogViewContextWithError; + context: LogViewContextWithReference & LogViewContextWithError; } | { value: 'updatingFailed'; - context: LogViewContextWithId & LogViewContextWithError; + context: LogViewContextWithReference & LogViewContextWithError; } | { value: 'resolutionFailed'; - context: LogViewContextWithId & LogViewContextWithLogView & LogViewContextWithError; + context: LogViewContextWithReference & LogViewContextWithLogView & LogViewContextWithError; } | { value: 'checkingStatusFailed'; - context: LogViewContextWithId & LogViewContextWithLogView & LogViewContextWithError; + context: LogViewContextWithReference & LogViewContextWithLogView & LogViewContextWithError; }; export type LogViewContext = LogViewTypestate['context']; @@ -92,7 +94,7 @@ export type LogViewEvent = } | { type: 'INITIALIZED_FROM_URL'; - logView: LogViewReference | null; + logViewReference: LogViewReference | null; } | { type: 'LOADING_SUCCEEDED'; diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/url_state_storage_service.ts b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/url_state_storage_service.ts index 705901f6081e..abad8ecb0a53 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/url_state_storage_service.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/url_state_storage_service.ts @@ -53,12 +53,12 @@ export const initializeFromUrl = send({ type: 'INITIALIZED_FROM_URL', - logView: null, + logViewReference: null, }); } else { send({ type: 'INITIALIZED_FROM_URL', - logView: pipe( + logViewReference: pipe( // Via the legacy sourceId key pipe( sourceIdQueryE.right, @@ -73,8 +73,8 @@ export const initializeFromUrl = } }; -const logViewStateInUrlRT = rt.union([logViewReferenceRT, rt.undefined]); -const sourceIdStateInUrl = rt.union([rt.string, rt.undefined]); +const logViewStateInUrlRT = rt.union([logViewReferenceRT, rt.null]); +const sourceIdStateInUrl = rt.union([rt.string, rt.null]); const decodeLogViewQueryValueFromUrl = (queryValueFromUrl: unknown) => { return logViewStateInUrlRT.decode(queryValueFromUrl); diff --git a/x-pack/plugins/infra/public/services/log_views/log_views_client.ts b/x-pack/plugins/infra/public/services/log_views/log_views_client.ts index 65bb031d3407..73256cac7599 100644 --- a/x-pack/plugins/infra/public/services/log_views/log_views_client.ts +++ b/x-pack/plugins/infra/public/services/log_views/log_views_client.ts @@ -18,8 +18,10 @@ import { import { FetchLogViewError, FetchLogViewStatusError, + inlineLogViewReferenceRT, LogView, LogViewAttributes, + LogViewReference, LogViewsStaticConfig, LogViewStatus, PutLogViewError, @@ -37,7 +39,15 @@ export class LogViewsClient implements ILogViewsClient { private readonly config: LogViewsStaticConfig ) {} - public async getLogView(logViewId: string): Promise { + public async getLogView(logViewReference: LogViewReference): Promise { + if (inlineLogViewReferenceRT.is(logViewReference)) { + return { + ...logViewReference, + origin: 'inline', + }; + } + + const { logViewId } = logViewReference; const response = await this.http.get(getLogViewUrl(logViewId)).catch((error) => { throw new FetchLogViewError(`Failed to fetch log view "${logViewId}": ${error}`); }); @@ -51,8 +61,8 @@ export class LogViewsClient implements ILogViewsClient { return data; } - public async getResolvedLogView(logViewId: string): Promise { - const logView = await this.getLogView(logViewId); + public async getResolvedLogView(logViewReference: LogViewReference): Promise { + const logView = await this.getLogView(logViewReference); const resolvedLogView = await this.resolveLogView(logView.id, logView.attributes); return resolvedLogView; } diff --git a/x-pack/plugins/infra/public/services/log_views/types.ts b/x-pack/plugins/infra/public/services/log_views/types.ts index 9054ef79b4a4..b4ad77c47f58 100644 --- a/x-pack/plugins/infra/public/services/log_views/types.ts +++ b/x-pack/plugins/infra/public/services/log_views/types.ts @@ -11,6 +11,7 @@ import { DataViewsContract } from '@kbn/data-views-plugin/public'; import { LogView, LogViewAttributes, + LogViewReference, LogViewStatus, ResolvedLogView, } from '../../../common/log_views'; @@ -28,9 +29,9 @@ export interface LogViewsServiceStartDeps { } export interface ILogViewsClient { - getLogView(logViewId: string): Promise; + getLogView(logViewReference: LogViewReference): Promise; getResolvedLogViewStatus(resolvedLogView: ResolvedLogView): Promise; - getResolvedLogView(logViewId: string): Promise; + getResolvedLogView(logViewReference: LogViewReference): Promise; putLogView(logViewId: string, logViewAttributes: Partial): Promise; resolveLogView(logViewId: string, logViewAttributes: LogViewAttributes): Promise; } From f980baa69595c07da080f57fb8a849c14b7224e1 Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Mon, 6 Mar 2023 13:41:54 +0000 Subject: [PATCH 09/29] WIP: Add support for updating and promoting inline log view to persisted --- .../components/expression_editor/editor.tsx | 2 +- .../infra/public/hooks/use_log_view.ts | 35 ++++--- .../log_view_state/src/defaults.ts | 6 +- .../log_view_state/src/state_machine.ts | 91 ++++++++++++++++--- .../log_view_state/src/types.ts | 12 ++- .../public/pages/logs/page_providers.tsx | 4 +- .../services/log_views/log_views_client.ts | 50 ++++++---- .../infra/public/services/log_views/types.ts | 5 +- 8 files changed, 154 insertions(+), 51 deletions(-) diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx index 1c38dca829ae..c043c595d359 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx @@ -112,7 +112,7 @@ export const ExpressionEditor: React.FC< ) : ( - + diff --git a/x-pack/plugins/infra/public/hooks/use_log_view.ts b/x-pack/plugins/infra/public/hooks/use_log_view.ts index 7f65a60f6965..98457bda3ede 100644 --- a/x-pack/plugins/infra/public/hooks/use_log_view.ts +++ b/x-pack/plugins/infra/public/hooks/use_log_view.ts @@ -7,9 +7,9 @@ import { useInterpret, useSelector } from '@xstate/react'; import createContainer from 'constate'; -import { useCallback, useEffect, useState } from 'react'; +import { useCallback, useState } from 'react'; import { waitFor } from 'xstate/lib/waitFor'; -import { LogViewAttributes } from '../../common/log_views'; +import { LogViewAttributes, LogViewReference } from '../../common/log_views'; import { createLogViewNotificationChannel, createLogViewStateMachine, @@ -21,11 +21,9 @@ import { useKbnUrlStateStorageFromRouterContext } from '../utils/kbn_url_state_c import { useKibanaContextForPlugin } from './use_kibana'; export const useLogView = ({ - logViewId, logViews, useDevTools = isDevMode(), }: { - logViewId: string; logViews: ILogViewsClient; useDevTools?: boolean; }) => { @@ -55,12 +53,20 @@ export const useLogView = ({ } ); - useEffect(() => { - logViewStateService.send({ - type: 'LOG_VIEW_ID_CHANGED', - logViewId, - }); - }, [logViewId, logViewStateService]); + const changeLogViewReference = useCallback( + (logViewReference: LogViewReference) => { + logViewStateService.send({ + type: 'LOG_VIEW_REFERENCE_CHANGED', + logViewReference, + }); + }, + [logViewStateService] + ); + + const logViewReference = useSelector( + logViewStateService, + (state) => state.context.logViewReference + ); const logView = useSelector(logViewStateService, (state) => state.matches('resolving') || state.matches('checkingStatus') || state.matches('resolved') @@ -142,7 +148,7 @@ export const useLogView = ({ ); return { - // underlying state machine + // Underlying state machine logViewStateService, logViewStateNotifications, @@ -160,17 +166,18 @@ export const useLogView = ({ isLoadingLogViewStatus, isResolvingLogView, - // data - logViewId, + // Data + logViewReference, logView, resolvedLogView, logViewStatus, derivedDataView: resolvedLogView?.dataViewReference, - // actions + // Actions load: retry, retry, update, + changeLogViewReference, }; }; diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/defaults.ts b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/defaults.ts index 6f00c40a214b..eb31f91ed12f 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/defaults.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/defaults.ts @@ -5,4 +5,8 @@ * 2.0. */ -export const DEFAULT_LOG_VIEW = { type: 'log-view-reference' as const, logViewId: 'default' }; +const DEFAULT_LOG_VIEW_ID = 'default'; +export const DEFAULT_LOG_VIEW = { + type: 'log-view-reference' as const, + logViewId: DEFAULT_LOG_VIEW_ID, +}; diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts index e64c9a963fcd..ae706c7abfa3 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts @@ -9,6 +9,10 @@ import { IToasts } from '@kbn/core/public'; import { IKbnUrlStateStorage } from '@kbn/kibana-utils-plugin/public'; import { catchError, from, map, of, throwError } from 'rxjs'; import { createMachine, actions, assign } from 'xstate'; +import { + inlineLogViewReferenceRT, + persistedLogViewReferenceRT, +} from '../../../../common/log_views'; import { ILogViewsClient } from '../../../services/log_views'; import { NotificationChannel } from '../../xstate_helpers'; import { LogViewNotificationEvent, logViewNotificationEventSelectors } from './notifications'; @@ -90,20 +94,59 @@ export const createPureLogViewStateMachine = (initialContext: LogViewContextWith target: 'checkingStatusFailed', actions: 'storeError', }, - CHECKING_STATUS_SUCCEEDED: { - target: 'resolved', - actions: 'storeStatus', - }, + CHECKING_STATUS_SUCCEEDED: [ + { + target: 'resolvedPersistedLogView', + actions: 'storeStatus', + cond: 'isPersistedLogView', + }, + { + target: 'resolvedInlineLogView', + actions: 'storeStatus', + }, + ], }, }, - resolved: { + resolvedPersistedLogView: { entry: 'notifyLoadingSucceeded', on: { + PERSIST_INLINE_LOG_VIEW: undefined, RELOAD_LOG_VIEW: { target: 'loading', }, }, }, + resolvedInlineLogView: { + entry: 'notifyLoadingSucceeded', + on: { + PERSIST_INLINE_LOG_VIEW: { + target: 'persistingInlineLogView', + }, + }, + }, + persistingInlineLogView: { + invoke: { + src: 'persistInlineLogView', + }, + on: { + PERSISTING_INLINE_LOG_VIEW_FAILED: { + target: 'persistingInlineLogViewFailed', + actions: 'storeError', + }, + PERSISTING_INLINE_LOG_VIEW_SUCCEEDED: { + target: 'resolving', + actions: ['convertInlineLogViewReferenceToPersistedLogViewReference', 'storeLogView'], + }, + }, + }, + persistingInlineLogViewFailed: { + entry: 'notifyPersistingInlineLogViewFailed', + on: { + RETRY_PERSISTING_INLINE_LOG_VIEW: { + target: 'persistingInlineLogView', + }, + }, + }, loadingFailed: { entry: 'notifyLoadingFailed', on: { @@ -140,7 +183,7 @@ export const createPureLogViewStateMachine = (initialContext: LogViewContextWith }, UPDATING_SUCCEEDED: { target: 'resolving', - actions: 'storeLogView', + actions: ['updateLogViewReference', 'storeLogView'], }, }, }, @@ -154,10 +197,9 @@ export const createPureLogViewStateMachine = (initialContext: LogViewContextWith }, }, on: { - LOG_VIEW_ID_CHANGED: { + LOG_VIEW_REFERENCE_CHANGED: { target: '.loading', - actions: 'storeLogViewId', - cond: 'isLogViewIdDifferent', + actions: 'storeLogViewReference', }, UPDATE: { target: '.updating', @@ -204,10 +246,33 @@ export const createPureLogViewStateMachine = (initialContext: LogViewContextWith } as LogViewContextWithError) : {} ), + convertInlineLogViewReferenceToPersistedLogViewReference: assign((context, event) => + 'logView' in event && inlineLogViewReferenceRT.is(context.logViewReference) + ? ({ + logViewReference: { + type: 'log-view-reference', + logViewId: context.logViewReference.id, + }, + } as LogViewContextWithReference) + : {} + ), + updateLogViewReference: assign((context, event) => + 'attributes' in event && inlineLogViewReferenceRT.is(context.logViewReference) + ? ({ + logViewReference: { + ...context.logViewReference, + attributes: { + ...context.logViewReference.attributes, + ...event.attributes, + }, + }, + } as LogViewContextWithReference) + : {} + ), }, guards: { - isLogViewIdDifferent: (context, event) => - 'logViewId' in event ? event.logViewId !== context.logViewId : false, + isPersistedLogView: (context, event) => + persistedLogViewReferenceRT.is(context.logViewReference), }, } ); @@ -265,8 +330,8 @@ export const createLogViewStateMachine = ({ ), updateLogView: (context, event) => from( - 'logViewId' in context && event.type === 'UPDATE' - ? logViews.putLogView(context.logViewId, event.attributes) + 'logViewReference' in context && event.type === 'UPDATE' + ? logViews.putLogView(context.logViewReference, event.attributes) : throwError( () => new Error( diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/types.ts b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/types.ts index 16d298532a26..1520db856f9d 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/types.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/types.ts @@ -89,8 +89,8 @@ export type LogViewStateValue = LogViewTypestate['value']; export type LogViewEvent = | { - type: 'LOG_VIEW_ID_CHANGED'; - logViewId: string; + type: 'LOG_VIEW_REFERENCE_CHANGED'; + logViewReference: LogViewReference; } | { type: 'INITIALIZED_FROM_URL'; @@ -137,6 +137,14 @@ export type LogViewEvent = } | { type: 'RELOAD_LOG_VIEW'; + } + | { + type: 'PERSIST_INLINE_LOG_VIEW'; + } + | { type: 'PERSISTING_INLINE_LOG_VIEW_FAILED'; error: Error } + | { type: 'PERSISTING_INLINE_LOG_VIEW_SUCCEEDED'; logView: LogView } + | { + type: 'RETRY_PERSISTING_INLINE_LOG_VIEW'; }; export type LogViewActorRef = ActorRef; diff --git a/x-pack/plugins/infra/public/pages/logs/page_providers.tsx b/x-pack/plugins/infra/public/pages/logs/page_providers.tsx index 92db5f003932..c6548cfbd40a 100644 --- a/x-pack/plugins/infra/public/pages/logs/page_providers.tsx +++ b/x-pack/plugins/infra/public/pages/logs/page_providers.tsx @@ -7,16 +7,14 @@ import React from 'react'; import { LogAnalysisCapabilitiesProvider } from '../../containers/logs/log_analysis'; -import { useSourceId } from '../../containers/source_id'; import { useKibanaContextForPlugin } from '../../hooks/use_kibana'; import { LogViewProvider } from '../../hooks/use_log_view'; export const LogsPageProviders: React.FunctionComponent = ({ children }) => { - const [sourceId] = useSourceId(); const { services } = useKibanaContextForPlugin(); return ( - + {children} ); diff --git a/x-pack/plugins/infra/public/services/log_views/log_views_client.ts b/x-pack/plugins/infra/public/services/log_views/log_views_client.ts index 73256cac7599..cdcf09c2d9c6 100644 --- a/x-pack/plugins/infra/public/services/log_views/log_views_client.ts +++ b/x-pack/plugins/infra/public/services/log_views/log_views_client.ts @@ -21,6 +21,7 @@ import { inlineLogViewReferenceRT, LogView, LogViewAttributes, + logViewAttributesRT, LogViewReference, LogViewsStaticConfig, LogViewStatus, @@ -108,24 +109,41 @@ export class LogViewsClient implements ILogViewsClient { } public async putLogView( - logViewId: string, + logViewReference: LogViewReference, logViewAttributes: Partial ): Promise { - const response = await this.http - .put(getLogViewUrl(logViewId), { - body: JSON.stringify(putLogViewRequestPayloadRT.encode({ attributes: logViewAttributes })), - }) - .catch((error) => { - throw new PutLogViewError(`Failed to write log view "${logViewId}": ${error}`); - }); - - const { data } = decodeOrThrow( - getLogViewResponsePayloadRT, - (message: string) => - new PutLogViewError(`Failed to decode written log view "${logViewId}": ${message}"`) - )(response); - - return data; + if (inlineLogViewReferenceRT.is(logViewReference)) { + const { id } = logViewReference; + const attributes = decodeOrThrow( + logViewAttributesRT, + (message: string) => + new PutLogViewError(`Failed to decode inline log view "${id}": ${message}"`) + )(logViewAttributes); + return { + id, + attributes, + origin: 'inline', + }; + } else { + const { logViewId } = logViewReference; + const response = await this.http + .put(getLogViewUrl(logViewId), { + body: JSON.stringify( + putLogViewRequestPayloadRT.encode({ attributes: logViewAttributes }) + ), + }) + .catch((error) => { + throw new PutLogViewError(`Failed to write log view "${logViewId}": ${error}`); + }); + + const { data } = decodeOrThrow( + getLogViewResponsePayloadRT, + (message: string) => + new PutLogViewError(`Failed to decode written log view "${logViewId}": ${message}"`) + )(response); + + return data; + } } public async resolveLogView( diff --git a/x-pack/plugins/infra/public/services/log_views/types.ts b/x-pack/plugins/infra/public/services/log_views/types.ts index b4ad77c47f58..6fd7a4d208b3 100644 --- a/x-pack/plugins/infra/public/services/log_views/types.ts +++ b/x-pack/plugins/infra/public/services/log_views/types.ts @@ -32,6 +32,9 @@ export interface ILogViewsClient { getLogView(logViewReference: LogViewReference): Promise; getResolvedLogViewStatus(resolvedLogView: ResolvedLogView): Promise; getResolvedLogView(logViewReference: LogViewReference): Promise; - putLogView(logViewId: string, logViewAttributes: Partial): Promise; + putLogView( + logViewReference: LogViewReference, + logViewAttributes: Partial + ): Promise; resolveLogView(logViewId: string, logViewAttributes: LogViewAttributes): Promise; } From ad249cd6e716e7ad9676b9dc78fd22b6ac25d42b Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Mon, 6 Mar 2023 18:23:53 +0000 Subject: [PATCH 10/29] WIP: Amend UI code references --- x-pack/plugins/infra/common/constants.ts | 6 +++ .../common/log_analysis/job_parameters.ts | 8 ++-- .../components/expression_editor/criteria.tsx | 13 ++++--- .../criterion_preview_chart.tsx | 13 ++++--- .../components/expression_editor/editor.tsx | 23 ++++++----- .../hooks/use_chart_preview_data.tsx | 13 ++++--- .../components/log_stream/log_stream.tsx | 16 +++----- .../log_entry_flyout/log_entry_flyout.tsx | 17 +++++---- .../logs/log_analysis/api/ml_cleanup.ts | 12 +++--- .../api/ml_get_jobs_summary_api.ts | 6 +-- .../log_analysis/log_analysis_cleanup.tsx | 16 ++++---- .../logs/log_analysis/log_analysis_module.tsx | 24 ++++++------ .../log_analysis_module_status.tsx | 14 +++---- .../log_analysis/log_analysis_module_types.ts | 6 +-- .../log_entry_categories/module_descriptor.ts | 14 +++---- .../use_log_entry_categories_module.tsx | 8 ++-- .../log_entry_rate/module_descriptor.ts | 14 +++---- .../use_log_entry_rate_module.tsx | 8 ++-- .../infra/public/containers/logs/log_entry.ts | 11 +++--- .../log_highlights/log_entry_highlights.tsx | 7 ++-- .../logs/log_highlights/log_highlights.tsx | 9 +++-- .../log_highlights/log_summary_highlights.ts | 7 ++-- .../containers/logs/log_stream/index.ts | 10 ++--- .../log_stream/use_fetch_log_entries_after.ts | 18 ++++----- .../use_fetch_log_entries_around.ts | 10 ++--- .../use_fetch_log_entries_before.ts | 18 ++++----- .../logs/log_summary/log_summary.test.tsx | 38 +++++++++++++++---- .../logs/log_summary/log_summary.tsx | 7 ++-- .../logs/log_summary/with_summary.ts | 4 +- .../view_log_in_context.ts | 7 ++-- .../infra/public/hooks/use_log_view.mock.ts | 7 +++- .../infra/public/hooks/use_log_view.ts | 4 +- .../log_view_state/src/notifications.ts | 8 ++-- .../pages/link_to/redirect_to_node_logs.tsx | 2 +- .../log_entry_categories/page_providers.tsx | 9 ++++- .../page_results_content.tsx | 8 ++-- .../top_categories/category_details_row.tsx | 7 ++-- .../top_categories/top_categories_section.tsx | 7 ++-- .../top_categories/top_categories_table.tsx | 9 +++-- .../get_log_entry_category_datasets.ts | 7 ++-- .../get_log_entry_category_examples.ts | 7 ++-- .../get_top_log_entry_categories.ts | 7 ++-- .../use_log_entry_categories_results.ts | 13 ++++--- .../use_log_entry_category_examples.tsx | 9 +++-- .../logs/log_entry_rate/page_providers.tsx | 12 ++++-- .../log_entry_rate/page_results_content.tsx | 11 ++++-- .../sections/anomalies/expanded_row.tsx | 9 ++++- .../service_calls/get_log_entry_anomalies.ts | 7 ++-- .../get_log_entry_anomalies_datasets.ts | 7 ++-- .../service_calls/get_log_entry_examples.ts | 7 ++-- .../use_log_entry_anomalies_results.ts | 13 ++++--- .../log_entry_rate/use_log_entry_examples.ts | 9 +++-- .../pages/logs/stream/page_logs_content.tsx | 13 +++++-- .../pages/logs/stream/page_providers.tsx | 12 +++--- .../logs/stream/page_view_log_in_context.tsx | 4 +- .../public/utils/logs_overview_fetchers.ts | 6 +-- 56 files changed, 336 insertions(+), 255 deletions(-) diff --git a/x-pack/plugins/infra/common/constants.ts b/x-pack/plugins/infra/common/constants.ts index 4c70e34c9899..77e9d36a90bb 100644 --- a/x-pack/plugins/infra/common/constants.ts +++ b/x-pack/plugins/infra/common/constants.ts @@ -6,6 +6,12 @@ */ export const DEFAULT_SOURCE_ID = 'default'; +const DEFAULT_LOG_VIEW_ID = 'default'; +export const DEFAULT_LOG_VIEW = { + type: 'log-view-reference' as const, + logViewId: DEFAULT_LOG_VIEW_ID, +}; + export const METRICS_INDEX_PATTERN = 'metrics-*,metricbeat-*'; export const LOGS_INDEX_PATTERN = 'logs-*,filebeat-*,kibana_sample_data_logs*'; export const METRICS_APP = 'metrics'; diff --git a/x-pack/plugins/infra/common/log_analysis/job_parameters.ts b/x-pack/plugins/infra/common/log_analysis/job_parameters.ts index b8fa429195ff..1a695af80a4d 100644 --- a/x-pack/plugins/infra/common/log_analysis/job_parameters.ts +++ b/x-pack/plugins/infra/common/log_analysis/job_parameters.ts @@ -16,11 +16,11 @@ export const partitionField = 'event.dataset'; export const getJobIdPrefix = (spaceId: string, sourceId: string) => `kibana-logs-ui-${spaceId}-${sourceId}-`; -export const getJobId = (spaceId: string, sourceId: string, jobType: string) => - `${getJobIdPrefix(spaceId, sourceId)}${jobType}`; +export const getJobId = (spaceId: string, logViewId: string, jobType: string) => + `${getJobIdPrefix(spaceId, logViewId)}${jobType}`; -export const getDatafeedId = (spaceId: string, sourceId: string, jobType: string) => - `datafeed-${getJobId(spaceId, sourceId, jobType)}`; +export const getDatafeedId = (spaceId: string, logViewId: string, jobType: string) => + `datafeed-${getJobId(spaceId, logViewId, jobType)}`; export const datasetFilterRT = rt.union([ rt.strict({ diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criteria.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criteria.tsx index 311df76ce740..3047aedfba5d 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criteria.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criteria.tsx @@ -9,7 +9,10 @@ import React, { useCallback } from 'react'; import { EuiFlexItem, EuiFlexGroup, EuiButtonEmpty, EuiAccordion, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; -import type { ResolvedLogViewField } from '../../../../../common/log_views'; +import type { + PersistedLogViewReference, + ResolvedLogViewField, +} from '../../../../../common/log_views'; import { Criterion } from './criterion'; import { PartialRuleParams, @@ -39,7 +42,7 @@ interface SharedProps { defaultCriterion: PartialCriterionType; errors: Errors['criteria']; ruleParams: PartialRuleParams; - sourceId: string; + logViewReference: PersistedLogViewReference; updateCriteria: (criteria: PartialCriteriaType) => void; } @@ -64,7 +67,7 @@ interface CriteriaWrapperProps { addCriterion: () => void; criteria: PartialCountCriteriaType; errors: CriterionErrors; - sourceId: SharedProps['sourceId']; + logViewReference: SharedProps['logViewReference']; isRatio?: boolean; } @@ -77,7 +80,7 @@ const CriteriaWrapper: React.FC = (props) => { fields, errors, ruleParams, - sourceId, + logViewReference, isRatio = false, } = props; @@ -105,7 +108,7 @@ const CriteriaWrapper: React.FC = (props) => { diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion_preview_chart.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion_preview_chart.tsx index 5ffefdd57119..ed9e56ec437d 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion_preview_chart.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion_preview_chart.tsx @@ -21,6 +21,7 @@ import { import { EuiText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { useKibana } from '@kbn/kibana-react-plugin/public'; +import { PersistedLogViewReference } from '../../../../../common/log_views'; import { ChartContainer, LoadingState, @@ -54,14 +55,14 @@ const GROUP_LIMIT = 5; interface Props { ruleParams: PartialRuleParams; chartCriterion: Partial; - sourceId: string; + logViewReference: PersistedLogViewReference; showThreshold: boolean; } export const CriterionPreview: React.FC = ({ ruleParams, chartCriterion, - sourceId, + logViewReference, showThreshold, }) => { const chartAlertParams: GetLogAlertsChartPreviewDataAlertParamsSubset | null = useMemo(() => { @@ -102,7 +103,7 @@ export const CriterionPreview: React.FC = ({ ? NUM_BUCKETS : NUM_BUCKETS / 4 } // Display less data for groups due to space limitations - sourceId={sourceId} + logViewReference={logViewReference} threshold={ruleParams.count} chartAlertParams={chartAlertParams} showThreshold={showThreshold} @@ -112,7 +113,7 @@ export const CriterionPreview: React.FC = ({ interface ChartProps { buckets: number; - sourceId: string; + logViewReference: PersistedLogViewReference; threshold?: Threshold; chartAlertParams: GetLogAlertsChartPreviewDataAlertParamsSubset; showThreshold: boolean; @@ -120,7 +121,7 @@ interface ChartProps { const CriterionPreviewChart: React.FC = ({ buckets, - sourceId, + logViewReference, threshold, chartAlertParams, showThreshold, @@ -135,7 +136,7 @@ const CriterionPreviewChart: React.FC = ({ hasError, chartPreviewData: series, } = useChartPreviewData({ - sourceId, + logViewReference, ruleParams: chartAlertParams, buckets, }); diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx index c043c595d359..35fb962911eb 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx @@ -13,7 +13,11 @@ import { ForLastExpression, RuleTypeParamsExpressionProps, } from '@kbn/triggers-actions-ui-plugin/public'; -import { PersistedLogViewReference, ResolvedLogViewField } from '../../../../../common/log_views'; +import { + PersistedLogViewReference, + persistedLogViewReferenceRT, + ResolvedLogViewField, +} from '../../../../../common/log_views'; import { Comparator, isOptimizableGroupedThreshold, @@ -27,7 +31,6 @@ import { } from '../../../../../common/alerting/logs/log_threshold/types'; import { decodeOrThrow } from '../../../../../common/runtime_types'; import { ObjectEntries } from '../../../../../common/utility_types'; -import { useSourceId } from '../../../../containers/source_id'; import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana'; import { LogViewProvider, useLogViewContext } from '../../../../hooks/use_log_view'; import { GroupByExpression } from '../../../common/group_by_expression/group_by_expression'; @@ -54,11 +57,6 @@ const DEFAULT_BASE_EXPRESSION = { const DEFAULT_FIELD = 'log.level'; -const createLogViewReference = (logViewId: string): PersistedLogViewReference => ({ - logViewId, - type: 'log-view-reference', -}); - const createDefaultCriterion = ( availableFields: ResolvedLogViewField[], value: ExpressionCriteria['value'] @@ -100,7 +98,6 @@ export const ExpressionEditor: React.FC< RuleTypeParamsExpressionProps > = (props) => { const isInternal = props.metadata?.isInternal ?? false; - const [logViewId] = useSourceId(); const { services: { logViews }, } = useKibanaContextForPlugin(); // injected during alert registration @@ -159,7 +156,11 @@ export const Editor: React.FC { const { setRuleParams, ruleParams, errors } = props; const [hasSetDefaults, setHasSetDefaults] = useState(false); - const { logViewId, resolvedLogView } = useLogViewContext(); + const { logViewReference, resolvedLogView } = useLogViewContext(); + + if (!persistedLogViewReferenceRT.is(logViewReference)) { + throw new Error('The Log Threshold rule type only supports persisted Log Views'); + } const { criteria: criteriaErrors, @@ -226,8 +227,6 @@ export const Editor: React.FC createLogViewReference(logViewId), [logViewId]); - const defaultCountAlertParams = useMemo( () => createDefaultCountRuleParams(supportedFields, logViewReference), [supportedFields, logViewReference] @@ -275,7 +274,7 @@ export const Editor: React.FC ) : null; diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/hooks/use_chart_preview_data.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/hooks/use_chart_preview_data.tsx index 0b99cea2fd7c..b7b6769e72d6 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/hooks/use_chart_preview_data.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/hooks/use_chart_preview_data.tsx @@ -8,6 +8,7 @@ import { useState, useMemo } from 'react'; import { HttpHandler } from '@kbn/core/public'; import { useKibana } from '@kbn/kibana-react-plugin/public'; +import { PersistedLogViewReference } from '../../../../../../common/log_views'; import { useTrackedPromise } from '../../../../../utils/use_tracked_promise'; import { GetLogAlertsChartPreviewDataSuccessResponsePayload, @@ -19,12 +20,12 @@ import { decodeOrThrow } from '../../../../../../common/runtime_types'; import { GetLogAlertsChartPreviewDataAlertParamsSubset } from '../../../../../../common/http_api/log_alerts'; interface Options { - sourceId: string; + logViewReference: PersistedLogViewReference; ruleParams: GetLogAlertsChartPreviewDataAlertParamsSubset; buckets: number; } -export const useChartPreviewData = ({ sourceId, ruleParams, buckets }: Options) => { +export const useChartPreviewData = ({ logViewReference, ruleParams, buckets }: Options) => { const { http } = useKibana().services; const [chartPreviewData, setChartPreviewData] = useState< @@ -36,7 +37,7 @@ export const useChartPreviewData = ({ sourceId, ruleParams, buckets }: Options) cancelPreviousOn: 'creation', createPromise: async () => { setHasError(false); - return await callGetChartPreviewDataAPI(sourceId, http!.fetch, ruleParams, buckets); + return await callGetChartPreviewDataAPI(logViewReference, http!.fetch, ruleParams, buckets); }, onResolve: ({ data: { series } }) => { setHasError(false); @@ -46,7 +47,7 @@ export const useChartPreviewData = ({ sourceId, ruleParams, buckets }: Options) setHasError(true); }, }, - [sourceId, http, ruleParams, buckets] + [logViewReference, http, ruleParams, buckets] ); const isLoading = useMemo( @@ -63,7 +64,7 @@ export const useChartPreviewData = ({ sourceId, ruleParams, buckets }: Options) }; export const callGetChartPreviewDataAPI = async ( - sourceId: string, + logViewReference: PersistedLogViewReference, fetch: HttpHandler, alertParams: GetLogAlertsChartPreviewDataAlertParamsSubset, buckets: number @@ -73,7 +74,7 @@ export const callGetChartPreviewDataAPI = async ( body: JSON.stringify( getLogAlertsChartPreviewDataRequestPayloadRT.encode({ data: { - logView: { type: 'log-view-reference', logViewId: sourceId }, + logView: logViewReference, alertParams, buckets, }, diff --git a/x-pack/plugins/infra/public/components/log_stream/log_stream.tsx b/x-pack/plugins/infra/public/components/log_stream/log_stream.tsx index 6a3e8bfb6352..5ae7daf0731b 100644 --- a/x-pack/plugins/infra/public/components/log_stream/log_stream.tsx +++ b/x-pack/plugins/infra/public/components/log_stream/log_stream.tsx @@ -13,7 +13,7 @@ import { euiStyled } from '@kbn/kibana-react-plugin/common'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { noop } from 'lodash'; import { LogEntryCursor } from '../../../common/log_entry'; -import { defaultLogViewsStaticConfig } from '../../../common/log_views'; +import { defaultLogViewsStaticConfig, LogViewReference } from '../../../common/log_views'; import { BuiltEsQuery, useLogStream } from '../../containers/logs/log_stream'; import { useLogView } from '../../hooks/use_log_view'; import { LogViewsClient } from '../../services/log_views'; @@ -63,14 +63,8 @@ type LogColumnDefinition = export interface LogStreamProps extends LogStreamContentProps { height?: string | number; } - -interface LogView { - type: 'log-view-reference'; - logViewId: string; -} - interface LogStreamContentProps { - logView: LogView; + logView: LogViewReference; startTimestamp: number; endTimestamp: number; query?: string | Query | BuiltEsQuery; @@ -120,7 +114,7 @@ Read more at https://github.com/elastic/kibana/blob/main/src/plugins/kibana_reac ); } - const { openLogEntryFlyout } = useLogEntryFlyout(logView.logViewId); + const { openLogEntryFlyout } = useLogEntryFlyout(logView); const kibanaQuerySettings = useKibanaQuerySettings(); @@ -135,7 +129,7 @@ Read more at https://github.com/elastic/kibana/blob/main/src/plugins/kibana_reac load: loadLogView, resolvedLogView, } = useLogView({ - logViewId: logView.logViewId, + initialLogViewReference: logView, logViews, }); @@ -166,7 +160,7 @@ Read more at https://github.com/elastic/kibana/blob/main/src/plugins/kibana_reac isLoadingMore, isReloading: isLoadingEntries, } = useLogStream({ - sourceId: logView.logViewId, + logViewReference: logView, startTimestamp, endTimestamp, query: parsedQuery, diff --git a/x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_flyout.tsx b/x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_flyout.tsx index d7b1b45e0242..619d83cf270c 100644 --- a/x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_flyout.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_flyout.tsx @@ -23,6 +23,7 @@ import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public'; import { OverlayRef } from '@kbn/core/public'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { DataPublicPluginStart } from '@kbn/data-plugin/public'; +import { LogViewReference } from '../../../../common/log_views'; import { TimeKey } from '../../../../common/time'; import { useLogEntry } from '../../../containers/logs/log_entry'; import { CenteredEuiFlyoutBody } from '../../centered_flyout_body'; @@ -35,10 +36,10 @@ export interface LogEntryFlyoutProps { logEntryId: string | null | undefined; onCloseFlyout: () => void; onSetFieldFilter?: (filter: Query, logEntryId: string, timeKey?: TimeKey) => void; - sourceId: string | null | undefined; + logViewReference: LogViewReference | null | undefined; } -export const useLogEntryFlyout = (sourceId: string) => { +export const useLogEntryFlyout = (logViewReference: LogViewReference) => { const flyoutRef = useRef(); const { services: { http, data, uiSettings, application }, @@ -63,12 +64,12 @@ export const useLogEntryFlyout = (sourceId: string) => { ); }, - [http, data, uiSettings, application, openFlyout, sourceId, closeLogEntryFlyout] + [http, data, uiSettings, application, openFlyout, logViewReference, closeLogEntryFlyout] ); useEffect(() => { @@ -87,7 +88,7 @@ export const LogEntryFlyout = ({ logEntryId, onCloseFlyout, onSetFieldFilter, - sourceId, + logViewReference, }: LogEntryFlyoutProps) => { const { cancelRequest: cancelLogEntryRequest, @@ -98,15 +99,15 @@ export const LogEntryFlyout = ({ logEntry, total: logEntryRequestTotal, } = useLogEntry({ - sourceId, + logViewReference, logEntryId, }); useEffect(() => { - if (sourceId && logEntryId) { + if (logViewReference && logEntryId) { fetchLogEntry(); } - }, [fetchLogEntry, sourceId, logEntryId]); + }, [fetchLogEntry, logViewReference, logEntryId]); return ( diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_cleanup.ts b/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_cleanup.ts index 17377e1484e2..2912cdf74a36 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_cleanup.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_cleanup.ts @@ -13,7 +13,7 @@ import { decodeOrThrow } from '../../../../../common/runtime_types'; interface DeleteJobsRequestArgs { spaceId: string; - sourceId: string; + logViewId: string; jobTypes: JobType[]; } @@ -21,14 +21,14 @@ export const callDeleteJobs = async ( requestArgs: DeleteJobsRequestArgs, fetch: HttpHandler ) => { - const { spaceId, sourceId, jobTypes } = requestArgs; + const { spaceId, logViewId, jobTypes } = requestArgs; // NOTE: Deleting the jobs via this API will delete the datafeeds at the same time const deleteJobsResponse = await fetch('/api/ml/jobs/delete_jobs', { method: 'POST', body: JSON.stringify( deleteJobsRequestPayloadRT.encode({ - jobIds: jobTypes.map((jobType) => getJobId(spaceId, sourceId, jobType)), + jobIds: jobTypes.map((jobType) => getJobId(spaceId, logViewId, jobType)), }) ), }); @@ -44,7 +44,7 @@ export const callGetJobDeletionTasks = async (fetch: HttpHandler) => { interface StopDatafeedsRequestArgs { spaceId: string; - sourceId: string; + logViewId: string; jobTypes: JobType[]; } @@ -52,14 +52,14 @@ export const callStopDatafeeds = async ( requestArgs: StopDatafeedsRequestArgs, fetch: HttpHandler ) => { - const { spaceId, sourceId, jobTypes } = requestArgs; + const { spaceId, logViewId, jobTypes } = requestArgs; // Stop datafeed due to https://github.com/elastic/kibana/issues/44652 const stopDatafeedResponse = await fetch('/api/ml/jobs/stop_datafeeds', { method: 'POST', body: JSON.stringify( stopDatafeedsRequestPayloadRT.encode({ - datafeedIds: jobTypes.map((jobType) => getDatafeedId(spaceId, sourceId, jobType)), + datafeedIds: jobTypes.map((jobType) => getDatafeedId(spaceId, logViewId, jobType)), }) ), }); diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_get_jobs_summary_api.ts b/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_get_jobs_summary_api.ts index 142304269687..b737427b2391 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_get_jobs_summary_api.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_get_jobs_summary_api.ts @@ -13,7 +13,7 @@ import { decodeOrThrow } from '../../../../../common/runtime_types'; interface RequestArgs { spaceId: string; - sourceId: string; + logViewId: string; jobTypes: JobType[]; } @@ -21,12 +21,12 @@ export const callJobsSummaryAPI = async ( requestArgs: RequestArgs, fetch: HttpHandler ) => { - const { spaceId, sourceId, jobTypes } = requestArgs; + const { spaceId, logViewId, jobTypes } = requestArgs; const response = await fetch('/api/ml/jobs/jobs_summary', { method: 'POST', body: JSON.stringify( fetchJobStatusRequestPayloadRT.encode({ - jobIds: jobTypes.map((jobType) => getJobId(spaceId, sourceId, jobType)), + jobIds: jobTypes.map((jobType) => getJobId(spaceId, logViewId, jobType)), }) ), }); diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_cleanup.tsx b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_cleanup.tsx index 7269a530409f..2a5493f153ff 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_cleanup.tsx +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_cleanup.tsx @@ -11,12 +11,12 @@ import { callDeleteJobs, callGetJobDeletionTasks, callStopDatafeeds } from './ap export const cleanUpJobsAndDatafeeds = async ( spaceId: string, - sourceId: string, + logViewId: string, jobTypes: JobType[], fetch: HttpHandler ) => { try { - await callStopDatafeeds({ spaceId, sourceId, jobTypes }, fetch); + await callStopDatafeeds({ spaceId, logViewId, jobTypes }, fetch); } catch (err) { // Proceed only if datafeed has been deleted or didn't exist in the first place if (err?.response?.status !== 404) { @@ -24,27 +24,27 @@ export const cleanUpJobsAndDatafeeds = async ( } } - return await deleteJobs(spaceId, sourceId, jobTypes, fetch); + return await deleteJobs(spaceId, logViewId, jobTypes, fetch); }; const deleteJobs = async ( spaceId: string, - sourceId: string, + logViewId: string, jobTypes: JobType[], fetch: HttpHandler ) => { - const deleteJobsResponse = await callDeleteJobs({ spaceId, sourceId, jobTypes }, fetch); - await waitUntilJobsAreDeleted(spaceId, sourceId, jobTypes, fetch); + const deleteJobsResponse = await callDeleteJobs({ spaceId, logViewId, jobTypes }, fetch); + await waitUntilJobsAreDeleted(spaceId, logViewId, jobTypes, fetch); return deleteJobsResponse; }; const waitUntilJobsAreDeleted = async ( spaceId: string, - sourceId: string, + logViewId: string, jobTypes: JobType[], fetch: HttpHandler ) => { - const moduleJobIds = jobTypes.map((jobType) => getJobId(spaceId, sourceId, jobType)); + const moduleJobIds = jobTypes.map((jobType) => getJobId(spaceId, logViewId, jobType)); while (true) { const { jobIds: jobIdsBeingDeleted } = await callGetJobDeletionTasks(fetch); const needToWait = jobIdsBeingDeleted.some((jobId) => moduleJobIds.includes(jobId)); diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module.tsx b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module.tsx index 29e5508b24d3..3695c6952cd1 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module.tsx +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module.tsx @@ -21,7 +21,7 @@ export const useLogAnalysisModule = ({ moduleDescriptor: ModuleDescriptor; }) => { const { services } = useKibanaContextForPlugin(); - const { spaceId, sourceId, timestampField, runtimeMappings } = sourceConfiguration; + const { spaceId, sourceId: logViewId, timestampField, runtimeMappings } = sourceConfiguration; const [moduleStatus, dispatchModuleStatus] = useModuleStatus(moduleDescriptor.jobTypes); const trackMetric = useUiTracker({ app: 'infra_logs' }); @@ -31,21 +31,21 @@ export const useLogAnalysisModule = ({ cancelPreviousOn: 'resolution', createPromise: async () => { dispatchModuleStatus({ type: 'fetchingJobStatuses' }); - return await moduleDescriptor.getJobSummary(spaceId, sourceId, services.http.fetch); + return await moduleDescriptor.getJobSummary(spaceId, logViewId, services.http.fetch); }, onResolve: (jobResponse) => { dispatchModuleStatus({ type: 'fetchedJobStatuses', payload: jobResponse, spaceId, - sourceId, + logViewId, }); }, onReject: () => { dispatchModuleStatus({ type: 'failedFetchingJobStatuses' }); }, }, - [spaceId, sourceId] + [spaceId, logViewId] ); const [, setUpModule] = useTrackedPromise( @@ -64,7 +64,7 @@ export const useLogAnalysisModule = ({ datasetFilter, { indices: selectedIndices, - sourceId, + sourceId: logViewId, spaceId, timestampField, runtimeMappings, @@ -73,7 +73,7 @@ export const useLogAnalysisModule = ({ ); const jobSummaries = await moduleDescriptor.getJobSummary( spaceId, - sourceId, + logViewId, services.http.fetch ); return { setupResult, jobSummaries }; @@ -104,7 +104,7 @@ export const useLogAnalysisModule = ({ jobSetupResults: jobs, jobSummaries, spaceId, - sourceId, + logViewId, }); }, onReject: (e: any) => { @@ -114,17 +114,17 @@ export const useLogAnalysisModule = ({ } }, }, - [moduleDescriptor.setUpModule, spaceId, sourceId, timestampField] + [moduleDescriptor.setUpModule, spaceId, logViewId, timestampField] ); const [cleanUpModuleRequest, cleanUpModule] = useTrackedPromise( { cancelPreviousOn: 'resolution', createPromise: async () => { - return await moduleDescriptor.cleanUpModule(spaceId, sourceId, services.http.fetch); + return await moduleDescriptor.cleanUpModule(spaceId, logViewId, services.http.fetch); }, }, - [spaceId, sourceId] + [spaceId, logViewId] ); const isCleaningUp = useMemo( @@ -156,8 +156,8 @@ export const useLogAnalysisModule = ({ }, [dispatchModuleStatus]); const jobIds = useMemo( - () => moduleDescriptor.getJobIds(spaceId, sourceId), - [moduleDescriptor, spaceId, sourceId] + () => moduleDescriptor.getJobIds(spaceId, logViewId), + [moduleDescriptor, spaceId, logViewId] ); return { diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module_status.tsx b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module_status.tsx index 5c4623075dec..90f36b40d14d 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module_status.tsx +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module_status.tsx @@ -29,7 +29,7 @@ type StatusReducerAction = | { type: 'startedSetup' } | { type: 'finishedSetup'; - sourceId: string; + logViewId: string; spaceId: string; jobSetupResults: SetupMlModuleResponsePayload['jobs']; jobSummaries: FetchJobStatusResponsePayload; @@ -40,7 +40,7 @@ type StatusReducerAction = | { type: 'fetchedJobStatuses'; spaceId: string; - sourceId: string; + logViewId: string; payload: FetchJobStatusResponsePayload; } | { type: 'failedFetchingJobStatuses' } @@ -84,13 +84,13 @@ const createStatusReducer = }; } case 'finishedSetup': { - const { datafeedSetupResults, jobSetupResults, jobSummaries, spaceId, sourceId } = action; + const { datafeedSetupResults, jobSetupResults, jobSummaries, spaceId, logViewId } = action; const nextJobStatus = jobTypes.reduce( (accumulatedJobStatus, jobType) => ({ ...accumulatedJobStatus, [jobType]: - hasSuccessfullyCreatedJob(getJobId(spaceId, sourceId, jobType))(jobSetupResults) && - hasSuccessfullyStartedDatafeed(getDatafeedId(spaceId, sourceId, jobType))( + hasSuccessfullyCreatedJob(getJobId(spaceId, logViewId, jobType))(jobSetupResults) && + hasSuccessfullyStartedDatafeed(getDatafeedId(spaceId, logViewId, jobType))( datafeedSetupResults ) ? 'started' @@ -142,13 +142,13 @@ const createStatusReducer = }; } case 'fetchedJobStatuses': { - const { payload: jobSummaries, spaceId, sourceId } = action; + const { payload: jobSummaries, spaceId, logViewId } = action; const { setupStatus } = state; const nextJobStatus = jobTypes.reduce( (accumulatedJobStatus, jobType) => ({ ...accumulatedJobStatus, - [jobType]: getJobStatus(getJobId(spaceId, sourceId, jobType))(jobSummaries), + [jobType]: getJobStatus(getJobId(spaceId, logViewId, jobType))(jobSummaries), }), {} as Record ); diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module_types.ts b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module_types.ts index b26916a22f7b..d82b8f66c8b7 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module_types.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module_types.ts @@ -25,10 +25,10 @@ export interface ModuleDescriptor { moduleDescription: string; jobTypes: JobType[]; bucketSpan: number; - getJobIds: (spaceId: string, sourceId: string) => Record; + getJobIds: (spaceId: string, logViewId: string) => Record; getJobSummary: ( spaceId: string, - sourceId: string, + logViewId: string, fetch: HttpHandler ) => Promise; getModuleDefinition: (fetch: HttpHandler) => Promise; @@ -41,7 +41,7 @@ export interface ModuleDescriptor { ) => Promise; cleanUpModule: ( spaceId: string, - sourceId: string, + logViewId: string, fetch: HttpHandler ) => Promise; validateSetupIndices: ( diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/modules/log_entry_categories/module_descriptor.ts b/x-pack/plugins/infra/public/containers/logs/log_analysis/modules/log_entry_categories/module_descriptor.ts index 02e977dfadd3..38a1c5c90752 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/modules/log_entry_categories/module_descriptor.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/modules/log_entry_categories/module_descriptor.ts @@ -36,21 +36,21 @@ const moduleDescription = i18n.translate( } ); -const getJobIds = (spaceId: string, sourceId: string) => +const getJobIds = (spaceId: string, logViewId: string) => logEntryCategoriesJobTypes.reduce( (accumulatedJobIds, jobType) => ({ ...accumulatedJobIds, - [jobType]: getJobId(spaceId, sourceId, jobType), + [jobType]: getJobId(spaceId, logViewId, jobType), }), {} as Record ); -const getJobSummary = async (spaceId: string, sourceId: string, fetch: HttpHandler) => { +const getJobSummary = async (spaceId: string, logViewId: string, fetch: HttpHandler) => { const response = await callJobsSummaryAPI( - { spaceId, sourceId, jobTypes: logEntryCategoriesJobTypes }, + { spaceId, logViewId, jobTypes: logEntryCategoriesJobTypes }, fetch ); - const jobIds = Object.values(getJobIds(spaceId, sourceId)); + const jobIds = Object.values(getJobIds(spaceId, logViewId)); return response.filter((jobSummary) => jobIds.includes(jobSummary.id)); }; @@ -130,8 +130,8 @@ const setUpModule = async ( ); }; -const cleanUpModule = async (spaceId: string, sourceId: string, fetch: HttpHandler) => { - return await cleanUpJobsAndDatafeeds(spaceId, sourceId, logEntryCategoriesJobTypes, fetch); +const cleanUpModule = async (spaceId: string, logViewId: string, fetch: HttpHandler) => { + return await cleanUpJobsAndDatafeeds(spaceId, logViewId, logEntryCategoriesJobTypes, fetch); }; const validateSetupIndices = async ( diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/modules/log_entry_categories/use_log_entry_categories_module.tsx b/x-pack/plugins/infra/public/containers/logs/log_analysis/modules/log_entry_categories/use_log_entry_categories_module.tsx index 433a24cffd93..3f4d80294097 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/modules/log_entry_categories/use_log_entry_categories_module.tsx +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/modules/log_entry_categories/use_log_entry_categories_module.tsx @@ -17,13 +17,13 @@ import { useLogEntryCategoriesQuality } from './use_log_entry_categories_quality export const useLogEntryCategoriesModule = ({ indexPattern, - sourceId, + logViewId, spaceId, timestampField, runtimeMappings, }: { indexPattern: string; - sourceId: string; + logViewId: string; spaceId: string; timestampField: string; runtimeMappings: estypes.MappingRuntimeFields; @@ -31,12 +31,12 @@ export const useLogEntryCategoriesModule = ({ const sourceConfiguration: ModuleSourceConfiguration = useMemo( () => ({ indices: indexPattern.split(','), - sourceId, + sourceId: logViewId, spaceId, timestampField, runtimeMappings, }), - [indexPattern, sourceId, spaceId, timestampField, runtimeMappings] + [indexPattern, logViewId, spaceId, timestampField, runtimeMappings] ); const logAnalysisModule = useLogAnalysisModule({ diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/modules/log_entry_rate/module_descriptor.ts b/x-pack/plugins/infra/public/containers/logs/log_analysis/modules/log_entry_rate/module_descriptor.ts index 8acf7ce9d9a5..8cb0bb8a2179 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/modules/log_entry_rate/module_descriptor.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/modules/log_entry_rate/module_descriptor.ts @@ -35,21 +35,21 @@ const moduleDescription = i18n.translate( } ); -const getJobIds = (spaceId: string, sourceId: string) => +const getJobIds = (spaceId: string, logViewId: string) => logEntryRateJobTypes.reduce( (accumulatedJobIds, jobType) => ({ ...accumulatedJobIds, - [jobType]: getJobId(spaceId, sourceId, jobType), + [jobType]: getJobId(spaceId, logViewId, jobType), }), {} as Record ); -const getJobSummary = async (spaceId: string, sourceId: string, fetch: HttpHandler) => { +const getJobSummary = async (spaceId: string, logViewId: string, fetch: HttpHandler) => { const response = await callJobsSummaryAPI( - { spaceId, sourceId, jobTypes: logEntryRateJobTypes }, + { spaceId, logViewId, jobTypes: logEntryRateJobTypes }, fetch ); - const jobIds = Object.values(getJobIds(spaceId, sourceId)); + const jobIds = Object.values(getJobIds(spaceId, logViewId)); return response.filter((jobSummary) => jobIds.includes(jobSummary.id)); }; @@ -122,8 +122,8 @@ const setUpModule = async ( ); }; -const cleanUpModule = async (spaceId: string, sourceId: string, fetch: HttpHandler) => { - return await cleanUpJobsAndDatafeeds(spaceId, sourceId, logEntryRateJobTypes, fetch); +const cleanUpModule = async (spaceId: string, logViewId: string, fetch: HttpHandler) => { + return await cleanUpJobsAndDatafeeds(spaceId, logViewId, logEntryRateJobTypes, fetch); }; const validateSetupIndices = async ( diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/modules/log_entry_rate/use_log_entry_rate_module.tsx b/x-pack/plugins/infra/public/containers/logs/log_analysis/modules/log_entry_rate/use_log_entry_rate_module.tsx index 46587969ca2a..65bddee00ce3 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/modules/log_entry_rate/use_log_entry_rate_module.tsx +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/modules/log_entry_rate/use_log_entry_rate_module.tsx @@ -16,13 +16,13 @@ import { logEntryRateModule } from './module_descriptor'; export const useLogEntryRateModule = ({ indexPattern, - sourceId, + logViewId, spaceId, timestampField, runtimeMappings, }: { indexPattern: string; - sourceId: string; + logViewId: string; spaceId: string; timestampField: string; runtimeMappings: estypes.MappingRuntimeFields; @@ -30,12 +30,12 @@ export const useLogEntryRateModule = ({ const sourceConfiguration: ModuleSourceConfiguration = useMemo( () => ({ indices: indexPattern.split(','), - sourceId, + sourceId: logViewId, spaceId, timestampField, runtimeMappings, }), - [indexPattern, sourceId, spaceId, timestampField, runtimeMappings] + [indexPattern, logViewId, spaceId, timestampField, runtimeMappings] ); const logAnalysisModule = useLogAnalysisModule({ diff --git a/x-pack/plugins/infra/public/containers/logs/log_entry.ts b/x-pack/plugins/infra/public/containers/logs/log_entry.ts index 958097fc3baa..51b98329ddd5 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_entry.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_entry.ts @@ -6,6 +6,7 @@ */ import { useCallback } from 'react'; +import { LogViewReference } from '../../../common/log_views'; import { decodeOrThrow } from '../../../common/runtime_types'; import { logEntrySearchRequestParamsRT, @@ -19,26 +20,26 @@ import { } from '../../utils/data_search'; export const useLogEntry = ({ - sourceId, + logViewReference, logEntryId, }: { - sourceId: string | null | undefined; + logViewReference: LogViewReference | null | undefined; logEntryId: string | null | undefined; }) => { const { search: fetchLogEntry, requests$: logEntrySearchRequests$ } = useDataSearch({ getRequest: useCallback(() => { - return !!logEntryId && !!sourceId + return !!logEntryId && !!logViewReference ? { request: { params: logEntrySearchRequestParamsRT.encode({ - logView: { type: 'log-view-reference', logViewId: sourceId }, + logView: logViewReference, logEntryId, }), }, options: { strategy: LOG_ENTRY_SEARCH_STRATEGY }, } : null; - }, [sourceId, logEntryId]), + }, [logViewReference, logEntryId]), parseResponses: parseLogEntrySearchResponses, }); diff --git a/x-pack/plugins/infra/public/containers/logs/log_highlights/log_entry_highlights.tsx b/x-pack/plugins/infra/public/containers/logs/log_highlights/log_entry_highlights.tsx index d9f7ab078ae0..ea0e1fa326c7 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_highlights/log_entry_highlights.tsx +++ b/x-pack/plugins/infra/public/containers/logs/log_highlights/log_entry_highlights.tsx @@ -6,6 +6,7 @@ */ import { useEffect, useMemo, useState } from 'react'; +import { LogViewReference } from '../../../../common/log_views'; import { LogEntriesHighlightsResponse } from '../../../../common/http_api'; import { LogEntry } from '../../../../common/log_entry'; import { TimeKey } from '../../../../common/time'; @@ -14,7 +15,7 @@ import { useTrackedPromise } from '../../../utils/use_tracked_promise'; import { fetchLogEntriesHighlights } from './api/fetch_log_entries_highlights'; export const useLogEntryHighlights = ( - sourceId: string, + logViewReference: LogViewReference, sourceVersion: string | undefined, startTimestamp: number | null, endTimestamp: number | null, @@ -37,7 +38,7 @@ export const useLogEntryHighlights = ( return await fetchLogEntriesHighlights( { - logView: { type: 'log-view-reference', logViewId: sourceId }, + logView: logViewReference, startTimestamp, endTimestamp, center: centerPoint, @@ -52,7 +53,7 @@ export const useLogEntryHighlights = ( setLogEntryHighlights(response.data); }, }, - [sourceId, startTimestamp, endTimestamp, centerPoint, size, filterQuery, highlightTerms] + [logViewReference, startTimestamp, endTimestamp, centerPoint, size, filterQuery, highlightTerms] ); useEffect(() => { diff --git a/x-pack/plugins/infra/public/containers/logs/log_highlights/log_highlights.tsx b/x-pack/plugins/infra/public/containers/logs/log_highlights/log_highlights.tsx index 9ca6858c3450..0a6710731bcb 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_highlights/log_highlights.tsx +++ b/x-pack/plugins/infra/public/containers/logs/log_highlights/log_highlights.tsx @@ -8,6 +8,7 @@ import createContainer from 'constate'; import { useState } from 'react'; import useThrottle from 'react-use/lib/useThrottle'; +import { LogViewReference } from '../../../../common/log_views'; import { useLogEntryHighlights } from './log_entry_highlights'; import { useLogSummaryHighlights } from './log_summary_highlights'; import { useNextAndPrevious } from './next_and_previous'; @@ -17,7 +18,7 @@ import { TimeKey } from '../../../../common/time'; const FETCH_THROTTLE_INTERVAL = 3000; interface UseLogHighlightsStateProps { - sourceId: string; + logViewReference: LogViewReference; sourceVersion: string | undefined; centerCursor: TimeKey | null; size: number; @@ -25,7 +26,7 @@ interface UseLogHighlightsStateProps { } export const useLogHighlightsState = ({ - sourceId, + logViewReference, sourceVersion, centerCursor, size, @@ -40,7 +41,7 @@ export const useLogHighlightsState = ({ const { logEntryHighlights, logEntryHighlightsById, loadLogEntryHighlightsRequest } = useLogEntryHighlights( - sourceId, + logViewReference, sourceVersion, throttledStartTimestamp, throttledEndTimestamp, @@ -51,7 +52,7 @@ export const useLogHighlightsState = ({ ); const { logSummaryHighlights, loadLogSummaryHighlightsRequest } = useLogSummaryHighlights( - sourceId, + logViewReference, sourceVersion, throttledStartTimestamp, throttledEndTimestamp, diff --git a/x-pack/plugins/infra/public/containers/logs/log_highlights/log_summary_highlights.ts b/x-pack/plugins/infra/public/containers/logs/log_highlights/log_summary_highlights.ts index e994e2a013bb..8c5f7fb7ae77 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_highlights/log_summary_highlights.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_highlights/log_summary_highlights.ts @@ -8,6 +8,7 @@ import { useEffect, useMemo, useState } from 'react'; import { debounce } from 'lodash'; +import { LogViewReference } from '../../../../common/log_views'; import { useTrackedPromise } from '../../../utils/use_tracked_promise'; import { fetchLogSummaryHighlights } from './api/fetch_log_summary_highlights'; import { LogEntriesSummaryHighlightsResponse } from '../../../../common/http_api'; @@ -15,7 +16,7 @@ import { useBucketSize } from '../log_summary/bucket_size'; import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; export const useLogSummaryHighlights = ( - sourceId: string, + logViewReference: LogViewReference, sourceVersion: string | undefined, startTimestamp: number | null, endTimestamp: number | null, @@ -39,7 +40,7 @@ export const useLogSummaryHighlights = ( return await fetchLogSummaryHighlights( { - logView: { type: 'log-view-reference', logViewId: sourceId }, + logView: logViewReference, startTimestamp, endTimestamp, bucketSize, @@ -53,7 +54,7 @@ export const useLogSummaryHighlights = ( setLogSummaryHighlights(response.data); }, }, - [sourceId, startTimestamp, endTimestamp, bucketSize, filterQuery, highlightTerms] + [logViewReference, startTimestamp, endTimestamp, bucketSize, filterQuery, highlightTerms] ); const debouncedLoadSummaryHighlights = useMemo( diff --git a/x-pack/plugins/infra/public/containers/logs/log_stream/index.ts b/x-pack/plugins/infra/public/containers/logs/log_stream/index.ts index 2a81afa23472..e1b425b112f8 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_stream/index.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_stream/index.ts @@ -12,7 +12,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react'; import usePrevious from 'react-use/lib/usePrevious'; import useSetState from 'react-use/lib/useSetState'; import { LogEntry, LogEntryCursor } from '../../../../common/log_entry'; -import { LogViewColumnConfiguration } from '../../../../common/log_views'; +import { LogViewColumnConfiguration, LogViewReference } from '../../../../common/log_views'; import { useSubscription } from '../../../utils/use_observable'; import { useFetchLogEntriesAfter } from './use_fetch_log_entries_after'; import { useFetchLogEntriesAround } from './use_fetch_log_entries_around'; @@ -21,7 +21,7 @@ import { useFetchLogEntriesBefore } from './use_fetch_log_entries_before'; export type BuiltEsQuery = ReturnType; interface LogStreamProps { - sourceId: string; + logViewReference: LogViewReference; startTimestamp: number; endTimestamp: number; query?: BuiltEsQuery; @@ -52,7 +52,7 @@ const INITIAL_STATE: LogStreamState = { const LOG_ENTRIES_CHUNK_SIZE = 200; export function useLogStream({ - sourceId, + logViewReference, startTimestamp, endTimestamp, query, @@ -85,13 +85,13 @@ export function useLogStream({ const commonFetchArguments = useMemo( () => ({ - sourceId, + logViewReference, startTimestamp, endTimestamp, query: cachedQuery, columnOverrides: columns, }), - [columns, endTimestamp, cachedQuery, sourceId, startTimestamp] + [columns, endTimestamp, cachedQuery, logViewReference, startTimestamp] ); const { diff --git a/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_after.ts b/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_after.ts index 3ee39fbda3d4..168d2e8577b8 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_after.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_after.ts @@ -11,7 +11,7 @@ import { Observable } from 'rxjs'; import { exhaustMap } from 'rxjs/operators'; import { IKibanaSearchRequest } from '@kbn/data-plugin/public'; import { LogEntryAfterCursor } from '../../../../common/log_entry'; -import { LogViewColumnConfiguration } from '../../../../common/log_views'; +import { LogViewColumnConfiguration, LogViewReference } from '../../../../common/log_views'; import { decodeOrThrow } from '../../../../common/runtime_types'; import { logEntriesSearchRequestParamsRT, @@ -34,21 +34,21 @@ export const useLogEntriesAfterRequest = ({ endTimestamp, highlightPhrase, query, - sourceId, + logViewReference, startTimestamp, }: { columnOverrides?: LogViewColumnConfiguration[]; endTimestamp: number; highlightPhrase?: string; query?: LogEntriesSearchRequestQuery; - sourceId: string; + logViewReference: LogViewReference; startTimestamp: number; }) => { const { search: fetchLogEntriesAfter, requests$: logEntriesAfterSearchRequests$ } = useDataSearch( { getRequest: useCallback( (cursor: LogEntryAfterCursor['after'], params: { size: number; extendTo?: number }) => { - return !!sourceId + return !!logViewReference ? { request: { params: logEntriesSearchRequestParamsRT.encode({ @@ -58,7 +58,7 @@ export const useLogEntriesAfterRequest = ({ highlightPhrase, query: query as JsonObject, size: params.size, - logView: { type: 'log-view-reference', logViewId: sourceId }, + logView: logViewReference, startTimestamp, }), }, @@ -66,7 +66,7 @@ export const useLogEntriesAfterRequest = ({ } : null; }, - [columnOverrides, endTimestamp, highlightPhrase, query, sourceId, startTimestamp] + [columnOverrides, endTimestamp, highlightPhrase, query, logViewReference, startTimestamp] ), parseResponses: parseLogEntriesAfterSearchResponses, } @@ -107,14 +107,14 @@ export const useFetchLogEntriesAfter = ({ endTimestamp, highlightPhrase, query, - sourceId, + logViewReference, startTimestamp, }: { columnOverrides?: LogViewColumnConfiguration[]; endTimestamp: number; highlightPhrase?: string; query?: LogEntriesSearchRequestQuery; - sourceId: string; + logViewReference: LogViewReference; startTimestamp: number; }) => { const { fetchLogEntriesAfter, logEntriesAfterSearchRequests$ } = useLogEntriesAfterRequest({ @@ -122,7 +122,7 @@ export const useFetchLogEntriesAfter = ({ endTimestamp, highlightPhrase, query, - sourceId, + logViewReference, startTimestamp, }); diff --git a/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_around.ts b/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_around.ts index 748281d5517a..a6bd8ba79428 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_around.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_around.ts @@ -9,7 +9,7 @@ import { useCallback } from 'react'; import { combineLatest, Observable, ReplaySubject } from 'rxjs'; import { last, map, startWith, switchMap } from 'rxjs/operators'; import { LogEntryCursor } from '../../../../common/log_entry'; -import { LogViewColumnConfiguration } from '../../../../common/log_views'; +import { LogViewColumnConfiguration, LogViewReference } from '../../../../common/log_views'; import { LogEntriesSearchRequestQuery } from '../../../../common/search_strategies/log_entries/log_entries'; import { flattenDataSearchResponseDescriptor } from '../../../utils/data_search'; import { useObservable, useObservableState } from '../../../utils/use_observable'; @@ -21,14 +21,14 @@ export const useFetchLogEntriesAround = ({ endTimestamp, highlightPhrase, query, - sourceId, + logViewReference, startTimestamp, }: { columnOverrides?: LogViewColumnConfiguration[]; endTimestamp: number; highlightPhrase?: string; query?: LogEntriesSearchRequestQuery; - sourceId: string; + logViewReference: LogViewReference; startTimestamp: number; }) => { const { fetchLogEntriesBefore } = useLogEntriesBeforeRequest({ @@ -36,7 +36,7 @@ export const useFetchLogEntriesAround = ({ endTimestamp, highlightPhrase, query, - sourceId, + logViewReference, startTimestamp, }); @@ -45,7 +45,7 @@ export const useFetchLogEntriesAround = ({ endTimestamp, highlightPhrase, query, - sourceId, + logViewReference, startTimestamp, }); diff --git a/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_before.ts b/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_before.ts index 581d31a28a8c..a745b5f13a19 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_before.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_before.ts @@ -11,7 +11,7 @@ import { Observable } from 'rxjs'; import { exhaustMap } from 'rxjs/operators'; import { IKibanaSearchRequest } from '@kbn/data-plugin/public'; import { LogEntryBeforeCursor } from '../../../../common/log_entry'; -import { LogViewColumnConfiguration } from '../../../../common/log_views'; +import { LogViewColumnConfiguration, LogViewReference } from '../../../../common/log_views'; import { decodeOrThrow } from '../../../../common/runtime_types'; import { logEntriesSearchRequestParamsRT, @@ -34,21 +34,21 @@ export const useLogEntriesBeforeRequest = ({ endTimestamp, highlightPhrase, query, - sourceId, + logViewReference, startTimestamp, }: { columnOverrides?: LogViewColumnConfiguration[]; endTimestamp: number; highlightPhrase?: string; query?: LogEntriesSearchRequestQuery; - sourceId: string; + logViewReference: LogViewReference; startTimestamp: number; }) => { const { search: fetchLogEntriesBefore, requests$: logEntriesBeforeSearchRequests$ } = useDataSearch({ getRequest: useCallback( (cursor: LogEntryBeforeCursor['before'], params: { size: number; extendTo?: number }) => { - return !!sourceId + return !!logViewReference ? { request: { params: logEntriesSearchRequestParamsRT.encode({ @@ -58,7 +58,7 @@ export const useLogEntriesBeforeRequest = ({ highlightPhrase, query: query as JsonObject, size: params.size, - logView: { type: 'log-view-reference', logViewId: sourceId }, + logView: logViewReference, startTimestamp: params.extendTo ?? startTimestamp, }), }, @@ -66,7 +66,7 @@ export const useLogEntriesBeforeRequest = ({ } : null; }, - [columnOverrides, endTimestamp, highlightPhrase, query, sourceId, startTimestamp] + [columnOverrides, endTimestamp, highlightPhrase, query, logViewReference, startTimestamp] ), parseResponses: parseLogEntriesBeforeSearchResponses, }); @@ -106,14 +106,14 @@ export const useFetchLogEntriesBefore = ({ endTimestamp, highlightPhrase, query, - sourceId, + logViewReference, startTimestamp, }: { columnOverrides?: LogViewColumnConfiguration[]; endTimestamp: number; highlightPhrase?: string; query?: LogEntriesSearchRequestQuery; - sourceId: string; + logViewReference: LogViewReference; startTimestamp: number; }) => { const { fetchLogEntriesBefore, logEntriesBeforeSearchRequests$ } = useLogEntriesBeforeRequest({ @@ -121,7 +121,7 @@ export const useFetchLogEntriesBefore = ({ endTimestamp, highlightPhrase, query, - sourceId, + logViewReference, startTimestamp, }); diff --git a/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.test.tsx b/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.test.tsx index fe02367e4b1f..3aa371402fcf 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.test.tsx +++ b/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.test.tsx @@ -32,7 +32,9 @@ describe('useLogSummary hook', () => { }); it('provides an empty list of buckets by default', () => { - const { result } = renderHook(() => useLogSummary('SOURCE_ID', null, null, null)); + const { result } = renderHook(() => + useLogSummary({ type: 'log-view-reference', logViewId: 'SOURCE_ID' }, null, null, null) + ); expect(result.current.buckets).toEqual([]); }); @@ -51,9 +53,15 @@ describe('useLogSummary hook', () => { .mockResolvedValueOnce(secondMockResponse); const { result, waitForNextUpdate, rerender } = renderHook( - ({ sourceId }) => useLogSummary(sourceId, startTimestamp, endTimestamp, null), + ({ logViewReference }) => + useLogSummary( + { type: 'log-view-reference', logViewId: 'SOURCE_ID' }, + startTimestamp, + endTimestamp, + null + ), { - initialProps: { sourceId: 'INITIAL_SOURCE_ID' }, + initialProps: { logViewReference: { type: 'log-view-reference', logViewId: 'SOURCE_ID' } }, } ); @@ -68,7 +76,7 @@ describe('useLogSummary hook', () => { ); expect(result.current.buckets).toEqual(firstMockResponse.data.buckets); - rerender({ sourceId: 'CHANGED_SOURCE_ID' }); + rerender({ logViewReference: { type: 'log-view-reference', logViewId: 'SOURCE_ID' } }); await waitForNextUpdate(); expect(fetchLogSummaryMock).toHaveBeenCalledTimes(2); @@ -96,7 +104,13 @@ describe('useLogSummary hook', () => { .mockResolvedValueOnce(secondMockResponse); const { result, waitForNextUpdate, rerender } = renderHook( - ({ filterQuery }) => useLogSummary('SOURCE_ID', startTimestamp, endTimestamp, filterQuery), + ({ filterQuery }) => + useLogSummary( + { type: 'log-view-reference', logViewId: 'SOURCE_ID' }, + startTimestamp, + endTimestamp, + filterQuery + ), { initialProps: { filterQuery: 'INITIAL_FILTER_QUERY' }, } @@ -134,7 +148,12 @@ describe('useLogSummary hook', () => { const firstRange = createMockDateRange(); const { waitForNextUpdate, rerender } = renderHook( ({ startTimestamp, endTimestamp }) => - useLogSummary('SOURCE_ID', startTimestamp, endTimestamp, null), + useLogSummary( + { type: 'log-view-reference', logViewId: 'SOURCE_ID' }, + startTimestamp, + endTimestamp, + null + ), { initialProps: firstRange, } @@ -171,7 +190,12 @@ describe('useLogSummary hook', () => { const firstRange = createMockDateRange(); const { waitForNextUpdate, rerender } = renderHook( ({ startTimestamp, endTimestamp }) => - useLogSummary('SOURCE_ID', startTimestamp, endTimestamp, null), + useLogSummary( + { type: 'log-view-reference', logViewId: 'SOURCE_ID' }, + startTimestamp, + endTimestamp, + null + ), { initialProps: firstRange, } diff --git a/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.tsx b/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.tsx index c4b933ab04cd..c2792300c5f3 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.tsx +++ b/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.tsx @@ -8,6 +8,7 @@ import { useEffect } from 'react'; import { exhaustMap, map, Observable } from 'rxjs'; import { HttpHandler } from '@kbn/core-http-browser'; +import { LogViewReference } from '../../../../common/log_views'; import { useObservableState, useReplaySubject } from '../../../utils/use_observable'; import { fetchLogSummary } from './api/fetch_log_summary'; import { LogEntriesSummaryRequest, LogEntriesSummaryResponse } from '../../../../common/http_api'; @@ -17,7 +18,7 @@ import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; export type LogSummaryBuckets = LogEntriesSummaryResponse['data']['buckets']; export const useLogSummary = ( - sourceId: string, + logViewReference: LogViewReference, startTimestamp: number | null, endTimestamp: number | null, filterQuery: string | null @@ -35,7 +36,7 @@ export const useLogSummary = ( pushLogSummaryBucketsArgs([ { - logView: { type: 'log-view-reference', logViewId: sourceId }, + logView: logViewReference, startTimestamp, endTimestamp, bucketSize, @@ -49,7 +50,7 @@ export const useLogSummary = ( filterQuery, pushLogSummaryBucketsArgs, services.http.fetch, - sourceId, + logViewReference, startTimestamp, ]); diff --git a/x-pack/plugins/infra/public/containers/logs/log_summary/with_summary.ts b/x-pack/plugins/infra/public/containers/logs/log_summary/with_summary.ts index 102999a19953..1dc5c7021d25 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_summary/with_summary.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_summary/with_summary.ts @@ -25,7 +25,7 @@ export const WithSummary = ({ end: number | null; }>; }) => { - const { logViewId } = useLogViewContext(); + const { logViewReference } = useLogViewContext(); const serializedParsedQuery = useSelector(useLogStreamPageStateContext(), (logStreamPageState) => logStreamPageState.matches({ hasLogViewIndices: 'initialized' }) ? stringify(logStreamPageState.context.parsedQuery) @@ -38,7 +38,7 @@ export const WithSummary = ({ const throttledEndTimestamp = useThrottle(endTimestamp, FETCH_THROTTLE_INTERVAL); const { buckets, start, end } = useLogSummary( - logViewId, + logViewReference, throttledStartTimestamp, throttledEndTimestamp, serializedParsedQuery diff --git a/x-pack/plugins/infra/public/containers/logs/view_log_in_context/view_log_in_context.ts b/x-pack/plugins/infra/public/containers/logs/view_log_in_context/view_log_in_context.ts index b22a73d77cc5..1ea8f71da129 100644 --- a/x-pack/plugins/infra/public/containers/logs/view_log_in_context/view_log_in_context.ts +++ b/x-pack/plugins/infra/public/containers/logs/view_log_in_context/view_log_in_context.ts @@ -7,10 +7,11 @@ import { useState } from 'react'; import createContainer from 'constate'; +import { LogViewReference } from '../../../../common/log_views'; import { LogEntry } from '../../../../common/log_entry'; interface ViewLogInContextProps { - sourceId: string; + logViewReference: LogViewReference; startTimestamp: number; endTimestamp: number; } @@ -27,13 +28,13 @@ export const useViewLogInContext = ( props: ViewLogInContextProps ): [ViewLogInContextState, ViewLogInContextCallbacks] => { const [contextEntry, setContextEntry] = useState(); - const { startTimestamp, endTimestamp, sourceId } = props; + const { startTimestamp, endTimestamp, logViewReference } = props; return [ { startTimestamp, endTimestamp, - sourceId, + logViewReference, contextEntry, }, { diff --git a/x-pack/plugins/infra/public/hooks/use_log_view.mock.ts b/x-pack/plugins/infra/public/hooks/use_log_view.mock.ts index cdf702f741c4..a3b2ecc4e08e 100644 --- a/x-pack/plugins/infra/public/hooks/use_log_view.mock.ts +++ b/x-pack/plugins/infra/public/hooks/use_log_view.mock.ts @@ -36,11 +36,14 @@ export const createUninitializedUseLogViewMock = load: jest.fn(), retry: jest.fn(), logView: undefined, - logViewId, + logViewReference: { type: 'log-view-reference', logViewId }, logViewStatus: undefined, resolvedLogView: undefined, update: jest.fn(), - logViewStateService: interpret(createPureLogViewStateMachine({ logViewId })), + changeLogViewReference: jest.fn(), + logViewStateService: interpret( + createPureLogViewStateMachine({ logViewReference: { type: 'log-view-reference', logViewId } }) + ), logViewStateNotifications: createLogViewNotificationChannel(), }); diff --git a/x-pack/plugins/infra/public/hooks/use_log_view.ts b/x-pack/plugins/infra/public/hooks/use_log_view.ts index 98457bda3ede..16f596eb8ce9 100644 --- a/x-pack/plugins/infra/public/hooks/use_log_view.ts +++ b/x-pack/plugins/infra/public/hooks/use_log_view.ts @@ -21,9 +21,11 @@ import { useKbnUrlStateStorageFromRouterContext } from '../utils/kbn_url_state_c import { useKibanaContextForPlugin } from './use_kibana'; export const useLogView = ({ + initialLogViewReference, logViews, useDevTools = isDevMode(), }: { + initialLogViewReference?: LogViewReference | null; logViews: ILogViewsClient; useDevTools?: boolean; }) => { @@ -41,7 +43,7 @@ export const useLogView = ({ () => createLogViewStateMachine({ initialContext: { - logViewReference: DEFAULT_LOG_VIEW, + logViewReference: initialLogViewReference ?? DEFAULT_LOG_VIEW, }, logViews, notificationChannel: logViewStateNotifications, diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/notifications.ts b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/notifications.ts index 4b5733452c03..105f911f6c78 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/notifications.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/notifications.ts @@ -5,14 +5,14 @@ * 2.0. */ -import { LogViewStatus, ResolvedLogView } from '../../../../common/log_views'; +import { LogViewReference, LogViewStatus, ResolvedLogView } from '../../../../common/log_views'; import { createNotificationChannel } from '../../xstate_helpers'; import { LogViewContext, LogViewEvent } from './types'; export type LogViewNotificationEvent = | { type: 'LOADING_LOG_VIEW_STARTED'; - logViewId: string; + logViewReference: LogViewReference; } | { type: 'LOADING_LOG_VIEW_SUCCEEDED'; @@ -29,10 +29,10 @@ export const createLogViewNotificationChannel = () => export const logViewNotificationEventSelectors = { loadingLogViewStarted: (context: LogViewContext) => - 'logViewId' in context + 'logViewReference' in context ? ({ type: 'LOADING_LOG_VIEW_STARTED', - logViewId: context.logViewId, + logViewReference: context.logViewReference, } as LogViewNotificationEvent) : undefined, loadingLogViewSucceeded: (context: LogViewContext) => diff --git a/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.tsx b/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.tsx index 4f5fb79acc76..477b04841208 100644 --- a/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.tsx +++ b/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.tsx @@ -35,7 +35,7 @@ export const RedirectToNodeLogs = ({ }: RedirectToNodeLogsType) => { const { services } = useKibanaContextForPlugin(); const { isLoading, load } = useLogView({ - logViewId: sourceId, + initialLogViewReference: { type: 'log-view-reference', logViewId: sourceId }, logViews: services.logViews.client, }); diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_providers.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_providers.tsx index 35150368b586..269f20145a48 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_providers.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_providers.tsx @@ -6,6 +6,7 @@ */ import React from 'react'; +import { persistedLogViewReferenceRT } from '../../../../common/log_views'; import { LogAnalysisSetupFlyoutStateProvider } from '../../../components/logging/log_analysis_setup/setup_flyout'; import { SourceLoadingPage } from '../../../components/source_loading_page'; import { LogEntryCategoriesModuleProvider } from '../../../containers/logs/log_analysis/modules/log_entry_categories'; @@ -14,10 +15,14 @@ import { useLogViewContext } from '../../../hooks/use_log_view'; import { ConnectedLogViewErrorPage } from '../shared/page_log_view_error'; export const LogEntryCategoriesPageProviders: React.FunctionComponent = ({ children }) => { - const { hasFailedLoading, isLoading, isUninitialized, resolvedLogView, logViewId } = + const { hasFailedLoading, isLoading, isUninitialized, resolvedLogView, logViewReference } = useLogViewContext(); const { space } = useActiveKibanaSpace(); + if (!persistedLogViewReferenceRT.is(logViewReference)) { + throw new Error('Logs ML features only support persisted Log View references'); + } + // This is a rather crude way of guarding the dependent providers against // arguments that are only made available asynchronously. Ideally, we'd use // React concurrent mode and Suspense in order to handle that more gracefully. @@ -31,7 +36,7 @@ export const LogEntryCategoriesPageProviders: React.FunctionComponent = ({ child return ( @@ -265,7 +265,7 @@ export const LogEntryCategoriesResultsContent: React.FunctionComponent< = ({ categoryId, timeRange, sourceId }) => { + logViewReference: PersistedLogViewReference; +}> = ({ categoryId, timeRange, logViewReference }) => { const { getLogEntryCategoryExamples, hasFailedLoadingLogEntryCategoryExamples, @@ -27,7 +28,7 @@ export const CategoryDetailsRow: React.FunctionComponent<{ categoryId, endTime: timeRange.endTime, exampleCount, - sourceId, + logViewReference, startTime: timeRange.startTime, }); diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/top_categories_section.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/top_categories_section.tsx index 0aabc570a89e..c9f93ee618dd 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/top_categories_section.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/top_categories_section.tsx @@ -9,6 +9,7 @@ import { EuiLoadingSpinner } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; +import { PersistedLogViewReference } from '../../../../../../common/log_views'; import { LogEntryCategory } from '../../../../../../common/log_analysis'; import { TimeRange } from '../../../../../../common/time'; import { LoadingOverlayWrapper } from '../../../../../components/loading_overlay_wrapper'; @@ -18,7 +19,7 @@ import { SortOptions, ChangeSortOptions } from '../../use_log_entry_categories_r export const TopCategoriesSection: React.FunctionComponent<{ isLoadingTopCategories?: boolean; jobId: string; - sourceId: string; + logViewReference: PersistedLogViewReference; timeRange: TimeRange; topCategories: LogEntryCategory[]; sortOptions: SortOptions; @@ -26,7 +27,7 @@ export const TopCategoriesSection: React.FunctionComponent<{ }> = ({ isLoadingTopCategories = false, jobId, - sourceId, + logViewReference, timeRange, topCategories, sortOptions, @@ -40,7 +41,7 @@ export const TopCategoriesSection: React.FunctionComponent<{ > ), }), {} ), - [expandedCategories, sourceId, timeRange] + [expandedCategories, logViewReference, timeRange] ); return ( diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_datasets.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_datasets.ts index 34358b983e12..e2f34f644eca 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_datasets.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_datasets.ts @@ -6,6 +6,7 @@ */ import type { HttpHandler } from '@kbn/core/public'; +import { PersistedLogViewReference } from '../../../../../common/log_views'; import { getLogEntryCategoryDatasetsRequestPayloadRT, @@ -15,7 +16,7 @@ import { import { decodeOrThrow } from '../../../../../common/runtime_types'; interface RequestArgs { - sourceId: string; + logViewReference: PersistedLogViewReference; startTime: number; endTime: number; } @@ -24,14 +25,14 @@ export const callGetLogEntryCategoryDatasetsAPI = async ( requestArgs: RequestArgs, fetch: HttpHandler ) => { - const { sourceId, startTime, endTime } = requestArgs; + const { logViewReference, startTime, endTime } = requestArgs; const response = await fetch(LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORY_DATASETS_PATH, { method: 'POST', body: JSON.stringify( getLogEntryCategoryDatasetsRequestPayloadRT.encode({ data: { - logView: { type: 'log-view-reference', logViewId: sourceId }, + logView: logViewReference, timeRange: { startTime, endTime, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_examples.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_examples.ts index e3b99750af71..52f9f17747b5 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_examples.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_examples.ts @@ -6,6 +6,7 @@ */ import type { HttpHandler } from '@kbn/core/public'; +import { PersistedLogViewReference } from '../../../../../common/log_views'; import { getLogEntryCategoryExamplesRequestPayloadRT, @@ -15,7 +16,7 @@ import { import { decodeOrThrow } from '../../../../../common/runtime_types'; interface RequestArgs { - sourceId: string; + logViewReference: PersistedLogViewReference; startTime: number; endTime: number; categoryId: number; @@ -26,7 +27,7 @@ export const callGetLogEntryCategoryExamplesAPI = async ( requestArgs: RequestArgs, fetch: HttpHandler ) => { - const { sourceId, startTime, endTime, categoryId, exampleCount } = requestArgs; + const { logViewReference, startTime, endTime, categoryId, exampleCount } = requestArgs; const response = await fetch(LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORY_EXAMPLES_PATH, { method: 'POST', @@ -35,7 +36,7 @@ export const callGetLogEntryCategoryExamplesAPI = async ( data: { categoryId, exampleCount, - logView: { type: 'log-view-reference', logViewId: sourceId }, + logView: logViewReference, timeRange: { startTime, endTime, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_top_log_entry_categories.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_top_log_entry_categories.ts index 93e9daf0b9cb..0cd04d999183 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_top_log_entry_categories.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_top_log_entry_categories.ts @@ -6,6 +6,7 @@ */ import type { HttpHandler } from '@kbn/core/public'; +import { PersistedLogViewReference } from '../../../../../common/log_views'; import { getLogEntryCategoriesRequestPayloadRT, @@ -16,7 +17,7 @@ import { CategoriesSort } from '../../../../../common/log_analysis'; import { decodeOrThrow } from '../../../../../common/runtime_types'; interface RequestArgs { - sourceId: string; + logViewReference: PersistedLogViewReference; startTime: number; endTime: number; categoryCount: number; @@ -28,7 +29,7 @@ export const callGetTopLogEntryCategoriesAPI = async ( requestArgs: RequestArgs, fetch: HttpHandler ) => { - const { sourceId, startTime, endTime, categoryCount, datasets, sort } = requestArgs; + const { logViewReference, startTime, endTime, categoryCount, datasets, sort } = requestArgs; const intervalDuration = endTime - startTime; const response = await fetch(LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORIES_PATH, { @@ -36,7 +37,7 @@ export const callGetTopLogEntryCategoriesAPI = async ( body: JSON.stringify( getLogEntryCategoriesRequestPayloadRT.encode({ data: { - logView: { type: 'log-view-reference', logViewId: sourceId }, + logView: logViewReference, timeRange: { startTime, endTime, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_categories_results.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_categories_results.ts index b4cfb301e040..f7e05c885f02 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_categories_results.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_categories_results.ts @@ -7,6 +7,7 @@ import { useMemo, useState } from 'react'; +import { PersistedLogViewReference } from '../../../../common/log_views'; import { GetLogEntryCategoriesSuccessResponsePayload, GetLogEntryCategoryDatasetsSuccessResponsePayload, @@ -30,7 +31,7 @@ export const useLogEntryCategoriesResults = ({ endTime, onGetLogEntryCategoryDatasetsError, onGetTopLogEntryCategoriesError, - sourceId, + logViewReference, startTime, }: { categoriesCount: number; @@ -38,7 +39,7 @@ export const useLogEntryCategoriesResults = ({ endTime: number; onGetLogEntryCategoryDatasetsError?: (error: Error) => void; onGetTopLogEntryCategoriesError?: (error: Error) => void; - sourceId: string; + logViewReference: PersistedLogViewReference; startTime: number; }) => { const [sortOptions, setSortOptions] = useState({ @@ -56,7 +57,7 @@ export const useLogEntryCategoriesResults = ({ createPromise: async () => { return await callGetTopLogEntryCategoriesAPI( { - sourceId, + logViewReference, startTime, endTime, categoryCount: categoriesCount, @@ -79,7 +80,7 @@ export const useLogEntryCategoriesResults = ({ } }, }, - [categoriesCount, endTime, filteredDatasets, sourceId, startTime, sortOptions] + [categoriesCount, endTime, filteredDatasets, logViewReference, startTime, sortOptions] ); const [getLogEntryCategoryDatasetsRequest, getLogEntryCategoryDatasets] = useTrackedPromise( @@ -87,7 +88,7 @@ export const useLogEntryCategoriesResults = ({ cancelPreviousOn: 'creation', createPromise: async () => { return await callGetLogEntryCategoryDatasetsAPI( - { sourceId, startTime, endTime }, + { logViewReference, startTime, endTime }, services.http.fetch ); }, @@ -104,7 +105,7 @@ export const useLogEntryCategoriesResults = ({ } }, }, - [categoriesCount, endTime, sourceId, startTime] + [categoriesCount, endTime, logViewReference, startTime] ); const isLoadingTopLogEntryCategories = useMemo( diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_category_examples.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_category_examples.tsx index 010bcaa47942..8152cae42644 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_category_examples.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_category_examples.tsx @@ -6,6 +6,7 @@ */ import { useMemo, useState } from 'react'; +import { PersistedLogViewReference } from '../../../../common/log_views'; import { LogEntryCategoryExample } from '../../../../common/http_api'; import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; @@ -16,13 +17,13 @@ export const useLogEntryCategoryExamples = ({ categoryId, endTime, exampleCount, - sourceId, + logViewReference, startTime, }: { categoryId: number; endTime: number; exampleCount: number; - sourceId: string; + logViewReference: PersistedLogViewReference; startTime: number; }) => { const { services } = useKibanaContextForPlugin(); @@ -37,7 +38,7 @@ export const useLogEntryCategoryExamples = ({ createPromise: async () => { return await callGetLogEntryCategoryExamplesAPI( { - sourceId, + logViewReference, startTime, endTime, categoryId, @@ -50,7 +51,7 @@ export const useLogEntryCategoryExamples = ({ setLogEntryCategoryExamples(examples); }, }, - [categoryId, endTime, exampleCount, sourceId, startTime] + [categoryId, endTime, exampleCount, logViewReference, startTime] ); const isLoadingLogEntryCategoryExamples = useMemo( diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx index f3ddc6c7cc57..43e8c0c8ddff 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx @@ -6,6 +6,7 @@ */ import React from 'react'; +import { persistedLogViewReferenceRT } from '../../../../common/log_views'; import { LogAnalysisSetupFlyoutStateProvider } from '../../../components/logging/log_analysis_setup/setup_flyout'; import { SourceLoadingPage } from '../../../components/source_loading_page'; import { LogEntryCategoriesModuleProvider } from '../../../containers/logs/log_analysis/modules/log_entry_categories'; @@ -16,8 +17,13 @@ import { useLogViewContext } from '../../../hooks/use_log_view'; import { ConnectedLogViewErrorPage } from '../shared/page_log_view_error'; export const LogEntryRatePageProviders: React.FunctionComponent = ({ children }) => { - const { hasFailedLoading, isLoading, isUninitialized, logViewId, resolvedLogView } = + const { hasFailedLoading, isLoading, isUninitialized, logViewReference, resolvedLogView } = useLogViewContext(); + + if (!persistedLogViewReferenceRT.is(logViewReference)) { + throw new Error('Logs ML features only support persisted Log Views'); + } + const { space } = useActiveKibanaSpace(); // This is a rather crude way of guarding the dependent providers against @@ -34,14 +40,14 @@ export const LogEntryRatePageProviders: React.FunctionComponent = ({ children }) ) : null} diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/expanded_row.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/expanded_row.tsx index ef5db53ebdc3..f30be3f593ed 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/expanded_row.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/expanded_row.tsx @@ -11,6 +11,7 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; import useMount from 'react-use/lib/useMount'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; +import { persistedLogViewReferenceRT } from '../../../../../../common/log_views'; import { isCategoryAnomaly, LogEntryAnomaly } from '../../../../../../common/log_analysis'; import { TimeRange } from '../../../../../../common/time/time_range'; import { LogEntryExampleMessages } from '../../../../../components/logging/log_entry_examples/log_entry_examples'; @@ -28,7 +29,11 @@ export const AnomaliesTableExpandedRow: React.FunctionComponent<{ anomaly: LogEntryAnomaly; timeRange: TimeRange; }> = ({ anomaly, timeRange }) => { - const { logViewId } = useLogViewContext(); + const { logViewReference } = useLogViewContext(); + + if (!persistedLogViewReferenceRT.is(logViewReference)) { + throw new Error('Logs ML features only support persisted Log Views'); + } const { getLogEntryExamples, @@ -39,7 +44,7 @@ export const AnomaliesTableExpandedRow: React.FunctionComponent<{ dataset: anomaly.dataset, endTime: anomaly.startTime + anomaly.duration, exampleCount: EXAMPLE_COUNT, - sourceId: logViewId, + logViewReference, startTime: anomaly.startTime, categoryId: isCategoryAnomaly(anomaly) ? anomaly.categoryId : undefined, }); diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies.ts index 7916cad0f1e0..ef39f6ac5f01 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies.ts @@ -6,6 +6,7 @@ */ import type { HttpHandler } from '@kbn/core/public'; +import { PersistedLogViewReference } from '../../../../../common/log_views'; import { getLogEntryAnomaliesRequestPayloadRT, getLogEntryAnomaliesSuccessReponsePayloadRT, @@ -15,7 +16,7 @@ import { decodeOrThrow } from '../../../../../common/runtime_types'; import { AnomaliesSort, Pagination } from '../../../../../common/log_analysis'; interface RequestArgs { - sourceId: string; + logViewReference: PersistedLogViewReference; startTime: number; endTime: number; sort: AnomaliesSort; @@ -24,13 +25,13 @@ interface RequestArgs { } export const callGetLogEntryAnomaliesAPI = async (requestArgs: RequestArgs, fetch: HttpHandler) => { - const { sourceId, startTime, endTime, sort, pagination, datasets } = requestArgs; + const { logViewReference, startTime, endTime, sort, pagination, datasets } = requestArgs; const response = await fetch(LOG_ANALYSIS_GET_LOG_ENTRY_ANOMALIES_PATH, { method: 'POST', body: JSON.stringify( getLogEntryAnomaliesRequestPayloadRT.encode({ data: { - logView: { type: 'log-view-reference', logViewId: sourceId }, + logView: logViewReference, timeRange: { startTime, endTime, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies_datasets.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies_datasets.ts index 16a8092f290f..8915f514d1bf 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies_datasets.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies_datasets.ts @@ -6,6 +6,7 @@ */ import type { HttpHandler } from '@kbn/core/public'; +import { PersistedLogViewReference } from '../../../../../common/log_views'; import { decodeOrThrow } from '../../../../../common/runtime_types'; import { getLogEntryAnomaliesDatasetsRequestPayloadRT, @@ -14,7 +15,7 @@ import { } from '../../../../../common/http_api/log_analysis'; interface RequestArgs { - sourceId: string; + logViewReference: PersistedLogViewReference; startTime: number; endTime: number; } @@ -23,13 +24,13 @@ export const callGetLogEntryAnomaliesDatasetsAPI = async ( requestArgs: RequestArgs, fetch: HttpHandler ) => { - const { sourceId, startTime, endTime } = requestArgs; + const { logViewReference, startTime, endTime } = requestArgs; const response = await fetch(LOG_ANALYSIS_GET_LOG_ENTRY_ANOMALIES_DATASETS_PATH, { method: 'POST', body: JSON.stringify( getLogEntryAnomaliesDatasetsRequestPayloadRT.encode({ data: { - logView: { type: 'log-view-reference', logViewId: sourceId }, + logView: logViewReference, timeRange: { startTime, endTime, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_examples.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_examples.ts index 0e44e5b02feb..75580caa6db8 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_examples.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_examples.ts @@ -6,6 +6,7 @@ */ import type { HttpHandler } from '@kbn/core/public'; +import { PersistedLogViewReference } from '../../../../../common/log_views'; import { getLogEntryExamplesRequestPayloadRT, @@ -15,7 +16,7 @@ import { import { decodeOrThrow } from '../../../../../common/runtime_types'; interface RequestArgs { - sourceId: string; + logViewReference: PersistedLogViewReference; startTime: number; endTime: number; dataset: string; @@ -24,7 +25,7 @@ interface RequestArgs { } export const callGetLogEntryExamplesAPI = async (requestArgs: RequestArgs, fetch: HttpHandler) => { - const { sourceId, startTime, endTime, dataset, exampleCount, categoryId } = requestArgs; + const { logViewReference, startTime, endTime, dataset, exampleCount, categoryId } = requestArgs; const response = await fetch(LOG_ANALYSIS_GET_LOG_ENTRY_RATE_EXAMPLES_PATH, { method: 'POST', body: JSON.stringify( @@ -32,7 +33,7 @@ export const callGetLogEntryExamplesAPI = async (requestArgs: RequestArgs, fetch data: { dataset, exampleCount, - logView: { type: 'log-view-reference', logViewId: sourceId }, + logView: logViewReference, timeRange: { startTime, endTime, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_anomalies_results.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_anomalies_results.ts index 80123bb10e55..f68aa20d41f0 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_anomalies_results.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_anomalies_results.ts @@ -7,6 +7,7 @@ import { useMemo, useState, useCallback, useEffect, useReducer } from 'react'; import useMount from 'react-use/lib/useMount'; +import { PersistedLogViewReference } from '../../../../common/log_views'; import { useTrackedPromise, CanceledPromiseError } from '../../../utils/use_tracked_promise'; import { callGetLogEntryAnomaliesAPI } from './service_calls/get_log_entry_anomalies'; import { callGetLogEntryAnomaliesDatasetsAPI } from './service_calls/get_log_entry_anomalies_datasets'; @@ -137,7 +138,7 @@ const STATE_DEFAULTS: ReducerStateDefaults = { export const useLogEntryAnomaliesResults = ({ endTime, startTime, - sourceId, + logViewReference, defaultSortOptions, defaultPaginationOptions, onGetLogEntryAnomaliesDatasetsError, @@ -145,7 +146,7 @@ export const useLogEntryAnomaliesResults = ({ }: { endTime: number; startTime: number; - sourceId: string; + logViewReference: PersistedLogViewReference; defaultSortOptions: AnomaliesSort; defaultPaginationOptions: Pick; onGetLogEntryAnomaliesDatasetsError?: (error: Error) => void; @@ -183,7 +184,7 @@ export const useLogEntryAnomaliesResults = ({ } = reducerState; return await callGetLogEntryAnomaliesAPI( { - sourceId, + logViewReference, startTime: queryStartTime, endTime: queryEndTime, sort: sortOptions, @@ -216,7 +217,7 @@ export const useLogEntryAnomaliesResults = ({ }, }, [ - sourceId, + logViewReference, dispatch, reducerState.timeRange, reducerState.sortOptions, @@ -294,7 +295,7 @@ export const useLogEntryAnomaliesResults = ({ cancelPreviousOn: 'creation', createPromise: async () => { return await callGetLogEntryAnomaliesDatasetsAPI( - { sourceId, startTime, endTime }, + { logViewReference, startTime, endTime }, services.http.fetch ); }, @@ -311,7 +312,7 @@ export const useLogEntryAnomaliesResults = ({ } }, }, - [endTime, sourceId, startTime] + [endTime, logViewReference, startTime] ); const isLoadingDatasets = useMemo( diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_examples.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_examples.ts index 8f6269c46c3d..a678f5deaf07 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_examples.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_examples.ts @@ -6,6 +6,7 @@ */ import { useMemo, useState } from 'react'; +import { PersistedLogViewReference } from '../../../../common/log_views'; import { LogEntryExample } from '../../../../common/log_analysis'; import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; @@ -16,14 +17,14 @@ export const useLogEntryExamples = ({ dataset, endTime, exampleCount, - sourceId, + logViewReference, startTime, categoryId, }: { dataset: string; endTime: number; exampleCount: number; - sourceId: string; + logViewReference: PersistedLogViewReference; startTime: number; categoryId?: string; }) => { @@ -36,7 +37,7 @@ export const useLogEntryExamples = ({ createPromise: async () => { return await callGetLogEntryExamplesAPI( { - sourceId, + logViewReference, startTime, endTime, dataset, @@ -50,7 +51,7 @@ export const useLogEntryExamples = ({ setLogEntryExamples(examples); }, }, - [dataset, endTime, exampleCount, sourceId, startTime] + [dataset, endTime, exampleCount, logViewReference, startTime] ); const isLoadingLogEntryExamples = useMemo( diff --git a/x-pack/plugins/infra/public/pages/logs/stream/page_logs_content.tsx b/x-pack/plugins/infra/public/pages/logs/stream/page_logs_content.tsx index 4cfd284ec453..6840ffa17f36 100644 --- a/x-pack/plugins/infra/public/pages/logs/stream/page_logs_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/stream/page_logs_content.tsx @@ -10,6 +10,7 @@ import type { Query } from '@kbn/es-query'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; import React, { useCallback, useEffect, useMemo } from 'react'; import usePrevious from 'react-use/lib/usePrevious'; +import { persistedLogViewReferenceRT } from '../../../../common/log_views'; import { LogEntry } from '../../../../common/log_entry'; import { TimeKey } from '../../../../common/time'; import { AutoSizer } from '../../../components/auto_sizer'; @@ -52,7 +53,7 @@ export const StreamPageLogsContent = React.memo<{ query: { queryString }, }, } = useKibanaContextForPlugin().services; - const { resolvedLogView, logView, logViewId } = useLogViewContext(); + const { resolvedLogView, logView, logViewReference } = useLogViewContext(); const { textScale, textWrap } = useLogViewConfigurationContext(); const { surroundingLogsId, @@ -228,10 +229,16 @@ export const StreamPageLogsContent = React.memo<{ logEntryId={flyoutLogEntryId} onCloseFlyout={closeLogEntryFlyout} onSetFieldFilter={setFilter} - sourceId={logViewId} + logViewReference={logViewReference} /> ) : null} - + { const { startTimestamp, endTimestamp } = useLogPositionStateContext(); - const { logViewId } = useLogViewContext(); + const { logViewReference } = useLogViewContext(); if (!startTimestamp || !endTimestamp) { return null; @@ -35,7 +35,7 @@ const ViewLogInContext: React.FC = ({ children }) => { {children} @@ -45,7 +45,7 @@ const ViewLogInContext: React.FC = ({ children }) => { const LogEntriesStateProvider: React.FC<{ logStreamPageState: InitializedLogStreamPageState; }> = ({ children, logStreamPageState }) => { - const { logViewId } = useLogViewContext(); + const { logViewReference } = useLogViewContext(); const { startTimestamp, endTimestamp, targetPosition } = useLogPositionStateContext(); const { context: { parsedQuery }, @@ -58,7 +58,7 @@ const LogEntriesStateProvider: React.FC<{ return ( = ({ children, logStreamPageState }) => { - const { logViewId, logView } = useLogViewContext(); + const { logViewReference, logView } = useLogViewContext(); const { topCursor, bottomCursor, entries } = useLogStreamContext(); const serializedParsedQuery = useMemo( () => stringify(logStreamPageState.context.parsedQuery), @@ -80,7 +80,7 @@ const LogHighlightsState: React.FC<{ ); const highlightsProps = { - sourceId: logViewId, + logViewReference, sourceVersion: logView?.version, entriesStart: topCursor, entriesEnd: bottomCursor, diff --git a/x-pack/plugins/infra/public/pages/logs/stream/page_view_log_in_context.tsx b/x-pack/plugins/infra/public/pages/logs/stream/page_view_log_in_context.tsx index 9b4a2ffb4185..15dbbcca7ce9 100644 --- a/x-pack/plugins/infra/public/pages/logs/stream/page_view_log_in_context.tsx +++ b/x-pack/plugins/infra/public/pages/logs/stream/page_view_log_in_context.tsx @@ -25,7 +25,7 @@ import { LogStream } from '../../../components/log_stream'; const MODAL_MARGIN = 25; export const PageViewLogInContext: React.FC = () => { - const [{ contextEntry, startTimestamp, endTimestamp, sourceId }, { setContextEntry }] = + const [{ contextEntry, startTimestamp, endTimestamp, logViewReference }, { setContextEntry }] = useViewLogInProviderContext(); const closeModal = useCallback(() => setContextEntry(undefined), [setContextEntry]); const { width: vw, height: vh } = useViewportDimensions(); @@ -56,7 +56,7 @@ export const PageViewLogInContext: React.FC = () => { ; export function getLogsHasDataFetcher(getStartServices: InfraClientStartServicesAccessor) { return async () => { const [, , { logViews }] = await getStartServices(); - const resolvedLogView = await logViews.client.getResolvedLogView(DEFAULT_SOURCE_ID); + const resolvedLogView = await logViews.client.getResolvedLogView(DEFAULT_LOG_VIEW); const logViewStatus = await logViews.client.getResolvedLogViewStatus(resolvedLogView); const hasData = logViewStatus.index === 'available'; @@ -56,7 +56,7 @@ export function getLogsOverviewDataFetcher( ): FetchData { return async (params) => { const [, { data }, { logViews }] = await getStartServices(); - const resolvedLogView = await logViews.client.getResolvedLogView(DEFAULT_SOURCE_ID); + const resolvedLogView = await logViews.client.getResolvedLogView(DEFAULT_LOG_VIEW); const { stats, series } = await fetchLogsOverview( { From 1f6ddbd871e7ac6b2d04757e57bfece36e8ce378 Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Mon, 6 Mar 2023 19:06:14 +0000 Subject: [PATCH 11/29] WIP: Update hook matches() --- .../infra/public/hooks/use_log_view.ts | 20 ++++++++++++++----- .../log_view_state/src/types.ts | 9 ++++++++- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/infra/public/hooks/use_log_view.ts b/x-pack/plugins/infra/public/hooks/use_log_view.ts index 16f596eb8ce9..e44807487b6c 100644 --- a/x-pack/plugins/infra/public/hooks/use_log_view.ts +++ b/x-pack/plugins/infra/public/hooks/use_log_view.ts @@ -25,7 +25,7 @@ export const useLogView = ({ logViews, useDevTools = isDevMode(), }: { - initialLogViewReference?: LogViewReference | null; + initialLogViewReference?: LogViewReference; logViews: ILogViewsClient; useDevTools?: boolean; }) => { @@ -71,19 +71,26 @@ export const useLogView = ({ ); const logView = useSelector(logViewStateService, (state) => - state.matches('resolving') || state.matches('checkingStatus') || state.matches('resolved') + state.matches('resolving') || + state.matches('checkingStatus') || + state.matches('resolvedPersistedLogView') || + state.matches('resolvedInlineLogView') ? state.context.logView : undefined ); const resolvedLogView = useSelector(logViewStateService, (state) => - state.matches('checkingStatus') || state.matches('resolved') + state.matches('checkingStatus') || + state.matches('resolvedPersistedLogView') || + state.matches('resolvedInlineLogView') ? state.context.resolvedLogView : undefined ); const logViewStatus = useSelector(logViewStateService, (state) => - state.matches('resolved') ? state.context.status : undefined + state.matches('resolvedPersistedLogView') || state.matches('resolvedInlineLogView') + ? state.context.status + : undefined ); const isLoadingLogView = useSelector(logViewStateService, (state) => state.matches('loading')); @@ -139,7 +146,10 @@ export const useLogView = ({ const doneState = await waitFor( logViewStateService, - (state) => state.matches('updatingFailed') || state.matches('resolved') + (state) => + state.matches('updatingFailed') || + state.matches('resolvedPersistedLogView') || + state.matches('resolvedInlineLogView') ); if (doneState.matches('updatingFailed')) { diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/types.ts b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/types.ts index 1520db856f9d..1f132656cfac 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/types.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/types.ts @@ -56,7 +56,14 @@ export type LogViewTypestate = LogViewContextWithResolvedLogView; } | { - value: 'resolved'; + value: 'resolvedPersistedLogView'; + context: LogViewContextWithReference & + LogViewContextWithLogView & + LogViewContextWithResolvedLogView & + LogViewContextWithStatus; + } + | { + value: 'resolvedInlineLogView'; context: LogViewContextWithReference & LogViewContextWithLogView & LogViewContextWithResolvedLogView & From d70b111c8fceec8e46d06bc1290a774c40dda5fe Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Wed, 8 Mar 2023 12:26:20 +0000 Subject: [PATCH 12/29] WIP: Sync to URL --- .../log_view_state/src/state_machine.ts | 12 +++++++----- .../log_view_state/src/url_state_storage_service.ts | 11 ++++++++++- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts index ae706c7abfa3..84fe5d3d2a1c 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts @@ -26,7 +26,7 @@ import { LogViewEvent, LogViewTypestate, } from './types'; -import { initializeFromUrl } from './url_state_storage_service'; +import { initializeFromUrl, updateContextInUrl } from './url_state_storage_service'; export const createPureLogViewStateMachine = (initialContext: LogViewContextWithReference) => /** @xstate-layout N4IgpgJg5mDOIC5QBkD2UBqBLMB3AxMgPIDiA+hgJICiA6mZQCJkDCAEgIIByJ1jA2gAYAuolAAHVLCwAXLKgB2YkAA9EAFkEBmAHQAmAGwB2dQYAcAVkGmAjGYMAaEAE9EAWi3qjO9WcGCLIzMbLWMLAE4AX0inNEwcAgBVAAVGDgAVaiFRJBBJaTlFZTUEG20DfUEDLUtwg3CbdXUtJ1cEDz11HSMLTzMagwtjAOjY9Gw8HQBXBSxZuQBDABssAC9IfGzlfNl5JVySz3CdGwMwrRsbCK0a1sQyiqNDCMEjcK09QT8LUZA4idwOiWqAWEDmUEIRA4jEoPDIAGVEiwWNQ+HwtrkdoV9qASkZPDoLnpwmZniTgmY7ghSTorP5fFo6lorHobL9-gkgSCwQoIcRobDyAAxDiUZDokTbKS7IoHRBWMzdT4vCxDPQ3PRUvTqnThcL+OoWVmdU7qdnjTkAJzgqCWADdwfgAErUeFEZCJdKUIhcMgisUSnISaXY4qIcm0y6XJ5mdR6Iw2IxanV6g2DY3qRPm+KTa2wW0O3nO13uz3e32I5GoxiBqUFPZh0ra7z9S6CBo9G4tFyIGl06z9JlWOzZgE6ADGAAswOOANbg+EyBYyKawfDsagsADSgoR6QyiXhftF4oEksxIYbctKFhCOksxjsF3CQSTPYQ2t0qfb6ZsJqMo6clOM7zryi7Lqu65sJuO5wvC+7pIeCJIiiaJnkGeSXrKuL3K+3RnJ8eqGPGgRUm8PjEvq5jBKE6oATEfwWrmNr2hsLr8swxDkFQdAYsG9bYao9x6BYXSkjcBrqp8RiOO+Hg6NUAzhEM6gkvUNRmgxHKTMCoLgkKCxYEsbHUOkToAJp8ZhAk4kJCCMl0MlPKqoS+O2b5tJ0jynGc+KCHowR1HogHMfmSxTNiBlGSZZmWee-EyrZJT6jYCkfARVxaDJsZaqY3Q+cYWj+YFBghYCwFzguS4rrAUXGRAxaxVZWJXjhpSZt4ng2O84Qie2njdp5eUJmchXFd1BjBVpTGAlM4gQMujopGkXpwv6p7NVhSXCV43SqfU2qqYYWVUm42rHAOcb1L12gsmV0zzYtRbLRku6VqhNboXWiWNi+3j6spfSDB84TqKdZjHAY-kRE05hfMSbLTTms2PXIvJ1SZHFkFxFA0LQm02Y2xiKsyJJNPqNxQ5Scl-hYOgBEVt6fsYqn0QxCioBAcDKNpuDfaG14hIq9T2FcjSWEEgync0XQkv4k1ZQYjQRD8SNjjMcy7MsayQPzrV2XYFQi0rt6+IE9gWFSZR09qZzNN1fRDFEaucrpPJQHrgklF4ej0yJInKRDpIeYg5hKoMZhvGUbxFfRYzIzoeYFuCnvbQgcs+Gb+oib4x1UsE4e9PYZzWLe90VaBUDgTVqeNmLF1GlU9S+FDRpkcLKkhO8Vwkqr8djknrEQLX16spcCl0poRoGE0NztxP1QvmLARPM7-eu9y+mGfVI9tV4RuXOqgSJsSIlUrRJyr8fdT+FUfeMQng8RXsGPDxehPXkvlTVAmQy9Le59JqX2JPiF8gxMyR3LtOSqYFqqrlfrvA2jcfAWH6IYGePtwjnwiCcYqHxbCqk0Jpdekw5oLTRh7d+P1P5nAUp8Dq6hRJeFVKdTovtSR2CaD+TMTQzD3TIU9KACCqECzauLOmYtiZZRqAOVhxJ7ysljCEGSTQ4xs0iEAA */ @@ -55,7 +55,7 @@ export const createPureLogViewStateMachine = (initialContext: LogViewContextWith }, }, loading: { - entry: 'notifyLoadingStarted', + entry: ['notifyLoadingStarted', 'updateContextInUrl'], invoke: { src: 'loadLogView', }, @@ -293,8 +293,8 @@ export const createLogViewStateMachine = ({ urlStateStorage, }: LogViewStateMachineDependencies) => createPureLogViewStateMachine(initialContext).withConfig({ - actions: - notificationChannel != null + actions: { + ...(notificationChannel != null ? { notifyLoadingStarted: notificationChannel.notify( logViewNotificationEventSelectors.loadingLogViewStarted @@ -306,7 +306,9 @@ export const createLogViewStateMachine = ({ logViewNotificationEventSelectors.loadingLogViewFailed ), } - : {}, + : {}), + updateContextInUrl: updateContextInUrl({ toastsService, urlStateStorage }), + }, services: { initializeFromUrl: initializeFromUrl({ toastsService, urlStateStorage }), loadLogView: (context) => diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/url_state_storage_service.ts b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/url_state_storage_service.ts index abad8ecb0a53..a6b76e2406e9 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/url_state_storage_service.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/url_state_storage_service.ts @@ -21,11 +21,20 @@ const defaultLegacySourceIdKey = 'sourceId'; interface LogViewUrlStateDependencies { logViewKey?: string; sourceIdKey?: string; - savedQueryIdKey?: string; toastsService: IToasts; urlStateStorage: IKbnUrlStateStorage; } +export const updateContextInUrl = + ({ urlStateStorage, logViewKey = defaultLogViewKey }: LogViewUrlStateDependencies) => + (context: LogViewContext, _event: LogViewEvent) => { + if (!('logViewReference' in context)) { + throw new Error('Missing keys from context needed to sync to the URL'); + } + + urlStateStorage.set(logViewKey, logViewStateInUrlRT.encode(context.logViewReference)); + }; + export const initializeFromUrl = ({ logViewKey = defaultLogViewKey, From a4857e88a25046ebecc217978faed8b986ff8050 Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Wed, 8 Mar 2023 13:34:03 +0000 Subject: [PATCH 13/29] WIP: Disable functionality where inline Log Views are not allowed --- .../components/alert_dropdown.tsx | 4 +- .../logging/inline_log_view_splash_page.tsx | 67 +++++++++++++++++++ .../infra/public/hooks/use_log_view.ts | 14 +++- .../log_entry_categories/page_content.tsx | 7 +- .../logs/log_entry_rate/page_content.tsx | 7 +- 5 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 x-pack/plugins/infra/public/components/logging/inline_log_view_splash_page.tsx diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx index a91e2d6ad92f..adb7d66b6458 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx @@ -9,6 +9,7 @@ import React, { useState, useCallback, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiPopover, EuiContextMenuItem, EuiContextMenuPanel, EuiHeaderLink } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; +import { useLogViewContext } from '../../../hooks/use_log_view'; import { AlertFlyout } from './alert_flyout'; import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; @@ -33,7 +34,8 @@ export const AlertDropdown = () => { observability, }, } = useKibanaContextForPlugin(); - const canCreateAlerts = capabilities?.logs?.save ?? false; + const { isPersistedLogView } = useLogViewContext(); + const canCreateAlerts = (capabilities?.logs?.save && isPersistedLogView) ?? false; const [popoverOpen, setPopoverOpen] = useState(false); const [flyoutVisible, setFlyoutVisible] = useState(false); diff --git a/x-pack/plugins/infra/public/components/logging/inline_log_view_splash_page.tsx b/x-pack/plugins/infra/public/components/logging/inline_log_view_splash_page.tsx new file mode 100644 index 000000000000..7248bed63d1c --- /dev/null +++ b/x-pack/plugins/infra/public/components/logging/inline_log_view_splash_page.tsx @@ -0,0 +1,67 @@ +/* + * 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 React from 'react'; +import { EuiButton } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { LazyObservabilityPageTemplateProps, useLinkProps } from '@kbn/observability-plugin/public'; +import { EuiEmptyPrompt } from '@elastic/eui'; +import { EuiText } from '@elastic/eui'; +import { PageTemplate } from '../page_template'; + +export const InlineLogViewSplashPage: React.FC = ( + templateProps +) => { + return ( + + + + ); +}; + +export const InlineLogViewSplashPrompt: React.FC = () => { + const linkProps = useLinkProps({ + app: 'logs', + pathname: '/settings', + }); + + const title = ( + + ); + + const ctaButton = ( + + + + ); + + const description = ( + + ); + + return ( + {title}} + body={ + +

{description}

+
+ } + actions={ctaButton} + /> + ); +}; diff --git a/x-pack/plugins/infra/public/hooks/use_log_view.ts b/x-pack/plugins/infra/public/hooks/use_log_view.ts index e44807487b6c..63fa05eaa4bf 100644 --- a/x-pack/plugins/infra/public/hooks/use_log_view.ts +++ b/x-pack/plugins/infra/public/hooks/use_log_view.ts @@ -9,7 +9,11 @@ import { useInterpret, useSelector } from '@xstate/react'; import createContainer from 'constate'; import { useCallback, useState } from 'react'; import { waitFor } from 'xstate/lib/waitFor'; -import { LogViewAttributes, LogViewReference } from '../../common/log_views'; +import { + LogViewAttributes, + LogViewReference, + persistedLogViewReferenceRT, +} from '../../common/log_views'; import { createLogViewNotificationChannel, createLogViewStateMachine, @@ -119,6 +123,12 @@ export const useLogView = ({ state.matches('checkingStatusFailed') ); + const isPersistedLogView = useSelector(logViewStateService, (state) => + persistedLogViewReferenceRT.is(state.context.logViewReference) + ); + + const isInlineLogView = !isPersistedLogView; + const latestLoadLogViewFailures = useSelector(logViewStateService, (state) => state.matches('loadingFailed') || state.matches('resolutionFailed') || @@ -184,6 +194,8 @@ export const useLogView = ({ resolvedLogView, logViewStatus, derivedDataView: resolvedLogView?.dataViewReference, + isInlineLogView, + isPersistedLogView, // Actions load: retry, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_content.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_content.tsx index 2f6d37ec8a97..ee42af91945d 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_content.tsx @@ -8,6 +8,7 @@ import { i18n } from '@kbn/i18n'; import React, { useCallback, useEffect } from 'react'; import type { LazyObservabilityPageTemplateProps } from '@kbn/observability-plugin/public'; +import { InlineLogViewSplashPage } from '../../../components/logging/inline_log_view_splash_page'; import { isJobStatusWithResults } from '../../../../common/log_analysis'; import { LoadingPage } from '../../../components/loading_page'; import { @@ -32,6 +33,8 @@ const logCategoriesTitle = i18n.translate('xpack.infra.logs.logCategoriesTitle', }); export const LogEntryCategoriesPageContent = () => { + const { isPersistedLogView } = useLogViewContext(); + const { hasLogAnalysisCapabilites, hasLogAnalysisReadCapabilities, @@ -52,7 +55,9 @@ export const LogEntryCategoriesPageContent = () => { } }, [fetchJobStatus, hasLogAnalysisReadCapabilities]); - if (!hasLogAnalysisCapabilites) { + if (!isPersistedLogView) { + return ; + } else if (!hasLogAnalysisCapabilites) { return ( { + const { isPersistedLogView } = useLogViewContext(); + const { hasLogAnalysisCapabilites, hasLogAnalysisReadCapabilities, @@ -89,7 +92,9 @@ export const LogEntryRatePageContent = memo(() => { } }, JOB_STATUS_POLLING_INTERVAL); - if (!hasLogAnalysisCapabilites) { + if (!isPersistedLogView) { + return ; + } else if (!hasLogAnalysisCapabilites) { return ( Date: Wed, 8 Mar 2023 14:12:21 +0000 Subject: [PATCH 14/29] WIP: Add callout to Settings page --- .../infra/public/hooks/use_log_view.ts | 5 +++ .../logs/settings/inline_log_view_callout.tsx | 42 +++++++++++++++++++ .../source_configuration_settings.tsx | 19 ++++++++- 3 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 x-pack/plugins/infra/public/pages/logs/settings/inline_log_view_callout.tsx diff --git a/x-pack/plugins/infra/public/hooks/use_log_view.ts b/x-pack/plugins/infra/public/hooks/use_log_view.ts index 63fa05eaa4bf..47e776300053 100644 --- a/x-pack/plugins/infra/public/hooks/use_log_view.ts +++ b/x-pack/plugins/infra/public/hooks/use_log_view.ts @@ -169,6 +169,10 @@ export const useLogView = ({ [logViewStateService] ); + const revertToDefaultLogView = useCallback(() => { + changeLogViewReference(DEFAULT_LOG_VIEW); + }, [changeLogViewReference]); + return { // Underlying state machine logViewStateService, @@ -202,6 +206,7 @@ export const useLogView = ({ retry, update, changeLogViewReference, + revertToDefaultLogView, }; }; diff --git a/x-pack/plugins/infra/public/pages/logs/settings/inline_log_view_callout.tsx b/x-pack/plugins/infra/public/pages/logs/settings/inline_log_view_callout.tsx new file mode 100644 index 000000000000..0102a6157b00 --- /dev/null +++ b/x-pack/plugins/infra/public/pages/logs/settings/inline_log_view_callout.tsx @@ -0,0 +1,42 @@ +/* + * 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 { EuiButton } from '@elastic/eui'; +import { EuiCallOut } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; + +export const InlineLogViewCallout = ({ + revertToDefaultLogView, +}: { + revertToDefaultLogView: () => void; +}) => { + return ( + + <> +

+ {i18n.translate('xpack.infra.logs.settings.inlineLogViewCalloutDescription', { + defaultMessage: + 'An inline Log View is currently being used, changes will be synchronized to the URL, but they will not be persisted.', + })} +

+ + + + +
+ ); +}; diff --git a/x-pack/plugins/infra/public/pages/logs/settings/source_configuration_settings.tsx b/x-pack/plugins/infra/public/pages/logs/settings/source_configuration_settings.tsx index 714bd88cd6d4..938042a6482e 100644 --- a/x-pack/plugins/infra/public/pages/logs/settings/source_configuration_settings.tsx +++ b/x-pack/plugins/infra/public/pages/logs/settings/source_configuration_settings.tsx @@ -28,6 +28,7 @@ import { LogColumnsConfigurationPanel } from './log_columns_configuration_panel' import { NameConfigurationPanel } from './name_configuration_panel'; import { LogSourceConfigurationFormErrors } from './source_configuration_form_errors'; import { useLogSourceConfigurationFormState } from './source_configuration_form_state'; +import { InlineLogViewCallout } from './inline_log_view_callout'; export const LogsSettingsPage = () => { const uiCapabilities = useKibana().services.application?.capabilities; @@ -46,8 +47,16 @@ export const LogsSettingsPage = () => { }, ]); - const { logView, hasFailedLoadingLogView, isLoading, isUninitialized, update, resolvedLogView } = - useLogViewContext(); + const { + logView, + hasFailedLoadingLogView, + isLoading, + isUninitialized, + update, + resolvedLogView, + isInlineLogView, + revertToDefaultLogView, + } = useLogViewContext(); const availableFields = useMemo( () => resolvedLogView?.fields.map((field) => field.name) ?? [], @@ -136,6 +145,12 @@ export const LogsSettingsPage = () => { ) : ( <> + {isInlineLogView && ( + + + + + )} Date: Wed, 8 Mar 2023 16:21:20 +0000 Subject: [PATCH 15/29] WIP: Fix update bug, add playground page, move ML checks in hierarchy --- .../xstate_helpers/src/index.ts | 1 + .../src/state_machine_playground.tsx | 55 +++++++++++++++++++ .../log_entry_categories/page_content.tsx | 7 +-- .../log_entry_categories/page_providers.tsx | 20 +++++-- .../logs/log_entry_rate/page_content.tsx | 7 +-- .../logs/log_entry_rate/page_providers.tsx | 20 +++++-- .../infra/public/pages/logs/page_content.tsx | 6 ++ .../services/log_views/log_views_client.ts | 7 ++- 8 files changed, 97 insertions(+), 26 deletions(-) create mode 100644 x-pack/plugins/infra/public/observability_logs/xstate_helpers/src/state_machine_playground.tsx diff --git a/x-pack/plugins/infra/public/observability_logs/xstate_helpers/src/index.ts b/x-pack/plugins/infra/public/observability_logs/xstate_helpers/src/index.ts index fa0e5da4cb4c..8e6f993a9755 100644 --- a/x-pack/plugins/infra/public/observability_logs/xstate_helpers/src/index.ts +++ b/x-pack/plugins/infra/public/observability_logs/xstate_helpers/src/index.ts @@ -9,3 +9,4 @@ export * from './invalid_state_callout'; export * from './notification_channel'; export * from './send_actions'; export * from './types'; +export * from './state_machine_playground'; diff --git a/x-pack/plugins/infra/public/observability_logs/xstate_helpers/src/state_machine_playground.tsx b/x-pack/plugins/infra/public/observability_logs/xstate_helpers/src/state_machine_playground.tsx new file mode 100644 index 000000000000..2355c0c4bea3 --- /dev/null +++ b/x-pack/plugins/infra/public/observability_logs/xstate_helpers/src/state_machine_playground.tsx @@ -0,0 +1,55 @@ +/* + * 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 { EuiButton } from '@elastic/eui'; +import React, { useCallback } from 'react'; +import { useLogViewContext } from '../../../hooks/use_log_view'; + +export const StateMachinePlayground = () => { + const { changeLogViewReference, revertToDefaultLogView, update, isLoading } = useLogViewContext(); + + const switchToInlineLogView = useCallback(() => { + changeLogViewReference({ + type: 'log-view-inline', + id: 'playground-log-view', + attributes: { + name: 'playground-log-view-name', + description: 'from the state machine playground', + logIndices: { type: 'index_name', indexName: 'logs-*' }, + logColumns: [ + { + fieldColumn: { + id: 'playground-field-column', + field: 'event.dataset', + }, + }, + ], + }, + }); + }, [changeLogViewReference]); + + const updateLogView = useCallback(() => { + update({ + name: 'Updated playground name', + }); + }, [update]); + + return ( + <> + {isLoading && 'Is loading'} + switchToInlineLogView()}> + {'Switch to inline Log View'} + + revertToDefaultLogView()}> + {'Revert to default Log View'} + + updateLogView()}> + {'Update log view'} + + + ); +}; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_content.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_content.tsx index ee42af91945d..2f6d37ec8a97 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_content.tsx @@ -8,7 +8,6 @@ import { i18n } from '@kbn/i18n'; import React, { useCallback, useEffect } from 'react'; import type { LazyObservabilityPageTemplateProps } from '@kbn/observability-plugin/public'; -import { InlineLogViewSplashPage } from '../../../components/logging/inline_log_view_splash_page'; import { isJobStatusWithResults } from '../../../../common/log_analysis'; import { LoadingPage } from '../../../components/loading_page'; import { @@ -33,8 +32,6 @@ const logCategoriesTitle = i18n.translate('xpack.infra.logs.logCategoriesTitle', }); export const LogEntryCategoriesPageContent = () => { - const { isPersistedLogView } = useLogViewContext(); - const { hasLogAnalysisCapabilites, hasLogAnalysisReadCapabilities, @@ -55,9 +52,7 @@ export const LogEntryCategoriesPageContent = () => { } }, [fetchJobStatus, hasLogAnalysisReadCapabilities]); - if (!isPersistedLogView) { - return ; - } else if (!hasLogAnalysisCapabilites) { + if (!hasLogAnalysisCapabilites) { return ( { - const { hasFailedLoading, isLoading, isUninitialized, resolvedLogView, logViewReference } = - useLogViewContext(); + const { + hasFailedLoading, + isLoading, + isUninitialized, + resolvedLogView, + logViewReference, + isPersistedLogView, + } = useLogViewContext(); const { space } = useActiveKibanaSpace(); - if (!persistedLogViewReferenceRT.is(logViewReference)) { - throw new Error('Logs ML features only support persisted Log View references'); - } - // This is a rather crude way of guarding the dependent providers against // arguments that are only made available asynchronously. Ideally, we'd use // React concurrent mode and Suspense in order to handle that more gracefully. if (space == null) { return null; + } else if (!isPersistedLogView) { + return ; } else if (hasFailedLoading) { return ; } else if (isLoading || isUninitialized) { return ; } else if (resolvedLogView != null) { + if (!persistedLogViewReferenceRT.is(logViewReference)) { + throw new Error('Logs ML features only support persisted Log View references'); + } return ( { - const { isPersistedLogView } = useLogViewContext(); - const { hasLogAnalysisCapabilites, hasLogAnalysisReadCapabilities, @@ -92,9 +89,7 @@ export const LogEntryRatePageContent = memo(() => { } }, JOB_STATUS_POLLING_INTERVAL); - if (!isPersistedLogView) { - return ; - } else if (!hasLogAnalysisCapabilites) { + if (!hasLogAnalysisCapabilites) { return ( { - const { hasFailedLoading, isLoading, isUninitialized, logViewReference, resolvedLogView } = - useLogViewContext(); - - if (!persistedLogViewReferenceRT.is(logViewReference)) { - throw new Error('Logs ML features only support persisted Log Views'); - } + const { + hasFailedLoading, + isLoading, + isUninitialized, + logViewReference, + resolvedLogView, + isPersistedLogView, + } = useLogViewContext(); const { space } = useActiveKibanaSpace(); @@ -31,11 +34,16 @@ export const LogEntryRatePageProviders: React.FunctionComponent = ({ children }) // React concurrent mode and Suspense in order to handle that more gracefully. if (space == null) { return null; + } else if (!isPersistedLogView) { + return ; } else if (isLoading || isUninitialized) { return ; } else if (hasFailedLoading) { return ; } else if (resolvedLogView != null) { + if (!persistedLogViewReferenceRT.is(logViewReference)) { + throw new Error('Logs ML features only support persisted Log Views'); + } return ( { + const enableDeveloperRoutes = isDevMode(); const uiCapabilities = useKibana().services.application?.capabilities; const { setHeaderActionMenu, theme$ } = useContext(HeaderActionMenuContext); @@ -87,6 +90,9 @@ export const LogsPageContent: React.FunctionComponent = () => { + {enableDeveloperRoutes && ( + + )} diff --git a/x-pack/plugins/infra/public/services/log_views/log_views_client.ts b/x-pack/plugins/infra/public/services/log_views/log_views_client.ts index cdcf09c2d9c6..2657a7701b28 100644 --- a/x-pack/plugins/infra/public/services/log_views/log_views_client.ts +++ b/x-pack/plugins/infra/public/services/log_views/log_views_client.ts @@ -115,13 +115,16 @@ export class LogViewsClient implements ILogViewsClient { if (inlineLogViewReferenceRT.is(logViewReference)) { const { id } = logViewReference; const attributes = decodeOrThrow( - logViewAttributesRT, + rt.partial(logViewAttributesRT.type.props), (message: string) => new PutLogViewError(`Failed to decode inline log view "${id}": ${message}"`) )(logViewAttributes); return { id, - attributes, + attributes: { + ...logViewReference.attributes, + ...attributes, + }, origin: 'inline', }; } else { From 794d5342285fddb777e5c2c21e16052e4ff4cbbd Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Thu, 9 Mar 2023 13:03:31 +0000 Subject: [PATCH 16/29] WIP: Ensure logView key stays in the URL --- .../log_view_state/src/state_machine.ts | 19 ++++++++++++- .../log_view_state/src/types.ts | 4 ++- .../src/url_state_storage_service.ts | 27 ++++++++++++++++++- 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts index 84fe5d3d2a1c..62edb5dfed33 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts @@ -26,7 +26,11 @@ import { LogViewEvent, LogViewTypestate, } from './types'; -import { initializeFromUrl, updateContextInUrl } from './url_state_storage_service'; +import { + initializeFromUrl, + updateContextInUrl, + listenForUrlChanges, +} from './url_state_storage_service'; export const createPureLogViewStateMachine = (initialContext: LogViewContextWithReference) => /** @xstate-layout N4IgpgJg5mDOIC5QBkD2UBqBLMB3AxMgPIDiA+hgJICiA6mZQCJkDCAEgIIByJ1jA2gAYAuolAAHVLCwAXLKgB2YkAA9EAFkEBmAHQAmAGwB2dQYAcAVkGmAjGYMAaEAE9EAWi3qjO9WcGCLIzMbLWMLAE4AX0inNEwcAgBVAAVGDgAVaiFRJBBJaTlFZTUEG20DfUEDLUtwg3CbdXUtJ1cEDz11HSMLTzMagwtjAOjY9Gw8HQBXBSxZuQBDABssAC9IfGzlfNl5JVySz3CdGwMwrRsbCK0a1sQyiqNDCMEjcK09QT8LUZA4idwOiWqAWEDmUEIRA4jEoPDIAGVEiwWNQ+HwtrkdoV9qASkZPDoLnpwmZniTgmY7ghSTorP5fFo6lorHobL9-gkgSCwQoIcRobDyAAxDiUZDokTbKS7IoHRBWMzdT4vCxDPQ3PRUvTqnThcL+OoWVmdU7qdnjTkAJzgqCWADdwfgAErUeFEZCJdKUIhcMgisUSnISaXY4qIcm0y6XJ5mdR6Iw2IxanV6g2DY3qRPm+KTa2wW0O3nO13uz3e32I5GoxiBqUFPZh0ra7z9S6CBo9G4tFyIGl06z9JlWOzZgE6ADGAAswOOANbg+EyBYyKawfDsagsADSgoR6QyiXhftF4oEksxIYbctKFhCOksxjsF3CQSTPYQ2t0qfb6ZsJqMo6clOM7zryi7Lqu65sJuO5wvC+7pIeCJIiiaJnkGeSXrKuL3K+3RnJ8eqGPGgRUm8PjEvq5jBKE6oATEfwWrmNr2hsLr8swxDkFQdAYsG9bYao9x6BYXSkjcBrqp8RiOO+Hg6NUAzhEM6gkvUNRmgxHKTMCoLgkKCxYEsbHUOkToAJp8ZhAk4kJCCMl0MlPKqoS+O2b5tJ0jynGc+KCHowR1HogHMfmSxTNiBlGSZZmWee-EyrZJT6jYCkfARVxaDJsZaqY3Q+cYWj+YFBghYCwFzguS4rrAUXGRAxaxVZWJXjhpSZt4ng2O84Qie2njdp5eUJmchXFd1BjBVpTGAlM4gQMujopGkXpwv6p7NVhSXCV43SqfU2qqYYWVUm42rHAOcb1L12gsmV0zzYtRbLRku6VqhNboXWiWNi+3j6spfSDB84TqKdZjHAY-kRE05hfMSbLTTms2PXIvJ1SZHFkFxFA0LQm02Y2xiKsyJJNPqNxQ5Scl-hYOgBEVt6fsYqn0QxCioBAcDKNpuDfaG14hIq9T2FcjSWEEgync0XQkv4k1ZQYjQRD8SNjjMcy7MsayQPzrV2XYFQi0rt6+IE9gWFSZR09qZzNN1fRDFEaucrpPJQHrgklF4ej0yJInKRDpIeYg5hKoMZhvGUbxFfRYzIzoeYFuCnvbQgcs+Gb+oib4x1UsE4e9PYZzWLe90VaBUDgTVqeNmLF1GlU9S+FDRpkcLKkhO8Vwkqr8djknrEQLX16spcCl0poRoGE0NztxP1QvmLARPM7-eu9y+mGfVI9tV4RuXOqgSJsSIlUrRJyr8fdT+FUfeMQng8RXsGPDxehPXkvlTVAmQy9Le59JqX2JPiF8gxMyR3LtOSqYFqqrlfrvA2jcfAWH6IYGePtwjnwiCcYqHxbCqk0Jpdekw5oLTRh7d+P1P5nAUp8Dq6hRJeFVKdTovtSR2CaD+TMTQzD3TIU9KACCqECzauLOmYtiZZRqAOVhxJ7ysljCEGSTQ4xs0iEAA */ @@ -108,20 +112,32 @@ export const createPureLogViewStateMachine = (initialContext: LogViewContextWith }, }, resolvedPersistedLogView: { + invoke: { + src: 'listenForUrlChanges', + }, entry: 'notifyLoadingSucceeded', on: { PERSIST_INLINE_LOG_VIEW: undefined, RELOAD_LOG_VIEW: { target: 'loading', }, + LOG_VIEW_URL_KEY_REMOVED: { + actions: 'updateContextInUrl', + }, }, }, resolvedInlineLogView: { + invoke: { + src: 'listenForUrlChanges', + }, entry: 'notifyLoadingSucceeded', on: { PERSIST_INLINE_LOG_VIEW: { target: 'persistingInlineLogView', }, + LOG_VIEW_URL_KEY_REMOVED: { + actions: 'updateContextInUrl', + }, }, }, persistingInlineLogView: { @@ -311,6 +327,7 @@ export const createLogViewStateMachine = ({ }, services: { initializeFromUrl: initializeFromUrl({ toastsService, urlStateStorage }), + listenForUrlChanges: listenForUrlChanges({ urlStateStorage }), loadLogView: (context) => from( 'logViewReference' in context diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/types.ts b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/types.ts index 1f132656cfac..3a7914e8ff6d 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/types.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/types.ts @@ -152,7 +152,9 @@ export type LogViewEvent = | { type: 'PERSISTING_INLINE_LOG_VIEW_SUCCEEDED'; logView: LogView } | { type: 'RETRY_PERSISTING_INLINE_LOG_VIEW'; - }; + } + | { type: 'LOG_VIEW_URL_KEY_REMOVED' } + | { type: 'LOG_VIEW_URL_KEY_CHANGED' }; export type LogViewActorRef = ActorRef; export type LogViewNotificationChannel = NotificationChannel< diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/url_state_storage_service.ts b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/url_state_storage_service.ts index a6b76e2406e9..36d69b42054f 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/url_state_storage_service.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/url_state_storage_service.ts @@ -11,6 +11,7 @@ import { IKbnUrlStateStorage, withNotifyOnErrors } from '@kbn/kibana-utils-plugi import { InvokeCreator } from 'xstate'; import * as Either from 'fp-ts/lib/Either'; import { identity, pipe } from 'fp-ts/lib/function'; +import { map } from 'rxjs'; import { createPlainError, formatErrors } from '../../../../common/runtime_types'; import { logViewReferenceRT, PersistedLogViewReference } from '../../../../common/log_views'; import { LogViewContext, LogViewEvent } from './types'; @@ -32,7 +33,9 @@ export const updateContextInUrl = throw new Error('Missing keys from context needed to sync to the URL'); } - urlStateStorage.set(logViewKey, logViewStateInUrlRT.encode(context.logViewReference)); + urlStateStorage.set(logViewKey, logViewStateInUrlRT.encode(context.logViewReference), { + replace: true, + }); }; export const initializeFromUrl = @@ -82,6 +85,28 @@ export const initializeFromUrl = } }; +// NOTE: Certain navigations within the Logs solution will remove the logView URL key, +// we want to ensure the logView key is present in the URL at all times by monitoring for it's removal. +export const listenForUrlChanges = + ({ + urlStateStorage, + logViewKey = defaultLogViewKey, + }: { + urlStateStorage: LogViewUrlStateDependencies['urlStateStorage']; + logViewKey?: LogViewUrlStateDependencies['logViewKey']; + }): InvokeCreator => + (context, event) => { + return urlStateStorage + .change$(logViewKey) + .pipe( + map((value) => + value === undefined || value === null + ? { type: 'LOG_VIEW_URL_KEY_REMOVED' } + : { type: 'LOG_VIEW_URL_KEY_CHANGED' } + ) + ); + }; + const logViewStateInUrlRT = rt.union([logViewReferenceRT, rt.null]); const sourceIdStateInUrl = rt.union([rt.string, rt.null]); From 4d8d60368140b79a59e44be89b50a3a28604482a Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Thu, 9 Mar 2023 14:13:33 +0000 Subject: [PATCH 17/29] WIP: Add service for persisting inline Log View --- .../infra/public/hooks/use_log_view.mock.ts | 3 ++ .../log_view_state/src/state_machine.ts | 30 +++++++++++++++++-- .../src/state_machine_playground.tsx | 14 +++++++-- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/infra/public/hooks/use_log_view.mock.ts b/x-pack/plugins/infra/public/hooks/use_log_view.mock.ts index a3b2ecc4e08e..3d95dfb72abb 100644 --- a/x-pack/plugins/infra/public/hooks/use_log_view.mock.ts +++ b/x-pack/plugins/infra/public/hooks/use_log_view.mock.ts @@ -41,10 +41,13 @@ export const createUninitializedUseLogViewMock = resolvedLogView: undefined, update: jest.fn(), changeLogViewReference: jest.fn(), + revertToDefaultLogView: jest.fn(), logViewStateService: interpret( createPureLogViewStateMachine({ logViewReference: { type: 'log-view-reference', logViewId } }) ), logViewStateNotifications: createLogViewNotificationChannel(), + isPersistedLogView: false, + isInlineLogView: false, }); export const createLoadingUseLogViewMock = diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts index 62edb5dfed33..a7f323b60c65 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts @@ -115,7 +115,7 @@ export const createPureLogViewStateMachine = (initialContext: LogViewContextWith invoke: { src: 'listenForUrlChanges', }, - entry: 'notifyLoadingSucceeded', + entry: ['notifyLoadingSucceeded', 'updateContextInUrl'], on: { PERSIST_INLINE_LOG_VIEW: undefined, RELOAD_LOG_VIEW: { @@ -130,7 +130,7 @@ export const createPureLogViewStateMachine = (initialContext: LogViewContextWith invoke: { src: 'listenForUrlChanges', }, - entry: 'notifyLoadingSucceeded', + entry: ['notifyLoadingSucceeded', 'updateContextInUrl'], on: { PERSIST_INLINE_LOG_VIEW: { target: 'persistingInlineLogView', @@ -263,7 +263,7 @@ export const createPureLogViewStateMachine = (initialContext: LogViewContextWith : {} ), convertInlineLogViewReferenceToPersistedLogViewReference: assign((context, event) => - 'logView' in event && inlineLogViewReferenceRT.is(context.logViewReference) + 'logView' in event && context.logViewReference.type === 'log-view-inline' ? ({ logViewReference: { type: 'log-view-reference', @@ -371,6 +371,30 @@ export const createLogViewStateMachine = ({ }) ) ), + persistInlineLogView: (context, event) => + from( + 'logViewReference' in context && + event.type === 'PERSIST_INLINE_LOG_VIEW' && + context.logViewReference.type === 'log-view-inline' + ? logViews.putLogView( + { type: 'log-view-reference', logViewId: context.logViewReference.id }, + context.logViewReference.attributes + ) + : throwError(() => new Error('Failed to persist inline Log View.')) + ).pipe( + map( + (logView): LogViewEvent => ({ + type: 'PERSISTING_INLINE_LOG_VIEW_SUCCEEDED', + logView, + }) + ), + catchError((error) => + of({ + type: 'PERSISTING_INLINE_LOG_VIEW_FAILED', + error, + }) + ) + ), resolveLogView: (context) => from( 'logView' in context diff --git a/x-pack/plugins/infra/public/observability_logs/xstate_helpers/src/state_machine_playground.tsx b/x-pack/plugins/infra/public/observability_logs/xstate_helpers/src/state_machine_playground.tsx index 2355c0c4bea3..febcb6d89bff 100644 --- a/x-pack/plugins/infra/public/observability_logs/xstate_helpers/src/state_machine_playground.tsx +++ b/x-pack/plugins/infra/public/observability_logs/xstate_helpers/src/state_machine_playground.tsx @@ -10,7 +10,8 @@ import React, { useCallback } from 'react'; import { useLogViewContext } from '../../../hooks/use_log_view'; export const StateMachinePlayground = () => { - const { changeLogViewReference, revertToDefaultLogView, update, isLoading } = useLogViewContext(); + const { changeLogViewReference, revertToDefaultLogView, update, isLoading, logViewStateService } = + useLogViewContext(); const switchToInlineLogView = useCallback(() => { changeLogViewReference({ @@ -38,14 +39,23 @@ export const StateMachinePlayground = () => { }); }, [update]); + const persistInlineLogView = useCallback(() => { + logViewStateService.send({ + type: 'PERSIST_INLINE_LOG_VIEW', + }); + }, [logViewStateService]); + return ( <> {isLoading && 'Is loading'} switchToInlineLogView()}> {'Switch to inline Log View'} + persistInlineLogView()}> + {'Persist inline Log View'} + revertToDefaultLogView()}> - {'Revert to default Log View'} + {'Revert to default (persisted) Log View'} updateLogView()}> {'Update log view'} From 94547717a7c369432c78eaa20a38c28c7d8a2ad4 Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Thu, 9 Mar 2023 14:33:46 +0000 Subject: [PATCH 18/29] WIP: Amend link-to handling --- .../public/containers/source_id/index.ts | 8 ----- .../public/containers/source_id/source_id.ts | 32 ------------------- .../src/url_state_storage_service.ts | 13 ++++++-- .../public/pages/link_to/link_to_logs.tsx | 6 ++-- .../public/pages/link_to/redirect_to_logs.tsx | 8 ++--- .../pages/link_to/redirect_to_node_logs.tsx | 10 +++--- 6 files changed, 23 insertions(+), 54 deletions(-) delete mode 100644 x-pack/plugins/infra/public/containers/source_id/index.ts delete mode 100644 x-pack/plugins/infra/public/containers/source_id/source_id.ts diff --git a/x-pack/plugins/infra/public/containers/source_id/index.ts b/x-pack/plugins/infra/public/containers/source_id/index.ts deleted file mode 100644 index 158169c82f89..000000000000 --- a/x-pack/plugins/infra/public/containers/source_id/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * 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 * from './source_id'; diff --git a/x-pack/plugins/infra/public/containers/source_id/source_id.ts b/x-pack/plugins/infra/public/containers/source_id/source_id.ts deleted file mode 100644 index f7c7c11b87fe..000000000000 --- a/x-pack/plugins/infra/public/containers/source_id/source_id.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 * as runtimeTypes from 'io-ts'; - -import { pipe } from 'fp-ts/lib/pipeable'; -import { fold } from 'fp-ts/lib/Either'; -import { constant, identity } from 'fp-ts/lib/function'; -import { useUrlState, replaceStateKeyInQueryString } from '../../utils/use_url_state'; - -const SOURCE_ID_URL_STATE_KEY = 'sourceId'; - -export const useSourceId = () => { - return useUrlState({ - defaultState: 'default', - decodeUrlState: decodeSourceIdUrlState, - encodeUrlState: encodeSourceIdUrlState, - urlStateKey: SOURCE_ID_URL_STATE_KEY, - }); -}; - -export const replaceSourceIdInQueryString = (sourceId: string) => - replaceStateKeyInQueryString(SOURCE_ID_URL_STATE_KEY, sourceId); - -const sourceIdRuntimeType = runtimeTypes.union([runtimeTypes.string, runtimeTypes.undefined]); -const encodeSourceIdUrlState = sourceIdRuntimeType.encode; -const decodeSourceIdUrlState = (value: unknown) => - pipe(sourceIdRuntimeType.decode(value), fold(constant(undefined), identity)); diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/url_state_storage_service.ts b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/url_state_storage_service.ts index 36d69b42054f..dd9098b09052 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/url_state_storage_service.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/url_state_storage_service.ts @@ -13,10 +13,15 @@ import * as Either from 'fp-ts/lib/Either'; import { identity, pipe } from 'fp-ts/lib/function'; import { map } from 'rxjs'; import { createPlainError, formatErrors } from '../../../../common/runtime_types'; -import { logViewReferenceRT, PersistedLogViewReference } from '../../../../common/log_views'; +import { + LogViewReference, + logViewReferenceRT, + PersistedLogViewReference, +} from '../../../../common/log_views'; import { LogViewContext, LogViewEvent } from './types'; +import { replaceStateKeyInQueryString } from '../../../utils/url_state'; -const defaultLogViewKey = 'logView'; +export const defaultLogViewKey = 'logView'; const defaultLegacySourceIdKey = 'sourceId'; interface LogViewUrlStateDependencies { @@ -124,3 +129,7 @@ const convertSourceIdToReference = (sourceId: string): PersistedLogViewReference logViewId: sourceId, }; }; + +// NOTE: Used by link-to components +export const replaceLogViewInQueryString = (logViewReference: LogViewReference) => + replaceStateKeyInQueryString(defaultLogViewKey, logViewReference); diff --git a/x-pack/plugins/infra/public/pages/link_to/link_to_logs.tsx b/x-pack/plugins/infra/public/pages/link_to/link_to_logs.tsx index 85d38e7f476d..60afe9c98bd5 100644 --- a/x-pack/plugins/infra/public/pages/link_to/link_to_logs.tsx +++ b/x-pack/plugins/infra/public/pages/link_to/link_to_logs.tsx @@ -26,11 +26,11 @@ export const LinkToLogsPage: React.FC = (props) => { return ( - - + + ); diff --git a/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.tsx b/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.tsx index 32bc4c909284..4d4533596fd5 100644 --- a/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.tsx +++ b/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.tsx @@ -8,27 +8,27 @@ import React from 'react'; import { match as RouteMatch, Redirect, RouteComponentProps } from 'react-router-dom'; import { flowRight } from 'lodash'; -import { replaceSourceIdInQueryString } from '../../containers/source_id'; import { replaceLogPositionInQueryString } from '../../observability_logs/log_stream_position_state/src/url_state_storage_service'; import { replaceLogFilterInQueryString } from '../../observability_logs/log_stream_query_state'; import { getFilterFromLocation, getTimeFromLocation } from './query_params'; +import { replaceLogViewInQueryString } from '../../observability_logs/log_view_state'; type RedirectToLogsType = RouteComponentProps<{}>; interface RedirectToLogsProps extends RedirectToLogsType { match: RouteMatch<{ - sourceId?: string; + logViewId?: string; }>; } export const RedirectToLogs = ({ location, match }: RedirectToLogsProps) => { - const sourceId = match.params.sourceId || 'default'; + const logViewId = match.params.logViewId || 'default'; const filter = getFilterFromLocation(location); const time = getTimeFromLocation(location); const searchString = flowRight( replaceLogFilterInQueryString({ language: 'kuery', query: filter }, time), replaceLogPositionInQueryString(time), - replaceSourceIdInQueryString(sourceId) + replaceLogViewInQueryString({ type: 'log-view-reference', logViewId }) )(''); return ; diff --git a/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.tsx b/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.tsx index 477b04841208..7be728273e5b 100644 --- a/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.tsx +++ b/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.tsx @@ -14,28 +14,28 @@ import { flowRight } from 'lodash'; import { findInventoryFields } from '../../../common/inventory_models'; import { InventoryItemType } from '../../../common/inventory_models/types'; import { LoadingPage } from '../../components/loading_page'; -import { replaceSourceIdInQueryString } from '../../containers/source_id'; import { useKibanaContextForPlugin } from '../../hooks/use_kibana'; import { useLogView } from '../../hooks/use_log_view'; import { replaceLogFilterInQueryString } from '../../observability_logs/log_stream_query_state'; import { getFilterFromLocation, getTimeFromLocation } from './query_params'; import { replaceLogPositionInQueryString } from '../../observability_logs/log_stream_position_state/src/url_state_storage_service'; +import { replaceLogViewInQueryString } from '../../observability_logs/log_view_state'; type RedirectToNodeLogsType = RouteComponentProps<{ nodeId: string; nodeType: InventoryItemType; - sourceId?: string; + logViewId?: string; }>; export const RedirectToNodeLogs = ({ match: { - params: { nodeId, nodeType, sourceId = 'default' }, + params: { nodeId, nodeType, logViewId = 'default' }, }, location, }: RedirectToNodeLogsType) => { const { services } = useKibanaContextForPlugin(); const { isLoading, load } = useLogView({ - initialLogViewReference: { type: 'log-view-reference', logViewId: sourceId }, + initialLogViewReference: { type: 'log-view-reference', logViewId }, logViews: services.logViews.client, }); @@ -65,7 +65,7 @@ export const RedirectToNodeLogs = ({ const searchString = flowRight( replaceLogFilterInQueryString({ language: 'kuery', query: filter }, time), replaceLogPositionInQueryString(time), - replaceSourceIdInQueryString(sourceId) + replaceLogViewInQueryString({ type: 'log-view-reference', logViewId }) )(''); return ; From e7137700ae79bb45e56c2815f79851f20740df2b Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Thu, 9 Mar 2023 16:35:29 +0000 Subject: [PATCH 19/29] WIP: Fix tests --- .../logging/inline_log_view_splash_page.tsx | 2 +- .../logs/log_summary/log_summary.test.tsx | 47 ++++++------------- .../pages/link_to/link_to_logs.test.tsx | 24 +++++----- x-pack/test/functional/apps/infra/link_to.ts | 3 +- 4 files changed, 31 insertions(+), 45 deletions(-) diff --git a/x-pack/plugins/infra/public/components/logging/inline_log_view_splash_page.tsx b/x-pack/plugins/infra/public/components/logging/inline_log_view_splash_page.tsx index 7248bed63d1c..9c99f31a4406 100644 --- a/x-pack/plugins/infra/public/components/logging/inline_log_view_splash_page.tsx +++ b/x-pack/plugins/infra/public/components/logging/inline_log_view_splash_page.tsx @@ -48,7 +48,7 @@ export const InlineLogViewSplashPrompt: React.FC = () => { const description = ( ); diff --git a/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.test.tsx b/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.test.tsx index 3aa371402fcf..183950edf977 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.test.tsx +++ b/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.test.tsx @@ -14,6 +14,12 @@ import { useLogSummary } from './log_summary'; import { fetchLogSummary } from './api/fetch_log_summary'; import { datemathToEpochMillis } from '../../../utils/datemath'; +const LOG_VIEW_REFERENCE = { type: 'log-view-reference' as const, logViewId: 'LOG_VIEW_ID' }; +const CHANGED_LOG_VIEW_REFERENCE = { + type: 'log-view-reference' as const, + logViewId: 'CHANGED_LOG_VIEW_ID', +}; + // Typescript doesn't know that `fetchLogSummary` is a jest mock. // We use a second variable with a type cast to help the compiler further down the line. jest.mock('./api/fetch_log_summary', () => ({ fetchLogSummary: jest.fn() })); @@ -32,9 +38,7 @@ describe('useLogSummary hook', () => { }); it('provides an empty list of buckets by default', () => { - const { result } = renderHook(() => - useLogSummary({ type: 'log-view-reference', logViewId: 'SOURCE_ID' }, null, null, null) - ); + const { result } = renderHook(() => useLogSummary(LOG_VIEW_REFERENCE, null, null, null)); expect(result.current.buckets).toEqual([]); }); @@ -53,15 +57,9 @@ describe('useLogSummary hook', () => { .mockResolvedValueOnce(secondMockResponse); const { result, waitForNextUpdate, rerender } = renderHook( - ({ logViewReference }) => - useLogSummary( - { type: 'log-view-reference', logViewId: 'SOURCE_ID' }, - startTimestamp, - endTimestamp, - null - ), + ({ logViewReference }) => useLogSummary(logViewReference, startTimestamp, endTimestamp, null), { - initialProps: { logViewReference: { type: 'log-view-reference', logViewId: 'SOURCE_ID' } }, + initialProps: { logViewReference: LOG_VIEW_REFERENCE }, } ); @@ -70,19 +68,19 @@ describe('useLogSummary hook', () => { expect(fetchLogSummaryMock).toHaveBeenCalledTimes(1); expect(fetchLogSummaryMock).toHaveBeenLastCalledWith( expect.objectContaining({ - logView: { logViewId: 'INITIAL_SOURCE_ID', type: 'log-view-reference' }, + logView: LOG_VIEW_REFERENCE, }), expect.anything() ); expect(result.current.buckets).toEqual(firstMockResponse.data.buckets); - rerender({ logViewReference: { type: 'log-view-reference', logViewId: 'SOURCE_ID' } }); + rerender({ logViewReference: CHANGED_LOG_VIEW_REFERENCE }); await waitForNextUpdate(); expect(fetchLogSummaryMock).toHaveBeenCalledTimes(2); expect(fetchLogSummaryMock).toHaveBeenLastCalledWith( expect.objectContaining({ - logView: { logViewId: 'CHANGED_SOURCE_ID', type: 'log-view-reference' }, + logView: CHANGED_LOG_VIEW_REFERENCE, }), expect.anything() ); @@ -105,12 +103,7 @@ describe('useLogSummary hook', () => { const { result, waitForNextUpdate, rerender } = renderHook( ({ filterQuery }) => - useLogSummary( - { type: 'log-view-reference', logViewId: 'SOURCE_ID' }, - startTimestamp, - endTimestamp, - filterQuery - ), + useLogSummary(LOG_VIEW_REFERENCE, startTimestamp, endTimestamp, filterQuery), { initialProps: { filterQuery: 'INITIAL_FILTER_QUERY' }, } @@ -148,12 +141,7 @@ describe('useLogSummary hook', () => { const firstRange = createMockDateRange(); const { waitForNextUpdate, rerender } = renderHook( ({ startTimestamp, endTimestamp }) => - useLogSummary( - { type: 'log-view-reference', logViewId: 'SOURCE_ID' }, - startTimestamp, - endTimestamp, - null - ), + useLogSummary(LOG_VIEW_REFERENCE, startTimestamp, endTimestamp, null), { initialProps: firstRange, } @@ -190,12 +178,7 @@ describe('useLogSummary hook', () => { const firstRange = createMockDateRange(); const { waitForNextUpdate, rerender } = renderHook( ({ startTimestamp, endTimestamp }) => - useLogSummary( - { type: 'log-view-reference', logViewId: 'SOURCE_ID' }, - startTimestamp, - endTimestamp, - null - ), + useLogSummary(LOG_VIEW_REFERENCE, startTimestamp, endTimestamp, null), { initialProps: firstRange, } diff --git a/x-pack/plugins/infra/public/pages/link_to/link_to_logs.test.tsx b/x-pack/plugins/infra/public/pages/link_to/link_to_logs.test.tsx index c6af835dad80..d3dd705a5981 100644 --- a/x-pack/plugins/infra/public/pages/link_to/link_to_logs.test.tsx +++ b/x-pack/plugins/infra/public/pages/link_to/link_to_logs.test.tsx @@ -22,6 +22,8 @@ import { LinkToLogsPage } from './link_to_logs'; jest.mock('../../hooks/use_log_view'); const useLogViewMock = useLogView as jest.MockedFunction; +const LOG_VIEW_REFERENCE = '(logViewId:default,type:log-view-reference)'; +const OTHER_LOG_VIEW_REFERENCE = '(logViewId:OTHER_SOURCE,type:log-view-reference)'; const renderRoutes = (routes: React.ReactElement) => { const history = createMemoryHistory(); @@ -71,7 +73,7 @@ describe('LinkToLogsPage component', () => { expect(history.location.pathname).toEqual('/stream'); const searchParams = new URLSearchParams(history.location.search); - expect(searchParams.get('sourceId')).toEqual('default'); + expect(searchParams.get('logView')).toEqual(LOG_VIEW_REFERENCE); expect(searchParams.get('logFilter')).toMatchInlineSnapshot( `"(query:(language:kuery,query:'FILTER_FIELD:FILTER_VALUE'),refreshInterval:(pause:!t,value:5000),timeRange:(from:'2019-02-20T12:58:09.404Z',to:'2019-02-20T14:58:09.404Z'))"` ); @@ -92,7 +94,7 @@ describe('LinkToLogsPage component', () => { expect(history.location.pathname).toEqual('/stream'); const searchParams = new URLSearchParams(history.location.search); - expect(searchParams.get('sourceId')).toEqual('OTHER_SOURCE'); + expect(searchParams.get('logView')).toEqual(OTHER_LOG_VIEW_REFERENCE); expect(searchParams.get('logFilter')).toMatchInlineSnapshot( `"(query:(language:kuery,query:''),refreshInterval:(pause:!t,value:5000))"` ); @@ -113,7 +115,7 @@ describe('LinkToLogsPage component', () => { expect(history.location.pathname).toEqual('/stream'); const searchParams = new URLSearchParams(history.location.search); - expect(searchParams.get('sourceId')).toEqual('default'); + expect(searchParams.get('logView')).toEqual(LOG_VIEW_REFERENCE); expect(searchParams.get('logFilter')).toMatchInlineSnapshot( `"(query:(language:kuery,query:'FILTER_FIELD:FILTER_VALUE'),refreshInterval:(pause:!t,value:5000),timeRange:(from:'2019-02-20T12:58:09.404Z',to:'2019-02-20T14:58:09.404Z'))"` ); @@ -134,7 +136,7 @@ describe('LinkToLogsPage component', () => { expect(history.location.pathname).toEqual('/stream'); const searchParams = new URLSearchParams(history.location.search); - expect(searchParams.get('sourceId')).toEqual('OTHER_SOURCE'); + expect(searchParams.get('logView')).toEqual(OTHER_LOG_VIEW_REFERENCE); expect(searchParams.get('logFilter')).toMatchInlineSnapshot( `"(query:(language:kuery,query:''),refreshInterval:(pause:!t,value:5000))"` ); @@ -155,7 +157,7 @@ describe('LinkToLogsPage component', () => { expect(history.location.pathname).toEqual('/stream'); const searchParams = new URLSearchParams(history.location.search); - expect(searchParams.get('sourceId')).toEqual('default'); + expect(searchParams.get('logView')).toEqual(LOG_VIEW_REFERENCE); expect(searchParams.get('logFilter')).toMatchInlineSnapshot( `"(query:(language:kuery,query:'host.name: HOST_NAME'),refreshInterval:(pause:!t,value:5000))"` ); @@ -176,7 +178,7 @@ describe('LinkToLogsPage component', () => { expect(history.location.pathname).toEqual('/stream'); const searchParams = new URLSearchParams(history.location.search); - expect(searchParams.get('sourceId')).toEqual('default'); + expect(searchParams.get('logView')).toEqual(LOG_VIEW_REFERENCE); expect(searchParams.get('logFilter')).toMatchInlineSnapshot( `"(query:(language:kuery,query:'(host.name: HOST_NAME) and (FILTER_FIELD:FILTER_VALUE)'),refreshInterval:(pause:!t,value:5000),timeRange:(from:'2019-02-20T12:58:09.404Z',to:'2019-02-20T14:58:09.404Z'))"` ); @@ -197,7 +199,7 @@ describe('LinkToLogsPage component', () => { expect(history.location.pathname).toEqual('/stream'); const searchParams = new URLSearchParams(history.location.search); - expect(searchParams.get('sourceId')).toEqual('OTHER_SOURCE'); + expect(searchParams.get('logView')).toEqual(OTHER_LOG_VIEW_REFERENCE); expect(searchParams.get('logFilter')).toMatchInlineSnapshot( `"(query:(language:kuery,query:'host.name: HOST_NAME'),refreshInterval:(pause:!t,value:5000))"` ); @@ -233,7 +235,7 @@ describe('LinkToLogsPage component', () => { expect(history.location.pathname).toEqual('/stream'); const searchParams = new URLSearchParams(history.location.search); - expect(searchParams.get('sourceId')).toEqual('default'); + expect(searchParams.get('logView')).toEqual(LOG_VIEW_REFERENCE); expect(searchParams.get('logFilter')).toMatchInlineSnapshot( `"(query:(language:kuery,query:'container.id: CONTAINER_ID'),refreshInterval:(pause:!t,value:5000))"` ); @@ -254,7 +256,7 @@ describe('LinkToLogsPage component', () => { expect(history.location.pathname).toEqual('/stream'); const searchParams = new URLSearchParams(history.location.search); - expect(searchParams.get('sourceId')).toEqual('default'); + expect(searchParams.get('logView')).toEqual(LOG_VIEW_REFERENCE); expect(searchParams.get('logFilter')).toMatchInlineSnapshot( `"(query:(language:kuery,query:'(container.id: CONTAINER_ID) and (FILTER_FIELD:FILTER_VALUE)'),refreshInterval:(pause:!t,value:5000),timeRange:(from:'2019-02-20T12:58:09.404Z',to:'2019-02-20T14:58:09.404Z'))"` ); @@ -291,7 +293,7 @@ describe('LinkToLogsPage component', () => { expect(history.location.pathname).toEqual('/stream'); const searchParams = new URLSearchParams(history.location.search); - expect(searchParams.get('sourceId')).toEqual('default'); + expect(searchParams.get('logView')).toEqual(LOG_VIEW_REFERENCE); expect(searchParams.get('logFilter')).toMatchInlineSnapshot( `"(query:(language:kuery,query:'kubernetes.pod.uid: POD_UID'),refreshInterval:(pause:!t,value:5000))"` ); @@ -310,7 +312,7 @@ describe('LinkToLogsPage component', () => { expect(history.location.pathname).toEqual('/stream'); const searchParams = new URLSearchParams(history.location.search); - expect(searchParams.get('sourceId')).toEqual('default'); + expect(searchParams.get('logView')).toEqual(LOG_VIEW_REFERENCE); expect(searchParams.get('logFilter')).toMatchInlineSnapshot( `"(query:(language:kuery,query:'(kubernetes.pod.uid: POD_UID) and (FILTER_FIELD:FILTER_VALUE)'),refreshInterval:(pause:!t,value:5000),timeRange:(from:'2019-02-20T12:58:09.404Z',to:'2019-02-20T14:58:09.404Z'))"` ); diff --git a/x-pack/test/functional/apps/infra/link_to.ts b/x-pack/test/functional/apps/infra/link_to.ts index 890f85369877..6598e0e03d6b 100644 --- a/x-pack/test/functional/apps/infra/link_to.ts +++ b/x-pack/test/functional/apps/infra/link_to.ts @@ -10,6 +10,7 @@ import { URL } from 'url'; import { FtrProviderContext } from '../../ftr_provider_context'; const ONE_HOUR = 60 * 60 * 1000; +const LOG_VIEW_REFERENCE = '(logViewId:default,type:log-view-reference)'; export default ({ getPageObjects, getService }: FtrProviderContext) => { const pageObjects = getPageObjects(['common']); @@ -51,7 +52,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { expect(parsedUrl.searchParams.get('logPosition')).to.be( `(position:(tiebreaker:0,time:${timestamp}))` ); - expect(parsedUrl.searchParams.get('sourceId')).to.be('default'); + expect(parsedUrl.searchParams.get('logView')).to.be(LOG_VIEW_REFERENCE); expect(documentTitle).to.contain('Stream - Logs - Observability - Elastic'); }); }); From 8874ed4f9ced7f42f33a46ca6a2cee8e0ca3183d Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Thu, 9 Mar 2023 17:51:29 +0000 Subject: [PATCH 20/29] WIP: Lazy load alert dropdown to avoid adding 100kb to page load bundle :O --- .../log_threshold/components/alert_dropdown.tsx | 4 ++++ .../components/lazy_alert_dropdown.tsx | 16 ++++++++++++++++ .../infra/public/alerting/log_threshold/index.ts | 2 +- .../infra/public/pages/logs/page_content.tsx | 4 ++-- 4 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 x-pack/plugins/infra/public/alerting/log_threshold/components/lazy_alert_dropdown.tsx diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx index adb7d66b6458..e28e18459765 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx @@ -106,3 +106,7 @@ export const AlertDropdown = () => { ); }; + +// Allow for lazy loading +// eslint-disable-next-line import/no-default-export +export default AlertDropdown; diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/lazy_alert_dropdown.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/lazy_alert_dropdown.tsx new file mode 100644 index 000000000000..902a3af8839e --- /dev/null +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/lazy_alert_dropdown.tsx @@ -0,0 +1,16 @@ +/* + * 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 React from 'react'; + +const LazyAlertDropdown = React.lazy(() => import('./alert_dropdown')); + +export const LazyAlertDropdownWrapper = () => ( + }> + + +); diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/index.ts b/x-pack/plugins/infra/public/alerting/log_threshold/index.ts index b6eff8ef3826..588d6008ab63 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/index.ts +++ b/x-pack/plugins/infra/public/alerting/log_threshold/index.ts @@ -6,4 +6,4 @@ */ export * from './log_threshold_rule_type'; -export { AlertDropdown } from './components/alert_dropdown'; +export { LazyAlertDropdownWrapper } from './components/lazy_alert_dropdown'; diff --git a/x-pack/plugins/infra/public/pages/logs/page_content.tsx b/x-pack/plugins/infra/public/pages/logs/page_content.tsx index 64f6556cab88..98efe6c74ad8 100644 --- a/x-pack/plugins/infra/public/pages/logs/page_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/page_content.tsx @@ -12,7 +12,7 @@ import { Switch } from 'react-router-dom'; import { Route } from '@kbn/shared-ux-router'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { HeaderMenuPortal, useLinkProps } from '@kbn/observability-plugin/public'; -import { AlertDropdown } from '../../alerting/log_threshold'; +import { LazyAlertDropdownWrapper } from '../../alerting/log_threshold'; import { HelpCenterContent } from '../../components/help_center_content'; import { useReadOnlyBadge } from '../../hooks/use_readonly_badge'; import { HeaderActionMenuContext } from '../../utils/header_action_menu_provider'; @@ -73,7 +73,7 @@ export const LogsPageContent: React.FunctionComponent = () => { {settingsTabTitle} - + Date: Thu, 9 Mar 2023 17:56:10 +0000 Subject: [PATCH 21/29] WIP: Fix tests --- .../infra/public/pages/link_to/redirect_to_logs.test.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.test.tsx b/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.test.tsx index 58ba0df004f2..c5c3e4d50758 100644 --- a/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.test.tsx +++ b/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.test.tsx @@ -20,7 +20,7 @@ describe('RedirectToLogs component', () => { expect(component).toMatchInlineSnapshot(` `); }); @@ -34,7 +34,7 @@ describe('RedirectToLogs component', () => { expect(component).toMatchInlineSnapshot(` `); }); @@ -46,7 +46,7 @@ describe('RedirectToLogs component', () => { expect(component).toMatchInlineSnapshot(` `); }); From 4ab9bd5e97daf78c62913e6d2a290742cb869252 Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Thu, 9 Mar 2023 18:06:56 +0000 Subject: [PATCH 22/29] WIP: Improve messaging --- .../components/alert_dropdown.tsx | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx index e28e18459765..df324169c98e 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx @@ -27,6 +27,20 @@ const readOnlyUserTooltipTitle = i18n.translate( } ); +const inlineLogViewTooltipTitle = i18n.translate( + 'xpack.infra.logs.alertDropdown.inlineLogViewCreateAlertTitle', + { + defaultMessage: 'Inline Log View', + } +); + +const inlineLogViewTooltipContent = i18n.translate( + 'xpack.infra.logs.alertDropdown.inlineLogViewCreateAlertContent', + { + defaultMessage: 'Creating alerts is not supported with inline Log Views', + } +); + export const AlertDropdown = () => { const { services: { @@ -35,7 +49,8 @@ export const AlertDropdown = () => { }, } = useKibanaContextForPlugin(); const { isPersistedLogView } = useLogViewContext(); - const canCreateAlerts = (capabilities?.logs?.save && isPersistedLogView) ?? false; + const readOnly = !capabilities?.logs?.save; + const canCreateAlerts = (!readOnly && isPersistedLogView) ?? false; const [popoverOpen, setPopoverOpen] = useState(false); const [flyoutVisible, setFlyoutVisible] = useState(false); @@ -63,8 +78,20 @@ export const AlertDropdown = () => { icon="bell" key="createLink" onClick={openFlyout} - toolTipContent={!canCreateAlerts ? readOnlyUserTooltipContent : undefined} - toolTipTitle={!canCreateAlerts ? readOnlyUserTooltipTitle : undefined} + toolTipContent={ + !canCreateAlerts + ? readOnly + ? readOnlyUserTooltipContent + : inlineLogViewTooltipContent + : undefined + } + toolTipTitle={ + !canCreateAlerts + ? readOnly + ? readOnlyUserTooltipTitle + : inlineLogViewTooltipTitle + : undefined + } > { /> , ]; - }, [manageRulesLinkProps, canCreateAlerts, openFlyout]); + }, [canCreateAlerts, openFlyout, readOnly, manageRulesLinkProps]); return ( <> From 55a5bd9930ce11c200a1315fc68b439bd3671812 Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Fri, 10 Mar 2023 14:32:18 +0000 Subject: [PATCH 23/29] Just use .type key rather than io-ts type --- .../components/expression_editor/editor.tsx | 8 ++------ x-pack/plugins/infra/public/hooks/use_log_view.ts | 11 ++++------- .../log_view_state/src/state_machine.ts | 8 ++------ .../logs/log_entry_categories/page_providers.tsx | 3 +-- .../pages/logs/log_entry_rate/page_providers.tsx | 3 +-- .../logs/log_entry_rate/page_results_content.tsx | 3 +-- .../sections/anomalies/expanded_row.tsx | 3 +-- .../public/pages/logs/stream/page_logs_content.tsx | 3 +-- .../public/services/log_views/log_views_client.ts | 5 ++--- 9 files changed, 15 insertions(+), 32 deletions(-) diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx index 35fb962911eb..4b9a8c15d2cf 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx @@ -13,11 +13,7 @@ import { ForLastExpression, RuleTypeParamsExpressionProps, } from '@kbn/triggers-actions-ui-plugin/public'; -import { - PersistedLogViewReference, - persistedLogViewReferenceRT, - ResolvedLogViewField, -} from '../../../../../common/log_views'; +import { PersistedLogViewReference, ResolvedLogViewField } from '../../../../../common/log_views'; import { Comparator, isOptimizableGroupedThreshold, @@ -158,7 +154,7 @@ export const Editor: React.FC(false); const { logViewReference, resolvedLogView } = useLogViewContext(); - if (!persistedLogViewReferenceRT.is(logViewReference)) { + if (logViewReference.type !== 'log-view-reference') { throw new Error('The Log Threshold rule type only supports persisted Log Views'); } diff --git a/x-pack/plugins/infra/public/hooks/use_log_view.ts b/x-pack/plugins/infra/public/hooks/use_log_view.ts index 47e776300053..258fbd76850f 100644 --- a/x-pack/plugins/infra/public/hooks/use_log_view.ts +++ b/x-pack/plugins/infra/public/hooks/use_log_view.ts @@ -9,11 +9,7 @@ import { useInterpret, useSelector } from '@xstate/react'; import createContainer from 'constate'; import { useCallback, useState } from 'react'; import { waitFor } from 'xstate/lib/waitFor'; -import { - LogViewAttributes, - LogViewReference, - persistedLogViewReferenceRT, -} from '../../common/log_views'; +import { LogViewAttributes, LogViewReference } from '../../common/log_views'; import { createLogViewNotificationChannel, createLogViewStateMachine, @@ -123,8 +119,9 @@ export const useLogView = ({ state.matches('checkingStatusFailed') ); - const isPersistedLogView = useSelector(logViewStateService, (state) => - persistedLogViewReferenceRT.is(state.context.logViewReference) + const isPersistedLogView = useSelector( + logViewStateService, + (state) => state.context.logViewReference.type === 'log-view-reference' ); const isInlineLogView = !isPersistedLogView; diff --git a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts index a7f323b60c65..2074119bb329 100644 --- a/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts +++ b/x-pack/plugins/infra/public/observability_logs/log_view_state/src/state_machine.ts @@ -9,10 +9,6 @@ import { IToasts } from '@kbn/core/public'; import { IKbnUrlStateStorage } from '@kbn/kibana-utils-plugin/public'; import { catchError, from, map, of, throwError } from 'rxjs'; import { createMachine, actions, assign } from 'xstate'; -import { - inlineLogViewReferenceRT, - persistedLogViewReferenceRT, -} from '../../../../common/log_views'; import { ILogViewsClient } from '../../../services/log_views'; import { NotificationChannel } from '../../xstate_helpers'; import { LogViewNotificationEvent, logViewNotificationEventSelectors } from './notifications'; @@ -273,7 +269,7 @@ export const createPureLogViewStateMachine = (initialContext: LogViewContextWith : {} ), updateLogViewReference: assign((context, event) => - 'attributes' in event && inlineLogViewReferenceRT.is(context.logViewReference) + 'attributes' in event && context.logViewReference.type === 'log-view-inline' ? ({ logViewReference: { ...context.logViewReference, @@ -288,7 +284,7 @@ export const createPureLogViewStateMachine = (initialContext: LogViewContextWith }, guards: { isPersistedLogView: (context, event) => - persistedLogViewReferenceRT.is(context.logViewReference), + context.logViewReference.type === 'log-view-reference', }, } ); diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_providers.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_providers.tsx index 24a56da6c78f..bc8e6fbb5a4f 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_providers.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_providers.tsx @@ -7,7 +7,6 @@ import React from 'react'; import { InlineLogViewSplashPage } from '../../../components/logging/inline_log_view_splash_page'; -import { persistedLogViewReferenceRT } from '../../../../common/log_views'; import { LogAnalysisSetupFlyoutStateProvider } from '../../../components/logging/log_analysis_setup/setup_flyout'; import { SourceLoadingPage } from '../../../components/source_loading_page'; import { LogEntryCategoriesModuleProvider } from '../../../containers/logs/log_analysis/modules/log_entry_categories'; @@ -38,7 +37,7 @@ export const LogEntryCategoriesPageProviders: React.FunctionComponent = ({ child } else if (isLoading || isUninitialized) { return ; } else if (resolvedLogView != null) { - if (!persistedLogViewReferenceRT.is(logViewReference)) { + if (logViewReference.type === 'log-view-inline') { throw new Error('Logs ML features only support persisted Log View references'); } return ( diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx index 248fc4e75284..2d38704cbca0 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx @@ -7,7 +7,6 @@ import React from 'react'; import { InlineLogViewSplashPage } from '../../../components/logging/inline_log_view_splash_page'; -import { persistedLogViewReferenceRT } from '../../../../common/log_views'; import { LogAnalysisSetupFlyoutStateProvider } from '../../../components/logging/log_analysis_setup/setup_flyout'; import { SourceLoadingPage } from '../../../components/source_loading_page'; import { LogEntryCategoriesModuleProvider } from '../../../containers/logs/log_analysis/modules/log_entry_categories'; @@ -41,7 +40,7 @@ export const LogEntryRatePageProviders: React.FunctionComponent = ({ children }) } else if (hasFailedLoading) { return ; } else if (resolvedLogView != null) { - if (!persistedLogViewReferenceRT.is(logViewReference)) { + if (logViewReference.type === 'log-view-inline') { throw new Error('Logs ML features only support persisted Log Views'); } return ( diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_results_content.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_results_content.tsx index 6a21b7be5052..2b274efcd566 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_results_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_results_content.tsx @@ -14,7 +14,6 @@ import { encode } from '@kbn/rison'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { MLJobsAwaitingNodeWarning } from '@kbn/ml-plugin/public'; import { useTrackPageview } from '@kbn/observability-plugin/public'; -import { persistedLogViewReferenceRT } from '../../../../common/log_views'; import { isJobStatusWithResults } from '../../../../common/log_analysis'; import { TimeKey } from '../../../../common/time'; import { @@ -55,7 +54,7 @@ export const LogEntryRateResultsContent: React.FunctionComponent<{ const { logViewReference, logViewStatus } = useLogViewContext(); - if (!persistedLogViewReferenceRT.is(logViewReference)) { + if (logViewReference.type === 'log-view-inline') { throw new Error('Logs ML features only support persisted Log Views'); } diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/expanded_row.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/expanded_row.tsx index f30be3f593ed..493b5c4077c6 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/expanded_row.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/expanded_row.tsx @@ -11,7 +11,6 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; import useMount from 'react-use/lib/useMount'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; -import { persistedLogViewReferenceRT } from '../../../../../../common/log_views'; import { isCategoryAnomaly, LogEntryAnomaly } from '../../../../../../common/log_analysis'; import { TimeRange } from '../../../../../../common/time/time_range'; import { LogEntryExampleMessages } from '../../../../../components/logging/log_entry_examples/log_entry_examples'; @@ -31,7 +30,7 @@ export const AnomaliesTableExpandedRow: React.FunctionComponent<{ }> = ({ anomaly, timeRange }) => { const { logViewReference } = useLogViewContext(); - if (!persistedLogViewReferenceRT.is(logViewReference)) { + if (logViewReference.type === 'log-view-inline') { throw new Error('Logs ML features only support persisted Log Views'); } diff --git a/x-pack/plugins/infra/public/pages/logs/stream/page_logs_content.tsx b/x-pack/plugins/infra/public/pages/logs/stream/page_logs_content.tsx index 6840ffa17f36..701cbeee2b6e 100644 --- a/x-pack/plugins/infra/public/pages/logs/stream/page_logs_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/stream/page_logs_content.tsx @@ -10,7 +10,6 @@ import type { Query } from '@kbn/es-query'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; import React, { useCallback, useEffect, useMemo } from 'react'; import usePrevious from 'react-use/lib/usePrevious'; -import { persistedLogViewReferenceRT } from '../../../../common/log_views'; import { LogEntry } from '../../../../common/log_entry'; import { TimeKey } from '../../../../common/time'; import { AutoSizer } from '../../../components/auto_sizer'; @@ -234,7 +233,7 @@ export const StreamPageLogsContent = React.memo<{ ) : null} { - if (inlineLogViewReferenceRT.is(logViewReference)) { + if (logViewReference.type === 'log-view-inline') { return { ...logViewReference, origin: 'inline', @@ -112,7 +111,7 @@ export class LogViewsClient implements ILogViewsClient { logViewReference: LogViewReference, logViewAttributes: Partial ): Promise { - if (inlineLogViewReferenceRT.is(logViewReference)) { + if (logViewReference.type === 'log-view-inline') { const { id } = logViewReference; const attributes = decodeOrThrow( rt.partial(logViewAttributesRT.type.props), From b288c094ad438ed16c825264ccd223aba7e96bb2 Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Tue, 28 Mar 2023 12:22:00 +0100 Subject: [PATCH 24/29] Use one constants location --- x-pack/plugins/infra/common/constants.ts | 7 ------- .../plugins/infra/public/utils/logs_overview_fetchers.ts | 3 ++- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/infra/common/constants.ts b/x-pack/plugins/infra/common/constants.ts index 77e9d36a90bb..9fcb488e02fd 100644 --- a/x-pack/plugins/infra/common/constants.ts +++ b/x-pack/plugins/infra/common/constants.ts @@ -5,13 +5,6 @@ * 2.0. */ -export const DEFAULT_SOURCE_ID = 'default'; -const DEFAULT_LOG_VIEW_ID = 'default'; -export const DEFAULT_LOG_VIEW = { - type: 'log-view-reference' as const, - logViewId: DEFAULT_LOG_VIEW_ID, -}; - export const METRICS_INDEX_PATTERN = 'metrics-*,metricbeat-*'; export const LOGS_INDEX_PATTERN = 'logs-*,filebeat-*,kibana_sample_data_logs*'; export const METRICS_APP = 'metrics'; diff --git a/x-pack/plugins/infra/public/utils/logs_overview_fetchers.ts b/x-pack/plugins/infra/public/utils/logs_overview_fetchers.ts index 2fd92df0e3f4..e76aad6ec70d 100644 --- a/x-pack/plugins/infra/public/utils/logs_overview_fetchers.ts +++ b/x-pack/plugins/infra/public/utils/logs_overview_fetchers.ts @@ -12,8 +12,9 @@ import { FetchDataParams, LogsFetchDataResponse, } from '@kbn/observability-plugin/public'; -import { DEFAULT_LOG_VIEW, TIMESTAMP_FIELD } from '../../common/constants'; +import { TIMESTAMP_FIELD } from '../../common/constants'; import { InfraClientStartDeps, InfraClientStartServicesAccessor } from '../types'; +import { DEFAULT_LOG_VIEW } from '../observability_logs/log_view_state'; interface StatsAggregation { buckets: Array<{ From e24eb795507e7a71a240a3270aeec07058554d3b Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Tue, 28 Mar 2023 13:19:34 +0100 Subject: [PATCH 25/29] Full width callout --- .../pages/logs/settings/source_configuration_settings.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/infra/public/pages/logs/settings/source_configuration_settings.tsx b/x-pack/plugins/infra/public/pages/logs/settings/source_configuration_settings.tsx index b35a472ecb64..6ee20c00b9e6 100644 --- a/x-pack/plugins/infra/public/pages/logs/settings/source_configuration_settings.tsx +++ b/x-pack/plugins/infra/public/pages/logs/settings/source_configuration_settings.tsx @@ -152,8 +152,10 @@ export const LogsSettingsPage = () => { <> {isInlineLogView && ( - - + + + + )} From 81fd520703cc3b27a72711f5db2ab8ac5d514fe0 Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Tue, 28 Mar 2023 13:42:19 +0100 Subject: [PATCH 26/29] Revert to default persisted Log View directly on ML pages --- .../logging/inline_log_view_splash_page.tsx | 33 +++++++++++-------- .../log_entry_categories/page_providers.tsx | 3 +- .../logs/log_entry_rate/page_providers.tsx | 3 +- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/x-pack/plugins/infra/public/components/logging/inline_log_view_splash_page.tsx b/x-pack/plugins/infra/public/components/logging/inline_log_view_splash_page.tsx index 9c99f31a4406..cebe7ea21d9c 100644 --- a/x-pack/plugins/infra/public/components/logging/inline_log_view_splash_page.tsx +++ b/x-pack/plugins/infra/public/components/logging/inline_log_view_splash_page.tsx @@ -8,27 +8,27 @@ import React from 'react'; import { EuiButton } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import { LazyObservabilityPageTemplateProps, useLinkProps } from '@kbn/observability-plugin/public'; +import { LazyObservabilityPageTemplateProps } from '@kbn/observability-plugin/public'; import { EuiEmptyPrompt } from '@elastic/eui'; import { EuiText } from '@elastic/eui'; import { PageTemplate } from '../page_template'; -export const InlineLogViewSplashPage: React.FC = ( - templateProps -) => { +type InlineLogViewSplashPageProps = { + revertToDefaultLogView: () => void; +} & LazyObservabilityPageTemplateProps; + +export const InlineLogViewSplashPage: React.FC = (props) => { + const { revertToDefaultLogView, ...templateProps } = props; return ( - + ); }; -export const InlineLogViewSplashPrompt: React.FC = () => { - const linkProps = useLinkProps({ - app: 'logs', - pathname: '/settings', - }); - +export const InlineLogViewSplashPrompt: React.FC<{ + revertToDefaultLogView: InlineLogViewSplashPageProps['revertToDefaultLogView']; +}> = ({ revertToDefaultLogView }) => { const title = ( { ); const ctaButton = ( - + ); @@ -48,7 +53,7 @@ export const InlineLogViewSplashPrompt: React.FC = () => { const description = ( ); diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_providers.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_providers.tsx index bc8e6fbb5a4f..6e1d3f4a4f0b 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_providers.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_providers.tsx @@ -22,6 +22,7 @@ export const LogEntryCategoriesPageProviders: React.FunctionComponent = ({ child resolvedLogView, logViewReference, isPersistedLogView, + revertToDefaultLogView, } = useLogViewContext(); const { space } = useActiveKibanaSpace(); @@ -31,7 +32,7 @@ export const LogEntryCategoriesPageProviders: React.FunctionComponent = ({ child if (space == null) { return null; } else if (!isPersistedLogView) { - return ; + return ; } else if (hasFailedLoading) { return ; } else if (isLoading || isUninitialized) { diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx index 2d38704cbca0..7e1381cbd4f2 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_providers.tsx @@ -24,6 +24,7 @@ export const LogEntryRatePageProviders: React.FunctionComponent = ({ children }) logViewReference, resolvedLogView, isPersistedLogView, + revertToDefaultLogView, } = useLogViewContext(); const { space } = useActiveKibanaSpace(); @@ -34,7 +35,7 @@ export const LogEntryRatePageProviders: React.FunctionComponent = ({ children }) if (space == null) { return null; } else if (!isPersistedLogView) { - return ; + return ; } else if (isLoading || isUninitialized) { return ; } else if (hasFailedLoading) { From a1fa8fd058f133d4d16b6b26d5195cc5bc25bf10 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 28 Mar 2023 13:29:15 +0000 Subject: [PATCH 27/29] [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' --- .../src/state_machine_playground.tsx | 24 +++++++++++++++---- .../logs/settings/inline_log_view_callout.tsx | 7 +++++- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/infra/public/observability_logs/xstate_helpers/src/state_machine_playground.tsx b/x-pack/plugins/infra/public/observability_logs/xstate_helpers/src/state_machine_playground.tsx index febcb6d89bff..78f1c5f15dee 100644 --- a/x-pack/plugins/infra/public/observability_logs/xstate_helpers/src/state_machine_playground.tsx +++ b/x-pack/plugins/infra/public/observability_logs/xstate_helpers/src/state_machine_playground.tsx @@ -48,16 +48,32 @@ export const StateMachinePlayground = () => { return ( <> {isLoading && 'Is loading'} - switchToInlineLogView()}> + switchToInlineLogView()} + > {'Switch to inline Log View'} - persistInlineLogView()}> + persistInlineLogView()} + > {'Persist inline Log View'} - revertToDefaultLogView()}> + revertToDefaultLogView()} + > {'Revert to default (persisted) Log View'} - updateLogView()}> + updateLogView()} + > {'Update log view'} diff --git a/x-pack/plugins/infra/public/pages/logs/settings/inline_log_view_callout.tsx b/x-pack/plugins/infra/public/pages/logs/settings/inline_log_view_callout.tsx index 0102a6157b00..ed332f97ea47 100644 --- a/x-pack/plugins/infra/public/pages/logs/settings/inline_log_view_callout.tsx +++ b/x-pack/plugins/infra/public/pages/logs/settings/inline_log_view_callout.tsx @@ -30,7 +30,12 @@ export const InlineLogViewCallout = ({ 'An inline Log View is currently being used, changes will be synchronized to the URL, but they will not be persisted.', })}

- + Date: Wed, 29 Mar 2023 10:54:12 +0100 Subject: [PATCH 28/29] Slightly alter import path (to reduce the page load bundle size) --- x-pack/plugins/infra/public/utils/logs_overview_fetchers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/infra/public/utils/logs_overview_fetchers.ts b/x-pack/plugins/infra/public/utils/logs_overview_fetchers.ts index e76aad6ec70d..511ef829553b 100644 --- a/x-pack/plugins/infra/public/utils/logs_overview_fetchers.ts +++ b/x-pack/plugins/infra/public/utils/logs_overview_fetchers.ts @@ -14,7 +14,7 @@ import { } from '@kbn/observability-plugin/public'; import { TIMESTAMP_FIELD } from '../../common/constants'; import { InfraClientStartDeps, InfraClientStartServicesAccessor } from '../types'; -import { DEFAULT_LOG_VIEW } from '../observability_logs/log_view_state'; +import { DEFAULT_LOG_VIEW } from '../observability_logs/log_view_state/src/defaults'; interface StatsAggregation { buckets: Array<{ From 665a45984b2e1eb83af1bd4cb8afe95bf8eda4b2 Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Wed, 29 Mar 2023 11:46:54 +0100 Subject: [PATCH 29/29] Update reference from merge --- .../components/alert_details_app_section/index.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_details_app_section/index.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_details_app_section/index.tsx index ad5ef8a99f23..bedd7a127394 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_details_app_section/index.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_details_app_section/index.tsx @@ -42,7 +42,10 @@ const AlertDetailsAppSection = ({ rule, alert }: AlertDetailsAppSectionProps) =>