Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Detection Rule telemetry from Security Solution (8.0+) #119047

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions x-pack/plugins/security_solution/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,6 @@ export class Plugin implements ISecuritySolutionPlugin {
});

initUsageCollectors({
core,
kibanaIndex: core.savedObjects.getKibanaIndex(),
signalsIndex: config.signalsIndex,
ml: plugins.ml,
usageCollection: plugins.usageCollection,
});
Expand Down
180 changes: 3 additions & 177 deletions x-pack/plugins/security_solution/server/usage/collector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
* 2.0.
*/

import { CoreSetup, SavedObjectsClientContract } from '../../../../../src/core/server';
import { CollectorFetchContext } from '../../../../../src/plugins/usage_collection/server';
import { CollectorDependencies } from './types';
import { fetchDetectionsMetrics } from './detections';
Expand All @@ -15,19 +14,7 @@ export interface UsageData {
detectionMetrics: {};
}

export async function getInternalSavedObjectsClient(core: CoreSetup) {
return core.getStartServices().then(async ([coreStart]) => {
return coreStart.savedObjects.createInternalRepository();
});
}

export const registerCollector: RegisterCollector = ({
core,
kibanaIndex,
signalsIndex,
ml,
usageCollection,
}) => {
export const registerCollector: RegisterCollector = ({ ml, usageCollection }) => {
if (!usageCollection) {
return;
}
Expand All @@ -36,163 +23,6 @@ export const registerCollector: RegisterCollector = ({
type: 'security_solution',
schema: {
detectionMetrics: {
detection_rules: {
detection_rule_usage: {
query: {
enabled: { type: 'long', _meta: { description: 'Number of query rules enabled' } },
disabled: { type: 'long', _meta: { description: 'Number of query rules disabled' } },
alerts: {
type: 'long',
_meta: { description: 'Number of alerts generated by query rules' },
},
cases: {
type: 'long',
_meta: { description: 'Number of cases attached to query detection rule alerts' },
},
},
threshold: {
enabled: {
type: 'long',
_meta: { description: 'Number of threshold rules enabled' },
},
disabled: {
type: 'long',
_meta: { description: 'Number of threshold rules disabled' },
},
alerts: {
type: 'long',
_meta: { description: 'Number of alerts generated by threshold rules' },
},
cases: {
type: 'long',
_meta: {
description: 'Number of cases attached to threshold detection rule alerts',
},
},
},
eql: {
enabled: { type: 'long', _meta: { description: 'Number of eql rules enabled' } },
disabled: { type: 'long', _meta: { description: 'Number of eql rules disabled' } },
alerts: {
type: 'long',
_meta: { description: 'Number of alerts generated by eql rules' },
},
cases: {
type: 'long',
_meta: { description: 'Number of cases attached to eql detection rule alerts' },
},
},
machine_learning: {
enabled: {
type: 'long',
_meta: { description: 'Number of machine_learning rules enabled' },
},
disabled: {
type: 'long',
_meta: { description: 'Number of machine_learning rules disabled' },
},
alerts: {
type: 'long',
_meta: { description: 'Number of alerts generated by machine_learning rules' },
},
cases: {
type: 'long',
_meta: {
description: 'Number of cases attached to machine_learning detection rule alerts',
},
},
},
threat_match: {
enabled: {
type: 'long',
_meta: { description: 'Number of threat_match rules enabled' },
},
disabled: {
type: 'long',
_meta: { description: 'Number of threat_match rules disabled' },
},
alerts: {
type: 'long',
_meta: { description: 'Number of alerts generated by threat_match rules' },
},
cases: {
type: 'long',
_meta: {
description: 'Number of cases attached to threat_match detection rule alerts',
},
},
},
elastic_total: {
enabled: { type: 'long', _meta: { description: 'Number of elastic rules enabled' } },
disabled: {
type: 'long',
_meta: { description: 'Number of elastic rules disabled' },
},
alerts: {
type: 'long',
_meta: { description: 'Number of alerts generated by elastic rules' },
},
cases: {
type: 'long',
_meta: { description: 'Number of cases attached to elastic detection rule alerts' },
},
},
custom_total: {
enabled: { type: 'long', _meta: { description: 'Number of custom rules enabled' } },
disabled: { type: 'long', _meta: { description: 'Number of custom rules disabled' } },
alerts: {
type: 'long',
_meta: { description: 'Number of alerts generated by custom rules' },
},
cases: {
type: 'long',
_meta: { description: 'Number of cases attached to custom detection rule alerts' },
},
},
},
detection_rule_detail: {
type: 'array',
items: {
rule_name: {
type: 'keyword',
_meta: { description: 'The name of the detection rule' },
},
rule_id: {
type: 'keyword',
_meta: { description: 'The UUID id of the detection rule' },
},
rule_type: {
type: 'keyword',
_meta: { description: 'The type of detection rule. ie eql, query...' },
},
rule_version: { type: 'long', _meta: { description: 'The version of the rule' } },
enabled: {
type: 'boolean',
_meta: { description: 'If the detection rule has been enabled by the user' },
},
elastic_rule: {
type: 'boolean',
_meta: { description: 'If the detection rule has been authored by Elastic' },
},
created_on: {
type: 'keyword',
_meta: { description: 'When the detection rule was created on the cluster' },
},
updated_on: {
type: 'keyword',
_meta: { description: 'When the detection rule was updated on the cluster' },
},
alert_count_daily: {
type: 'long',
_meta: { description: 'The number of daily alerts generated by a rule' },
},
cases_count_total: {
type: 'long',
_meta: { description: 'The number of total cases generated by a rule' },
},
},
},
},
ml_jobs: {
ml_job_usage: {
custom: {
Expand Down Expand Up @@ -396,13 +226,9 @@ export const registerCollector: RegisterCollector = ({
},
},
isReady: () => true,
fetch: async ({ esClient }: CollectorFetchContext): Promise<UsageData> => {
const internalSavedObjectsClient = await getInternalSavedObjectsClient(core);
const soClient = internalSavedObjectsClient as unknown as SavedObjectsClientContract;

fetch: async ({ soClient }: CollectorFetchContext): Promise<UsageData> => {
return {
detectionMetrics:
(await fetchDetectionsMetrics(kibanaIndex, signalsIndex, esClient, soClient, ml)) || {},
detectionMetrics: (await fetchDetectionsMetrics(soClient, ml)) || {},
};
},
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@

import { initialMlJobsUsage, updateMlJobsUsage } from './detection_ml_helpers';

describe('Security Machine Learning usage metrics', () => {
describe('Security ML Usage Metrics', () => {
describe('Updates metrics with job information', () => {
it('Should update ML total for elastic rules', async () => {
it('Should update ML total for elastic jobs', async () => {
const initialUsage = initialMlJobsUsage;
const isElastic = true;
const isEnabled = true;
Expand All @@ -30,7 +30,7 @@ describe('Security Machine Learning usage metrics', () => {
);
});

it('Should update ML total for custom rules', async () => {
it('Should update ML total for custom jobs', async () => {
const initialUsage = initialMlJobsUsage;
const isElastic = false;
const isEnabled = true;
Expand All @@ -51,7 +51,7 @@ describe('Security Machine Learning usage metrics', () => {
);
});

it('Should update ML total for both elastic and custom rules', async () => {
it('Should update ML total for both elastic and custom jobs', async () => {
const initialUsage = initialMlJobsUsage;

let updatedUsage = updateMlJobsUsage({ isElastic: true, isEnabled: true }, initialUsage);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,12 @@
* 2.0.
*/

import { KibanaRequest, SavedObjectsClientContract } from '../../../../../../src/core/server';
import { KibanaRequest, SavedObjectsClientContract } from 'kibana/server';
import { DatafeedStats, Job, MlPluginSetup } from '../../../../ml/server';
import { isJobStarted } from '../../../common/machine_learning/helpers';
import { isSecurityJob } from '../../../common/machine_learning/is_security_job';
import { DetectionsMetric, MlJobMetric, MlJobsUsage, MlJobUsage } from './types';

/**
* Default ml job usage count
*/
export const initialMlJobsUsage: MlJobsUsage = {
custom: {
enabled: 0,
Expand Down Expand Up @@ -66,17 +63,17 @@ export const updateMlJobsUsage = (jobMetric: DetectionsMetric, usage: MlJobsUsag

export const getMlJobMetrics = async (
ml: MlPluginSetup | undefined,
savedObjectClient: SavedObjectsClientContract
soClient: SavedObjectsClientContract
): Promise<MlJobUsage> => {
let jobsUsage: MlJobsUsage = initialMlJobsUsage;

if (ml) {
try {
const fakeRequest = { headers: {} } as KibanaRequest;

const modules = await ml.modulesProvider(fakeRequest, savedObjectClient).listModules();
const modules = await ml.modulesProvider(fakeRequest, soClient).listModules();
const moduleJobs = modules.flatMap((module) => module.jobs);
const jobs = await ml.jobServiceProvider(fakeRequest, savedObjectClient).jobsSummary();
const jobs = await ml.jobServiceProvider(fakeRequest, soClient).jobsSummary();

jobsUsage = jobs.filter(isSecurityJob).reduce((usage, job) => {
const isElastic = moduleJobs.some((moduleJob) => moduleJob.id === job.id);
Expand All @@ -87,18 +84,16 @@ export const getMlJobMetrics = async (

const jobsType = 'security';
const securityJobStats = await ml
.anomalyDetectorsProvider(fakeRequest, savedObjectClient)
.anomalyDetectorsProvider(fakeRequest, soClient)
.jobStats(jobsType);

const jobDetails = await ml
.anomalyDetectorsProvider(fakeRequest, savedObjectClient)
.jobs(jobsType);
const jobDetails = await ml.anomalyDetectorsProvider(fakeRequest, soClient).jobs(jobsType);

const jobDetailsCache = new Map<string, Job>();
jobDetails.jobs.forEach((detail) => jobDetailsCache.set(detail.job_id, detail));

const datafeedStats = await ml
.anomalyDetectorsProvider(fakeRequest, savedObjectClient)
.anomalyDetectorsProvider(fakeRequest, soClient)
.datafeedStats();

const datafeedStatsCache = new Map<string, DatafeedStats>();
Expand Down
Loading