From 3da68e86e228f5b98ab738928e4e15bee2402e24 Mon Sep 17 00:00:00 2001 From: Yashwant Date: Fri, 7 Feb 2025 17:55:10 +0530 Subject: [PATCH 1/5] test to use shaded util, instead of client --- instrumentation/grpc-1.6/build.gradle.kts | 3 +- .../grpc/v1_6/GrpcSpanDecorator.java | 32 ++++-- .../grpc/v1_6/ProtobufRoundTripConverter.java | 104 ++++++++++++++++++ shaded-protobuf-java-util/build.gradle.kts | 9 +- 4 files changed, 131 insertions(+), 17 deletions(-) create mode 100644 instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/ProtobufRoundTripConverter.java diff --git a/instrumentation/grpc-1.6/build.gradle.kts b/instrumentation/grpc-1.6/build.gradle.kts index 87742e9f8..15782c315 100644 --- a/instrumentation/grpc-1.6/build.gradle.kts +++ b/instrumentation/grpc-1.6/build.gradle.kts @@ -15,8 +15,7 @@ muzzle { group = "io.grpc" module = "grpc-core" versions = "[1.6.0,)" - // for body capture via com.google.protobuf.Message to exist always - extraDependency("com.google.protobuf:protobuf-java:3.3.1") + extraDependency("io.grpc:grpc-netty:1.6.0") } } diff --git a/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/GrpcSpanDecorator.java b/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/GrpcSpanDecorator.java index a44289735..f32212e72 100644 --- a/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/GrpcSpanDecorator.java +++ b/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/GrpcSpanDecorator.java @@ -16,20 +16,16 @@ package io.opentelemetry.javaagent.instrumentation.hypertrace.grpc.v1_6; -import com.google.protobuf.Message; import io.grpc.Metadata; import io.grpc.Metadata.Key; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.trace.Span; import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.util.JsonFormat; import io.opentelemetry.javaagent.instrumentation.hypertrace.grpc.GrpcSemanticAttributes; -import java.io.IOException; import java.util.LinkedHashMap; import java.util.Map; import java.util.function.Function; import org.hypertrace.agent.core.instrumentation.HypertraceSemanticAttributes; -import org.hypertrace.agent.core.instrumentation.buffer.BoundedBuffersFactory; -import org.hypertrace.agent.core.instrumentation.buffer.BoundedCharArrayWriter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,14 +37,11 @@ private GrpcSpanDecorator() {} private static final JsonFormat.Printer PRINTER = JsonFormat.printer(); public static void addMessageAttribute(Object message, Span span, AttributeKey key) { - if (message instanceof Message) { - Message mb = (Message) message; + if (isProtobufMessage(message)) { try { - BoundedCharArrayWriter writer = BoundedBuffersFactory.createWriter(); - PRINTER.appendTo(mb, writer); - span.setAttribute(key, writer.toString()); - } catch (IOException e) { - log.error("Failed to decode message to JSON", e); + ProtobufRoundTripConverter.addConvertedMessageAttribute(message, span, key); + } catch (Exception e) { + log.error("Failed to print message as JSON", e); } } } @@ -90,4 +83,21 @@ public static Map metadataToMap(Metadata metadata) { } return mapHeaders; } + + private static boolean isProtobufMessage(Object message) { + if (message == null) { + return false; + } + // Check the interfaces on the class and its superclasses + Class cls = message.getClass(); + while (cls != null) { + for (Class iface : cls.getInterfaces()) { + if ("com.google.protobuf.Message".equals(iface.getName())) { + return true; + } + } + cls = cls.getSuperclass(); + } + return false; + } } diff --git a/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/ProtobufRoundTripConverter.java b/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/ProtobufRoundTripConverter.java new file mode 100644 index 000000000..2783f1063 --- /dev/null +++ b/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/ProtobufRoundTripConverter.java @@ -0,0 +1,104 @@ +/* + * Copyright The Hypertrace Authors + * + * 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 io.opentelemetry.javaagent.instrumentation.hypertrace.grpc.v1_6; + +import com.google.protobuf.Descriptors; +import com.google.protobuf.Message; +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.DescriptorProtos.FileDescriptorProto; +import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.Descriptors.Descriptor; +import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.Descriptors.FileDescriptor; +import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.DynamicMessage; +import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.util.JsonFormat; + +public class ProtobufRoundTripConverter { + + /** + * Converts an unrelocated protobuf message into a relocated DynamicMessage via a byte-array + * round-trip. + * + * @param message The original protobuf message (an instance of com.google.protobuf.Message). + * @return A relocated DynamicMessage built from your relocated protobuf classes. + * @throws Exception if conversion fails. + */ + public static DynamicMessage convertToRelocatedDynamicMessage(Object message) throws Exception { + if (!(message instanceof Message)) { + throw new IllegalArgumentException("message is not a protobuf Message"); + } + // 1. Serialize the original message to bytes. + Message originalMessage = (Message) message; + byte[] messageBytes = originalMessage.toByteArray(); + + // 2. Obtain the original (unrelocated) message descriptor. + Descriptors.Descriptor originalDescriptor = originalMessage.getDescriptorForType(); + + // 3. Get the unrelocated file descriptor and its proto representation. + Descriptors.FileDescriptor unrelocatedFileDescriptor = originalDescriptor.getFile(); + com.google.protobuf.DescriptorProtos.FileDescriptorProto unrelocatedFileProto = + unrelocatedFileDescriptor.toProto(); + byte[] fileProtoBytes = unrelocatedFileProto.toByteArray(); + + // 4. Parse the file descriptor proto using relocated classes. + // This converts the unrelocated FileDescriptorProto into your relocated FileDescriptorProto. + FileDescriptorProto relocatedFileProto = FileDescriptorProto.parseFrom(fileProtoBytes); + + // 5. Build the relocated FileDescriptor. + // Note: This example assumes there are no dependencies. + FileDescriptor relocatedFileDescriptor = + FileDescriptor.buildFrom(relocatedFileProto, new FileDescriptor[] {}); + + // 6. Find the relocated message descriptor by name. + // We assume the message name is the same in both relocated and unrelocated files. + Descriptor relocatedDescriptor = + relocatedFileDescriptor.findMessageTypeByName(originalDescriptor.getName()); + if (relocatedDescriptor == null) { + throw new IllegalStateException( + "Could not find relocated descriptor for message type: " + originalDescriptor.getName()); + } + + // 7. Parse the original message bytes using the relocated descriptor. + DynamicMessage relocatedMessage = DynamicMessage.parseFrom(relocatedDescriptor, messageBytes); + return relocatedMessage; + } + + /** + * Example method that takes an incoming message, converts it to a relocated one, prints it as + * JSON using the relocated JsonFormat, and attaches it as a span attribute. + * + * @param message The incoming (unrelocated) protobuf message. + * @param span The span to which to attach the attribute. + * @param key The attribute key. + */ + public static void addConvertedMessageAttribute( + Object message, Span span, AttributeKey key) { + try { + // Convert the unrelocated message into a relocated DynamicMessage. + DynamicMessage relocatedMessage = convertToRelocatedDynamicMessage(message); + + // Use the relocated JsonFormat to print the message as JSON. + JsonFormat.Printer relocatedPrinter = JsonFormat.printer(); + String jsonOutput = relocatedPrinter.print(relocatedMessage); + + // Set the JSON output as a span attribute. + span.setAttribute(key, jsonOutput); + } catch (Exception e) { + System.err.println("Failed to convert message via byte-array round-trip: " + e.getMessage()); + e.printStackTrace(); + } + } +} diff --git a/shaded-protobuf-java-util/build.gradle.kts b/shaded-protobuf-java-util/build.gradle.kts index d06ff8888..14a49a133 100644 --- a/shaded-protobuf-java-util/build.gradle.kts +++ b/shaded-protobuf-java-util/build.gradle.kts @@ -4,10 +4,8 @@ plugins { } dependencies { - implementation("com.google.protobuf:protobuf-java-util:3.25.5") { - exclude("com.google.protobuf", "protobuf-java") - exclude("com.google.guava", "guava") - } + implementation("com.google.protobuf:protobuf-java-util:3.25.5") + // fix vulnerability constraints { implementation("com.google.code.gson:gson:2.8.9") @@ -15,6 +13,9 @@ dependencies { } tasks.shadowJar { + relocate("com.google.protobuf", "io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf") relocate("com.google.protobuf.util", "io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.util") relocate("com.google.gson", "io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.gson") + relocate("com.google.common", "io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.common") // Add this + relocate("com.google.guava", "io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.guava") } From 394626e16f3681675cba853377b6d7b8a1feb077 Mon Sep 17 00:00:00 2001 From: Yashwant Date: Fri, 7 Feb 2025 18:29:11 +0530 Subject: [PATCH 2/5] muzzle fix --- instrumentation/grpc-1.6/build.gradle.kts | 1 + .../hypertrace/grpc/v1_6/ProtobufRoundTripConverter.java | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/instrumentation/grpc-1.6/build.gradle.kts b/instrumentation/grpc-1.6/build.gradle.kts index 15782c315..809bb4b03 100644 --- a/instrumentation/grpc-1.6/build.gradle.kts +++ b/instrumentation/grpc-1.6/build.gradle.kts @@ -16,6 +16,7 @@ muzzle { module = "grpc-core" versions = "[1.6.0,)" + //extraDependency("com.google.protobuf:protobuf-java:3.3.1") extraDependency("io.grpc:grpc-netty:1.6.0") } } diff --git a/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/ProtobufRoundTripConverter.java b/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/ProtobufRoundTripConverter.java index 2783f1063..5383f0774 100644 --- a/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/ProtobufRoundTripConverter.java +++ b/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/ProtobufRoundTripConverter.java @@ -16,14 +16,14 @@ package io.opentelemetry.javaagent.instrumentation.hypertrace.grpc.v1_6; -import com.google.protobuf.Descriptors; -import com.google.protobuf.Message; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.trace.Span; import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.DescriptorProtos.FileDescriptorProto; +import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.Descriptors; import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.Descriptors.Descriptor; import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.Descriptors.FileDescriptor; import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.DynamicMessage; +import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.Message; import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.util.JsonFormat; public class ProtobufRoundTripConverter { @@ -49,8 +49,7 @@ public static DynamicMessage convertToRelocatedDynamicMessage(Object message) th // 3. Get the unrelocated file descriptor and its proto representation. Descriptors.FileDescriptor unrelocatedFileDescriptor = originalDescriptor.getFile(); - com.google.protobuf.DescriptorProtos.FileDescriptorProto unrelocatedFileProto = - unrelocatedFileDescriptor.toProto(); + FileDescriptorProto unrelocatedFileProto = unrelocatedFileDescriptor.toProto(); byte[] fileProtoBytes = unrelocatedFileProto.toByteArray(); // 4. Parse the file descriptor proto using relocated classes. From 0b094c4b1c1f561d96c1ec00ccfea5c2752d6810 Mon Sep 17 00:00:00 2001 From: Yashwant Date: Fri, 7 Feb 2025 18:37:47 +0530 Subject: [PATCH 3/5] nit fix --- instrumentation/grpc-1.6/build.gradle.kts | 2 +- .../hypertrace/grpc/v1_6/ProtobufRoundTripConverter.java | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/instrumentation/grpc-1.6/build.gradle.kts b/instrumentation/grpc-1.6/build.gradle.kts index 809bb4b03..3ee2adb2b 100644 --- a/instrumentation/grpc-1.6/build.gradle.kts +++ b/instrumentation/grpc-1.6/build.gradle.kts @@ -16,7 +16,7 @@ muzzle { module = "grpc-core" versions = "[1.6.0,)" - //extraDependency("com.google.protobuf:protobuf-java:3.3.1") + extraDependency("com.google.protobuf:protobuf-java:3.3.1") extraDependency("io.grpc:grpc-netty:1.6.0") } } diff --git a/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/ProtobufRoundTripConverter.java b/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/ProtobufRoundTripConverter.java index 5383f0774..65c716c31 100644 --- a/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/ProtobufRoundTripConverter.java +++ b/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/ProtobufRoundTripConverter.java @@ -19,11 +19,11 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.trace.Span; import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.DescriptorProtos.FileDescriptorProto; -import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.Descriptors; +import com.google.protobuf.Descriptors; import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.Descriptors.Descriptor; import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.Descriptors.FileDescriptor; import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.DynamicMessage; -import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.Message; +import com.google.protobuf.Message; import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.util.JsonFormat; public class ProtobufRoundTripConverter { @@ -49,7 +49,8 @@ public static DynamicMessage convertToRelocatedDynamicMessage(Object message) th // 3. Get the unrelocated file descriptor and its proto representation. Descriptors.FileDescriptor unrelocatedFileDescriptor = originalDescriptor.getFile(); - FileDescriptorProto unrelocatedFileProto = unrelocatedFileDescriptor.toProto(); + com.google.protobuf.DescriptorProtos.FileDescriptorProto unrelocatedFileProto = + unrelocatedFileDescriptor.toProto(); byte[] fileProtoBytes = unrelocatedFileProto.toByteArray(); // 4. Parse the file descriptor proto using relocated classes. From 5648f0ee616b72d04ea42185074b51a003b5cb93 Mon Sep 17 00:00:00 2001 From: Yashwant Date: Fri, 7 Feb 2025 18:43:17 +0530 Subject: [PATCH 4/5] feat spotlessApply --- .../hypertrace/grpc/v1_6/ProtobufRoundTripConverter.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/ProtobufRoundTripConverter.java b/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/ProtobufRoundTripConverter.java index 65c716c31..2783f1063 100644 --- a/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/ProtobufRoundTripConverter.java +++ b/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/ProtobufRoundTripConverter.java @@ -16,14 +16,14 @@ package io.opentelemetry.javaagent.instrumentation.hypertrace.grpc.v1_6; +import com.google.protobuf.Descriptors; +import com.google.protobuf.Message; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.trace.Span; import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.DescriptorProtos.FileDescriptorProto; -import com.google.protobuf.Descriptors; import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.Descriptors.Descriptor; import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.Descriptors.FileDescriptor; import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.DynamicMessage; -import com.google.protobuf.Message; import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.util.JsonFormat; public class ProtobufRoundTripConverter { @@ -50,7 +50,7 @@ public static DynamicMessage convertToRelocatedDynamicMessage(Object message) th // 3. Get the unrelocated file descriptor and its proto representation. Descriptors.FileDescriptor unrelocatedFileDescriptor = originalDescriptor.getFile(); com.google.protobuf.DescriptorProtos.FileDescriptorProto unrelocatedFileProto = - unrelocatedFileDescriptor.toProto(); + unrelocatedFileDescriptor.toProto(); byte[] fileProtoBytes = unrelocatedFileProto.toByteArray(); // 4. Parse the file descriptor proto using relocated classes. From 6817c8bad80d87019415d6eb7472d0130dd83a34 Mon Sep 17 00:00:00 2001 From: Yashwant Date: Wed, 12 Feb 2025 12:01:12 +0530 Subject: [PATCH 5/5] refactor code --- .../grpc/v1_6/GrpcSpanDecorator.java | 28 +++++---------- ...ter.java => ProtobufMessageConverter.java} | 36 +++++++------------ 2 files changed, 21 insertions(+), 43 deletions(-) rename instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/{ProtobufRoundTripConverter.java => ProtobufMessageConverter.java} (74%) diff --git a/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/GrpcSpanDecorator.java b/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/GrpcSpanDecorator.java index f32212e72..085a5613a 100644 --- a/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/GrpcSpanDecorator.java +++ b/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/GrpcSpanDecorator.java @@ -16,6 +16,7 @@ package io.opentelemetry.javaagent.instrumentation.hypertrace.grpc.v1_6; +import com.google.protobuf.Message; import io.grpc.Metadata; import io.grpc.Metadata.Key; import io.opentelemetry.api.common.AttributeKey; @@ -37,12 +38,16 @@ private GrpcSpanDecorator() {} private static final JsonFormat.Printer PRINTER = JsonFormat.printer(); public static void addMessageAttribute(Object message, Span span, AttributeKey key) { - if (isProtobufMessage(message)) { + if (message instanceof Message) { + Message mb = (Message) message; try { - ProtobufRoundTripConverter.addConvertedMessageAttribute(message, span, key); + String jsonOutput = ProtobufMessageConverter.getMessage(mb); + span.setAttribute(key, jsonOutput); } catch (Exception e) { - log.error("Failed to print message as JSON", e); + log.error("Failed to decode message as JSON", e); } + } else { + log.debug("message is not an instance of com.google.protobuf.Message"); } } @@ -83,21 +88,4 @@ public static Map metadataToMap(Metadata metadata) { } return mapHeaders; } - - private static boolean isProtobufMessage(Object message) { - if (message == null) { - return false; - } - // Check the interfaces on the class and its superclasses - Class cls = message.getClass(); - while (cls != null) { - for (Class iface : cls.getInterfaces()) { - if ("com.google.protobuf.Message".equals(iface.getName())) { - return true; - } - } - cls = cls.getSuperclass(); - } - return false; - } } diff --git a/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/ProtobufRoundTripConverter.java b/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/ProtobufMessageConverter.java similarity index 74% rename from instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/ProtobufRoundTripConverter.java rename to instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/ProtobufMessageConverter.java index 2783f1063..ff9d7a33a 100644 --- a/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/ProtobufRoundTripConverter.java +++ b/instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/ProtobufMessageConverter.java @@ -18,16 +18,16 @@ import com.google.protobuf.Descriptors; import com.google.protobuf.Message; -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.trace.Span; import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.DescriptorProtos.FileDescriptorProto; import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.Descriptors.Descriptor; import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.Descriptors.FileDescriptor; import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.DynamicMessage; import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.util.JsonFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -public class ProtobufRoundTripConverter { - +public class ProtobufMessageConverter { + private static final Logger log = LoggerFactory.getLogger(ProtobufMessageConverter.class); /** * Converts an unrelocated protobuf message into a relocated DynamicMessage via a byte-array * round-trip. @@ -36,16 +36,12 @@ public class ProtobufRoundTripConverter { * @return A relocated DynamicMessage built from your relocated protobuf classes. * @throws Exception if conversion fails. */ - public static DynamicMessage convertToRelocatedDynamicMessage(Object message) throws Exception { - if (!(message instanceof Message)) { - throw new IllegalArgumentException("message is not a protobuf Message"); - } + public static DynamicMessage convertToRelocatedDynamicMessage(Message message) throws Exception { // 1. Serialize the original message to bytes. - Message originalMessage = (Message) message; - byte[] messageBytes = originalMessage.toByteArray(); + byte[] messageBytes = message.toByteArray(); // 2. Obtain the original (unrelocated) message descriptor. - Descriptors.Descriptor originalDescriptor = originalMessage.getDescriptorForType(); + Descriptors.Descriptor originalDescriptor = message.getDescriptorForType(); // 3. Get the unrelocated file descriptor and its proto representation. Descriptors.FileDescriptor unrelocatedFileDescriptor = originalDescriptor.getFile(); @@ -58,12 +54,10 @@ public static DynamicMessage convertToRelocatedDynamicMessage(Object message) th FileDescriptorProto relocatedFileProto = FileDescriptorProto.parseFrom(fileProtoBytes); // 5. Build the relocated FileDescriptor. - // Note: This example assumes there are no dependencies. FileDescriptor relocatedFileDescriptor = FileDescriptor.buildFrom(relocatedFileProto, new FileDescriptor[] {}); // 6. Find the relocated message descriptor by name. - // We assume the message name is the same in both relocated and unrelocated files. Descriptor relocatedDescriptor = relocatedFileDescriptor.findMessageTypeByName(originalDescriptor.getName()); if (relocatedDescriptor == null) { @@ -77,15 +71,12 @@ public static DynamicMessage convertToRelocatedDynamicMessage(Object message) th } /** - * Example method that takes an incoming message, converts it to a relocated one, prints it as - * JSON using the relocated JsonFormat, and attaches it as a span attribute. + * Method that takes an incoming message, converts it to a relocated one, prints it as JSON using + * the relocated JsonFormat * * @param message The incoming (unrelocated) protobuf message. - * @param span The span to which to attach the attribute. - * @param key The attribute key. */ - public static void addConvertedMessageAttribute( - Object message, Span span, AttributeKey key) { + public static String getMessage(Message message) { try { // Convert the unrelocated message into a relocated DynamicMessage. DynamicMessage relocatedMessage = convertToRelocatedDynamicMessage(message); @@ -94,11 +85,10 @@ public static void addConvertedMessageAttribute( JsonFormat.Printer relocatedPrinter = JsonFormat.printer(); String jsonOutput = relocatedPrinter.print(relocatedMessage); - // Set the JSON output as a span attribute. - span.setAttribute(key, jsonOutput); + return jsonOutput; } catch (Exception e) { - System.err.println("Failed to convert message via byte-array round-trip: " + e.getMessage()); - e.printStackTrace(); + log.error("Failed to convert message with relocated protobuf message: {}", e.getMessage()); } + return ""; } }