Skip to content

Commit

Permalink
[Logs+] Use central log sources setting in the Logs UI (elastic#188020)
Browse files Browse the repository at this point in the history
## Summary

Implements elastic/logs-dev#170

## High-level overview of changes

- Log Views now have a new log indices reference type of
`kibana_advanced_setting`.

- The Log View clients have been amended to be able to fully resolve
this new type.

- **All** consumers of the Log Stream Component have had to be updated
to require the logs data access plugin, this is due to the component
relying on consumers correctly setting up dependencies in a wrapping
Kibana Context Provider. This facilitates the LSC instantiating it's own
Log Views client (the log sources service is a dependency of the Log
View client). I had some issues setting up Enterprise Search locally,
would really appreciate if someone from that team could check that
usage.

- Originally I'd implemented this so that if using the defaults
(advanced setting) or switching to the `kibana_advanced_setting` type
the other two deprecated options would be hidden, however this breaks a
lot of functional tests, so all three remain selectable (but noted as
deprecated), realistically we're always going to have to deal with the
migration path anyway.

## 🎨 UI / UX changes 

![Screenshot 2024-07-24 at 11 55
46](https://github.com/user-attachments/assets/e04dfd31-155a-4026-8355-895854e54aab)

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
Kerry350 and kibanamachine authored Aug 7, 2024
1 parent 0559de6 commit 59abfd3
Show file tree
Hide file tree
Showing 52 changed files with 533 additions and 79 deletions.
1 change: 1 addition & 0 deletions x-pack/plugins/enterprise_search/kibana.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"features",
"licensing",
"logsShared",
"logsDataAccess",
"esUiShared",
"navigation",
],
Expand Down
3 changes: 2 additions & 1 deletion x-pack/plugins/fleet/kibana.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
"files",
"uiActions",
"dashboard",
"fieldsMetadata"
"fieldsMetadata",
"logsDataAccess"
],
"optionalPlugins": [
"features",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@
* 2.0.
*/

import { LOGS_INDEX_PATTERN, METRICS_INDEX_PATTERN } from '../constants';
import { METRICS_INDEX_PATTERN } from '../constants';
import { InfraSourceConfiguration } from './source_configuration';

export const defaultSourceConfiguration: InfraSourceConfiguration = {
name: 'Default',
description: '',
metricAlias: METRICS_INDEX_PATTERN,
logIndices: {
type: 'index_name',
indexName: LOGS_INDEX_PATTERN,
type: 'kibana_advanced_setting',
},
inventoryDefaultView: '0',
metricsExplorerDefaultView: '0',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,16 @@ export const logIndexNameReferenceRT = rt.type({
});
export type LogIndexNameReference = rt.TypeOf<typeof logIndexNameReferenceRT>;

export const logIndexReferenceRT = rt.union([logIndexPatternReferenceRT, logIndexNameReferenceRT]);
// Kibana advanced setting
export const logSourcesKibanaAdvancedSettingRT = rt.type({
type: rt.literal('kibana_advanced_setting'),
});

export const logIndexReferenceRT = rt.union([
logIndexPatternReferenceRT,
logIndexNameReferenceRT,
logSourcesKibanaAdvancedSettingRT,
]);
export type LogIndexReference = rt.TypeOf<typeof logIndexReferenceRT>;

export const SourceConfigurationRT = rt.type({
Expand Down
3 changes: 2 additions & 1 deletion x-pack/plugins/observability_solution/infra/kibana.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
"unifiedSearch",
"usageCollection",
"visTypeTimeseries",
"apmDataAccess"
"apmDataAccess",
"logsDataAccess"
],
"optionalPlugins": [
"spaces",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {
LogDataViewReference,
LogIndexNameReference,
logIndexNameReferenceRT,
LogSourcesKibanaAdvancedSettingReference,
logSourcesKibanaAdvancedSettingRT,
} from '@kbn/logs-shared-plugin/common';
import { useKibanaIndexPatternService } from '../../../hooks/use_kibana_index_patterns';
import { useFormElement } from './form_elements';
Expand All @@ -22,7 +24,11 @@ import {
validateStringNoSpaces,
} from './validation_errors';

export type LogIndicesFormState = LogIndexNameReference | LogDataViewReference | undefined;
export type LogIndicesFormState =
| LogIndexNameReference
| LogDataViewReference
| LogSourcesKibanaAdvancedSettingReference
| undefined;

export const useLogIndicesFormElement = (initialValue: LogIndicesFormState) => {
const indexPatternService = useKibanaIndexPatternService();
Expand All @@ -35,6 +41,8 @@ export const useLogIndicesFormElement = (initialValue: LogIndicesFormState) => {
() => async (logIndices) => {
if (logIndices == null) {
return validateStringNotEmpty('log data view', '');
} else if (logSourcesKibanaAdvancedSettingRT.is(logIndices)) {
return [];
} else if (logIndexNameReferenceRT.is(logIndices)) {
return [
...validateStringNotEmpty('log indices', logIndices.indexName),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
LogDataViewReference,
logDataViewReferenceRT,
LogIndexReference,
logSourcesKibanaAdvancedSettingRT,
} from '@kbn/logs-shared-plugin/common';
import { EuiCallOut } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
Expand All @@ -27,6 +28,7 @@ import { FormElement, isFormElementForType } from './form_elements';
import { IndexNamesConfigurationPanel } from './index_names_configuration_panel';
import { IndexPatternConfigurationPanel } from './index_pattern_configuration_panel';
import { FormValidationError } from './validation_errors';
import { KibanaAdvancedSettingConfigurationPanel } from './kibana_advanced_setting_configuration_panel';

export const IndicesConfigurationPanel = React.memo<{
isLoading: boolean;
Expand Down Expand Up @@ -75,6 +77,17 @@ export const IndicesConfigurationPanel = React.memo<{
});
}, [indicesFormElement, trackChangeIndexSourceType]);

const changeToKibanaAdvancedSettingType = useCallback(() => {
// This is always a readonly value, synced with the setting, we just reset back to the correct type.
indicesFormElement.updateValue(() => ({
type: 'kibana_advanced_setting',
}));

trackChangeIndexSourceType({
metric: 'configuration_switch_to_kibana_advanced_setting_reference',
});
}, [indicesFormElement, trackChangeIndexSourceType]);

useEffect(() => {
const getNumberOfInfraRules = async () => {
if (http) {
Expand Down Expand Up @@ -107,14 +120,42 @@ export const IndicesConfigurationPanel = React.memo<{
),
}}
>
{' '}
<EuiCheckableCard
id="kibanaAdvancedSetting"
label={
<EuiTitle size="xs">
<h2>
<FormattedMessage
id="xpack.infra.logSourceConfiguration.kibanaAdvancedSettingSectionTitle"
defaultMessage="Kibana log sources advanced setting"
/>
</h2>
</EuiTitle>
}
name="kibanaAdvancedSetting"
value="kibanaAdvancedSetting"
checked={isKibanaAdvancedSettingFormElement(indicesFormElement)}
onChange={changeToKibanaAdvancedSettingType}
disabled={isReadOnly}
>
{isKibanaAdvancedSettingFormElement(indicesFormElement) && (
<KibanaAdvancedSettingConfigurationPanel
isLoading={isLoading}
isReadOnly={isReadOnly}
advancedSettingFormElement={indicesFormElement}
/>
)}
</EuiCheckableCard>
<EuiSpacer size="m" />
<EuiCheckableCard
id="dataView"
label={
<EuiTitle size="xs">
<h2>
<FormattedMessage
id="xpack.infra.logSourceConfiguration.dataViewSectionTitle"
defaultMessage="Data view (recommended)"
defaultMessage="Data view (deprecated)"
/>
</h2>
</EuiTitle>
Expand All @@ -134,15 +175,14 @@ export const IndicesConfigurationPanel = React.memo<{
)}
</EuiCheckableCard>
<EuiSpacer size="m" />

<EuiCheckableCard
id="indexNames"
label={
<EuiTitle size="xs">
<h2>
<FormattedMessage
id="xpack.infra.sourceConfiguration.indicesSectionTitle"
defaultMessage="Indices"
id="xpack.infra.sourceConfiguration.logsIndicesSectionTitle"
defaultMessage="Indices (deprecated)"
/>
</h2>
</EuiTitle>
Expand All @@ -152,6 +192,7 @@ export const IndicesConfigurationPanel = React.memo<{
checked={isIndexNamesFormElement(indicesFormElement)}
onChange={changeToIndexNameType}
disabled={isReadOnly}
data-test-subj="logIndicesCheckableCard"
>
{isIndexNamesFormElement(indicesFormElement) && (
<IndexNamesConfigurationPanel
Expand Down Expand Up @@ -201,3 +242,7 @@ const isDataViewFormElement = isFormElementForType(
);

const isIndexNamesFormElement = isFormElementForType(logIndexNameReferenceRT.is);

const isKibanaAdvancedSettingFormElement = isFormElementForType(
logSourcesKibanaAdvancedSettingRT.is
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*
* 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 { EuiDescribedFormGroup, EuiFieldText, EuiFormRow } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import React, { useEffect, useMemo, useState } from 'react';
import { useTrackPageview } from '@kbn/observability-shared-plugin/public';
import { LogSourcesKibanaAdvancedSettingReference } from '@kbn/logs-shared-plugin/common';
import { ApplicationStart } from '@kbn/core-application-browser';
import { EuiLink } from '@elastic/eui';
import { useTrackedPromise } from '../../../hooks/use_tracked_promise';
import { useKibanaContextForPlugin } from '../../../hooks/use_kibana';
import { FormElement } from './form_elements';
import { getFormRowProps } from './form_field_props';
import { FormValidationError } from './validation_errors';

function getKibanaAdvancedSettingsHref(application: ApplicationStart) {
return application.getUrlForApp('management', {
path: `/kibana/settings?query=${encodeURIComponent('Log sources')}`,
});
}

export const KibanaAdvancedSettingConfigurationPanel: React.FC<{
isLoading: boolean;
isReadOnly: boolean;
advancedSettingFormElement: FormElement<
LogSourcesKibanaAdvancedSettingReference,
FormValidationError
>;
}> = ({ isLoading, isReadOnly, advancedSettingFormElement }) => {
const {
services: { application, logsDataAccess },
} = useKibanaContextForPlugin();

useTrackPageview({ app: 'infra_logs', path: 'log_source_configuration_kibana_advanced_setting' });
useTrackPageview({
app: 'infra_logs',
path: 'log_source_configuration_kibana_advanced_setting',
delay: 15000,
});

const advancedSettingsHref = useMemo(
() => getKibanaAdvancedSettingsHref(application),
[application]
);

const [logSourcesSettingValue, setLogSourcesSettingValue] = useState<string | undefined>(
undefined
);

const [getLogSourcesRequest, getLogSources] = useTrackedPromise(
{
cancelPreviousOn: 'resolution',
createPromise: async () => {
return await logsDataAccess.services.logSourcesService.getLogSources();
},
onResolve: (response) => {
setLogSourcesSettingValue(response.map((logSource) => logSource.indexPattern).join(','));
},
},
[]
);

const isLoadingLogSourcesSetting = useMemo(
() => getLogSourcesRequest.state === 'pending',
[getLogSourcesRequest.state]
);

useEffect(() => {
getLogSources();
}, [getLogSources]);

return (
<>
<EuiDescribedFormGroup
title={
<h4>
<FormattedMessage
id="xpack.infra.sourceConfiguration.logSourcesSettingTitle"
defaultMessage="Advanced setting"
/>
</h4>
}
description={
<FormattedMessage
id="xpack.infra.sourceConfiguration.logSourcesSettingDescription"
defaultMessage="This value is synchronised with the Kibana log sources advanced setting. It can be changed via the {advancedSettingsLink}."
values={{
advancedSettingsLink: (
<EuiLink
data-test-subj="xpack.infra.sourceConfiguration.logSourcesSettingLink"
href={advancedSettingsHref}
>
<FormattedMessage
id="xpack.infra.sourceConfiguration.logSourcesSettingLinkText"
defaultMessage="advanced settings page"
/>
</EuiLink>
),
}}
/>
}
>
<EuiFormRow
fullWidth
helpText={
<FormattedMessage
id="xpack.infra.sourceConfiguration.logSourcesSettingValue"
defaultMessage="The current setting value"
/>
}
label={
<FormattedMessage
id="xpack.infra.sourceConfiguration.logSourcesSettingLabel"
defaultMessage="Log sources advanced setting"
/>
}
{...getFormRowProps(advancedSettingFormElement)}
>
<EuiFieldText
data-test-subj="logSourcesSettingInput"
fullWidth
disabled={isLoading}
isLoading={isLoadingLogSourcesSetting}
readOnly={true}
value={logSourcesSettingValue}
isInvalid={false}
/>
</EuiFormRow>
</EuiDescribedFormGroup>
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ export const useLogSourceConfigurationFormState = (logViewAttributes?: LogViewAt
useMemo(
() =>
logViewAttributes?.logIndices ?? {
type: 'index_name',
indexName: '',
type: 'kibana_advanced_setting',
},
[logViewAttributes]
)
Expand Down
2 changes: 2 additions & 0 deletions x-pack/plugins/observability_solution/infra/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import type { CloudSetup } from '@kbn/cloud-plugin/public';
import type { LicenseManagementUIPluginSetup } from '@kbn/license-management-plugin/public';
import type { ServerlessPluginStart } from '@kbn/serverless/public';
import type { DashboardStart } from '@kbn/dashboard-plugin/public';
import { LogsDataAccessPluginStart } from '@kbn/logs-data-access-plugin/public';
import type { UnwrapPromise } from '../common/utility_types';
import { InventoryViewsServiceStart } from './services/inventory_views';
import { MetricsExplorerViewsServiceStart } from './services/metrics_explorer_views';
Expand Down Expand Up @@ -95,6 +96,7 @@ export interface InfraClientStartDeps {
embeddable?: EmbeddableStart;
lens: LensPublicStart;
logsShared: LogsSharedClientStartExports;
logsDataAccess: LogsDataAccessPluginStart;
ml?: MlPluginStart;
observability: ObservabilityPublicStart;
observabilityShared: ObservabilitySharedPluginStart;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
ApmDataAccessPluginSetup,
ApmDataAccessPluginStart,
} from '@kbn/apm-data-access-plugin/server';
import { LogsDataAccessPluginStart } from '@kbn/logs-data-access-plugin/server';

export interface InfraServerPluginSetupDeps {
alerting: AlertingPluginContract;
Expand All @@ -64,6 +65,7 @@ export interface InfraServerPluginStartDeps {
profilingDataAccess?: ProfilingDataAccessPluginStart;
ruleRegistry: RuleRegistryPluginStartContract;
apmDataAccess: ApmDataAccessPluginStart;
logsDataAccess: LogsDataAccessPluginStart;
}

export interface CallWithRequestParams extends estypes.RequestBase {
Expand Down
Loading

0 comments on commit 59abfd3

Please sign in to comment.