[Monitoring] Add Logstash monitoring feature
This PR adds UI for visualizing Logstash internal metrics with contributions from @ph, @jsvd and @pickypg Changes include: * x-pack component for Logstash which installs a monitoring exporter plugin to Logstash core. This periodically ships monitoring data to the monitoring bulk API endpoint. * Adds xpack.monitoring.* setting to logstash.yml when x-pack is installed. * UI changes to graph Logstash monitoring data. Logstash processes are called nodes. They send separate monitoring info which gets aggregated and displayed at cluster level and also at individual node level. * Adds gradle build support for Logstash x-pack which can be controled via `xpack.logstash.build=false` Fixes elastic/elasticsearch#4169 Original commit: elastic/x-pack-elasticsearch@f58ef406c1
This commit is contained in:
parent
37a29c0387
commit
2bce702f62
|
@ -51,7 +51,7 @@ gradle clean assemble
|
||||||
gradle clean install
|
gradle clean install
|
||||||
-----
|
-----
|
||||||
|
|
||||||
- If you don't work on the UI side of x-plugins, you can force gradle to skip building kibana by adding
|
- If you don't work on the UI/Logstash side of x-plugins, you can force gradle to skip building kibana and/or Logstash by adding
|
||||||
`xpack.kibana.build=false` to your `~/.gradle/gradle.properties`. Alternatively you add `-Pxpack.kibana.build=false`
|
`xpack.kibana.build=false`/`xpack.logstash.build=false` to your `~/.gradle/gradle.properties`. Alternatively you add `-Pxpack.kibana.build=false` or `-Pxpack.logstash.build=false`
|
||||||
on the command line if you only want to do this on individual builds (or `-Pxpack.kibana.build=true` if you need to
|
on the command line if you only want to do this on individual builds (or `-Pxpack.kibana.build=true` if you need to
|
||||||
override having added this to your `gradle.properties`).
|
override having added this to your `gradle.properties`).
|
||||||
|
|
|
@ -32,10 +32,13 @@ subprojects {
|
||||||
|
|
||||||
task bundlePack(type: Zip) {
|
task bundlePack(type: Zip) {
|
||||||
onlyIf { project('kibana').bundlePlugin.enabled }
|
onlyIf { project('kibana').bundlePlugin.enabled }
|
||||||
|
onlyIf { project('logstash').bundlePlugin.enabled }
|
||||||
dependsOn 'elasticsearch:bundlePlugin'
|
dependsOn 'elasticsearch:bundlePlugin'
|
||||||
dependsOn 'kibana:bundlePlugin'
|
dependsOn 'kibana:bundlePlugin'
|
||||||
|
dependsOn 'logstash:bundlePlugin'
|
||||||
from { zipTree(project('elasticsearch').bundlePlugin.outputs.files.singleFile) }
|
from { zipTree(project('elasticsearch').bundlePlugin.outputs.files.singleFile) }
|
||||||
from { zipTree(project('kibana').bundlePlugin.outputs.files.singleFile) }
|
from { zipTree(project('kibana').bundlePlugin.outputs.files.singleFile) }
|
||||||
|
from { zipTree(project('logstash').bundlePlugin.outputs.files.singleFile) }
|
||||||
destinationDir file('build/distributions')
|
destinationDir file('build/distributions')
|
||||||
baseName = 'x-pack'
|
baseName = 'x-pack'
|
||||||
version = VersionProperties.elasticsearch
|
version = VersionProperties.elasticsearch
|
||||||
|
|
|
@ -10,7 +10,8 @@ import java.util.Locale;
|
||||||
public enum MonitoredSystem {
|
public enum MonitoredSystem {
|
||||||
|
|
||||||
ES("es"),
|
ES("es"),
|
||||||
KIBANA("kibana");
|
KIBANA("kibana"),
|
||||||
|
LOGSTASH("logstash");
|
||||||
|
|
||||||
private final String system;
|
private final String system;
|
||||||
|
|
||||||
|
@ -28,6 +29,8 @@ public enum MonitoredSystem {
|
||||||
return ES;
|
return ES;
|
||||||
case "kibana":
|
case "kibana":
|
||||||
return KIBANA;
|
return KIBANA;
|
||||||
|
case "logstash":
|
||||||
|
return LOGSTASH;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unknown monitoring system [" + system + "]");
|
throw new IllegalArgumentException("Unknown monitoring system [" + system + "]");
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ public class ResolversRegistry implements Iterable<MonitoringIndexNameResolver>
|
||||||
|
|
||||||
// register resolvers for monitored systems
|
// register resolvers for monitored systems
|
||||||
registerMonitoredSystem(MonitoredSystem.KIBANA, settings);
|
registerMonitoredSystem(MonitoredSystem.KIBANA, settings);
|
||||||
|
registerMonitoredSystem(MonitoredSystem.LOGSTASH, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -18,6 +18,9 @@
|
||||||
},
|
},
|
||||||
"node": {
|
"node": {
|
||||||
"enabled": false
|
"enabled": false
|
||||||
|
},
|
||||||
|
"logstash": {
|
||||||
|
"enabled": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,211 @@
|
||||||
|
{
|
||||||
|
"template": ".monitoring-logstash-${monitoring.template.version}-*",
|
||||||
|
"settings": {
|
||||||
|
"index.number_of_shards": 1,
|
||||||
|
"index.number_of_replicas": 1,
|
||||||
|
"index.codec": "best_compression"
|
||||||
|
},
|
||||||
|
"mappings": {
|
||||||
|
"_default_": {
|
||||||
|
"_all": {
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"cluster_uuid": {
|
||||||
|
"type": "keyword"
|
||||||
|
},
|
||||||
|
"timestamp": {
|
||||||
|
"type": "date",
|
||||||
|
"format": "date_time"
|
||||||
|
},
|
||||||
|
"source_node": {
|
||||||
|
"properties": {
|
||||||
|
"uuid": {
|
||||||
|
"type": "keyword"
|
||||||
|
},
|
||||||
|
"host": {
|
||||||
|
"type": "keyword"
|
||||||
|
},
|
||||||
|
"transport_address": {
|
||||||
|
"type": "keyword"
|
||||||
|
},
|
||||||
|
"ip": {
|
||||||
|
"type": "keyword"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "keyword"
|
||||||
|
},
|
||||||
|
"attributes": {
|
||||||
|
"dynamic": true,
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"master": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"logstash_stats": {
|
||||||
|
"properties": {
|
||||||
|
"logstash_stats": {
|
||||||
|
"properties": {
|
||||||
|
"logstash": {
|
||||||
|
"properties": {
|
||||||
|
"uuid": {
|
||||||
|
"type": "keyword"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "keyword"
|
||||||
|
},
|
||||||
|
"host": {
|
||||||
|
"type": "keyword"
|
||||||
|
},
|
||||||
|
"http_address": {
|
||||||
|
"type": "keyword"
|
||||||
|
},
|
||||||
|
"version": {
|
||||||
|
"type": "keyword"
|
||||||
|
},
|
||||||
|
"snapshot": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"type": "keyword"
|
||||||
|
},
|
||||||
|
"pipeline": {
|
||||||
|
"properties": {
|
||||||
|
"workers": {
|
||||||
|
"type": "short"
|
||||||
|
},
|
||||||
|
"batch_size": {
|
||||||
|
"type": "long"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"events": {
|
||||||
|
"properties": {
|
||||||
|
"filtered": {
|
||||||
|
"type": "long"
|
||||||
|
},
|
||||||
|
"in": {
|
||||||
|
"type": "long"
|
||||||
|
},
|
||||||
|
"out": {
|
||||||
|
"type": "long"
|
||||||
|
},
|
||||||
|
"duration_in_millis": {
|
||||||
|
"type": "long"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"timestamp": {
|
||||||
|
"type": "date"
|
||||||
|
},
|
||||||
|
"jvm": {
|
||||||
|
"properties": {
|
||||||
|
"uptime_in_millis": {
|
||||||
|
"type": "long"
|
||||||
|
},
|
||||||
|
"gc": {
|
||||||
|
"properties": {
|
||||||
|
"collectors": {
|
||||||
|
"properties": {
|
||||||
|
"old": {
|
||||||
|
"properties": {
|
||||||
|
"collection_count": {
|
||||||
|
"type": "long"
|
||||||
|
},
|
||||||
|
"collection_time_in_millis": {
|
||||||
|
"type": "long"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"young": {
|
||||||
|
"properties": {
|
||||||
|
"collection_count": {
|
||||||
|
"type": "long"
|
||||||
|
},
|
||||||
|
"collection_time_in_millis": {
|
||||||
|
"type": "long"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mem": {
|
||||||
|
"properties": {
|
||||||
|
"heap_max_in_bytes": {
|
||||||
|
"type": "long"
|
||||||
|
},
|
||||||
|
"heap_used_in_bytes": {
|
||||||
|
"type": "long"
|
||||||
|
},
|
||||||
|
"heap_used_percent": {
|
||||||
|
"type": "long"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"os": {
|
||||||
|
"properties": {
|
||||||
|
"load": {
|
||||||
|
"properties": {
|
||||||
|
"1m": {
|
||||||
|
"type": "half_float"
|
||||||
|
},
|
||||||
|
"5m": {
|
||||||
|
"type": "half_float"
|
||||||
|
},
|
||||||
|
"15m": {
|
||||||
|
"type": "half_float"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"process": {
|
||||||
|
"properties": {
|
||||||
|
"cpu": {
|
||||||
|
"properties": {
|
||||||
|
"percent": {
|
||||||
|
"type": "long"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"max_file_descriptors": {
|
||||||
|
"type": "long"
|
||||||
|
},
|
||||||
|
"open_file_descriptors": {
|
||||||
|
"type": "long"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"reloads": {
|
||||||
|
"properties": {
|
||||||
|
"failures": {
|
||||||
|
"type": "long"
|
||||||
|
},
|
||||||
|
"successes": {
|
||||||
|
"type": "long"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.xpack.monitoring;
|
||||||
|
|
||||||
|
import org.elasticsearch.test.ESTestCase;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests {@link MonitoredSystem}.
|
||||||
|
*/
|
||||||
|
public class MonitoredSystemTests extends ESTestCase {
|
||||||
|
|
||||||
|
public void testGetSystem() {
|
||||||
|
// everything is just lowercased...
|
||||||
|
for (final MonitoredSystem system : MonitoredSystem.values()) {
|
||||||
|
assertEquals(system.name().toLowerCase(Locale.ROOT), system.getSystem());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testFromSystem() {
|
||||||
|
for (final MonitoredSystem system : MonitoredSystem.values()) {
|
||||||
|
final String lowercased = system.name().toLowerCase(Locale.ROOT);
|
||||||
|
|
||||||
|
assertSame(system, MonitoredSystem.fromSystem(system.name()));
|
||||||
|
assertSame(system, MonitoredSystem.fromSystem(lowercased));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testFromUnknownSystem() {
|
||||||
|
final String unknownSystem = randomAsciiOfLengthBetween(3, 4);
|
||||||
|
|
||||||
|
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> {
|
||||||
|
MonitoredSystem.fromSystem(unknownSystem);
|
||||||
|
});
|
||||||
|
|
||||||
|
assertThat(e.getMessage(), containsString(unknownSystem));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -37,7 +37,7 @@ import static org.mockito.Mockito.when;
|
||||||
*/
|
*/
|
||||||
public class HttpExporterResourceTests extends AbstractPublishableHttpResourceTestCase {
|
public class HttpExporterResourceTests extends AbstractPublishableHttpResourceTestCase {
|
||||||
|
|
||||||
private final int EXPECTED_TEMPLATES = 3;
|
private final int EXPECTED_TEMPLATES = 4;
|
||||||
|
|
||||||
private final RestClient client = mock(RestClient.class);
|
private final RestClient client = mock(RestClient.class);
|
||||||
private final Response versionResponse = mock(Response.class);
|
private final Response versionResponse = mock(Response.class);
|
||||||
|
|
|
@ -300,7 +300,7 @@ public class HttpExporterTests extends ESTestCase {
|
||||||
// expected number of resources
|
// expected number of resources
|
||||||
assertThat(multiResource.getResources().size(), equalTo(version + templates.size() + pipelines.size() + bwc.size()));
|
assertThat(multiResource.getResources().size(), equalTo(version + templates.size() + pipelines.size() + bwc.size()));
|
||||||
assertThat(version, equalTo(1));
|
assertThat(version, equalTo(1));
|
||||||
assertThat(templates, hasSize(3));
|
assertThat(templates, hasSize(4));
|
||||||
assertThat(pipelines, hasSize(useIngest ? 1 : 0));
|
assertThat(pipelines, hasSize(useIngest ? 1 : 0));
|
||||||
assertThat(bwc, hasSize(1));
|
assertThat(bwc, hasSize(1));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue