Skip to content

Commit c3a0119

Browse files
committed
add new classifications
1 parent db6e9bd commit c3a0119

File tree

21 files changed

+268
-43
lines changed

21 files changed

+268
-43
lines changed

docs/instrumentation-list.yaml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ libraries:
6262
description: This instrumentation provides context propagation for Akka actors,
6363
it does not emit any telemetry on its own.
6464
source_path: instrumentation/akka/akka-actor-2.3
65+
classification:
66+
- propagator
6567
scope:
6668
name: io.opentelemetry.akka-actor-2.3
6769
target_versions:
@@ -73,6 +75,8 @@ libraries:
7375
description: This instrumentation provides context propagation for the Akka Fork-Join
7476
Pool, it does not emit any telemetry on its own.
7577
source_path: instrumentation/akka/akka-actor-fork-join-2.5
78+
classification:
79+
- propagator
7680
scope:
7781
name: io.opentelemetry.akka-actor-fork-join-2.5
7882
target_versions:
@@ -668,6 +672,8 @@ libraries:
668672
description: |
669673
This instrumentation does not emit telemetry on its own. Instead, it augments existing SERVER spans and HTTP server metrics with the HTTP route and Shenyu specific attributes.
670674
source_path: instrumentation/apache-shenyu-2.4
675+
classification:
676+
- enricher
671677
scope:
672678
name: io.opentelemetry.apache-shenyu-2.4
673679
target_versions:
@@ -913,6 +919,8 @@ libraries:
913919
description: |
914920
This instrumentation does not emit telemetry on its own. Instead, it hooks into the Avaje Jex Context to extract the HTTP route and attach it to existing SERVER spans and HTTP server metrics.
915921
source_path: instrumentation/avaje-jex-3.0
922+
classification:
923+
- enricher
916924
minimum_java_version: 21
917925
scope:
918926
name: io.opentelemetry.avaje-jex-3.0
@@ -983,6 +991,14 @@ libraries:
983991
type: STRING
984992
- name: user_agent.original
985993
type: STRING
994+
- name: aws-lambda-events-3.11
995+
source_path: instrumentation/aws-lambda/aws-lambda-events-3.11
996+
scope:
997+
name: io.opentelemetry.aws-lambda-events-3.11
998+
target_versions:
999+
library:
1000+
- com.amazonaws:aws-lambda-java-events:3.11.0
1001+
- com.amazonaws:aws-lambda-java-core:1.0.0
9861002
- name: aws-sdk-1.11
9871003
description: |
9881004
This instrumentation covers the AWS SDK 1.11+ client library, enabling messaging and client spans and metrics for calls to AWS services including DynamoDB, EC2, Kinesis, Lambda, RDS, S3, secrets manager, SNS/SQS and step functions.
@@ -1572,6 +1588,8 @@ libraries:
15721588
description: This instrumentation enables context propagation for the Azure Core
15731589
library, it does not emit any telemetry on its own.
15741590
source_path: instrumentation/azure-core/azure-core-1.14
1591+
classification:
1592+
- propagator
15751593
scope:
15761594
name: io.opentelemetry.azure-core-1.14
15771595
target_versions:
@@ -1581,6 +1599,8 @@ libraries:
15811599
description: This instrumentation enables context propagation for the Azure Core
15821600
library, it does not emit any telemetry on its own.
15831601
source_path: instrumentation/azure-core/azure-core-1.19
1602+
classification:
1603+
- propagator
15841604
scope:
15851605
name: io.opentelemetry.azure-core-1.19
15861606
target_versions:
@@ -1590,6 +1610,8 @@ libraries:
15901610
description: This instrumentation enables context propagation for the Azure Core
15911611
library, it does not emit any telemetry on its own.
15921612
source_path: instrumentation/azure-core/azure-core-1.36
1613+
classification:
1614+
- propagator
15931615
scope:
15941616
name: io.opentelemetry.azure-core-1.36
15951617
target_versions:
@@ -2217,6 +2239,8 @@ libraries:
22172239
description: |
22182240
Couchbase instrumentation is owned by the Couchbase project for versions 3+. This instrumentation automatically configures the instrumentation provided by the Couchbase library.
22192241
source_path: instrumentation/couchbase/couchbase-3.1
2242+
classification:
2243+
- configuration
22202244
scope:
22212245
name: io.opentelemetry.couchbase-3.1
22222246
target_versions:
@@ -2226,6 +2250,8 @@ libraries:
22262250
description: |
22272251
Couchbase instrumentation is owned by the Couchbase project for versions 3+. This instrumentation automatically configures the instrumentation provided by the Couchbase library.
22282252
source_path: instrumentation/couchbase/couchbase-3.1.6
2253+
classification:
2254+
- configuration
22292255
scope:
22302256
name: io.opentelemetry.couchbase-3.1.6
22312257
target_versions:
@@ -2235,6 +2261,8 @@ libraries:
22352261
description: |
22362262
Couchbase instrumentation is owned by the Couchbase project for versions 3+. This instrumentation automatically configures the instrumentation provided by the Couchbase library.
22372263
source_path: instrumentation/couchbase/couchbase-3.2
2264+
classification:
2265+
- configuration
22382266
scope:
22392267
name: io.opentelemetry.couchbase-3.2
22402268
target_versions:
@@ -2817,6 +2845,8 @@ libraries:
28172845
description: |
28182846
The executor instrumentation ensures that context is automatically propagated when using common Java executors (e.g., ThreadPoolExecutor, ScheduledThreadPoolExecutor, ForkJoinPool). When a task is submitted, the current context is captured and bound to the task. Then, when the task eventually runs, even if it’s on a different thread, the instrumentation reactivates that context, enabling consistent correlation across concurrent and asynchronous workflows.
28192847
source_path: instrumentation/executors
2848+
classification:
2849+
- propagator
28202850
scope:
28212851
name: io.opentelemetry.executors
28222852
target_versions:
@@ -5220,6 +5250,8 @@ libraries:
52205250
description: |
52215251
This instrumentation does not emit telemetry on its own. Instead, it extracts the HTTP route and attaches it to SERVER spans and HTTP server metrics.
52225252
source_path: instrumentation/spark-2.3
5253+
classification:
5254+
- enricher
52235255
scope:
52245256
name: io.opentelemetry.spark-2.3
52255257
target_versions:
@@ -5648,6 +5680,8 @@ libraries:
56485680
This instrumentation does not emit any telemetry on its own. Instead, it captures enduser attributes, and is only enabled when at least one of the `enduser` configurations is enabled.
56495681
NOTE: The `enduser` attributes have been deprecated and will be removed in 3.0+ of the java agent.
56505682
source_path: instrumentation/spring/spring-security-config-6.0
5683+
classification:
5684+
- enricher
56515685
minimum_java_version: 17
56525686
scope:
56535687
name: io.opentelemetry.spring-security-config-6.0

