Skip to content

Commit

Permalink
PR feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
jack-berg committed Nov 20, 2023
1 parent 6a18b7e commit 2cf58ea
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 11 deletions.
44 changes: 40 additions & 4 deletions newrelic-opentelemetry-agent-extension/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,48 @@ will need to download the New Relic OpenTelemetry Agent extension, which is publ
**IMPORTANT**: This package is marked "-alpha". All APIs and behaviors are subject to change. Please use with caution and be sure to check the release notes for
changes before upgrading.

Calls to the [Java agent API](https://docs.newrelic.com/docs/apm/agents/java-agent/api-guides/guide-using-java-agent-api/) API will be routed through the
See [OpenTelemetry Java Getting started guide](https://docs.newrelic.com/docs/more-integrations/open-source-telemetry-integrations/opentelemetry/get-started/opentelemetry-tutorial-java/)
for information on configuring the OpenTelemetry Java agent to export to New Relic.

## Supported Operations

Calls to the [Java agent API](https://docs.newrelic.com/docs/apm/agents/java-agent/api-guides/guide-using-java-agent-api/) will be routed through the
OpenTelemetry API. Note that many concepts of the New Relic API do not map to an equivalent in the OpenTelemetry API. When an API is called which is not bridged
to OpenTelemetry, the extension will log details from logger named `com.newrelic.opentelemetry.OpenTelemetryNewRelic` at `FINER` level (if `FINEST` level is
enabled, a stacktrace to the calling code is included).

TODO: add table defining which NewRelic APIs are supported and describe the behavior of each
The following operations are supported:

See [OpenTelemetry Java Getting started guide](https://docs.newrelic.com/docs/more-integrations/open-source-telemetry-integrations/opentelemetry/get-started/opentelemetry-tutorial-java/)
for information on configuring the OpenTelemetry Java agent to export to New Relic.
* NewRelic Metric APIs for recording custom timeslice metrics. Record to OpenTelemetry dimensional metrics, where the name of the metric is `newrelic.timeslice.value` for `recordMetric`, `recordResponseTimeMetric`, and `newrelic.timeslice.counter.value` for `incrementCounter`. The name of timeslice metric is set to the value of a dimension on metric with key `metricTimesliceName`.
* `NewRelic.recordMetric(String, float)`
* `NewRelic.recordResponseTimeMetric(String, long)`
* `NewRelic.incrementCounter(String)`
* `NewRelic.incrementCounter(String, int)`
* `MetricAggregator.recordMetric(String, float)`
* `MetricAggregator.recordResponseTimeMetric(String, long)`
* `MetricAggregator.incrementCounter(String)`
* `MetricAggregator.incrementCounter(String, int)`
* NewRelic Error APIs for recording errors. Record the error on whatever OpenTelemetry span is currently active (i.e. `Span.current()`) using `recordException`. Sets the active span status to `ERROR`.
* `NewRelic.noticeError(Throwable, Map<String, ?>)`
* `NewRelic.noticeError(Throwable)`
* `NewRelic.noticeError(String, Map<String, ?>)`
* `NewRelic.noticeError(String)`
* `NewRelic.noticeError(Throwable, Map<String, ?>, boolean)`
* `NewRelic.noticeError(Throwable, boolean)`
* `NewRelic.noticeError(String, Map<String, ?>, boolean)`
* `NewRelic.noticeError(String, boolean)`
* `ErrorApi.noticeError(Throwable, Map<String, ?>)`
* `ErrorApi.noticeError(Throwable)`
* `ErrorApi.noticeError(String, Map<String, ?>)`
* `ErrorApi.noticeError(String)`
* `ErrorApi.noticeError(Throwable, Map<String, ?>, boolean)`
* `ErrorApi.noticeError(Throwable, boolean)`
* `ErrorApi.noticeError(String, Map<String, ?>, boolean)`
* `ErrorApi.noticeError(String, boolean)`
* NewRelic TracedMethod APIs for adding custom attributes. Record the custom attributes to whatever OpenTelemetry span is currently active (i.e. `Span.current()`).
* `TracedMethod.addCustomAttribute(String, Number)`
* `TracedMethod.addCustomAttribute(String, Strg)`
* `TracedMethod.addCustomAttribute(String, boolean)`
* `TracedMethod.addCustomAttributes(Map<String, Object>)`
* NewRelic Insights API for recording custom events. Record the event as an OpenTelemetry LogRecord following the [semantic conventions for events](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/events.md). The `event.domain` is set to `newrelic.agent_api`, the `event.name` is set to the name of the custom event.
* `Insights.recordCustomEvent(String, Map<String, ?>)`
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

final class OpenTelemetryInsights implements Insights {

private static final String NEW_RELIC_AGENT_API_DOMAIN = "newrelic.agent_api";
private final io.opentelemetry.api.logs.Logger logger;

private OpenTelemetryInsights(OpenTelemetry openTelemetry) {
Expand All @@ -24,7 +25,7 @@ static OpenTelemetryInsights create(OpenTelemetry openTelemetry) {
public void recordCustomEvent(String eventType, Map<String, ?> attributesMap) {
Attributes attributes = OpenTelemetryNewRelic.toAttributes(attributesMap)
// TODO: is this the right domain?
.put(SemanticAttributes.EVENT_DOMAIN, "newrelic.api")
.put(SemanticAttributes.EVENT_DOMAIN, NEW_RELIC_AGENT_API_DOMAIN)
.put(SemanticAttributes.EVENT_NAME, eventType)
.build();
// TODO: use event API when stable. For now, its not possible to without taking
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.newrelic.api.agent.ErrorGroupCallback;
import com.newrelic.api.agent.Request;
import com.newrelic.api.agent.Response;
import com.newrelic.api.agent.TransactionNamePriority;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.AttributesBuilder;

Expand Down Expand Up @@ -86,6 +87,10 @@ public static void noticeError(String message, boolean expected) {
getAgent().getErrorApi().noticeError(message, expected);
}

public static void setErrorGroupCallback(ErrorGroupCallback errorGroupCallback) {
getAgent().getErrorApi().setErrorGroupCallback(errorGroupCallback);
}

// **************************** Transaction APIs ********************************//

public static void addCustomParameter(String key, Number value) {
Expand All @@ -109,11 +114,11 @@ public static void setUserId(String userId) {
}

public static void setTransactionName(String category, String name) {
logUnsupportedMethod("NewRelic", "setTransactionName");
getAgent().getTransaction().setTransactionName(TransactionNamePriority.CUSTOM_LOW, true, category, name);
}

public static void ignoreTransaction() {
logUnsupportedMethod("NewRelic", "ignoreTransaction");
getAgent().getTransaction().ignore();
}

public static void ignoreApdex() {
Expand Down Expand Up @@ -174,9 +179,7 @@ public static void setInstanceName(String instanceName) {
logUnsupportedMethod("NewRelic", "setInstanceName");
}

public static void setErrorGroupCallback(ErrorGroupCallback errorGroupCallback) {
getAgent().getErrorApi().setErrorGroupCallback(errorGroupCallback);
}
// Internal helpers

static void logUnsupportedMethod(String className, String methodName) {
// If FINER or FINEST is enabled, indicate that an unsupported method was called.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ void recordCustomEvent() {
assertThat(exporter.getFinishedLogRecordItems())
.satisfiesExactly(logRecordData -> assertThat(logRecordData)
.hasAttributesSatisfying(
equalTo(AttributeKey.stringKey("event.domain"), "newrelic.api"),
equalTo(AttributeKey.stringKey("event.domain"), "newrelic.agent_api"),
equalTo(AttributeKey.stringKey("event.name"), "eventType"),
satisfies(AttributeKey.doubleKey("double_key"), value -> value.isCloseTo(1.1, Offset.offset(0.01))),
equalTo(AttributeKey.longKey("long_key"), 1),
Expand Down

0 comments on commit 2cf58ea

Please sign in to comment.