Skip to content

Commit

Permalink
[Ingest] Allow to enable monitoring of elastic agent
Browse files Browse the repository at this point in the history
  • Loading branch information
nchaulet committed Apr 15, 2020
1 parent c2f2a79 commit 5d030c3
Show file tree
Hide file tree
Showing 6 changed files with 227 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export interface NewAgentConfig {
namespace?: string;
description?: string;
is_default?: boolean;
monitoring_enabled?: Array<'logs' | 'metrics'>;
}

export interface AgentConfig extends NewAgentConfig, SavedObjectAttributes {
Expand Down Expand Up @@ -58,4 +59,10 @@ export interface FullAgentConfig {
};
datasources: FullAgentConfigDatasource[];
revision?: number;
'settings.monitoring'?: {
use_output: string;
enabled: boolean;
metrics: boolean;
logs: boolean;
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ interface ValidationResults {

const StyledEuiAccordion = styled(EuiAccordion)`
.ingest-active-button {
color: ${props => props.theme.eui.euiColorPrimary}};
color: ${props => props.theme.eui.euiColorPrimary};
}
`;

Expand Down Expand Up @@ -244,6 +244,71 @@ export const AgentConfigForm: React.FunctionComponent<Props> = ({
)}
</EuiFlexItem>
</EuiFlexGroup>
<EuiFlexGroup>
<EuiFlexItem>
<EuiText>
<h4>
<FormattedMessage
id="xpack.ingestManager.agentConfigForm.monitoringLabel"
defaultMessage="Monitor Elastic agent"
/>
</h4>
</EuiText>
</EuiFlexItem>
<EuiFlexItem>
<EuiSwitch
showLabel={true}
label={
<FormattedMessage
id="xpack.ingestManager.agentConfigForm.monitoringLogsFieldLabel"
defaultMessage="Collect agent logs"
/>
}
checked={
agentConfig.monitoring_enabled !== undefined &&
agentConfig.monitoring_enabled.indexOf('logs') >= 0
}
onChange={() => {
const hasLogs =
agentConfig.monitoring_enabled &&
agentConfig.monitoring_enabled.indexOf('logs') >= 0;

const previousValues = agentConfig.monitoring_enabled || [];
updateAgentConfig({
monitoring_enabled: hasLogs
? previousValues.filter(type => type !== 'logs')
: [...previousValues, 'logs'],
});
}}
/>
<EuiSpacer size="m" />
<EuiSwitch
showLabel={true}
label={
<FormattedMessage
id="xpack.ingestManager.agentConfigForm.monitoringMetricsFieldLabel"
defaultMessage="Collect agent metrics"
/>
}
checked={
agentConfig.monitoring_enabled !== undefined &&
agentConfig.monitoring_enabled.indexOf('metrics') >= 0
}
onChange={() => {
const hasMetrics =
agentConfig.monitoring_enabled &&
agentConfig.monitoring_enabled.indexOf('metrics') >= 0;

const previousValues = agentConfig.monitoring_enabled || [];
updateAgentConfig({
monitoring_enabled: hasMetrics
? previousValues.filter(type => type !== 'metrics')
: [...previousValues, 'metrics'],
});
}}
/>
</EuiFlexItem>
</EuiFlexGroup>
</StyledEuiAccordion>
</EuiForm>
);
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/ingest_manager/server/saved_objects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export const savedObjectMappings = {
updated_on: { type: 'keyword' },
updated_by: { type: 'keyword' },
revision: { type: 'integer' },
monitoring_enabled: { type: 'keyword' },
},
},
[ENROLLMENT_API_KEYS_SAVED_OBJECT_TYPE]: {
Expand Down
123 changes: 123 additions & 0 deletions x-pack/plugins/ingest_manager/server/services/agent_config.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* 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 { agentConfigService } from './agent_config';
import { savedObjectsClientMock } from '../../../../../src/core/server/saved_objects/service/saved_objects_client.mock';
import { Output } from '../types';

function getSavedObjectMock(configAttributes: any) {
const mock = savedObjectsClientMock.create();

mock.get.mockImplementation(async (type: string, id: string) => {
return {
type,
id,
references: [],
attributes: configAttributes,
};
});

return mock;
}

jest.mock('./output', () => {
return {
outputService: {
getDefaultOutputId: () => 'test-id',
get: (): Output => {
return {
id: 'test-id',
is_default: true,
name: 'default',
// @ts-ignore
type: 'elasticsearch',
hosts: ['http://127.0.0.1:9201'],
};
},
},
};
});

describe('agent config', () => {
describe('getFullConfig', () => {
it('should return a config without monitoring if not monitoring is not enabled', async () => {
const soClient = getSavedObjectMock({
revision: 1,
});
const config = await agentConfigService.getFullConfig(soClient, 'config');

expect(config).toMatchObject({
id: 'config',
outputs: {
default: {
type: 'elasticsearch',
hosts: ['http://127.0.0.1:9201'],
ca_sha256: undefined,
api_key: undefined,
},
},
datasources: [],
revision: 1,
});
});

it('should return a config with monitoring if monitoring is enabled for logs', async () => {
const soClient = getSavedObjectMock({
revision: 1,
monitoring_enabled: ['logs'],
});
const config = await agentConfigService.getFullConfig(soClient, 'config');

expect(config).toMatchObject({
id: 'config',
outputs: {
default: {
type: 'elasticsearch',
hosts: ['http://127.0.0.1:9201'],
ca_sha256: undefined,
api_key: undefined,
},
},
datasources: [],
revision: 1,
'settings.monitoring': {
use_output: 'default',
enabled: true,
logs: true,
metrics: false,
},
});
});

it('should return a config with monitoring if monitoring is enabled for metrics', async () => {
const soClient = getSavedObjectMock({
revision: 1,
monitoring_enabled: ['metrics'],
});
const config = await agentConfigService.getFullConfig(soClient, 'config');

expect(config).toMatchObject({
id: 'config',
outputs: {
default: {
type: 'elasticsearch',
hosts: ['http://127.0.0.1:9201'],
ca_sha256: undefined,
api_key: undefined,
},
},
datasources: [],
revision: 1,
'settings.monitoring': {
use_output: 'default',
enabled: true,
logs: false,
metrics: true,
},
});
});
});
});
39 changes: 27 additions & 12 deletions x-pack/plugins/ingest_manager/server/services/agent_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,28 +301,43 @@ class AgentConfigService {
if (!config) {
return null;
}
const defaultOutput = await outputService.get(
soClient,
await outputService.getDefaultOutputId(soClient)
);

const agentConfig: FullAgentConfig = {
id: config.id,
outputs: {
// TEMPORARY as we only support a default output
...[
await outputService.get(soClient, await outputService.getDefaultOutputId(soClient)),
].reduce((outputs, { config: outputConfig, name, type, hosts, ca_sha256, api_key }) => {
outputs[name] = {
type,
hosts,
ca_sha256,
api_key,
...outputConfig,
};
return outputs;
}, {} as FullAgentConfig['outputs']),
...[defaultOutput].reduce(
(outputs, { config: outputConfig, name, type, hosts, ca_sha256, api_key }) => {
outputs[name] = {
type,
hosts,
ca_sha256,
api_key,
...outputConfig,
};
return outputs;
},
{} as FullAgentConfig['outputs']
),
},
datasources: (config.datasources as Datasource[])
.filter(datasource => datasource.enabled)
.map(ds => storedDatasourceToAgentDatasource(ds)),
revision: config.revision,
...(config.monitoring_enabled && config.monitoring_enabled.length > 0
? {
'settings.monitoring': {
use_output: defaultOutput.name,
enabled: true,
logs: config.monitoring_enabled.indexOf('logs') >= 0,
metrics: config.monitoring_enabled.indexOf('metrics') >= 0,
},
}
: {}),
};

return agentConfig;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ const AgentConfigBaseSchema = {
name: schema.string(),
namespace: schema.maybe(schema.string()),
description: schema.maybe(schema.string()),
monitoring_enabled: schema.maybe(
schema.arrayOf(schema.oneOf([schema.literal('logs'), schema.literal('metrics')]))
),
};

export const NewAgentConfigSchema = schema.object({
Expand Down

0 comments on commit 5d030c3

Please sign in to comment.