mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Logs UI] Versioning for Logs related APIs (#158710)
## 📓 Summary Closes #157324 Closes #159275 Closes #159303 This work converts the APIs related to the Logs UI feature into versioned APIs using the new [Kibana versioned router](https://docs.elastic.dev/kibana-dev-docs/versioning-http-apis#4-adhere-to-the-http-versioning-specification). The converted APIs are the following, where each endpoint now is set to version `1`: - [log_views](https://github.com/elastic/kibana/tree/main/x-pack/plugins/infra/server/routes/log_views) - [log_entries](https://github.com/elastic/kibana/tree/main/x-pack/plugins/infra/server/routes/log_entries) - [log_analysis](https://github.com/elastic/kibana/tree/main/x-pack/plugins/infra/server/routes/log_analysis) - [log_alerts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/infra/server/routes/log_alerts) The PR also includes moving the interfaces and runtime types relatives to each endpoint's group into the recommended practices for [versioning interfaces](https://docs.elastic.dev/kibana-dev-docs/versioning-interfaces). ## 🧪 Testing - Navigate to the Logs UI settings page and verify the log view is correctly retrieved and can be successfully updated. - Navigate to the Logs stream page and verify the stream entries are retrieved and rendered. - Navigate to the Anomalies and Categories pages page and verify the anomalies entries are retrieved and rendered correctly. - Create a Log threshold alert and verify the chart preview data are correctly retrieved and shown. --------- Co-authored-by: Marco Antonio Ghiani <marcoantonio.ghiani@elastic.co> Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
4f6784339f
commit
e3fddf38f7
70 changed files with 1003 additions and 860 deletions
|
@ -5,12 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
export * from './log_analysis';
|
||||
export * from './metadata_api';
|
||||
export * from './log_entries';
|
||||
export * from './metrics_explorer';
|
||||
export * from './metrics_api';
|
||||
export * from './log_alerts';
|
||||
export * from './snapshot_api';
|
||||
export * from './host_details';
|
||||
export * from './infra';
|
||||
|
@ -20,4 +17,9 @@ export * from './infra';
|
|||
*/
|
||||
export * from './latest';
|
||||
export * as inventoryViewsV1 from './inventory_views/v1';
|
||||
export * as logAlertsV1 from './log_alerts/v1';
|
||||
export * as logAnalysisResultsV1 from './log_analysis/results/v1';
|
||||
export * as logAnalysisValidationV1 from './log_analysis/validation/v1';
|
||||
export * as logEntriesV1 from './log_entries/v1';
|
||||
export * as logViewsV1 from './log_views/v1';
|
||||
export * as metricsExplorerViewsV1 from './metrics_explorer_views/v1';
|
||||
|
|
|
@ -6,4 +6,9 @@
|
|||
*/
|
||||
|
||||
export * from './inventory_views/v1';
|
||||
export * from './log_alerts/v1';
|
||||
export * from './log_analysis/results/v1';
|
||||
export * from './log_analysis/validation/v1';
|
||||
export * from './log_entries/v1';
|
||||
export * from './log_views/v1';
|
||||
export * from './metrics_explorer_views/v1';
|
||||
|
|
|
@ -12,8 +12,8 @@ import {
|
|||
timeUnitRT,
|
||||
timeSizeRT,
|
||||
groupByRT,
|
||||
} from '../../alerting/logs/log_threshold/types';
|
||||
import { persistedLogViewReferenceRT } from '../../log_views';
|
||||
} from '../../../alerting/logs/log_threshold/types';
|
||||
import { persistedLogViewReferenceRT } from '../../../log_views';
|
||||
|
||||
export const LOG_ALERTS_CHART_PREVIEW_DATA_PATH = '/api/infra/log_alerts/chart_preview_data';
|
||||
|
|
@ -7,15 +7,15 @@
|
|||
|
||||
import * as rt from 'io-ts';
|
||||
|
||||
import { persistedLogViewReferenceRT } from '../../../log_views';
|
||||
import { timeRangeRT, routeTimingMetadataRT } from '../../shared';
|
||||
import { persistedLogViewReferenceRT } from '../../../../log_views';
|
||||
import { timeRangeRT, routeTimingMetadataRT } from '../../../shared';
|
||||
import {
|
||||
logEntryAnomalyRT,
|
||||
logEntryAnomalyDatasetsRT,
|
||||
anomaliesSortRT,
|
||||
paginationRT,
|
||||
paginationCursorRT,
|
||||
} from '../../../log_analysis';
|
||||
} from '../../../../log_analysis';
|
||||
|
||||
export const LOG_ANALYSIS_GET_LOG_ENTRY_ANOMALIES_PATH =
|
||||
'/api/infra/log_analysis/results/log_entry_anomalies';
|
|
@ -6,14 +6,14 @@
|
|||
*/
|
||||
|
||||
import * as rt from 'io-ts';
|
||||
import { persistedLogViewReferenceRT } from '../../../log_views';
|
||||
import { persistedLogViewReferenceRT } from '../../../../log_views';
|
||||
|
||||
import {
|
||||
badRequestErrorRT,
|
||||
forbiddenErrorRT,
|
||||
timeRangeRT,
|
||||
routeTimingMetadataRT,
|
||||
} from '../../shared';
|
||||
} from '../../../shared';
|
||||
|
||||
export const LOG_ANALYSIS_GET_LOG_ENTRY_ANOMALIES_DATASETS_PATH =
|
||||
'/api/infra/log_analysis/results/log_entry_anomalies_datasets';
|
|
@ -7,15 +7,15 @@
|
|||
|
||||
import * as rt from 'io-ts';
|
||||
|
||||
import { persistedLogViewReferenceRT } from '../../../log_views';
|
||||
import { persistedLogViewReferenceRT } from '../../../../log_views';
|
||||
import {
|
||||
badRequestErrorRT,
|
||||
forbiddenErrorRT,
|
||||
timeRangeRT,
|
||||
routeTimingMetadataRT,
|
||||
} from '../../shared';
|
||||
} from '../../../shared';
|
||||
|
||||
import { logEntryCategoryRT, categoriesSortRT } from '../../../log_analysis';
|
||||
import { logEntryCategoryRT, categoriesSortRT } from '../../../../log_analysis';
|
||||
|
||||
export const LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORIES_PATH =
|
||||
'/api/infra/log_analysis/results/log_entry_categories';
|
|
@ -12,8 +12,8 @@ import {
|
|||
forbiddenErrorRT,
|
||||
timeRangeRT,
|
||||
routeTimingMetadataRT,
|
||||
} from '../../shared';
|
||||
import { persistedLogViewReferenceRT } from '../../../log_views';
|
||||
} from '../../../shared';
|
||||
import { persistedLogViewReferenceRT } from '../../../../log_views';
|
||||
export const LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORY_DATASETS_PATH =
|
||||
'/api/infra/log_analysis/results/log_entry_category_datasets';
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import * as rt from 'io-ts';
|
||||
|
||||
import { timeRangeRT, routeTimingMetadataRT } from '../../shared';
|
||||
import { timeRangeRT, routeTimingMetadataRT } from '../../../shared';
|
||||
|
||||
export const LOG_ANALYSIS_GET_LATEST_LOG_ENTRY_CATEGORY_DATASETS_STATS_PATH =
|
||||
'/api/infra/log_analysis/results/latest_log_entry_category_datasets_stats';
|
|
@ -7,14 +7,14 @@
|
|||
|
||||
import * as rt from 'io-ts';
|
||||
|
||||
import { persistedLogViewReferenceRT } from '../../../log_views';
|
||||
import { persistedLogViewReferenceRT } from '../../../../log_views';
|
||||
import {
|
||||
badRequestErrorRT,
|
||||
forbiddenErrorRT,
|
||||
timeRangeRT,
|
||||
routeTimingMetadataRT,
|
||||
} from '../../shared';
|
||||
import { logEntryContextRT } from '../../../log_entry';
|
||||
} from '../../../shared';
|
||||
import { logEntryContextRT } from '../../../../log_entry';
|
||||
|
||||
export const LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORY_EXAMPLES_PATH =
|
||||
'/api/infra/log_analysis/results/log_entry_category_examples';
|
|
@ -6,14 +6,14 @@
|
|||
*/
|
||||
|
||||
import * as rt from 'io-ts';
|
||||
import { persistedLogViewReferenceRT } from '../../../log_views';
|
||||
import { logEntryExampleRT } from '../../../log_analysis';
|
||||
import { persistedLogViewReferenceRT } from '../../../../log_views';
|
||||
import { logEntryExampleRT } from '../../../../log_analysis';
|
||||
import {
|
||||
badRequestErrorRT,
|
||||
forbiddenErrorRT,
|
||||
timeRangeRT,
|
||||
routeTimingMetadataRT,
|
||||
} from '../../shared';
|
||||
} from '../../../shared';
|
||||
|
||||
export const LOG_ANALYSIS_GET_LOG_ENTRY_RATE_EXAMPLES_PATH =
|
||||
'/api/infra/log_analysis/results/log_entry_examples';
|
||||
|
@ -48,7 +48,7 @@ export type GetLogEntryExamplesRequestPayload = rt.TypeOf<
|
|||
* response
|
||||
*/
|
||||
|
||||
export const getLogEntryExamplesSuccessReponsePayloadRT = rt.intersection([
|
||||
export const getLogEntryExamplesSuccessResponsePayloadRT = rt.intersection([
|
||||
rt.type({
|
||||
data: rt.type({
|
||||
examples: rt.array(logEntryExampleRT),
|
||||
|
@ -60,11 +60,11 @@ export const getLogEntryExamplesSuccessReponsePayloadRT = rt.intersection([
|
|||
]);
|
||||
|
||||
export type GetLogEntryExamplesSuccessReponsePayload = rt.TypeOf<
|
||||
typeof getLogEntryExamplesSuccessReponsePayloadRT
|
||||
typeof getLogEntryExamplesSuccessResponsePayloadRT
|
||||
>;
|
||||
|
||||
export const getLogEntryExamplesResponsePayloadRT = rt.union([
|
||||
getLogEntryExamplesSuccessReponsePayloadRT,
|
||||
getLogEntryExamplesSuccessResponsePayloadRT,
|
||||
badRequestErrorRT,
|
||||
forbiddenErrorRT,
|
||||
]);
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import * as rt from 'io-ts';
|
||||
import { mappingRuntimeFieldRT } from '../../shared/es_request';
|
||||
import { mappingRuntimeFieldRT } from '../../../shared/es_request';
|
||||
|
||||
export const LOG_ANALYSIS_VALIDATE_INDICES_PATH =
|
||||
'/api/infra/log_analysis/validation/log_entry_rate_indices';
|
|
@ -6,9 +6,9 @@
|
|||
*/
|
||||
|
||||
import * as rt from 'io-ts';
|
||||
import { logEntryCursorRT, logEntryRT } from '../../log_entry';
|
||||
import { logViewColumnConfigurationRT } from '../../log_views';
|
||||
import { logViewReferenceRT } from '../../log_views';
|
||||
import { logEntryCursorRT, logEntryRT } from '../../../log_entry';
|
||||
import { logViewColumnConfigurationRT } from '../../../log_views';
|
||||
import { logViewReferenceRT } from '../../../log_views';
|
||||
|
||||
export const LOG_ENTRIES_HIGHLIGHTS_PATH = '/api/log_entries/highlights';
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import * as rt from 'io-ts';
|
||||
import { logViewReferenceRT } from '../../log_views';
|
||||
import { logViewReferenceRT } from '../../../log_views';
|
||||
|
||||
export const LOG_ENTRIES_SUMMARY_PATH = '/api/log_entries/summary';
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import * as rt from 'io-ts';
|
||||
import { logEntryCursorRT } from '../../log_entry';
|
||||
import { logEntryCursorRT } from '../../../log_entry';
|
||||
import { logEntriesSummaryRequestRT, logEntriesSummaryBucketRT } from './summary';
|
||||
|
||||
export const LOG_ENTRIES_SUMMARY_HIGHLIGHTS_PATH = '/api/log_entries/summary_highlights';
|
|
@ -6,5 +6,3 @@
|
|||
*/
|
||||
|
||||
export { getLogViewUrl, LOG_VIEW_URL } from './common';
|
||||
export * from './get_log_view';
|
||||
export * from './put_log_view';
|
||||
|
|
|
@ -6,13 +6,15 @@
|
|||
*/
|
||||
|
||||
import * as rt from 'io-ts';
|
||||
import { logViewRT } from '../../log_views';
|
||||
import { logViewRT } from '../../../log_views';
|
||||
|
||||
export const getLogViewRequestParamsRT = rt.type({
|
||||
// the id of the log view
|
||||
logViewId: rt.string,
|
||||
});
|
||||
|
||||
export type GetLogViewRequestParams = rt.TypeOf<typeof getLogViewRequestParamsRT>;
|
||||
|
||||
export const getLogViewResponsePayloadRT = rt.type({
|
||||
data: logViewRT,
|
||||
});
|
|
@ -5,5 +5,5 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
export * from './results';
|
||||
export * from './validation';
|
||||
export * from './get_log_view';
|
||||
export * from './put_log_view';
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import * as rt from 'io-ts';
|
||||
import { logViewAttributesRT, logViewRT } from '../../log_views';
|
||||
import { logViewAttributesRT, logViewRT } from '../../../log_views';
|
||||
|
||||
export const putLogViewRequestParamsRT = rt.type({
|
||||
logViewId: rt.string,
|
||||
|
@ -15,6 +15,7 @@ export const putLogViewRequestParamsRT = rt.type({
|
|||
export const putLogViewRequestPayloadRT = rt.type({
|
||||
attributes: rt.partial(logViewAttributesRT.type.props),
|
||||
});
|
||||
|
||||
export type PutLogViewRequestPayload = rt.TypeOf<typeof putLogViewRequestPayloadRT>;
|
||||
|
||||
export const putLogViewResponsePayloadRT = rt.type({
|
|
@ -46,7 +46,7 @@ import { Color, colorTransformer } from '../../../../../common/color_palette';
|
|||
import {
|
||||
GetLogAlertsChartPreviewDataAlertParamsSubset,
|
||||
getLogAlertsChartPreviewDataAlertParamsSubsetRT,
|
||||
} from '../../../../../common/http_api/log_alerts';
|
||||
} from '../../../../../common/http_api';
|
||||
import { useChartPreviewData } from './hooks/use_chart_preview_data';
|
||||
import { decodeOrThrow } from '../../../../../common/runtime_types';
|
||||
import { useKibanaTimeZoneSetting } from '../../../../hooks/use_kibana_time_zone_setting';
|
||||
|
|
|
@ -5,21 +5,21 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { useState, useMemo } from 'react';
|
||||
import { HttpHandler } from '@kbn/core/public';
|
||||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { isRatioRule } from '../../../../../../common/alerting/logs/log_threshold';
|
||||
import { PersistedLogViewReference } from '../../../../../../common/log_views';
|
||||
import { ExecutionTimeRange } from '../../../../../types';
|
||||
import { useTrackedPromise } from '../../../../../utils/use_tracked_promise';
|
||||
import {
|
||||
GetLogAlertsChartPreviewDataAlertParamsSubset,
|
||||
getLogAlertsChartPreviewDataRequestPayloadRT,
|
||||
GetLogAlertsChartPreviewDataSuccessResponsePayload,
|
||||
getLogAlertsChartPreviewDataSuccessResponsePayloadRT,
|
||||
getLogAlertsChartPreviewDataRequestPayloadRT,
|
||||
LOG_ALERTS_CHART_PREVIEW_DATA_PATH,
|
||||
} from '../../../../../../common/http_api';
|
||||
import { PersistedLogViewReference } from '../../../../../../common/log_views';
|
||||
import { decodeOrThrow } from '../../../../../../common/runtime_types';
|
||||
import { GetLogAlertsChartPreviewDataAlertParamsSubset } from '../../../../../../common/http_api/log_alerts';
|
||||
import { ExecutionTimeRange } from '../../../../../types';
|
||||
import { useTrackedPromise } from '../../../../../utils/use_tracked_promise';
|
||||
|
||||
interface Options {
|
||||
logViewReference: PersistedLogViewReference;
|
||||
|
@ -147,6 +147,7 @@ export const callGetChartPreviewDataAPI = async (
|
|||
},
|
||||
})
|
||||
),
|
||||
version: '1',
|
||||
});
|
||||
|
||||
return decodeOrThrow(getLogAlertsChartPreviewDataSuccessResponsePayloadRT)(response);
|
||||
|
|
|
@ -21,7 +21,7 @@ import {
|
|||
ISearchOptions,
|
||||
} from '@kbn/data-plugin/public';
|
||||
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import { getLogViewResponsePayloadRT } from '../../../common/http_api/log_views';
|
||||
import { getLogViewResponsePayloadRT } from '../../../common/http_api';
|
||||
import { defaultLogViewAttributes } from '../../../common/log_views';
|
||||
import {
|
||||
LogEntriesSearchResponsePayload,
|
||||
|
|
|
@ -42,6 +42,7 @@ export const callGetLatestCategoriesDatasetsStatsAPI = async (
|
|||
},
|
||||
})
|
||||
),
|
||||
version: '1',
|
||||
});
|
||||
|
||||
return decodeOrThrow(getLatestLogEntryCategoryDatasetsStatsSuccessResponsePayloadRT)(response);
|
||||
|
|
|
@ -37,6 +37,7 @@ export const callValidateDatasetsAPI = async (requestArgs: RequestArgs, fetch: H
|
|||
},
|
||||
})
|
||||
),
|
||||
version: '1',
|
||||
});
|
||||
|
||||
return decodeOrThrow(validateLogEntryDatasetsResponsePayloadRT)(response);
|
||||
|
|
|
@ -31,6 +31,7 @@ export const callValidateIndicesAPI = async (requestArgs: RequestArgs, fetch: Ht
|
|||
// @ts-expect-error TODO: fix after elasticsearch-js bump
|
||||
validationIndicesRequestPayloadRT.encode({ data: { indices, fields, runtimeMappings } })
|
||||
),
|
||||
version: '1',
|
||||
});
|
||||
|
||||
return decodeOrThrow(validationIndicesResponsePayloadRT)(response);
|
||||
|
|
|
@ -10,7 +10,7 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
|||
import {
|
||||
ValidateLogEntryDatasetsResponsePayload,
|
||||
ValidationIndicesResponsePayload,
|
||||
} from '../../../../common/http_api/log_analysis';
|
||||
} from '../../../../common/http_api';
|
||||
import { DatasetFilter } from '../../../../common/log_analysis';
|
||||
import { DeleteJobsResponsePayload } from './api/ml_cleanup';
|
||||
import { FetchJobStatusResponsePayload } from './api/ml_get_jobs_summary_api';
|
||||
|
|
|
@ -23,6 +23,7 @@ export const fetchLogEntriesHighlights = async (
|
|||
const response = await fetch(LOG_ENTRIES_HIGHLIGHTS_PATH, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(logEntriesHighlightsRequestRT.encode(requestArgs)),
|
||||
version: '1',
|
||||
});
|
||||
|
||||
return decodeOrThrow(logEntriesHighlightsResponseRT)(response);
|
||||
|
|
|
@ -22,6 +22,7 @@ export const fetchLogSummaryHighlights = async (
|
|||
const response = await fetch(LOG_ENTRIES_SUMMARY_HIGHLIGHTS_PATH, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(logEntriesSummaryHighlightsRequestRT.encode(requestArgs)),
|
||||
version: '1',
|
||||
});
|
||||
|
||||
return decodeOrThrow(logEntriesSummaryHighlightsResponseRT)(response);
|
||||
|
|
|
@ -22,6 +22,7 @@ export const fetchLogSummary = async (
|
|||
const response = await fetch(LOG_ENTRIES_SUMMARY_PATH, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(logEntriesSummaryRequestRT.encode(requestArgs)),
|
||||
version: '1',
|
||||
});
|
||||
|
||||
return decodeOrThrow(logEntriesSummaryResponseRT)(response);
|
||||
|
|
|
@ -9,7 +9,7 @@ import { HttpHandler } from '@kbn/core/public';
|
|||
import {
|
||||
ValidateLogEntryDatasetsResponsePayload,
|
||||
ValidationIndicesResponsePayload,
|
||||
} from '../../../common/http_api/log_analysis';
|
||||
} from '../../../common/http_api';
|
||||
import { DeleteJobsResponsePayload } from './api/ml_cleanup';
|
||||
import { FetchJobStatusResponsePayload } from './api/ml_get_jobs_summary_api';
|
||||
import { GetMlModuleResponsePayload } from './api/ml_get_module';
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
getLogEntryCategoryDatasetsRequestPayloadRT,
|
||||
getLogEntryCategoryDatasetsSuccessReponsePayloadRT,
|
||||
LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORY_DATASETS_PATH,
|
||||
} from '../../../../../common/http_api/log_analysis';
|
||||
} from '../../../../../common/http_api';
|
||||
import { decodeOrThrow } from '../../../../../common/runtime_types';
|
||||
|
||||
interface RequestArgs {
|
||||
|
@ -40,6 +40,7 @@ export const callGetLogEntryCategoryDatasetsAPI = async (
|
|||
},
|
||||
})
|
||||
),
|
||||
version: '1',
|
||||
});
|
||||
|
||||
return decodeOrThrow(getLogEntryCategoryDatasetsSuccessReponsePayloadRT)(response);
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
getLogEntryCategoryExamplesRequestPayloadRT,
|
||||
getLogEntryCategoryExamplesSuccessReponsePayloadRT,
|
||||
LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORY_EXAMPLES_PATH,
|
||||
} from '../../../../../common/http_api/log_analysis';
|
||||
} from '../../../../../common/http_api';
|
||||
import { decodeOrThrow } from '../../../../../common/runtime_types';
|
||||
|
||||
interface RequestArgs {
|
||||
|
@ -44,6 +44,7 @@ export const callGetLogEntryCategoryExamplesAPI = async (
|
|||
},
|
||||
})
|
||||
),
|
||||
version: '1',
|
||||
});
|
||||
|
||||
return decodeOrThrow(getLogEntryCategoryExamplesSuccessReponsePayloadRT)(response);
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
getLogEntryCategoriesRequestPayloadRT,
|
||||
getLogEntryCategoriesSuccessReponsePayloadRT,
|
||||
LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORIES_PATH,
|
||||
} from '../../../../../common/http_api/log_analysis';
|
||||
} from '../../../../../common/http_api';
|
||||
import { CategoriesSort } from '../../../../../common/log_analysis';
|
||||
import { decodeOrThrow } from '../../../../../common/runtime_types';
|
||||
|
||||
|
@ -66,6 +66,7 @@ export const callGetTopLogEntryCategoriesAPI = async (
|
|||
},
|
||||
})
|
||||
),
|
||||
version: '1',
|
||||
});
|
||||
|
||||
return decodeOrThrow(getLogEntryCategoriesSuccessReponsePayloadRT)(response);
|
||||
|
|
|
@ -11,7 +11,7 @@ import { PersistedLogViewReference } from '../../../../common/log_views';
|
|||
import {
|
||||
GetLogEntryCategoriesSuccessResponsePayload,
|
||||
GetLogEntryCategoryDatasetsSuccessResponsePayload,
|
||||
} from '../../../../common/http_api/log_analysis';
|
||||
} from '../../../../common/http_api';
|
||||
import { CategoriesSort } from '../../../../common/log_analysis';
|
||||
import { useTrackedPromise, CanceledPromiseError } from '../../../utils/use_tracked_promise';
|
||||
import { callGetTopLogEntryCategoriesAPI } from './service_calls/get_top_log_entry_categories';
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
getLogEntryAnomaliesRequestPayloadRT,
|
||||
getLogEntryAnomaliesSuccessReponsePayloadRT,
|
||||
LOG_ANALYSIS_GET_LOG_ENTRY_ANOMALIES_PATH,
|
||||
} from '../../../../../common/http_api/log_analysis';
|
||||
} from '../../../../../common/http_api';
|
||||
import { decodeOrThrow } from '../../../../../common/runtime_types';
|
||||
import { AnomaliesSort, Pagination } from '../../../../../common/log_analysis';
|
||||
|
||||
|
@ -42,6 +42,7 @@ export const callGetLogEntryAnomaliesAPI = async (requestArgs: RequestArgs, fetc
|
|||
},
|
||||
})
|
||||
),
|
||||
version: '1',
|
||||
});
|
||||
|
||||
return decodeOrThrow(getLogEntryAnomaliesSuccessReponsePayloadRT)(response);
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
getLogEntryAnomaliesDatasetsRequestPayloadRT,
|
||||
getLogEntryAnomaliesDatasetsSuccessReponsePayloadRT,
|
||||
LOG_ANALYSIS_GET_LOG_ENTRY_ANOMALIES_DATASETS_PATH,
|
||||
} from '../../../../../common/http_api/log_analysis';
|
||||
} from '../../../../../common/http_api';
|
||||
|
||||
interface RequestArgs {
|
||||
logViewReference: PersistedLogViewReference;
|
||||
|
@ -38,6 +38,7 @@ export const callGetLogEntryAnomaliesDatasetsAPI = async (
|
|||
},
|
||||
})
|
||||
),
|
||||
version: '1',
|
||||
});
|
||||
|
||||
return decodeOrThrow(getLogEntryAnomaliesDatasetsSuccessReponsePayloadRT)(response);
|
||||
|
|
|
@ -10,9 +10,9 @@ import { PersistedLogViewReference } from '../../../../../common/log_views';
|
|||
|
||||
import {
|
||||
getLogEntryExamplesRequestPayloadRT,
|
||||
getLogEntryExamplesSuccessReponsePayloadRT,
|
||||
getLogEntryExamplesSuccessResponsePayloadRT,
|
||||
LOG_ANALYSIS_GET_LOG_ENTRY_RATE_EXAMPLES_PATH,
|
||||
} from '../../../../../common/http_api/log_analysis';
|
||||
} from '../../../../../common/http_api';
|
||||
import { decodeOrThrow } from '../../../../../common/runtime_types';
|
||||
|
||||
interface RequestArgs {
|
||||
|
@ -42,7 +42,8 @@ export const callGetLogEntryExamplesAPI = async (requestArgs: RequestArgs, fetch
|
|||
},
|
||||
})
|
||||
),
|
||||
version: '1',
|
||||
});
|
||||
|
||||
return decodeOrThrow(getLogEntryExamplesSuccessReponsePayloadRT)(response);
|
||||
return decodeOrThrow(getLogEntryExamplesSuccessResponsePayloadRT)(response);
|
||||
};
|
||||
|
|
|
@ -11,7 +11,7 @@ import { PersistedLogViewReference } from '../../../../common/log_views';
|
|||
import { useTrackedPromise, CanceledPromiseError } from '../../../utils/use_tracked_promise';
|
||||
import { callGetLogEntryAnomaliesAPI } from './service_calls/get_log_entry_anomalies';
|
||||
import { callGetLogEntryAnomaliesDatasetsAPI } from './service_calls/get_log_entry_anomalies_datasets';
|
||||
import { GetLogEntryAnomaliesDatasetsSuccessResponsePayload } from '../../../../common/http_api/log_analysis';
|
||||
import { GetLogEntryAnomaliesDatasetsSuccessResponsePayload } from '../../../../common/http_api';
|
||||
import {
|
||||
AnomaliesSort,
|
||||
Pagination,
|
||||
|
|
|
@ -10,11 +10,8 @@ import { HttpStart } from '@kbn/core/public';
|
|||
import { ISearchGeneric } from '@kbn/data-plugin/public';
|
||||
import { DataViewsContract } from '@kbn/data-views-plugin/public';
|
||||
import { lastValueFrom } from 'rxjs';
|
||||
import {
|
||||
getLogViewResponsePayloadRT,
|
||||
getLogViewUrl,
|
||||
putLogViewRequestPayloadRT,
|
||||
} from '../../../common/http_api/log_views';
|
||||
import { getLogViewResponsePayloadRT, putLogViewRequestPayloadRT } from '../../../common/http_api';
|
||||
import { getLogViewUrl } from '../../../common/http_api/log_views';
|
||||
import {
|
||||
FetchLogViewError,
|
||||
FetchLogViewStatusError,
|
||||
|
@ -48,9 +45,11 @@ export class LogViewsClient implements ILogViewsClient {
|
|||
}
|
||||
|
||||
const { logViewId } = logViewReference;
|
||||
const response = await this.http.get(getLogViewUrl(logViewId)).catch((error) => {
|
||||
throw new FetchLogViewError(`Failed to fetch log view "${logViewId}": ${error}`);
|
||||
});
|
||||
const response = await this.http
|
||||
.get(getLogViewUrl(logViewId), { version: '1' })
|
||||
.catch((error) => {
|
||||
throw new FetchLogViewError(`Failed to fetch log view "${logViewId}": ${error}`);
|
||||
});
|
||||
|
||||
const { data } = decodeOrThrow(
|
||||
getLogViewResponsePayloadRT,
|
||||
|
@ -133,6 +132,7 @@ export class LogViewsClient implements ILogViewsClient {
|
|||
body: JSON.stringify(
|
||||
putLogViewRequestPayloadRT.encode({ attributes: logViewAttributes })
|
||||
),
|
||||
version: '1',
|
||||
})
|
||||
.catch((error) => {
|
||||
throw new PutLogViewError(`Failed to write log view "${logViewId}": ${error}`);
|
||||
|
|
|
@ -24,6 +24,7 @@ import { PluginSetupContract as AlertingPluginContract } from '@kbn/alerting-plu
|
|||
import { MlPluginSetup } from '@kbn/ml-plugin/server';
|
||||
import { RuleRegistryPluginSetupContract } from '@kbn/rule-registry-plugin/server';
|
||||
import { ObservabilityPluginSetup } from '@kbn/observability-plugin/server';
|
||||
import { VersionedRouteConfig } from '@kbn/core-http-server';
|
||||
|
||||
export interface InfraServerPluginSetupDeps {
|
||||
alerting: AlertingPluginContract;
|
||||
|
@ -173,3 +174,7 @@ export interface InfraFieldDef {
|
|||
export type InfraRouteConfig<Params, Query, Body, Method extends RouteMethod> = {
|
||||
method: RouteMethod;
|
||||
} & RouteConfig<Params, Query, Body, Method>;
|
||||
|
||||
export type InfraVersionedRouteConfig<Method extends RouteMethod> = {
|
||||
method: RouteMethod;
|
||||
} & VersionedRouteConfig<Method>;
|
||||
|
|
|
@ -24,6 +24,7 @@ import {
|
|||
InfraRouteConfig,
|
||||
InfraServerPluginSetupDeps,
|
||||
InfraServerPluginStartDeps,
|
||||
InfraVersionedRouteConfig,
|
||||
} from './adapter_types';
|
||||
|
||||
interface FrozenIndexParams {
|
||||
|
@ -78,6 +79,37 @@ export class KibanaFramework {
|
|||
}
|
||||
}
|
||||
|
||||
public registerVersionedRoute<Method extends RouteMethod = any>(
|
||||
config: InfraVersionedRouteConfig<Method>
|
||||
) {
|
||||
const defaultOptions = {
|
||||
tags: ['access:infra'],
|
||||
};
|
||||
const routeConfig = {
|
||||
access: config.access,
|
||||
path: config.path,
|
||||
// Currently we have no use of custom options beyond tags, this can be extended
|
||||
// beyond defaultOptions if it's needed.
|
||||
options: defaultOptions,
|
||||
};
|
||||
switch (config.method) {
|
||||
case 'get':
|
||||
return this.router.versioned.get(routeConfig);
|
||||
case 'post':
|
||||
return this.router.versioned.post(routeConfig);
|
||||
case 'delete':
|
||||
return this.router.versioned.delete(routeConfig);
|
||||
case 'put':
|
||||
return this.router.versioned.put(routeConfig);
|
||||
case 'patch':
|
||||
return this.router.versioned.patch(routeConfig);
|
||||
default:
|
||||
throw new RangeError(
|
||||
`#registerVersionedRoute: "${config.method}" is not an accepted method`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
callWithRequest<Hit = {}, Aggregation = undefined>(
|
||||
requestContext: InfraPluginRequestHandlerContext,
|
||||
endpoint: 'search',
|
||||
|
|
|
@ -18,7 +18,7 @@ import {
|
|||
GetLogAlertsChartPreviewDataAlertParamsSubset,
|
||||
Point,
|
||||
Series,
|
||||
} from '../../../../common/http_api/log_alerts';
|
||||
} from '../../../../common/http_api';
|
||||
import { ResolvedLogView } from '../../../../common/log_views';
|
||||
import { decodeOrThrow } from '../../../../common/runtime_types';
|
||||
import type { InfraPluginRequestHandlerContext } from '../../../types';
|
||||
|
|
|
@ -6,12 +6,9 @@
|
|||
*/
|
||||
|
||||
import Boom from '@hapi/boom';
|
||||
import { logAlertsV1 } from '../../../common/http_api';
|
||||
import { InfraBackendLibs } from '../../lib/infra_types';
|
||||
import {
|
||||
LOG_ALERTS_CHART_PREVIEW_DATA_PATH,
|
||||
getLogAlertsChartPreviewDataSuccessResponsePayloadRT,
|
||||
getLogAlertsChartPreviewDataRequestPayloadRT,
|
||||
} from '../../../common/http_api/log_alerts/chart_preview_data';
|
||||
|
||||
import { createValidationFunction } from '../../../common/runtime_types';
|
||||
import { getChartPreviewData } from '../../lib/alerting/log_threshold/log_threshold_chart_preview';
|
||||
|
||||
|
@ -19,49 +16,58 @@ export const initGetLogAlertsChartPreviewDataRoute = ({
|
|||
framework,
|
||||
getStartServices,
|
||||
}: Pick<InfraBackendLibs, 'framework' | 'getStartServices'>) => {
|
||||
framework.registerRoute(
|
||||
{
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
method: 'post',
|
||||
path: LOG_ALERTS_CHART_PREVIEW_DATA_PATH,
|
||||
validate: {
|
||||
body: createValidationFunction(getLogAlertsChartPreviewDataRequestPayloadRT),
|
||||
},
|
||||
},
|
||||
framework.router.handleLegacyErrors(async (requestContext, request, response) => {
|
||||
const {
|
||||
data: { logView, buckets, alertParams, executionTimeRange },
|
||||
} = request.body;
|
||||
|
||||
const [, , { logViews }] = await getStartServices();
|
||||
const resolvedLogView = await logViews.getScopedClient(request).getResolvedLogView(logView);
|
||||
|
||||
try {
|
||||
const { series } = await getChartPreviewData(
|
||||
requestContext,
|
||||
resolvedLogView,
|
||||
framework.callWithRequest,
|
||||
alertParams,
|
||||
buckets,
|
||||
executionTimeRange
|
||||
);
|
||||
|
||||
return response.ok({
|
||||
body: getLogAlertsChartPreviewDataSuccessResponsePayloadRT.encode({
|
||||
data: { series },
|
||||
}),
|
||||
});
|
||||
} catch (error) {
|
||||
if (Boom.isBoom(error)) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return response.customError({
|
||||
statusCode: error.statusCode ?? 500,
|
||||
body: {
|
||||
message: error.message ?? 'An unexpected error occurred',
|
||||
},
|
||||
});
|
||||
}
|
||||
path: logAlertsV1.LOG_ALERTS_CHART_PREVIEW_DATA_PATH,
|
||||
})
|
||||
);
|
||||
.addVersion(
|
||||
{
|
||||
version: '1',
|
||||
validate: {
|
||||
request: {
|
||||
body: createValidationFunction(
|
||||
logAlertsV1.getLogAlertsChartPreviewDataRequestPayloadRT
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
framework.router.handleLegacyErrors(async (requestContext, request, response) => {
|
||||
const {
|
||||
data: { logView, buckets, alertParams, executionTimeRange },
|
||||
} = request.body;
|
||||
|
||||
const [, , { logViews }] = await getStartServices();
|
||||
const resolvedLogView = await logViews.getScopedClient(request).getResolvedLogView(logView);
|
||||
|
||||
try {
|
||||
const { series } = await getChartPreviewData(
|
||||
requestContext,
|
||||
resolvedLogView,
|
||||
framework.callWithRequest,
|
||||
alertParams,
|
||||
buckets,
|
||||
executionTimeRange
|
||||
);
|
||||
|
||||
return response.ok({
|
||||
body: logAlertsV1.getLogAlertsChartPreviewDataSuccessResponsePayloadRT.encode({
|
||||
data: { series },
|
||||
}),
|
||||
});
|
||||
} catch (error) {
|
||||
if (Boom.isBoom(error)) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return response.customError({
|
||||
statusCode: error.statusCode ?? 500,
|
||||
body: {
|
||||
message: error.message ?? 'An unexpected error occurred',
|
||||
},
|
||||
});
|
||||
}
|
||||
})
|
||||
);
|
||||
};
|
||||
|
|
|
@ -6,13 +6,9 @@
|
|||
*/
|
||||
|
||||
import Boom from '@hapi/boom';
|
||||
import { logAnalysisResultsV1 } from '../../../../common/http_api';
|
||||
import { InfraBackendLibs } from '../../../lib/infra_types';
|
||||
import {
|
||||
LOG_ANALYSIS_GET_LOG_ENTRY_ANOMALIES_PATH,
|
||||
getLogEntryAnomaliesSuccessReponsePayloadRT,
|
||||
getLogEntryAnomaliesRequestPayloadRT,
|
||||
GetLogEntryAnomaliesRequestPayload,
|
||||
} from '../../../../common/http_api/log_analysis';
|
||||
|
||||
import { AnomaliesSort, Pagination } from '../../../../common/log_analysis';
|
||||
import { createValidationFunction } from '../../../../common/runtime_types';
|
||||
import { assertHasInfraMlPlugins } from '../../../utils/request_context';
|
||||
|
@ -20,83 +16,94 @@ import { getLogEntryAnomalies } from '../../../lib/log_analysis';
|
|||
import { isMlPrivilegesError } from '../../../lib/log_analysis/errors';
|
||||
|
||||
export const initGetLogEntryAnomaliesRoute = ({ framework }: InfraBackendLibs) => {
|
||||
framework.registerRoute(
|
||||
{
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
method: 'post',
|
||||
path: LOG_ANALYSIS_GET_LOG_ENTRY_ANOMALIES_PATH,
|
||||
validate: {
|
||||
body: createValidationFunction(getLogEntryAnomaliesRequestPayloadRT),
|
||||
},
|
||||
},
|
||||
framework.router.handleLegacyErrors(async (requestContext, request, response) => {
|
||||
const {
|
||||
data: {
|
||||
logView,
|
||||
timeRange: { startTime, endTime },
|
||||
sort: sortParam,
|
||||
pagination: paginationParam,
|
||||
datasets,
|
||||
path: logAnalysisResultsV1.LOG_ANALYSIS_GET_LOG_ENTRY_ANOMALIES_PATH,
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: '1',
|
||||
validate: {
|
||||
request: {
|
||||
body: createValidationFunction(
|
||||
logAnalysisResultsV1.getLogEntryAnomaliesRequestPayloadRT
|
||||
),
|
||||
},
|
||||
},
|
||||
} = request.body;
|
||||
|
||||
const { sort, pagination } = getSortAndPagination(sortParam, paginationParam);
|
||||
|
||||
try {
|
||||
const infraMlContext = await assertHasInfraMlPlugins(requestContext);
|
||||
|
||||
},
|
||||
framework.router.handleLegacyErrors(async (requestContext, request, response) => {
|
||||
const {
|
||||
data: logEntryAnomalies,
|
||||
paginationCursors,
|
||||
hasMoreEntries,
|
||||
timing,
|
||||
} = await getLogEntryAnomalies(
|
||||
infraMlContext,
|
||||
logView,
|
||||
startTime,
|
||||
endTime,
|
||||
sort,
|
||||
pagination,
|
||||
datasets
|
||||
);
|
||||
data: {
|
||||
logView,
|
||||
timeRange: { startTime, endTime },
|
||||
sort: sortParam,
|
||||
pagination: paginationParam,
|
||||
datasets,
|
||||
},
|
||||
} = request.body;
|
||||
|
||||
return response.ok({
|
||||
body: getLogEntryAnomaliesSuccessReponsePayloadRT.encode({
|
||||
data: {
|
||||
anomalies: logEntryAnomalies,
|
||||
hasMoreEntries,
|
||||
paginationCursors,
|
||||
},
|
||||
const { sort, pagination } = getSortAndPagination(sortParam, paginationParam);
|
||||
|
||||
try {
|
||||
const infraMlContext = await assertHasInfraMlPlugins(requestContext);
|
||||
|
||||
const {
|
||||
data: logEntryAnomalies,
|
||||
paginationCursors,
|
||||
hasMoreEntries,
|
||||
timing,
|
||||
}),
|
||||
});
|
||||
} catch (error) {
|
||||
if (Boom.isBoom(error)) {
|
||||
throw error;
|
||||
}
|
||||
} = await getLogEntryAnomalies(
|
||||
infraMlContext,
|
||||
logView,
|
||||
startTime,
|
||||
endTime,
|
||||
sort,
|
||||
pagination,
|
||||
datasets
|
||||
);
|
||||
|
||||
return response.ok({
|
||||
body: logAnalysisResultsV1.getLogEntryAnomaliesSuccessReponsePayloadRT.encode({
|
||||
data: {
|
||||
anomalies: logEntryAnomalies,
|
||||
hasMoreEntries,
|
||||
paginationCursors,
|
||||
},
|
||||
timing,
|
||||
}),
|
||||
});
|
||||
} catch (error) {
|
||||
if (Boom.isBoom(error)) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (isMlPrivilegesError(error)) {
|
||||
return response.customError({
|
||||
statusCode: 403,
|
||||
body: {
|
||||
message: error.message,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (isMlPrivilegesError(error)) {
|
||||
return response.customError({
|
||||
statusCode: 403,
|
||||
statusCode: error.statusCode ?? 500,
|
||||
body: {
|
||||
message: error.message,
|
||||
message: error.message ?? 'An unexpected error occurred',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return response.customError({
|
||||
statusCode: error.statusCode ?? 500,
|
||||
body: {
|
||||
message: error.message ?? 'An unexpected error occurred',
|
||||
},
|
||||
});
|
||||
}
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const getSortAndPagination = (
|
||||
sort: Partial<GetLogEntryAnomaliesRequestPayload['data']['sort']> = {},
|
||||
pagination: Partial<GetLogEntryAnomaliesRequestPayload['data']['pagination']> = {}
|
||||
sort: Partial<logAnalysisResultsV1.GetLogEntryAnomaliesRequestPayload['data']['sort']> = {},
|
||||
pagination: Partial<
|
||||
logAnalysisResultsV1.GetLogEntryAnomaliesRequestPayload['data']['pagination']
|
||||
> = {}
|
||||
): {
|
||||
sort: AnomaliesSort;
|
||||
pagination: Pagination;
|
||||
|
|
|
@ -6,11 +6,8 @@
|
|||
*/
|
||||
|
||||
import Boom from '@hapi/boom';
|
||||
import {
|
||||
getLogEntryAnomaliesDatasetsRequestPayloadRT,
|
||||
getLogEntryAnomaliesDatasetsSuccessReponsePayloadRT,
|
||||
LOG_ANALYSIS_GET_LOG_ENTRY_ANOMALIES_DATASETS_PATH,
|
||||
} from '../../../../common/http_api/log_analysis';
|
||||
|
||||
import { logAnalysisResultsV1 } from '../../../../common/http_api';
|
||||
import { createValidationFunction } from '../../../../common/runtime_types';
|
||||
import type { InfraBackendLibs } from '../../../lib/infra_types';
|
||||
import { getLogEntryAnomaliesDatasets } from '../../../lib/log_analysis';
|
||||
|
@ -18,61 +15,70 @@ import { assertHasInfraMlPlugins } from '../../../utils/request_context';
|
|||
import { isMlPrivilegesError } from '../../../lib/log_analysis/errors';
|
||||
|
||||
export const initGetLogEntryAnomaliesDatasetsRoute = ({ framework }: InfraBackendLibs) => {
|
||||
framework.registerRoute(
|
||||
{
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
method: 'post',
|
||||
path: LOG_ANALYSIS_GET_LOG_ENTRY_ANOMALIES_DATASETS_PATH,
|
||||
validate: {
|
||||
body: createValidationFunction(getLogEntryAnomaliesDatasetsRequestPayloadRT),
|
||||
},
|
||||
},
|
||||
framework.router.handleLegacyErrors(async (requestContext, request, response) => {
|
||||
const {
|
||||
data: {
|
||||
logView,
|
||||
timeRange: { startTime, endTime },
|
||||
path: logAnalysisResultsV1.LOG_ANALYSIS_GET_LOG_ENTRY_ANOMALIES_DATASETS_PATH,
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: '1',
|
||||
validate: {
|
||||
request: {
|
||||
body: createValidationFunction(
|
||||
logAnalysisResultsV1.getLogEntryAnomaliesDatasetsRequestPayloadRT
|
||||
),
|
||||
},
|
||||
},
|
||||
} = request.body;
|
||||
},
|
||||
framework.router.handleLegacyErrors(async (requestContext, request, response) => {
|
||||
const {
|
||||
data: {
|
||||
logView,
|
||||
timeRange: { startTime, endTime },
|
||||
},
|
||||
} = request.body;
|
||||
|
||||
try {
|
||||
const infraMlContext = await assertHasInfraMlPlugins(requestContext);
|
||||
try {
|
||||
const infraMlContext = await assertHasInfraMlPlugins(requestContext);
|
||||
|
||||
const { datasets, timing } = await getLogEntryAnomaliesDatasets(
|
||||
{ infra: await infraMlContext.infra },
|
||||
logView,
|
||||
startTime,
|
||||
endTime
|
||||
);
|
||||
const { datasets, timing } = await getLogEntryAnomaliesDatasets(
|
||||
{ infra: await infraMlContext.infra },
|
||||
logView,
|
||||
startTime,
|
||||
endTime
|
||||
);
|
||||
|
||||
return response.ok({
|
||||
body: getLogEntryAnomaliesDatasetsSuccessReponsePayloadRT.encode({
|
||||
data: {
|
||||
datasets,
|
||||
},
|
||||
timing,
|
||||
}),
|
||||
});
|
||||
} catch (error) {
|
||||
if (Boom.isBoom(error)) {
|
||||
throw error;
|
||||
}
|
||||
return response.ok({
|
||||
body: logAnalysisResultsV1.getLogEntryAnomaliesDatasetsSuccessReponsePayloadRT.encode({
|
||||
data: {
|
||||
datasets,
|
||||
},
|
||||
timing,
|
||||
}),
|
||||
});
|
||||
} catch (error) {
|
||||
if (Boom.isBoom(error)) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (isMlPrivilegesError(error)) {
|
||||
return response.customError({
|
||||
statusCode: 403,
|
||||
body: {
|
||||
message: error.message,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (isMlPrivilegesError(error)) {
|
||||
return response.customError({
|
||||
statusCode: 403,
|
||||
statusCode: error.statusCode ?? 500,
|
||||
body: {
|
||||
message: error.message,
|
||||
message: error.message ?? 'An unexpected error occurred',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return response.customError({
|
||||
statusCode: error.statusCode ?? 500,
|
||||
body: {
|
||||
message: error.message ?? 'An unexpected error occurred',
|
||||
},
|
||||
});
|
||||
}
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
};
|
||||
|
|
|
@ -6,11 +6,8 @@
|
|||
*/
|
||||
|
||||
import Boom from '@hapi/boom';
|
||||
import {
|
||||
getLogEntryCategoriesRequestPayloadRT,
|
||||
getLogEntryCategoriesSuccessReponsePayloadRT,
|
||||
LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORIES_PATH,
|
||||
} from '../../../../common/http_api/log_analysis';
|
||||
|
||||
import { logAnalysisResultsV1 } from '../../../../common/http_api';
|
||||
import { createValidationFunction } from '../../../../common/runtime_types';
|
||||
import type { InfraBackendLibs } from '../../../lib/infra_types';
|
||||
import { getTopLogEntryCategories } from '../../../lib/log_analysis';
|
||||
|
@ -18,74 +15,83 @@ import { assertHasInfraMlPlugins } from '../../../utils/request_context';
|
|||
import { isMlPrivilegesError } from '../../../lib/log_analysis/errors';
|
||||
|
||||
export const initGetLogEntryCategoriesRoute = ({ framework }: InfraBackendLibs) => {
|
||||
framework.registerRoute(
|
||||
{
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
method: 'post',
|
||||
path: LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORIES_PATH,
|
||||
validate: {
|
||||
body: createValidationFunction(getLogEntryCategoriesRequestPayloadRT),
|
||||
},
|
||||
},
|
||||
framework.router.handleLegacyErrors(async (requestContext, request, response) => {
|
||||
const {
|
||||
data: {
|
||||
categoryCount,
|
||||
histograms,
|
||||
logView,
|
||||
timeRange: { startTime, endTime },
|
||||
datasets,
|
||||
sort,
|
||||
path: logAnalysisResultsV1.LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORIES_PATH,
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: '1',
|
||||
validate: {
|
||||
request: {
|
||||
body: createValidationFunction(
|
||||
logAnalysisResultsV1.getLogEntryCategoriesRequestPayloadRT
|
||||
),
|
||||
},
|
||||
},
|
||||
} = request.body;
|
||||
},
|
||||
framework.router.handleLegacyErrors(async (requestContext, request, response) => {
|
||||
const {
|
||||
data: {
|
||||
categoryCount,
|
||||
histograms,
|
||||
logView,
|
||||
timeRange: { startTime, endTime },
|
||||
datasets,
|
||||
sort,
|
||||
},
|
||||
} = request.body;
|
||||
|
||||
try {
|
||||
const infraMlContext = await assertHasInfraMlPlugins(requestContext);
|
||||
try {
|
||||
const infraMlContext = await assertHasInfraMlPlugins(requestContext);
|
||||
|
||||
const { data: topLogEntryCategories, timing } = await getTopLogEntryCategories(
|
||||
{ infra: await infraMlContext.infra },
|
||||
logView,
|
||||
startTime,
|
||||
endTime,
|
||||
categoryCount,
|
||||
datasets ?? [],
|
||||
histograms.map((histogram) => ({
|
||||
bucketCount: histogram.bucketCount,
|
||||
endTime: histogram.timeRange.endTime,
|
||||
id: histogram.id,
|
||||
startTime: histogram.timeRange.startTime,
|
||||
})),
|
||||
sort
|
||||
);
|
||||
const { data: topLogEntryCategories, timing } = await getTopLogEntryCategories(
|
||||
{ infra: await infraMlContext.infra },
|
||||
logView,
|
||||
startTime,
|
||||
endTime,
|
||||
categoryCount,
|
||||
datasets ?? [],
|
||||
histograms.map((histogram) => ({
|
||||
bucketCount: histogram.bucketCount,
|
||||
endTime: histogram.timeRange.endTime,
|
||||
id: histogram.id,
|
||||
startTime: histogram.timeRange.startTime,
|
||||
})),
|
||||
sort
|
||||
);
|
||||
|
||||
return response.ok({
|
||||
body: getLogEntryCategoriesSuccessReponsePayloadRT.encode({
|
||||
data: {
|
||||
categories: topLogEntryCategories,
|
||||
},
|
||||
timing,
|
||||
}),
|
||||
});
|
||||
} catch (error) {
|
||||
if (Boom.isBoom(error)) {
|
||||
throw error;
|
||||
}
|
||||
return response.ok({
|
||||
body: logAnalysisResultsV1.getLogEntryCategoriesSuccessReponsePayloadRT.encode({
|
||||
data: {
|
||||
categories: topLogEntryCategories,
|
||||
},
|
||||
timing,
|
||||
}),
|
||||
});
|
||||
} catch (error) {
|
||||
if (Boom.isBoom(error)) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (isMlPrivilegesError(error)) {
|
||||
return response.customError({
|
||||
statusCode: 403,
|
||||
body: {
|
||||
message: error.message,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (isMlPrivilegesError(error)) {
|
||||
return response.customError({
|
||||
statusCode: 403,
|
||||
statusCode: error.statusCode ?? 500,
|
||||
body: {
|
||||
message: error.message,
|
||||
message: error.message ?? 'An unexpected error occurred',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return response.customError({
|
||||
statusCode: error.statusCode ?? 500,
|
||||
body: {
|
||||
message: error.message ?? 'An unexpected error occurred',
|
||||
},
|
||||
});
|
||||
}
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
};
|
||||
|
|
|
@ -6,11 +6,8 @@
|
|||
*/
|
||||
|
||||
import Boom from '@hapi/boom';
|
||||
import {
|
||||
getLogEntryCategoryDatasetsRequestPayloadRT,
|
||||
getLogEntryCategoryDatasetsSuccessReponsePayloadRT,
|
||||
LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORY_DATASETS_PATH,
|
||||
} from '../../../../common/http_api/log_analysis';
|
||||
|
||||
import { logAnalysisResultsV1 } from '../../../../common/http_api';
|
||||
import { createValidationFunction } from '../../../../common/runtime_types';
|
||||
import type { InfraBackendLibs } from '../../../lib/infra_types';
|
||||
import { getLogEntryCategoryDatasets } from '../../../lib/log_analysis';
|
||||
|
@ -18,61 +15,70 @@ import { assertHasInfraMlPlugins } from '../../../utils/request_context';
|
|||
import { isMlPrivilegesError } from '../../../lib/log_analysis/errors';
|
||||
|
||||
export const initGetLogEntryCategoryDatasetsRoute = ({ framework }: InfraBackendLibs) => {
|
||||
framework.registerRoute(
|
||||
{
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
method: 'post',
|
||||
path: LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORY_DATASETS_PATH,
|
||||
validate: {
|
||||
body: createValidationFunction(getLogEntryCategoryDatasetsRequestPayloadRT),
|
||||
},
|
||||
},
|
||||
framework.router.handleLegacyErrors(async (requestContext, request, response) => {
|
||||
const {
|
||||
data: {
|
||||
logView,
|
||||
timeRange: { startTime, endTime },
|
||||
path: logAnalysisResultsV1.LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORY_DATASETS_PATH,
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: '1',
|
||||
validate: {
|
||||
request: {
|
||||
body: createValidationFunction(
|
||||
logAnalysisResultsV1.getLogEntryCategoryDatasetsRequestPayloadRT
|
||||
),
|
||||
},
|
||||
},
|
||||
} = request.body;
|
||||
},
|
||||
framework.router.handleLegacyErrors(async (requestContext, request, response) => {
|
||||
const {
|
||||
data: {
|
||||
logView,
|
||||
timeRange: { startTime, endTime },
|
||||
},
|
||||
} = request.body;
|
||||
|
||||
try {
|
||||
const infraMlContext = await assertHasInfraMlPlugins(requestContext);
|
||||
try {
|
||||
const infraMlContext = await assertHasInfraMlPlugins(requestContext);
|
||||
|
||||
const { data: logEntryCategoryDatasets, timing } = await getLogEntryCategoryDatasets(
|
||||
{ infra: await infraMlContext.infra },
|
||||
logView,
|
||||
startTime,
|
||||
endTime
|
||||
);
|
||||
const { data: logEntryCategoryDatasets, timing } = await getLogEntryCategoryDatasets(
|
||||
{ infra: await infraMlContext.infra },
|
||||
logView,
|
||||
startTime,
|
||||
endTime
|
||||
);
|
||||
|
||||
return response.ok({
|
||||
body: getLogEntryCategoryDatasetsSuccessReponsePayloadRT.encode({
|
||||
data: {
|
||||
datasets: logEntryCategoryDatasets,
|
||||
},
|
||||
timing,
|
||||
}),
|
||||
});
|
||||
} catch (error) {
|
||||
if (Boom.isBoom(error)) {
|
||||
throw error;
|
||||
}
|
||||
return response.ok({
|
||||
body: logAnalysisResultsV1.getLogEntryCategoryDatasetsSuccessReponsePayloadRT.encode({
|
||||
data: {
|
||||
datasets: logEntryCategoryDatasets,
|
||||
},
|
||||
timing,
|
||||
}),
|
||||
});
|
||||
} catch (error) {
|
||||
if (Boom.isBoom(error)) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (isMlPrivilegesError(error)) {
|
||||
return response.customError({
|
||||
statusCode: 403,
|
||||
body: {
|
||||
message: error.message,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (isMlPrivilegesError(error)) {
|
||||
return response.customError({
|
||||
statusCode: 403,
|
||||
statusCode: error.statusCode ?? 500,
|
||||
body: {
|
||||
message: error.message,
|
||||
message: error.message ?? 'An unexpected error occurred',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return response.customError({
|
||||
statusCode: error.statusCode ?? 500,
|
||||
body: {
|
||||
message: error.message ?? 'An unexpected error occurred',
|
||||
},
|
||||
});
|
||||
}
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
};
|
||||
|
|
|
@ -6,11 +6,8 @@
|
|||
*/
|
||||
|
||||
import Boom from '@hapi/boom';
|
||||
import {
|
||||
getLatestLogEntryCategoryDatasetsStatsRequestPayloadRT,
|
||||
getLatestLogEntryCategoryDatasetsStatsSuccessResponsePayloadRT,
|
||||
LOG_ANALYSIS_GET_LATEST_LOG_ENTRY_CATEGORY_DATASETS_STATS_PATH,
|
||||
} from '../../../../common/http_api/log_analysis';
|
||||
import { logAnalysisResultsV1 } from '../../../../common/http_api';
|
||||
|
||||
import { createValidationFunction } from '../../../../common/runtime_types';
|
||||
import type { InfraBackendLibs } from '../../../lib/infra_types';
|
||||
import { getLatestLogEntriesCategoriesDatasetsStats } from '../../../lib/log_analysis';
|
||||
|
@ -18,63 +15,74 @@ import { isMlPrivilegesError } from '../../../lib/log_analysis/errors';
|
|||
import { assertHasInfraMlPlugins } from '../../../utils/request_context';
|
||||
|
||||
export const initGetLogEntryCategoryDatasetsStatsRoute = ({ framework }: InfraBackendLibs) => {
|
||||
framework.registerRoute(
|
||||
{
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
method: 'post',
|
||||
path: LOG_ANALYSIS_GET_LATEST_LOG_ENTRY_CATEGORY_DATASETS_STATS_PATH,
|
||||
validate: {
|
||||
body: createValidationFunction(getLatestLogEntryCategoryDatasetsStatsRequestPayloadRT),
|
||||
},
|
||||
},
|
||||
framework.router.handleLegacyErrors(async (requestContext, request, response) => {
|
||||
const {
|
||||
data: {
|
||||
jobIds,
|
||||
timeRange: { startTime, endTime },
|
||||
includeCategorizerStatuses,
|
||||
path: logAnalysisResultsV1.LOG_ANALYSIS_GET_LATEST_LOG_ENTRY_CATEGORY_DATASETS_STATS_PATH,
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: '1',
|
||||
validate: {
|
||||
request: {
|
||||
body: createValidationFunction(
|
||||
logAnalysisResultsV1.getLatestLogEntryCategoryDatasetsStatsRequestPayloadRT
|
||||
),
|
||||
},
|
||||
},
|
||||
} = request.body;
|
||||
},
|
||||
framework.router.handleLegacyErrors(async (requestContext, request, response) => {
|
||||
const {
|
||||
data: {
|
||||
jobIds,
|
||||
timeRange: { startTime, endTime },
|
||||
includeCategorizerStatuses,
|
||||
},
|
||||
} = request.body;
|
||||
|
||||
try {
|
||||
const infraMlContext = await assertHasInfraMlPlugins(requestContext);
|
||||
try {
|
||||
const infraMlContext = await assertHasInfraMlPlugins(requestContext);
|
||||
|
||||
const { data: datasetStats, timing } = await getLatestLogEntriesCategoriesDatasetsStats(
|
||||
{ infra: await infraMlContext.infra },
|
||||
jobIds,
|
||||
startTime,
|
||||
endTime,
|
||||
includeCategorizerStatuses
|
||||
);
|
||||
const { data: datasetStats, timing } = await getLatestLogEntriesCategoriesDatasetsStats(
|
||||
{ infra: await infraMlContext.infra },
|
||||
jobIds,
|
||||
startTime,
|
||||
endTime,
|
||||
includeCategorizerStatuses
|
||||
);
|
||||
|
||||
return response.ok({
|
||||
body: getLatestLogEntryCategoryDatasetsStatsSuccessResponsePayloadRT.encode({
|
||||
data: {
|
||||
datasetStats,
|
||||
},
|
||||
timing,
|
||||
}),
|
||||
});
|
||||
} catch (error) {
|
||||
if (Boom.isBoom(error)) {
|
||||
throw error;
|
||||
}
|
||||
return response.ok({
|
||||
body: logAnalysisResultsV1.getLatestLogEntryCategoryDatasetsStatsSuccessResponsePayloadRT.encode(
|
||||
{
|
||||
data: {
|
||||
datasetStats,
|
||||
},
|
||||
timing,
|
||||
}
|
||||
),
|
||||
});
|
||||
} catch (error) {
|
||||
if (Boom.isBoom(error)) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (isMlPrivilegesError(error)) {
|
||||
return response.customError({
|
||||
statusCode: 403,
|
||||
body: {
|
||||
message: error.message,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (isMlPrivilegesError(error)) {
|
||||
return response.customError({
|
||||
statusCode: 403,
|
||||
statusCode: error.statusCode ?? 500,
|
||||
body: {
|
||||
message: error.message,
|
||||
message: error.message ?? 'An unexpected error occurred',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return response.customError({
|
||||
statusCode: error.statusCode ?? 500,
|
||||
body: {
|
||||
message: error.message ?? 'An unexpected error occurred',
|
||||
},
|
||||
});
|
||||
}
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
};
|
||||
|
|
|
@ -6,11 +6,8 @@
|
|||
*/
|
||||
|
||||
import Boom from '@hapi/boom';
|
||||
import {
|
||||
getLogEntryCategoryExamplesRequestPayloadRT,
|
||||
getLogEntryCategoryExamplesSuccessReponsePayloadRT,
|
||||
LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORY_EXAMPLES_PATH,
|
||||
} from '../../../../common/http_api/log_analysis';
|
||||
import { logAnalysisResultsV1 } from '../../../../common/http_api';
|
||||
|
||||
import { createValidationFunction } from '../../../../common/runtime_types';
|
||||
import type { InfraBackendLibs } from '../../../lib/infra_types';
|
||||
import { getLogEntryCategoryExamples } from '../../../lib/log_analysis';
|
||||
|
@ -21,69 +18,78 @@ export const initGetLogEntryCategoryExamplesRoute = ({
|
|||
framework,
|
||||
getStartServices,
|
||||
}: Pick<InfraBackendLibs, 'framework' | 'getStartServices'>) => {
|
||||
framework.registerRoute(
|
||||
{
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
method: 'post',
|
||||
path: LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORY_EXAMPLES_PATH,
|
||||
validate: {
|
||||
body: createValidationFunction(getLogEntryCategoryExamplesRequestPayloadRT),
|
||||
},
|
||||
},
|
||||
framework.router.handleLegacyErrors(async (requestContext, request, response) => {
|
||||
const {
|
||||
data: {
|
||||
categoryId,
|
||||
exampleCount,
|
||||
logView,
|
||||
timeRange: { startTime, endTime },
|
||||
path: logAnalysisResultsV1.LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORY_EXAMPLES_PATH,
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: '1',
|
||||
validate: {
|
||||
request: {
|
||||
body: createValidationFunction(
|
||||
logAnalysisResultsV1.getLogEntryCategoryExamplesRequestPayloadRT
|
||||
),
|
||||
},
|
||||
},
|
||||
} = request.body;
|
||||
},
|
||||
framework.router.handleLegacyErrors(async (requestContext, request, response) => {
|
||||
const {
|
||||
data: {
|
||||
categoryId,
|
||||
exampleCount,
|
||||
logView,
|
||||
timeRange: { startTime, endTime },
|
||||
},
|
||||
} = request.body;
|
||||
|
||||
const [, , { logViews }] = await getStartServices();
|
||||
const resolvedLogView = await logViews.getScopedClient(request).getResolvedLogView(logView);
|
||||
const [, , { logViews }] = await getStartServices();
|
||||
const resolvedLogView = await logViews.getScopedClient(request).getResolvedLogView(logView);
|
||||
|
||||
try {
|
||||
const infraMlContext = await assertHasInfraMlPlugins(requestContext);
|
||||
try {
|
||||
const infraMlContext = await assertHasInfraMlPlugins(requestContext);
|
||||
|
||||
const { data: logEntryCategoryExamples, timing } = await getLogEntryCategoryExamples(
|
||||
{ infra: await infraMlContext.infra, core: await infraMlContext.core },
|
||||
logView,
|
||||
startTime,
|
||||
endTime,
|
||||
categoryId,
|
||||
exampleCount,
|
||||
resolvedLogView
|
||||
);
|
||||
const { data: logEntryCategoryExamples, timing } = await getLogEntryCategoryExamples(
|
||||
{ infra: await infraMlContext.infra, core: await infraMlContext.core },
|
||||
logView,
|
||||
startTime,
|
||||
endTime,
|
||||
categoryId,
|
||||
exampleCount,
|
||||
resolvedLogView
|
||||
);
|
||||
|
||||
return response.ok({
|
||||
body: getLogEntryCategoryExamplesSuccessReponsePayloadRT.encode({
|
||||
data: {
|
||||
examples: logEntryCategoryExamples,
|
||||
},
|
||||
timing,
|
||||
}),
|
||||
});
|
||||
} catch (error) {
|
||||
if (Boom.isBoom(error)) {
|
||||
throw error;
|
||||
}
|
||||
return response.ok({
|
||||
body: logAnalysisResultsV1.getLogEntryCategoryExamplesSuccessReponsePayloadRT.encode({
|
||||
data: {
|
||||
examples: logEntryCategoryExamples,
|
||||
},
|
||||
timing,
|
||||
}),
|
||||
});
|
||||
} catch (error) {
|
||||
if (Boom.isBoom(error)) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (isMlPrivilegesError(error)) {
|
||||
return response.customError({
|
||||
statusCode: 403,
|
||||
body: {
|
||||
message: error.message,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (isMlPrivilegesError(error)) {
|
||||
return response.customError({
|
||||
statusCode: 403,
|
||||
statusCode: error.statusCode ?? 500,
|
||||
body: {
|
||||
message: error.message,
|
||||
message: error.message ?? 'An unexpected error occurred',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return response.customError({
|
||||
statusCode: error.statusCode ?? 500,
|
||||
body: {
|
||||
message: error.message ?? 'An unexpected error occurred',
|
||||
},
|
||||
});
|
||||
}
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
};
|
||||
|
|
|
@ -6,11 +6,8 @@
|
|||
*/
|
||||
|
||||
import Boom from '@hapi/boom';
|
||||
import {
|
||||
getLogEntryExamplesRequestPayloadRT,
|
||||
getLogEntryExamplesSuccessReponsePayloadRT,
|
||||
LOG_ANALYSIS_GET_LOG_ENTRY_RATE_EXAMPLES_PATH,
|
||||
} from '../../../../common/http_api/log_analysis';
|
||||
import { logAnalysisResultsV1 } from '../../../../common/http_api';
|
||||
|
||||
import { createValidationFunction } from '../../../../common/runtime_types';
|
||||
import { InfraBackendLibs } from '../../../lib/infra_types';
|
||||
import { getLogEntryExamples } from '../../../lib/log_analysis';
|
||||
|
@ -21,72 +18,81 @@ export const initGetLogEntryExamplesRoute = ({
|
|||
framework,
|
||||
getStartServices,
|
||||
}: Pick<InfraBackendLibs, 'framework' | 'getStartServices'>) => {
|
||||
framework.registerRoute(
|
||||
{
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
method: 'post',
|
||||
path: LOG_ANALYSIS_GET_LOG_ENTRY_RATE_EXAMPLES_PATH,
|
||||
validate: {
|
||||
body: createValidationFunction(getLogEntryExamplesRequestPayloadRT),
|
||||
},
|
||||
},
|
||||
framework.router.handleLegacyErrors(async (requestContext, request, response) => {
|
||||
const {
|
||||
data: {
|
||||
dataset,
|
||||
exampleCount,
|
||||
logView,
|
||||
timeRange: { startTime, endTime },
|
||||
categoryId,
|
||||
path: logAnalysisResultsV1.LOG_ANALYSIS_GET_LOG_ENTRY_RATE_EXAMPLES_PATH,
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: '1',
|
||||
validate: {
|
||||
request: {
|
||||
body: createValidationFunction(
|
||||
logAnalysisResultsV1.getLogEntryExamplesRequestPayloadRT
|
||||
),
|
||||
},
|
||||
},
|
||||
} = request.body;
|
||||
},
|
||||
framework.router.handleLegacyErrors(async (requestContext, request, response) => {
|
||||
const {
|
||||
data: {
|
||||
dataset,
|
||||
exampleCount,
|
||||
logView,
|
||||
timeRange: { startTime, endTime },
|
||||
categoryId,
|
||||
},
|
||||
} = request.body;
|
||||
|
||||
const [, , { logViews }] = await getStartServices();
|
||||
const resolvedLogView = await logViews.getScopedClient(request).getResolvedLogView(logView);
|
||||
const [, , { logViews }] = await getStartServices();
|
||||
const resolvedLogView = await logViews.getScopedClient(request).getResolvedLogView(logView);
|
||||
|
||||
try {
|
||||
const infraMlContext = await assertHasInfraMlPlugins(requestContext);
|
||||
try {
|
||||
const infraMlContext = await assertHasInfraMlPlugins(requestContext);
|
||||
|
||||
const { data: logEntryExamples, timing } = await getLogEntryExamples(
|
||||
infraMlContext,
|
||||
logView,
|
||||
startTime,
|
||||
endTime,
|
||||
dataset,
|
||||
exampleCount,
|
||||
resolvedLogView,
|
||||
framework.callWithRequest,
|
||||
categoryId
|
||||
);
|
||||
const { data: logEntryExamples, timing } = await getLogEntryExamples(
|
||||
infraMlContext,
|
||||
logView,
|
||||
startTime,
|
||||
endTime,
|
||||
dataset,
|
||||
exampleCount,
|
||||
resolvedLogView,
|
||||
framework.callWithRequest,
|
||||
categoryId
|
||||
);
|
||||
|
||||
return response.ok({
|
||||
body: getLogEntryExamplesSuccessReponsePayloadRT.encode({
|
||||
data: {
|
||||
examples: logEntryExamples,
|
||||
},
|
||||
timing,
|
||||
}),
|
||||
});
|
||||
} catch (error) {
|
||||
if (Boom.isBoom(error)) {
|
||||
throw error;
|
||||
}
|
||||
return response.ok({
|
||||
body: logAnalysisResultsV1.getLogEntryExamplesSuccessResponsePayloadRT.encode({
|
||||
data: {
|
||||
examples: logEntryExamples,
|
||||
},
|
||||
timing,
|
||||
}),
|
||||
});
|
||||
} catch (error) {
|
||||
if (Boom.isBoom(error)) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (isMlPrivilegesError(error)) {
|
||||
return response.customError({
|
||||
statusCode: 403,
|
||||
body: {
|
||||
message: error.message,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (isMlPrivilegesError(error)) {
|
||||
return response.customError({
|
||||
statusCode: 403,
|
||||
statusCode: error.statusCode ?? 500,
|
||||
body: {
|
||||
message: error.message,
|
||||
message: error.message ?? 'An unexpected error occurred',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return response.customError({
|
||||
statusCode: error.statusCode ?? 500,
|
||||
body: {
|
||||
message: error.message ?? 'An unexpected error occurred',
|
||||
},
|
||||
});
|
||||
}
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
};
|
||||
|
|
|
@ -9,65 +9,72 @@ import Boom from '@hapi/boom';
|
|||
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
|
||||
import { InfraBackendLibs } from '../../../lib/infra_types';
|
||||
import {
|
||||
LOG_ANALYSIS_VALIDATE_DATASETS_PATH,
|
||||
validateLogEntryDatasetsRequestPayloadRT,
|
||||
validateLogEntryDatasetsResponsePayloadRT,
|
||||
} from '../../../../common/http_api';
|
||||
|
||||
import { createValidationFunction } from '../../../../common/runtime_types';
|
||||
import { logAnalysisValidationV1 } from '../../../../common/http_api';
|
||||
|
||||
export const initValidateLogAnalysisDatasetsRoute = ({
|
||||
framework,
|
||||
logEntries,
|
||||
}: InfraBackendLibs) => {
|
||||
framework.registerRoute(
|
||||
{
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
method: 'post',
|
||||
path: LOG_ANALYSIS_VALIDATE_DATASETS_PATH,
|
||||
validate: {
|
||||
body: createValidationFunction(validateLogEntryDatasetsRequestPayloadRT),
|
||||
},
|
||||
},
|
||||
framework.router.handleLegacyErrors(async (requestContext, request, response) => {
|
||||
try {
|
||||
const {
|
||||
data: { indices, timestampField, startTime, endTime, runtimeMappings },
|
||||
} = request.body;
|
||||
|
||||
const datasets = await Promise.all(
|
||||
indices.map(async (indexName) => {
|
||||
const indexDatasets = await logEntries.getLogEntryDatasets(
|
||||
requestContext,
|
||||
timestampField,
|
||||
indexName,
|
||||
startTime,
|
||||
endTime,
|
||||
runtimeMappings as estypes.MappingRuntimeFields
|
||||
);
|
||||
|
||||
return {
|
||||
indexName,
|
||||
datasets: indexDatasets,
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
return response.ok({
|
||||
body: validateLogEntryDatasetsResponsePayloadRT.encode({ data: { datasets } }),
|
||||
});
|
||||
} catch (error) {
|
||||
if (Boom.isBoom(error)) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return response.customError({
|
||||
statusCode: error.statusCode ?? 500,
|
||||
body: {
|
||||
message: error.message ?? 'An unexpected error occurred',
|
||||
},
|
||||
});
|
||||
}
|
||||
path: logAnalysisValidationV1.LOG_ANALYSIS_VALIDATE_DATASETS_PATH,
|
||||
})
|
||||
);
|
||||
.addVersion(
|
||||
{
|
||||
version: '1',
|
||||
validate: {
|
||||
request: {
|
||||
body: createValidationFunction(
|
||||
logAnalysisValidationV1.validateLogEntryDatasetsRequestPayloadRT
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
framework.router.handleLegacyErrors(async (requestContext, request, response) => {
|
||||
try {
|
||||
const {
|
||||
data: { indices, timestampField, startTime, endTime, runtimeMappings },
|
||||
} = request.body;
|
||||
|
||||
const datasets = await Promise.all(
|
||||
indices.map(async (indexName) => {
|
||||
const indexDatasets = await logEntries.getLogEntryDatasets(
|
||||
requestContext,
|
||||
timestampField,
|
||||
indexName,
|
||||
startTime,
|
||||
endTime,
|
||||
runtimeMappings as estypes.MappingRuntimeFields
|
||||
);
|
||||
|
||||
return {
|
||||
indexName,
|
||||
datasets: indexDatasets,
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
return response.ok({
|
||||
body: logAnalysisValidationV1.validateLogEntryDatasetsResponsePayloadRT.encode({
|
||||
data: { datasets },
|
||||
}),
|
||||
});
|
||||
} catch (error) {
|
||||
if (Boom.isBoom(error)) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return response.customError({
|
||||
statusCode: error.statusCode ?? 500,
|
||||
body: {
|
||||
message: error.message ?? 'An unexpected error occurred',
|
||||
},
|
||||
});
|
||||
}
|
||||
})
|
||||
);
|
||||
};
|
||||
|
|
|
@ -12,83 +12,85 @@ import { fold } from 'fp-ts/lib/Either';
|
|||
import { identity } from 'fp-ts/lib/function';
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { InfraBackendLibs } from '../../../lib/infra_types';
|
||||
import {
|
||||
LOG_ANALYSIS_VALIDATE_INDICES_PATH,
|
||||
validationIndicesRequestPayloadRT,
|
||||
validationIndicesResponsePayloadRT,
|
||||
ValidationIndicesError,
|
||||
} from '../../../../common/http_api';
|
||||
|
||||
import { throwErrors } from '../../../../common/runtime_types';
|
||||
import { logAnalysisValidationV1 } from '../../../../common/http_api';
|
||||
|
||||
const escapeHatch = schema.object({}, { unknowns: 'allow' });
|
||||
|
||||
export const initValidateLogAnalysisIndicesRoute = ({ framework }: InfraBackendLibs) => {
|
||||
framework.registerRoute(
|
||||
{
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
method: 'post',
|
||||
path: LOG_ANALYSIS_VALIDATE_INDICES_PATH,
|
||||
validate: { body: escapeHatch },
|
||||
},
|
||||
async (requestContext, request, response) => {
|
||||
const payload = pipe(
|
||||
validationIndicesRequestPayloadRT.decode(request.body),
|
||||
fold(throwErrors(Boom.badRequest), identity)
|
||||
);
|
||||
path: logAnalysisValidationV1.LOG_ANALYSIS_VALIDATE_INDICES_PATH,
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: '1',
|
||||
validate: { request: { body: escapeHatch } },
|
||||
},
|
||||
async (requestContext, request, response) => {
|
||||
const payload = pipe(
|
||||
logAnalysisValidationV1.validationIndicesRequestPayloadRT.decode(request.body),
|
||||
fold(throwErrors(Boom.badRequest), identity)
|
||||
);
|
||||
|
||||
const { fields, indices, runtimeMappings } = payload.data;
|
||||
const errors: ValidationIndicesError[] = [];
|
||||
const { fields, indices, runtimeMappings } = payload.data;
|
||||
const errors: logAnalysisValidationV1.ValidationIndicesError[] = [];
|
||||
|
||||
// Query each pattern individually, to map correctly the errors
|
||||
await Promise.all(
|
||||
indices.map(async (index) => {
|
||||
const fieldCaps = await (
|
||||
await requestContext.core
|
||||
).elasticsearch.client.asCurrentUser.fieldCaps({
|
||||
allow_no_indices: true,
|
||||
fields: fields.map((field) => field.name),
|
||||
ignore_unavailable: true,
|
||||
index,
|
||||
body: {
|
||||
runtime_mappings: runtimeMappings,
|
||||
},
|
||||
});
|
||||
|
||||
if (fieldCaps.indices.length === 0) {
|
||||
errors.push({
|
||||
error: 'INDEX_NOT_FOUND',
|
||||
// Query each pattern individually, to map correctly the errors
|
||||
await Promise.all(
|
||||
indices.map(async (index) => {
|
||||
const fieldCaps = await (
|
||||
await requestContext.core
|
||||
).elasticsearch.client.asCurrentUser.fieldCaps({
|
||||
allow_no_indices: true,
|
||||
fields: fields.map((field) => field.name),
|
||||
ignore_unavailable: true,
|
||||
index,
|
||||
body: {
|
||||
runtime_mappings: runtimeMappings,
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
fields.forEach(({ name: fieldName, validTypes }) => {
|
||||
const fieldMetadata = fieldCaps.fields[fieldName];
|
||||
|
||||
if (fieldMetadata === undefined) {
|
||||
if (fieldCaps.indices.length === 0) {
|
||||
errors.push({
|
||||
error: 'FIELD_NOT_FOUND',
|
||||
error: 'INDEX_NOT_FOUND',
|
||||
index,
|
||||
field: fieldName,
|
||||
});
|
||||
} else {
|
||||
const fieldTypes = Object.keys(fieldMetadata);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fieldTypes.every((fieldType) => validTypes.includes(fieldType))) {
|
||||
fields.forEach(({ name: fieldName, validTypes }) => {
|
||||
const fieldMetadata = fieldCaps.fields[fieldName];
|
||||
|
||||
if (fieldMetadata === undefined) {
|
||||
errors.push({
|
||||
error: `FIELD_NOT_VALID`,
|
||||
error: 'FIELD_NOT_FOUND',
|
||||
index,
|
||||
field: fieldName,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
);
|
||||
} else {
|
||||
const fieldTypes = Object.keys(fieldMetadata);
|
||||
|
||||
return response.ok({
|
||||
body: validationIndicesResponsePayloadRT.encode({ data: { errors } }),
|
||||
});
|
||||
}
|
||||
);
|
||||
if (!fieldTypes.every((fieldType) => validTypes.includes(fieldType))) {
|
||||
errors.push({
|
||||
error: `FIELD_NOT_VALID`,
|
||||
index,
|
||||
field: fieldName,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
return response.ok({
|
||||
body: logAnalysisValidationV1.validationIndicesResponsePayloadRT.encode({
|
||||
data: { errors },
|
||||
}),
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
|
|
|
@ -12,90 +12,92 @@ import { fold } from 'fp-ts/lib/Either';
|
|||
import { identity } from 'fp-ts/lib/function';
|
||||
import { schema } from '@kbn/config-schema';
|
||||
|
||||
import { logEntriesV1 } from '../../../common/http_api';
|
||||
import { throwErrors } from '../../../common/runtime_types';
|
||||
|
||||
import { InfraBackendLibs } from '../../lib/infra_types';
|
||||
import {
|
||||
LOG_ENTRIES_HIGHLIGHTS_PATH,
|
||||
logEntriesHighlightsRequestRT,
|
||||
logEntriesHighlightsResponseRT,
|
||||
} from '../../../common/http_api/log_entries';
|
||||
|
||||
import { parseFilterQuery } from '../../utils/serialized_query';
|
||||
import { LogEntriesParams } from '../../lib/domains/log_entries_domain';
|
||||
|
||||
const escapeHatch = schema.object({}, { unknowns: 'allow' });
|
||||
|
||||
export const initLogEntriesHighlightsRoute = ({ framework, logEntries }: InfraBackendLibs) => {
|
||||
framework.registerRoute(
|
||||
{
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
method: 'post',
|
||||
path: LOG_ENTRIES_HIGHLIGHTS_PATH,
|
||||
validate: { body: escapeHatch },
|
||||
},
|
||||
async (requestContext, request, response) => {
|
||||
const payload = pipe(
|
||||
logEntriesHighlightsRequestRT.decode(request.body),
|
||||
fold(throwErrors(Boom.badRequest), identity)
|
||||
);
|
||||
|
||||
const { startTimestamp, endTimestamp, logView, query, size, highlightTerms } = payload;
|
||||
|
||||
let entriesPerHighlightTerm;
|
||||
|
||||
if ('center' in payload) {
|
||||
entriesPerHighlightTerm = await Promise.all(
|
||||
highlightTerms.map((highlightTerm) =>
|
||||
logEntries.getLogEntriesAround(requestContext, logView, {
|
||||
startTimestamp,
|
||||
endTimestamp,
|
||||
query: parseFilterQuery(query),
|
||||
center: payload.center,
|
||||
size,
|
||||
highlightTerm,
|
||||
})
|
||||
)
|
||||
path: logEntriesV1.LOG_ENTRIES_HIGHLIGHTS_PATH,
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: '1',
|
||||
validate: { request: { body: escapeHatch } },
|
||||
},
|
||||
async (requestContext, request, response) => {
|
||||
const payload = pipe(
|
||||
logEntriesV1.logEntriesHighlightsRequestRT.decode(request.body),
|
||||
fold(throwErrors(Boom.badRequest), identity)
|
||||
);
|
||||
} else {
|
||||
let cursor: LogEntriesParams['cursor'];
|
||||
if ('before' in payload) {
|
||||
cursor = { before: payload.before };
|
||||
} else if ('after' in payload) {
|
||||
cursor = { after: payload.after };
|
||||
|
||||
const { startTimestamp, endTimestamp, logView, query, size, highlightTerms } = payload;
|
||||
|
||||
let entriesPerHighlightTerm;
|
||||
|
||||
if ('center' in payload) {
|
||||
entriesPerHighlightTerm = await Promise.all(
|
||||
highlightTerms.map((highlightTerm) =>
|
||||
logEntries.getLogEntriesAround(requestContext, logView, {
|
||||
startTimestamp,
|
||||
endTimestamp,
|
||||
query: parseFilterQuery(query),
|
||||
center: payload.center,
|
||||
size,
|
||||
highlightTerm,
|
||||
})
|
||||
)
|
||||
);
|
||||
} else {
|
||||
let cursor: LogEntriesParams['cursor'];
|
||||
if ('before' in payload) {
|
||||
cursor = { before: payload.before };
|
||||
} else if ('after' in payload) {
|
||||
cursor = { after: payload.after };
|
||||
}
|
||||
|
||||
entriesPerHighlightTerm = await Promise.all(
|
||||
highlightTerms.map((highlightTerm) =>
|
||||
logEntries.getLogEntries(requestContext, logView, {
|
||||
startTimestamp,
|
||||
endTimestamp,
|
||||
query: parseFilterQuery(query),
|
||||
cursor,
|
||||
size,
|
||||
highlightTerm,
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
entriesPerHighlightTerm = await Promise.all(
|
||||
highlightTerms.map((highlightTerm) =>
|
||||
logEntries.getLogEntries(requestContext, logView, {
|
||||
startTimestamp,
|
||||
endTimestamp,
|
||||
query: parseFilterQuery(query),
|
||||
cursor,
|
||||
size,
|
||||
highlightTerm,
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return response.ok({
|
||||
body: logEntriesHighlightsResponseRT.encode({
|
||||
data: entriesPerHighlightTerm.map(({ entries }) => {
|
||||
if (entries.length > 0) {
|
||||
return {
|
||||
entries,
|
||||
topCursor: entries[0].cursor,
|
||||
bottomCursor: entries[entries.length - 1].cursor,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
entries,
|
||||
topCursor: null,
|
||||
bottomCursor: null,
|
||||
};
|
||||
}
|
||||
return response.ok({
|
||||
body: logEntriesV1.logEntriesHighlightsResponseRT.encode({
|
||||
data: entriesPerHighlightTerm.map(({ entries }) => {
|
||||
if (entries.length > 0) {
|
||||
return {
|
||||
entries,
|
||||
topCursor: entries[0].cursor,
|
||||
bottomCursor: entries[entries.length - 1].cursor,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
entries,
|
||||
topCursor: null,
|
||||
bottomCursor: null,
|
||||
};
|
||||
}
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
|
|
|
@ -12,53 +12,55 @@ import { fold } from 'fp-ts/lib/Either';
|
|||
import { identity } from 'fp-ts/lib/function';
|
||||
import { schema } from '@kbn/config-schema';
|
||||
|
||||
import { logEntriesV1 } from '../../../common/http_api';
|
||||
import { throwErrors } from '../../../common/runtime_types';
|
||||
|
||||
import { InfraBackendLibs } from '../../lib/infra_types';
|
||||
import {
|
||||
LOG_ENTRIES_SUMMARY_PATH,
|
||||
logEntriesSummaryRequestRT,
|
||||
logEntriesSummaryResponseRT,
|
||||
} from '../../../common/http_api/log_entries';
|
||||
|
||||
import { parseFilterQuery } from '../../utils/serialized_query';
|
||||
import { UsageCollector } from '../../usage/usage_collector';
|
||||
|
||||
const escapeHatch = schema.object({}, { unknowns: 'allow' });
|
||||
|
||||
export const initLogEntriesSummaryRoute = ({ framework, logEntries }: InfraBackendLibs) => {
|
||||
framework.registerRoute(
|
||||
{
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
method: 'post',
|
||||
path: LOG_ENTRIES_SUMMARY_PATH,
|
||||
validate: { body: escapeHatch },
|
||||
},
|
||||
async (requestContext, request, response) => {
|
||||
const payload = pipe(
|
||||
logEntriesSummaryRequestRT.decode(request.body),
|
||||
fold(throwErrors(Boom.badRequest), identity)
|
||||
);
|
||||
const { logView, startTimestamp, endTimestamp, bucketSize, query } = payload;
|
||||
path: logEntriesV1.LOG_ENTRIES_SUMMARY_PATH,
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: '1',
|
||||
validate: { request: { body: escapeHatch } },
|
||||
},
|
||||
async (requestContext, request, response) => {
|
||||
const payload = pipe(
|
||||
logEntriesV1.logEntriesSummaryRequestRT.decode(request.body),
|
||||
fold(throwErrors(Boom.badRequest), identity)
|
||||
);
|
||||
const { logView, startTimestamp, endTimestamp, bucketSize, query } = payload;
|
||||
|
||||
const buckets = await logEntries.getLogSummaryBucketsBetween(
|
||||
requestContext,
|
||||
logView,
|
||||
startTimestamp,
|
||||
endTimestamp,
|
||||
bucketSize,
|
||||
parseFilterQuery(query)
|
||||
);
|
||||
const buckets = await logEntries.getLogSummaryBucketsBetween(
|
||||
requestContext,
|
||||
logView,
|
||||
startTimestamp,
|
||||
endTimestamp,
|
||||
bucketSize,
|
||||
parseFilterQuery(query)
|
||||
);
|
||||
|
||||
UsageCollector.countLogs();
|
||||
UsageCollector.countLogs();
|
||||
|
||||
return response.ok({
|
||||
body: logEntriesSummaryResponseRT.encode({
|
||||
data: {
|
||||
start: startTimestamp,
|
||||
end: endTimestamp,
|
||||
buckets,
|
||||
},
|
||||
}),
|
||||
});
|
||||
}
|
||||
);
|
||||
return response.ok({
|
||||
body: logEntriesV1.logEntriesSummaryResponseRT.encode({
|
||||
data: {
|
||||
start: startTimestamp,
|
||||
end: endTimestamp,
|
||||
buckets,
|
||||
},
|
||||
}),
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
|
|
|
@ -12,14 +12,11 @@ import { fold } from 'fp-ts/lib/Either';
|
|||
import { identity } from 'fp-ts/lib/function';
|
||||
import { schema } from '@kbn/config-schema';
|
||||
|
||||
import { logEntriesV1 } from '../../../common/http_api';
|
||||
import { throwErrors } from '../../../common/runtime_types';
|
||||
|
||||
import { InfraBackendLibs } from '../../lib/infra_types';
|
||||
import {
|
||||
LOG_ENTRIES_SUMMARY_HIGHLIGHTS_PATH,
|
||||
logEntriesSummaryHighlightsRequestRT,
|
||||
logEntriesSummaryHighlightsResponseRT,
|
||||
} from '../../../common/http_api/log_entries';
|
||||
|
||||
import { parseFilterQuery } from '../../utils/serialized_query';
|
||||
|
||||
const escapeHatch = schema.object({}, { unknowns: 'allow' });
|
||||
|
@ -28,38 +25,44 @@ export const initLogEntriesSummaryHighlightsRoute = ({
|
|||
framework,
|
||||
logEntries,
|
||||
}: InfraBackendLibs) => {
|
||||
framework.registerRoute(
|
||||
{
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
method: 'post',
|
||||
path: LOG_ENTRIES_SUMMARY_HIGHLIGHTS_PATH,
|
||||
validate: { body: escapeHatch },
|
||||
},
|
||||
async (requestContext, request, response) => {
|
||||
const payload = pipe(
|
||||
logEntriesSummaryHighlightsRequestRT.decode(request.body),
|
||||
fold(throwErrors(Boom.badRequest), identity)
|
||||
);
|
||||
const { logView, startTimestamp, endTimestamp, bucketSize, query, highlightTerms } = payload;
|
||||
path: logEntriesV1.LOG_ENTRIES_SUMMARY_HIGHLIGHTS_PATH,
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: '1',
|
||||
validate: { request: { body: escapeHatch } },
|
||||
},
|
||||
async (requestContext, request, response) => {
|
||||
const payload = pipe(
|
||||
logEntriesV1.logEntriesSummaryHighlightsRequestRT.decode(request.body),
|
||||
fold(throwErrors(Boom.badRequest), identity)
|
||||
);
|
||||
const { logView, startTimestamp, endTimestamp, bucketSize, query, highlightTerms } =
|
||||
payload;
|
||||
|
||||
const bucketsPerHighlightTerm = await logEntries.getLogSummaryHighlightBucketsBetween(
|
||||
requestContext,
|
||||
logView,
|
||||
startTimestamp,
|
||||
endTimestamp,
|
||||
bucketSize,
|
||||
highlightTerms,
|
||||
parseFilterQuery(query)
|
||||
);
|
||||
const bucketsPerHighlightTerm = await logEntries.getLogSummaryHighlightBucketsBetween(
|
||||
requestContext,
|
||||
logView,
|
||||
startTimestamp,
|
||||
endTimestamp,
|
||||
bucketSize,
|
||||
highlightTerms,
|
||||
parseFilterQuery(query)
|
||||
);
|
||||
|
||||
return response.ok({
|
||||
body: logEntriesSummaryHighlightsResponseRT.encode({
|
||||
data: bucketsPerHighlightTerm.map((buckets) => ({
|
||||
start: startTimestamp,
|
||||
end: endTimestamp,
|
||||
buckets,
|
||||
})),
|
||||
}),
|
||||
});
|
||||
}
|
||||
);
|
||||
return response.ok({
|
||||
body: logEntriesV1.logEntriesSummaryHighlightsResponseRT.encode({
|
||||
data: bucketsPerHighlightTerm.map((buckets) => ({
|
||||
start: startTimestamp,
|
||||
end: endTimestamp,
|
||||
buckets,
|
||||
})),
|
||||
}),
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
|
|
|
@ -5,11 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
getLogViewRequestParamsRT,
|
||||
getLogViewResponsePayloadRT,
|
||||
LOG_VIEW_URL,
|
||||
} from '../../../common/http_api/log_views';
|
||||
import { logViewsV1 } from '../../../common/http_api';
|
||||
import { LOG_VIEW_URL } from '../../../common/http_api/log_views';
|
||||
import { createValidationFunction } from '../../../common/runtime_types';
|
||||
import type { KibanaFramework } from '../../lib/adapters/framework/kibana_framework_adapter';
|
||||
import type { InfraPluginStartServicesAccessor } from '../../types';
|
||||
|
@ -21,35 +18,42 @@ export const initGetLogViewRoute = ({
|
|||
framework: KibanaFramework;
|
||||
getStartServices: InfraPluginStartServicesAccessor;
|
||||
}) => {
|
||||
framework.registerRoute(
|
||||
{
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
method: 'get',
|
||||
path: LOG_VIEW_URL,
|
||||
validate: {
|
||||
params: createValidationFunction(getLogViewRequestParamsRT),
|
||||
},
|
||||
},
|
||||
async (_requestContext, request, response) => {
|
||||
const { logViewId } = request.params;
|
||||
const { logViews } = (await getStartServices())[2];
|
||||
const logViewsClient = logViews.getScopedClient(request);
|
||||
|
||||
try {
|
||||
const logView = await logViewsClient.getLogView(logViewId);
|
||||
|
||||
return response.ok({
|
||||
body: getLogViewResponsePayloadRT.encode({
|
||||
data: logView,
|
||||
}),
|
||||
});
|
||||
} catch (error) {
|
||||
return response.customError({
|
||||
statusCode: error.statusCode ?? 500,
|
||||
body: {
|
||||
message: error.message ?? 'An unexpected error occurred',
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: '1',
|
||||
validate: {
|
||||
request: {
|
||||
params: createValidationFunction(logViewsV1.getLogViewRequestParamsRT),
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
async (_requestContext, request, response) => {
|
||||
const { logViewId } = request.params;
|
||||
const { logViews } = (await getStartServices())[2];
|
||||
const logViewsClient = logViews.getScopedClient(request);
|
||||
|
||||
try {
|
||||
const logView = await logViewsClient.getLogView(logViewId);
|
||||
|
||||
return response.ok({
|
||||
body: logViewsV1.getLogViewResponsePayloadRT.encode({
|
||||
data: logView,
|
||||
}),
|
||||
});
|
||||
} catch (error) {
|
||||
return response.customError({
|
||||
statusCode: error.statusCode ?? 500,
|
||||
body: {
|
||||
message: error.message ?? 'An unexpected error occurred',
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
);
|
||||
};
|
||||
|
|
|
@ -5,12 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
LOG_VIEW_URL,
|
||||
putLogViewRequestParamsRT,
|
||||
putLogViewRequestPayloadRT,
|
||||
putLogViewResponsePayloadRT,
|
||||
} from '../../../common/http_api/log_views';
|
||||
import { logViewsV1 } from '../../../common/http_api';
|
||||
import { LOG_VIEW_URL } from '../../../common/http_api/log_views';
|
||||
import { createValidationFunction } from '../../../common/runtime_types';
|
||||
import type { KibanaFramework } from '../../lib/adapters/framework/kibana_framework_adapter';
|
||||
import type { InfraPluginStartServicesAccessor } from '../../types';
|
||||
|
@ -22,37 +18,44 @@ export const initPutLogViewRoute = ({
|
|||
framework: KibanaFramework;
|
||||
getStartServices: InfraPluginStartServicesAccessor;
|
||||
}) => {
|
||||
framework.registerRoute(
|
||||
{
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
method: 'put',
|
||||
path: LOG_VIEW_URL,
|
||||
validate: {
|
||||
params: createValidationFunction(putLogViewRequestParamsRT),
|
||||
body: createValidationFunction(putLogViewRequestPayloadRT),
|
||||
},
|
||||
},
|
||||
async (_requestContext, request, response) => {
|
||||
const { logViewId } = request.params;
|
||||
const { attributes } = request.body;
|
||||
const { logViews } = (await getStartServices())[2];
|
||||
const logViewsClient = logViews.getScopedClient(request);
|
||||
|
||||
try {
|
||||
const logView = await logViewsClient.putLogView(logViewId, attributes);
|
||||
|
||||
return response.ok({
|
||||
body: putLogViewResponsePayloadRT.encode({
|
||||
data: logView,
|
||||
}),
|
||||
});
|
||||
} catch (error) {
|
||||
return response.customError({
|
||||
statusCode: error.statusCode ?? 500,
|
||||
body: {
|
||||
message: error.message ?? 'An unexpected error occurred',
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: '1',
|
||||
validate: {
|
||||
request: {
|
||||
params: createValidationFunction(logViewsV1.putLogViewRequestParamsRT),
|
||||
body: createValidationFunction(logViewsV1.putLogViewRequestPayloadRT),
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
async (_requestContext, request, response) => {
|
||||
const { logViewId } = request.params;
|
||||
const { attributes } = request.body;
|
||||
const { logViews } = (await getStartServices())[2];
|
||||
const logViewsClient = logViews.getScopedClient(request);
|
||||
|
||||
try {
|
||||
const logView = await logViewsClient.putLogView(logViewId, attributes);
|
||||
|
||||
return response.ok({
|
||||
body: logViewsV1.putLogViewResponsePayloadRT.encode({
|
||||
data: logView,
|
||||
}),
|
||||
});
|
||||
} catch (error) {
|
||||
return response.customError({
|
||||
statusCode: error.statusCode ?? 500,
|
||||
body: {
|
||||
message: error.message ?? 'An unexpected error occurred',
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
);
|
||||
};
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
"@kbn/observability-shared-plugin",
|
||||
"@kbn/ui-theme",
|
||||
"@kbn/ml-anomaly-utils",
|
||||
"@kbn/core-http-server",
|
||||
],
|
||||
"exclude": ["target/**/*"]
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
LOG_ANALYSIS_VALIDATE_DATASETS_PATH,
|
||||
validateLogEntryDatasetsRequestPayloadRT,
|
||||
validateLogEntryDatasetsResponsePayloadRT,
|
||||
} from '@kbn/infra-plugin/common/http_api/log_analysis/validation/datasets';
|
||||
} from '@kbn/infra-plugin/common/http_api';
|
||||
import { decodeOrThrow } from '@kbn/infra-plugin/common/runtime_types';
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
|
@ -31,6 +31,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
.post(LOG_ANALYSIS_VALIDATE_DATASETS_PATH)
|
||||
.set({
|
||||
'kbn-xsrf': 'some-xsrf-token',
|
||||
'Elastic-Api-Version': '1',
|
||||
})
|
||||
.send(
|
||||
validateLogEntryDatasetsRequestPayloadRT.encode({
|
||||
|
|
|
@ -32,6 +32,7 @@ const KEY_AFTER_END = {
|
|||
|
||||
const COMMON_HEADERS = {
|
||||
'kbn-xsrf': 'some-xsrf-token',
|
||||
'Elastic-Api-Version': '1',
|
||||
};
|
||||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
|
|
|
@ -19,7 +19,7 @@ import {
|
|||
LOG_ENTRIES_SUMMARY_PATH,
|
||||
logEntriesSummaryRequestRT,
|
||||
logEntriesSummaryResponseRT,
|
||||
} from '@kbn/infra-plugin/common/http_api/log_entries';
|
||||
} from '@kbn/infra-plugin/common/http_api';
|
||||
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
|
@ -28,6 +28,7 @@ const LATEST_TIME_WITH_DATA = new Date('2018-10-17T19:57:21.611Z').valueOf();
|
|||
|
||||
const COMMON_HEADERS = {
|
||||
'kbn-xsrf': 'some-xsrf-token',
|
||||
'Elastic-Api-Version': '1',
|
||||
};
|
||||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
|
||||
import {
|
||||
getLogViewResponsePayloadRT,
|
||||
getLogViewUrl,
|
||||
PutLogViewRequestPayload,
|
||||
putLogViewRequestPayloadRT,
|
||||
putLogViewResponsePayloadRT,
|
||||
} from '@kbn/infra-plugin/common/http_api/log_views';
|
||||
} from '@kbn/infra-plugin/common/http_api';
|
||||
import { getLogViewUrl } from '@kbn/infra-plugin/common/http_api/log_views';
|
||||
import { decodeOrThrow } from '@kbn/infra-plugin/common/runtime_types';
|
||||
import { FtrProviderContext } from '../ftr_provider_context';
|
||||
|
||||
|
@ -24,6 +24,7 @@ export function InfraLogViewsServiceProvider({ getService }: FtrProviderContext)
|
|||
.get(getLogViewUrl(logViewId))
|
||||
.set({
|
||||
'kbn-xsrf': 'some-xsrf-token',
|
||||
'Elastic-Api-Version': '1',
|
||||
})
|
||||
.send();
|
||||
|
||||
|
@ -40,6 +41,7 @@ export function InfraLogViewsServiceProvider({ getService }: FtrProviderContext)
|
|||
.put(getLogViewUrl(logViewId))
|
||||
.set({
|
||||
'kbn-xsrf': 'some-xsrf-token',
|
||||
'Elastic-Api-Version': '1',
|
||||
})
|
||||
.send(putLogViewRequestPayloadRT.encode(payload));
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ const timepickerFormat = 'MMM D, YYYY @ HH:mm:ss.SSS';
|
|||
const tableEntries = [
|
||||
{
|
||||
title: 'demo-stack-apache-01',
|
||||
os: '-',
|
||||
cpuUsage: '1.2%',
|
||||
diskLatency: '1.6 ms',
|
||||
rx: '0 bit/s',
|
||||
|
@ -33,7 +32,6 @@ const tableEntries = [
|
|||
},
|
||||
{
|
||||
title: 'demo-stack-client-01',
|
||||
os: '-',
|
||||
cpuUsage: '0.5%',
|
||||
diskLatency: '8.7 ms',
|
||||
rx: '0 bit/s',
|
||||
|
@ -43,7 +41,6 @@ const tableEntries = [
|
|||
},
|
||||
{
|
||||
title: 'demo-stack-haproxy-01',
|
||||
os: '-',
|
||||
cpuUsage: '0.8%',
|
||||
diskLatency: '7 ms',
|
||||
rx: '0 bit/s',
|
||||
|
@ -53,7 +50,6 @@ const tableEntries = [
|
|||
},
|
||||
{
|
||||
title: 'demo-stack-mysql-01',
|
||||
os: '-',
|
||||
cpuUsage: '0.9%',
|
||||
diskLatency: '6.6 ms',
|
||||
rx: '0 bit/s',
|
||||
|
@ -63,7 +59,6 @@ const tableEntries = [
|
|||
},
|
||||
{
|
||||
title: 'demo-stack-nginx-01',
|
||||
os: '-',
|
||||
cpuUsage: '0.8%',
|
||||
diskLatency: '5.7 ms',
|
||||
rx: '0 bit/s',
|
||||
|
@ -73,7 +68,6 @@ const tableEntries = [
|
|||
},
|
||||
{
|
||||
title: 'demo-stack-redis-01',
|
||||
os: '-',
|
||||
cpuUsage: '0.8%',
|
||||
diskLatency: '6.3 ms',
|
||||
rx: '0 bit/s',
|
||||
|
|
|
@ -90,11 +90,11 @@ export function InfraHostsViewProvider({ getService }: FtrProviderContext) {
|
|||
const cells = await row.findAllByCssSelector('[data-test-subj*="hostsView-tableRow-"]');
|
||||
|
||||
// Retrieve content for each cell
|
||||
const [title, os, cpuUsage, diskLatency, rx, tx, memoryTotal, memory] = await Promise.all(
|
||||
const [title, cpuUsage, diskLatency, rx, tx, memoryTotal, memory] = await Promise.all(
|
||||
cells.map((cell) => this.getHostsCellContent(cell))
|
||||
);
|
||||
|
||||
return { title, os, cpuUsage, diskLatency, rx, tx, memoryTotal, memory };
|
||||
return { title, cpuUsage, diskLatency, rx, tx, memoryTotal, memory };
|
||||
},
|
||||
|
||||
async getHostsCellContent(cell: WebElementWrapper) {
|
||||
|
@ -285,7 +285,7 @@ export function InfraHostsViewProvider({ getService }: FtrProviderContext) {
|
|||
|
||||
// Sorting
|
||||
getDiskLatencyHeader() {
|
||||
return testSubjects.find('tableHeaderCell_diskLatency_4');
|
||||
return testSubjects.find('tableHeaderCell_diskLatency_3');
|
||||
},
|
||||
|
||||
getTitleHeader() {
|
||||
|
|
|
@ -6,7 +6,10 @@
|
|||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
import { GET_TOTAL_IO_BYTES_ROUTE } from '@kbn/session-view-plugin/common/constants';
|
||||
import {
|
||||
CURRENT_API_VERSION,
|
||||
GET_TOTAL_IO_BYTES_ROUTE,
|
||||
} from '@kbn/session-view-plugin/common/constants';
|
||||
import { FtrProviderContext } from '../../common/ftr_provider_context';
|
||||
|
||||
const MOCK_INDEX = 'logs-endpoint.events.process*';
|
||||
|
@ -20,6 +23,13 @@ export default function getTotalIOBytesTests({ getService }: FtrProviderContext)
|
|||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
|
||||
function getTestRoute() {
|
||||
return supertest
|
||||
.get(GET_TOTAL_IO_BYTES_ROUTE)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.set('Elastic-Api-Version', CURRENT_API_VERSION);
|
||||
}
|
||||
|
||||
describe(`Session view - ${GET_TOTAL_IO_BYTES_ROUTE} - with a basic license`, () => {
|
||||
before(async () => {
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/session_view/process_events');
|
||||
|
@ -32,7 +42,7 @@ export default function getTotalIOBytesTests({ getService }: FtrProviderContext)
|
|||
});
|
||||
|
||||
it(`${GET_TOTAL_IO_BYTES_ROUTE} returns a page of IO events`, async () => {
|
||||
const response = await supertest.get(GET_TOTAL_IO_BYTES_ROUTE).set('kbn-xsrf', 'foo').query({
|
||||
const response = await getTestRoute().query({
|
||||
index: MOCK_INDEX,
|
||||
sessionEntityId: MOCK_SESSION_ENTITY_ID,
|
||||
sessionStartTime: MOCK_SESSION_START_TIME,
|
||||
|
@ -42,7 +52,7 @@ export default function getTotalIOBytesTests({ getService }: FtrProviderContext)
|
|||
});
|
||||
|
||||
it(`${GET_TOTAL_IO_BYTES_ROUTE} returns 0 for invalid query`, async () => {
|
||||
const response = await supertest.get(GET_TOTAL_IO_BYTES_ROUTE).set('kbn-xsrf', 'foo').query({
|
||||
const response = await getTestRoute().query({
|
||||
index: MOCK_INDEX,
|
||||
sessionStartTime: MOCK_SESSION_START_TIME,
|
||||
sessionEntityId: 'xyz',
|
||||
|
|
|
@ -54,8 +54,7 @@ export default function processEventsTests({ getService }: FtrProviderContext) {
|
|||
.set('Elastic-Api-Version', CURRENT_API_VERSION);
|
||||
}
|
||||
|
||||
// Failing: See https://github.com/elastic/kibana/issues/159275
|
||||
describe.skip(`Session view - ${PROCESS_EVENTS_ROUTE} - with a basic license`, () => {
|
||||
describe(`Session view - ${PROCESS_EVENTS_ROUTE} - with a basic license`, () => {
|
||||
describe(`using typical process event data`, () => {
|
||||
before(async () => {
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/session_view/process_events');
|
||||
|
@ -144,6 +143,7 @@ export default function processEventsTests({ getService }: FtrProviderContext) {
|
|||
.get(`${PROCESS_EVENTS_ROUTE}`)
|
||||
.auth(username, password)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set('Elastic-Api-Version', CURRENT_API_VERSION)
|
||||
.query({
|
||||
index: MOCK_INDEX,
|
||||
sessionEntityId: MOCK_SESSION_ENTITY_ID,
|
||||
|
@ -167,6 +167,7 @@ export default function processEventsTests({ getService }: FtrProviderContext) {
|
|||
.get(`${PROCESS_EVENTS_ROUTE}`)
|
||||
.auth(username, password)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set('Elastic-Api-Version', CURRENT_API_VERSION)
|
||||
.query({
|
||||
index: MOCK_INDEX,
|
||||
sessionEntityId: MOCK_SESSION_ENTITY_ID,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue