[Logs UI] Add setup error telemetry for ML functionality (#90298) (#90798)

* Add logs ML setup error telemetry

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Kerry Gallagher 2021-02-10 14:21:52 +00:00 committed by GitHub
parent 9bfd91ecbe
commit c8df62f697
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 5 deletions

View file

@ -75,7 +75,7 @@ export const ProcessStep: React.FunctionComponent<ProcessStepProps> = ({
defaultMessage="Something went wrong creating the necessary ML jobs. Please ensure all selected log indices exist."
/>
<EuiSpacer />
{errorMessages.map((errorMessage, i) => (
{setupStatus.reasons.map((errorMessage, i) => (
<EuiCallOut key={i} color="danger" iconType="alert" title={errorCalloutTitle}>
<EuiCode transparentBackground>{errorMessage}</EuiCode>
</EuiCallOut>

View file

@ -91,8 +91,19 @@ const setupMlModuleRequestPayloadRT = rt.intersection([
setupMlModuleRequestParamsRT,
]);
const setupErrorRT = rt.type({
reason: rt.string,
type: rt.string,
});
const setupErrorResponseRT = rt.type({
msg: rt.string,
status: rt.number,
error: rt.intersection([
setupErrorRT,
rt.type({
root_cause: rt.array(setupErrorRT),
}),
]),
});
const datafeedSetupResponseRT = rt.intersection([

View file

@ -11,6 +11,7 @@ import { useKibanaContextForPlugin } from '../../../hooks/use_kibana';
import { useTrackedPromise } from '../../../utils/use_tracked_promise';
import { useModuleStatus } from './log_analysis_module_status';
import { ModuleDescriptor, ModuleSourceConfiguration } from './log_analysis_module_types';
import { useUiTracker } from '../../../../../observability/public';
export const useLogAnalysisModule = <JobType extends string>({
sourceConfiguration,
@ -23,6 +24,8 @@ export const useLogAnalysisModule = <JobType extends string>({
const { spaceId, sourceId, timestampField } = sourceConfiguration;
const [moduleStatus, dispatchModuleStatus] = useModuleStatus(moduleDescriptor.jobTypes);
const trackMetric = useUiTracker({ app: 'infra_logs' });
const [, fetchJobStatus] = useTrackedPromise(
{
cancelPreviousOn: 'resolution',
@ -75,6 +78,25 @@ export const useLogAnalysisModule = <JobType extends string>({
return { setupResult, jobSummaries };
},
onResolve: ({ setupResult: { datafeeds, jobs }, jobSummaries }) => {
// Track failures
if (
[...datafeeds, ...jobs]
.reduce<string[]>((acc, resource) => [...acc, ...Object.keys(resource)], [])
.some((key) => key === 'error')
) {
const reasons = [...datafeeds, ...jobs]
.filter((resource) => resource.error !== undefined)
.map((resource) => resource.error?.error?.reason ?? '');
// NOTE: Lack of indices and a missing field mapping have the same error
if (
reasons.filter((reason) => reason.includes('because it has no mappings')).length > 0
) {
trackMetric({ metric: 'logs_ml_setup_error_bad_indices_or_mappings' });
} else {
trackMetric({ metric: 'logs_ml_setup_error_unknown_cause' });
}
}
dispatchModuleStatus({
type: 'finishedSetup',
datafeedSetupResults: datafeeds,
@ -84,8 +106,11 @@ export const useLogAnalysisModule = <JobType extends string>({
sourceId,
});
},
onReject: () => {
onReject: (e: any) => {
dispatchModuleStatus({ type: 'failedSetup' });
if (e?.body?.statusCode === 403) {
trackMetric({ metric: 'logs_ml_setup_error_lack_of_privileges' });
}
},
},
[moduleDescriptor.setUpModule, spaceId, sourceId, timestampField]

View file

@ -105,10 +105,10 @@ const createStatusReducer = <JobType extends string>(jobTypes: JobType[]) => (
reasons: [
...Object.values(datafeedSetupResults)
.filter(hasError)
.map((datafeed) => datafeed.error.msg),
.map((datafeed) => datafeed.error.error?.reason),
...Object.values(jobSetupResults)
.filter(hasError)
.map((job) => job.error.msg),
.map((job) => job.error.error?.reason),
],
};