mirror of https://github.com/apache/druid.git
[statsd-emitter] Add config to send Druid process/service as tag (#8238)
* [statsd-emitter] Add serviceAsTag option * [statsd-emitter] Refactor serviceAsTag option * [statsd-emitter] Update statsd.md * [statsd-emitter] add default prefix * [statsd-emitter] update statsd.md * [statsd-emitter] Remove extra spaces * [statsd-emitter] Improve docs for config `dogstatsdServiceAsTag` * [statsd-emitter] Simplify equals() for StatsDEmitterConfig.java * [statsd-emitter] Add @Nullable for StatsDEmitterConfig.java
This commit is contained in:
parent
1054d85171
commit
6b4d028b96
|
@ -47,6 +47,7 @@ All the configuration parameters for the StatsD emitter are under `druid.emitter
|
||||||
|`druid.emitter.statsd.blankHolder`|The blank character replacement as statsD does not support path with blank character|no|"-"|
|
|`druid.emitter.statsd.blankHolder`|The blank character replacement as statsD does not support path with blank character|no|"-"|
|
||||||
|`druid.emitter.statsd.dogstatsd`|Flag to enable [DogStatsD](https://docs.datadoghq.com/developers/dogstatsd/) support. Causes dimensions to be included as tags, not as a part of the metric name. `convertRange` fields will be ignored.|no|false|
|
|`druid.emitter.statsd.dogstatsd`|Flag to enable [DogStatsD](https://docs.datadoghq.com/developers/dogstatsd/) support. Causes dimensions to be included as tags, not as a part of the metric name. `convertRange` fields will be ignored.|no|false|
|
||||||
|`druid.emitter.statsd.dogstatsdConstantTags`|If `druid.emitter.statsd.dogstatsd` is true, the tags in the JSON list of strings will be sent with every event.|no|[]|
|
|`druid.emitter.statsd.dogstatsdConstantTags`|If `druid.emitter.statsd.dogstatsd` is true, the tags in the JSON list of strings will be sent with every event.|no|[]|
|
||||||
|
|`druid.emitter.statsd.dogstatsdServiceAsTag`|If `druid.emitter.statsd.dogstatsd` and `druid.emitter.statsd.dogstatsdServiceAsTag` are true, druid service (e.g. `druid/broker`, `druid/coordinator`, etc) is reported as a tag (e.g. `service:druid/broker`) instead of being included in metric name (e.g. `druid.broker.my_metric`) and `druid` is used as metric prefix (e.g. `druid.query.time`).|no|false|
|
||||||
|
|
||||||
### Druid to StatsD Event Converter
|
### Druid to StatsD Event Converter
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ public class StatsDEmitter implements Emitter
|
||||||
|
|
||||||
private static final Logger log = new Logger(StatsDEmitter.class);
|
private static final Logger log = new Logger(StatsDEmitter.class);
|
||||||
private static final char DRUID_METRIC_SEPARATOR = '/';
|
private static final char DRUID_METRIC_SEPARATOR = '/';
|
||||||
|
private static final String DRUID_DEFAULT_PREFIX = "druid";
|
||||||
private static final Pattern STATSD_SEPARATOR = Pattern.compile("[:|]");
|
private static final Pattern STATSD_SEPARATOR = Pattern.compile("[:|]");
|
||||||
private static final Pattern BLANK = Pattern.compile("\\s+");
|
private static final Pattern BLANK = Pattern.compile("\\s+");
|
||||||
private static final String[] EMPTY_ARRAY = new String[0];
|
private static final String[] EMPTY_ARRAY = new String[0];
|
||||||
|
@ -99,10 +100,16 @@ public class StatsDEmitter implements Emitter
|
||||||
Number value = metricEvent.getValue();
|
Number value = metricEvent.getValue();
|
||||||
|
|
||||||
ImmutableList.Builder<String> nameBuilder = new ImmutableList.Builder<>();
|
ImmutableList.Builder<String> nameBuilder = new ImmutableList.Builder<>();
|
||||||
nameBuilder.add(service);
|
ImmutableMap.Builder<String, String> dimsBuilder = new ImmutableMap.Builder<>();
|
||||||
|
|
||||||
|
if (config.isDogstatsd() && config.isDogstatsdServiceAsTag()) {
|
||||||
|
dimsBuilder.put("service", service);
|
||||||
|
nameBuilder.add(DRUID_DEFAULT_PREFIX);
|
||||||
|
} else {
|
||||||
|
nameBuilder.add(service);
|
||||||
|
}
|
||||||
nameBuilder.add(metric);
|
nameBuilder.add(metric);
|
||||||
|
|
||||||
ImmutableMap.Builder<String, String> dimsBuilder = new ImmutableMap.Builder<>();
|
|
||||||
StatsDMetric statsDMetric = converter.addFilteredUserDims(service, metric, userDims, dimsBuilder);
|
StatsDMetric statsDMetric = converter.addFilteredUserDims(service, metric, userDims, dimsBuilder);
|
||||||
|
|
||||||
if (statsDMetric != null) {
|
if (statsDMetric != null) {
|
||||||
|
|
|
@ -23,6 +23,7 @@ import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
@ -43,6 +44,7 @@ public class StatsDEmitterConfig
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
private final Boolean includeHost;
|
private final Boolean includeHost;
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
|
@Nullable
|
||||||
private final String dimensionMapPath;
|
private final String dimensionMapPath;
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
private final String blankHolder;
|
private final String blankHolder;
|
||||||
|
@ -50,18 +52,21 @@ public class StatsDEmitterConfig
|
||||||
private final Boolean dogstatsd;
|
private final Boolean dogstatsd;
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
private final List<String> dogstatsdConstantTags;
|
private final List<String> dogstatsdConstantTags;
|
||||||
|
@JsonProperty
|
||||||
|
private final Boolean dogstatsdServiceAsTag;
|
||||||
|
|
||||||
@JsonCreator
|
@JsonCreator
|
||||||
public StatsDEmitterConfig(
|
public StatsDEmitterConfig(
|
||||||
@JsonProperty("hostname") String hostname,
|
@JsonProperty("hostname") String hostname,
|
||||||
@JsonProperty("port") Integer port,
|
@JsonProperty("port") Integer port,
|
||||||
@JsonProperty("prefix") String prefix,
|
@JsonProperty("prefix") @Nullable String prefix,
|
||||||
@JsonProperty("separator") String separator,
|
@JsonProperty("separator") @Nullable String separator,
|
||||||
@JsonProperty("includeHost") Boolean includeHost,
|
@JsonProperty("includeHost") @Nullable Boolean includeHost,
|
||||||
@JsonProperty("dimensionMapPath") String dimensionMapPath,
|
@JsonProperty("dimensionMapPath") @Nullable String dimensionMapPath,
|
||||||
@JsonProperty("blankHolder") String blankHolder,
|
@JsonProperty("blankHolder") @Nullable String blankHolder,
|
||||||
@JsonProperty("dogstatsd") Boolean dogstatsd,
|
@JsonProperty("dogstatsd") @Nullable Boolean dogstatsd,
|
||||||
@JsonProperty("dogstatsdConstantTags") List<String> dogstatsdConstantTags
|
@JsonProperty("dogstatsdConstantTags") @Nullable List<String> dogstatsdConstantTags,
|
||||||
|
@JsonProperty("dogstatsdServiceAsTag") @Nullable Boolean dogstatsdServiceAsTag
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
this.hostname = Preconditions.checkNotNull(hostname, "StatsD hostname cannot be null.");
|
this.hostname = Preconditions.checkNotNull(hostname, "StatsD hostname cannot be null.");
|
||||||
|
@ -73,6 +78,7 @@ public class StatsDEmitterConfig
|
||||||
this.blankHolder = blankHolder != null ? blankHolder : "-";
|
this.blankHolder = blankHolder != null ? blankHolder : "-";
|
||||||
this.dogstatsd = dogstatsd != null ? dogstatsd : false;
|
this.dogstatsd = dogstatsd != null ? dogstatsd : false;
|
||||||
this.dogstatsdConstantTags = dogstatsdConstantTags != null ? dogstatsdConstantTags : Collections.emptyList();
|
this.dogstatsdConstantTags = dogstatsdConstantTags != null ? dogstatsdConstantTags : Collections.emptyList();
|
||||||
|
this.dogstatsdServiceAsTag = dogstatsdServiceAsTag != null ? dogstatsdServiceAsTag : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -87,37 +93,38 @@ public class StatsDEmitterConfig
|
||||||
|
|
||||||
StatsDEmitterConfig that = (StatsDEmitterConfig) o;
|
StatsDEmitterConfig that = (StatsDEmitterConfig) o;
|
||||||
|
|
||||||
if (hostname != null ? !hostname.equals(that.hostname) : that.hostname != null) {
|
if (!Objects.equals(hostname, that.hostname)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (port != null ? !port.equals(that.port) : that.port != null) {
|
if (!Objects.equals(port, that.port)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (prefix != null ? !prefix.equals(that.prefix) : that.prefix != null) {
|
if (!Objects.equals(prefix, that.prefix)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (separator != null ? !separator.equals(that.separator) : that.separator != null) {
|
if (!Objects.equals(separator, that.separator)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (includeHost != null ? !includeHost.equals(that.includeHost) : that.includeHost != null) {
|
if (!Objects.equals(includeHost, that.includeHost)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (dimensionMapPath != null ? !dimensionMapPath.equals(that.dimensionMapPath) : that.dimensionMapPath != null) {
|
if (!Objects.equals(dimensionMapPath, that.dimensionMapPath)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (dogstatsd != null ? !dogstatsd.equals(that.dogstatsd) : that.dogstatsd != null) {
|
if (!Objects.equals(dogstatsd, that.dogstatsd)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return dogstatsdConstantTags != null ? dogstatsdConstantTags.equals(that.dogstatsdConstantTags)
|
if (!Objects.equals(dogstatsdServiceAsTag, that.dogstatsdServiceAsTag)) {
|
||||||
: that.dogstatsdConstantTags == null;
|
return false;
|
||||||
|
}
|
||||||
|
return Objects.equals(dogstatsdConstantTags, that.dogstatsdConstantTags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode()
|
public int hashCode()
|
||||||
{
|
{
|
||||||
return Objects.hash(hostname, port, prefix, separator, includeHost, dimensionMapPath,
|
return Objects.hash(hostname, port, prefix, separator, includeHost, dimensionMapPath,
|
||||||
blankHolder, dogstatsd, dogstatsdConstantTags);
|
blankHolder, dogstatsd, dogstatsdConstantTags, dogstatsdServiceAsTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
|
@ -151,6 +158,7 @@ public class StatsDEmitterConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
|
@Nullable
|
||||||
public String getDimensionMapPath()
|
public String getDimensionMapPath()
|
||||||
{
|
{
|
||||||
return dimensionMapPath;
|
return dimensionMapPath;
|
||||||
|
@ -173,4 +181,10 @@ public class StatsDEmitterConfig
|
||||||
{
|
{
|
||||||
return dogstatsdConstantTags;
|
return dogstatsdConstantTags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonProperty
|
||||||
|
public Boolean isDogstatsdServiceAsTag()
|
||||||
|
{
|
||||||
|
return dogstatsdServiceAsTag;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ public class StatsDEmitterTest
|
||||||
{
|
{
|
||||||
StatsDClient client = EasyMock.createMock(StatsDClient.class);
|
StatsDClient client = EasyMock.createMock(StatsDClient.class);
|
||||||
StatsDEmitter emitter = new StatsDEmitter(
|
StatsDEmitter emitter = new StatsDEmitter(
|
||||||
new StatsDEmitterConfig("localhost", 8888, null, null, null, null, null, null, null),
|
new StatsDEmitterConfig("localhost", 8888, null, null, null, null, null, null, null, null),
|
||||||
new ObjectMapper(),
|
new ObjectMapper(),
|
||||||
client
|
client
|
||||||
);
|
);
|
||||||
|
@ -52,7 +52,7 @@ public class StatsDEmitterTest
|
||||||
{
|
{
|
||||||
StatsDClient client = EasyMock.createMock(StatsDClient.class);
|
StatsDClient client = EasyMock.createMock(StatsDClient.class);
|
||||||
StatsDEmitter emitter = new StatsDEmitter(
|
StatsDEmitter emitter = new StatsDEmitter(
|
||||||
new StatsDEmitterConfig("localhost", 8888, null, null, null, null, null, true, null),
|
new StatsDEmitterConfig("localhost", 8888, null, null, null, null, null, true, null, null),
|
||||||
new ObjectMapper(),
|
new ObjectMapper(),
|
||||||
client
|
client
|
||||||
);
|
);
|
||||||
|
@ -71,7 +71,7 @@ public class StatsDEmitterTest
|
||||||
{
|
{
|
||||||
StatsDClient client = EasyMock.createMock(StatsDClient.class);
|
StatsDClient client = EasyMock.createMock(StatsDClient.class);
|
||||||
StatsDEmitter emitter = new StatsDEmitter(
|
StatsDEmitter emitter = new StatsDEmitter(
|
||||||
new StatsDEmitterConfig("localhost", 8888, null, null, null, null, null, null, null),
|
new StatsDEmitterConfig("localhost", 8888, null, null, null, null, null, null, null, null),
|
||||||
new ObjectMapper(),
|
new ObjectMapper(),
|
||||||
client
|
client
|
||||||
);
|
);
|
||||||
|
@ -99,7 +99,7 @@ public class StatsDEmitterTest
|
||||||
{
|
{
|
||||||
StatsDClient client = EasyMock.createMock(StatsDClient.class);
|
StatsDClient client = EasyMock.createMock(StatsDClient.class);
|
||||||
StatsDEmitter emitter = new StatsDEmitter(
|
StatsDEmitter emitter = new StatsDEmitter(
|
||||||
new StatsDEmitterConfig("localhost", 8888, null, "#", true, null, null, null, null),
|
new StatsDEmitterConfig("localhost", 8888, null, "#", true, null, null, null, null, null),
|
||||||
new ObjectMapper(),
|
new ObjectMapper(),
|
||||||
client
|
client
|
||||||
);
|
);
|
||||||
|
@ -127,7 +127,7 @@ public class StatsDEmitterTest
|
||||||
{
|
{
|
||||||
StatsDClient client = EasyMock.createMock(StatsDClient.class);
|
StatsDClient client = EasyMock.createMock(StatsDClient.class);
|
||||||
StatsDEmitter emitter = new StatsDEmitter(
|
StatsDEmitter emitter = new StatsDEmitter(
|
||||||
new StatsDEmitterConfig("localhost", 8888, null, "#", true, null, null, true, null),
|
new StatsDEmitterConfig("localhost", 8888, null, "#", true, null, null, true, null, null),
|
||||||
new ObjectMapper(),
|
new ObjectMapper(),
|
||||||
client
|
client
|
||||||
);
|
);
|
||||||
|
@ -157,7 +157,7 @@ public class StatsDEmitterTest
|
||||||
{
|
{
|
||||||
StatsDClient client = EasyMock.createMock(StatsDClient.class);
|
StatsDClient client = EasyMock.createMock(StatsDClient.class);
|
||||||
StatsDEmitter emitter = new StatsDEmitter(
|
StatsDEmitter emitter = new StatsDEmitter(
|
||||||
new StatsDEmitterConfig("localhost", 8888, null, null, true, null, null, null, null),
|
new StatsDEmitterConfig("localhost", 8888, null, null, true, null, null, null, null, null),
|
||||||
new ObjectMapper(),
|
new ObjectMapper(),
|
||||||
client
|
client
|
||||||
);
|
);
|
||||||
|
@ -170,4 +170,26 @@ public class StatsDEmitterTest
|
||||||
);
|
);
|
||||||
EasyMock.verify(client);
|
EasyMock.verify(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testServiceAsTagOption()
|
||||||
|
{
|
||||||
|
StatsDClient client = EasyMock.createMock(StatsDClient.class);
|
||||||
|
StatsDEmitter emitter = new StatsDEmitter(
|
||||||
|
new StatsDEmitterConfig("localhost", 8888, null, null, true, null, null, true, null, true),
|
||||||
|
new ObjectMapper(),
|
||||||
|
client
|
||||||
|
);
|
||||||
|
client.time("druid.query.time", 10,
|
||||||
|
"service:druid/broker", "dataSource:data-source", "type:groupBy", "hostname:brokerHost1"
|
||||||
|
);
|
||||||
|
EasyMock.replay(client);
|
||||||
|
emitter.emit(new ServiceMetricEvent.Builder()
|
||||||
|
.setDimension("dataSource", "data-source")
|
||||||
|
.setDimension("type", "groupBy")
|
||||||
|
.build(DateTimes.nowUtc(), "query/time", 10)
|
||||||
|
.build("druid/broker", "brokerHost1")
|
||||||
|
);
|
||||||
|
EasyMock.verify(client);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue