Skip to content

Commit

Permalink
[ML] Refactoring anomaly detector job types (#59556)
Browse files Browse the repository at this point in the history
* [ML] Refactoring anomaly detector job types

* removing calendar type

* update validateCardinality

* fixing test

* updating  types in functional tests

* using state constants
  • Loading branch information
jgowdyelastic committed Mar 9, 2020
1 parent 492a97e commit 92cc04c
Show file tree
Hide file tree
Showing 63 changed files with 536 additions and 331 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
* you may not use this file except in compliance with the Elastic License.
*/

import jobConfigFarequote from './__mocks__/job_config_farequote';
import { isMlJob, isMlJobs } from './jobs';
// @ts-ignore importing JSON file
import jobConfigFarequote from '../__mocks__/job_config_farequote';
import { isCombinedJobWithStats } from './combined_job';

describe('Types: Jobs', () => {
test('Minimal integrity check.', () => {
expect(isMlJob(jobConfigFarequote)).toBe(true);
expect(isMlJobs([jobConfigFarequote])).toBe(true);
expect(isCombinedJobWithStats(jobConfigFarequote)).toBe(true);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,25 @@

import { cloneDeep } from 'lodash';
import { Datafeed } from './datafeed';
import { DatafeedStats } from './datafeed_stats';
import { Job } from './job';
import { JobStats } from './job_stats';

export type JobWithStats = Job & JobStats;
export type DatafeedWithStats = Datafeed & DatafeedStats;

// in older implementations of the job config, the datafeed was placed inside the job
// for convenience.
export interface CombinedJob extends Job {
calendars?: string[];
datafeed_config: Datafeed;
}

export interface CombinedJobWithStats extends JobWithStats {
calendars?: string[];
datafeed_config: DatafeedWithStats;
}

export function expandCombinedJobConfig(combinedJob: CombinedJob) {
const combinedJobClone = cloneDeep(combinedJob);
const job = combinedJobClone;
Expand All @@ -22,3 +33,7 @@ export function expandCombinedJobConfig(combinedJob: CombinedJob) {

return { job, datafeed };
}

export function isCombinedJobWithStats(arg: any): arg is CombinedJobWithStats {
return typeof arg.job_id === 'string';
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { IndexPatternTitle } from '../../../../../../../common/types/kibana';
import { IndexPatternTitle } from '../kibana';
import { JobId } from './job';
export type DatafeedId = string;

Expand All @@ -15,11 +15,8 @@ export interface Datafeed {
chunking_config?: ChunkingConfig;
frequency?: string;
indices: IndexPatternTitle[];
/**
* The datafeed can contain indexes and indices
*/
indexes?: IndexPatternTitle[];
job_id?: JobId;
indexes?: IndexPatternTitle[]; // The datafeed can contain indexes and indices
job_id: JobId;
query: object;
query_delay?: string;
script_fields?: object;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { Node } from './job_stats';
import { DATAFEED_STATE } from '../../constants/states';

export interface DatafeedStats {
datafeed_id: string;
state: DATAFEED_STATE;
node: Node;
assignment_explanation: string;
timing_stats: TimingStats;
}

interface TimingStats {
job_id: string;
search_count: number;
bucket_count: number;
total_search_time_ms: number;
average_search_time_per_bucket_ms: number;
exponential_average_search_time_per_hour_ms: number;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@
*/

export * from './job';
export * from './job_stats';
export * from './datafeed';
export * from './datafeed_stats';
export * from './combined_job';
export * from './summary_job';
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { UrlConfig } from '../../../../../../../common/types/custom_urls';
import { CREATED_BY_LABEL } from '../../../../../../../common/constants/new_job';
import { UrlConfig } from '../custom_urls';
import { CREATED_BY_LABEL } from '../../constants/new_job';

export type JobId = string;
export type BucketSpan = string;
Expand All @@ -29,6 +29,14 @@ export interface Job {
renormalization_window_days?: number;
results_index_name?: string;
results_retention_days?: number;

// optional properties added when the job has been created
create_time?: number;
finished_time?: number;
job_type?: 'anomaly_detector';
job_version?: string;
model_snapshot_id?: string;
deleting?: boolean;
}

export interface AnalysisConfig {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { JOB_STATE } from '../../constants/states';

export interface JobStats {
job_id: string;
data_counts: DataCounts;
model_size_stats: ModelSizeStats;
forecasts_stats: ForecastsStats;
state: JOB_STATE;
node: Node;
assignment_explanation: string;
open_time: string;
timing_stats: TimingStats;
}

export interface DataCounts {
job_id: string;
processed_record_count: number;
processed_field_count: number;
input_bytes: number;
input_field_count: number;
invalid_date_count: number;
missing_field_count: number;
out_of_order_timestamp_count: number;
empty_bucket_count: number;
sparse_bucket_count: number;
bucket_count: number;
earliest_record_timestamp: number;
latest_record_timestamp: number;
last_data_time: number;
input_record_count: number;
latest_empty_bucket_timestamp: number;
latest_sparse_bucket_timestamp: number;
latest_bucket_timestamp?: number; // stat added by the UI
}

export interface ModelSizeStats {
job_id: string;
result_type: string;
model_bytes: number;
model_bytes_exceeded: number;
model_bytes_memory_limit: number;
total_by_field_count: number;
total_over_field_count: number;
total_partition_field_count: number;
bucket_allocation_failures_count: number;
memory_status: 'ok' | 'soft_limit' | 'hard_limit';
categorized_doc_count: number;
total_category_count: number;
frequent_category_count: number;
rare_category_count: number;
dead_category_count: number;
categorization_status: 'ok' | 'warn';
log_time: number;
timestamp: number;
}

export interface ForecastsStats {
total: number;
forecasted_jobs: number;
memory_bytes?: any;
records?: any;
processing_time_ms?: any;
status?: any;
}

export interface Node {
id: string;
name: string;
ephemeral_id: string;
transport_address: string;
attributes: {
'transform.remote_connect'?: boolean;
'ml.machine_memory'?: number;
'xpack.installed'?: boolean;
'transform.node'?: boolean;
'ml.max_open_jobs'?: number;
};
}

interface TimingStats {
job_id: string;
bucket_count: number;
total_bucket_processing_time_ms: number;
minimum_bucket_processing_time_ms: number;
maximum_bucket_processing_time_ms: number;
average_bucket_processing_time_ms: number;
exponential_average_bucket_processing_time_ms: number;
exponential_average_bucket_processing_time_per_hour_ms: number;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { Moment } from 'moment';

import { CombinedJob, CombinedJobWithStats } from './combined_job';
export { Datafeed } from './datafeed';
export { DatafeedStats } from './datafeed_stats';

export interface MlSummaryJob {
id: string;
description: string;
groups: string[];
processed_record_count?: number;
memory_status?: string;
jobState: string;
datafeedIndices: string[];
hasDatafeed: boolean;
datafeedId: string;
datafeedState: string;
latestTimestampMs?: number;
earliestTimestampMs?: number;
latestResultsTimestampMs?: number;
fullJob?: CombinedJob;
nodeName?: string;
auditMessage?: Partial<AuditMessage>;
isSingleMetricViewerJob: boolean;
deleting?: boolean;
latestTimestampSortValue?: number;
}

export interface AuditMessage {
job_id: string;
msgTime: number;
level: number;
highestLevel: number;
highestLevelText: string;
text: string;
}

export type MlSummaryJobs = MlSummaryJob[];

export interface MlJobWithTimeRange extends CombinedJobWithStats {
timeRange: {
from: number;
to: number;
fromPx: number;
toPx: number;
fromMoment: Moment;
toMoment: Moment;
widthPx: number;
label: string;
};
}
97 changes: 0 additions & 97 deletions x-pack/legacy/plugins/ml/common/types/jobs.ts

This file was deleted.

2 changes: 1 addition & 1 deletion x-pack/legacy/plugins/ml/common/types/modules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { SavedObjectAttributes } from 'src/core/public';
import { Datafeed, Job } from '../../public/application/jobs/new_job/common/job_creator/configs';
import { Datafeed, Job } from '../types/anomaly_detection_jobs';

export interface ModuleJob {
id: string;
Expand Down
Loading

0 comments on commit 92cc04c

Please sign in to comment.