mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[8.6][ML Inference] Add ML inference failure handler (#142488)
* Add ML Inference failure handler
This commit is contained in:
parent
b81993d6d8
commit
524363d9ff
2 changed files with 71 additions and 64 deletions
|
@ -52,6 +52,20 @@ export const generateMlInferencePipelineBody = ({
|
|||
},
|
||||
model_id: model.model_id,
|
||||
target_field: `ml.inference.${destinationField}`,
|
||||
on_failure: [
|
||||
{
|
||||
append: {
|
||||
field: '_source._ingest.inference_errors',
|
||||
value: [
|
||||
{
|
||||
pipeline: pipelineName,
|
||||
message: `Processor 'inference' in pipeline '${pipelineName}' failed with message '{{ _ingest.on_failure_message }}'`,
|
||||
timestamp: '{{{ _ingest.timestamp }}}',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import { merge } from 'lodash';
|
||||
|
||||
import { ElasticsearchClient } from '@kbn/core/server';
|
||||
|
||||
|
@ -41,7 +42,7 @@ describe('createIndexPipelineDefinitions util function', () => {
|
|||
describe('formatMlPipelineBody util function', () => {
|
||||
const pipelineName = 'ml-inference-my-ml-proc';
|
||||
const modelId = 'my-model-id';
|
||||
let modelInputField = 'my-model-input-field';
|
||||
const modelInputField = 'my-model-input-field';
|
||||
const modelType = 'pytorch';
|
||||
const inferenceConfigKey = 'my-model-type';
|
||||
const modelTypes = ['pytorch', 'my-model-type'];
|
||||
|
@ -49,6 +50,55 @@ describe('formatMlPipelineBody util function', () => {
|
|||
const sourceField = 'my-source-field';
|
||||
const destField = 'my-dest-field';
|
||||
|
||||
const expectedResult = {
|
||||
description: '',
|
||||
processors: [
|
||||
{
|
||||
remove: {
|
||||
field: `ml.inference.${destField}`,
|
||||
ignore_missing: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
inference: {
|
||||
field_map: {
|
||||
[sourceField]: modelInputField,
|
||||
},
|
||||
model_id: modelId,
|
||||
target_field: `ml.inference.${destField}`,
|
||||
on_failure: [
|
||||
{
|
||||
append: {
|
||||
field: '_source._ingest.inference_errors',
|
||||
value: [
|
||||
{
|
||||
pipeline: pipelineName,
|
||||
message: `Processor 'inference' in pipeline '${pipelineName}' failed with message '{{ _ingest.on_failure_message }}'`,
|
||||
timestamp: '{{{ _ingest.timestamp }}}',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
append: {
|
||||
field: '_source._ingest.processors',
|
||||
value: [
|
||||
{
|
||||
model_version: modelVersion,
|
||||
pipeline: pipelineName,
|
||||
processed_timestamp: '{{{ _ingest.timestamp }}}',
|
||||
types: modelTypes,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
version: 1,
|
||||
};
|
||||
|
||||
const mockClient = {
|
||||
ml: {
|
||||
getTrainedModels: jest.fn(),
|
||||
|
@ -60,41 +110,6 @@ describe('formatMlPipelineBody util function', () => {
|
|||
});
|
||||
|
||||
it('should return the pipeline body', async () => {
|
||||
const expectedResult = {
|
||||
description: '',
|
||||
processors: [
|
||||
{
|
||||
remove: {
|
||||
field: `ml.inference.${destField}`,
|
||||
ignore_missing: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
inference: {
|
||||
field_map: {
|
||||
[sourceField]: modelInputField,
|
||||
},
|
||||
model_id: modelId,
|
||||
target_field: `ml.inference.${destField}`,
|
||||
},
|
||||
},
|
||||
{
|
||||
append: {
|
||||
field: '_source._ingest.processors',
|
||||
value: [
|
||||
{
|
||||
model_version: modelVersion,
|
||||
pipeline: pipelineName,
|
||||
processed_timestamp: '{{{ _ingest.timestamp }}}',
|
||||
types: modelTypes,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
version: 1,
|
||||
};
|
||||
|
||||
const mockResponse = {
|
||||
count: 1,
|
||||
trained_model_configs: [
|
||||
|
@ -136,41 +151,19 @@ describe('formatMlPipelineBody util function', () => {
|
|||
});
|
||||
|
||||
it('should insert a placeholder if model has no input fields', async () => {
|
||||
modelInputField = 'MODEL_INPUT_FIELD';
|
||||
const expectedResult = {
|
||||
description: '',
|
||||
const expectedResultWithNoInputField = merge({}, expectedResult, {
|
||||
processors: [
|
||||
{
|
||||
remove: {
|
||||
field: `ml.inference.${destField}`,
|
||||
ignore_missing: true,
|
||||
},
|
||||
},
|
||||
{}, // append - we'll leave it untouched
|
||||
{
|
||||
inference: {
|
||||
field_map: {
|
||||
[sourceField]: modelInputField,
|
||||
[sourceField]: 'MODEL_INPUT_FIELD',
|
||||
},
|
||||
model_id: modelId,
|
||||
target_field: `ml.inference.${destField}`,
|
||||
},
|
||||
},
|
||||
{
|
||||
append: {
|
||||
field: '_source._ingest.processors',
|
||||
value: [
|
||||
{
|
||||
model_version: modelVersion,
|
||||
pipeline: pipelineName,
|
||||
processed_timestamp: '{{{ _ingest.timestamp }}}',
|
||||
types: modelTypes,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
version: 1,
|
||||
};
|
||||
});
|
||||
|
||||
const mockResponse = {
|
||||
count: 1,
|
||||
trained_model_configs: [
|
||||
|
@ -193,7 +186,7 @@ describe('formatMlPipelineBody util function', () => {
|
|||
destField,
|
||||
mockClient as unknown as ElasticsearchClient
|
||||
);
|
||||
expect(actualResult).toEqual(expectedResult);
|
||||
expect(actualResult).toEqual(expectedResultWithNoInputField);
|
||||
expect(mockClient.ml.getTrainedModels).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue