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.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.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
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ public class StatsDEmitter implements Emitter
|
|||
|
||||
private static final Logger log = new Logger(StatsDEmitter.class);
|
||||
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 BLANK = Pattern.compile("\\s+");
|
||||
private static final String[] EMPTY_ARRAY = new String[0];
|
||||
|
@ -99,10 +100,16 @@ public class StatsDEmitter implements Emitter
|
|||
Number value = metricEvent.getValue();
|
||||
|
||||
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);
|
||||
|
||||
ImmutableMap.Builder<String, String> dimsBuilder = new ImmutableMap.Builder<>();
|
||||
StatsDMetric statsDMetric = converter.addFilteredUserDims(service, metric, userDims, dimsBuilder);
|
||||
|
||||
if (statsDMetric != null) {
|
||||
|
|
|
@ -23,6 +23,7 @@ import com.fasterxml.jackson.annotation.JsonCreator;
|
|||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
@ -43,6 +44,7 @@ public class StatsDEmitterConfig
|
|||
@JsonProperty
|
||||
private final Boolean includeHost;
|
||||
@JsonProperty
|
||||
@Nullable
|
||||
private final String dimensionMapPath;
|
||||
@JsonProperty
|
||||
private final String blankHolder;
|
||||
|
@ -50,18 +52,21 @@ public class StatsDEmitterConfig
|
|||
private final Boolean dogstatsd;
|
||||
@JsonProperty
|
||||
private final List<String> dogstatsdConstantTags;
|
||||
@JsonProperty
|
||||
private final Boolean dogstatsdServiceAsTag;
|
||||
|
||||
@JsonCreator
|
||||
public StatsDEmitterConfig(
|
||||
@JsonProperty("hostname") String hostname,
|
||||
@JsonProperty("port") Integer port,
|
||||
@JsonProperty("prefix") String prefix,
|
||||
@JsonProperty("separator") String separator,
|
||||
@JsonProperty("includeHost") Boolean includeHost,
|
||||
@JsonProperty("dimensionMapPath") String dimensionMapPath,
|
||||
@JsonProperty("blankHolder") String blankHolder,
|
||||
@JsonProperty("dogstatsd") Boolean dogstatsd,
|
||||
@JsonProperty("dogstatsdConstantTags") List<String> dogstatsdConstantTags
|
||||
@JsonProperty("prefix") @Nullable String prefix,
|
||||
@JsonProperty("separator") @Nullable String separator,
|
||||
@JsonProperty("includeHost") @Nullable Boolean includeHost,
|
||||
@JsonProperty("dimensionMapPath") @Nullable String dimensionMapPath,
|
||||
@JsonProperty("blankHolder") @Nullable String blankHolder,
|
||||
@JsonProperty("dogstatsd") @Nullable Boolean dogstatsd,
|
||||
@JsonProperty("dogstatsdConstantTags") @Nullable List<String> dogstatsdConstantTags,
|
||||
@JsonProperty("dogstatsdServiceAsTag") @Nullable Boolean dogstatsdServiceAsTag
|
||||
)
|
||||
{
|
||||
this.hostname = Preconditions.checkNotNull(hostname, "StatsD hostname cannot be null.");
|
||||
|
@ -73,6 +78,7 @@ public class StatsDEmitterConfig
|
|||
this.blankHolder = blankHolder != null ? blankHolder : "-";
|
||||
this.dogstatsd = dogstatsd != null ? dogstatsd : false;
|
||||
this.dogstatsdConstantTags = dogstatsdConstantTags != null ? dogstatsdConstantTags : Collections.emptyList();
|
||||
this.dogstatsdServiceAsTag = dogstatsdServiceAsTag != null ? dogstatsdServiceAsTag : false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -87,37 +93,38 @@ public class StatsDEmitterConfig
|
|||
|
||||
StatsDEmitterConfig that = (StatsDEmitterConfig) o;
|
||||
|
||||
if (hostname != null ? !hostname.equals(that.hostname) : that.hostname != null) {
|
||||
if (!Objects.equals(hostname, that.hostname)) {
|
||||
return false;
|
||||
}
|
||||
if (port != null ? !port.equals(that.port) : that.port != null) {
|
||||
if (!Objects.equals(port, that.port)) {
|
||||
return false;
|
||||
}
|
||||
if (prefix != null ? !prefix.equals(that.prefix) : that.prefix != null) {
|
||||
if (!Objects.equals(prefix, that.prefix)) {
|
||||
return false;
|
||||
}
|
||||
if (separator != null ? !separator.equals(that.separator) : that.separator != null) {
|
||||
if (!Objects.equals(separator, that.separator)) {
|
||||
return false;
|
||||
}
|
||||
if (includeHost != null ? !includeHost.equals(that.includeHost) : that.includeHost != null) {
|
||||
if (!Objects.equals(includeHost, that.includeHost)) {
|
||||
return false;
|
||||
}
|
||||
if (dimensionMapPath != null ? !dimensionMapPath.equals(that.dimensionMapPath) : that.dimensionMapPath != null) {
|
||||
if (!Objects.equals(dimensionMapPath, that.dimensionMapPath)) {
|
||||
return false;
|
||||
}
|
||||
if (dogstatsd != null ? !dogstatsd.equals(that.dogstatsd) : that.dogstatsd != null) {
|
||||
if (!Objects.equals(dogstatsd, that.dogstatsd)) {
|
||||
return false;
|
||||
}
|
||||
return dogstatsdConstantTags != null ? dogstatsdConstantTags.equals(that.dogstatsdConstantTags)
|
||||
: that.dogstatsdConstantTags == null;
|
||||
|
||||
if (!Objects.equals(dogstatsdServiceAsTag, that.dogstatsdServiceAsTag)) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(dogstatsdConstantTags, that.dogstatsdConstantTags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return Objects.hash(hostname, port, prefix, separator, includeHost, dimensionMapPath,
|
||||
blankHolder, dogstatsd, dogstatsdConstantTags);
|
||||
blankHolder, dogstatsd, dogstatsdConstantTags, dogstatsdServiceAsTag);
|
||||
}
|
||||
|
||||
@JsonProperty
|
||||
|
@ -151,6 +158,7 @@ public class StatsDEmitterConfig
|
|||
}
|
||||
|
||||
@JsonProperty
|
||||
@Nullable
|
||||
public String getDimensionMapPath()
|
||||
{
|
||||
return dimensionMapPath;
|
||||
|
@ -173,4 +181,10 @@ public class StatsDEmitterConfig
|
|||
{
|
||||
return dogstatsdConstantTags;
|
||||
}
|
||||
|
||||
@JsonProperty
|
||||
public Boolean isDogstatsdServiceAsTag()
|
||||
{
|
||||
return dogstatsdServiceAsTag;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ public class StatsDEmitterTest
|
|||
{
|
||||
StatsDClient client = EasyMock.createMock(StatsDClient.class);
|
||||
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(),
|
||||
client
|
||||
);
|
||||
|
@ -52,7 +52,7 @@ public class StatsDEmitterTest
|
|||
{
|
||||
StatsDClient client = EasyMock.createMock(StatsDClient.class);
|
||||
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(),
|
||||
client
|
||||
);
|
||||
|
@ -71,7 +71,7 @@ public class StatsDEmitterTest
|
|||
{
|
||||
StatsDClient client = EasyMock.createMock(StatsDClient.class);
|
||||
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(),
|
||||
client
|
||||
);
|
||||
|
@ -99,7 +99,7 @@ public class StatsDEmitterTest
|
|||
{
|
||||
StatsDClient client = EasyMock.createMock(StatsDClient.class);
|
||||
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(),
|
||||
client
|
||||
);
|
||||
|
@ -127,7 +127,7 @@ public class StatsDEmitterTest
|
|||
{
|
||||
StatsDClient client = EasyMock.createMock(StatsDClient.class);
|
||||
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(),
|
||||
client
|
||||
);
|
||||
|
@ -157,7 +157,7 @@ public class StatsDEmitterTest
|
|||
{
|
||||
StatsDClient client = EasyMock.createMock(StatsDClient.class);
|
||||
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(),
|
||||
client
|
||||
);
|
||||
|
@ -170,4 +170,26 @@ public class StatsDEmitterTest
|
|||
);
|
||||
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