Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Logs Explorer][Discover] Move Logs Overview into Discover codebase #180262

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
9e09084
refactor(unified-doc-viewer): switch to dynamic utility
Apr 3, 2024
47a094c
wip(unified-doc-viewer): push down logs overview doc view
Apr 4, 2024
511b86b
wip(unified-doc-viewer): support enable/disable doc views
Apr 5, 2024
16473ec
wip(unified-doc-viewer): move ui actions
Apr 5, 2024
3714e80
wip(unified-doc-viewer): minor naming changes
Apr 5, 2024
91062be
wip(unified-doc-viewer): move constants into discover-utils
Apr 5, 2024
b97e8be
wip(unified-doc-viewer): move all required components
Apr 8, 2024
6e9438e
wip(unified-doc-viewer): disable e2e tests for logs explorer flyout
Apr 8, 2024
bbee341
wip(unified-doc-viewer): remove flyout code from logs explorer
Apr 8, 2024
319ca9a
wip(unified-doc-viewer): update doc view registry code
Apr 8, 2024
142239f
refactor(logs-explorer): disable legacy code
Apr 8, 2024
9c981a7
Merge branch 'main' into refactor/push-flyout-down-to-discover
tonyghiani Apr 8, 2024
f08fe44
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Apr 8, 2024
ec4ccc7
refactor(unified-doc-views): update clone for doc views
Apr 8, 2024
fd62031
Merge branch 'refactor/push-flyout-down-to-discover' of github.com:to…
Apr 8, 2024
e6a13cd
Merge branch 'main' into refactor/push-flyout-down-to-discover
tonyghiani Apr 8, 2024
9c4cae4
refactor(unified-doc-views): i18n lint
Apr 9, 2024
55f2714
refactor(logs-explorer): remove moced code
Apr 9, 2024
54367cd
refactor(unified-doc-views): update data test subj
Apr 9, 2024
40b3148
Merge branch 'main' into refactor/push-flyout-down-to-discover
tonyghiani Apr 9, 2024
eae46a9
refactor(logs-explorer): add doc comment
Apr 9, 2024
f1b12a9
Merge branch 'main' into refactor/push-flyout-down-to-discover
tonyghiani Apr 9, 2024
67c22e4
Merge branch 'main' into refactor/push-flyout-down-to-discover
tonyghiani Apr 9, 2024
aa49b05
Merge branch 'main' into refactor/push-flyout-down-to-discover
tonyghiani Apr 10, 2024
34b7868
Merge branch 'main' into refactor/push-flyout-down-to-discover
tonyghiani Apr 11, 2024
a04ed72
Merge branch 'main' into refactor/push-flyout-down-to-discover
tonyghiani Apr 11, 2024
18a59f2
refactor(unified-doc-viewer): assign logs overview doc view ownership
Apr 12, 2024
37e5542
refactor(unified-doc-viewer): port tests from e2e
Apr 12, 2024
540766e
refactor(unified-doc-viewer): remove legacy e2e flyout tests
Apr 12, 2024
9972211
Merge branch 'main' into refactor/push-flyout-down-to-discover
tonyghiani Apr 22, 2024
cb9a96b
refactor: change request
Apr 22, 2024
0b6ff80
test(infra): update page object
Apr 22, 2024
4ea0c2f
refactor(unified-doc-viewer): simplify logs overview logic
Apr 23, 2024
88ab78d
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Apr 23, 2024
5286739
Update packages/kbn-unified-doc-viewer/src/services/doc_views_registr…
tonyghiani Apr 24, 2024
d2647a6
refactor(unified-doc-viewer): update naming
Apr 24, 2024
88b6787
refactor(unified-doc-viewer): update naming getLogDocumentOverview
Apr 24, 2024
b7a5a32
Merge branch 'main' into refactor/push-flyout-down-to-discover
tonyghiani Apr 24, 2024
72f7460
refactor(unified-doc-viewer): update grid layout to auto-fill for bet…
Apr 25, 2024
29ef1f4
Merge branch 'main' into refactor/push-flyout-down-to-discover
tonyghiani Apr 25, 2024
496d13a
Merge branch 'main' into refactor/push-flyout-down-to-discover
tonyghiani Apr 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,7 @@ packages/kbn-monaco/src/esql @elastic/kibana-esql
/x-pack/test/functional/apps/dataset_quality @elastic/obs-ux-logs-team
/x-pack/test_serverless/functional/test_suites/observability/dataset_quality @elastic/obs-ux-logs-team
/x-pack/test_serverless/functional/test_suites/observability/ @elastic/obs-ux-logs-team
/src/plugins/unified_doc_viewer/public/components/doc_viewer_logs_overview @elastic/obs-ux-logs-team

