mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[ML][AIOps] Telemetry: track analysis endpoint usage (#166988)
## Summary This PR adds tracking for Log Rate Analysis and Log Pattern Analysis endpoints for AIOps. - tracks type of analysis and source (where the analysis is being run from) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
7dd352a65e
commit
0bdbcc0ccc
23 changed files with 153 additions and 21 deletions
|
@ -27,7 +27,7 @@ export interface VisualizeFieldContext {
|
|||
export interface CategorizeFieldContext {
|
||||
field: DataViewField;
|
||||
dataView: DataView;
|
||||
originatingApp?: string;
|
||||
originatingApp: string;
|
||||
}
|
||||
|
||||
export const ACTION_VISUALIZE_FIELD = 'ACTION_VISUALIZE_FIELD';
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import startsWith from 'lodash/startsWith';
|
||||
import type { Reducer, ReducerAction } from 'react';
|
||||
|
||||
import type { HttpSetup } from '@kbn/core/public';
|
||||
import type { HttpSetup, HttpFetchOptions } from '@kbn/core/public';
|
||||
|
||||
type GeneratorError = string | null;
|
||||
|
||||
|
@ -42,7 +42,8 @@ export async function* fetchStream<B extends object, R extends Reducer<any, any>
|
|||
apiVersion: string | undefined,
|
||||
abortCtrl: React.MutableRefObject<AbortController>,
|
||||
body?: B,
|
||||
ndjson = true
|
||||
ndjson = true,
|
||||
headers?: HttpFetchOptions['headers']
|
||||
): AsyncGenerator<[GeneratorError, ReducerAction<R> | Array<ReducerAction<R>> | undefined]> {
|
||||
let stream: Readonly<Response> | undefined;
|
||||
|
||||
|
@ -52,6 +53,7 @@ export async function* fetchStream<B extends object, R extends Reducer<any, any>
|
|||
version: apiVersion,
|
||||
asResponse: true,
|
||||
rawResponse: true,
|
||||
headers,
|
||||
...(body && Object.keys(body).length > 0 ? { body: JSON.stringify(body) } : {}),
|
||||
});
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ import {
|
|||
} from 'react';
|
||||
import useThrottle from 'react-use/lib/useThrottle';
|
||||
|
||||
import type { HttpSetup } from '@kbn/core/public';
|
||||
import type { HttpSetup, HttpFetchOptions } from '@kbn/core/public';
|
||||
import { isPopulatedObject } from '@kbn/ml-is-populated-object';
|
||||
|
||||
import { fetchStream } from './fetch_stream';
|
||||
|
@ -64,7 +64,8 @@ export function useFetchStream<B extends object, R extends Reducer<any, any>>(
|
|||
endpoint: string,
|
||||
apiVersion?: string,
|
||||
body?: B,
|
||||
customReducer?: FetchStreamCustomReducer<R>
|
||||
customReducer?: FetchStreamCustomReducer<R>,
|
||||
headers?: HttpFetchOptions['headers']
|
||||
) {
|
||||
const [errors, setErrors] = useState<string[]>([]);
|
||||
const [isCancelled, setIsCancelled] = useState(false);
|
||||
|
@ -104,7 +105,8 @@ export function useFetchStream<B extends object, R extends Reducer<any, any>>(
|
|||
apiVersion,
|
||||
abortCtrl,
|
||||
body,
|
||||
customReducer !== undefined
|
||||
customReducer !== undefined,
|
||||
headers
|
||||
)) {
|
||||
if (fetchStreamError !== null) {
|
||||
addError(fetchStreamError);
|
||||
|
|
|
@ -19,3 +19,8 @@ export const RANDOM_SAMPLER_SEED = 3867412;
|
|||
export const CASES_ATTACHMENT_CHANGE_POINT_CHART = 'aiopsChangePointChart';
|
||||
|
||||
export const EMBEDDABLE_CHANGE_POINT_CHART_TYPE = 'aiopsChangePointChart' as const;
|
||||
|
||||
export const AIOPS_TELEMETRY_ID = {
|
||||
AIOPS_DEFAULT_SOURCE: 'ml_aiops_labs',
|
||||
AIOPS_ANALYSIS_RUN_ORIGIN: 'aiops-analysis-run-origin',
|
||||
} as const;
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
"unifiedSearch"
|
||||
],
|
||||
"optionalPlugins": [
|
||||
"cases"
|
||||
"cases",
|
||||
"usageCollection"
|
||||
],
|
||||
"requiredBundles": [
|
||||
"fieldFormats",
|
||||
|
|
|
@ -27,7 +27,7 @@ export const categorizeFieldAction = (coreStart: CoreStart, plugins: AiopsPlugin
|
|||
return field.esTypes?.includes('text') === true;
|
||||
},
|
||||
execute: async (context: CategorizeFieldContext) => {
|
||||
const { field, dataView } = context;
|
||||
showCategorizeFlyout(field, dataView, coreStart, plugins);
|
||||
const { field, dataView, originatingApp } = context;
|
||||
showCategorizeFlyout(field, dataView, coreStart, plugins, originatingApp);
|
||||
},
|
||||
});
|
||||
|
|
|
@ -15,6 +15,7 @@ import { Storage } from '@kbn/kibana-utils-plugin/public';
|
|||
import { DatePickerContextProvider, type DatePickerDependencies } from '@kbn/ml-date-picker';
|
||||
import { UI_SETTINGS } from '@kbn/data-plugin/common';
|
||||
|
||||
import { AIOPS_TELEMETRY_ID } from '../../../common/constants';
|
||||
import { DataSourceContext } from '../../hooks/use_data_source';
|
||||
import type { AiopsAppDependencies } from '../../hooks/use_aiops_app_context';
|
||||
import { AIOPS_STORAGE_KEYS } from '../../types/storage';
|
||||
|
@ -65,7 +66,7 @@ export const LogCategorizationAppState: FC<LogCategorizationAppStateProps> = ({
|
|||
<DataSourceContext.Provider value={{ dataView, savedSearch }}>
|
||||
<StorageContextProvider storage={localStorage} storageKeys={AIOPS_STORAGE_KEYS}>
|
||||
<DatePickerContextProvider {...datePickerDeps}>
|
||||
<LogCategorizationPage />
|
||||
<LogCategorizationPage embeddingOrigin={AIOPS_TELEMETRY_ID.AIOPS_DEFAULT_SOURCE} />
|
||||
</DatePickerContextProvider>
|
||||
</StorageContextProvider>
|
||||
</DataSourceContext.Provider>
|
||||
|
|
|
@ -22,6 +22,7 @@ import { FormattedMessage } from '@kbn/i18n-react';
|
|||
import { buildEmptyFilter, Filter } from '@kbn/es-query';
|
||||
import { usePageUrlState } from '@kbn/ml-url-state';
|
||||
import type { FieldValidationResults } from '@kbn/ml-category-validator';
|
||||
import { AIOPS_TELEMETRY_ID } from '../../../common/constants';
|
||||
|
||||
import type { Category, SparkLinesPerCategory } from '../../../common/api/log_categorization/types';
|
||||
|
||||
|
@ -49,6 +50,8 @@ export interface LogCategorizationPageProps {
|
|||
savedSearch: SavedSearch | null;
|
||||
selectedField: DataViewField;
|
||||
onClose: () => void;
|
||||
/** Identifier to indicate the plugin utilizing the component */
|
||||
embeddingOrigin: string;
|
||||
}
|
||||
|
||||
const BAR_TARGET = 20;
|
||||
|
@ -58,6 +61,7 @@ export const LogCategorizationFlyout: FC<LogCategorizationPageProps> = ({
|
|||
savedSearch,
|
||||
selectedField,
|
||||
onClose,
|
||||
embeddingOrigin,
|
||||
}) => {
|
||||
const {
|
||||
notifications: { toasts },
|
||||
|
@ -151,7 +155,8 @@ export const LogCategorizationFlyout: FC<LogCategorizationPageProps> = ({
|
|||
timeField,
|
||||
earliest,
|
||||
latest,
|
||||
searchQuery
|
||||
searchQuery,
|
||||
{ [AIOPS_TELEMETRY_ID.AIOPS_ANALYSIS_RUN_ORIGIN]: embeddingOrigin }
|
||||
),
|
||||
runCategorizeRequest(
|
||||
index,
|
||||
|
@ -193,6 +198,7 @@ export const LogCategorizationFlyout: FC<LogCategorizationPageProps> = ({
|
|||
runCategorizeRequest,
|
||||
intervalMs,
|
||||
toasts,
|
||||
embeddingOrigin,
|
||||
]);
|
||||
|
||||
const onAddFilter = useCallback(
|
||||
|
|
|
@ -26,6 +26,7 @@ import { FormattedMessage } from '@kbn/i18n-react';
|
|||
import { usePageUrlState, useUrlState } from '@kbn/ml-url-state';
|
||||
import type { FieldValidationResults } from '@kbn/ml-category-validator';
|
||||
import type { SearchQueryLanguage } from '@kbn/ml-query-utils';
|
||||
import { AIOPS_TELEMETRY_ID } from '../../../common/constants';
|
||||
|
||||
import type { Category, SparkLinesPerCategory } from '../../../common/api/log_categorization/types';
|
||||
|
||||
|
@ -53,7 +54,12 @@ import { FieldValidationCallout } from './category_validation_callout';
|
|||
const BAR_TARGET = 20;
|
||||
const DEFAULT_SELECTED_FIELD = 'message';
|
||||
|
||||
export const LogCategorizationPage: FC = () => {
|
||||
interface LogCategorizationPageProps {
|
||||
/** Identifier to indicate the plugin utilizing the component */
|
||||
embeddingOrigin: string;
|
||||
}
|
||||
|
||||
export const LogCategorizationPage: FC<LogCategorizationPageProps> = ({ embeddingOrigin }) => {
|
||||
const {
|
||||
notifications: { toasts },
|
||||
} = useAiopsAppContext();
|
||||
|
@ -208,7 +214,10 @@ export const LogCategorizationPage: FC = () => {
|
|||
|
||||
try {
|
||||
const [validationResult, categorizationResult] = await Promise.all([
|
||||
runValidateFieldRequest(index, selectedField, timeField, earliest, latest, searchQuery),
|
||||
runValidateFieldRequest(index, selectedField, timeField, earliest, latest, searchQuery, {
|
||||
[AIOPS_TELEMETRY_ID.AIOPS_ANALYSIS_RUN_ORIGIN]: embeddingOrigin,
|
||||
}),
|
||||
|
||||
runCategorizeRequest(
|
||||
index,
|
||||
selectedField,
|
||||
|
@ -245,6 +254,7 @@ export const LogCategorizationPage: FC = () => {
|
|||
runCategorizeRequest,
|
||||
intervalMs,
|
||||
toasts,
|
||||
embeddingOrigin,
|
||||
]);
|
||||
|
||||
useEffect(
|
||||
|
|
|
@ -29,7 +29,8 @@ export async function showCategorizeFlyout(
|
|||
field: DataViewField,
|
||||
dataView: DataView,
|
||||
coreStart: CoreStart,
|
||||
plugins: AiopsPluginStartDeps
|
||||
plugins: AiopsPluginStartDeps,
|
||||
originatingApp: string
|
||||
): Promise<void> {
|
||||
const { http, theme, overlays, application, notifications, uiSettings, i18n } = coreStart;
|
||||
|
||||
|
@ -70,6 +71,7 @@ export async function showCategorizeFlyout(
|
|||
savedSearch={null}
|
||||
selectedField={field}
|
||||
onClose={onFlyoutClose}
|
||||
embeddingOrigin={originatingApp}
|
||||
/>
|
||||
</StorageContextProvider>
|
||||
</DatePickerContextProvider>
|
||||
|
|
|
@ -11,6 +11,8 @@ import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/type
|
|||
|
||||
import type { FieldValidationResults } from '@kbn/ml-category-validator';
|
||||
|
||||
import type { HttpFetchOptions } from '@kbn/core/public';
|
||||
|
||||
import { AIOPS_API_ENDPOINT } from '../../../common/api';
|
||||
import { createCategorizeQuery } from '../../../common/api/log_categorization/create_categorize_query';
|
||||
|
||||
|
@ -27,7 +29,8 @@ export function useValidateFieldRequest() {
|
|||
timeField: string,
|
||||
start: number | undefined,
|
||||
end: number | undefined,
|
||||
queryIn: QueryDslQueryContainer
|
||||
queryIn: QueryDslQueryContainer,
|
||||
headers?: HttpFetchOptions['headers']
|
||||
) => {
|
||||
const query = createCategorizeQuery(queryIn, timeField, start, end);
|
||||
const resp = await http.post<FieldValidationResults>(
|
||||
|
@ -48,6 +51,7 @@ export function useValidateFieldRequest() {
|
|||
indicesOptions: undefined,
|
||||
includeExamples: false,
|
||||
}),
|
||||
headers,
|
||||
version: '1',
|
||||
}
|
||||
);
|
||||
|
|
|
@ -64,6 +64,8 @@ export interface LogRateAnalysisContentProps {
|
|||
barHighlightColorOverride?: string;
|
||||
/** Optional callback that exposes data of the completed analysis */
|
||||
onAnalysisCompleted?: (d: LogRateAnalysisResultsData) => void;
|
||||
/** Identifier to indicate the plugin utilizing the component */
|
||||
embeddingOrigin: string;
|
||||
}
|
||||
|
||||
export const LogRateAnalysisContent: FC<LogRateAnalysisContentProps> = ({
|
||||
|
@ -76,6 +78,7 @@ export const LogRateAnalysisContent: FC<LogRateAnalysisContentProps> = ({
|
|||
barColorOverride,
|
||||
barHighlightColorOverride,
|
||||
onAnalysisCompleted,
|
||||
embeddingOrigin,
|
||||
}) => {
|
||||
const [windowParameters, setWindowParameters] = useState<WindowParameters | undefined>();
|
||||
const [initialAnalysisStart, setInitialAnalysisStart] = useState<
|
||||
|
@ -172,6 +175,7 @@ export const LogRateAnalysisContent: FC<LogRateAnalysisContentProps> = ({
|
|||
barColorOverride={barColorOverride}
|
||||
barHighlightColorOverride={barHighlightColorOverride}
|
||||
onAnalysisCompleted={onAnalysisCompleted}
|
||||
embeddingOrigin={embeddingOrigin}
|
||||
/>
|
||||
)}
|
||||
{windowParameters === undefined && (
|
||||
|
|
|
@ -59,6 +59,8 @@ export interface LogRateAnalysisContentWrapperProps {
|
|||
onAnalysisCompleted?: (d: LogRateAnalysisResultsData) => void;
|
||||
/** Optional flag to indicate whether kibana is running in serverless */
|
||||
showFrozenDataTierChoice?: boolean;
|
||||
/** Identifier to indicate the plugin utilizing the component */
|
||||
embeddingOrigin: string;
|
||||
}
|
||||
|
||||
export const LogRateAnalysisContentWrapper: FC<LogRateAnalysisContentWrapperProps> = ({
|
||||
|
@ -73,6 +75,7 @@ export const LogRateAnalysisContentWrapper: FC<LogRateAnalysisContentWrapperProp
|
|||
barHighlightColorOverride,
|
||||
onAnalysisCompleted,
|
||||
showFrozenDataTierChoice = true,
|
||||
embeddingOrigin,
|
||||
}) => {
|
||||
if (!dataView) return null;
|
||||
|
||||
|
@ -105,6 +108,7 @@ export const LogRateAnalysisContentWrapper: FC<LogRateAnalysisContentWrapperProp
|
|||
barColorOverride={barColorOverride}
|
||||
barHighlightColorOverride={barHighlightColorOverride}
|
||||
onAnalysisCompleted={onAnalysisCompleted}
|
||||
embeddingOrigin={embeddingOrigin}
|
||||
/>
|
||||
</DatePickerContextProvider>
|
||||
</StorageContextProvider>
|
||||
|
|
|
@ -22,6 +22,7 @@ import {
|
|||
getDefaultAiOpsListState,
|
||||
type AiOpsPageUrlState,
|
||||
} from '../../application/utils/url_state';
|
||||
import { AIOPS_TELEMETRY_ID } from '../../../common/constants';
|
||||
|
||||
import { SearchPanel } from '../search_panel';
|
||||
import { useLogRateAnalysisResultsTableRowContext } from '../log_rate_analysis_results_table/log_rate_analysis_results_table_row_provider';
|
||||
|
@ -151,6 +152,7 @@ export const LogRateAnalysisPage: FC<Props> = ({ stickyHistogram }) => {
|
|||
setGlobalState={setGlobalState}
|
||||
esSearchQuery={searchQuery}
|
||||
stickyHistogram={stickyHistogram}
|
||||
embeddingOrigin={AIOPS_TELEMETRY_ID.AIOPS_DEFAULT_SOURCE}
|
||||
/>
|
||||
</EuiFlexGroup>
|
||||
</EuiPageSection>
|
||||
|
|
|
@ -36,6 +36,7 @@ import type { SignificantTerm, SignificantTermGroup } from '@kbn/ml-agg-utils';
|
|||
import { useAiopsAppContext } from '../../hooks/use_aiops_app_context';
|
||||
import { initialState, streamReducer } from '../../../common/api/stream_reducer';
|
||||
import type { AiopsApiLogRateAnalysis } from '../../../common/api';
|
||||
import { AIOPS_TELEMETRY_ID } from '../../../common/constants';
|
||||
import {
|
||||
getGroupTableItems,
|
||||
LogRateAnalysisResultsTable,
|
||||
|
@ -113,6 +114,8 @@ interface LogRateAnalysisResultsProps {
|
|||
barHighlightColorOverride?: string;
|
||||
/** Optional callback that exposes data of the completed analysis */
|
||||
onAnalysisCompleted?: (d: LogRateAnalysisResultsData) => void;
|
||||
/** Identifier to indicate the plugin utilizing the component */
|
||||
embeddingOrigin: string;
|
||||
}
|
||||
|
||||
export const LogRateAnalysisResults: FC<LogRateAnalysisResultsProps> = ({
|
||||
|
@ -129,6 +132,7 @@ export const LogRateAnalysisResults: FC<LogRateAnalysisResultsProps> = ({
|
|||
barColorOverride,
|
||||
barHighlightColorOverride,
|
||||
onAnalysisCompleted,
|
||||
embeddingOrigin,
|
||||
}) => {
|
||||
const { http } = useAiopsAppContext();
|
||||
|
||||
|
@ -198,7 +202,8 @@ export const LogRateAnalysisResults: FC<LogRateAnalysisResultsProps> = ({
|
|||
overrides,
|
||||
sampleProbability,
|
||||
},
|
||||
{ reducer: streamReducer, initialState }
|
||||
{ reducer: streamReducer, initialState },
|
||||
{ [AIOPS_TELEMETRY_ID.AIOPS_ANALYSIS_RUN_ORIGIN]: embeddingOrigin }
|
||||
);
|
||||
|
||||
const { significantTerms } = data;
|
||||
|
|
32
x-pack/plugins/aiops/server/lib/track_route_usage.test.ts
Normal file
32
x-pack/plugins/aiops/server/lib/track_route_usage.test.ts
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import { usageCountersServiceMock } from '@kbn/usage-collection-plugin/server/usage_counters/usage_counters_service.mock';
|
||||
import { trackAIOpsRouteUsage } from './track_route_usage';
|
||||
|
||||
describe('trackAIOpsRouteUsage', () => {
|
||||
it('should call `usageCounter.incrementCounter`', () => {
|
||||
const mockUsageCountersSetup = usageCountersServiceMock.createSetupContract();
|
||||
const mockUsageCounter = mockUsageCountersSetup.createUsageCounter('test');
|
||||
|
||||
trackAIOpsRouteUsage('test_type', 'test_source', mockUsageCounter);
|
||||
expect(mockUsageCounter.incrementCounter).toHaveBeenCalledWith({
|
||||
counterName: 'test_type',
|
||||
counterType: 'run_via_test_source',
|
||||
incrementBy: 1,
|
||||
});
|
||||
});
|
||||
|
||||
it('should do nothing if no usage counter is provided', () => {
|
||||
let err;
|
||||
try {
|
||||
trackAIOpsRouteUsage('test', undefined);
|
||||
} catch (e) {
|
||||
err = e;
|
||||
}
|
||||
expect(err).toBeUndefined();
|
||||
});
|
||||
});
|
22
x-pack/plugins/aiops/server/lib/track_route_usage.ts
Normal file
22
x-pack/plugins/aiops/server/lib/track_route_usage.ts
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { UsageCounter } from '@kbn/usage-collection-plugin/server';
|
||||
|
||||
export function trackAIOpsRouteUsage(
|
||||
analysisType: string,
|
||||
source?: string | string[],
|
||||
usageCounter?: UsageCounter
|
||||
) {
|
||||
if (usageCounter && typeof source === 'string') {
|
||||
usageCounter.incrementCounter({
|
||||
counterName: analysisType,
|
||||
counterType: `run_via_${source}`,
|
||||
incrementBy: 1,
|
||||
});
|
||||
}
|
||||
}
|
|
@ -9,8 +9,10 @@ import { Subscription } from 'rxjs';
|
|||
|
||||
import { PluginInitializerContext, CoreSetup, CoreStart, Plugin, Logger } from '@kbn/core/server';
|
||||
import type { DataRequestHandlerContext } from '@kbn/data-plugin/server';
|
||||
import type { UsageCounter } from '@kbn/usage-collection-plugin/server';
|
||||
|
||||
import { CASES_ATTACHMENT_CHANGE_POINT_CHART } from '../common/constants';
|
||||
import { PLUGIN_ID } from '../common';
|
||||
import { isActiveLicense } from './lib/license';
|
||||
import {
|
||||
AiopsLicense,
|
||||
|
@ -28,6 +30,7 @@ export class AiopsPlugin
|
|||
{
|
||||
private readonly logger: Logger;
|
||||
private licenseSubscription: Subscription | null = null;
|
||||
private usageCounter?: UsageCounter;
|
||||
|
||||
constructor(initializerContext: PluginInitializerContext) {
|
||||
this.logger = initializerContext.logger.get();
|
||||
|
@ -38,6 +41,7 @@ export class AiopsPlugin
|
|||
plugins: AiopsPluginSetupDeps
|
||||
) {
|
||||
this.logger.debug('aiops: Setup');
|
||||
this.usageCounter = plugins.usageCollection?.createUsageCounter(PLUGIN_ID);
|
||||
|
||||
// Subscribe to license changes and store the current license in `currentLicense`.
|
||||
// This way we can pass on license changes to the route factory having always
|
||||
|
@ -51,8 +55,8 @@ export class AiopsPlugin
|
|||
|
||||
// Register server side APIs
|
||||
core.getStartServices().then(([coreStart, depsStart]) => {
|
||||
defineLogRateAnalysisRoute(router, aiopsLicense, this.logger, coreStart);
|
||||
defineLogCategorizationRoutes(router, aiopsLicense);
|
||||
defineLogRateAnalysisRoute(router, aiopsLicense, this.logger, coreStart, this.usageCounter);
|
||||
defineLogCategorizationRoutes(router, aiopsLicense, this.usageCounter);
|
||||
});
|
||||
|
||||
if (plugins.cases) {
|
||||
|
|
|
@ -8,14 +8,18 @@
|
|||
import type { IRouter } from '@kbn/core/server';
|
||||
import type { DataRequestHandlerContext } from '@kbn/data-plugin/server';
|
||||
import { categorizationExamplesProvider } from '@kbn/ml-category-validator';
|
||||
import type { UsageCounter } from '@kbn/usage-collection-plugin/server';
|
||||
import { categorizationFieldValidationSchema } from '../../common/api/log_categorization/schema';
|
||||
import { AIOPS_API_ENDPOINT } from '../../common/api';
|
||||
import type { AiopsLicense } from '../types';
|
||||
import { wrapError } from './error_wrapper';
|
||||
import { trackAIOpsRouteUsage } from '../lib/track_route_usage';
|
||||
import { AIOPS_TELEMETRY_ID } from '../../common/constants';
|
||||
|
||||
export const defineLogCategorizationRoutes = (
|
||||
router: IRouter<DataRequestHandlerContext>,
|
||||
license: AiopsLicense
|
||||
license: AiopsLicense,
|
||||
usageCounter?: UsageCounter
|
||||
) => {
|
||||
router.versioned
|
||||
.post({
|
||||
|
@ -32,6 +36,13 @@ export const defineLogCategorizationRoutes = (
|
|||
},
|
||||
},
|
||||
async (context, request, response) => {
|
||||
const { headers } = request;
|
||||
trackAIOpsRouteUsage(
|
||||
`POST ${AIOPS_API_ENDPOINT.CATEGORIZATION_FIELD_VALIDATION}`,
|
||||
headers[AIOPS_TELEMETRY_ID.AIOPS_ANALYSIS_RUN_ORIGIN],
|
||||
usageCounter
|
||||
);
|
||||
|
||||
if (!license.isActivePlatinumLicense) {
|
||||
return response.forbidden();
|
||||
}
|
||||
|
|
|
@ -23,8 +23,9 @@ import type {
|
|||
} from '@kbn/ml-agg-utils';
|
||||
import { fetchHistogramsForFields } from '@kbn/ml-agg-utils';
|
||||
import { createExecutionContext } from '@kbn/ml-route-utils';
|
||||
import type { UsageCounter } from '@kbn/usage-collection-plugin/server';
|
||||
|
||||
import { RANDOM_SAMPLER_SEED } from '../../common/constants';
|
||||
import { RANDOM_SAMPLER_SEED, AIOPS_TELEMETRY_ID } from '../../common/constants';
|
||||
import {
|
||||
addSignificantTermsAction,
|
||||
addSignificantTermsGroupAction,
|
||||
|
@ -52,6 +53,7 @@ import { fetchFrequentItemSets } from './queries/fetch_frequent_item_sets';
|
|||
import { getHistogramQuery } from './queries/get_histogram_query';
|
||||
import { getGroupFilter } from './queries/get_group_filter';
|
||||
import { getSignificantTermGroups } from './queries/get_significant_term_groups';
|
||||
import { trackAIOpsRouteUsage } from '../lib/track_route_usage';
|
||||
|
||||
// 10s ping frequency to keep the stream alive.
|
||||
const PING_FREQUENCY = 10000;
|
||||
|
@ -67,7 +69,8 @@ export const defineLogRateAnalysisRoute = (
|
|||
router: IRouter<DataRequestHandlerContext>,
|
||||
license: AiopsLicense,
|
||||
logger: Logger,
|
||||
coreStart: CoreStart
|
||||
coreStart: CoreStart,
|
||||
usageCounter?: UsageCounter
|
||||
) => {
|
||||
router.versioned
|
||||
.post({
|
||||
|
@ -85,6 +88,14 @@ export const defineLogRateAnalysisRoute = (
|
|||
},
|
||||
},
|
||||
async (context, request, response) => {
|
||||
const { headers } = request;
|
||||
|
||||
trackAIOpsRouteUsage(
|
||||
`POST ${AIOPS_API_ENDPOINT.LOG_RATE_ANALYSIS}`,
|
||||
headers[AIOPS_TELEMETRY_ID.AIOPS_ANALYSIS_RUN_ORIGIN],
|
||||
usageCounter
|
||||
);
|
||||
|
||||
if (!license.isActivePlatinumLicense) {
|
||||
return response.forbidden();
|
||||
}
|
||||
|
|
|
@ -8,11 +8,13 @@
|
|||
import type { PluginSetup, PluginStart } from '@kbn/data-plugin/server';
|
||||
import type { LicensingPluginStart } from '@kbn/licensing-plugin/server';
|
||||
import type { CasesSetup } from '@kbn/cases-plugin/server';
|
||||
import type { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server';
|
||||
|
||||
export interface AiopsPluginSetupDeps {
|
||||
data: PluginSetup;
|
||||
licensing: LicensingPluginStart;
|
||||
cases?: CasesSetup;
|
||||
usageCollection?: UsageCollectionSetup;
|
||||
}
|
||||
|
||||
export interface AiopsPluginStartDeps {
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
"@kbn/core-lifecycle-browser",
|
||||
"@kbn/cases-plugin",
|
||||
"@kbn/react-kibana-mount",
|
||||
"@kbn/usage-collection-plugin",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -268,6 +268,7 @@ export const LogRateAnalysis: FC<AlertDetailsLogRateAnalysisSectionProps> = ({ r
|
|||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<LogRateAnalysisContent
|
||||
embeddingOrigin="observability_log_threshold_alert_details"
|
||||
dataView={dataView}
|
||||
timeRange={timeRange}
|
||||
esSearchQuery={esSearchQuery}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue