/**
* Copyright 2016-2017 Sixt GmbH & Co. Autovermietung KG
* 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.
*/
package com.sixt.service.framework.metrics;
import com.codahale.metrics.Metric;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.MetricSet;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
//DO NOT MAKE @Singleton
public class MetricBuilder {
private static final Logger logger = LoggerFactory.getLogger(MetricBuilder.class);
private final MetricRegistry registry;
private final List<MetricTag> tags = new ArrayList<>();
private String baseName;
@Inject
public MetricBuilder(MetricRegistry registry) {
this.registry = registry;
}
public MetricBuilder withTag(String name, String value) {
tags.add(new MetricTag(name, value));
return this;
}
public synchronized GoTimer buildTimer() {
String name = generateName("timing");
GoTimer timer = getExistingTimer(name);
if (timer == null) {
timer = new GoTimer(name);
Map<String, Metric> map = new HashMap<>(1);
map.put(name, timer);
MetricSet set = () -> map;
try {
registry.registerAll(set);
} catch (Exception ex) {
//I haven't figured out a good solution around this...
}
}
return timer;
}
public synchronized GoCounter buildCounter() {
String name = generateName("counter");
GoCounter counter = getExistingCounter(name);
if (counter == null) {
counter = new GoCounter(name);
Map<String, Metric> map = new HashMap<>();
map.put(name, counter);
MetricSet set = () -> map;
registry.registerAll(set);
}
return counter;
}
public synchronized GoGauge buildGauge() {
String name = generateName("gauge");
GoGauge gauge = getExistingGauge(name);
if (gauge == null) {
gauge = new GoGauge(name);
Map<String, Metric> map = new HashMap<>();
map.put(name, gauge);
MetricSet set = () -> map;
registry.registerAll(set);
}
return gauge;
}
private GoTimer getExistingTimer(String name) {
Metric m = registry.getMetrics().get(name);
if (m instanceof GoTimer) {
return (GoTimer) m;
} else if (m != null) {
logger.warn("Existing metric with name {} is not a GoTimer", name);
}
return null;
}
private GoCounter getExistingCounter(String name) {
Metric m = registry.getMetrics().get(name);
if (m instanceof GoCounter) {
return (GoCounter) m;
} else if (m != null) {
logger.warn("Existing metric with name {} is not a GoCounter", name);
}
return null;
}
private GoGauge getExistingGauge(String name) {
Metric m = registry.getMetrics().get(name);
if (m instanceof GoGauge) {
return (GoGauge) m;
} else if (m != null) {
logger.warn("Existing metric with name {} is not a GoGauge", name);
}
return null;
}
//this name is highly-dependent upon the Sixt GoOrange metrics infrastructure
//TODO: when we implement pluggable metrics reporting, the metrics reporter
// should interact here...
protected String generateName(String metricType) {
if (baseName == null || baseName.isEmpty()) {
throw new IllegalStateException("No baseName was provided");
}
StringBuilder sb = new StringBuilder();
sb.append(baseName);
for (MetricTag tag : tags) {
sb.append(",");
sb.append(tag.name);
sb.append("=");
sb.append(tag.value);
}
sb.append(",metric_type=");
sb.append(metricType);
return sb.toString();
}
void setBaseName(String baseName) {
this.baseName = baseName;
}
}