Skip to content

Commit 5d030c3

Browse files
committed
[Ingest] Allow to enable monitoring of elastic agent
1 parent c2f2a79 commit 5d030c3

File tree

6 files changed

+227
-13
lines changed

6 files changed

+227
-13
lines changed

x-pack/plugins/ingest_manager/common/types/models/agent_config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export interface NewAgentConfig {
2323
namespace?: string;
2424
description?: string;
2525
is_default?: boolean;
26+
monitoring_enabled?: Array<'logs' | 'metrics'>;
2627
}
2728

2829
export interface AgentConfig extends NewAgentConfig, SavedObjectAttributes {
@@ -58,4 +59,10 @@ export interface FullAgentConfig {
5859
};
5960
datasources: FullAgentConfigDatasource[];
6061
revision?: number;
62+
'settings.monitoring'?: {
63+
use_output: string;
64+
enabled: boolean;
65+
metrics: boolean;
66+
logs: boolean;
67+
};
6168
}

x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/components/config_form.tsx

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ interface ValidationResults {
3030

3131
const StyledEuiAccordion = styled(EuiAccordion)`
3232
.ingest-active-button {
33-
color: ${props => props.theme.eui.euiColorPrimary}};
33+
color: ${props => props.theme.eui.euiColorPrimary};
3434
}
3535
`;
3636

@@ -244,6 +244,71 @@ export const AgentConfigForm: React.FunctionComponent<Props> = ({
244244
)}
245245
</EuiFlexItem>
246246
</EuiFlexGroup>
247+
<EuiFlexGroup>
248+
<EuiFlexItem>
249+
<EuiText>
250+
<h4>
251+
<FormattedMessage
252+
id="xpack.ingestManager.agentConfigForm.monitoringLabel"
253+
defaultMessage="Monitor Elastic agent"
254+
/>
255+
</h4>
256+
</EuiText>
257+
</EuiFlexItem>
258+
<EuiFlexItem>
259+
<EuiSwitch
260+
showLabel={true}
261+
label={
262+
<FormattedMessage
263+
id="xpack.ingestManager.agentConfigForm.monitoringLogsFieldLabel"
264+
defaultMessage="Collect agent logs"
265+
/>
266+
}
267+
checked={
268+
agentConfig.monitoring_enabled !== undefined &&
269+
agentConfig.monitoring_enabled.indexOf('logs') >= 0
270+
}
271+
onChange={() => {
272+
const hasLogs =
273+
agentConfig.monitoring_enabled &&
274+
agentConfig.monitoring_enabled.indexOf('logs') >= 0;
275+
276+
const previousValues = agentConfig.monitoring_enabled || [];
277+
updateAgentConfig({
278+
monitoring_enabled: hasLogs
279+
? previousValues.filter(type => type !== 'logs')
280+
: [...previousValues, 'logs'],
281+
});
282+
}}
283+
/>
284+
<EuiSpacer size="m" />
285+
<EuiSwitch
286+
showLabel={true}
287+
label={
288+
<FormattedMessage
289+
id="xpack.ingestManager.agentConfigForm.monitoringMetricsFieldLabel"
290+
defaultMessage="Collect agent metrics"
291+
/>
292+
}
293+
checked={
294+
agentConfig.monitoring_enabled !== undefined &&
295+
agentConfig.monitoring_enabled.indexOf('metrics') >= 0
296+
}
297+
onChange={() => {
298+
const hasMetrics =
299+
agentConfig.monitoring_enabled &&
300+
agentConfig.monitoring_enabled.indexOf('metrics') >= 0;
301+
302+
const previousValues = agentConfig.monitoring_enabled || [];
303+
updateAgentConfig({
304+
monitoring_enabled: hasMetrics
305+
? previousValues.filter(type => type !== 'metrics')
306+
: [...previousValues, 'metrics'],
307+
});
308+
}}
309+
/>
310+
</EuiFlexItem>
311+
</EuiFlexGroup>
247312
</StyledEuiAccordion>
248313
</EuiForm>
249314
);

