Skip to content

Commit

Permalink
Support OTEL_SERVICE_NAME (#353)
Browse files Browse the repository at this point in the history
* Support OTEL_SERVICE_NAME

* spotless
  • Loading branch information
Mateusz Rzeszutek authored Jul 13, 2021
1 parent 657af1e commit 3e878f0
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 9 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ Then the runtime parameters would be updated to:

```bash
java -javaagent:./splunk-otel-javaagent.jar \
-Dotel.resource.attributes=service.name=my-java-app \
-Dotel.service.name=my-java-app \
-jar myapp.jar https://splunk.com
```

Expand All @@ -121,9 +121,9 @@ To see the Java Agent in action with sample applications, see our

### Basic Configuration

The service name resource attribute is the only configuration option
that needs to be specified. You can set it by adding a `service.name`
attribute as shown in the [example above](#getting-started).
The service name is the only configuration option that is required. You can
specify it by setting the `otel.service.name` system property as shown in the
[example above](#getting-started).

A few other configuration options that may need to be changed or set are:

Expand All @@ -139,12 +139,12 @@ A few other configuration options that may need to be changed or set are:
- Environment resource attribute `deployment.environment` to specify what
environment the span originated from. For example:
```
-Dotel.resource.attributes=service.name=my-java-app,deployment.environment=production
-Dotel.resource.attributes=deployment.environment=production
```
- Service version resource attribute `service.version` to specify the version
of your instrumented application. For example:
```
-Dotel.resource.attributes=service.name=my-java-app,service.version=1.2.3
-Dotel.resource.attributes=deployment.environment=production,service.version=1.2.3
```

The `deployment.environment` and `service.version` resource attributes are not
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,46 @@
import io.opentelemetry.javaagent.extension.AgentListener;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
import java.util.Map;
import java.util.function.Consumer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@AutoService(AgentListener.class)
public class ServiceNameChecker implements AgentListener {
private static final Logger log = LoggerFactory.getLogger(ServiceNameChecker.class);

private final Consumer<String> logWarn;

public ServiceNameChecker() {
this(log::warn);
}

// visible for tests
ServiceNameChecker(Consumer<String> logWarn) {
this.logWarn = logWarn;
}

@Override
public void beforeAgent(Config config) {
Map<String, String> resourceAttributes = config.getMapProperty("otel.resource.attributes");
if (!resourceAttributes.containsKey(ResourceAttributes.SERVICE_NAME.getKey())) {
log.warn(
if (serviceNameNotConfigured(config)) {
logWarn.accept(
"Resource attribute 'service.name' is not set: your service is unnamed and will be difficult to identify."
+ " Please Set your service name using the 'OTEL_RESOURCE_ATTRIBUTES' environment variable"
+ " or the 'otel.resource.attributes' system property."
+ " E.g. 'export OTEL_RESOURCE_ATTRIBUTES=\"service.name=<YOUR_SERVICE_NAME_HERE>\"'");
}
}

// make sure this listener is one of the first things run by the agent
@Override
public int order() {
return -100;
}

private static boolean serviceNameNotConfigured(Config config) {
String serviceName = config.getProperty("otel.service.name");
Map<String, String> resourceAttributes = config.getMapProperty("otel.resource.attributes");
return serviceName == null
&& !resourceAttributes.containsKey(ResourceAttributes.SERVICE_NAME.getKey());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright Splunk Inc.
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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 com.splunk.opentelemetry;

import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;

import io.opentelemetry.instrumentation.api.config.Config;
import java.util.Map;
import java.util.function.Consumer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
class ServiceNameCheckerTest {
@Mock Consumer<String> logWarn;

@Test
void shouldLogWarnWhenNeitherServiceNameNorResourceAttributeIsConfigured() {
// given
var config = Config.newBuilder().build();

var underTest = new ServiceNameChecker(logWarn);

// when
underTest.beforeAgent(config);

// then
verify(logWarn).accept(anyString());
}

@Test
void shouldNotLogWarnWhenServiceNameIsConfigured() {
// given
var config = Config.newBuilder().readProperties(Map.of("otel.service.name", "test")).build();

var underTest = new ServiceNameChecker(logWarn);

// when
underTest.beforeAgent(config);

// then
verifyNoInteractions(logWarn);
}

@Test
void shouldNotLogWarnWhenResourceAttributeIsConfigured() {
// given
var config =
Config.newBuilder()
.readProperties(Map.of("otel.resource.attributes", "service.name=test"))
.build();

var underTest = new ServiceNameChecker(logWarn);

// when
underTest.beforeAgent(config);

// then
verifyNoInteractions(logWarn);
}
}
1 change: 1 addition & 0 deletions docs/advanced-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export OTEL_PROPAGATORS=b3multi
| `otel.instrumentation.methods.include` | `OTEL_INSTRUMENTATION_METHODS_INCLUDE` | unset | Stable | Same as adding `@WithSpan` annotation functionality for the target method string. <details><summary>Format</summary>`my.package.MyClass1[method1,method2];my.package.MyClass2[method3]`</details>
| `otel.instrumentation.opentelemetry-annotations.exclude-methods` | `OTEL_INSTRUMENTATION_OPENTELEMETRY_ANNOTATIONS_EXCLUDE_METHODS` | unset | Stable | Suppress `@WithSpan` instrumentation for specific methods. <details><summary>Format</summary>`my.package.MyClass1[method1,method2];my.package.MyClass2[method3]`</details>
| `otel.resource.attributes` | `OTEL_RESOURCE_ATTRIBUTES` | unset | Stable | Comma-separated list of resource attributes added to every reported span. <details><summary>Example</summary>`key1=val1,key2=val2`</details>
| `otel.service.name` | `OTEL_SERVICE_NAME` | unset | Stable | Sets the value of the `service.name` resource attribute. If `service.name` is also set in `otel.resource.attributes`, this setting takes precedence.
| `otel.span.attribute.count.limit` | `OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT` | unlimited | Stable | Maximum number of attributes per span.
| `otel.span.event.count.limit` | `OTEL_SPAN_EVENT_COUNT_LIMIT` | unlimited | Stable | Maximum number of events per span.
| `otel.span.link.count.limit` | `OTEL_SPAN_LINK_COUNT_LIMIT` | `1000` | Stable | Maximum number of links per span.
Expand Down

0 comments on commit 3e878f0

Please sign in to comment.