diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/CriteriaInstrumentation.java b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/CriteriaInstrumentation.java index 764ba5318cd5..7f589896dbc0 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/CriteriaInstrumentation.java +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/CriteriaInstrumentation.java @@ -21,9 +21,9 @@ import io.opentelemetry.javaagent.instrumentation.hibernate.SessionMethodUtils; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; -import net.bytebuddy.implementation.bytecode.assign.Assigner; import net.bytebuddy.matcher.ElementMatcher; import org.hibernate.Criteria; +import org.hibernate.impl.CriteriaImpl; public class CriteriaInstrumentation implements TypeInstrumentation { @@ -63,7 +63,13 @@ public static void startMethod( ContextStore contextStore = InstrumentationContext.get(Criteria.class, Context.class); - context = SessionMethodUtils.startSpanFrom(contextStore, criteria, "Criteria." + name, null); + String entityName = null; + if (criteria instanceof CriteriaImpl) { + entityName = ((CriteriaImpl) criteria).getEntityOrClassName(); + } + + context = + SessionMethodUtils.startSpanFrom(contextStore, criteria, "Criteria." + name, entityName); if (context != null) { scope = context.makeCurrent(); } @@ -72,7 +78,6 @@ public static void startMethod( @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endMethod( @Advice.Thrown Throwable throwable, - @Advice.Return(typing = Assigner.Typing.DYNAMIC) Object entity, @Advice.Origin("#m") String name, @Advice.Local("otelCallDepth") CallDepth callDepth, @Advice.Local("otelContext") Context context, @@ -84,7 +89,7 @@ public static void endMethod( if (scope != null) { scope.close(); - SessionMethodUtils.end(context, throwable, "Criteria." + name, entity); + SessionMethodUtils.end(context, throwable); } } } diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/EntityNameUtil.java b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/EntityNameUtil.java new file mode 100644 index 000000000000..f2f7a6016a43 --- /dev/null +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/EntityNameUtil.java @@ -0,0 +1,30 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.hibernate.v3_3; + +import java.util.function.Function; +import org.hibernate.impl.AbstractSessionImpl; + +public final class EntityNameUtil { + + private EntityNameUtil() {} + + private static String bestGuessEntityName(Object session, Object entity) { + if (entity == null) { + return null; + } + + if (session instanceof AbstractSessionImpl) { + return ((AbstractSessionImpl) session).bestGuessEntityName(entity); + } + + return null; + } + + public static Function bestGuessEntityName(Object session) { + return (entity) -> bestGuessEntityName(session, entity); + } +} diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/QueryInstrumentation.java b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/QueryInstrumentation.java index cdcf586bac2c..e01cf57325da 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/QueryInstrumentation.java +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/QueryInstrumentation.java @@ -80,7 +80,7 @@ public static void endMethod( if (scope != null) { scope.close(); - SessionMethodUtils.end(context, throwable, null, null); + SessionMethodUtils.end(context, throwable); } } } diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/SessionInstrumentation.java b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/SessionInstrumentation.java index 6534b204eb57..d38f2cb9c116 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/SessionInstrumentation.java +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/SessionInstrumentation.java @@ -9,6 +9,7 @@ import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.implementsInterface; import static io.opentelemetry.javaagent.instrumentation.hibernate.HibernateTracer.tracer; import static io.opentelemetry.javaagent.instrumentation.hibernate.SessionMethodUtils.SCOPE_ONLY_METHODS; +import static io.opentelemetry.javaagent.instrumentation.hibernate.SessionMethodUtils.getEntityName; import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.namedOneOf; @@ -26,7 +27,6 @@ import io.opentelemetry.javaagent.instrumentation.hibernate.SessionMethodUtils; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; -import net.bytebuddy.implementation.bytecode.assign.Assigner; import net.bytebuddy.matcher.ElementMatcher; import org.hibernate.Criteria; import org.hibernate.Query; @@ -131,7 +131,9 @@ public static class SessionMethodAdvice { public static void startMethod( @Advice.This Object session, @Advice.Origin("#m") String name, - @Advice.Argument(0) Object entity, + @Advice.Origin("#d") String descriptor, + @Advice.Argument(0) Object arg0, + @Advice.Argument(value = 1, optional = true) Object arg1, @Advice.Local("otelCallDepth") CallDepth callDepth, @Advice.Local("otelContext") Context spanContext, @Advice.Local("otelScope") Scope scope) { @@ -157,7 +159,9 @@ public static void startMethod( } if (!SCOPE_ONLY_METHODS.contains(name)) { - spanContext = tracer().startSpan(sessionContext, "Session." + name, entity); + String entityName = + getEntityName(descriptor, arg0, arg1, EntityNameUtil.bestGuessEntityName(session)); + spanContext = tracer().startSpan(sessionContext, "Session." + name, entityName); scope = spanContext.makeCurrent(); } else { scope = sessionContext.makeCurrent(); @@ -167,8 +171,6 @@ public static void startMethod( @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endMethod( @Advice.Thrown Throwable throwable, - @Advice.Return(typing = Assigner.Typing.DYNAMIC) Object returned, - @Advice.Origin("#m") String name, @Advice.Local("otelCallDepth") CallDepth callDepth, @Advice.Local("otelContext") Context spanContext, @Advice.Local("otelScope") Scope scope) { @@ -179,7 +181,7 @@ public static void endMethod( if (scope != null) { scope.close(); - SessionMethodUtils.end(spanContext, throwable, "Session." + name, returned); + SessionMethodUtils.end(spanContext, throwable); } } } diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/TransactionInstrumentation.java b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/TransactionInstrumentation.java index ea3222b782a2..34cb1fae0608 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/TransactionInstrumentation.java +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/TransactionInstrumentation.java @@ -81,7 +81,7 @@ public static void endCommit( if (scope != null) { scope.close(); - SessionMethodUtils.end(context, throwable, null, null); + SessionMethodUtils.end(context, throwable); } } } diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/test/groovy/CriteriaTest.groovy b/instrumentation/hibernate/hibernate-3.3/javaagent/src/test/groovy/CriteriaTest.groovy index 946748153573..2e7ca301e5b2 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/test/groovy/CriteriaTest.groovy +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/test/groovy/CriteriaTest.groovy @@ -36,7 +36,7 @@ class CriteriaTest extends AbstractHibernateTest { } } span(1) { - name "Criteria.$methodName" + name "Criteria.$methodName Value" kind INTERNAL childOf span(0) attributes { diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/test/groovy/SessionTest.groovy b/instrumentation/hibernate/hibernate-3.3/javaagent/src/test/groovy/SessionTest.groovy index 9d3e2ad5d53b..ea5460e119b1 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/test/groovy/SessionTest.groovy +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/test/groovy/SessionTest.groovy @@ -283,7 +283,7 @@ class SessionTest extends AbstractHibernateTest { } } span(1) { - name "Session.replicate" + name "Session.replicate java.lang.Long" kind INTERNAL childOf span(0) status ERROR diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/CriteriaInstrumentation.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/CriteriaInstrumentation.java index 395c5deec2ac..f3bd92fafccb 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/CriteriaInstrumentation.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/CriteriaInstrumentation.java @@ -21,9 +21,9 @@ import io.opentelemetry.javaagent.instrumentation.hibernate.SessionMethodUtils; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; -import net.bytebuddy.implementation.bytecode.assign.Assigner; import net.bytebuddy.matcher.ElementMatcher; import org.hibernate.Criteria; +import org.hibernate.internal.CriteriaImpl; public class CriteriaInstrumentation implements TypeInstrumentation { @@ -63,7 +63,13 @@ public static void startMethod( ContextStore contextStore = InstrumentationContext.get(Criteria.class, Context.class); - context = SessionMethodUtils.startSpanFrom(contextStore, criteria, "Criteria." + name, null); + String entityName = null; + if (criteria instanceof CriteriaImpl) { + entityName = ((CriteriaImpl) criteria).getEntityOrClassName(); + } + + context = + SessionMethodUtils.startSpanFrom(contextStore, criteria, "Criteria." + name, entityName); if (context != null) { scope = context.makeCurrent(); } @@ -72,8 +78,6 @@ public static void startMethod( @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endMethod( @Advice.Thrown Throwable throwable, - @Advice.Return(typing = Assigner.Typing.DYNAMIC) Object entity, - @Advice.Origin("#m") String name, @Advice.Local("otelCallDepth") CallDepth callDepth, @Advice.Local("otelContext") Context context, @Advice.Local("otelScope") Scope scope) { @@ -84,7 +88,7 @@ public static void endMethod( if (scope != null) { scope.close(); - SessionMethodUtils.end(context, throwable, "Criteria." + name, entity); + SessionMethodUtils.end(context, throwable); } } } diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/EntityNameUtil.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/EntityNameUtil.java new file mode 100644 index 000000000000..52d3875cd9b1 --- /dev/null +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/EntityNameUtil.java @@ -0,0 +1,34 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.hibernate.v4_0; + +import java.util.function.Function; +import org.hibernate.SharedSessionContract; +import org.hibernate.internal.SessionImpl; +import org.hibernate.internal.StatelessSessionImpl; + +public final class EntityNameUtil { + + private EntityNameUtil() {} + + private static String bestGuessEntityName(SharedSessionContract session, Object entity) { + if (entity == null) { + return null; + } + + if (session instanceof SessionImpl) { + return ((SessionImpl) session).bestGuessEntityName(entity); + } else if (session instanceof StatelessSessionImpl) { + return ((StatelessSessionImpl) session).bestGuessEntityName(entity); + } + + return null; + } + + public static Function bestGuessEntityName(SharedSessionContract session) { + return (entity) -> bestGuessEntityName(session, entity); + } +} diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/QueryInstrumentation.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/QueryInstrumentation.java index 586c56d0fe71..c73f1189513b 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/QueryInstrumentation.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/QueryInstrumentation.java @@ -80,7 +80,7 @@ public static void endMethod( if (scope != null) { scope.close(); - SessionMethodUtils.end(context, throwable, null, null); + SessionMethodUtils.end(context, throwable); } } } diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionInstrumentation.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionInstrumentation.java index 29c6b8854626..b580efa32987 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionInstrumentation.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionInstrumentation.java @@ -9,6 +9,7 @@ import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.implementsInterface; import static io.opentelemetry.javaagent.instrumentation.hibernate.HibernateTracer.tracer; import static io.opentelemetry.javaagent.instrumentation.hibernate.SessionMethodUtils.SCOPE_ONLY_METHODS; +import static io.opentelemetry.javaagent.instrumentation.hibernate.SessionMethodUtils.getEntityName; import static io.opentelemetry.javaagent.instrumentation.hibernate.SessionMethodUtils.getSessionMethodSpanName; import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.named; @@ -27,7 +28,6 @@ import io.opentelemetry.javaagent.instrumentation.hibernate.SessionMethodUtils; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; -import net.bytebuddy.implementation.bytecode.assign.Assigner; import net.bytebuddy.matcher.ElementMatcher; import org.hibernate.Criteria; import org.hibernate.Query; @@ -125,7 +125,9 @@ public static class SessionMethodAdvice { public static void startMethod( @Advice.This SharedSessionContract session, @Advice.Origin("#m") String name, - @Advice.Argument(0) Object entity, + @Advice.Origin("#d") String descriptor, + @Advice.Argument(0) Object arg0, + @Advice.Argument(value = 1, optional = true) Object arg1, @Advice.Local("otelCallDepth") CallDepth callDepth, @Advice.Local("otelContext") Context spanContext, @Advice.Local("otelScope") Scope scope) { @@ -144,7 +146,10 @@ public static void startMethod( } if (!SCOPE_ONLY_METHODS.contains(name)) { - spanContext = tracer().startSpan(sessionContext, getSessionMethodSpanName(name), entity); + String entityName = + getEntityName(descriptor, arg0, arg1, EntityNameUtil.bestGuessEntityName(session)); + spanContext = + tracer().startSpan(sessionContext, getSessionMethodSpanName(name), entityName); scope = spanContext.makeCurrent(); } else { scope = sessionContext.makeCurrent(); @@ -154,8 +159,6 @@ public static void startMethod( @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endMethod( @Advice.Thrown Throwable throwable, - @Advice.Return(typing = Assigner.Typing.DYNAMIC) Object returned, - @Advice.Origin("#m") String name, @Advice.Local("otelCallDepth") CallDepth callDepth, @Advice.Local("otelContext") Context spanContext, @Advice.Local("otelScope") Scope scope) { @@ -166,7 +169,7 @@ public static void endMethod( if (scope != null) { scope.close(); - SessionMethodUtils.end(spanContext, throwable, getSessionMethodSpanName(name), returned); + SessionMethodUtils.end(spanContext, throwable); } } } diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/TransactionInstrumentation.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/TransactionInstrumentation.java index 00745f34b508..a43757097d8a 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/TransactionInstrumentation.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/TransactionInstrumentation.java @@ -81,7 +81,7 @@ public static void endCommit( if (scope != null) { scope.close(); - SessionMethodUtils.end(context, throwable, null, null); + SessionMethodUtils.end(context, throwable); } } } diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/AbstractHibernateTest.groovy b/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/AbstractHibernateTest.groovy index 09b6d5842f7e..79c3b8ddf288 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/AbstractHibernateTest.groovy +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/AbstractHibernateTest.groovy @@ -23,7 +23,7 @@ abstract class AbstractHibernateTest extends AgentInstrumentationSpecification { Session writer = sessionFactory.openSession() writer.beginTransaction() prepopulated = new ArrayList<>() - for (int i = 0; i < 2; i++) { + for (int i = 0; i < 5; i++) { prepopulated.add(new Value("Hello :) " + i)) writer.save(prepopulated.get(i)) } diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/CriteriaTest.groovy b/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/CriteriaTest.groovy index 946748153573..2e7ca301e5b2 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/CriteriaTest.groovy +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/CriteriaTest.groovy @@ -36,7 +36,7 @@ class CriteriaTest extends AbstractHibernateTest { } } span(1) { - name "Criteria.$methodName" + name "Criteria.$methodName Value" kind INTERNAL childOf span(0) attributes { diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/SessionTest.groovy b/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/SessionTest.groovy index 678bd3d80c6f..b2a6266a7ec7 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/SessionTest.groovy +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/test/groovy/SessionTest.groovy @@ -9,6 +9,7 @@ import static io.opentelemetry.api.trace.StatusCode.ERROR import io.opentelemetry.semconv.trace.attributes.SemanticAttributes import org.hibernate.LockMode +import org.hibernate.LockOptions import org.hibernate.MappingException import org.hibernate.Query import org.hibernate.ReplicationMode @@ -84,29 +85,56 @@ class SessionTest extends AbstractHibernateTest { } where: - testName | methodName | resource | sessionImplementations | sessionMethodTest - "lock" | "lock" | "Value" | [sessionBuilder] | { sesh, val -> + testName | methodName | resource | sessionImplementations | sessionMethodTest + "lock" | "lock" | "Value" | [sessionBuilder] | { sesh, val -> sesh.lock(val, LockMode.READ) } - "refresh" | "refresh" | "Value" | [sessionBuilder, statelessSessionBuilder] | { sesh, val -> + "lock with entity name" | "lock" | "Value" | [sessionBuilder] | { sesh, val -> + sesh.lock("Value", val, LockMode.READ) + } + "lock with null name" | "lock" | "Value" | [sessionBuilder] | { sesh, val -> + sesh.lock(null, val, LockMode.READ) + } + "buildLockRequest" | "lock" | "Value" | [sessionBuilder] | { sesh, val -> + sesh.buildLockRequest(LockOptions.READ) + .lock(val) + } + "refresh" | "refresh" | "Value" | [sessionBuilder, statelessSessionBuilder] | { sesh, val -> sesh.refresh(val) } - "get" | "get" | "Value" | [sessionBuilder, statelessSessionBuilder] | { sesh, val -> + "refresh with entity name" | "refresh" | "Value" | [sessionBuilder, statelessSessionBuilder] | { sesh, val -> + sesh.refresh("Value", val) + } + "get with entity name" | "get" | "Value" | [sessionBuilder, statelessSessionBuilder] | { sesh, val -> sesh.get("Value", val.getId()) } - "insert" | "insert" | "Value" | [statelessSessionBuilder] | { sesh, val -> + "get with entity class" | "get" | "Value" | [sessionBuilder, statelessSessionBuilder] | { sesh, val -> + sesh.get(Value, val.getId()) + } + "insert" | "insert" | "Value" | [statelessSessionBuilder] | { sesh, val -> + sesh.insert(new Value("insert me")) + } + "insert with entity name" | "insert" | "Value" | [statelessSessionBuilder] | { sesh, val -> sesh.insert("Value", new Value("insert me")) } - "update (StatelessSession)" | "update" | "Value" | [statelessSessionBuilder] | { sesh, val -> + "insert with null entity name" | "insert" | "Value" | [statelessSessionBuilder] | { sesh, val -> + sesh.insert(null, new Value("insert me")) + } + "update (StatelessSession)" | "update" | "Value" | [statelessSessionBuilder] | { sesh, val -> val.setName("New name") sesh.update(val) } - "update by entityName (StatelessSession)" | "update" | "Value" | [statelessSessionBuilder] | { sesh, val -> + "update with entity name (StatelessSession)" | "update" | "Value" | [statelessSessionBuilder] | { sesh, val -> val.setName("New name") sesh.update("Value", val) } - "delete (Session)" | "delete" | "Value" | [statelessSessionBuilder] | { sesh, val -> + "delete (Session)" | "delete" | "Value" | [statelessSessionBuilder] | { sesh, val -> sesh.delete(val) + prepopulated.remove(val) + } + "delete with entity name (Session)" | "delete" | "Value" | [statelessSessionBuilder] | { sesh, val -> + sesh.delete("Value", val) + prepopulated.remove(val) } } @@ -222,7 +250,7 @@ class SessionTest extends AbstractHibernateTest { } } span(1) { - name "Session.replicate" + name "Session.replicate java.lang.Long" kind INTERNAL childOf span(0) status ERROR @@ -297,33 +325,53 @@ class SessionTest extends AbstractHibernateTest { } where: - testName | methodName | resource | sessionMethodTest - "save" | "save" | "Value" | { sesh, val -> + testName | methodName | resource | sessionMethodTest + "save" | "save" | "Value" | { sesh, val -> sesh.save(new Value("Another value")) } - "saveOrUpdate save" | "saveOrUpdate" | "Value" | { sesh, val -> + "save with entity name" | "save" | "Value" | { sesh, val -> + sesh.save("Value", new Value("Another value")) + } + "saveOrUpdate save" | "saveOrUpdate" | "Value" | { sesh, val -> sesh.saveOrUpdate(new Value("Value")) } - "saveOrUpdate update" | "saveOrUpdate" | "Value" | { sesh, val -> + "saveOrUpdate save with entity name" | "saveOrUpdate" | "Value" | { sesh, val -> + sesh.saveOrUpdate("Value", new Value("Value")) + } + "saveOrUpdate update with entity name" | "saveOrUpdate" | "Value" | { sesh, val -> val.setName("New name") - sesh.saveOrUpdate(val) + sesh.saveOrUpdate("Value", val) } - "merge" | "merge" | "Value" | { sesh, val -> + "merge" | "merge" | "Value" | { sesh, val -> sesh.merge(new Value("merge me in")) } - "persist" | "persist" | "Value" | { sesh, val -> + "merge with entity name" | "merge" | "Value" | { sesh, val -> + sesh.merge("Value", new Value("merge me in")) + } + "persist" | "persist" | "Value" | { sesh, val -> sesh.persist(new Value("merge me in")) } - "update (Session)" | "update" | "Value" | { sesh, val -> + "persist with entity name" | "persist" | "Value" | { sesh, val -> + sesh.persist("Value", new Value("merge me in")) + } + "persist with null entity name" | "persist" | "Value" | { sesh, val -> + sesh.persist(null, new Value("merge me in")) + } + "update (Session)" | "update" | "Value" | { sesh, val -> val.setName("New name") sesh.update(val) } - "update by entityName (Session)" | "update" | "Value" | { sesh, val -> + "update by entityName (Session)" | "update" | "Value" | { sesh, val -> val.setName("New name") sesh.update("Value", val) } - "delete (Session)" | "delete" | "Value" | { sesh, val -> + "delete (Session)" | "delete" | "Value" | { sesh, val -> sesh.delete(val) + prepopulated.remove(val) + } + "delete by entityName (Session)" | "delete" | "Value" | { sesh, val -> + sesh.delete("Value", val) + prepopulated.remove(val) } } diff --git a/instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/HibernateTracer.java b/instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/HibernateTracer.java index 6ead21502f14..50699f77bbb9 100644 --- a/instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/HibernateTracer.java +++ b/instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/HibernateTracer.java @@ -8,10 +8,6 @@ import io.opentelemetry.api.trace.SpanKind; import io.opentelemetry.context.Context; import io.opentelemetry.instrumentation.api.tracer.BaseTracer; -import java.lang.annotation.Annotation; -import java.util.HashSet; -import java.util.List; -import java.util.Set; public class HibernateTracer extends BaseTracer { private static final HibernateTracer TRACER = new HibernateTracer(); @@ -20,48 +16,21 @@ public static HibernateTracer tracer() { return TRACER; } - public Context startSpan(Context parentContext, String operationName, Object entity) { - return startSpan(parentContext, spanNameForOperation(operationName, entity)); + public Context startSpan(Context parentContext, String operationName, String entityName) { + return startSpan(parentContext, spanNameForOperation(operationName, entityName)); } public Context startSpan(Context parentContext, String spanName) { return startSpan(parentContext, spanName, SpanKind.INTERNAL); } - private String spanNameForOperation(String operationName, Object entity) { - if (entity != null) { - String entityName = entityName(entity); - if (entityName != null) { - return operationName + " " + entityName; - } + private static String spanNameForOperation(String operationName, String entityName) { + if (entityName != null) { + return operationName + " " + entityName; } return operationName; } - String entityName(Object entity) { - if (entity == null) { - return null; - } - String name = null; - Set annotations = new HashSet<>(); - for (Annotation annotation : entity.getClass().getDeclaredAnnotations()) { - annotations.add(annotation.annotationType().getName()); - } - - if (entity instanceof String) { - // We were given an entity name, not the entity itself. - name = (String) entity; - } else if (annotations.contains("javax.persistence.Entity")) { - // We were given an instance of an entity. - name = entity.getClass().getName(); - } else if (entity instanceof List && !((List) entity).isEmpty()) { - // We have a list of entities. - name = entityName(((List) entity).get(0)); - } - - return name; - } - @Override protected String getInstrumentationName() { return "io.opentelemetry.hibernate-common"; diff --git a/instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/SessionMethodUtils.java b/instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/SessionMethodUtils.java index b1e36186ecbf..95a8ea94d4c5 100644 --- a/instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/SessionMethodUtils.java +++ b/instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/SessionMethodUtils.java @@ -7,7 +7,6 @@ import static io.opentelemetry.javaagent.instrumentation.hibernate.HibernateTracer.tracer; -import io.opentelemetry.api.trace.Span; import io.opentelemetry.context.Context; import io.opentelemetry.instrumentation.api.db.SqlStatementInfo; import io.opentelemetry.instrumentation.api.db.SqlStatementSanitizer; @@ -15,6 +14,7 @@ import java.util.Arrays; import java.util.HashSet; import java.util.Set; +import java.util.function.Function; import java.util.function.Supplier; import org.checkerframework.checker.nullness.qual.Nullable; @@ -27,22 +27,22 @@ public static Context startSpanFrom( ContextStore contextStore, TARGET spanKey, String operationName, - ENTITY entity) { - return startSpanFrom(contextStore, spanKey, () -> operationName, entity); + String entityName) { + return startSpanFrom(contextStore, spanKey, () -> operationName, entityName); } private static Context startSpanFrom( ContextStore contextStore, TARGET spanKey, Supplier operationNameSupplier, - ENTITY entity) { + String entityName) { Context sessionContext = contextStore.get(spanKey); if (sessionContext == null) { return null; // No state found. We aren't in a Session. } - return tracer().startSpan(sessionContext, operationNameSupplier.get(), entity); + return tracer().startSpan(sessionContext, operationNameSupplier.get(), entityName); } public static Context startSpanFromQuery( @@ -64,19 +64,12 @@ public static Context startSpanFromQuery( return startSpanFrom(contextStore, spanKey, operationNameSupplier, null); } - public static void end( - @Nullable Context context, Throwable throwable, String operationName, Object entity) { + public static void end(@Nullable Context context, Throwable throwable) { if (context == null) { return; } - if (operationName != null && entity != null) { - String entityName = tracer().entityName(entity); - if (entityName != null) { - Span.fromContext(context).updateName(operationName + " " + entityName); - } - } if (throwable != null) { tracer().endExceptionally(context, throwable); } else { @@ -107,5 +100,27 @@ public static String getSessionMethodSpanName(String methodName) { return "Session." + methodName; } + public static String getEntityName( + String descriptor, Object arg0, Object arg1, Function nameFromEntity) { + String entityName = null; + // methods like save(String entityName, Object object) + // that take entity name as first argument and entity as second + // if given entity name is null compute it from entity object + if (descriptor.startsWith("(Ljava/lang/String;Ljava/lang/Object;")) { + entityName = arg0 == null ? nameFromEntity.apply(arg1) : (String) arg0; + // methods like save(Object obj) + } else if (descriptor.startsWith("(Ljava/lang/Object;")) { + entityName = nameFromEntity.apply(arg0); + // methods like get(String entityName, Serializable id) + } else if (descriptor.startsWith("(Ljava/lang/String;")) { + entityName = (String) arg0; + // methods like get(Class entityClass, Serializable id) + } else if (descriptor.startsWith("(Ljava/lang/Class;") && arg0 != null) { + entityName = ((Class) arg0).getName(); + } + + return entityName; + } + private SessionMethodUtils() {} } diff --git a/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/ProcedureCallInstrumentation.java b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/ProcedureCallInstrumentation.java index 11f00a72d609..b54f20cb098f 100644 --- a/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/ProcedureCallInstrumentation.java +++ b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/ProcedureCallInstrumentation.java @@ -82,7 +82,7 @@ public static void endMethod( if (scope != null) { scope.close(); - SessionMethodUtils.end(context, throwable, null, null); + SessionMethodUtils.end(context, throwable); } } }