x-pack/plugins/ingest_manager/server/saved_objects.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ export const savedObjectMappings = {
7777
updated_on: { type: 'keyword' },
7878
updated_by: { type: 'keyword' },
7979
revision: { type: 'integer' },
80+
monitoring_enabled: { type: 'keyword' },
8081
},
8182
},
8283
[ENROLLMENT_API_KEYS_SAVED_OBJECT_TYPE]: {
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
import { agentConfigService } from './agent_config';
8+
import { savedObjectsClientMock } from '../../../../../src/core/server/saved_objects/service/saved_objects_client.mock';
9+
import { Output } from '../types';
10+
11+
function getSavedObjectMock(configAttributes: any) {
12+
const mock = savedObjectsClientMock.create();
13+
14+
mock.get.mockImplementation(async (type: string, id: string) => {
15+
return {
16+
type,
17+
id,
18+
references: [],
19+
attributes: configAttributes,
20+
};
21+
});
22+
23+
return mock;
24+
}
25+
26+
jest.mock('./output', () => {
27+
return {
28+
outputService: {
29+
getDefaultOutputId: () => 'test-id',
30+
get: (): Output => {
31+
return {
32+
id: 'test-id',
33+
is_default: true,
34+
name: 'default',
35+
// @ts-ignore
36+
type: 'elasticsearch',
37+
hosts: ['http://127.0.0.1:9201'],
38+
};
39+
},
40+
},
41+
};
42+
});
43+
44+
describe('agent config', () => {
45+
describe('getFullConfig', () => {
46+
it('should return a config without monitoring if not monitoring is not enabled', async () => {
47+
const soClient = getSavedObjectMock({
48+
revision: 1,
49+
});
50+
const config = await agentConfigService.getFullConfig(soClient, 'config');
51+
52+
expect(config).toMatchObject({
53+
id: 'config',
54+
outputs: {
55+
default: {
56+
type: 'elasticsearch',
57+
hosts: ['http://127.0.0.1:9201'],
58+
ca_sha256: undefined,
59+
api_key: undefined,
60+
},
61+
},
62+
datasources: [],
63+
revision: 1,
64+
});
65+
});
66+
67+
it('should return a config with monitoring if monitoring is enabled for logs', async () => {
68+
const soClient = getSavedObjectMock({
69+
revision: 1,
70+
monitoring_enabled: ['logs'],
71+
});
72+
const config = await agentConfigService.getFullConfig(soClient, 'config');
73+
74+
expect(config).toMatchObject({
75+
id: 'config',
76+
outputs: {
77+
default: {
78+
type: 'elasticsearch',
79+
hosts: ['http://127.0.0.1:9201'],
80+
ca_sha256: undefined,
81+
api_key: undefined,
82+
},
83+
},
84+
datasources: [],
85+
revision: 1,
86+
'settings.monitoring': {
87+
use_output: 'default',
88+
enabled: true,
89+
logs: true,
90+
metrics: false,
91+
},
92+
});
93+
});
94+
95+
it('should return a config with monitoring if monitoring is enabled for metrics', async () => {
96+
const soClient = getSavedObjectMock({
97+
revision: 1,
98+
monitoring_enabled: ['metrics'],
99+
});
100+
const config = await agentConfigService.getFullConfig(soClient, 'config');
101+
102+
expect(config).toMatchObject({
103+
id: 'config',
104+
outputs: {
105+
default: {
106+
type: 'elasticsearch',
107+
hosts: ['http://127.0.0.1:9201'],
108+
ca_sha256: undefined,
109+
api_key: undefined,
110+
},
111+
},
112+
datasources: [],
113+
revision: 1,
114+
'settings.monitoring': {
115+
use_output: 'default',
116+
enabled: true,
117+
logs: false,
118+
metrics: true,
119+
},
120+
});
121+
});
122+
});
123+
});

x-pack/plugins/ingest_manager/server/services/agent_config.ts

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -301,28 +301,43 @@ class AgentConfigService {
301301
if (!config) {
302302
return null;
303303
}
304+
const defaultOutput = await outputService.get(
305+
soClient,
306+
await outputService.getDefaultOutputId(soClient)
307+
);
304308

305309
const agentConfig: FullAgentConfig = {
306310
id: config.id,
307311
outputs: {
308312
// TEMPORARY as we only support a default output
309-
...[
310-
await outputService.get(soClient, await outputService.getDefaultOutputId(soClient)),
311-
].reduce((outputs, { config: outputConfig, name, type, hosts, ca_sha256, api_key }) => {
312-
outputs[name] = {
313-
type,
314-
hosts,
315-
ca_sha256,
316-
api_key,
317-
...outputConfig,
318-
};
319-
return outputs;
320-
}, {} as FullAgentConfig['outputs']),
313+
...[defaultOutput].reduce(
314+
(outputs, { config: outputConfig, name, type, hosts, ca_sha256, api_key }) => {
315+
outputs[name] = {
316+
type,
317+
hosts,
318+
ca_sha256,
319+
api_key,
320+
...outputConfig,
321+
};
322+
return outputs;
323+
},
324+
{} as FullAgentConfig['outputs']
325+
),
321326
},
322327
datasources: (config.datasources as Datasource[])
323328
.filter(datasource => datasource.enabled)
324329
.map(ds => storedDatasourceToAgentDatasource(ds)),
325330
revision: config.revision,
331+
...(config.monitoring_enabled && config.monitoring_enabled.length > 0
332+
? {
333+
'settings.monitoring': {
334+
use_output: defaultOutput.name,
335+
enabled: true,
336+
logs: config.monitoring_enabled.indexOf('logs') >= 0,
337+
metrics: config.monitoring_enabled.indexOf('metrics') >= 0,
338+
},
339+
}
340+
: {}),
326341
};
327342

328343
return agentConfig;

x-pack/plugins/ingest_manager/server/types/models/agent_config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ const AgentConfigBaseSchema = {
1111
name: schema.string(),
1212
namespace: schema.maybe(schema.string()),
1313
description: schema.maybe(schema.string()),
14+
monitoring_enabled: schema.maybe(
15+
schema.arrayOf(schema.oneOf([schema.literal('logs'), schema.literal('metrics')]))
16+
),
1417
};
1518

1619
export const NewAgentConfigSchema = schema.object({

0 commit comments

Comments
 (0)