# Observability onboarding tour
/x-pack/plugins/observability_solution/observability_shared/public/components/tour @elastic/platform-onboarding
Expand Down
5 changes: 5 additions & 0 deletions packages/kbn-discover-utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,17 @@ export {
IgnoredReason,
buildDataTableRecord,
buildDataTableRecordList,
fieldConstants,
formatFieldValue,
formatHit,
getDocId,
getLogDocumentOverview,
getIgnoredReason,
getMessageFieldWithFallbacks,
getShouldShowFieldHandler,
isNestedFieldParent,
isLegacyTableEnabled,
usePager,
} from './src';

export * from './src/types';
42 changes: 42 additions & 0 deletions packages/kbn-discover-utils/src/field_constants.ts
Original file line number Diff line number Diff line change
@@ -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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

// Fields constants
export const TIMESTAMP_FIELD = '@timestamp';
export const HOST_NAME_FIELD = 'host.name';
export const LOG_LEVEL_FIELD = 'log.level';
export const MESSAGE_FIELD = 'message';
export const ERROR_MESSAGE_FIELD = 'error.message';
export const EVENT_ORIGINAL_FIELD = 'event.original';
export const TRACE_ID_FIELD = 'trace.id';

export const LOG_FILE_PATH_FIELD = 'log.file.path';
export const DATASTREAM_NAMESPACE_FIELD = 'data_stream.namespace';
export const DATASTREAM_DATASET_FIELD = 'data_stream.dataset';

// Resource Fields
export const AGENT_NAME_FIELD = 'agent.name';
export const CLOUD_PROVIDER_FIELD = 'cloud.provider';
export const CLOUD_REGION_FIELD = 'cloud.region';
export const CLOUD_AVAILABILITY_ZONE_FIELD = 'cloud.availability_zone';
export const CLOUD_PROJECT_ID_FIELD = 'cloud.project.id';
export const CLOUD_INSTANCE_ID_FIELD = 'cloud.instance.id';
export const SERVICE_NAME_FIELD = 'service.name';
export const ORCHESTRATOR_CLUSTER_NAME_FIELD = 'orchestrator.cluster.name';
export const ORCHESTRATOR_RESOURCE_ID_FIELD = 'orchestrator.resource.id';
export const ORCHESTRATOR_NAMESPACE_FIELD = 'orchestrator.namespace';
export const CONTAINER_NAME_FIELD = 'container.name';
export const CONTAINER_ID_FIELD = 'container.id';

// Degraded Docs
export const DEGRADED_DOCS_FIELD = 'ignored_field_values';

// Error Stacktrace
export const ERROR_STACK_TRACE = 'error.stack_trace';
export const ERROR_EXCEPTION_STACKTRACE = 'error.exception.stacktrace';
export const ERROR_LOG_STACKTRACE = 'error.log.stacktrace';
1 change: 1 addition & 0 deletions packages/kbn-discover-utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
*/

