Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable NewRelicMeterRegistry to publish via APM in addition to API (resolves #1761) #1854

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def VERSIONS = [
// <=1.5.11 or 1.5.18 doesn't break with Micrometer, but open metrics won't be correct necessarily.
'com.netflix.hystrix:hystrix-core:1.5.12',
'com.netflix.spectator:spectator-reg-atlas:latest.release',
'com.newrelic.agent.java:newrelic-api:latest.release',
'com.signalfx.public:signalfx-java:latest.release',
'com.squareup.okhttp3:okhttp:latest.release',
'com.wavefront:wavefront-sdk-java:latest.release',
Expand Down Expand Up @@ -52,7 +53,8 @@ def VERSIONS = [
'org.hdrhistogram:HdrHistogram:latest.release',
'org.hibernate:hibernate-entitymanager:latest.release',
'org.hsqldb:hsqldb:latest.release',
'org.jooq:jooq:latest.release',
// Pin version temporarily to restore builds. See gh-1852
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Included so the build will pass, can be removed once #1852 is resolved

'org.jooq:jooq:3.12.+',
'org.jsr107.ri:cache-ri-impl:1.0.0',
'org.junit.jupiter:junit-jupiter:latest.release',
'org.junit.platform:junit-platform-launcher:latest.release',
Expand Down
5 changes: 5 additions & 0 deletions implementations/micrometer-registry-new-relic/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ dependencies {
api project(':micrometer-core')

implementation 'org.slf4j:slf4j-api'
implementation 'com.newrelic.agent.java:newrelic-api'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding APM support requires the addition of a compile time dependency on the newrelic-api.
The API is fairly light, containing only annotations, interfaces, POJOs, and enums, so I don't expect this to cause any issues for consumers not using the APM integration


testImplementation project(':micrometer-test')

testImplementation 'ch.qos.logback:logback-classic'
testImplementation 'com.fasterxml.jackson.core:jackson-databind'
testImplementation 'com.google.guava:guava'
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2017 Pivotal Software, Inc.
* Copyright 2019 Pivotal Software, Inc.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -15,8 +15,8 @@
*/
package io.micrometer.newrelic;

import io.micrometer.core.instrument.config.MissingRequiredConfigurationException;
import io.micrometer.core.instrument.step.StepRegistryConfig;
import io.micrometer.core.lang.Nullable;

/**
* Configuration for {@link NewRelicMeterRegistry}.
Expand All @@ -32,46 +32,75 @@ default String prefix() {
}

/**
* When this is {@code false}, the New Relic eventType value will be set to {@link #eventType()}. Otherwise, the meter name will be used.
* When {@code true}, the meter name will be used as the {@code eventType} for the NewRelic event.
* When {@code false}, the {@code eventType} will be set to {@link #eventType()}.
* <br><br>
* Defaults to {@code false}.
* @return whether to use meter names as the New Relic eventType value
*
* @return whether to use meter names as the NewRelic {@code eventType}
*/
default boolean meterNameEventTypeEnabled() {
String v = get(prefix() + ".meterNameEventTypeEnabled");
return Boolean.parseBoolean(v);
return Boolean.parseBoolean(get(prefix() + ".meterNameEventTypeEnabled"));
}

/**
* This configuration property will only be used if {@link #meterNameEventTypeEnabled()} is {@code false}.
* Default value is {@code MicrometerSample}.
* The {@code eventType} to use for events sent to NewRelic.
* <br><br>
* Ignored if {@link #meterNameEventTypeEnabled()} is {@code true}.
* <br><br>
* Defaults to {@code MicrometerSample}.
*
* @return static eventType value to send to New Relic for all metrics.
*/
default String eventType() {
String v = get(prefix() + ".eventType");
if (v == null)
return "MicrometerSample";
return v;
return (v == null) ? "MicrometerSample" : v;
}

/**
* The {@link NewRelicIntegration} method to use for reporting metric data.
* <br><br>
* Defaults to {@link NewRelicIntegration#API}.
*
* @return The NewRelic integration method
*/
default NewRelicIntegration integration() {
return NewRelicIntegration.fromString(get(prefix() + ".integration")).orElse(NewRelicIntegration.API);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default to API integration to preserve existing behavior

}

/**
* The <a href="https://docs.newrelic.com/docs/apis/get-started/intro-apis/types-new-relic-api-keys#event-insert-key">NewRelic Insights API key</a> to use.
* <br><br>
* Ignored when {@link #integration()} is not {@link NewRelicIntegration#API}.
*
* @return The NewRelic Insights API key
*/
@Nullable
default String apiKey() {
String v = get(prefix() + ".apiKey");
if (v == null)
throw new MissingRequiredConfigurationException("apiKey must be set to report metrics to New Relic");
return v;
return get(prefix() + ".apiKey");
}

/**
* The ID of the NewRelic account to report Insights data to.
* <br><br>
* Ignored when {@link #integration()} is not {@link NewRelicIntegration#API}.
*
* @return The NewRelic account ID
*/
@Nullable
default String accountId() {
String v = get(prefix() + ".accountId");
if (v == null)
throw new MissingRequiredConfigurationException("accountId must be set to report metrics to New Relic");
return v;
return get(prefix() + ".accountId");
}

/**
* @return The URI for the New Relic insights API. The default is
* {@code https://insights-collector.newrelic.com}. If you need to pass through
* a proxy, you can change this value.
* The URI for the New Relic insights API to report events to.
* The default is {@code https://insights-collector.newrelic.com}, but this can be changed if needed to pass data through a proxy.
* <br><br>
* Ignored when {@link #integration()} is not {@link NewRelicIntegration#API}.
*
* @return The NewRelic Insights API endpoint to use
*/
@Nullable
default String uri() {
String v = get(prefix() + ".uri");
return (v == null) ? "https://insights-collector.newrelic.com" : v;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* Copyright 2019 Pivotal Software, Inc.
* <p>
* 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
* <p>
* https://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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 io.micrometer.newrelic;

import io.micrometer.core.lang.Nullable;

import java.util.Map;
import java.util.Optional;

/**
* Enum representing the possible NewRelic integration methods.
*
* @author Galen Schmidt
*/
public enum NewRelicIntegration {

/**
* API integration, in which the {@link NewRelicMeterRegistry}
* will directly call the NewRelic REST API to publish metrics.
*/
API,

/**
* APM integration, in which the {@link NewRelicMeterRegistry}
* will use {@link com.newrelic.api.agent.Insights#recordCustomEvent(String, Map)} to publish metrics.
*/
APM;

/**
* Returns the {@code NewRelicIntegration} for the given name (case insensitive),
* or {@link Optional#empty()} if none match.
*
* @param input The enum name, as returned by {@link #name()}
* @return The enum value with the given name, if one exists
*/
public static Optional<NewRelicIntegration> fromString(@Nullable String input) {

for (NewRelicIntegration value : NewRelicIntegration.values()) {
if (value.name().equalsIgnoreCase(input)) {
return Optional.of(value);
}
}

return Optional.empty();
}

}
Loading