All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alibaba.metrics.tomcat.HttpGaugeSet Maven / Gradle / Ivy

There is a newer version: 2.0.6
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */
package com.alibaba.metrics.tomcat;

import com.alibaba.metrics.CachedMetricSet;
import com.alibaba.metrics.Clock;
import com.alibaba.metrics.Metric;
import com.alibaba.metrics.MetricName;
import com.alibaba.metrics.PersistentGauge;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.management.MBeanServer;
import javax.management.ObjectName;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class HttpGaugeSet extends CachedMetricSet {

    private static final Logger logger = LoggerFactory.getLogger(HttpGaugeSet.class);

    private enum HttpMetrics {
        REQUEST_COUNT, PROCESSING_TIME, ERROR_COUNT,
        MAX_TIME, BYTES_SENT, BYTES_RECEIVED
    }

    private static final String[] metricNames = {
            "request_count",
            "request.processing_time",
            "request.error_count",
            "request.max_time",
            "request.bytes_sent",
            "request.bytes_received"
    };

    private ObjectName globalReqProcessor;
    private MBeanServer mbeanServer;
    private Map connectorMetrics;
    private Map failureStats;
    final Map gauges;

    public HttpGaugeSet() {
        this(JMXUtils.getMBeanServer(), DEFAULT_DATA_TTL, TimeUnit.MILLISECONDS, Clock.defaultClock());
    }

    public HttpGaugeSet(long dataTTL, TimeUnit unit) {
        this(JMXUtils.getMBeanServer(), dataTTL, unit, Clock.defaultClock());
    }

    public HttpGaugeSet(MBeanServer mbeanServer, long dataTTL, TimeUnit unit, Clock clock) {
        super(dataTTL, unit, clock);
        connectorMetrics = new HashMap();
        globalReqProcessor = JMXUtils.createObjectName("*:type=GlobalRequestProcessor,*");
        this.mbeanServer = mbeanServer;
        failureStats = new HashMap();
        gauges = new HashMap();
        populateGauges();
    }

    @Override
    protected void getValueInternal() {
        // collect http metrics
        ObjectName[] connectorNames = JMXUtils.getObjectNames(globalReqProcessor);

        for (ObjectName connectorName : connectorNames) {
            String name = ObjectName.unquote(connectorName.getKeyProperty("name"));
            Long[] metrics = connectorMetrics.get(name);
            if (null == metrics) {
                continue;
            }

            try {
                metrics[HttpMetrics.REQUEST_COUNT.ordinal()] =
                        Long.valueOf((Integer)mbeanServer.getAttribute(connectorName, "requestCount"));
                metrics[HttpMetrics.PROCESSING_TIME.ordinal()] =
                        (Long)mbeanServer.getAttribute(connectorName, "processingTime");
                metrics[HttpMetrics.ERROR_COUNT.ordinal()] =
                        Long.valueOf((Integer)mbeanServer.getAttribute(connectorName, "errorCount"));
                metrics[HttpMetrics.MAX_TIME.ordinal()] =
                        (Long)mbeanServer.getAttribute(connectorName, "maxTime");
                metrics[HttpMetrics.BYTES_RECEIVED.ordinal()] =
                        (Long)mbeanServer.getAttribute(connectorName, "bytesReceived");
                metrics[HttpMetrics.BYTES_SENT.ordinal()] =
                        (Long)mbeanServer.getAttribute(connectorName, "bytesSent");
            } catch (Exception e) {
                logger.error("Exception occur when getting connector global stats: ", e);
            }

            // get request failure count
            try {
                Object attribute = mbeanServer.getAttribute(connectorName, "requestFailureCount");
                if (attribute != null) {
                    Integer[] data = (Integer[]) attribute;
                    for (int i = 0; i < data.length; i++) {
                        failureStats.get(name)[i] = data[i];
                    }
                }
            } catch (Exception ex) {
                // it is ok if running on Apache Tomcat, which has no such attribute indeed.
            }
        }
    }

    @Override
    public Map getMetrics() {
        return gauges;
    }

    private void populateGauges() {
        // collect http metrics
        ObjectName[] connectorNames = JMXUtils.getObjectNames(globalReqProcessor);

        for (ObjectName connectorName : connectorNames) {
            String name = ObjectName.unquote(connectorName.getKeyProperty("name"));
            connectorMetrics.put(name, new Long[HttpMetrics.values().length]);
        }

        for (Map.Entry entry: connectorMetrics.entrySet()) {
            for (HttpMetrics metric : HttpMetrics.values()) {
                gauges.put(MetricName.build(metricNames[metric.ordinal()]).tagged("connector", entry.getKey()),
                        new HttpStatGauge(entry.getValue(), metric.ordinal()));
            }
        }

    }

    private class HttpStatGauge extends PersistentGauge {
        private T[] dataArray;
        private int index;

        public HttpStatGauge(T[] dataArray, int index) {
            this.dataArray = dataArray;
            this.index = index;
        }

        @Override
        public T getValue() {
            refreshIfNecessary();
            return dataArray[index];
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy