Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import static io.opentelemetry.api.common.AttributeKey.stringKey;

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

/** A builder of {@link Attributes} supporting an arbitrary number of key-value pairs. */
Expand Down Expand Up @@ -100,6 +101,19 @@ default AttributesBuilder put(String key, String... value) {
return put(stringArrayKey(key), Arrays.asList(value));
}

/**
* Puts a List attribute into this.
*
* @return this Builder
*/
@SuppressWarnings("unchecked")
default <T> AttributesBuilder put(AttributeKey<List<T>> key, T... value) {
if (value == null) {
return this;
}
return put(key, Arrays.asList(value));
}

/**
* Puts a Long array attribute into this.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,52 @@ void builder() {
assertThat(attributes).isEqualTo(wantAttributes);
}

@Test
void builderWithAttributeKeyList() {
Attributes attributes =
Attributes.builder()
.put("string", "value1")
.put(longKey("long"), 10)
.put(stringArrayKey("anotherString"), "value1", "value2", "value3")
.put(longArrayKey("anotherLong"), 10L, 20L, 30L)
.put(booleanArrayKey("anotherBoolean"), true, false, true)
.build();

Attributes wantAttributes =
Attributes.of(
stringKey("string"),
"value1",
longKey("long"),
10L,
stringArrayKey("anotherString"),
Arrays.asList("value1", "value2", "value3"),
longArrayKey("anotherLong"),
Arrays.asList(10L, 20L, 30L),
booleanArrayKey("anotherBoolean"),
Arrays.asList(true, false, true));
assertThat(attributes).isEqualTo(wantAttributes);

AttributesBuilder newAttributes = attributes.toBuilder();
newAttributes.put("newKey", "newValue");
assertThat(newAttributes.build())
.isEqualTo(
Attributes.of(
stringKey("string"),
"value1",
longKey("long"),
10L,
stringArrayKey("anotherString"),
Arrays.asList("value1", "value2", "value3"),
longArrayKey("anotherLong"),
Arrays.asList(10L, 20L, 30L),
booleanArrayKey("anotherBoolean"),
Arrays.asList(true, false, true),
stringKey("newKey"),
"newValue"));
// Original not mutated.
assertThat(attributes).isEqualTo(wantAttributes);
}

@Test
void builder_arrayTypes() {
Attributes attributes =
Expand Down
3 changes: 2 additions & 1 deletion dependencyManagement/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ val DEPENDENCY_BOMS = listOf(
"io.zipkin.brave:brave-bom:5.13.7",
"io.zipkin.reporter2:zipkin-reporter-bom:2.16.3",
"org.junit:junit-bom:5.8.2",
"org.testcontainers:testcontainers-bom:1.16.3"
"org.testcontainers:testcontainers-bom:1.16.3",
"org.yaml:snakeyaml:1.30"
)

val DEPENDENCY_SETS = listOf(
Expand Down
4 changes: 3 additions & 1 deletion docs/apidiffs/current_vs_latest/opentelemetry-api.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
Comparing source compatibility of against
No changes.
***! MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.api.common.AttributesBuilder (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++! NEW METHOD: PUBLIC(+) io.opentelemetry.api.common.AttributesBuilder put(io.opentelemetry.api.common.AttributeKey, java.lang.Object[])
1 change: 0 additions & 1 deletion exporters/otlp-http/logs/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ dependencies {
implementation(project(":exporters:otlp:common"))

implementation("com.squareup.okhttp3:okhttp")
implementation("com.squareup.okio:okio")

testImplementation(project(":sdk:testing"))

Expand Down
1 change: 0 additions & 1 deletion exporters/otlp-http/metrics/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ dependencies {
implementation(project(":exporters:otlp:common"))

implementation("com.squareup.okhttp3:okhttp")
implementation("com.squareup.okio:okio")

testImplementation(project(":sdk:testing"))

Expand Down
1 change: 0 additions & 1 deletion exporters/otlp-http/trace/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ dependencies {
implementation(project(":exporters:otlp:common"))

implementation("com.squareup.okhttp3:okhttp")
implementation("com.squareup.okio:okio")

testImplementation(project(":sdk:testing"))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ static class PrometheusHttpServerIntegrationTest extends AbstractPrometheusInteg
static class PrometheusCollectorIntegrationTest extends AbstractPrometheusIntegrationTest {
private final HTTPServer server;

// Tests deprecated class
@SuppressWarnings("deprecation")
PrometheusCollectorIntegrationTest() throws IOException {
server = new HTTPServer(0);
port = server.getPort();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,16 @@
* A reader of OpenTelemetry metrics that exports into Prometheus as a Collector.
*
* <p>Usage: <code>sdkMeterProvider.registerMetricReader(PrometheusCollector.create());</code>
*
* @deprecated This class was intended to fill OpenTelemetry metrics into a Prometheus registry.
* Instead, use {@link PrometheusHttpServer} to expose OpenTelemetry metrics as a Prometheus
* HTTP endpoint. If you generate metrics with Micrometer in addition to OpenTelemetry, also use
* <a
* href="https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/instrumentation/micrometer/micrometer-1.5/library">
* Micrometer OpenTelemetry Integration</a> to export Micrometer metrics together. If your use
* case is not handled by these, please file an issue to let us know.
*/
@Deprecated
public final class PrometheusCollector extends Collector implements MetricReader {
private final MetricProducer metricProducer;
private volatile boolean registered = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
// Tests deprecated class
@SuppressWarnings("deprecation")
class PrometheusCollectorTest {
@Mock MetricProducer metricProducer;
PrometheusCollector prometheusCollector;
Expand Down
83 changes: 83 additions & 0 deletions sdk-extensions/metric-incubator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# OpenTelemetry Metric Incubator

[![Javadocs][javadoc-image]][javadoc-url]

This artifact contains experimental code related to metrics.

## View File Configuration

Adds support for file based YAML configuration of Metric SDK Views.

For example, suppose `/Users/user123/view.yaml` has the following content:

```yaml
- selector:
instrument_name: my-instrument
instrument_type: COUNTER
meter_name: my-meter
meter_version: 1.0.0
meter_schema_url: http://example.com
view:
name: new-instrument-name
description: new-description
aggregation: histogram
attribute_keys:
- foo
- bar
```

The equivalent view configuration would be:

```
SdkMeterProvider.builder()
.registerView(
InstrumentSelector.builder()
.setInstrumentName("my-instrument")
.setInstrumentType(InstrumentType.COUNTER)
.setMeterSelector(
MeterSelector.builder()
.setName("my-meter")
.setVersion("1.0.0")
.setSchemaUrl("http://example.com")
.build())
.build(),
View.builder()
.setName("new-instrument")
.setDescription("new-description")
.setAggregation(Aggregation.histogram())
.filterAttributes(key -> new HashSet<>(Arrays.asList("foo", "bar")).contains(key))
.build());
```

If using [autoconfigure](../autoconfigure) with this artifact on your classpath, it will automatically load a list of view config files specified via environment variable or system property:

| System property | Environment variable | Purpose |
|---------------------------------------|---------------------------------------|------------------------------------------------------|
| otel.experimental.metrics.view-config | OTEL_EXPERIMENTAL_METRICS_VIEW_CONFIG | List of files containing view configuration YAML [1] |

**[1]** In addition to absolute paths, resources on the classpath packaged with a jar can be loaded.
For example, `otel.experimental.metrics.view-config=classpath:/my-view.yaml` loads the
resource `/my-view.yaml`.

If not using autoconfigure, a file can be used to configure views as follows:

```
SdkMeterProviderBuilder builder = SdkMeterProvider.builder();
try (FileInputStream fileInputStream = new FileInputStream("/Users/user123/view.yaml")) {
ViewConfig.registerViews(builder, fileInputStream);
}
```

Notes on usage:

- Many view configurations can live in one file. The YAML is parsed as an array of view
configurations.
- At least one selection field is required, but including all is not necessary. Any omitted fields
will result in the default from `InstrumentSelector` being used.
- At least one view field is required, but including all is not required. Any omitted fields will
result in the default from `View` being used.
- Advanced selection criteria, like regular expressions, is not yet supported.

[javadoc-image]: https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-extension-metric-incubator

[javadoc-url]: https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-extension-metric-incubator
22 changes: 22 additions & 0 deletions sdk-extensions/metric-incubator/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
plugins {
id("otel.java-conventions")
id("otel.publish-conventions")
}

description = "OpenTelemetry SDK Metric Incubator"
otelJava.moduleName.set("io.opentelemetry.sdk.extension.metric.incubator")

dependencies {
implementation(project(":sdk:metrics"))
implementation(project(":sdk-extensions:autoconfigure-spi"))

implementation("org.yaml:snakeyaml")

annotationProcessor("com.google.auto.value:auto-value")

testImplementation(project(":sdk:testing"))
testImplementation(project(":sdk-extensions:autoconfigure"))
testImplementation(project(":sdk:metrics-testing"))

testImplementation("com.google.guava:guava")
}
1 change: 1 addition & 0 deletions sdk-extensions/metric-incubator/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
otel.release=alpha
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.sdk.viewconfig;

import com.google.auto.value.AutoValue;
import io.opentelemetry.sdk.metrics.common.InstrumentType;
import javax.annotation.Nullable;

@AutoValue
abstract class SelectorSpecification {

static AutoValue_SelectorSpecification.Builder builder() {
return new AutoValue_SelectorSpecification.Builder();
}

@Nullable
abstract String getInstrumentName();

@Nullable
abstract InstrumentType getInstrumentType();

@Nullable
abstract String getMeterName();

@Nullable
abstract String getMeterVersion();

@Nullable
abstract String getMeterSchemaUrl();

@AutoValue.Builder
interface Builder {
Builder instrumentName(@Nullable String instrumentName);

Builder instrumentType(@Nullable InstrumentType instrumentType);

Builder meterName(@Nullable String meterName);

Builder meterVersion(@Nullable String meterVersion);

Builder meterSchemaUrl(@Nullable String meterSchemaUrl);

SelectorSpecification build();
}
}
Loading