ElasticsearchReporter extends ScheduledMetrics2Reporter { @Override public void reportMetrics(final Map<MetricName, Gauge> gauges, final Map<MetricName, Counter> counters, final Map<MetricName, Histogram> histograms, final Map<MetricName, Meter> meters, final Map<MetricName, Timer> timers) { if (!corePlugin.isStagemonitorActive()) { return; } long timestamp = clock.getTime(); final Timer.Context time = registry.timer(reportingTimeMetricName).time(); final MetricsOutputStreamHandler metricsOutputStreamHandler = new MetricsOutputStreamHandler(gauges, counters, histograms, meters, timers, timestamp); if (!corePlugin.isOnlyLogElasticsearchMetricReports()) { if (!elasticsearchClient.isElasticsearchAvailable()) { return; } final String url = corePlugin.getElasticsearchUrl() + "/" + getTodaysIndexName() + "/" + METRICS_TYPE + "/_bulk"; httpClient.send("POST", url, CONTENT_TYPE_JSON, metricsOutputStreamHandler, NoopResponseHandler.INSTANCE); } else { try { final ByteArrayOutputStream os = new ByteArrayOutputStream(); metricsOutputStreamHandler.withHttpURLConnection(os); elasticsearchMetricsLogger.info(os.toString("UTF-8")); } catch (IOException e) { logger.warn(e.getMessage(), e); } } time.stop(); } private  ElasticsearchReporter(Builder builder); static ElasticsearchReporter.Builder forRegistry(Metric2Registry registry, CorePlugin corePlugin); @Override void reportMetrics(final Map<MetricName, Gauge> gauges,
							  final Map<MetricName, Counter> counters,
							  final Map<MetricName, Histogram> histograms,
							  final Map<MetricName, Meter> meters,
							  final Map<MetricName, Timer> timers); void reportMetrics(Map<MetricName, Gauge> gauges, Map<MetricName, Counter> counters,
							  Map<MetricName, Histogram> histograms, final Map<MetricName, Meter> meters,
							  Map<MetricName, Timer> timers, OutputStream os, byte[] bulkActionBytes, long timestamp); static String getTodaysIndexName(); static final String STAGEMONITOR_METRICS_INDEX_PREFIX; static final String ES_METRICS_LOGGER; }
