Hystrix metadata (#14604)

This commit is contained in:
Jay DeLuca 2025-09-09 08:02:33 -04:00 committed by GitHub
parent 5307e20028
commit aa3bd49d38
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 136 additions and 45 deletions

View File

@ -3743,12 +3743,35 @@ libraries:
type: STRING
hystrix:
- name: hystrix-1.4
description: This instrumentation enables the generation of INTERNAL spans for
Hystrix command executions and fallbacks.
source_path: instrumentation/hystrix-1.4
scope:
name: io.opentelemetry.hystrix-1.4
target_versions:
javaagent:
- com.netflix.hystrix:hystrix-core:[1.4.0,)
configurations:
- name: otel.instrumentation.hystrix.experimental-span-attributes
description: Enables capturing the experimental `hystrix.command`, `hystrix.circuit_open`
and `hystrix.group` span attributes.
type: boolean
default: false
telemetry:
- when: default
spans:
- span_kind: INTERNAL
attributes: []
- when: otel.instrumentation.hystrix.experimental-span-attributes=true
spans:
- span_kind: INTERNAL
attributes:
- name: hystrix.circuit_open
type: BOOLEAN
- name: hystrix.command
type: STRING
- name: hystrix.group
type: STRING
influxdb:
- name: influxdb-2.4
source_path: instrumentation/influxdb-2.4

View File

@ -151,6 +151,8 @@ readonly INSTRUMENTATIONS=(
"hibernate:hibernate-6.0:javaagent:testExperimental"
"hibernate:hibernate-procedure-call-4.3:javaagent:test"
"hibernate:hibernate-procedure-call-4.3:javaagent:testExperimental"
"hystrix-1.4:javaagent:test"
"hystrix-1.4:javaagent:testExperimental"
)
# Some instrumentation test suites don't run ARM, so we use colima to run them in an x86_64

View File

@ -20,13 +20,27 @@ dependencies {
library("io.reactivex:rxjava:1.0.8")
}
tasks.withType<Test>().configureEach {
// TODO run tests both with and without experimental span attributes
jvmArgs("-Dotel.instrumentation.hystrix.experimental-span-attributes=true")
// Disable so failure testing below doesn't inadvertently change the behavior.
jvmArgs("-Dhystrix.command.default.circuitBreaker.enabled=false")
jvmArgs("-Dio.opentelemetry.javaagent.shaded.io.opentelemetry.context.enableStrictContext=false")
tasks {
withType<Test>().configureEach {
// Disable so failure testing below doesn't inadvertently change the behavior.
jvmArgs("-Dhystrix.command.default.circuitBreaker.enabled=false")
jvmArgs("-Dio.opentelemetry.javaagent.shaded.io.opentelemetry.context.enableStrictContext=false")
// Uncomment for debugging:
// jvmArgs("-Dhystrix.command.default.execution.timeout.enabled=false")
systemProperty("collectMetadata", findProperty("collectMetadata")?.toString() ?: "false")
// Uncomment for debugging:
// jvmArgs("-Dhystrix.command.default.execution.timeout.enabled=false")
}
val testExperimental by registering(Test::class) {
testClassesDirs = sourceSets.test.get().output.classesDirs
classpath = sourceSets.test.get().runtimeClasspath
jvmArgs("-Dotel.instrumentation.hystrix.experimental-span-attributes=true")
systemProperty("metadataConfig", "otel.instrumentation.hystrix.experimental-span-attributes=true")
}
check {
dependsOn(testExperimental)
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.hystrix;
import static io.opentelemetry.api.common.AttributeKey.booleanKey;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import io.opentelemetry.api.common.AttributeKey;
import javax.annotation.Nullable;
class ExperimentalTestHelper {
private static final boolean isEnabled =
Boolean.getBoolean("otel.instrumentation.hystrix.experimental-span-attributes");
static final AttributeKey<String> HYSTRIX_COMMAND = stringKey("hystrix.command");
static final AttributeKey<String> HYSTRIX_GROUP = stringKey("hystrix.group");
static final AttributeKey<Boolean> HYSTRIX_CIRCUIT_OPEN = booleanKey("hystrix.circuit_open");
@Nullable
static String experimental(String value) {
if (isEnabled) {
return value;
}
return null;
}
@Nullable
static Boolean experimental(Boolean value) {
if (isEnabled) {
return value;
}
return null;
}
private ExperimentalTestHelper() {}
}

View File

@ -5,8 +5,10 @@
package io.opentelemetry.javaagent.instrumentation.hystrix;
import static io.opentelemetry.api.common.AttributeKey.booleanKey;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import static io.opentelemetry.javaagent.instrumentation.hystrix.ExperimentalTestHelper.HYSTRIX_CIRCUIT_OPEN;
import static io.opentelemetry.javaagent.instrumentation.hystrix.ExperimentalTestHelper.HYSTRIX_COMMAND;
import static io.opentelemetry.javaagent.instrumentation.hystrix.ExperimentalTestHelper.HYSTRIX_GROUP;
import static io.opentelemetry.javaagent.instrumentation.hystrix.ExperimentalTestHelper.experimental;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
import static org.assertj.core.api.Assertions.assertThat;
@ -24,7 +26,7 @@ import rx.schedulers.Schedulers;
class HystrixObservableChainTest {
@RegisterExtension
protected static final InstrumentationExtension testing = AgentInstrumentationExtension.create();
static final InstrumentationExtension testing = AgentInstrumentationExtension.create();
@Test
@SuppressWarnings("RxReturnValueIgnored")
@ -93,9 +95,9 @@ class HystrixObservableChainTest {
span.hasName("ExampleGroup.TestCommand.execute")
.hasParent(trace.getSpan(0))
.hasAttributesSatisfyingExactly(
equalTo(stringKey("hystrix.command"), "TestCommand"),
equalTo(stringKey("hystrix.group"), "ExampleGroup"),
equalTo(booleanKey("hystrix.circuit_open"), false)),
equalTo(HYSTRIX_COMMAND, experimental("TestCommand")),
equalTo(HYSTRIX_GROUP, experimental("ExampleGroup")),
equalTo(HYSTRIX_CIRCUIT_OPEN, experimental(false))),
span ->
span.hasName("tracedMethod")
.hasParent(trace.getSpan(1))
@ -104,9 +106,9 @@ class HystrixObservableChainTest {
span.hasName("OtherGroup.AnotherTestCommand.execute")
.hasParent(trace.getSpan(1))
.hasAttributesSatisfyingExactly(
equalTo(stringKey("hystrix.command"), "AnotherTestCommand"),
equalTo(stringKey("hystrix.group"), "OtherGroup"),
equalTo(booleanKey("hystrix.circuit_open"), false)),
equalTo(HYSTRIX_COMMAND, experimental("AnotherTestCommand")),
equalTo(HYSTRIX_GROUP, experimental("OtherGroup")),
equalTo(HYSTRIX_CIRCUIT_OPEN, experimental(false))),
span ->
span.hasName("anotherTracedMethod")
.hasParent(trace.getSpan(3))

View File

@ -5,8 +5,10 @@
package io.opentelemetry.javaagent.instrumentation.hystrix;
import static io.opentelemetry.api.common.AttributeKey.booleanKey;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import static io.opentelemetry.javaagent.instrumentation.hystrix.ExperimentalTestHelper.HYSTRIX_CIRCUIT_OPEN;
import static io.opentelemetry.javaagent.instrumentation.hystrix.ExperimentalTestHelper.HYSTRIX_COMMAND;
import static io.opentelemetry.javaagent.instrumentation.hystrix.ExperimentalTestHelper.HYSTRIX_GROUP;
import static io.opentelemetry.javaagent.instrumentation.hystrix.ExperimentalTestHelper.experimental;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchException;
@ -36,7 +38,7 @@ import rx.schedulers.Schedulers;
class HystrixObservableTest {
@RegisterExtension
protected static final InstrumentationExtension testing = AgentInstrumentationExtension.create();
static final InstrumentationExtension testing = AgentInstrumentationExtension.create();
@ParameterizedTest
@MethodSource("provideCommandActionArguments")
@ -83,9 +85,9 @@ class HystrixObservableTest {
span.hasName("ExampleGroup.TestCommand.execute")
.hasParent(trace.getSpan(0))
.hasAttributesSatisfyingExactly(
equalTo(stringKey("hystrix.command"), "TestCommand"),
equalTo(stringKey("hystrix.group"), "ExampleGroup"),
equalTo(booleanKey("hystrix.circuit_open"), false)),
equalTo(HYSTRIX_COMMAND, experimental("TestCommand")),
equalTo(HYSTRIX_GROUP, experimental("ExampleGroup")),
equalTo(HYSTRIX_CIRCUIT_OPEN, experimental(false))),
span ->
span.hasName("tracedMethod")
.hasParent(trace.getSpan(1))
@ -292,9 +294,9 @@ class HystrixObservableTest {
span.hasName("ExampleGroup.TestCommand.fallback")
.hasParent(trace.getSpan(1))
.hasAttributesSatisfyingExactly(
equalTo(stringKey("hystrix.command"), "TestCommand"),
equalTo(stringKey("hystrix.group"), "ExampleGroup"),
equalTo(booleanKey("hystrix.circuit_open"), false))));
equalTo(HYSTRIX_COMMAND, experimental("TestCommand")),
equalTo(HYSTRIX_GROUP, experimental("ExampleGroup")),
equalTo(HYSTRIX_CIRCUIT_OPEN, experimental(false)))));
}
private static Stream<Arguments> provideCommandFallbackArguments() {
@ -383,17 +385,17 @@ class HystrixObservableTest {
.hasStatus(StatusData.error())
.hasException(exception.getCause())
.hasAttributesSatisfyingExactly(
equalTo(stringKey("hystrix.command"), "TestCommand"),
equalTo(stringKey("hystrix.group"), "FailingGroup"),
equalTo(booleanKey("hystrix.circuit_open"), false)),
equalTo(HYSTRIX_COMMAND, experimental("TestCommand")),
equalTo(HYSTRIX_GROUP, experimental("FailingGroup")),
equalTo(HYSTRIX_CIRCUIT_OPEN, experimental(false))),
span ->
span.hasName("FailingGroup.TestCommand.fallback")
.hasParent(trace.getSpan(1))
.hasException(hystrixRuntimeException.getFallbackException())
.hasAttributesSatisfyingExactly(
equalTo(stringKey("hystrix.command"), "TestCommand"),
equalTo(stringKey("hystrix.group"), "FailingGroup"),
equalTo(booleanKey("hystrix.circuit_open"), false))));
equalTo(HYSTRIX_COMMAND, experimental("TestCommand")),
equalTo(HYSTRIX_GROUP, experimental("FailingGroup")),
equalTo(HYSTRIX_CIRCUIT_OPEN, experimental(false)))));
}
private static Stream<Arguments> provideCommandNoFallbackResultsInErrorArguments() {

View File

@ -5,8 +5,10 @@
package io.opentelemetry.javaagent.instrumentation.hystrix;
import static io.opentelemetry.api.common.AttributeKey.booleanKey;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import static io.opentelemetry.javaagent.instrumentation.hystrix.ExperimentalTestHelper.HYSTRIX_CIRCUIT_OPEN;
import static io.opentelemetry.javaagent.instrumentation.hystrix.ExperimentalTestHelper.HYSTRIX_COMMAND;
import static io.opentelemetry.javaagent.instrumentation.hystrix.ExperimentalTestHelper.HYSTRIX_GROUP;
import static io.opentelemetry.javaagent.instrumentation.hystrix.ExperimentalTestHelper.experimental;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Named.named;
@ -31,7 +33,7 @@ import org.junit.jupiter.params.provider.MethodSource;
class HystrixTest {
@RegisterExtension
protected static final InstrumentationExtension testing = AgentInstrumentationExtension.create();
static final InstrumentationExtension testing = AgentInstrumentationExtension.create();
@ParameterizedTest
@MethodSource("provideCommandActionArguments")
@ -42,7 +44,7 @@ class HystrixTest {
}
@Override
protected String run() throws Exception {
protected String run() {
return tracedMethod();
}
@ -65,9 +67,9 @@ class HystrixTest {
span.hasName("ExampleGroup.TestCommand.execute")
.hasParent(trace.getSpan(0))
.hasAttributesSatisfyingExactly(
equalTo(stringKey("hystrix.command"), "TestCommand"),
equalTo(stringKey("hystrix.group"), "ExampleGroup"),
equalTo(booleanKey("hystrix.circuit_open"), false)),
equalTo(HYSTRIX_COMMAND, experimental("TestCommand")),
equalTo(HYSTRIX_GROUP, experimental("ExampleGroup")),
equalTo(HYSTRIX_CIRCUIT_OPEN, experimental(false))),
span ->
span.hasName("tracedMethod")
.hasParent(trace.getSpan(1))
@ -108,16 +110,16 @@ class HystrixTest {
.hasStatus(StatusData.error())
.hasException(new IllegalArgumentException())
.hasAttributesSatisfyingExactly(
equalTo(stringKey("hystrix.command"), "TestCommand"),
equalTo(stringKey("hystrix.group"), "ExampleGroup"),
equalTo(booleanKey("hystrix.circuit_open"), false)),
equalTo(HYSTRIX_COMMAND, experimental("TestCommand")),
equalTo(HYSTRIX_GROUP, experimental("ExampleGroup")),
equalTo(HYSTRIX_CIRCUIT_OPEN, experimental(false))),
span ->
span.hasName("ExampleGroup.TestCommand.fallback")
.hasParent(trace.getSpan(1))
.hasAttributesSatisfyingExactly(
equalTo(stringKey("hystrix.command"), "TestCommand"),
equalTo(stringKey("hystrix.group"), "ExampleGroup"),
equalTo(booleanKey("hystrix.circuit_open"), false))));
equalTo(HYSTRIX_COMMAND, experimental("TestCommand")),
equalTo(HYSTRIX_GROUP, experimental("ExampleGroup")),
equalTo(HYSTRIX_CIRCUIT_OPEN, experimental(false)))));
}
private static Stream<Arguments> provideCommandActionArguments() {

View File

@ -0,0 +1,7 @@
description: This instrumentation enables the generation of INTERNAL spans for Hystrix command executions and fallbacks.
configurations:
- name: otel.instrumentation.hystrix.experimental-span-attributes
description: Enables capturing the experimental `hystrix.command`, `hystrix.circuit_open` and `hystrix.group` span attributes.
type: boolean
default: false