java-源码-工具包-Metrics
一. 成员
ScheduledReporter成员
    private final MetricRegistry registry;
    private final ScheduledExecutorService executor;
    private final MetricFilter filter;
    private final double durationFactor;
    private final String durationUnit;
    private final double rateFactor;
    private final String rateUnit;
ConsoleReporter成员
    private static final int CONSOLE_WIDTH = 80;
    private final PrintStream output;
    private final Locale locale;
    private final Clock clock;
    private final DateFormat dateFormat;		//java自带的类
二. MetricRegistry
创建MetricRegistry的实例,默认构造方法创建,内部含有metrics是一个ConcurrentHashMap
private final ConcurrentMap<String, Metric> metrics
其value是一个Metric,是一个空接口,这个空接口是什么作用呢,从类图可以看到继承关系
MetricRegistry---->MertricSet->Metric
MetricRegistry自身也是一个Mertric接口的实现,所有的数据类型都是Metric
内部包含一些getXX方法,比如:
   public SortedMap<String, Gauge> getGauges() {
        return getGauges(MetricFilter.ALL);
   }
   public SortedMap<String, Gauge> getGauges(MetricFilter filter) {
        return getMetrics(Gauge.class, filter);
   }
   ...
无参getGauges方法中,调用了MetricFilter接口如下,All是一个始终返回true的滤波器
public interface MetricFilter {
    MetricFilter ALL = new MetricFilter() {
        @Override
        public boolean matches(String name, Metric metric) {
            return true;
        }
    };
    boolean matches(String name, Metric metric);
}
调用有参方法
    public SortedMap<String, Gauge> getGauges(MetricFilter filter) {
        return getMetrics(Gauge.class, filter);
    }
getMertrics如下
    private <T extends Metric> SortedMap<String, T> getMetrics(Class<T> klass, MetricFilter filter) {
        final TreeMap<String, T> timers = new TreeMap<String, T>();
        for (Map.Entry<String, Metric> entry : metrics.entrySet()) {
            if (klass.isInstance(entry.getValue()) && filter.matches(entry.getKey(),
                                                                     entry.getValue())) {
                timers.put(entry.getKey(), (T) entry.getValue());
            }
        }
        return Collections.unmodifiableSortedMap(timers);
    }
返回一个不可变的TreeMap,这里显然是空的
三. ConsoleReporter
ConsoleReporter创建时调用构造器方法,把metrics传入,然后设置了一些默认参数
private static ConsoleReporter reporter = ConsoleReporter.forRegistry(metrics).build();
构造器默认参数
    this.registry = registry;
    this.output = System.out;		//输出流可以配置
    this.locale = Locale.getDefault();
    this.clock = Clock.defaultClock();
    this.timeZone = TimeZone.getDefault();
    this.rateUnit = TimeUnit.SECONDS;
    this.durationUnit = TimeUnit.MILLISECONDS;
    this.filter = MetricFilter.ALL;
构造器调用build创建ConsoleReporter
    private ConsoleReporter(MetricRegistry registry,
                            PrintStream output,
                            Locale locale,
                            Clock clock,
                            TimeZone timeZone,
                            TimeUnit rateUnit,
                            TimeUnit durationUnit,
                            MetricFilter filter) {
        super(registry, "console-reporter", filter, rateUnit, durationUnit);
        this.output = output;
        this.locale = locale;
        this.clock = clock;
        this.dateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT,
                                                         DateFormat.MEDIUM,
                                                         locale);
        dateFormat.setTimeZone(timeZone);
    }
ScheduledReporter构造时调用的默认参数
    protected ScheduledReporter(MetricRegistry registry,
                                String name,
                                MetricFilter filter,
                                TimeUnit rateUnit,
                                TimeUnit durationUnit) {
        this.registry = registry;
        this.filter = filter;
        this.executor = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory(name));
        this.rateFactor = rateUnit.toSeconds(1);
        this.rateUnit = calculateRateUnit(rateUnit);
        this.durationFactor = 1.0 / durationUnit.toNanos(1);
        this.durationUnit = durationUnit.toString().toLowerCase(Locale.US);
    }
start方法
reporter.start(3, TimeUnit.SECONDS);
以固定频率即3s执行,report任务
    public void start(long period, TimeUnit unit) {
        executor.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                report();
            }
        }, period, period, unit);
    }
空参report如下
    public void report() {
        report(registry.getGauges(filter),
               registry.getCounters(filter),
               registry.getHistograms(filter),
               registry.getMeters(filter),
               registry.getTimers(filter));
    }
这里调用的是带参report是抽象方法,实现在ConsoleReporter中
    public void report(SortedMap<String, Gauge> gauges,
                       SortedMap<String, Counter> counters,
                       SortedMap<String, Histogram> histograms,
                       SortedMap<String, Meter> meters,
                       SortedMap<String, Timer> timers) {
        final String dateTime = dateFormat.format(new Date(clock.getTime()));
        printWithBanner(dateTime, '=');
        output.println();
        if (!gauges.isEmpty()) {
            printWithBanner("-- Gauges", '-');
            for (Map.Entry<String, Gauge> entry : gauges.entrySet()) {
                output.println(entry.getKey());
                printGauge(entry);
            }
            output.println();
        }
        if (!counters.isEmpty()) {
            printWithBanner("-- Counters", '-');
            for (Map.Entry<String, Counter> entry : counters.entrySet()) {
                output.println(entry.getKey());
                printCounter(entry);
            }
            output.println();
        }
        if (!histograms.isEmpty()) {
            printWithBanner("-- Histograms", '-');
            for (Map.Entry<String, Histogram> entry : histograms.entrySet()) {
                output.println(entry.getKey());
                printHistogram(entry.getValue());
            }
            output.println();
        }
        if (!meters.isEmpty()) {
            printWithBanner("-- Meters", '-');
            for (Map.Entry<String, Meter> entry : meters.entrySet()) {
                output.println(entry.getKey());
                printMeter(entry.getValue());
            }
            output.println();
        }
        if (!timers.isEmpty()) {
            printWithBanner("-- Timers", '-');
            for (Map.Entry<String, Timer> entry : timers.entrySet()) {
                output.println(entry.getKey());
                printTimer(entry.getValue());
            }
            output.println();
        }
        output.println();
        output.flush();
    }
默认的report方法就是输出所有容器的内容
四. 构造类型
Gauge接口,有一个getValue方法
	public interface Gauge<T> extends Metric {
	    T getValue();
	}
我们的调用实现这个方法
   Gauge<Integer> gauge = new Gauge<Integer>() {
        @Override
        public Integer getValue() {
            return queue.size();
        }
   };
调用register注册进MetricRegistry容器中
metrics.register(MetricRegistry.name(MetricsTest.class, "pending-job", "size"), gauge);
名字以.分隔的形式,这里是MetricsTest.pending-job.size
该方法源码如下
    public <T extends Metric> T register(String name, T metric) throws IllegalArgumentException {
        if (metric instanceof MetricSet) {
            registerAll(name, (MetricSet) metric);
        } else {
            final Metric existing = metrics.putIfAbsent(name, metric);
            if (existing == null) {
                onMetricAdded(name, metric);
            } else {
                throw new IllegalArgumentException("A metric named " + name + " already exists");
            }
        }
        return metric;
    }
把key value加入到metrics中,然后退出
 
                    
                     
                    
                 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号