instrumentation-docs/readme.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,12 @@ public class SpringWebInstrumentationModule extends InstrumentationModule
108108
## Instrumentation metadata
109109

110110
* classification
111-
* `library` - Instrumentation that targets a library
112-
* `internal` - Instrumentation that is used internally by the OpenTelemetry Java Agent
113-
* `custom` - Utilities that are used to create custom instrumentation
111+
* `library` - Instrumentation that targets a library.
112+
* `internal` - Instrumentation that is used internally by the OpenTelemetry Java Agent.
113+
* `custom` - Utilities that are used by end users to create custom instrumentation.
114+
* `enricher` - Instrumentation that enriches the telemetry produced by other instrumentations but does not generate or emit telemetry on its own.
115+
* `propagator` - Instrumentation that acts as a bridge for context propagation but does not generate or emit telemetry on its own.
116+
* `configuration` - Instrumentation that configures or sets up native library instrumentation.
114117
* name
115118
* Identifier for instrumentation module, used to enable/disable
116119
* Configured in `InstrumentationModule` code for each module
@@ -147,7 +150,9 @@ As of now, the following fields are supported, all of which are optional:
147150
```yaml
148151
description: "Instruments..." # Description of the instrumentation module
149152
disabled_by_default: true # Defaults to `false`
150-
classification: internal # instrumentation classification: library | internal | custom
153+
classification:
154+
- library
155+
- enricher
151156
configurations:
152157
- name: otel.instrumentation.common.db-statement-sanitizer.enabled
153158
description: Enables statement sanitization for database queries.

instrumentation-docs/src/main/java/io/opentelemetry/instrumentation/docs/DocGeneratorApplication.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public static void main(String[] args) throws IOException {
4949
printStats(modules);
5050
}
5151

52+
@SuppressWarnings("unused") // temporary helper method used for project tracking
5253
private static void printStats(List<InstrumentationModule> modules) {
5354
List<InstrumentationModule> metadata =
5455
modules.stream().filter(m -> m.getMetadata() != null).toList();
@@ -86,16 +87,14 @@ private static void printStats(List<InstrumentationModule> modules) {
8687
}
8788

8889
private static String getClassificationStats(List<InstrumentationModule> modules) {
90+
// Flatten all classifications and count each individually
8991
return modules.stream()
90-
.collect(
91-
Collectors.groupingBy(
92-
m -> m.getMetadata().getClassification(), TreeMap::new, Collectors.toList()))
92+
.flatMap(m -> m.getMetadata().getClassifications().stream())
93+
.map(c -> c.name().toLowerCase(Locale.ROOT))
94+
.collect(Collectors.groupingBy(c -> c, TreeMap::new, Collectors.counting()))
9395
.entrySet()
9496
.stream()
95-
.map(
96-
entry ->
97-
String.format(
98-
Locale.getDefault(FORMAT), "\t%s: %d", entry.getKey(), entry.getValue().size()))
97+
.map(entry -> String.format(Locale.ROOT, "\t%s: %d", entry.getKey(), entry.getValue()))
9998
.collect(Collectors.joining("\n"));
10099
}
101100

instrumentation-docs/src/main/java/io/opentelemetry/instrumentation/docs/internal/InstrumentationClassification.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515
public enum InstrumentationClassification {
1616
LIBRARY,
1717
CUSTOM,
18-
INTERNAL;
18+
INTERNAL,
19+
ENRICHER,
20+
CONFIGURATION,
21+
PROPAGATOR;
1922

2023
@Nullable
2124
public static InstrumentationClassification fromString(@Nullable String type) {
@@ -26,6 +29,9 @@ public static InstrumentationClassification fromString(@Nullable String type) {
2629
case "library" -> LIBRARY;
2730
case "internal" -> INTERNAL;
2831
case "custom" -> CUSTOM;
32+
case "enricher" -> ENRICHER;
33+
case "configuration" -> CONFIGURATION;
34+
case "propagator" -> PROPAGATOR;
2935
default -> null;
3036
};
3137
}

instrumentation-docs/src/main/java/io/opentelemetry/instrumentation/docs/internal/InstrumentationMetaData.java

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@
55

66
package io.opentelemetry.instrumentation.docs.internal;
77

8+
import static java.util.Collections.emptyList;
9+
import static java.util.Collections.singletonList;
10+
811
import com.fasterxml.jackson.annotation.JsonProperty;
9-
import java.util.Collections;
1012
import java.util.List;
1113
import java.util.Objects;
12-
import javax.annotation.Nonnull;
1314
import javax.annotation.Nullable;
1415

1516
/**
@@ -23,35 +24,37 @@ public class InstrumentationMetaData {
2324
@Nullable
2425
private Boolean disabledByDefault;
2526

26-
private String classification;
27+
private List<String> classifications;
2728

28-
private List<ConfigurationOption> configurations = Collections.emptyList();
29+
private List<ConfigurationOption> configurations = emptyList();
2930

3031
public InstrumentationMetaData() {
31-
this.classification = InstrumentationClassification.LIBRARY.toString();
32+
this.classifications = singletonList(InstrumentationClassification.LIBRARY.name());
3233
}
3334

3435
public InstrumentationMetaData(
3536
@Nullable String description,
36-
String classification,
37+
@Nullable List<String> classifications,
3738
@Nullable Boolean disabledByDefault,
3839
@Nullable List<ConfigurationOption> configurations) {
39-
this.classification = classification;
40+
this.classifications =
41+
Objects.requireNonNullElse(
42+
classifications, singletonList(InstrumentationClassification.LIBRARY.name()));
4043
this.disabledByDefault = disabledByDefault;
4144
this.description = description;
42-
this.configurations = Objects.requireNonNullElse(configurations, Collections.emptyList());
45+
this.configurations = Objects.requireNonNullElse(configurations, emptyList());
4346
}
4447

4548
@Nullable
4649
public String getDescription() {
4750
return description;
4851
}
4952

50-
@Nonnull
51-
public InstrumentationClassification getClassification() {
52-
return Objects.requireNonNullElse(
53-
InstrumentationClassification.fromString(classification),
54-
InstrumentationClassification.LIBRARY);
53+
public List<InstrumentationClassification> getClassifications() {
54+
if (classifications == null || classifications.isEmpty()) {
55+
return singletonList(InstrumentationClassification.LIBRARY);
56+
}
57+
return classifications.stream().map(InstrumentationClassification::fromString).toList();
5558
}
5659

5760
public Boolean getDisabledByDefault() {
@@ -62,8 +65,11 @@ public void setDescription(@Nullable String description) {
6265
this.description = description;
6366
}
6467

65-
public void setClassification(String classification) {
66-
this.classification = classification;
68+
public void setClassifications(@Nullable List<String> classifications) {
69+
this.classifications =
70+
(classifications == null || classifications.isEmpty())
71+
? singletonList(InstrumentationClassification.LIBRARY.name())
72+
: classifications;
6773
}
6874

6975
public void setDisabledByDefault(@Nullable Boolean disabledByDefault) {
@@ -75,6 +81,6 @@ public List<ConfigurationOption> getConfigurations() {
7581
}
7682

7783
public void setConfigurations(@Nullable List<ConfigurationOption> configurations) {
78-
this.configurations = Objects.requireNonNullElse(configurations, Collections.emptyList());
84+
this.configurations = Objects.requireNonNullElse(configurations, emptyList());
7985
}
8086
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.instrumentation.docs.internal;
7+
8+
import static java.util.Collections.emptyList;
9+
import static java.util.Collections.unmodifiableList;
10+
11+
import com.fasterxml.jackson.core.JsonParser;
12+
import com.fasterxml.jackson.databind.DeserializationContext;
13+
import com.fasterxml.jackson.databind.JsonDeserializer;
14+
import com.fasterxml.jackson.databind.JsonNode;
15+
import java.io.IOException;
16+
import java.util.ArrayList;
17+
import java.util.List;
18+
import java.util.Locale;
19+
import java.util.Objects;
20+
import javax.annotation.Nullable;
21+
22+
/**
23+
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
24+
* any time.
25+
*/
26+
public final class InstrumentationMetaDataDeserializer
27+
extends JsonDeserializer<InstrumentationMetaData> {
28+
29+
@Override
30+
public InstrumentationMetaData deserialize(JsonParser p, DeserializationContext ctx)
31+
throws IOException {
32+
JsonNode node = p.getCodec().readTree(p);
33+
34+
String description = textOrNull(node, "description");
35+
Boolean disabledByDefault = boolOrNull(node, "disabled_by_default");
36+
37+
List<String> classifications = readClassifications(node.path("classification"));
38+
List<ConfigurationOption> configurations = readConfigurations(node.path("configurations"));
39+
40+
return new InstrumentationMetaData(
41+
description, classifications, disabledByDefault, configurations);
42+
}
43+
44+
@Nullable
45+
private static String textOrNull(JsonNode parent, String field) {
46+
JsonNode n = parent.path(field);
47+
return n.isMissingNode() || n.isNull() ? null : n.asText();
48+
}
49+
50+
@Nullable
51+
private static Boolean boolOrNull(JsonNode parent, String field) {
52+
JsonNode n = parent.path(field);
53+
return (n.isMissingNode() || n.isNull()) ? null : n.asBoolean();
54+
}
55+
56+
private static List<String> readClassifications(JsonNode node) {
57+
if (node.isMissingNode() || node.isNull()) {
58+
return List.of(InstrumentationClassification.LIBRARY.name());
59+
}
60+
List<String> out = new ArrayList<>();
61+
if (node.isArray()) {
62+
for (JsonNode c : node) {
63+
if (c.isTextual()) {
64+
out.add(c.asText());
65+
}
66+
}
67+
} else if (node.isTextual()) {
68+
out.add(node.asText());
69+
}
70+
if (out.isEmpty()) {
71+
out.add(InstrumentationClassification.LIBRARY.name());
72+
}
73+
return unmodifiableList(out);
74+
}
75+
76+
private static List<ConfigurationOption> readConfigurations(JsonNode configs) {
77+
if (!configs.isArray()) {
78+
return emptyList();
79+
}
80+
List<ConfigurationOption> out = new ArrayList<>(configs.size());
81+
int i = 0;
82+
for (JsonNode cfg : configs) {
83+
String name = Objects.requireNonNull(textOrNull(cfg, "name"));
84+
String desc = Objects.requireNonNull(textOrNull(cfg, "description"));
85+
String def = Objects.requireNonNull(textOrNull(cfg, "default"));
86+
String typeStr = Objects.requireNonNull(textOrNull(cfg, "type"));
87+
88+
ConfigurationType type;
89+
try {
90+
type = ConfigurationType.valueOf(typeStr.toUpperCase(Locale.ROOT));
91+
} catch (IllegalArgumentException ex) {
92+
throw new IllegalArgumentException(
93+
"configurations[" + i + "].type invalid: '" + typeStr + "'", ex);
94+
}
95+
out.add(new ConfigurationOption(name, desc, def, type));
96+
i++;
97+
}
98+
return unmodifiableList(out);
99+
}
100+
}

0 commit comments

Comments
 (0)