export * from './constants';
export * as fieldConstants from './field_constants';
export * from './hooks';
export * from './utils';
41 changes: 41 additions & 0 deletions packages/kbn-discover-utils/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,44 @@ type FormattedHitPair = readonly [
* Pairs array for each field in the hit
*/
export type FormattedHit = FormattedHitPair[];

export interface LogDocumentOverview
extends LogResourceFields,
LogStackTraceFields,
LogCloudFields {
'@timestamp': string;
'log.level'?: string;
message?: string;
'error.message'?: string;
'event.original'?: string;
'trace.id'?: string;
'log.file.path'?: string;
'data_stream.namespace': string;
'data_stream.dataset': string;
}

export interface LogResourceFields {
'host.name'?: string;
'service.name'?: string;
'agent.name'?: string;
'orchestrator.cluster.name'?: string;
'orchestrator.cluster.id'?: string;
'orchestrator.resource.id'?: string;
'orchestrator.namespace'?: string;
'container.name'?: string;
'container.id'?: string;
}

export interface LogStackTraceFields {
'error.stack_trace'?: string;
'error.exception.stacktrace'?: string;
'error.log.stacktrace'?: string;
}

export interface LogCloudFields {
'cloud.provider'?: string;
'cloud.region'?: string;
'cloud.availability_zone'?: string;
'cloud.project.id'?: string;
'cloud.instance.id'?: string;
}
Original file line number Diff line number Diff line change
@@ -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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public';
import type { DataView } from '@kbn/data-views-plugin/public';
import { DataTableRecord, LogDocumentOverview, fieldConstants, formatFieldValue } from '../..';

export function getLogDocumentOverview(
doc: DataTableRecord,
{ dataView, fieldFormats }: { dataView: DataView; fieldFormats: FieldFormatsStart }
): LogDocumentOverview {
const formatField = <T extends keyof LogDocumentOverview>(field: T) => {
return (
field in doc.flattened
? formatFieldValue(
doc.flattened[field],
doc.raw,
fieldFormats,
dataView,
dataView.fields.getByName(field)
)
: undefined
) as LogDocumentOverview[T];
};

const levelArray = doc.flattened[fieldConstants.LOG_LEVEL_FIELD];
const level =
Array.isArray(levelArray) && levelArray.length ? levelArray[0].toLowerCase() : levelArray;
const messageArray = doc.flattened[fieldConstants.MESSAGE_FIELD];
const message =
Array.isArray(messageArray) && messageArray.length ? messageArray[0] : messageArray;
const errorMessageArray = doc.flattened[fieldConstants.ERROR_MESSAGE_FIELD];
const errorMessage =
Array.isArray(errorMessageArray) && errorMessageArray.length
? errorMessageArray[0]
: errorMessageArray;
const eventOriginalArray = doc.flattened[fieldConstants.EVENT_ORIGINAL_FIELD];
const eventOriginal =
Array.isArray(eventOriginalArray) && eventOriginalArray.length
? eventOriginalArray[0]
: eventOriginalArray;
const timestamp = formatField(fieldConstants.TIMESTAMP_FIELD);

// Service
const serviceName = formatField(fieldConstants.SERVICE_NAME_FIELD);
const traceId = formatField(fieldConstants.TRACE_ID_FIELD);

// Infrastructure
const hostname = formatField(fieldConstants.HOST_NAME_FIELD);
const orchestratorClusterName = formatField(fieldConstants.ORCHESTRATOR_CLUSTER_NAME_FIELD);
const orchestratorResourceId = formatField(fieldConstants.ORCHESTRATOR_RESOURCE_ID_FIELD);

// Cloud
const cloudProvider = formatField(fieldConstants.CLOUD_PROVIDER_FIELD);
const cloudRegion = formatField(fieldConstants.CLOUD_REGION_FIELD);
const cloudAz = formatField(fieldConstants.CLOUD_AVAILABILITY_ZONE_FIELD);
const cloudProjectId = formatField(fieldConstants.CLOUD_PROJECT_ID_FIELD);
const cloudInstanceId = formatField(fieldConstants.CLOUD_INSTANCE_ID_FIELD);

// Other
const logFilePath = formatField(fieldConstants.LOG_FILE_PATH_FIELD);
const namespace = formatField(fieldConstants.DATASTREAM_NAMESPACE_FIELD);
const dataset = formatField(fieldConstants.DATASTREAM_DATASET_FIELD);
const agentName = formatField(fieldConstants.AGENT_NAME_FIELD);

return {
[fieldConstants.LOG_LEVEL_FIELD]: level,
[fieldConstants.TIMESTAMP_FIELD]: timestamp,
[fieldConstants.MESSAGE_FIELD]: message,
[fieldConstants.ERROR_MESSAGE_FIELD]: errorMessage,
[fieldConstants.EVENT_ORIGINAL_FIELD]: eventOriginal,
[fieldConstants.SERVICE_NAME_FIELD]: serviceName,
[fieldConstants.TRACE_ID_FIELD]: traceId,
[fieldConstants.HOST_NAME_FIELD]: hostname,
[fieldConstants.ORCHESTRATOR_CLUSTER_NAME_FIELD]: orchestratorClusterName,
[fieldConstants.ORCHESTRATOR_RESOURCE_ID_FIELD]: orchestratorResourceId,
[fieldConstants.CLOUD_PROVIDER_FIELD]: cloudProvider,
[fieldConstants.CLOUD_REGION_FIELD]: cloudRegion,
[fieldConstants.CLOUD_AVAILABILITY_ZONE_FIELD]: cloudAz,
[fieldConstants.CLOUD_PROJECT_ID_FIELD]: cloudProjectId,
[fieldConstants.CLOUD_INSTANCE_ID_FIELD]: cloudInstanceId,
[fieldConstants.LOG_FILE_PATH_FIELD]: logFilePath,
[fieldConstants.DATASTREAM_NAMESPACE_FIELD]: namespace,
[fieldConstants.DATASTREAM_DATASET_FIELD]: dataset,
[fieldConstants.AGENT_NAME_FIELD]: agentName,
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { fieldConstants } from '..';
import { LogDocumentOverview } from '../types';

export const getMessageFieldWithFallbacks = (doc: LogDocumentOverview) => {
const rankingOrder = [
fieldConstants.MESSAGE_FIELD,
fieldConstants.ERROR_MESSAGE_FIELD,
fieldConstants.EVENT_ORIGINAL_FIELD,
] as const;

for (const rank of rankingOrder) {
if (doc[rank] !== undefined && doc[rank] !== null) {
return { field: rank, value: doc[rank] };
}
}

// If none of the ranks (fallbacks) are present
return { field: undefined };
};
2 changes: 2 additions & 0 deletions packages/kbn-discover-utils/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export * from './format_hit';
export * from './format_value';
export * from './get_doc_id';
export * from './get_ignored_reason';
export * from './get_log_document_overview';
export * from './get_message_field_with_fallbacks';
export * from './get_should_show_field_handler';
export * from './nested_fields';
export { isLegacyTableEnabled } from './is_legacy_table_enabled';
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,24 @@ export interface DocViewerProps extends DocViewRenderProps {
* a `render` function.
*/
export function DocViewer({ docViews, ...renderProps }: DocViewerProps) {
const tabs = docViews.map(({ id, title, render, component }: DocView) => {
return {
id: `kbn_doc_viewer_tab_${id}`,
name: title,
content: (
<DocViewerTab
id={id}
title={title}
component={component}
renderProps={renderProps}
render={render}
/>
),
['data-test-subj']: `docViewerTab-${id}`,
};
});
const tabs = docViews
.filter(({ enabled }) => enabled) // Filter out disabled doc views
.map(({ id, title, render, component }: DocView) => {
return {
id: `kbn_doc_viewer_tab_${id}`,
name: title,
content: (
<DocViewerTab
id={id}
title={title}
component={component}
renderProps={renderProps}
render={render}
/>
),
['data-test-subj']: `docViewerTab-${id}`,
};
});

if (!tabs.length) {
// There's a minimum of 2 tabs active in Discover.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,25 @@ describe('DocViewerRegistry', () => {
});
});

describe('#enableById & #disableById', () => {
test('should enable/disable a doc view given the passed id', () => {
weltenwort marked this conversation as resolved.
Show resolved Hide resolved
const registry = new DocViewsRegistry([fnDocView, componentDocView]);

const docViews = registry.getAll();

expect(docViews[0]).toHaveProperty('enabled', true);
expect(docViews[1]).toHaveProperty('enabled', true);

registry.disableById('function-doc-view');

expect(registry.getAll()[0]).toHaveProperty('enabled', false);

registry.enableById('function-doc-view');

expect(registry.getAll()[0]).toHaveProperty('enabled', true);
});
});

describe('#clone', () => {
test('should return a new DocViewRegistry instance starting from the current one', () => {
const registry = new DocViewsRegistry([fnDocView, componentDocView]);
Expand All @@ -84,6 +103,24 @@ describe('DocViewerRegistry', () => {
expect(docViews[0]).toHaveProperty('id', 'function-doc-view');
expect(docViews[1]).toHaveProperty('id', 'component-doc-view');
expect(registry).not.toBe(clonedRegistry);

// Test against shared references between clones
expect(clonedRegistry).not.toBe(registry);

// Mutating a cloned registry should not affect the original registry
registry.disableById('function-doc-view');
expect(registry.getAll()[0]).toHaveProperty('enabled', false);
expect(clonedRegistry.getAll()[0]).toHaveProperty('enabled', true);

clonedRegistry.add({
id: 'additional-doc-view',
order: 20,
title: 'Render function',
render: jest.fn(),
});

expect(registry.getAll().length).toBe(2);
expect(clonedRegistry.getAll().length).toBe(3);
});
});
});
Loading