/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * This class includes modified code from the following source: * * Metrics * Copyright 2010-2013 Coda Hale and Yammer, Inc. * This product includes software developed by Coda Hale and Yammer, Inc. */ package com.addthis.hydra.util; import javax.servlet.ServletException; import java.io.IOException; import java.io.Writer; import java.util.Map; import java.util.concurrent.TimeUnit; import com.addthis.basis.kv.KVPairs; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.ObjectMapper; import com.yammer.metrics.Metrics; import com.yammer.metrics.core.Clock; import com.yammer.metrics.core.MetricsRegistry; import com.yammer.metrics.core.VirtualMachineMetrics; import com.yammer.metrics.reporting.MetricsServlet; public class MetricsServletShim extends MetricsServlet { private static final JsonFactory DEFAULT_JSON_FACTORY = new JsonFactory(new ObjectMapper()); private final Clock clock; private final VirtualMachineMetrics vm; /** * Creates a new {@link MetricsServlet}. */ public MetricsServletShim() { this(Clock.defaultClock(), VirtualMachineMetrics.getInstance(), Metrics.defaultRegistry(), DEFAULT_JSON_FACTORY, true); } public MetricsServletShim(Clock clock, VirtualMachineMetrics vm, MetricsRegistry registry, JsonFactory factory, boolean showJvmMetrics) { super(clock, vm, registry, factory, showJvmMetrics); this.clock = clock; this.vm = vm; } public void writeMetrics(Writer writer, KVPairs kv) throws ServletException, IOException { final String classPrefix = kv.getValue("class"); final boolean pretty = Boolean.parseBoolean(kv.getValue("pretty")); final boolean showFullSamples = Boolean.parseBoolean(kv.getValue("full-samples")); final JsonGenerator json = DEFAULT_JSON_FACTORY.createGenerator(writer); if (pretty) { json.useDefaultPrettyPrinter(); } json.writeStartObject(); { if ("jvm".equals(classPrefix) || classPrefix == null) { writeVmMetrics(json); } writeRegularMetrics(json, classPrefix, showFullSamples); } json.writeEndObject(); json.close(); } private void writeVmMetrics(JsonGenerator json) throws IOException { json.writeFieldName("jvm"); json.writeStartObject(); { json.writeFieldName("vm"); json.writeStartObject(); { json.writeStringField("name", vm.name()); json.writeStringField("version", vm.version()); } json.writeEndObject(); json.writeFieldName("memory"); json.writeStartObject(); { json.writeNumberField("totalInit", vm.totalInit()); json.writeNumberField("totalUsed", vm.totalUsed()); json.writeNumberField("totalMax", vm.totalMax()); json.writeNumberField("totalCommitted", vm.totalCommitted()); json.writeNumberField("heapInit", vm.heapInit()); json.writeNumberField("heapUsed", vm.heapUsed()); json.writeNumberField("heapMax", vm.heapMax()); json.writeNumberField("heapCommitted", vm.heapCommitted()); json.writeNumberField("heap_usage", vm.heapUsage()); json.writeNumberField("non_heap_usage", vm.nonHeapUsage()); json.writeFieldName("memory_pool_usages"); json.writeStartObject(); { for (Map.Entry<String, Double> pool : vm.memoryPoolUsage().entrySet()) { json.writeNumberField(pool.getKey(), pool.getValue()); } } json.writeEndObject(); } json.writeEndObject(); final Map<String, VirtualMachineMetrics.BufferPoolStats> bufferPoolStats = vm.getBufferPoolStats(); if (!bufferPoolStats.isEmpty()) { json.writeFieldName("buffers"); json.writeStartObject(); { json.writeFieldName("direct"); json.writeStartObject(); { json.writeNumberField("count", bufferPoolStats.get("direct").getCount()); json.writeNumberField("memoryUsed", bufferPoolStats.get("direct").getMemoryUsed()); json.writeNumberField("totalCapacity", bufferPoolStats.get("direct").getTotalCapacity()); } json.writeEndObject(); json.writeFieldName("mapped"); json.writeStartObject(); { json.writeNumberField("count", bufferPoolStats.get("mapped").getCount()); json.writeNumberField("memoryUsed", bufferPoolStats.get("mapped").getMemoryUsed()); json.writeNumberField("totalCapacity", bufferPoolStats.get("mapped").getTotalCapacity()); } json.writeEndObject(); } json.writeEndObject(); } json.writeNumberField("daemon_thread_count", vm.daemonThreadCount()); json.writeNumberField("thread_count", vm.threadCount()); json.writeNumberField("current_time", clock.time()); json.writeNumberField("uptime", vm.uptime()); json.writeNumberField("fd_usage", vm.fileDescriptorUsage()); json.writeFieldName("thread-states"); json.writeStartObject(); { for (Map.Entry<Thread.State, Double> entry : vm.threadStatePercentages() .entrySet()) { json.writeNumberField(entry.getKey().toString().toLowerCase(), entry.getValue()); } } json.writeEndObject(); json.writeFieldName("garbage-collectors"); json.writeStartObject(); { for (Map.Entry<String, VirtualMachineMetrics.GarbageCollectorStats> entry : vm.garbageCollectors() .entrySet()) { json.writeFieldName(entry.getKey()); json.writeStartObject(); { final VirtualMachineMetrics.GarbageCollectorStats gc = entry.getValue(); json.writeNumberField("runs", gc.getRuns()); json.writeNumberField("time", gc.getTime(TimeUnit.MILLISECONDS)); } json.writeEndObject(); } } json.writeEndObject(); } json.writeEndObject(); } }