[One Discover] Push Smart Fields / Virtual Columns down into Discover (#181870)

## Summary

Implements **part one** of
https://github.com/elastic/kibana/issues/181674.

The main focus here is to get the code for Smart Fields and Virtual
Columns located within Discover. Whilst some hooks have been added to
decide what to register / render these should most definitely be treated
as "subject to change" once the real data type context awareness lands
in Discover. For now these hooks rely on the old extension points to say
"yes, this is a logs context". As far as I could see other solutions are
not using the extension points that have been temporarily altered here.

As this is functionality related to a data type (logs) and not a
solution (observability, for example) this is all treated as a first
class citizen. Some code has been moved to the `discover-utils`.

## Reviewer notes

- Nothing should really have *changed*, this is mostly about verifying
that the Smart Fields and Virtual Columns still work as expected when
using Logs Explorer (and that core Discover still works as expected).
Please also check the Flyout still works as expected as this was rebased
on top of https://github.com/elastic/kibana/pull/180262/files and there
were some conflicts between file relocation in the two.

- There are a couple of components now duplicated in Discover and Logs
Explorer as the `actions` column still uses them and hasn't been moved
across yet.

<img width="306" alt="Screenshot 2024-04-28 at 15 39 15"
src="7b56df75-8b0b-41a7-8f15-f1066ef269d7">
<img width="1183" alt="Screenshot 2024-04-28 at 15 39 21"
src="167ab53c-9e86-464d-9622-86d87b311b46">

---------

Co-authored-by: Achyut Jhunjhunwala <achyut.jhunjhunwala@elastic.co>
This commit is contained in:
Kerry Gallagher 2024-05-16 15:41:42 +01:00 committed by GitHub
parent c4ef9bdccf
commit 2de84ce4dd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
47 changed files with 812 additions and 194 deletions

View file

@ -0,0 +1,9 @@
/*
* 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.
*/
export * from './logs';

View file

@ -0,0 +1,10 @@
/*
* 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.
*/
export * from './types';
export * from './utils';

View file

@ -1,11 +1,12 @@
/*
* 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.
* 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 { DataTableRecord } from '@kbn/discover-utils/src/types';
import { DataTableRecord } from '../../types';
export interface LogDocument extends DataTableRecord {
flattened: {
@ -40,7 +41,7 @@ export interface LogDocument extends DataTableRecord {
};
}
export interface FlyoutDoc {
export interface LogFlyoutDoc {
'@timestamp': string;
'log.level'?: string;
message?: string;

View file

@ -1,11 +1,12 @@
/*
* 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.
* 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 { LogDocument } from '../../common/document';
import { LogDocument } from '../types';
type Field = keyof LogDocument['flattened'];

View file

@ -0,0 +1,9 @@
/*
* 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.
*/
export * from './get_field_from_doc';

View file

@ -10,3 +10,4 @@ export * from './constants';
export * as fieldConstants from './field_constants';
export * from './hooks';
export * from './utils';
export * from './data_types';

View file

@ -0,0 +1,65 @@
/*
* 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 '@kbn/discover-utils';
import { SmartFieldGridColumnOptions } from './display_options';
export * from '@kbn/discover-utils/src/field_constants';
export const LOGS_EXPLORER_PROFILE_ID = 'logs-explorer';
// Virtual column fields
export const CONTENT_FIELD = 'content';
export const RESOURCE_FIELD = 'resource';
// Sizing
export const DATA_GRID_COLUMN_WIDTH_SMALL = 240;
export const DATA_GRID_COLUMN_WIDTH_MEDIUM = 320;
export const ACTIONS_COLUMN_WIDTH = 80;
export const RESOURCE_FIELD_CONFIGURATION: SmartFieldGridColumnOptions = {
type: 'smart-field',
smartField: RESOURCE_FIELD,
fallbackFields: [fieldConstants.HOST_NAME_FIELD, fieldConstants.SERVICE_NAME_FIELD],
width: DATA_GRID_COLUMN_WIDTH_MEDIUM,
};
export const CONTENT_FIELD_CONFIGURATION: SmartFieldGridColumnOptions = {
type: 'smart-field',
smartField: CONTENT_FIELD,
fallbackFields: [fieldConstants.MESSAGE_FIELD],
};
export const SMART_FALLBACK_FIELDS = {
[CONTENT_FIELD]: CONTENT_FIELD_CONFIGURATION,
[RESOURCE_FIELD]: RESOURCE_FIELD_CONFIGURATION,
};
// UI preferences
export const DEFAULT_COLUMNS = [RESOURCE_FIELD_CONFIGURATION, CONTENT_FIELD_CONFIGURATION];
export const DEFAULT_ROWS_PER_PAGE = 100;
// List of prefixes which needs to be filtered out for Display in Content Column
export const FILTER_OUT_FIELDS_PREFIXES_FOR_CONTENT = [
'_', // Filter fields like '_id', '_score'
'@timestamp',
'agent.',
'elastic_agent.',
'data_stream.',
'ecs.',
'host.',
'container.',
'cloud.',
'kubernetes.',
'orchestrator.',
'log.',
'service.',
];
export const DEFAULT_ALLOWED_DATA_VIEWS = ['logs', 'auditbeat', 'filebeat', 'winlogbeat'];
export const DEFAULT_ALLOWED_LOGS_DATA_VIEWS = ['logs', 'auditbeat', 'filebeat', 'winlogbeat'];

View file

@ -0,0 +1,14 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 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.
*/
export interface SmartFieldGridColumnOptions {
type: 'smart-field';
smartField: 'content' | 'resource';
fallbackFields: string[];
width?: number;
}

View file

@ -109,17 +109,6 @@ describe('Discover documents layout', () => {
});
test('should render customisations', async () => {
const customCellRenderer = {
content: () => <span className="custom-renderer-test">Test</span>,
};
const customGridColumnsConfiguration = {
content: () => ({
id: 'content',
displayText: <span className="custom-column-test">Column</span>,
}),
};
const customControlColumnsConfiguration = () => ({
leadingControlColumns: [],
trailingControlColumns: [],
@ -127,8 +116,7 @@ describe('Discover documents layout', () => {
const customization: DiscoverCustomization = {
id: 'data_table',
customCellRenderer,
customGridColumnsConfiguration,
logsEnabled: true,
customControlColumnsConfiguration,
};
@ -137,12 +125,10 @@ describe('Discover documents layout', () => {
const discoverGridComponent = component.find(DiscoverGrid);
expect(discoverGridComponent.exists()).toBeTruthy();
expect(discoverGridComponent.prop('externalCustomRenderers')).toEqual(customCellRenderer);
expect(discoverGridComponent.prop('customGridColumnsConfiguration')).toEqual(
customGridColumnsConfiguration
);
expect(discoverGridComponent.prop('customControlColumnsConfiguration')).toEqual(
customControlColumnsConfiguration
);
expect(discoverGridComponent.prop('externalCustomRenderers')).toBeDefined();
expect(discoverGridComponent.prop('customGridColumnsConfiguration')).toBeDefined();
});
});

View file

@ -67,6 +67,7 @@ import { useFetchMoreRecords } from './use_fetch_more_records';
import { SelectedVSAvailableCallout } from './selected_vs_available_callout';
import { useDiscoverCustomization } from '../../../../customizations';
import { onResizeGridColumn } from '../../../../utils/on_resize_grid_column';
import { useContextualGridCustomisations } from '../../hooks/grid_customisations';
const containerStyles = css`
position: relative;
@ -258,11 +259,9 @@ function DiscoverDocumentsComponent({
[dataView, onAddColumn, onAddFilter, onRemoveColumn, query, savedSearch.id, setExpandedDoc]
);
const {
customCellRenderer: externalCustomRenderers,
customGridColumnsConfiguration,
customControlColumnsConfiguration,
} = useDiscoverCustomization('data_table') || {};
const { customControlColumnsConfiguration } = useDiscoverCustomization('data_table') || {};
const { customCellRenderer, customGridColumnsConfiguration } =
useContextualGridCustomisations() || {};
const documents = useObservable(stateContainer.dataState.data$.documents$);
@ -432,7 +431,7 @@ function DiscoverDocumentsComponent({
totalHits={totalHits}
onFetchMoreRecords={onFetchMoreRecords}
componentsTourSteps={TOUR_STEPS}
externalCustomRenderers={externalCustomRenderers}
externalCustomRenderers={customCellRenderer}
customGridColumnsConfiguration={customGridColumnsConfiguration}
customControlColumnsConfiguration={customControlColumnsConfiguration}
/>

View file

@ -37,7 +37,6 @@ import { buildDataTableRecord } from '@kbn/discover-utils';
import type { DataTableRecord } from '@kbn/discover-utils/types';
import type { DiscoverCustomizationId } from '../../../../customizations/customization_service';
import { FieldListCustomization, SearchBarCustomization } from '../../../../customizations';
import { DataViewField } from '@kbn/data-views-plugin/common';
const mockSearchBarCustomization: SearchBarCustomization = {
id: 'search_bar',
@ -46,22 +45,9 @@ const mockSearchBarCustomization: SearchBarCustomization = {
.mockName('CustomDataViewPickerMock'),
};
const smartFields = [
new DataViewField({
name: 'mock_field',
type: 'mock_field',
searchable: false,
aggregatable: false,
}),
];
const additionalFieldGroups = {
smartFields,
};
const mockFieldListCustomisation: FieldListCustomization = {
id: 'field_list',
additionalFieldGroups,
logsFieldsEnabled: true,
};
let mockUseCustomizations = false;
@ -786,7 +772,7 @@ describe('discover responsive sidebar', function () {
const smartFieldsCount = findTestSubject(comp, 'fieldListGroupedSmartFields-count');
expect(smartFieldsCount.text()).toBe('1');
expect(smartFieldsCount.text()).toBe('2');
});
});
});

View file

@ -38,6 +38,7 @@ import {
DiscoverSidebarReducerStatus,
} from './lib/sidebar_reducer';
import { useDiscoverCustomization } from '../../../../customizations';
import { useAdditionalFieldGroups } from '../../hooks/sidebar/use_additional_field_groups';
const EMPTY_FIELD_COUNTS = {};
@ -331,7 +332,7 @@ export function DiscoverSidebarResponsive(props: DiscoverSidebarResponsiveProps)
);
const searchBarCustomization = useDiscoverCustomization('search_bar');
const fieldListCustomization = useDiscoverCustomization('field_list');
const additionalFieldGroups = useAdditionalFieldGroups();
const CustomDataViewPicker = searchBarCustomization?.CustomDataViewPicker;
const createField = unifiedFieldListSidebarContainerApi?.createField;
@ -408,7 +409,7 @@ export function DiscoverSidebarResponsive(props: DiscoverSidebarResponsiveProps)
onAddFilter={onAddFilter}
onFieldEdited={onFieldEdited}
prependInFlyout={prependDataViewPickerForMobile}
additionalFieldGroups={fieldListCustomization?.additionalFieldGroups}
additionalFieldGroups={additionalFieldGroups}
/>
) : null}
</EuiFlexItem>

View file

@ -0,0 +1,28 @@
/*
* 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 { useMemo } from 'react';
import { useDiscoverServices } from '../../../../hooks/use_discover_services';
import { useDiscoverCustomization } from '../../../../customizations';
import { getLogsVirtualColumnsConfiguration } from './logs';
export * from './logs';
export const useContextualGridCustomisations = () => {
const { data } = useDiscoverServices();
// TODO / NOTE: This will eventually rely on Discover's context resolution to determine which fields
// are returned based on the data type.
const isLogsContext = useDiscoverCustomization('data_table')?.logsEnabled;
const virtualColumnsConfiguration = useMemo(() => {
if (!isLogsContext) return null;
if (isLogsContext) return getLogsVirtualColumnsConfiguration(data);
}, [data, isLogsContext]);
return virtualColumnsConfiguration;
};

View file

@ -0,0 +1,31 @@
/*
* 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 { DataPublicPluginStart } from '@kbn/data-plugin/public';
import { CONTENT_FIELD, RESOURCE_FIELD } from '../../../../../common/data_types/logs/constants';
import { renderCell } from '../../../../components/discover_grid/virtual_columns/logs/cell_renderer';
import { renderColumn } from '../../../../components/discover_grid/virtual_columns/logs/column';
export const getLogsVirtualColumnsConfiguration = (data: DataPublicPluginStart) => {
return {
customCellRenderer: createCustomCellRenderer({ data }),
customGridColumnsConfiguration: createCustomGridColumnsConfiguration(),
};
};
export const createCustomCellRenderer = ({ data }: { data: DataPublicPluginStart }) => {
return {
[CONTENT_FIELD]: renderCell(CONTENT_FIELD, { data }),
[RESOURCE_FIELD]: renderCell(RESOURCE_FIELD, { data }),
};
};
export const createCustomGridColumnsConfiguration = () => ({
[CONTENT_FIELD]: renderColumn(CONTENT_FIELD),
[RESOURCE_FIELD]: renderColumn(RESOURCE_FIELD),
});

View file

@ -0,0 +1,23 @@
/*
* 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 createContainer from 'constate';
import type { DataView } from '@kbn/data-views-plugin/common';
import { DataPublicPluginStart } from '@kbn/data-plugin/public';
export interface UseVirtualColumnServices {
services: {
data: DataPublicPluginStart;
dataView: DataView;
};
}
const useVirtualColumns = ({ services }: UseVirtualColumnServices) => services;
export const [VirtualColumnServiceProvider, useVirtualColumnServiceContext] =
createContainer(useVirtualColumns);

View file

@ -0,0 +1,37 @@
/*
* 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 { DataViewField } from '@kbn/data-views-plugin/common';
import { useDiscoverCustomization } from '../../../../customizations';
import * as constants from '../../../../../common/data_types/logs/constants';
export const useAdditionalFieldGroups = () => {
// TODO / NOTE: This will eventually rely on Discover's context resolution to determine which fields
// are returned based on the data type.
const isLogsContext = useDiscoverCustomization('field_list')?.logsFieldsEnabled;
if (isLogsContext) {
const smartFields = [
new DataViewField({
name: constants.RESOURCE_FIELD,
type: 'smart_field',
searchable: false,
aggregatable: false,
}),
new DataViewField({
name: constants.CONTENT_FIELD,
type: 'smart_field',
searchable: false,
aggregatable: false,
}),
];
return {
smartFields,
};
}
};

View file

@ -1,8 +1,9 @@
/*
* 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.
* 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 { EuiButtonEmpty, EuiFlexItem, copyToClipboard } from '@elastic/eui';

View file

@ -1,15 +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.
* 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 { EuiButtonEmpty, EuiFlexItem } from '@elastic/eui';
import React from 'react';
import { generateFilters } from '@kbn/data-plugin/public';
import { filterForText, actionFilterForText } from './translations';
import { useVirtualColumnServiceContext } from '../../hooks/use_virtual_column_services';
import { useVirtualColumnServiceContext } from '../../../application/main/hooks/grid_customisations/use_virtual_column_services';
import { actionFilterForText, filterForText } from './translations';
export const FilterInButton = ({ property, value }: { property: string; value: string }) => {
const ariaFilterForText = actionFilterForText(value);

View file

@ -1,15 +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.
* 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 { EuiButtonEmpty, EuiFlexItem } from '@elastic/eui';
import React from 'react';
import { generateFilters } from '@kbn/data-plugin/public';
import { filterOutText, actionFilterOutText } from './translations';
import { useVirtualColumnServiceContext } from '../../hooks/use_virtual_column_services';
import { useVirtualColumnServiceContext } from '../../../application/main/hooks/grid_customisations/use_virtual_column_services';
import { actionFilterOutText, filterOutText } from './translations';
export const FilterOutButton = ({ property, value }: { property: string; value: string }) => {
const ariaFilterOutText = actionFilterOutText(value);

View file

@ -1,15 +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.
* 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 React from 'react';
import { useEuiTheme } from '@elastic/eui';
import { FlyoutDoc } from '../../../common/document';
import { LogFlyoutDoc } from '@kbn/discover-utils/src';
import * as constants from '../../../../common/data_types/logs/constants';
import { ChipWithPopover } from './popover_chip';
import * as constants from '../../../common/constants';
const LEVEL_DICT = {
error: 'danger',
@ -19,7 +20,7 @@ const LEVEL_DICT = {
} as const;
interface LogLevelProps {
level: FlyoutDoc['log.level'];
level: LogFlyoutDoc['log.level'];
dataTestSubj?: string;
renderInFlyout?: boolean;
}

View file

@ -1,8 +1,9 @@
/*
* 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.
* 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 React, { useCallback, useState } from 'react';

View file

@ -0,0 +1,300 @@
/*
* 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 React from 'react';
import { i18n } from '@kbn/i18n';
import { EuiCode } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
export const flyoutContentLabel = i18n.translate('discover.logs.flyoutDetail.label.message', {
defaultMessage: 'Content breakdown',
});
export const contentLabel = i18n.translate('discover.logs.dataTable.header.popover.content', {
defaultMessage: 'Content',
});
export const resourceLabel = i18n.translate('discover.logs.dataTable.header.popover.resource', {
defaultMessage: 'Resource',
});
export const actionsLabel = i18n.translate('discover.logs.dataTable.header.popover.actions', {
defaultMessage: 'Actions',
});
export const actionsLabelLowerCase = i18n.translate(
'discover.logs.dataTable.header.popover.actions.lowercase',
{
defaultMessage: 'actions',
}
);
export const flyoutServiceLabel = i18n.translate('discover.logs.flyoutDetail.label.service', {
defaultMessage: 'Service',
});
export const flyoutTraceLabel = i18n.translate('discover.logs.flyoutDetail.label.trace', {
defaultMessage: 'Trace',
});
export const flyoutHostNameLabel = i18n.translate('discover.logs.flyoutDetail.label.hostName', {
defaultMessage: 'Host name',
});
export const serviceInfraAccordionTitle = i18n.translate(
'discover.logs.flyoutDetail.accordion.title.serviceInfra',
{
defaultMessage: 'Service & Infrastructure',
}
);
export const cloudAccordionTitle = i18n.translate(
'discover.logs.flyoutDetail.accordion.title.cloud',
{
defaultMessage: 'Cloud',
}
);
export const otherAccordionTitle = i18n.translate(
'discover.logs.flyoutDetail.accordion.title.other',
{
defaultMessage: 'Other',
}
);
export const flyoutOrchestratorClusterNameLabel = i18n.translate(
'discover.logs.flyoutDetail.label.orchestratorClusterName',
{
defaultMessage: 'Orchestrator cluster Name',
}
);
export const flyoutOrchestratorResourceIdLabel = i18n.translate(
'discover.logs.flyoutDetail.label.orchestratorResourceId',
{
defaultMessage: 'Orchestrator resource ID',
}
);
export const flyoutCloudProviderLabel = i18n.translate(
'discover.logs.flyoutDetail.label.cloudProvider',
{
defaultMessage: 'Cloud provider',
}
);
export const flyoutCloudRegionLabel = i18n.translate(
'discover.logs.flyoutDetail.label.cloudRegion',
{
defaultMessage: 'Cloud region',
}
);
export const flyoutCloudAvailabilityZoneLabel = i18n.translate(
'discover.logs.flyoutDetail.label.cloudAvailabilityZone',
{
defaultMessage: 'Cloud availability zone',
}
);
export const flyoutCloudProjectIdLabel = i18n.translate(
'discover.logs.flyoutDetail.label.cloudProjectId',
{
defaultMessage: 'Cloud project ID',
}
);
export const flyoutCloudInstanceIdLabel = i18n.translate(
'discover.logs.flyoutDetail.label.cloudInstanceId',
{
defaultMessage: 'Cloud instance ID',
}
);
export const flyoutLogPathFileLabel = i18n.translate(
'discover.logs.flyoutDetail.label.logPathFile',
{
defaultMessage: 'Log path file',
}
);
export const flyoutNamespaceLabel = i18n.translate('discover.logs.flyoutDetail.label.namespace', {
defaultMessage: 'Namespace',
});
export const flyoutDatasetLabel = i18n.translate('discover.logs.flyoutDetail.label.dataset', {
defaultMessage: 'Dataset',
});
export const flyoutShipperLabel = i18n.translate('discover.logs.flyoutDetail.label.shipper', {
defaultMessage: 'Shipper',
});
export const actionFilterForText = (text: string) =>
i18n.translate('discover.logs.flyoutDetail.value.hover.filterFor', {
defaultMessage: 'Filter for this {value}',
values: {
value: text,
},
});
export const actionFilterOutText = (text: string) =>
i18n.translate('discover.logs.flyoutDetail.value.hover.filterOut', {
defaultMessage: 'Filter out this {value}',
values: {
value: text,
},
});
export const filterOutText = i18n.translate('discover.logs.popoverAction.filterOut', {
defaultMessage: 'Filter out',
});
export const filterForText = i18n.translate('discover.logs.popoverAction.filterFor', {
defaultMessage: 'Filter for',
});
export const flyoutHoverActionFilterForFieldPresentText = i18n.translate(
'discover.logs.flyoutDetail.value.hover.filterForFieldPresent',
{
defaultMessage: 'Filter for field present',
}
);
export const flyoutHoverActionToggleColumnText = i18n.translate(
'discover.logs.flyoutDetail.value.hover.toggleColumn',
{
defaultMessage: 'Toggle column in table',
}
);
export const flyoutHoverActionCopyToClipboardText = i18n.translate(
'discover.logs.flyoutDetail.value.hover.copyToClipboard',
{
defaultMessage: 'Copy to clipboard',
}
);
export const copyValueText = i18n.translate('discover.logs.popoverAction.copyValue', {
defaultMessage: 'Copy value',
});
export const copyValueAriaText = (fieldName: string) =>
i18n.translate('discover.logs.popoverAction.copyValueAriaText', {
defaultMessage: 'Copy value of {fieldName}',
values: {
fieldName,
},
});
export const flyoutAccordionShowMoreText = (count: number) =>
i18n.translate('discover.logs.flyoutDetail.section.showMore', {
defaultMessage: '+ {hiddenCount} more',
values: {
hiddenCount: count,
},
});
export const openCellActionPopoverAriaText = i18n.translate(
'discover.logs.popoverAction.openPopover',
{
defaultMessage: 'Open popover',
}
);
export const closeCellActionPopoverText = i18n.translate(
'discover.logs.popoverAction.closePopover',
{
defaultMessage: 'Close popover',
}
);
export const contentHeaderTooltipParagraph1 = (
<FormattedMessage
id="discover.logs.dataTable.header.content.tooltip.paragraph1"
defaultMessage="Displays the document's {logLevel} and {message} fields."
values={{
logLevel: <strong>log.level</strong>,
message: <strong>message</strong>,
}}
/>
);
export const contentHeaderTooltipParagraph2 = i18n.translate(
'discover.logs.dataTable.header.content.tooltip.paragraph2',
{
defaultMessage: 'When the message field is empty, one of the following is displayed:',
}
);
export const resourceHeaderTooltipParagraph = i18n.translate(
'discover.logs.dataTable.header.resource.tooltip.paragraph',
{
defaultMessage: "Fields that provide information on the document's source, such as:",
}
);
export const actionsHeaderTooltipParagraph = i18n.translate(
'discover.logs.dataTable.header.actions.tooltip.paragraph',
{
defaultMessage: 'Fields that provide actionable information, such as:',
}
);
export const actionsHeaderTooltipExpandAction = i18n.translate(
'discover.logs.dataTable.header.actions.tooltip.expand',
{ defaultMessage: 'Expand log details' }
);
export const actionsHeaderTooltipDegradedAction = (
<FormattedMessage
id="discover.logs.dataTable.controlColumn.actions.button.degradedDoc"
defaultMessage="Access to degraded doc with {ignoredProperty} field"
values={{
ignoredProperty: (
<EuiCode language="json" transparentBackground>
_ignored
</EuiCode>
),
}}
/>
);
export const actionsHeaderTooltipStacktraceAction = i18n.translate(
'discover.logs.dataTable.header.actions.tooltip.stacktrace',
{ defaultMessage: 'Access to available stacktraces based on:' }
);
export const degradedDocButtonLabelWhenPresent = i18n.translate(
'discover.logs.dataTable.controlColumn.actions.button.degradedDocPresent',
{
defaultMessage:
"This document couldn't be parsed correctly. Not all fields are properly populated",
}
);
export const degradedDocButtonLabelWhenNotPresent = i18n.translate(
'discover.logs.dataTable.controlColumn.actions.button.degradedDocNotPresent',
{
defaultMessage: 'All fields in this document were parsed correctly',
}
);
export const stacktraceAvailableControlButton = i18n.translate(
'discover.logs.dataTable.controlColumn.actions.button.stacktrace.available',
{
defaultMessage: 'Stacktraces available',
}
);
export const stacktraceNotAvailableControlButton = i18n.translate(
'discover.logs.dataTable.controlColumn.actions.button.stacktrace.notAvailable',
{
defaultMessage: 'Stacktraces not available',
}
);

View file

@ -1,20 +1,21 @@
/*
* 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.
* 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 React from 'react';
import type { DataGridCellValueElementProps } from '@kbn/unified-data-table';
import { LogsExplorerDiscoverServices } from '../../controller';
import { VirtualColumnServiceProvider } from '../../hooks/use_virtual_column_services';
import { CONTENT_FIELD, RESOURCE_FIELD } from '../../../common/constants';
import { DataPublicPluginStart } from '@kbn/data-plugin/public';
import { VirtualColumnServiceProvider } from '../../../../application/main/hooks/grid_customisations/use_virtual_column_services';
import { CONTENT_FIELD, RESOURCE_FIELD } from '../../../../../common/data_types/logs/constants';
import { Content } from './content';
import { Resource } from './resource';
export const renderCell =
(type: string, { data }: { data: LogsExplorerDiscoverServices['data'] }) =>
(type: string, { data }: { data: DataPublicPluginStart }) =>
(props: DataGridCellValueElementProps) => {
const { dataView } = props;
const virtualColumnServices = {

View file

@ -1,14 +1,15 @@
/*
* 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.
* 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 React from 'react';
import { CustomGridColumnProps } from '@kbn/unified-data-table';
import { CONTENT_FIELD, RESOURCE_FIELD } from '../../../../../common/data_types/logs/constants';
import { ContentColumnTooltip } from './column_tooltips/content_column_tooltip';
import { CONTENT_FIELD, RESOURCE_FIELD } from '../../../common/constants';
import { ResourceColumnTooltip } from './column_tooltips/resource_column_tooltip';
export const renderColumn =

View file

@ -1,8 +1,9 @@
/*
* 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.
* 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 { EuiText, useEuiTheme } from '@elastic/eui';
@ -13,10 +14,10 @@ import {
contentHeaderTooltipParagraph1,
contentHeaderTooltipParagraph2,
contentLabel,
} from '../../common/translations';
} from '../../../../data_types/logs/translations';
import * as constants from '../../../../../../common/data_types/logs/constants';
import { TooltipButton } from './tooltip_button';
import { FieldWithToken } from './field_with_token';
import * as constants from '../../../../common/constants';
export const ContentColumnTooltip = ({ column, headerRowHeight }: CustomGridColumnProps) => {
const { euiTheme } = useEuiTheme();

View file

@ -0,0 +1,44 @@
/*
* 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 { EuiFlexGroup, EuiFlexItem, EuiText, EuiToken } from '@elastic/eui';
import React from 'react';
import { css } from '@emotion/react';
import { euiThemeVars } from '@kbn/ui-theme';
const spacingXsCss = css`
margin-bottom: ${euiThemeVars.euiSizeXS};
`;
export const FieldWithToken = ({
field,
iconType = 'tokenKeyword',
}: {
field: string;
iconType?: string;
}) => {
return (
<div css={spacingXsCss}>
<EuiFlexGroup
responsive={false}
alignItems="center"
justifyContent="flexStart"
gutterSize="xs"
>
<EuiFlexItem grow={false}>
<EuiToken iconType={iconType} size="s" />
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiText size="s">
<strong>{field}</strong>
</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
</div>
);
};

View file

@ -0,0 +1,59 @@
/*
* 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 React, { useEffect, useRef, useState } from 'react';
import { EuiPopover, EuiPopoverTitle } from '@elastic/eui';
export const HoverPopover = ({
children,
button,
title,
}: {
children: React.ReactChild;
button: React.ReactElement;
title: string;
}) => {
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
const leaveTimer = useRef<NodeJS.Timeout | null>(null);
const clearTimer = () => {
if (leaveTimer.current) {
clearTimeout(leaveTimer.current);
}
};
const onMouseEnter = () => {
clearTimer();
setIsPopoverOpen(true);
};
const onMouseLeave = () => {
leaveTimer.current = setTimeout(() => setIsPopoverOpen(false), 100);
};
useEffect(() => {
return () => {
clearTimer();
};
}, []);
return (
<div onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>
<EuiPopover
button={button}
isOpen={isPopoverOpen}
anchorPosition="upCenter"
panelPaddingSize="s"
ownFocus={false}
>
<EuiPopoverTitle>{title}</EuiPopoverTitle>
{children}
</EuiPopover>
</div>
);
};

View file

@ -1,8 +1,9 @@
/*
* 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.
* 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 React from 'react';
@ -10,9 +11,12 @@ import { css } from '@emotion/react';
import { EuiText } from '@elastic/eui';
import type { CustomGridColumnProps } from '@kbn/unified-data-table';
import { euiThemeVars } from '@kbn/ui-theme';
import { resourceHeaderTooltipParagraph, resourceLabel } from '../../common/translations';
import {
resourceHeaderTooltipParagraph,
resourceLabel,
} from '../../../../data_types/logs/translations';
import * as constants from '../../../../../../common/data_types/logs/constants';
import { TooltipButton } from './tooltip_button';
import * as constants from '../../../../common/constants';
import { FieldWithToken } from './field_with_token';
const spacingCSS = css`

View file

@ -0,0 +1,79 @@
/*
* 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 React, { useEffect, useRef, useState, useCallback, useMemo } from 'react';
import { EuiIcon } from '@elastic/eui';
import ColumnHeaderTruncateContainer from '@kbn/unified-data-table/src/components/column_header_truncate_container';
import { EuiPopover, EuiPopoverTitle } from '@elastic/eui';
export const TooltipButton = ({
children,
popoverTitle,
displayText,
headerRowHeight,
iconType = 'questionInCircle',
}: {
children: React.ReactChild;
popoverTitle: string;
displayText?: string;
headerRowHeight?: number;
iconType?: string;
}) => {
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
const leaveTimer = useRef<NodeJS.Timeout | null>(null);
const clearTimer = useMemo(
() => () => {
if (leaveTimer.current) {
clearTimeout(leaveTimer.current);
}
},
[]
);
const onMouseEnter = useCallback(() => {
clearTimer();
setIsPopoverOpen(true);
}, [clearTimer]);
const onMouseLeave = useCallback(() => {
leaveTimer.current = setTimeout(() => setIsPopoverOpen(false), 100);
}, []);
useEffect(() => {
return () => {
clearTimer();
};
}, [clearTimer]);
return (
<ColumnHeaderTruncateContainer headerRowHeight={headerRowHeight}>
{displayText}{' '}
<EuiPopover
button={
<EuiIcon
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onFocus={onMouseEnter}
onBlur={onMouseLeave}
type={iconType}
tabIndex={0}
/>
}
isOpen={isPopoverOpen}
anchorPosition="upCenter"
panelPaddingSize="s"
ownFocus={false}
>
<EuiPopoverTitle>{popoverTitle}</EuiPopoverTitle>
{children}
</EuiPopover>
</ColumnHeaderTruncateContainer>
);
};

View file

@ -1,8 +1,9 @@
/*
* 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.
* 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 React, { useMemo } from 'react';
@ -18,8 +19,8 @@ import {
import { i18n } from '@kbn/i18n';
import type { DataTableRecord } from '@kbn/discover-utils/src/types';
import { dynamic } from '@kbn/shared-ux-utility';
import { LogLevel } from '../common/log_level';
import * as constants from '../../../common/constants';
import * as constants from '../../../../../common/data_types/logs/constants';
import { LogLevel } from '../../../data_types/logs/log_level';
const SourceDocument = dynamic(
() => import('@kbn/unified-data-table/src/components/source_document')
@ -38,10 +39,8 @@ const LogMessage = ({ field, value }: { field?: string; value: string }) => {
const renderFieldPrefix = field && field !== constants.MESSAGE_FIELD;
return (
<EuiText size="xs" style={{ display: 'inline', marginLeft: '5px' }}>
{renderFieldPrefix && (
<strong data-test-subj="logsExplorerDataTableMessageKey">{field}</strong>
)}
<span data-test-subj="logsExplorerDataTableMessageValue" style={{ marginLeft: '5px' }}>
{renderFieldPrefix && <strong data-test-subj="discoverDataTableMessageKey">{field}</strong>}
<span data-test-subj="discoverDataTableMessageValue" style={{ marginLeft: '5px' }}>
{value}
</span>
</EuiText>
@ -59,7 +58,7 @@ const SourcePopoverContent = ({
}) => {
const closeButton = (
<EuiButtonIcon
aria-label={i18n.translate('xpack.logsExplorer.grid.closePopover', {
aria-label={i18n.translate('discover.logs.grid.closePopover', {
defaultMessage: `Close popover`,
})}
data-test-subj="docTableClosePopover"
@ -122,7 +121,7 @@ export const Content = ({
fieldFormats={fieldFormats}
shouldShowFieldHandler={shouldShowFieldHandler}
maxEntries={50}
dataTestSubj="logsExplorerCellDescriptionList"
dataTestSubj="discoverCellDescriptionList"
className={sourceDocumentClassName}
/>
)}

View file

@ -1,18 +1,19 @@
/*
* 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.
* 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 React from 'react';
import type { DataGridCellValueElementProps } from '@kbn/unified-data-table';
import { AgentName } from '@kbn/elastic-agent-utils';
import { dynamic } from '@kbn/shared-ux-utility';
import { ChipWithPopover } from '../common/popover_chip';
import * as constants from '../../../common/constants';
import { getUnformattedResourceFields } from '../../utils/resource';
import { LogDocument } from '../../../common/document';
import { LogDocument } from '@kbn/discover-utils/src';
import * as constants from '../../../../../common/data_types/logs/constants';
import { getUnformattedResourceFields } from './utils/resource';
import { ChipWithPopover } from '../../../data_types/logs/popover_chip';
const AgentIcon = dynamic(() => import('@kbn/custom-icons/src/components/agent_icon'));

View file

@ -1,13 +1,13 @@
/*
* 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.
* 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 { LogDocument, ResourceFields } from '../../common/document';
import * as constants from '../../common/constants';
import { getFieldFromDoc } from './get_field_from_flattened_doc';
import { getFieldFromDoc, LogDocument, ResourceFields } from '@kbn/discover-utils/src';
import * as constants from '../../../../../../common/data_types/logs/constants';
export const getUnformattedResourceFields = (doc: LogDocument): ResourceFields => {
const serviceName = getFieldFromDoc(doc, constants.SERVICE_NAME_FIELD);

View file

@ -6,15 +6,10 @@
* Side Public License, v 1.
*/
import {
CustomCellRenderer,
CustomControlColumnConfiguration,
CustomGridColumnsConfiguration,
} from '@kbn/unified-data-table';
import { CustomControlColumnConfiguration } from '@kbn/unified-data-table';
export interface DataTableCustomization {
id: 'data_table';
customCellRenderer?: CustomCellRenderer;
customGridColumnsConfiguration?: CustomGridColumnsConfiguration;
logsEnabled: boolean; // TODO / NOTE: Just temporary until Discover's data type contextual awareness lands.
customControlColumnsConfiguration?: CustomControlColumnConfiguration;
}

View file

@ -6,12 +6,7 @@
* Side Public License, v 1.
*/
import type { DataViewField } from '@kbn/data-views-plugin/common';
import { FieldsGroup } from '@kbn/unified-field-list/src/types';
export interface FieldListCustomization {
id: 'field_list';
additionalFieldGroups?: {
smartFields?: FieldsGroup<DataViewField>['fields'];
};
logsFieldsEnabled: boolean; // TODO / NOTE: Just temporary until Discover's data type contextual awareness lands.
}

View file

@ -84,9 +84,13 @@
"@kbn/shared-ux-markdown",
"@kbn/data-view-utils",
"@kbn/presentation-publishing",
"@kbn/elastic-agent-utils",
"@kbn/custom-icons",
"@kbn/observability-ai-assistant-plugin",
"@kbn/data-visualizer-plugin",
"@kbn/search-types"
"@kbn/search-types",
"@kbn/custom-icons",
"@kbn/observability-ai-assistant-plugin"
],
"exclude": ["target/**/*"]
}

View file

@ -1,17 +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 type { DataPublicPluginStart } from '@kbn/data-plugin/public';
import { CONTENT_FIELD, RESOURCE_FIELD } from '../../common/constants';
import { renderCell } from '../components/virtual_columns/cell_renderer';
export const createCustomCellRenderer = ({ data }: { data: DataPublicPluginStart }) => {
return {
[CONTENT_FIELD]: renderCell(CONTENT_FIELD, { data }),
[RESOURCE_FIELD]: renderCell(RESOURCE_FIELD, { data }),
};
};

View file

@ -1,14 +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 { CONTENT_FIELD, RESOURCE_FIELD } from '../../common/constants';
import { renderColumn } from '../components/virtual_columns/column';
export const createCustomGridColumnsConfiguration = () => ({
[CONTENT_FIELD]: renderColumn(CONTENT_FIELD),
[RESOURCE_FIELD]: renderColumn(RESOURCE_FIELD),
});

View file

@ -15,6 +15,7 @@ import {
import { EuiButtonIcon, EuiDataGridCellValueElementProps, EuiToolTip } from '@elastic/eui';
import type { DataTableRecord } from '@kbn/discover-utils/src/types';
import { useActor } from '@xstate/react';
import { LogDocument } from '@kbn/discover-utils/src';
import { LogsExplorerControllerStateService } from '../state_machines/logs_explorer_controller';
import {
degradedDocButtonLabelWhenNotPresent,
@ -24,7 +25,6 @@ import {
} from '../components/common/translations';
import * as constants from '../../common/constants';
import { getStacktraceFields } from '../utils/get_stack_trace';
import { LogDocument } from '../../common/document';
import { ActionsColumnTooltip } from '../components/virtual_columns/column_tooltips/actions_column_tooltip';
const ConnectedDegradedDocs = ({

View file

@ -1,24 +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 { DataViewField } from '@kbn/data-views-plugin/common';
import * as constants from '../../common/constants';
export const smartFields = [
new DataViewField({
name: constants.RESOURCE_FIELD,
type: 'smart_field',
searchable: false,
aggregatable: false,
}),
new DataViewField({
name: constants.CONTENT_FIELD,
type: 'smart_field',
searchable: false,
aggregatable: false,
}),
];

View file

@ -15,9 +15,6 @@ import type { LogsExplorerController } from '../controller';
import type { LogsExplorerStartDeps } from '../types';
import { useKibanaContextForPluginProvider } from '../utils/use_kibana';
import { createCustomSearchBar } from './custom_search_bar';
import { createCustomCellRenderer } from './custom_cell_renderer';
import { createCustomGridColumnsConfiguration } from './custom_column';
import { smartFields } from './custom_field_list';
import { createCustomUnifiedHistogram } from './custom_unified_histogram';
const LazyCustomDataSourceFilters = dynamic(() => import('./custom_data_source_filters'));
@ -83,8 +80,7 @@ export const createLogsExplorerProfileCustomizations =
customizations.set({
id: 'data_table',
customCellRenderer: createCustomCellRenderer({ data }),
customGridColumnsConfiguration: createCustomGridColumnsConfiguration(),
logsEnabled: true,
customControlColumnsConfiguration: await import('./custom_control_column').then((module) =>
module.createCustomControlColumnsConfiguration(service)
),
@ -92,9 +88,7 @@ export const createLogsExplorerProfileCustomizations =
customizations.set({
id: 'field_list',
additionalFieldGroups: {
smartFields,
},
logsFieldsEnabled: true,
});
// Fix bug where filtering on histogram does not work

View file

@ -5,9 +5,8 @@
* 2.0.
*/
import { LogDocument, StackTraceFields } from '../../common/document';
import { getFieldFromDoc, LogDocument, StackTraceFields } from '@kbn/discover-utils/src';
import * as constants from '../../common/constants';
import { getFieldFromDoc } from './get_field_from_flattened_doc';
export const getStacktraceFields = (doc: LogDocument): StackTraceFields => {
const errorStackTrace = getFieldFromDoc(doc, constants.ERROR_STACK_TRACE);

View file

@ -19,13 +19,11 @@
"@kbn/core-ui-settings-browser",
"@kbn/core-ui-settings-common",
"@kbn/core",
"@kbn/custom-icons",
"@kbn/data-plugin",
"@kbn/data-views-plugin",
"@kbn/deeplinks-observability",
"@kbn/discover-plugin",
"@kbn/discover-utils",
"@kbn/elastic-agent-utils",
"@kbn/embeddable-plugin",
"@kbn/es-query",
"@kbn/field-formats-plugin",

View file

@ -24100,7 +24100,6 @@
"xpack.logsExplorer.dataTable.header.popover.resource": "Ressource",
"xpack.logsExplorer.dataTable.header.resource.tooltip.paragraph": "Les champs fournissant des informations sur la source du document, comme :",
"xpack.logsExplorer.flyoutDetail.title": "Détails du log",
"xpack.logsExplorer.grid.closePopover": "Fermer la fenêtre contextuelle",
"xpack.logsExplorer.popoverAction.closePopover": "Fermer la fenêtre contextuelle",
"xpack.logsExplorer.popoverAction.copyValue": "Copier la valeur",
"xpack.logsExplorer.popoverAction.filterFor": "Filtrer sur",

View file

@ -24075,7 +24075,6 @@
"xpack.logsExplorer.dataTable.header.popover.resource": "リソース",
"xpack.logsExplorer.dataTable.header.resource.tooltip.paragraph": "次のようなドキュメントのソースに関する情報を提供するフィールド:",
"xpack.logsExplorer.flyoutDetail.title": "ログの詳細",
"xpack.logsExplorer.grid.closePopover": "ポップオーバーを閉じる",
"xpack.logsExplorer.popoverAction.closePopover": "ポップオーバーを閉じる",
"xpack.logsExplorer.popoverAction.copyValue": "値をコピー",
"xpack.logsExplorer.popoverAction.filterFor": "フィルター",

View file

@ -24108,7 +24108,6 @@
"xpack.logsExplorer.dataTable.header.popover.resource": "资源",
"xpack.logsExplorer.dataTable.header.resource.tooltip.paragraph": "提供有关文档来源信息的字段,例如:",
"xpack.logsExplorer.flyoutDetail.title": "日志详情",
"xpack.logsExplorer.grid.closePopover": "关闭弹出框",
"xpack.logsExplorer.popoverAction.closePopover": "关闭弹出框",
"xpack.logsExplorer.popoverAction.copyValue": "复制值",
"xpack.logsExplorer.popoverAction.filterFor": "筛留",

View file

@ -130,9 +130,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
expect(cellValue.includes('error.message')).to.be(false);
expect(cellValue.includes('event.original')).to.be(false);
const cellAttribute = await cellElement.findByTestSubject(
'logsExplorerCellDescriptionList'
);
const cellAttribute = await cellElement.findByTestSubject('discoverCellDescriptionList');
expect(cellAttribute).not.to.be.empty();
});
});

View file

@ -132,9 +132,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
expect(cellValue.includes('error.message')).to.be(false);
expect(cellValue.includes('event.original')).to.be(false);
const cellAttribute = await cellElement.findByTestSubject(
'logsExplorerCellDescriptionList'
);
const cellAttribute = await cellElement.findByTestSubject('discoverCellDescriptionList');
expect(cellAttribute).not.to.be.empty();
});
});