Skip to content

Commit 45de24d

Browse files
committed
recursive handling of dependencies
1 parent e076234 commit 45de24d

File tree

2 files changed

+64
-13
lines changed

2 files changed

+64
-13
lines changed

instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/GrpcSpanDecorator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public static void addMessageAttribute(Object message, Span span, AttributeKey<S
4444
String jsonOutput = ProtobufMessageConverter.getMessage(mb);
4545
span.setAttribute(key, jsonOutput);
4646
} catch (Exception e) {
47-
log.error("Failed to decode message as JSON", e);
47+
log.debug("Failed to decode message as JSON", e);
4848
}
4949
} else {
5050
log.debug("message is not an instance of com.google.protobuf.Message");

instrumentation/grpc-1.6/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_6/ProtobufMessageConverter.java

Lines changed: 63 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,14 @@
2525
import io.opentelemetry.javaagent.instrumentation.hypertrace.com.google.protobuf.util.JsonFormat;
2626
import java.util.ArrayList;
2727
import java.util.HashMap;
28+
import java.util.HashSet;
2829
import java.util.List;
2930
import java.util.Map;
31+
import java.util.Set;
3032
import org.slf4j.Logger;
3133
import org.slf4j.LoggerFactory;
3234

35+
/** Utility class to convert protobuf messages to JSON. */
3336
public class ProtobufMessageConverter {
3437
private static final Logger log = LoggerFactory.getLogger(ProtobufMessageConverter.class);
3538
private static final Map<String, FileDescriptor> fileDescriptorCache = new HashMap<>();
@@ -75,25 +78,73 @@ private static Descriptor getRelocatedDescriptor(Descriptors.Descriptor original
7578
String fileKey = unrelocatedFileDescriptor.getName();
7679
if (fileDescriptorCache.containsKey(fileKey)) {
7780
FileDescriptor relocatedFileDescriptor = fileDescriptorCache.get(fileKey);
78-
return relocatedFileDescriptor.findMessageTypeByName(originalDescriptor.getName());
81+
82+
// Check if the message type exists in the relocated descriptor
83+
Descriptor messageType =
84+
relocatedFileDescriptor.findMessageTypeByName(originalDescriptor.getName());
85+
if (messageType == null) {
86+
log.debug("Message type not found in cached descriptor: {}", originalDescriptor.getName());
87+
}
88+
89+
return messageType;
90+
}
91+
92+
// Process all dependencies recursively, including transitive ones
93+
FileDescriptor fileDescriptor =
94+
processFileDescriptorWithDependencies(unrelocatedFileDescriptor, new HashSet<>());
95+
96+
// Find the message type in the relocated descriptor
97+
Descriptor result = fileDescriptor.findMessageTypeByName(originalDescriptor.getName());
98+
if (result == null) {
99+
log.debug("Message type not found in new descriptor: {}", originalDescriptor.getName());
79100
}
80101

81-
// Process all dependencies first
102+
return result;
103+
}
104+
105+
/**
106+
* Process a file descriptor and all its dependencies recursively.
107+
*
108+
* @param unrelocatedFileDescriptor The file descriptor to process
109+
* @param processedFiles Set of file names that have already been processed to avoid circular
110+
* dependencies
111+
* @return The relocated file descriptor
112+
*/
113+
private static FileDescriptor processFileDescriptorWithDependencies(
114+
Descriptors.FileDescriptor unrelocatedFileDescriptor, Set<String> processedFiles)
115+
throws Exception {
116+
String fileKey = unrelocatedFileDescriptor.getName();
117+
118+
// Check if we've already processed this file
119+
if (fileDescriptorCache.containsKey(fileKey)) {
120+
return fileDescriptorCache.get(fileKey);
121+
}
122+
123+
// Mark this file as processed to avoid circular dependencies
124+
processedFiles.add(fileKey);
125+
82126
List<FileDescriptor> dependencies = new ArrayList<>();
127+
128+
// Process all direct dependencies first
83129
for (Descriptors.FileDescriptor dependency : unrelocatedFileDescriptor.getDependencies()) {
84130
String depKey = dependency.getName();
85-
if (!fileDescriptorCache.containsKey(depKey)) {
86-
// Convert the dependency file descriptor
87-
com.google.protobuf.DescriptorProtos.FileDescriptorProto depProto = dependency.toProto();
88-
byte[] depBytes = depProto.toByteArray();
89-
FileDescriptorProto relocatedDepProto = FileDescriptorProto.parseFrom(depBytes);
90131

91-
// Build with empty dependencies first (we'll fill them in later)
132+
// Skip if we've already processed this dependency in this call chain
133+
if (processedFiles.contains(depKey)) {
134+
if (fileDescriptorCache.containsKey(depKey)) {
135+
dependencies.add(fileDescriptorCache.get(depKey));
136+
}
137+
continue;
138+
}
139+
140+
if (!fileDescriptorCache.containsKey(depKey)) {
141+
// Process this dependency recursively
92142
FileDescriptor relocatedDep =
93-
FileDescriptor.buildFrom(relocatedDepProto, new FileDescriptor[] {});
94-
fileDescriptorCache.put(depKey, relocatedDep);
143+
processFileDescriptorWithDependencies(dependency, processedFiles);
144+
dependencies.add(relocatedDep);
145+
} else {
146+
dependencies.add(fileDescriptorCache.get(depKey));
95147
}
96-
dependencies.add(fileDescriptorCache.get(depKey));
97148
}
98149

99150
// Now build the current file descriptor with its dependencies
@@ -106,7 +157,7 @@ private static Descriptor getRelocatedDescriptor(Descriptors.Descriptor original
106157
FileDescriptor.buildFrom(relocatedFileProto, dependencies.toArray(new FileDescriptor[0]));
107158
fileDescriptorCache.put(fileKey, relocatedFileDescriptor);
108159

109-
return relocatedFileDescriptor.findMessageTypeByName(originalDescriptor.getName());
160+
return relocatedFileDescriptor;
110161
}
111162

112163
/**

0 commit comments

Comments
 (0)