summaryrefslogtreecommitdiffstats
path: root/configserver/src/main/java/com/yahoo/vespa/config/server/monitoring/Metrics.java
diff options
context:
space:
mode:
Diffstat (limited to 'configserver/src/main/java/com/yahoo/vespa/config/server/monitoring/Metrics.java')
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/monitoring/Metrics.java140
1 files changed, 140 insertions, 0 deletions
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/monitoring/Metrics.java b/configserver/src/main/java/com/yahoo/vespa/config/server/monitoring/Metrics.java
new file mode 100644
index 00000000000..d0984baefc2
--- /dev/null
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/monitoring/Metrics.java
@@ -0,0 +1,140 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.config.server.monitoring;
+
+import com.google.inject.Inject;
+import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.TenantName;
+import com.yahoo.container.jdisc.config.HealthMonitorConfig;
+import com.yahoo.docproc.jdisc.metric.NullMetric;
+import com.yahoo.jdisc.Metric;
+import com.yahoo.log.LogLevel;
+import com.yahoo.statistics.Statistics;
+import com.yahoo.statistics.Counter;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Statistics for server. The statistics framework takes care of logging.
+ *
+ * @author Harald Musum
+ * @since 4.2
+ */
+public class Metrics extends TimerTask implements MetricUpdaterFactory {
+ private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(Metrics.class.getName());
+ private static final String METRIC_REQUESTS = getMetricName("requests");
+ private static final String METRIC_FAILED_REQUESTS = getMetricName("failedRequests");
+ private static final String METRIC_FREE_MEMORY = getMetricName("freeMemory");
+ private static final String METRIC_LATENCY = getMetricName("latency");
+
+ private final Counter requests;
+ private final Counter failedRequests;
+ private final Counter procTimeCounter;
+ private final Metric metric;
+
+ // TODO The map is the key for now
+ private final Map<Map<String, String>, MetricUpdater> metricUpdaters = new ConcurrentHashMap<>();
+ private final Timer timer = new Timer();
+
+ @Inject
+ public Metrics(Metric metric, Statistics statistics, HealthMonitorConfig healthMonitorConfig) {
+ this.metric = metric;
+ requests = createCounter(METRIC_REQUESTS, statistics);
+ failedRequests = createCounter(METRIC_FAILED_REQUESTS, statistics);
+ procTimeCounter = createCounter("procTime", statistics);
+ timer.scheduleAtFixedRate(this, 5000, (long) (healthMonitorConfig.snapshot_interval() * 1000));
+ log.log(LogLevel.DEBUG, "Metric update interval is " + healthMonitorConfig.snapshot_interval() + " seconds");
+ }
+
+ public static Metrics createTestMetrics() {
+ NullMetric metric = new NullMetric();
+ Statistics.NullImplementation statistics = new Statistics.NullImplementation();
+ HealthMonitorConfig.Builder builder = new HealthMonitorConfig.Builder();
+ builder.snapshot_interval(60.0);
+ return new Metrics(metric, statistics, new HealthMonitorConfig(builder));
+ }
+
+ private Counter createCounter(String name, Statistics statistics) {
+ return new Counter(name, statistics, false);
+ }
+
+
+ void incrementRequests(Metric.Context metricContext) {
+ requests.increment(1);
+ metric.add(METRIC_REQUESTS, 1, metricContext);
+ }
+
+ void incrementFailedRequests(Metric.Context metricContext) {
+ failedRequests.increment(1);
+ metric.add(METRIC_FAILED_REQUESTS, 1, metricContext);
+ }
+
+ void incrementProcTime(long increment, Metric.Context metricContext) {
+ procTimeCounter.increment(increment);
+ metric.set(METRIC_LATENCY, increment, metricContext);
+ }
+
+ public long getRequests() {
+ return requests.get();
+ }
+
+ public Metric getMetric() {
+ return metric;
+ }
+
+ public MetricUpdater removeMetricUpdater(Map<String, String> dimensions) {
+ return metricUpdaters.remove(dimensions);
+ }
+
+ public static Map<String, String> createDimensions(ApplicationId applicationId) {
+ final Map<String, String> properties = new LinkedHashMap<>();
+ properties.put("tenantName", applicationId.tenant().value());
+ properties.put("applicationName", applicationId.application().value());
+ properties.put("applicationInstance", applicationId.instance().value());
+ return properties;
+ }
+
+ public static Map<String, String> createDimensions(TenantName tenant) {
+ final Map<String, String> properties = new LinkedHashMap<>();
+ properties.put("tenantName", tenant.value());
+ return properties;
+ }
+
+ public synchronized MetricUpdater getOrCreateMetricUpdater(Map<String, String> dimensions) {
+ if (metricUpdaters.containsKey(dimensions)) {
+ return metricUpdaters.get(dimensions);
+ }
+ MetricUpdater metricUpdater = new MetricUpdater(this, dimensions);
+ metricUpdaters.put(dimensions, metricUpdater);
+ return metricUpdater;
+ }
+
+ @Override
+ public void run() {
+ for (MetricUpdater metricUpdater : metricUpdaters.values()) {
+ log.log(LogLevel.DEBUG, "Running metric updater for static values for " + metricUpdater.getDimensions());
+ for (Map.Entry<String, Number> fixedMetric : metricUpdater.getStaticMetrics().entrySet()) {
+ log.log(LogLevel.DEBUG, "Setting " + fixedMetric.getKey());
+ metric.set(fixedMetric.getKey(), fixedMetric.getValue(), metricUpdater.getMetricContext());
+ }
+ }
+ setRegularMetrics();
+ timer.purge();
+ }
+
+ private void setRegularMetrics() {
+ metric.set(METRIC_FREE_MEMORY, Runtime.getRuntime().freeMemory(), null);
+ }
+
+ void increment(String metricName, Metric.Context context) {
+ metric.add(metricName, 1, context);
+ }
+
+ void set(String metricName, Number value, Metric.Context context) {
+ metric.set(metricName, value, context);
+ }
+
+ static String getMetricName(String name) {
+ return "configserver." + name;
+ }
+}