diff --git a/packages/kbn-es-archiver/src/lib/indices/create_index_stream.ts b/packages/kbn-es-archiver/src/lib/indices/create_index_stream.ts index bb59ca9c5e9d4..c41ff3a399797 100644 --- a/packages/kbn-es-archiver/src/lib/indices/create_index_stream.ts +++ b/packages/kbn-es-archiver/src/lib/indices/create_index_stream.ts @@ -10,7 +10,7 @@ import { Transform, Readable } from 'stream'; import { inspect } from 'util'; -import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import * as estypes from '@elastic/elasticsearch/lib/api/types'; import type { Client } from '@elastic/elasticsearch'; import { ToolingLog } from '@kbn/tooling-log'; diff --git a/packages/kbn-es-query/src/filters/build_filters/exists_filter.ts b/packages/kbn-es-query/src/filters/build_filters/exists_filter.ts index 5cce6d939156a..7246962a85269 100644 --- a/packages/kbn-es-query/src/filters/build_filters/exists_filter.ts +++ b/packages/kbn-es-query/src/filters/build_filters/exists_filter.ts @@ -57,3 +57,16 @@ export const buildExistsFilter = (field: DataViewFieldBase, indexPattern: DataVi }, } as ExistsFilter; }; + +export const buildSimpleExistFilter = (fieldName: string, dataViewId: string) => { + return { + meta: { + index: dataViewId, + }, + query: { + exists: { + field: fieldName, + }, + }, + } as ExistsFilter; +}; diff --git a/packages/kbn-es-query/src/filters/build_filters/range_filter.ts b/packages/kbn-es-query/src/filters/build_filters/range_filter.ts index ebc11d36550d2..5b89e57548655 100644 --- a/packages/kbn-es-query/src/filters/build_filters/range_filter.ts +++ b/packages/kbn-es-query/src/filters/build_filters/range_filter.ts @@ -187,6 +187,20 @@ export const buildRangeFilter = ( } }; +export const buildSimpleNumberRangeFilter = ( + fieldName: string, + params: RangeFilterParams, + value: string, + dataViewId: string +) => { + return buildRangeFilter( + { name: fieldName, type: 'number' }, + params, + { id: dataViewId, title: dataViewId }, + value + ); +}; + /** * @internal */ diff --git a/packages/kbn-eslint-plugin-css/src/rules/no_css_color.test.ts b/packages/kbn-eslint-plugin-css/src/rules/no_css_color.test.ts index e1f683b09814f..d5323e7423ce4 100644 --- a/packages/kbn-eslint-plugin-css/src/rules/no_css_color.test.ts +++ b/packages/kbn-eslint-plugin-css/src/rules/no_css_color.test.ts @@ -45,7 +45,7 @@ const invalid: RuleTester.InvalidTestCase[] = [ filename: '/x-pack/plugins/observability_solution/observability/public/test_component.tsx', code: ` import React from 'react'; - + function TestComponent() { return ( This is a test @@ -86,7 +86,7 @@ const invalid: RuleTester.InvalidTestCase[] = [ filename: '/x-pack/plugins/observability_solution/observability/public/test_component.tsx', code: ` import React from 'react'; - + function TestComponent() { const baseStyle = { background: 'rgb(255, 255, 255)' }; @@ -116,7 +116,7 @@ const invalid: RuleTester.InvalidTestCase[] = [ filename: '/x-pack/plugins/observability_solution/observability/public/test_component.tsx', code: ` import React from 'react'; - + function TestComponent() { return ( This is a test @@ -129,7 +129,7 @@ const invalid: RuleTester.InvalidTestCase[] = [ filename: '/x-pack/plugins/observability_solution/observability/public/test_component.tsx', code: ` import React from 'react'; - + function TestComponent() { return ( This is a test @@ -153,7 +153,7 @@ const invalid: RuleTester.InvalidTestCase[] = [ code: ` import React from 'react'; import { css } from '@emotion/css'; - + function TestComponent() { return ( This is a test @@ -171,7 +171,7 @@ const invalid: RuleTester.InvalidTestCase[] = [ const codeCss = css({ color: '#dd4040', }) - + function TestComponent() { return ( This is a test @@ -187,7 +187,7 @@ const invalid: RuleTester.InvalidTestCase[] = [ import { css } from '@emotion/css'; const codeCss = css\` color: #dd4040; \` - + function TestComponent() { return ( This is a test @@ -200,7 +200,7 @@ const invalid: RuleTester.InvalidTestCase[] = [ filename: '/x-pack/plugins/observability_solution/observability/public/test_component.tsx', code: ` import React from 'react'; - + function TestComponent() { return ( ({ color: '#dd4040' })}>This is a test @@ -213,7 +213,7 @@ const invalid: RuleTester.InvalidTestCase[] = [ filename: '/x-pack/plugins/observability_solution/observability/public/test_component.tsx', code: ` import React from 'react'; - + function TestComponent() { return ( This is a test @@ -227,7 +227,7 @@ const invalid: RuleTester.InvalidTestCase[] = [ code: ` import React from 'react'; import { css } from '@emotion/css'; - + function TestComponent() { return ( This is a test @@ -237,7 +237,24 @@ const invalid: RuleTester.InvalidTestCase[] = [ }, ]; -const valid: RuleTester.ValidTestCase[] = []; +const valid: RuleTester.ValidTestCase[] = [ + { + name: 'Does not raise an error when a CSS color is not used in a JSX css prop attribute', + filename: '/x-pack/plugins/observability_solution/observability/public/test_component.tsx', + code: ` + import React from 'react'; + import { EuiCode } from '@elastic/eui'; + import { css } from '@emotion/react'; + function TestComponent() { + return ( + This is a test + ) + }`, + }, +]; for (const [name, tester] of [tsTester, babelTester]) { describe(name, () => { diff --git a/packages/kbn-eslint-plugin-css/src/rules/no_css_color.ts b/packages/kbn-eslint-plugin-css/src/rules/no_css_color.ts index c453e5edfcd74..fb73fe53fda07 100644 --- a/packages/kbn-eslint-plugin-css/src/rules/no_css_color.ts +++ b/packages/kbn-eslint-plugin-css/src/rules/no_css_color.ts @@ -30,8 +30,8 @@ const checkPropertySpecifiesInvalidCSSColor = ([property, value]: string[]) => { const style = new CSSStyleDeclaration(); - // @ts-ignore the types for this packages specifics an index signature of number, alongside other valid CSS properties - style[property] = value; + // @ts-ignore the types for this packages specifies an index signature of number, alongside other valid CSS properties + style[property.trim()] = typeof value === 'string' ? value.trim() : value; const anchor = propertiesSupportingCssColor.find((resolvedProperty) => property.includes(resolvedProperty) @@ -42,9 +42,9 @@ const checkPropertySpecifiesInvalidCSSColor = ([property, value]: string[]) => { // build the resolved color property to check if the value is a string after parsing the style declaration const resolvedColorProperty = anchor === 'color' ? 'color' : anchor + 'Color'; - // in trying to keep this rule simple, it's enough if a string is used to define a color to mark it as invalid + // in trying to keep this rule simple, it's enough if we get a value back, because if it was an identifier we would have been able to set a value within this invocation // @ts-ignore the types for this packages specifics an index signature of number, alongside other valid CSS properties - return typeof style[resolvedColorProperty] === 'string'; + return Boolean(style[resolvedColorProperty]); }; const resolveMemberExpressionRoot = (node: TSESTree.MemberExpression): TSESTree.Identifier => { diff --git a/packages/kbn-management/settings/setting_ids/index.ts b/packages/kbn-management/settings/setting_ids/index.ts index 0a1b3e2bcdade..58024e2ae31f3 100644 --- a/packages/kbn-management/settings/setting_ids/index.ts +++ b/packages/kbn-management/settings/setting_ids/index.ts @@ -137,7 +137,6 @@ export const OBSERVABILITY_LOGS_EXPLORER_ALLOWED_DATA_VIEWS_ID = export const OBSERVABILITY_LOGS_SHARED_NEW_LOGS_OVERVIEW_ID = 'observability:newLogsOverview'; export const OBSERVABILITY_ENTITY_CENTRIC_EXPERIENCE = 'observability:entityCentricExperience'; export const OBSERVABILITY_LOGS_DATA_ACCESS_LOG_SOURCES_ID = 'observability:logSources'; -export const OBSERVABILITY_ENABLE_LOGS_STREAM = 'observability:enableLogsStream'; export const OBSERVABILITY_AI_ASSISTANT_SIMULATED_FUNCTION_CALLING = 'observability:aiAssistantSimulatedFunctionCalling'; export const OBSERVABILITY_AI_ASSISTANT_SEARCH_CONNECTOR_INDEX_PATTERN = diff --git a/packages/kbn-performance-testing-dataset-extractor/src/es_client.ts b/packages/kbn-performance-testing-dataset-extractor/src/es_client.ts index 7c38789fe3dd9..97d0c390d8aee 100644 --- a/packages/kbn-performance-testing-dataset-extractor/src/es_client.ts +++ b/packages/kbn-performance-testing-dataset-extractor/src/es_client.ts @@ -9,7 +9,7 @@ import { Client } from '@elastic/elasticsearch'; import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; -import { SearchRequest, MsearchRequestItem } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { SearchRequest, MsearchRequestItem } from '@elastic/elasticsearch/lib/api/types'; import { ToolingLog } from '@kbn/tooling-log'; interface ClientOptions { @@ -116,26 +116,24 @@ export class ESClient { async getTransactions(queryFilters: QueryDslQueryContainer[]) { const searchRequest: SearchRequest = { index: this.tracesIndex, - body: { - sort: [ - { - '@timestamp': { - order: 'asc', - unmapped_type: 'boolean', - }, + sort: [ + { + '@timestamp': { + order: 'asc', + unmapped_type: 'boolean', }, - ], - size: 10000, - query: { - bool: { - filter: [ - { - bool: { - filter: queryFilters, - }, + }, + ], + size: 10000, + query: { + bool: { + filter: [ + { + bool: { + filter: queryFilters, }, - ], - }, + }, + ], }, }, }; diff --git a/src/platform/packages/shared/kbn-esql-utils/index.ts b/src/platform/packages/shared/kbn-esql-utils/index.ts index 0956816c59ed7..7d75e230389f5 100644 --- a/src/platform/packages/shared/kbn-esql-utils/index.ts +++ b/src/platform/packages/shared/kbn-esql-utils/index.ts @@ -33,6 +33,7 @@ export { isESQLColumnGroupable, isESQLFieldGroupable, TextBasedLanguages, + sanitazeESQLInput, queryCannotBeSampled, } from './src'; diff --git a/src/platform/packages/shared/kbn-esql-utils/src/index.ts b/src/platform/packages/shared/kbn-esql-utils/src/index.ts index d56a56c62d6ba..a28d9c6244f74 100644 --- a/src/platform/packages/shared/kbn-esql-utils/src/index.ts +++ b/src/platform/packages/shared/kbn-esql-utils/src/index.ts @@ -37,3 +37,4 @@ export { isESQLColumnGroupable, isESQLFieldGroupable, } from './utils/esql_fields_utils'; +export { sanitazeESQLInput } from './utils/sanitaze_input'; diff --git a/src/platform/packages/shared/kbn-esql-utils/src/utils/append_to_query.ts b/src/platform/packages/shared/kbn-esql-utils/src/utils/append_to_query.ts index 36af3c91a8f04..4a7736714effa 100644 --- a/src/platform/packages/shared/kbn-esql-utils/src/utils/append_to_query.ts +++ b/src/platform/packages/shared/kbn-esql-utils/src/utils/append_to_query.ts @@ -8,6 +8,7 @@ */ import { getAstAndSyntaxErrors } from '@kbn/esql-ast'; +import { sanitazeESQLInput } from './sanitaze_input'; // Append in a new line the appended text to take care of the case where the user adds a comment at the end of the query // in these cases a base query such as "from index // comment" will result in errors or wrong data if we don't append in a new line @@ -43,7 +44,7 @@ export function appendWhereClauseToESQLQuery( let filterValue = typeof value === 'string' ? `"${value.replace(/\\/g, '\\\\').replace(/\"/g, '\\"')}"` : value; // Adding the backticks here are they are needed for special char fields - let fieldName = `\`${field}\``; + let fieldName = sanitazeESQLInput(field); // casting to string // there are some field types such as the ip that need diff --git a/src/platform/packages/shared/kbn-esql-utils/src/utils/sanitaze_input.ts b/src/platform/packages/shared/kbn-esql-utils/src/utils/sanitaze_input.ts new file mode 100644 index 0000000000000..a776b1b4ae961 --- /dev/null +++ b/src/platform/packages/shared/kbn-esql-utils/src/utils/sanitaze_input.ts @@ -0,0 +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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +export function sanitazeESQLInput(input: string): string | undefined { + return `\`${input.replace(/`/g, '``')}\``; +} diff --git a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.ts b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.ts index 2a37155358e85..e0b5d8c3ffcee 100644 --- a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.ts +++ b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.ts @@ -612,22 +612,30 @@ async function getExpressionSuggestionsByType( (fragment) => Boolean(getColumnByName(fragment, references)), (_fragment: string, rangeToReplace?: { start: number; end: number }) => { // COMMAND fie - return fieldSuggestions.map((suggestion) => ({ - ...suggestion, - text: suggestion.text + (['grok', 'dissect'].includes(command.name) ? ' ' : ''), - command: TRIGGER_SUGGESTION_COMMAND, - rangeToReplace, - })); + return fieldSuggestions.map((suggestion) => { + // if there is already a command, we don't want to override it + if (suggestion.command) return suggestion; + return { + ...suggestion, + text: suggestion.text + (['grok', 'dissect'].includes(command.name) ? ' ' : ''), + command: TRIGGER_SUGGESTION_COMMAND, + rangeToReplace, + }; + }); }, (fragment: string, rangeToReplace: { start: number; end: number }) => { // COMMAND field if (['grok', 'dissect'].includes(command.name)) { - return fieldSuggestions.map((suggestion) => ({ - ...suggestion, - text: suggestion.text + ' ', - command: TRIGGER_SUGGESTION_COMMAND, - rangeToReplace, - })); + return fieldSuggestions.map((suggestion) => { + // if there is already a command, we don't want to override it + if (suggestion.command) return suggestion; + return { + ...suggestion, + text: suggestion.text + ' ', + command: TRIGGER_SUGGESTION_COMMAND, + rangeToReplace, + }; + }); } const finalSuggestions = [{ ...pipeCompleteItem, text: ' | ' }]; diff --git a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/commands/drop/index.ts b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/commands/drop/index.ts index 43eb272ba203a..dee04f5f8eba6 100644 --- a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/commands/drop/index.ts +++ b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/commands/drop/index.ts @@ -41,12 +41,16 @@ export async function suggest( (fragment) => columnExists(fragment), (_fragment: string, rangeToReplace?: { start: number; end: number }) => { // KEEP fie - return fieldSuggestions.map((suggestion) => ({ - ...suggestion, - text: suggestion.text, - command: TRIGGER_SUGGESTION_COMMAND, - rangeToReplace, - })); + return fieldSuggestions.map((suggestion) => { + // if there is already a command, we don't want to override it + if (suggestion.command) return suggestion; + return { + ...suggestion, + text: suggestion.text, + command: TRIGGER_SUGGESTION_COMMAND, + rangeToReplace, + }; + }); }, (fragment: string, rangeToReplace: { start: number; end: number }) => { // KEEP field diff --git a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/commands/keep/index.ts b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/commands/keep/index.ts index 85d5c716b20a6..f17f9cf7445ca 100644 --- a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/commands/keep/index.ts +++ b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/commands/keep/index.ts @@ -41,12 +41,16 @@ export async function suggest( (fragment) => columnExists(fragment), (_fragment: string, rangeToReplace?: { start: number; end: number }) => { // KEEP fie - return fieldSuggestions.map((suggestion) => ({ - ...suggestion, - text: suggestion.text, - command: TRIGGER_SUGGESTION_COMMAND, - rangeToReplace, - })); + return fieldSuggestions.map((suggestion) => { + // if there is already a command, we don't want to override it + if (suggestion.command) return suggestion; + return { + ...suggestion, + text: suggestion.text, + command: TRIGGER_SUGGESTION_COMMAND, + rangeToReplace, + }; + }); }, (fragment: string, rangeToReplace: { start: number; end: number }) => { // KEEP field diff --git a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/commands/sort/index.ts b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/commands/sort/index.ts index 61561dea96b72..8012abc5be6d2 100644 --- a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/commands/sort/index.ts +++ b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/commands/sort/index.ts @@ -128,11 +128,15 @@ export async function suggest( // SORT fie return [ ...pushItUpInTheList( - fieldSuggestions.map((suggestion) => ({ - ...suggestion, - command: TRIGGER_SUGGESTION_COMMAND, - rangeToReplace, - })), + fieldSuggestions.map((suggestion) => { + // if there is already a command, we don't want to override it + if (suggestion.command) return suggestion; + return { + ...suggestion, + command: TRIGGER_SUGGESTION_COMMAND, + rangeToReplace, + }; + }), true ), ...functionSuggestions, diff --git a/src/plugins/data/common/search/aggs/buckets/lib/time_buckets/time_buckets.ts b/src/plugins/data/common/search/aggs/buckets/lib/time_buckets/time_buckets.ts index 9028a696ef022..054a7b923ca6a 100644 --- a/src/plugins/data/common/search/aggs/buckets/lib/time_buckets/time_buckets.ts +++ b/src/plugins/data/common/search/aggs/buckets/lib/time_buckets/time_buckets.ts @@ -23,7 +23,7 @@ import { } from './calc_es_interval'; import { autoInterval } from '../../_interval_options'; -interface TimeBucketsInterval extends moment.Duration { +export interface TimeBucketsInterval extends moment.Duration { // TODO double-check whether all of these are needed description: string; esValue: EsInterval['value']; diff --git a/src/plugins/data/common/search/aggs/utils/calculate_auto_time_expression.ts b/src/plugins/data/common/search/aggs/utils/calculate_auto_time_expression.ts index c16810f27280b..fa9e2b45f0562 100644 --- a/src/plugins/data/common/search/aggs/utils/calculate_auto_time_expression.ts +++ b/src/plugins/data/common/search/aggs/utils/calculate_auto_time_expression.ts @@ -8,6 +8,7 @@ */ import moment from 'moment'; +import { TimeBucketsInterval } from '../buckets/lib/time_buckets/time_buckets'; import { UI_SETTINGS } from '../../../constants'; import { TimeRange } from '../../../query'; import { TimeBuckets } from '../buckets/lib/time_buckets'; @@ -15,7 +16,28 @@ import { toAbsoluteDates } from './date_interval_utils'; import { autoInterval } from '../buckets/_interval_options'; export function getCalculateAutoTimeExpression(getConfig: (key: string) => any) { - return function calculateAutoTimeExpression(range: TimeRange) { + function calculateAutoTimeExpression(range: TimeRange): string | undefined; + function calculateAutoTimeExpression( + range: TimeRange, + interval: string, + asExpression?: true + ): string | undefined; + function calculateAutoTimeExpression( + range: TimeRange, + interval: string, + asExpression: false + ): TimeBucketsInterval | undefined; + function calculateAutoTimeExpression( + range: TimeRange, + interval?: string, + asExpression?: boolean + ): string | TimeBucketsInterval | undefined; + + function calculateAutoTimeExpression( + range: TimeRange, + interval: string = autoInterval, + asExpression: boolean = true + ): string | TimeBucketsInterval | undefined { const dates = toAbsoluteDates(range); if (!dates) { return; @@ -28,12 +50,18 @@ export function getCalculateAutoTimeExpression(getConfig: (key: string) => any) 'dateFormat:scaled': getConfig('dateFormat:scaled'), }); - buckets.setInterval(autoInterval); + buckets.setInterval(interval); buckets.setBounds({ min: moment(dates.from), max: moment(dates.to), }); - return buckets.getInterval().expression; - }; + const intervalResult = buckets.getInterval(); + if (asExpression) { + return intervalResult.expression; + } + return intervalResult; + } + + return calculateAutoTimeExpression; } diff --git a/src/plugins/data/common/search/expressions/esql.ts b/src/plugins/data/common/search/expressions/esql.ts index cc1180ff57e49..59f5d2a642fbf 100644 --- a/src/plugins/data/common/search/expressions/esql.ts +++ b/src/plugins/data/common/search/expressions/esql.ts @@ -17,7 +17,7 @@ import type { } from '@kbn/search-types'; import type { Datatable, ExpressionFunctionDefinition } from '@kbn/expressions-plugin/common'; import { RequestAdapter } from '@kbn/inspector-plugin/common'; -import { getStartEndParams } from '@kbn/esql-utils'; +import { getIndexPatternFromESQLQuery, getStartEndParams } from '@kbn/esql-utils'; import { zipObject } from 'lodash'; import { catchError, defer, map, Observable, switchMap, tap, throwError } from 'rxjs'; import { buildEsQuery, type Filter } from '@kbn/es-query'; @@ -58,6 +58,7 @@ interface Arguments { */ titleForInspector?: string; descriptionForInspector?: string; + ignoreGlobalFilters?: boolean; } export type EsqlExpressionFunctionDefinition = ExpressionFunctionDefinition< @@ -140,10 +141,24 @@ export const getEsqlFn = ({ getStartDependencies }: EsqlFnArguments) => { defaultMessage: 'The description to show in Inspector.', }), }, + ignoreGlobalFilters: { + types: ['boolean'], + default: false, + help: i18n.translate('data.search.esql.ignoreGlobalFilters.help', { + defaultMessage: 'Whether to ignore or use global query and filters', + }), + }, }, fn( input, - { query, /* timezone, */ timeField, locale, titleForInspector, descriptionForInspector }, + { + query, + /* timezone, */ timeField, + locale, + titleForInspector, + descriptionForInspector, + ignoreGlobalFilters, + }, { abortSignal, inspectorAdapters, getKibanaRequest } ) { return defer(() => @@ -202,7 +217,7 @@ export const getEsqlFn = ({ getStartDependencies }: EsqlFnArguments) => { : undefined; const filters = [ - ...(input.filters ?? []), + ...(ignoreGlobalFilters ? [] : input.filters ?? []), ...(timeFilter ? [timeFilter] : []), ...(delayFilter ? [delayFilter] : []), ]; @@ -311,6 +326,8 @@ export const getEsqlFn = ({ getStartDependencies }: EsqlFnArguments) => { const lookup = new Set( hasEmptyColumns ? body.columns?.map(({ name }) => name) || [] : [] ); + const indexPattern = getIndexPatternFromESQLQuery(query); + const allColumns = (body.all_columns ?? body.columns)?.map(({ name, type }) => ({ id: name, @@ -323,8 +340,11 @@ export const getEsqlFn = ({ getStartDependencies }: EsqlFnArguments) => { ? { appliedTimeRange: input?.timeRange, params: {}, + indexPattern, } - : {}, + : { + indexPattern, + }, }, isNull: hasEmptyColumns ? !lookup.has(name) : false, })) ?? []; @@ -341,6 +361,10 @@ export const getEsqlFn = ({ getStartDependencies }: EsqlFnArguments) => { type: 'datatable', meta: { type: ESQL_TABLE_TYPE, + query, + statistics: { + totalCount: body.values.length, + }, }, columns: allColumns, rows, diff --git a/src/plugins/discover/public/components/discover_grid/discover_grid.tsx b/src/plugins/discover/public/components/discover_grid/discover_grid.tsx index e909d3e256d22..b14da8c2d4836 100644 --- a/src/plugins/discover/public/components/discover_grid/discover_grid.tsx +++ b/src/plugins/discover/public/components/discover_grid/discover_grid.tsx @@ -63,6 +63,7 @@ export const DiscoverGrid: React.FC = ({ renderCustomToolbar={renderCustomToolbar} getRowIndicator={getRowIndicator} rowAdditionalLeadingControls={rowAdditionalLeadingControls} + visibleCellActions={3} // this allows to show up to 3 actions on cell hover if available (filter in, filter out, and copy) {...props} /> ); diff --git a/src/plugins/discover/public/context_awareness/profile_providers/observability/log_document_profile/accessors/get_doc_viewer.tsx b/src/plugins/discover/public/context_awareness/profile_providers/observability/log_document_profile/accessors/get_doc_viewer.tsx index 1d433b5272d7b..89bb1166d7a2c 100644 --- a/src/plugins/discover/public/context_awareness/profile_providers/observability/log_document_profile/accessors/get_doc_viewer.tsx +++ b/src/plugins/discover/public/context_awareness/profile_providers/observability/log_document_profile/accessors/get_doc_viewer.tsx @@ -11,11 +11,18 @@ import { i18n } from '@kbn/i18n'; import { UnifiedDocViewerLogsOverview } from '@kbn/unified-doc-viewer-plugin/public'; import React from 'react'; import type { DocumentProfileProvider } from '../../../../profiles'; +import { ProfileProviderServices } from '../../../profile_provider_services'; -export const getDocViewer: DocumentProfileProvider['profile']['getDocViewer'] = - (prev) => (params) => { +export const createGetDocViewer = + (services: ProfileProviderServices): DocumentProfileProvider['profile']['getDocViewer'] => + (prev) => + (params) => { const prevDocViewer = prev(params); + const logsAIAssistantFeature = services.discoverShared.features.registry.getById( + 'observability-logs-ai-assistant' + ); + return { ...prevDocViewer, docViewsRegistry: (registry) => { @@ -25,7 +32,12 @@ export const getDocViewer: DocumentProfileProvider['profile']['getDocViewer'] = defaultMessage: 'Log overview', }), order: 0, - component: (props) => , + component: (props) => ( + + ), }); return prevDocViewer.docViewsRegistry(registry); diff --git a/src/plugins/discover/public/context_awareness/profile_providers/observability/log_document_profile/accessors/index.ts b/src/plugins/discover/public/context_awareness/profile_providers/observability/log_document_profile/accessors/index.ts index 6612fbc50e5c6..19941fc188720 100644 --- a/src/plugins/discover/public/context_awareness/profile_providers/observability/log_document_profile/accessors/index.ts +++ b/src/plugins/discover/public/context_awareness/profile_providers/observability/log_document_profile/accessors/index.ts @@ -7,4 +7,4 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -export { getDocViewer } from './get_doc_viewer'; +export { createGetDocViewer } from './get_doc_viewer'; diff --git a/src/plugins/discover/public/context_awareness/profile_providers/observability/log_document_profile/profile.tsx b/src/plugins/discover/public/context_awareness/profile_providers/observability/log_document_profile/profile.tsx index e92bbb9a59605..7d7662fbf20b4 100644 --- a/src/plugins/discover/public/context_awareness/profile_providers/observability/log_document_profile/profile.tsx +++ b/src/plugins/discover/public/context_awareness/profile_providers/observability/log_document_profile/profile.tsx @@ -10,7 +10,7 @@ import { DataTableRecord } from '@kbn/discover-utils'; import { DocumentProfileProvider, DocumentType } from '../../../profiles'; import { ProfileProviderServices } from '../../profile_provider_services'; -import { getDocViewer } from './accessors'; +import { createGetDocViewer } from './accessors'; import { OBSERVABILITY_ROOT_PROFILE_ID } from '../consts'; export const createObservabilityLogDocumentProfileProvider = ( @@ -18,7 +18,7 @@ export const createObservabilityLogDocumentProfileProvider = ( ): DocumentProfileProvider => ({ profileId: 'observability-log-document-profile', profile: { - getDocViewer, + getDocViewer: createGetDocViewer(services), }, resolve: ({ record, rootContext }) => { if (rootContext.profileId !== OBSERVABILITY_ROOT_PROFILE_ID) { diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts index f04e8cc62022a..475f81d9be536 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts @@ -502,10 +502,6 @@ export const stackManagementSchema: MakeSchemaFrom = { _meta: { description: 'Non-default value of setting.' }, }, }, - 'observability:enableLogsStream': { - type: 'boolean', - _meta: { description: 'Non-default value of setting.' }, - }, 'banners:placement': { type: 'keyword', _meta: { description: 'Non-default value of setting.' }, diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts index 0182f688f5ecf..6614d08442c08 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts @@ -51,7 +51,6 @@ export interface UsageStats { 'observability:apmEnableServiceInventoryTableSearchBar': boolean; 'observability:logsExplorer:allowedDataViews': string[]; 'observability:logSources': string[]; - 'observability:enableLogsStream': boolean; 'observability:newLogsOverview': boolean; 'observability:aiAssistantSimulatedFunctionCalling': boolean; 'observability:aiAssistantSearchConnectorIndexPattern': string; diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json index 8ba1367641679..2fb6314a348b9 100644 --- a/src/plugins/telemetry/schema/oss_plugins.json +++ b/src/plugins/telemetry/schema/oss_plugins.json @@ -11010,12 +11010,6 @@ } } }, - "observability:enableLogsStream": { - "type": "boolean", - "_meta": { - "description": "Non-default value of setting." - } - }, "banners:placement": { "type": "keyword", "_meta": { diff --git a/test/functional/apps/dashboard/group1/create_and_add_embeddables.ts b/test/functional/apps/dashboard/group1/create_and_add_embeddables.ts index 34e78f3e68632..84afd3885f987 100644 --- a/test/functional/apps/dashboard/group1/create_and_add_embeddables.ts +++ b/test/functional/apps/dashboard/group1/create_and_add_embeddables.ts @@ -8,7 +8,6 @@ */ import expect from '@kbn/expect'; -import { OBSERVABILITY_ENABLE_LOGS_STREAM } from '@kbn/management-settings-ids'; import { VisualizeConstants } from '@kbn/visualizations-plugin/common/constants'; import { FtrProviderContext } from '../../../ftr_provider_context'; @@ -28,12 +27,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await kibanaServer.uiSettings.replace({ defaultIndex: '0bf35f60-3dc9-11e8-8660-4d65aa086b3c', }); - await kibanaServer.uiSettings.update({ [OBSERVABILITY_ENABLE_LOGS_STREAM]: true }); }); after(async () => { await kibanaServer.savedObjects.cleanStandardList(); - await kibanaServer.uiSettings.update({ [OBSERVABILITY_ENABLE_LOGS_STREAM]: false }); }); it('ensure toolbar popover closes on add', async () => { @@ -41,7 +38,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await dashboard.clickNewDashboard(); await dashboard.switchToEditMode(); await dashboardAddPanel.clickEditorMenuButton(); - await dashboardAddPanel.clickAddNewPanelFromUIActionLink('Log stream (deprecated)'); + await dashboardAddPanel.clickAddNewPanelFromUIActionLink('Monitors stats'); await dashboardAddPanel.expectEditorMenuClosed(); }); diff --git a/test/tsconfig.json b/test/tsconfig.json index 1ba594b8ecbdb..10fdefbb7b6ac 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -75,7 +75,6 @@ "@kbn/default-nav-management", "@kbn/default-nav-devtools", "@kbn/core-saved-objects-import-export-server-internal", - "@kbn/management-settings-ids", "@kbn/core-deprecations-common", ] } diff --git a/x-pack/platform/plugins/private/translations/translations/fr-FR.json b/x-pack/platform/plugins/private/translations/translations/fr-FR.json index 98ea70111ef56..458e4ab1e73e5 100644 --- a/x-pack/platform/plugins/private/translations/translations/fr-FR.json +++ b/x-pack/platform/plugins/private/translations/translations/fr-FR.json @@ -23883,8 +23883,6 @@ "xpack.infra.durationUnits.weeks.singular": "semaine", "xpack.infra.durationUnits.years.plural": "années", "xpack.infra.durationUnits.years.singular": "an", - "xpack.infra.enableLogsStream": "Flux de logs", - "xpack.infra.enableLogsStreamDescription": "Active l'application Logs Stream héritée et le panneau du tableau de bord.", "xpack.infra.errorPage.errorOccurredTitle": "Une erreur s'est produite", "xpack.infra.errorPage.tryAgainButtonLabel": "Réessayer", "xpack.infra.errorPage.tryAgainDescription ": "Cliquez sur le bouton Retour et réessayez.", @@ -24274,8 +24272,6 @@ "xpack.infra.logsPage.toolbar.logFilterErrorToastTitle": "Erreur de filtrage du log", "xpack.infra.logsSettingsPage.loadingButtonLabel": "Chargement", "xpack.infra.logsStreamEmbeddable.deprecationWarningDescription": "La maintenance des panneaux de flux de logs n'est plus assurée. Essayez d'utiliser {savedSearchDocsLink} pour une visualisation similaire.", - "xpack.infra.logStreamEmbeddable.displayName": "Logs Stream (déclassé)", - "xpack.infra.logStreamEmbeddable.title": "Flux de log", "xpack.infra.logStreamPageTemplate.backtoLogsStream": "Retour au flux de logs", "xpack.infra.logStreamPageTemplate.widgetBadge": "Widget", "xpack.infra.logStreamPageTemplate.widgetDescription": "Vous visionnez un widget intégré. Les modifications seront synchronisées avec l'URL, mais elles ne seront pas conservées dans la vue par défaut du flux de logs.", @@ -33853,8 +33849,6 @@ "xpack.observability.obltNav.otherTools": "Autres outils", "xpack.observability.obltNav.otherTools.logsAnomalies": "Anomalies des logs", "xpack.observability.obltNav.otherTools.logsCategories": "Bibliothèque Visualize", - "xpack.observability.obltNav.otherTools.logsSettings": "Paramètres des logs", - "xpack.observability.obltNav.otherTools.logsStream": "Flux de logs", "xpack.observability.obltNav.stackManagement": "Gestion de la Suite", "xpack.observability.overview.alerts.appLink": "Afficher les alertes", "xpack.observability.overview.alerts.title": "Alertes", diff --git a/x-pack/platform/plugins/private/translations/translations/ja-JP.json b/x-pack/platform/plugins/private/translations/translations/ja-JP.json index 06802ee2be796..f396226fdf560 100644 --- a/x-pack/platform/plugins/private/translations/translations/ja-JP.json +++ b/x-pack/platform/plugins/private/translations/translations/ja-JP.json @@ -23745,8 +23745,6 @@ "xpack.infra.durationUnits.weeks.singular": "週", "xpack.infra.durationUnits.years.plural": "年", "xpack.infra.durationUnits.years.singular": "年", - "xpack.infra.enableLogsStream": "ログストリーム", - "xpack.infra.enableLogsStreamDescription": "レガシーログストリームアプリケーションとダッシュボードパネルを有効化します。", "xpack.infra.errorPage.errorOccurredTitle": "エラーが発生しました", "xpack.infra.errorPage.tryAgainButtonLabel": "再試行", "xpack.infra.errorPage.tryAgainDescription ": "戻るボタンをクリックして再試行してください。", @@ -24135,8 +24133,6 @@ "xpack.infra.logsPage.toolbar.logFilterErrorToastTitle": "ログフィルターエラー", "xpack.infra.logsSettingsPage.loadingButtonLabel": "読み込み中", "xpack.infra.logsStreamEmbeddable.deprecationWarningDescription": "ログストリームパネルは管理されていません。{savedSearchDocsLink}を同様の視覚化に活用してください。", - "xpack.infra.logStreamEmbeddable.displayName": "ログストリーム(廃止予定)", - "xpack.infra.logStreamEmbeddable.title": "ログストリーム", "xpack.infra.logStreamPageTemplate.backtoLogsStream": "ログストリームに戻る", "xpack.infra.logStreamPageTemplate.widgetBadge": "ウィジェット", "xpack.infra.logStreamPageTemplate.widgetDescription": "埋め込まれたウィジェットを表示しています。変更はURLと同期されますが、デフォルトログストリームビューには永続しません。", @@ -33714,8 +33710,6 @@ "xpack.observability.obltNav.otherTools": "その他のツール", "xpack.observability.obltNav.otherTools.logsAnomalies": "Logs異常", "xpack.observability.obltNav.otherTools.logsCategories": "Visualizeライブラリ", - "xpack.observability.obltNav.otherTools.logsSettings": "Logs設定", - "xpack.observability.obltNav.otherTools.logsStream": "ログストリーム", "xpack.observability.obltNav.stackManagement": "スタック管理", "xpack.observability.overview.alerts.appLink": "アラートを表示", "xpack.observability.overview.alerts.title": "アラート", diff --git a/x-pack/platform/plugins/private/translations/translations/zh-CN.json b/x-pack/platform/plugins/private/translations/translations/zh-CN.json index de40b51eca65e..73ef6cc59c976 100644 --- a/x-pack/platform/plugins/private/translations/translations/zh-CN.json +++ b/x-pack/platform/plugins/private/translations/translations/zh-CN.json @@ -23366,8 +23366,6 @@ "xpack.infra.durationUnits.weeks.singular": "周", "xpack.infra.durationUnits.years.plural": "年", "xpack.infra.durationUnits.years.singular": "年", - "xpack.infra.enableLogsStream": "日志流", - "xpack.infra.enableLogsStreamDescription": "启用旧版日志流应用程序和仪表板面板。", "xpack.infra.errorPage.errorOccurredTitle": "发生错误", "xpack.infra.errorPage.tryAgainButtonLabel": "重试", "xpack.infra.errorPage.tryAgainDescription ": "请点击后退按钮,然后重试。", @@ -23752,8 +23750,6 @@ "xpack.infra.logsPage.toolbar.logFilterErrorToastTitle": "日志筛选错误", "xpack.infra.logsSettingsPage.loadingButtonLabel": "正在加载", "xpack.infra.logsStreamEmbeddable.deprecationWarningDescription": "将不再维护日志流面板。尝试将 {savedSearchDocsLink} 用于类似可视化。", - "xpack.infra.logStreamEmbeddable.displayName": "日志流(已过时)", - "xpack.infra.logStreamEmbeddable.title": "日志流", "xpack.infra.logStreamPageTemplate.backtoLogsStream": "返回到日志流", "xpack.infra.logStreamPageTemplate.widgetBadge": "小组件", "xpack.infra.logStreamPageTemplate.widgetDescription": "您正在查看嵌入式小组件。更改将同步到 URL,但不会持续存在于默认日志流视图。", @@ -33229,8 +33225,6 @@ "xpack.observability.obltNav.otherTools": "其他工具", "xpack.observability.obltNav.otherTools.logsAnomalies": "日志异常", "xpack.observability.obltNav.otherTools.logsCategories": "Visualize 库", - "xpack.observability.obltNav.otherTools.logsSettings": "日志设置", - "xpack.observability.obltNav.otherTools.logsStream": "日志流", "xpack.observability.obltNav.stackManagement": "Stack Management", "xpack.observability.overview.alerts.appLink": "显示告警", "xpack.observability.overview.alerts.title": "告警", diff --git a/x-pack/plugins/observability_solution/apm/public/components/shared/stacktrace/cause_stacktrace.tsx b/x-pack/plugins/observability_solution/apm/public/components/shared/stacktrace/cause_stacktrace.tsx index d36a5bf422160..9db86f6147eb9 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/shared/stacktrace/cause_stacktrace.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/shared/stacktrace/cause_stacktrace.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { EuiAccordion, EuiTitle } from '@elastic/eui'; +import { EuiAccordion, EuiTitle, useEuiFontSize } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; import styled from '@emotion/styled'; @@ -24,7 +24,7 @@ const CausedByContainer = styled('h5')` const CausedByHeading = styled('span')` color: ${({ theme }) => theme.euiTheme.colors.textSubdued}; display: block; - font-size: ${({ theme }) => theme.euiTheme.size.xs}; + font-size: ${() => useEuiFontSize('xs').fontSize}; font-weight: ${({ theme }) => theme.euiTheme.font.weight.bold}; text-transform: uppercase; `; diff --git a/x-pack/plugins/observability_solution/apm/public/components/shared/stacktrace/stackframe.tsx b/x-pack/plugins/observability_solution/apm/public/components/shared/stacktrace/stackframe.tsx index 1180b1c9ed05c..8eb6138557d25 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/shared/stacktrace/stackframe.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/shared/stacktrace/stackframe.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { EuiAccordion } from '@elastic/eui'; +import { EuiAccordion, useEuiFontSize } from '@elastic/eui'; import React from 'react'; import styled from '@emotion/styled'; import { @@ -19,8 +19,8 @@ import { Variables } from './variables'; const ContextContainer = styled.div<{ isLibraryFrame: boolean }>` position: relative; font-family: ${({ theme }) => theme.euiTheme.font.familyCode}; - font-size: ${({ theme }) => theme.euiTheme.size.s}; - border: 1px solid ${({ theme }) => theme.euiTheme.colors.lightShade}; + font-size: ${() => useEuiFontSize('s').fontSize}; + border: ${({ theme }) => theme.euiTheme.border.thin}; border-radius: ${({ theme }) => theme.euiTheme.border.radius.small}; background: ${({ isLibraryFrame, theme }) => isLibraryFrame ? theme.euiTheme.colors.emptyShade : theme.euiTheme.colors.lightestShade}; diff --git a/x-pack/plugins/observability_solution/infra/common/ui_settings.ts b/x-pack/plugins/observability_solution/infra/common/ui_settings.ts deleted file mode 100644 index 9b85630761942..0000000000000 --- a/x-pack/plugins/observability_solution/infra/common/ui_settings.ts +++ /dev/null @@ -1,37 +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. - */ - -/** - * uiSettings definitions for the logs_data_access plugin. - */ -import { schema } from '@kbn/config-schema'; -import { UiSettingsParams } from '@kbn/core-ui-settings-common'; -import { i18n } from '@kbn/i18n'; -import { OBSERVABILITY_ENABLE_LOGS_STREAM } from '@kbn/management-settings-ids'; - -export const uiSettings: Record = { - [OBSERVABILITY_ENABLE_LOGS_STREAM]: { - category: ['observability'], - name: i18n.translate('xpack.infra.enableLogsStream', { - defaultMessage: 'Logs Stream', - }), - value: false, - description: i18n.translate('xpack.infra.enableLogsStreamDescription', { - defaultMessage: 'Enables the legacy Logs Stream application and dashboard panel. ', - }), - deprecation: { - message: i18n.translate('xpack.infra.enableLogsStreamDeprecationWarning', { - defaultMessage: - 'Logs Stream is deprecated, and this setting will be removed in Kibana 9.0.', - }), - docLinksKey: 'generalSettings', - }, - type: 'boolean', - schema: schema.boolean(), - requiresPageReload: true, - }, -}; diff --git a/x-pack/plugins/observability_solution/infra/public/components/logging/log_minimap/time_ruler.tsx b/x-pack/plugins/observability_solution/infra/public/components/logging/log_minimap/time_ruler.tsx index 59e94333e94ee..93df67958144a 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/logging/log_minimap/time_ruler.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/logging/log_minimap/time_ruler.tsx @@ -60,7 +60,7 @@ export const TimeRuler: React.FC = ({ end, height, start, tickCo TimeRuler.displayName = 'TimeRuler'; const TimeRulerTickLabel = styled.text` - font-size: 9px; + font-size: ${() => useEuiFontSize('xxxs').fontSize}; line-height: ${() => useEuiFontSize('s').lineHeight}; fill: ${(props) => props.theme.euiTheme.colors.textSubdued}; user-select: none; diff --git a/x-pack/plugins/observability_solution/infra/public/pages/logs/page_content.tsx b/x-pack/plugins/observability_solution/infra/public/pages/logs/page_content.tsx index ecf5af5572b31..bdb738c33315c 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/logs/page_content.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/logs/page_content.tsx @@ -9,7 +9,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiHeaderLink, EuiHeaderLinks } from '@elast import { i18n } from '@kbn/i18n'; import React, { useContext } from 'react'; import { Routes, Route } from '@kbn/shared-ux-router'; -import { useKibana, useUiSetting } from '@kbn/kibana-react-plugin/public'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; import { HeaderMenuPortal, useLinkProps } from '@kbn/observability-shared-plugin/public'; import { SharePublicStart } from '@kbn/share-plugin/public/plugin'; import { @@ -20,7 +20,6 @@ import { } from '@kbn/deeplinks-observability'; import { dynamic } from '@kbn/shared-ux-utility'; import { isDevMode } from '@kbn/xstate-utils'; -import { OBSERVABILITY_ENABLE_LOGS_STREAM } from '@kbn/management-settings-ids'; import { LazyAlertDropdownWrapper } from '../../alerting/log_threshold'; import { HelpCenterContent } from '../../components/help_center_content'; import { useReadOnlyBadge } from '../../hooks/use_readonly_badge'; @@ -29,16 +28,13 @@ import { RedirectWithQueryParams } from '../../utils/redirect_with_query_params' import { NotFoundPage } from '../404'; import { getLogsAppRoutes } from './routes'; -const StreamPage = dynamic(() => import('./stream').then((mod) => ({ default: mod.StreamPage }))); const LogEntryCategoriesPage = dynamic(() => import('./log_entry_categories').then((mod) => ({ default: mod.LogEntryCategoriesPage })) ); const LogEntryRatePage = dynamic(() => import('./log_entry_rate').then((mod) => ({ default: mod.LogEntryRatePage })) ); -const LogsSettingsPage = dynamic(() => - import('./settings').then((mod) => ({ default: mod.LogsSettingsPage })) -); + const StateMachinePlayground = dynamic(() => import('../../observability_logs/xstate_helpers').then((mod) => ({ default: mod.StateMachinePlayground, @@ -48,8 +44,6 @@ const StateMachinePlayground = dynamic(() => export const LogsPageContent: React.FunctionComponent = () => { const { application, share } = useKibana<{ share: SharePublicStart }>().services; - const isLogsStreamEnabled: boolean = useUiSetting(OBSERVABILITY_ENABLE_LOGS_STREAM, false); - const uiCapabilities = application?.capabilities; const onboardingLocator = share?.url.locators.get( OBSERVABILITY_ONBOARDING_LOCATOR @@ -60,7 +54,7 @@ export const LogsPageContent: React.FunctionComponent = () => { useReadOnlyBadge(!uiCapabilities?.logs?.save); - const routes = getLogsAppRoutes({ isLogsStreamEnabled }); + const routes = getLogsAppRoutes(); const settingsLinkProps = useLinkProps({ app: 'logs', @@ -94,34 +88,23 @@ export const LogsPageContent: React.FunctionComponent = () => { )} - {routes.stream ? ( - - ) : ( - { - share.url.locators - .get(ALL_DATASETS_LOCATOR_ID) - ?.navigate({}); - - return null; - }} - /> - )} + { + share.url.locators.get(ALL_DATASETS_LOCATOR_ID)?.navigate({}); + + return null; + }} + /> - {enableDeveloperRoutes && ( )} - + } /> diff --git a/x-pack/plugins/observability_solution/infra/public/pages/logs/routes.ts b/x-pack/plugins/observability_solution/infra/public/pages/logs/routes.ts index a5c38672a8bed..c575492a63e37 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/logs/routes.ts +++ b/x-pack/plugins/observability_solution/infra/public/pages/logs/routes.ts @@ -5,12 +5,7 @@ * 2.0. */ -import { - logsAnomaliesTitle, - logCategoriesTitle, - settingsTitle, - streamTitle, -} from '../../translations'; +import { logsAnomaliesTitle, logCategoriesTitle } from '../../translations'; export interface LogsRoute { id: string; @@ -21,11 +16,9 @@ export interface LogsRoute { export interface LogsAppRoutes { logsAnomalies: LogsRoute; logsCategories: LogsRoute; - settings: LogsRoute; - stream?: LogsRoute; } -export const getLogsAppRoutes = ({ isLogsStreamEnabled }: { isLogsStreamEnabled: boolean }) => { +export const getLogsAppRoutes = () => { const routes: LogsAppRoutes = { logsAnomalies: { id: 'anomalies', @@ -37,20 +30,7 @@ export const getLogsAppRoutes = ({ isLogsStreamEnabled }: { isLogsStreamEnabled: title: logCategoriesTitle, path: '/log-categories', }, - settings: { - id: 'settings', - title: settingsTitle, - path: '/settings', - }, }; - if (isLogsStreamEnabled) { - routes.stream = { - id: 'stream', - title: streamTitle, - path: '/stream', - }; - } - return routes; }; diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/waffle/gradient_legend.tsx b/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/waffle/gradient_legend.tsx index d17cd89eaf067..f76f1af711970 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/waffle/gradient_legend.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/waffle/gradient_legend.tsx @@ -7,6 +7,7 @@ import React from 'react'; import styled from '@emotion/styled'; +import { useEuiFontSize } from '@elastic/eui'; import { InfraFormatter, InfraWaffleMapBounds, @@ -68,7 +69,7 @@ const GradientLegendTick = styled.div` const GradientLegendTickLine = styled.div` position: absolute; - background-color: ${(props) => props.theme.euiTheme.border.color}; + background-color: ${(props) => props.theme.euiTheme.colors.backgroundBaseSubdued}; width: 1px; left: 0; top: 15px; @@ -83,7 +84,7 @@ const GradientLegendTickLine = styled.div` const GradientLegendTickLabel = styled.div` position: absolute; - font-size: 11px; + font-size: ${() => useEuiFontSize('xxs').fontSize}; text-align: center; top: 0; left: 0; diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/waffle/group_name.tsx b/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/waffle/group_name.tsx index 6b93a205f6365..eeafce9a7ae49 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/waffle/group_name.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/waffle/group_name.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { EuiLink, EuiToolTip } from '@elastic/eui'; +import { EuiLink, EuiToolTip, useEuiFontSize } from '@elastic/eui'; import React from 'react'; import styled from '@emotion/styled'; import { InfraWaffleMapGroup, InfraWaffleMapOptions } from '../../../../../common/inventory/types'; @@ -58,7 +58,7 @@ export class GroupName extends React.PureComponent { const GroupNameContainer = styled.div` position: relative; text-align: center; - font-size: 16px; + font-size: ${(props) => useEuiFontSize('m').fontSize}; margin-bottom: 5px; top: 20px; display: flex; @@ -96,6 +96,6 @@ const Count = styled.div` flex: 0 0 auto; border-left: ${(props) => props.theme.euiTheme.border.thin}; padding: 6px 10px; - font-size: 0.85em; + font-size: ${() => useEuiFontSize('xs').fontSize}; font-weight: normal; `; diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/waffle/steps_legend.tsx b/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/waffle/steps_legend.tsx index 2cdb8ca7d2e2b..2c4ab09fa82d3 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/waffle/steps_legend.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/waffle/steps_legend.tsx @@ -8,6 +8,7 @@ import { darken } from 'polished'; import React from 'react'; import styled from '@emotion/styled'; +import { useEuiFontSize } from '@elastic/eui'; import { InfraFormatter, InfraWaffleMapRuleOperator, @@ -78,5 +79,5 @@ const StepSquareInner = styled.div` `; const StepLabel = styled.div` - font-size: 12px; + font-size: ${() => useEuiFontSize('xs').fontSize}; `; diff --git a/x-pack/plugins/observability_solution/infra/public/plugin.ts b/x-pack/plugins/observability_solution/infra/public/plugin.ts index f9825915a6815..70a07b13b7c81 100644 --- a/x-pack/plugins/observability_solution/infra/public/plugin.ts +++ b/x-pack/plugins/observability_solution/infra/public/plugin.ts @@ -30,24 +30,19 @@ import { map, firstValueFrom, } from 'rxjs'; -import type { EmbeddableApiContext } from '@kbn/presentation-publishing'; -import { apiCanAddNewPanel } from '@kbn/presentation-containers'; -import { IncompatibleActionError, ADD_PANEL_TRIGGER } from '@kbn/ui-actions-plugin/public'; -import { COMMON_EMBEDDABLE_GROUPING } from '@kbn/embeddable-plugin/public'; import { ASSET_DETAILS_LOCATOR_ID, INVENTORY_LOCATOR_ID, type AssetDetailsLocatorParams, type InventoryLocatorParams, } from '@kbn/observability-shared-plugin/common'; -import { OBSERVABILITY_ENABLE_LOGS_STREAM } from '@kbn/management-settings-ids'; import { NavigationEntry } from '@kbn/observability-shared-plugin/public'; import { OBSERVABILITY_LOGS_EXPLORER_APP_ID } from '@kbn/deeplinks-observability/constants'; import type { InfraPublicConfig } from '../common/plugin_config_types'; import { createInventoryMetricRuleType } from './alerting/inventory'; import { createLogThresholdRuleType } from './alerting/log_threshold'; import { createMetricThresholdRuleType } from './alerting/metric_threshold'; -import { ADD_LOG_STREAM_ACTION_ID, LOG_STREAM_EMBEDDABLE } from './components/log_stream/constants'; +import { LOG_STREAM_EMBEDDABLE } from './components/log_stream/constants'; import { createMetricsFetchData, createMetricsHasData } from './metrics_overview_fetchers'; import { registerFeatures } from './register_feature'; import { InventoryViewsService } from './services/inventory_views'; @@ -62,7 +57,6 @@ import type { InfraClientStartExports, } from './types'; import { getLogsHasDataFetcher, getLogsOverviewDataFetcher } from './utils/logs_overview_fetchers'; -import type { LogStreamSerializedState } from './components/log_stream/types'; import { hostsTitle, inventoryTitle, @@ -94,8 +88,6 @@ export class Plugin implements InfraClientPluginClass { } setup(core: InfraClientCoreSetup, pluginsSetup: InfraClientSetupDeps) { - const isLogsStreamEnabled = core.uiSettings.get(OBSERVABILITY_ENABLE_LOGS_STREAM, false); - if (pluginsSetup.home) { registerFeatures(pluginsSetup.home); } @@ -141,7 +133,7 @@ export class Plugin implements InfraClientPluginClass { ) ); - const logRoutes = getLogsAppRoutes({ isLogsStreamEnabled }); + const logRoutes = getLogsAppRoutes(); /** !! Need to be kept in sync with the deepLinks in x-pack/plugins/observability_solution/infra/public/plugin.ts */ pluginsSetup.observabilityShared.navigation.registerSections( @@ -335,48 +327,11 @@ export class Plugin implements InfraClientPluginClass { } start(core: InfraClientCoreStart, plugins: InfraClientStartDeps) { - const { http, uiSettings } = core; - const isLogsStreamEnabled = uiSettings.get(OBSERVABILITY_ENABLE_LOGS_STREAM, false); + const { http } = core; const inventoryViews = this.inventoryViews.start({ http }); const metricsExplorerViews = this.metricsExplorerViews?.start({ http }); const telemetry = this.telemetry.start(); - if (isLogsStreamEnabled) { - plugins.uiActions.registerAction({ - id: ADD_LOG_STREAM_ACTION_ID, - grouping: [COMMON_EMBEDDABLE_GROUPING.legacy], - order: 30, - getDisplayName: () => - i18n.translate('xpack.infra.logStreamEmbeddable.displayName', { - defaultMessage: 'Log stream (deprecated)', - }), - getDisplayNameTooltip: () => - i18n.translate('xpack.infra.logStreamEmbeddable.description', { - defaultMessage: - 'Add a table of live streaming logs. For a more efficient experience, we recommend using the Discover Page to create a saved Discover session instead of using Log stream.', - }), - getIconType: () => 'logsApp', - isCompatible: async ({ embeddable }) => { - return apiCanAddNewPanel(embeddable); - }, - execute: async ({ embeddable }) => { - if (!apiCanAddNewPanel(embeddable)) throw new IncompatibleActionError(); - embeddable.addNewPanel( - { - panelType: LOG_STREAM_EMBEDDABLE, - initialState: { - title: i18n.translate('xpack.infra.logStreamEmbeddable.title', { - defaultMessage: 'Log stream', - }), - }, - }, - true - ); - }, - }); - plugins.uiActions.attachAction(ADD_PANEL_TRIGGER, ADD_LOG_STREAM_ACTION_ID); - } - const startContract: InfraClientStartExports = { inventoryViews, metricsExplorerViews, @@ -411,13 +366,9 @@ const getLogsNavigationEntries = ({ }); } - // Display Stream nav entry when Logs Stream is enabled - if (routes.stream) entries.push(createNavEntryFromRoute(routes.stream)); // Display always Logs Anomalies and Logs Categories entries entries.push(createNavEntryFromRoute(routes.logsAnomalies)); entries.push(createNavEntryFromRoute(routes.logsCategories)); - // Display Logs Settings entry when Logs Stream is not enabled - if (!routes.stream) entries.push(createNavEntryFromRoute(routes.settings)); return entries; }; diff --git a/x-pack/plugins/observability_solution/infra/server/plugin.ts b/x-pack/plugins/observability_solution/infra/server/plugin.ts index 6008954b63bde..6eac138e9fc91 100644 --- a/x-pack/plugins/observability_solution/infra/server/plugin.ts +++ b/x-pack/plugins/observability_solution/infra/server/plugin.ts @@ -52,7 +52,6 @@ import { } from './types'; import { UsageCollector } from './usage/usage_collector'; import { mapSourceToLogView } from './utils/map_source_to_log_view'; -import { uiSettings } from '../common/ui_settings'; export interface KbnServer extends Server { usage: any; @@ -134,9 +133,6 @@ export class InfraServerPlugin const inventoryViews = this.inventoryViews.setup(); const metricsExplorerViews = this.metricsExplorerViews?.setup(); - // Register uiSettings config - core.uiSettings.register(uiSettings); - // Register saved object types core.savedObjects.registerType(infraSourceConfigurationSavedObjectType); core.savedObjects.registerType(inventoryViewSavedObjectType); diff --git a/x-pack/plugins/observability_solution/infra/tsconfig.json b/x-pack/plugins/observability_solution/infra/tsconfig.json index 639780d61ae82..6ec9100ce7661 100644 --- a/x-pack/plugins/observability_solution/infra/tsconfig.json +++ b/x-pack/plugins/observability_solution/infra/tsconfig.json @@ -101,7 +101,6 @@ "@kbn/react-kibana-context-render", "@kbn/react-kibana-context-theme", "@kbn/presentation-publishing", - "@kbn/presentation-containers", "@kbn/deeplinks-observability", "@kbn/event-annotation-common", "@kbn/logs-data-access-plugin", @@ -110,8 +109,6 @@ "@kbn/core-application-browser", "@kbn/shared-ux-page-no-data-types", "@kbn/xstate-utils", - "@kbn/management-settings-ids", - "@kbn/core-ui-settings-common", "@kbn/entityManager-plugin", "@kbn/entities-schema", "@kbn/zod", diff --git a/x-pack/plugins/observability_solution/logs_shared/public/components/log_ai_assistant/log_ai_assistant.tsx b/x-pack/plugins/observability_solution/logs_shared/public/components/log_ai_assistant/log_ai_assistant.tsx index 3e1b6fced3337..6e570f5824d17 100644 --- a/x-pack/plugins/observability_solution/logs_shared/public/components/log_ai_assistant/log_ai_assistant.tsx +++ b/x-pack/plugins/observability_solution/logs_shared/public/components/log_ai_assistant/log_ai_assistant.tsx @@ -35,6 +35,12 @@ export const LogAIAssistant = ({ return undefined; } + const message = doc.fields.find((field) => field.field === 'message')?.value[0]; + + if (!message) { + return undefined; + } + return getContextualInsightMessages({ message: 'Can you explain what this log message means? Where it could be coming from, whether it is expected and whether it is an issue.', @@ -53,6 +59,10 @@ export const LogAIAssistant = ({ const message = doc.fields.find((field) => field.field === 'message')?.value[0]; + if (!message) { + return undefined; + } + return getContextualInsightMessages({ message: `I'm looking at a log entry. Can you construct a Kibana KQL query that I can enter in the search bar that gives me similar log entries, based on the message field?`, instructions: JSON.stringify({ @@ -61,7 +71,9 @@ export const LogAIAssistant = ({ }); }, [getContextualInsightMessages, doc]); - return ( + const hasAtLeastOnePrompt = Boolean(explainLogMessageMessages || similarLogMessageMessages); + + return hasAtLeastOnePrompt ? ( {ObservabilityAIAssistantContextualInsight && explainLogMessageMessages ? ( @@ -82,7 +94,7 @@ export const LogAIAssistant = ({ ) : null} - ); + ) : null; }; // eslint-disable-next-line import/no-default-export diff --git a/x-pack/plugins/observability_solution/observability_onboarding/public/application/quickstart_flows/otel_kubernetes/otel_kubernetes_panel.tsx b/x-pack/plugins/observability_solution/observability_onboarding/public/application/quickstart_flows/otel_kubernetes/otel_kubernetes_panel.tsx index 942cecb13aeeb..cf7fd341a1cab 100644 --- a/x-pack/plugins/observability_solution/observability_onboarding/public/application/quickstart_flows/otel_kubernetes/otel_kubernetes_panel.tsx +++ b/x-pack/plugins/observability_solution/observability_onboarding/public/application/quickstart_flows/otel_kubernetes/otel_kubernetes_panel.tsx @@ -18,11 +18,14 @@ import { EuiFlexGroup, EuiFlexItem, EuiButtonEmpty, + EuiAccordion, + useEuiTheme, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { FormattedMessage } from '@kbn/i18n-react'; import { DASHBOARD_APP_LOCATOR } from '@kbn/deeplinks-analytics'; +import { css } from '@emotion/react'; import { EmptyPrompt } from '../shared/empty_prompt'; import { GetStartedPanel } from '../shared/get_started_panel'; import { FeedbackButtons } from '../shared/feedback_buttons'; @@ -44,6 +47,7 @@ export const OtelKubernetesPanel: React.FC = () => { } = useKibana(); const apmLocator = share.url.locators.get('APM_LOCATOR'); const dashboardLocator = share.url.locators.get(DASHBOARD_APP_LOCATOR); + const theme = useEuiTheme(); if (error) { return ( @@ -187,7 +191,7 @@ helm install opentelemetry-kube-stack open-telemetry/opentelemetry-kube-stack \\ 'xpack.observability_onboarding.otelKubernetesPanel.theOperatorAutomatesTheLabel', { defaultMessage: - 'Enable automatic instrumentation for your applications by annotating the pods template (spec.template.metadata.annotations) in your Deployment or relevant workload object (StatefulSet, Job, CronJob, etc.)', + 'The Operator automates the injection of auto-instrumentation libraries into the annotated pods for some languages.', } )}

@@ -225,9 +229,27 @@ helm install opentelemetry-kube-stack open-telemetry/opentelemetry-kube-stack \\ ]} /> - - {`# To annotate specific deployment Pods modify its manifest -apiVersion: apps/v1 +

+ {i18n.translate( + 'xpack.observability_onboarding.otelKubernetesPanel.step3a.title', + { defaultMessage: '3(a) - Start with one of these annotations methods:' } + )} +

+ + + + {`apiVersion: apps/v1 kind: Deployment metadata: name: myapp @@ -242,24 +264,43 @@ spec: containers: - image: myapplication-image name: app - ... - -# To annotate all resources in a namespace -kubectl annotate namespace my-namespace instrumentation.opentelemetry.io/inject-${idSelected}="${namespace}/elastic-instrumentation" - -# Restart your deployment -kubectl rollout restart deployment myapp -n my-namespace + ...`} + + + + + + {`kubectl annotate namespace my-namespace instrumentation.opentelemetry.io/inject-${idSelected}="${namespace}/elastic-instrumentation"`} + + + +

+ {i18n.translate( + 'xpack.observability_onboarding.otelKubernetesPanel.step3b.title', + { + defaultMessage: + '3(b) - Restart deployment and ensure the annotations are applied and the auto-instrumentation library is injected:', + } + )} +

+ + + {`kubectl rollout restart deployment myapp -n my-namespace -# Check annotations have been applied correctly and auto-instrumentation library is injected kubectl describe pod -n my-namespace`} - -

= memo((props: NodeProps) => { style={HandleStyleOverride} /> - {label ? label : id} +