-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Logs UI] Register Logs UI Locators (#155156)
## Summary Closes #104855 This PR creates 2 registered locators: 1. Logs Locator 2. Node Logs Locator With these 2 locators, we now have a typed navigation to the logs UI which also redirects to Discover in serverless mode. ## Testing ### Normal behaviour When Kibana is used as always then on any navigation to the logs UI, the user will be redirected to the stream UI. All links to `link-to` routes should still behave as before. - Launch the Kibana dev environment with `yarn start` - Navigate to Hosts UI - Click the logs tab - Add a filter text in the search bar - Click on the Open in Logs link - Verify that navigation to the Stream view and the state is maintained https://user-images.githubusercontent.com/11225826/234514430-ddc1ffaa-0cb2-4f2a-84e9-6c6230937d9f.mov ### Serverless behaviour When Kibana is used in serverless mode, we want to redirect any user landing to Logs UI to the Discover page - Launch the Kibana dev environment with `yarn serverless-oblt` - Navigate to Hosts UI - Click the logs tab - Add a filter text in the search bar - Click on the Open in Logs link - Verify to be redirected to Discover and that the state is maintained https://user-images.githubusercontent.com/11225826/234514454-dfb2774e-d6f1-4f4c-ba10-77815dc1ae9d.mov ### Next Steps A separate PR will be created to fulfill the below AC - All usages of link-to routes in other apps are replaced with usage of the appropriate locator.
- Loading branch information
1 parent
0eb1d0f
commit 5d96ef9
Showing
29 changed files
with
872 additions
and
667 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
25 changes: 25 additions & 0 deletions
25
x-pack/plugins/infra/public/locators/discover_logs_locator.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/* | ||
* 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 { LocatorDefinition, LocatorPublic } from '@kbn/share-plugin/public'; | ||
import type { LogsLocatorDependencies, LogsLocatorParams } from './logs_locator'; | ||
|
||
const DISCOVER_LOGS_LOCATOR_ID = 'DISCOVER_LOGS_LOCATOR'; | ||
|
||
export type DiscoverLogsLocator = LocatorPublic<LogsLocatorParams>; | ||
|
||
export class DiscoverLogsLocatorDefinition implements LocatorDefinition<LogsLocatorParams> { | ||
public readonly id = DISCOVER_LOGS_LOCATOR_ID; | ||
|
||
constructor(protected readonly deps: LogsLocatorDependencies) {} | ||
|
||
public readonly getLocation = async (params: LogsLocatorParams) => { | ||
const { getLocationToDiscover } = await import('./helpers'); | ||
|
||
return getLocationToDiscover({ core: this.deps.core, ...params }); | ||
}; | ||
} |
33 changes: 33 additions & 0 deletions
33
x-pack/plugins/infra/public/locators/discover_node_logs_locator.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* | ||
* 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 { LocatorDefinition, LocatorPublic } from '@kbn/share-plugin/public'; | ||
import type { NodeLogsLocatorDependencies, NodeLogsLocatorParams } from './node_logs_locator'; | ||
|
||
const DISCOVER_NODE_LOGS_LOCATOR_ID = 'DISCOVER_NODE_LOGS_LOCATOR'; | ||
|
||
export type DiscoverNodeLogsLocator = LocatorPublic<NodeLogsLocatorParams>; | ||
|
||
export class DiscoverNodeLogsLocatorDefinition implements LocatorDefinition<NodeLogsLocatorParams> { | ||
public readonly id = DISCOVER_NODE_LOGS_LOCATOR_ID; | ||
|
||
constructor(protected readonly deps: NodeLogsLocatorDependencies) {} | ||
|
||
public readonly getLocation = async (params: NodeLogsLocatorParams) => { | ||
const { createNodeLogsQuery, getLocationToDiscover } = await import('./helpers'); | ||
|
||
const { timeRange, logView } = params; | ||
const query = createNodeLogsQuery(params); | ||
|
||
return getLocationToDiscover({ | ||
core: this.deps.core, | ||
timeRange, | ||
filter: query, | ||
logView, | ||
}); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
/* | ||
* 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 { interpret } from 'xstate'; | ||
import { waitFor } from 'xstate/lib/waitFor'; | ||
import { flowRight } from 'lodash'; | ||
import type { DiscoverAppLocatorParams } from '@kbn/discover-plugin/common'; | ||
import type { DiscoverStart } from '@kbn/discover-plugin/public'; | ||
import { findInventoryFields } from '../../common/inventory_models'; | ||
import { MESSAGE_FIELD, TIMESTAMP_FIELD } from '../../common/constants'; | ||
import { | ||
createLogViewStateMachine, | ||
DEFAULT_LOG_VIEW, | ||
replaceLogViewInQueryString, | ||
} from '../observability_logs/log_view_state'; | ||
import { replaceLogFilterInQueryString } from '../observability_logs/log_stream_query_state'; | ||
import { replaceLogPositionInQueryString } from '../observability_logs/log_stream_position_state/src/url_state_storage_service'; | ||
import type { TimeRange } from '../../common/time'; | ||
import type { LogsLocatorParams } from './logs_locator'; | ||
import type { InfraClientCoreSetup } from '../types'; | ||
import type { | ||
LogViewColumnConfiguration, | ||
LogViewReference, | ||
ResolvedLogView, | ||
} from '../../common/log_views'; | ||
import type { NodeLogsLocatorParams } from './node_logs_locator'; | ||
|
||
interface LocationToDiscoverParams { | ||
core: InfraClientCoreSetup; | ||
timeRange?: TimeRange; | ||
filter?: string; | ||
logView?: LogViewReference; | ||
} | ||
|
||
export const createNodeLogsQuery = (params: NodeLogsLocatorParams) => { | ||
const { nodeType, nodeId, filter } = params; | ||
|
||
const nodeFilter = `${findInventoryFields(nodeType).id}: ${nodeId}`; | ||
const query = filter ? `(${nodeFilter}) and (${filter})` : nodeFilter; | ||
|
||
return query; | ||
}; | ||
|
||
export const createSearchString = ({ | ||
time, | ||
timeRange, | ||
filter = '', | ||
logView = DEFAULT_LOG_VIEW, | ||
}: LogsLocatorParams) => { | ||
return flowRight( | ||
replaceLogFilterInQueryString({ language: 'kuery', query: filter }, time, timeRange), | ||
replaceLogPositionInQueryString(time), | ||
replaceLogViewInQueryString(logView) | ||
)(''); | ||
}; | ||
|
||
export const getLocationToDiscover = async ({ | ||
core, | ||
timeRange, | ||
filter, | ||
logView, | ||
}: LocationToDiscoverParams) => { | ||
const [, plugins, pluginStart] = await core.getStartServices(); | ||
const { discover } = plugins; | ||
const { logViews } = pluginStart; | ||
|
||
const machine = createLogViewStateMachine({ | ||
initialContext: { logViewReference: logView || DEFAULT_LOG_VIEW }, | ||
logViews: logViews.client, | ||
}); | ||
|
||
const discoverParams: DiscoverAppLocatorParams = { | ||
...(timeRange ? { from: timeRange.startTime, to: timeRange.endTime } : {}), | ||
...(filter | ||
? { | ||
query: { | ||
language: 'kuery', | ||
query: filter, | ||
}, | ||
} | ||
: {}), | ||
}; | ||
|
||
let discoverLocation; | ||
|
||
const service = interpret(machine).start(); | ||
const doneState = await waitFor( | ||
service, | ||
(state) => | ||
state.matches('checkingStatus') || | ||
state.matches('resolvedPersistedLogView') || | ||
state.matches('resolvedInlineLogView') || | ||
state.matches('loadingFailed') || | ||
state.matches('resolutionFailed') || | ||
state.matches('checkingStatusFailed') | ||
); | ||
|
||
service.stop(); | ||
|
||
if ('resolvedLogView' in doneState.context) { | ||
discoverLocation = await constructDiscoverLocation( | ||
discover, | ||
discoverParams, | ||
doneState.context.resolvedLogView | ||
); | ||
} else { | ||
discoverLocation = await constructDiscoverLocation(discover, discoverParams); | ||
} | ||
|
||
if (!discoverLocation) { | ||
throw new Error('Discover location not found'); | ||
} | ||
|
||
return discoverLocation; | ||
}; | ||
|
||
const constructDiscoverLocation = async ( | ||
discover: DiscoverStart, | ||
discoverParams: DiscoverAppLocatorParams, | ||
resolvedLogView?: ResolvedLogView | ||
) => { | ||
if (!resolvedLogView) { | ||
return await discover.locator?.getLocation(discoverParams); | ||
} | ||
|
||
const columns = parseColumns(resolvedLogView.columns); | ||
const dataViewSpec = resolvedLogView.dataViewReference.toSpec(); | ||
|
||
return await discover.locator?.getLocation({ | ||
...discoverParams, | ||
columns, | ||
dataViewId: dataViewSpec.id, | ||
dataViewSpec, | ||
}); | ||
}; | ||
|
||
const parseColumns = (columns: ResolvedLogView['columns']) => { | ||
return columns.map(getColumnValue).filter(Boolean) as string[]; | ||
}; | ||
|
||
const getColumnValue = (column: LogViewColumnConfiguration) => { | ||
if ('messageColumn' in column) return MESSAGE_FIELD; | ||
if ('timestampColumn' in column) return TIMESTAMP_FIELD; | ||
if ('fieldColumn' in column) return column.fieldColumn.field; | ||
|
||
return null; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +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. | ||
*/ | ||
|
||
import type { DiscoverLogsLocator } from './discover_logs_locator'; | ||
import type { DiscoverNodeLogsLocator } from './discover_node_logs_locator'; | ||
import type { LogsLocator } from './logs_locator'; | ||
import type { NodeLogsLocator } from './node_logs_locator'; | ||
|
||
export * from './discover_logs_locator'; | ||
export * from './discover_node_logs_locator'; | ||
export * from './logs_locator'; | ||
export * from './node_logs_locator'; | ||
|
||
export interface InfraLocators { | ||
logsLocator: LogsLocator | DiscoverLogsLocator; | ||
nodeLogsLocator: NodeLogsLocator | DiscoverNodeLogsLocator; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import { sharePluginMock } from '@kbn/share-plugin/public/mocks'; | ||
import type { InfraLocators } from '.'; | ||
|
||
export const createLocatorMock = (): jest.Mocked<InfraLocators> => ({ | ||
logsLocator: sharePluginMock.createLocator(), | ||
nodeLogsLocator: sharePluginMock.createLocator(), | ||
}); |
Oops, something went wrong.