@Test public void testReportGauges() throws Exception { elasticsearchReporter.reportMetrics( metricNameMap( name("cpu_usage").type("user").tag("core", "1").build(), gauge(3) ), metricNameMap(Counter.class), metricNameMap(Histogram.class), metricNameMap(Meter.class), metricNameMap(Timer.class)); final String jsons = new String(out.toByteArray()); assertEquals(jsons, 2, jsons.split("\n").length); assertEquals( objectMap("index", map("_type", "metrics") .add("_index", "stagemonitor-metrics-" + StringUtils.getLogstashStyleDate())), asMap(jsons.split("\n")[0])); assertEquals( objectMap("@timestamp", timestamp) .add("name", "cpu_usage") .add("app", "test") .add("type", "user") .add("core", "1") .add("value", 3.0), asMap(jsons.split("\n")[1])); }
@Test public void testReportNullGauge() throws Exception { elasticsearchReporter.reportMetrics( metricNameMap(name("gauge").build(), gauge(null)), metricNameMap(Counter.class), metricNameMap(Histogram.class), metricNameMap(Meter.class), metricNameMap(Timer.class)); assertEquals( objectMap("@timestamp", timestamp) .add("name", "gauge") .add("app", "test"), asMap(out)); }
@Test public void testReportToLog() throws Exception { when(corePlugin.isOnlyLogElasticsearchMetricReports()).thenReturn(true); elasticsearchReporter.reportMetrics( metricNameMap(name("gauge").build(), gauge(1)), metricNameMap(Counter.class), metricNameMap(Histogram.class), metricNameMap(Meter.class), metricNameMap(Timer.class)); verify(metricsLogger).info(eq(String.format("{\"index\":{\"_index\":\"stagemonitor-metrics-%s\",\"_type\":\"metrics\"}}\n" + "{\"@timestamp\":%d,\"name\":\"gauge\",\"app\":\"test\",\"value\":1.0}\n", StringUtils.getLogstashStyleDate(), timestamp))); }
@Test public void testReportBooleanGauge() throws Exception { elasticsearchReporter.reportMetrics( metricNameMap(name("gauge").build(), gauge(true)), metricNameMap(Counter.class), metricNameMap(Histogram.class), metricNameMap(Meter.class), metricNameMap(Timer.class)); assertEquals( objectMap("@timestamp", timestamp) .add("name", "gauge") .add("app", "test") .add("value_boolean", true), asMap(out)); }
@Test public void testReportStringGauge() throws Exception { elasticsearchReporter.reportMetrics( metricNameMap(name("gauge").build(), gauge("foo")), metricNameMap(Counter.class), metricNameMap(Histogram.class), metricNameMap(Meter.class), metricNameMap(Timer.class)); assertEquals( objectMap("@timestamp", timestamp) .add("name", "gauge") .add("app", "test") .add("value_string", "foo"), asMap(out)); }
@Test public void testReportCounters() throws Exception { elasticsearchReporter.reportMetrics( metricNameMap(Gauge.class), metricNameMap(name("web_sessions").build(), counter(123)), metricNameMap(Histogram.class), metricNameMap(Meter.class), metricNameMap(Timer.class)); assertEquals( map("@timestamp", timestamp, Object.class) .add("name", "web_sessions") .add("app", "test") .add("count", 123), asMap(out)); }
@Test public void testReportHistograms() throws Exception { elasticsearchReporter.reportMetrics( metricNameMap(Gauge.class), metricNameMap(Counter.class), metricNameMap(name("histogram").build(), histogram(400)), metricNameMap(Meter.class), metricNameMap(Timer.class)); assertEquals(objectMap("@timestamp", timestamp) .add("name", "histogram") .add("app", "test") .add("count", 1) .add("max", 200.0) .add("mean", 400.0) .add("p50", 600.0) .add("min", 400.0) .add("p25", 0.0) .add("p75", 700.0) .add("p95", 800.0) .add("p98", 900.0) .add("p99", 1000.0) .add("p999", 1100.0) .add("std", 500.0), asMap(out)); }
@Test public void testReportMeters() throws Exception { elasticsearchReporter.reportMetrics( metricNameMap(Gauge.class), metricNameMap(Counter.class), metricNameMap(Histogram.class), metricNameMap(name("meter").build(), meter(10)), metricNameMap(Timer.class)); assertEquals(map("@timestamp", timestamp, Object.class) .add("name", "meter") .add("app", "test") .add("count", 10) .add("m15_rate", 5.0) .add("m1_rate", 3.0) .add("m5_rate", 4.0) .add("mean_rate", 2.0), asMap(out)); }
@Test public void testReportTimers() throws Exception { elasticsearchReporter.reportMetrics( metricNameMap(Gauge.class), metricNameMap(Counter.class), metricNameMap(Histogram.class), metricNameMap(Meter.class), metricNameMap(name("response_time").build(), timer(400))); assertEquals(map("@timestamp", timestamp, Object.class) .add("name", "response_time") .add("app", "test") .add("count", 1) .add("m15_rate", 5.0) .add("m1_rate", 3.0) .add("m5_rate", 4.0) .add("mean_rate", 2.0) .add("max", 200.0 * DURATION_FACTOR) .add("mean", 400.0 * DURATION_FACTOR) .add("p50", 600.0 * DURATION_FACTOR) .add("min", 400.0 * DURATION_FACTOR) .add("p25", 0.0 * DURATION_FACTOR) .add("p75", 700.0 * DURATION_FACTOR) .add("p95", 800.0 * DURATION_FACTOR) .add("p98", 900.0 * DURATION_FACTOR) .add("p99", 1000.0 * DURATION_FACTOR) .add("p999", 1100.0 * DURATION_FACTOR) .add("std", 500.0 * DURATION_FACTOR), asMap(out)); }