package com.twitter.common.metrics; import java.util.concurrent.atomic.AtomicLong; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.twitter.common.base.MorePreconditions; /** * A metric registry that is a 'child' of another metric registry. */ public class ScopedMetrics implements MetricRegistry { private static final String SCOPE_DELIMITER = "."; private final String name; private final MetricRegistry parentScope; /** * Creates a new scoped metric registry. * When a gauge is registered with this registry, it will be passed directly to the parent, * with the scope name applied to the gauge name. * * @param name Name of this scope. * @param parentScope Parent scope to register gauges with. */ @VisibleForTesting ScopedMetrics(String name, MetricRegistry parentScope) { this.name = MorePreconditions.checkNotBlank(name); this.parentScope = Preconditions.checkNotNull(parentScope); } @Override public MetricRegistry scope(String scopeName) { return new ScopedMetrics(scopeName, this); } private String scopeName(String metricName) { return name + SCOPE_DELIMITER + metricName; } @Override public <T extends Number> void register(final Gauge<T> gauge) { final String scopedName = scopeName(gauge.getName()); parentScope.register(new AbstractGauge<T>(scopedName) { @Override public T read() { return gauge.read(); } }); } @Override public AtomicLong registerLong(String gaugeName) { return parentScope.registerLong(scopeName(gaugeName)); } }