package com.github.digital_wonderland.sling_metrics.service;
import com.codahale.metrics.*;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.InetAddress;
import java.net.UnknownHostException;
@Component(label = "Sling Metrics :: Metric Service", metatype = true)
@Service(value = MetricService.class)
public class MetricService {
private static final Logger LOG = LoggerFactory.getLogger(MetricService.class);
@Property(label = "Enabled", boolValue = true, description = "Should the metrics service be enabled")
private static final String METRIC_SERVICE_ENABLED = "metricService.enabled";
@Property(label = "Global Metric Prefix", description = "Leave empty to use 'sling.metrics.$hostname|$ip'")
private static final String METRIC_PREFIX = "metricService.metricPrefix";
private MetricRegistry registry;
private boolean isEnabled;
private String metricPrefix;
@Activate
protected void activate(final ComponentContext context) {
isEnabled = (Boolean) context.getProperties().get(METRIC_SERVICE_ENABLED);
metricPrefix = (String) context.getProperties().get(METRIC_PREFIX);
metricPrefix = metricPrefix == null ? "" : metricPrefix.trim();
if(metricPrefix.isEmpty()) {
final String tmpl = "sling.metrics.%s";
try {
String hostname = InetAddress.getLocalHost().getHostName();
// shorten foo.bar.example.com to foo
hostname = hostname.split("\\.")[0];
metricPrefix = String.format(tmpl, hostname);
} catch (UnknownHostException e) {
LOG.warn("Unable to determine hostname", e);
try {
metricPrefix = String.format(tmpl, InetAddress.getLocalHost().getHostAddress());
} catch (UnknownHostException e1) {
LOG.warn("Unable to determine ip", e1);
metricPrefix = "sling.metrics";
}
}
}
if(isEnabled) {
registry = new MetricRegistry();
LOG.debug("New MetricRegistry created");
}
}
public MetricRegistry getRegistry() {
return registry;
}
public boolean isEnabled() {
return isEnabled;
}
public String getMetricPrefix() { return metricPrefix; }
/**
* Concatenates elements to form a dotted name, eliding any null values or empty strings.
*
* @param name the first element of the name
* @param names the remaining elements of the name
* @return {@code name} and {@code names} concatenated by periods
* @see com.codahale.metrics.MetricRegistry#name
*/
public String name(String name, String... names) {
return com.codahale.metrics.MetricRegistry.name(String.format("%s.%s", metricPrefix, name), names);
}
/**
* Given a {@link Metric}, registers it under the given name.
*
* @param name the name of the metric
* @param metric the metric
* @param <T> the type of the metric
* @return {@code metric}
* @throws IllegalArgumentException if the name is already registered
* @see com.codahale.metrics.MetricRegistry#register
*/
public <T extends Metric> T register(String name, T metric) throws IllegalArgumentException {
return registry.register(name(name), metric);
}
/**
* Removes the metric with the given name.
*
* @param name the name of the metric
* @return whether or not the metric was removed
* @see com.codahale.metrics.MetricRegistry#remove
*/
public boolean remove(String name) { return registry.remove(name(name)); }
/**
* Creates a new {@link Meter} and registers it under the given name.
*
* @param name the name of the metric
* @return a new {@link Meter}
* @see com.codahale.metrics.MetricRegistry#meter
*/
public Meter meter(String name) { return registry.meter(name(name)); }
/**
* Creates a new {@link Histogram} and registers it under the given name.
*
* @param name the name of the metric
* @return a new {@link Histogram}
* @see com.codahale.metrics.MetricRegistry#histogram
*/
public Histogram histogram(String name) { return registry.histogram(name(name)); }
/**
* Creates a new {@link Counter} and registers it under the given name.
*
* @param name the name of the metric
* @return a new {@link Counter}
* @see com.codahale.metrics.MetricRegistry#counter
*/
public Counter counter(String name) { return registry.counter(name(name)); }
/**
* Creates a new {@link Timer} and registers it under the given name.
*
* @param name the name of the metric
* @return a new {@link Timer}
* @see com.codahale.metrics.MetricRegistry#timer
*/
public Timer timer(String name) { return registry.timer(name(name)); }
}