diff --git a/service/config/sample.yml b/service/config/sample.yml index 2e55985df..3cb2b1e8b 100644 --- a/service/config/sample.yml +++ b/service/config/sample.yml @@ -97,5 +97,7 @@ gcm: # GCM Configuration apiKey: micrometer: # Micrometer metrics config - uri: "https://metrics.example.com/" - apiToken: + - name: "example" + - uri: "https://metrics.example.com/" + - apiKey: + - accountId: diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerConfiguration.java b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerConfiguration.java index 46a031546..16a41c208 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerConfiguration.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerConfiguration.java @@ -61,7 +61,7 @@ public class WhisperServerConfiguration extends Configuration { @NotNull @Valid @JsonProperty - private MicrometerConfiguration micrometer; + private List micrometer = new LinkedList<>(); @NotNull @Valid @@ -286,8 +286,14 @@ public class WhisperServerConfiguration extends Configuration { return cdn; } - public MicrometerConfiguration getMicrometerConfiguration() { - return micrometer; + public Map getMicrometerConfiguration() { + final Map micrometerConfigurationByName = new HashMap<>(); + + for (final MicrometerConfiguration micrometerConfiguration : micrometer) { + micrometerConfigurationByName.put(micrometerConfiguration.getName(), micrometerConfiguration); + } + + return micrometerConfigurationByName; } public UnidentifiedDeliveryConfiguration getDeliveryCertificate() { diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java index 7d6236e71..606678859 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java @@ -43,7 +43,11 @@ import io.dropwizard.setup.Bootstrap; import io.dropwizard.setup.Environment; import io.lettuce.core.RedisURI; import io.lettuce.core.cluster.RedisClusterClient; +import io.micrometer.core.instrument.Clock; import io.micrometer.core.instrument.Metrics; +import io.micrometer.newrelic.NewRelicConfig; +import io.micrometer.newrelic.NewRelicMeterRegistry; +import io.micrometer.wavefront.WavefrontConfig; import io.micrometer.wavefront.WavefrontMeterRegistry; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.eclipse.jetty.servlets.CrossOriginFilter; @@ -157,6 +161,7 @@ import javax.servlet.ServletRegistration; import java.security.Security; import java.util.EnumSet; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; @@ -210,21 +215,61 @@ public class WhisperServerService extends Application micrometerConfigurationByName = config.getMicrometerConfiguration(); + { // This is a workaround for an issue where the configured step duration isn't being honored by // WavefrontMeterRegistry; we can simplify if https://github.com/micrometer-metrics/micrometer/pull/2173 gets // merged. - final MicrometerConfiguration micrometerConfig = config.getMicrometerConfiguration(); + final MicrometerConfiguration micrometerWavefrontConfig = micrometerConfigurationByName.get("wavefront"); - final WavefrontSender wavefrontSender = WavefrontMeterRegistry.getDefaultSenderBuilder(micrometerConfig) - .flushIntervalSeconds((int)micrometerConfig.step().toSeconds()) + final WavefrontConfig wavefrontConfig = new WavefrontConfig() { + @Override + public String get(final String key) { + return null; + } + + @Override + public String uri() { + return micrometerWavefrontConfig.getUri(); + } + + @Override + public String apiToken() { + return micrometerWavefrontConfig.getApiKey(); + } + }; + + final WavefrontSender wavefrontSender = WavefrontMeterRegistry.getDefaultSenderBuilder(wavefrontConfig) + .flushIntervalSeconds((int)wavefrontConfig.step().toSeconds()) .build(); - Metrics.addRegistry(WavefrontMeterRegistry.builder(micrometerConfig) + Metrics.addRegistry(WavefrontMeterRegistry.builder(wavefrontConfig) .wavefrontSender(wavefrontSender) .build()); } + { + final MicrometerConfiguration micrometerNewRelicConfig = micrometerConfigurationByName.get("newrelic"); + + Metrics.addRegistry(new NewRelicMeterRegistry(new NewRelicConfig() { + @Override + public String get(final String key) { + return null; + } + + @Override + public String accountId() { + return micrometerNewRelicConfig.getAccountId(); + } + + @Override + public String apiKey() { + return micrometerNewRelicConfig.getApiKey(); + } + }, Clock.SYSTEM)); + } + environment.getObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); environment.getObjectMapper().setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE); environment.getObjectMapper().setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/configuration/MicrometerConfiguration.java b/service/src/main/java/org/whispersystems/textsecuregcm/configuration/MicrometerConfiguration.java index d4b3563f0..e1df62171 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/configuration/MicrometerConfiguration.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/configuration/MicrometerConfiguration.java @@ -5,28 +5,35 @@ import io.micrometer.wavefront.WavefrontConfig; import javax.validation.constraints.NotEmpty; -public class MicrometerConfiguration implements WavefrontConfig { +public class MicrometerConfiguration { @JsonProperty @NotEmpty + private String name; + + @JsonProperty private String uri; @JsonProperty @NotEmpty - private String apiToken; + private String apiKey; - @Override - public String get(final String key) { - return null; + @JsonProperty + private String accountId; + + public String getName() { + return name; } - @Override - public String uri() { + public String getUri() { return uri; } - @Override - public String apiToken() { - return apiToken; + public String getApiKey() { + return apiKey; + } + + public String getAccountId() { + return accountId; } }