Skip to content

Commit fcfaf54

Browse files
authored
Merge pull request #6947 from DataDog/jpbempel/optimize-redaction-detection
Optimize Redaction detection when capturing values
2 parents 2b0502c + ccc2058 commit fcfaf54

3 files changed

Lines changed: 107 additions & 67 deletions

File tree

dd-java-agent/agent-debugger/debugger-bootstrap/src/main/java/datadog/trace/bootstrap/debugger/CapturedContext.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,10 @@ public static CapturedValue of(
544544
null);
545545
}
546546

547+
public static CapturedValue redacted(String name, String type) {
548+
return build(name, type, REDACTED_VALUE, Limits.DEFAULT, null);
549+
}
550+
547551
public static CapturedValue notCapturedReason(String name, String type, String reason) {
548552
return build(name, type, null, Limits.DEFAULT, reason);
549553
}
@@ -565,9 +569,6 @@ public static CapturedValue raw(
565569

566570
private static CapturedValue build(
567571
String name, String declaredType, Object value, Limits limits, String notCapturedReason) {
568-
if (Redaction.isRedactedKeyword(name)) {
569-
value = REDACTED_VALUE;
570-
}
571572
CapturedValue val =
572573
new CapturedValue(
573574
name, declaredType, value, limits, Collections.emptyMap(), notCapturedReason);

dd-java-agent/agent-debugger/debugger-el/src/test/java/com/datadog/debugger/el/RefResolverHelper.java

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import datadog.trace.bootstrap.debugger.CapturedContext;
44
import datadog.trace.bootstrap.debugger.el.ValueReferenceResolver;
5+
import datadog.trace.bootstrap.debugger.util.Redaction;
56
import java.lang.reflect.Field;
67
import java.util.*;
78

@@ -19,9 +20,15 @@ public static ValueReferenceResolver createResolver(Object instance) {
1920
for (Field field : fields) {
2021
try {
2122
field.setAccessible(true);
22-
fieldValues[index++] =
23-
CapturedContext.CapturedValue.of(
24-
field.getName(), field.getType().getTypeName(), field.get(instance));
23+
if (Redaction.isRedactedKeyword(field.getName())) {
24+
fieldValues[index++] =
25+
CapturedContext.CapturedValue.redacted(
26+
field.getName(), field.getType().getTypeName());
27+
} else {
28+
fieldValues[index++] =
29+
CapturedContext.CapturedValue.of(
30+
field.getName(), field.getType().getTypeName(), field.get(instance));
31+
}
2532
} catch (Exception ex) {
2633
ex.printStackTrace();
2734
}
@@ -54,11 +61,18 @@ private static void fillValues(
5461
int index = 0;
5562
for (Map.Entry<String, Object> entry : fields.entrySet()) {
5663
Object value = entry.getValue();
57-
fieldValues[index++] =
58-
CapturedContext.CapturedValue.of(
59-
entry.getKey(),
60-
value != null ? value.getClass().getTypeName() : Object.class.getTypeName(),
61-
value);
64+
if (Redaction.isRedactedKeyword(entry.getKey())) {
65+
fieldValues[index++] =
66+
CapturedContext.CapturedValue.redacted(
67+
entry.getKey(),
68+
value != null ? value.getClass().getTypeName() : Object.class.getTypeName());
69+
} else {
70+
fieldValues[index++] =
71+
CapturedContext.CapturedValue.of(
72+
entry.getKey(),
73+
value != null ? value.getClass().getTypeName() : Object.class.getTypeName(),
74+
value);
75+
}
6276
}
6377
}
6478
}

dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/CapturedContextInstrumentor.java

Lines changed: 81 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import datadog.trace.bootstrap.debugger.Limits;
3737
import datadog.trace.bootstrap.debugger.MethodLocation;
3838
import datadog.trace.bootstrap.debugger.ProbeId;
39+
import datadog.trace.bootstrap.debugger.util.Redaction;
3940
import datadog.trace.util.Strings;
4041
import java.lang.reflect.Field;
4142
import java.util.ArrayList;
@@ -605,12 +606,16 @@ private void collectArguments(InsnList insnList, Snapshot.Kind kind) {
605606
// stack: [capturedcontext, capturedcontext, array, array, int, string]
606607
ldc(insnList, argType.getClassName());
607608
// stack: [capturedcontext, capturedcontext, array, array, int, string, type_name]
608-
insnList.add(new VarInsnNode(argType.getOpcode(Opcodes.ILOAD), slot));
609-
// stack: [capturedcontext, capturedcontext, array, array, int, string, type_name, arg]
610-
tryBox(argType, insnList);
611-
// stack: [capturedcontext, capturedcontext, array, array, int, type_name, object]
612-
addCapturedValueOf(insnList, limits);
613-
// stack: [capturedcontext, capturedcontext, array, array, int, typed_value]
609+
if (Redaction.isRedactedKeyword(currentArgName)) {
610+
addCapturedValueRedacted(insnList);
611+
} else {
612+
insnList.add(new VarInsnNode(argType.getOpcode(Opcodes.ILOAD), slot));
613+
// stack: [capturedcontext, capturedcontext, array, array, int, string, type_name, arg]
614+
tryBox(argType, insnList);
615+
// stack: [capturedcontext, capturedcontext, array, array, int, string, type_name, object]
616+
addCapturedValueOf(insnList, limits);
617+
}
618+
// stack: [capturedcontext, capturedcontext, array, array, int, captured_value]
614619
insnList.add(new InsnNode(Opcodes.AASTORE));
615620
// stack: [capturedcontext, capturedcontext, array]
616621
slot += argType.getSize();
@@ -635,6 +640,7 @@ private void captureThis(InsnList insnList) {
635640
// stack: [capturedcontext, capturedcontext, array, array, int, string, type_name]
636641
insnList.add(new VarInsnNode(Opcodes.ALOAD, 0));
637642
// stack: [capturedcontext, capturedcontext, array, array, int, string, type_name, this]
643+
// no need to test redaction, 'this' is never redacted
638644
addCapturedValueOf(insnList, limits);
639645
// stack: [capturedcontext, capturedcontext, array, array, int, field_value]
640646
insnList.add(new InsnNode(Opcodes.AASTORE));
@@ -689,12 +695,16 @@ private void collectLocalVariables(AbstractInsnNode location, InsnList insnList)
689695
Type varType = Type.getType(variableNode.desc);
690696
ldc(insnList, Type.getType(variableNode.desc).getClassName());
691697
// stack: [capturedcontext, capturedcontext, array, array, int, name, type_name]
692-
insnList.add(new VarInsnNode(varType.getOpcode(Opcodes.ILOAD), variableNode.index));
693-
// stack: [capturedcontext, capturedcontext, array, array, int, name, type_name, value]
694-
tryBox(varType, insnList);
695-
// stack: [capturedcontext, capturedcontext, array, array, int, name, type_name, object]
696-
addCapturedValueOf(insnList, limits);
697-
// stack: [capturedcontext, capturedcontext, array, array, int, typed_value]
698+
if (Redaction.isRedactedKeyword(variableNode.name)) {
699+
addCapturedValueRedacted(insnList);
700+
} else {
701+
insnList.add(new VarInsnNode(varType.getOpcode(Opcodes.ILOAD), variableNode.index));
702+
// stack: [capturedcontext, capturedcontext, array, array, int, name, type_name, value]
703+
tryBox(varType, insnList);
704+
// stack: [capturedcontext, capturedcontext, array, array, int, name, type_name, object]
705+
addCapturedValueOf(insnList, limits);
706+
}
707+
// stack: [capturedcontext, capturedcontext, array, array, int, captured_value]
698708
insnList.add(new InsnNode(Opcodes.AASTORE));
699709
// stack: [capturedcontext, capturedcontext, array]
700710
}
@@ -745,6 +755,7 @@ private void collectReturnValue(AbstractInsnNode location, InsnList insnList) {
745755
// stack: [ret_value, capturedcontext, capturedcontext, null, type_name, ret_value]
746756
tryBox(returnType, insnList);
747757
// stack: [ret_value, capturedcontext, capturedcontext, null, type_name, ret_value]
758+
// no name, no redaction
748759
addCapturedValueOf(insnList, limits);
749760
// stack: [ret_value, capturedcontext, capturedcontext, capturedvalue]
750761
invokeVirtual(insnList, CAPTURED_CONTEXT_TYPE, "addReturn", Type.VOID_TYPE, CAPTURED_VALUE);
@@ -815,14 +826,18 @@ private void collectStaticFields(InsnList insnList) {
815826
Type fieldType = Type.getType(fieldNode.desc);
816827
ldc(insnList, fieldType.getClassName());
817828
// stack: [capturedcontext, capturedcontext, array, array, int, string, type_name]
818-
insnList.add(
819-
new FieldInsnNode(Opcodes.GETSTATIC, classNode.name, fieldNode.name, fieldNode.desc));
820-
// stack: [capturedcontext, capturedcontext, array, array, int, string, type_name,
821-
// field_value]
822-
tryBox(fieldType, insnList);
823-
// stack: [capturedcontext, capturedcontext, array, array, int, type_name, object]
824-
addCapturedValueOf(insnList, limits);
825-
// stack: [capturedcontext, capturedcontext, array, array, int, typed_value]
829+
if (Redaction.isRedactedKeyword(fieldNode.name)) {
830+
addCapturedValueRedacted(insnList);
831+
} else {
832+
insnList.add(
833+
new FieldInsnNode(Opcodes.GETSTATIC, classNode.name, fieldNode.name, fieldNode.desc));
834+
// stack: [capturedcontext, capturedcontext, array, array, int, string, type_name,
835+
// field_value]
836+
tryBox(fieldType, insnList);
837+
// stack: [capturedcontext, capturedcontext, array, array, int, string, type_name, object]
838+
addCapturedValueOf(insnList, limits);
839+
}
840+
// stack: [capturedcontext, capturedcontext, array, array, int, captured_value]
826841
insnList.add(new InsnNode(Opcodes.AASTORE));
827842
// stack: [capturedcontext, capturedcontext, array]
828843
}
@@ -887,42 +902,46 @@ private void collectFields(InsnList insnList) {
887902
Type fieldType = Type.getType(fieldNode.desc);
888903
ldc(insnList, fieldType.getClassName());
889904
// stack: [capturedcontext, capturedcontext, array, array, int, string, type_name]
890-
switch (fieldNode.name) {
891-
case "dd.trace_id":
892-
{
893-
invokeStatic(insnList, CORRELATION_ACCESS_TYPE, "instance", CORRELATION_ACCESS_TYPE);
894-
// stack: [capturedcontext, capturedcontext, array, array, int, string, type_name,
895-
// access]
896-
invokeVirtual(insnList, CORRELATION_ACCESS_TYPE, "getTraceId", STRING_TYPE);
897-
// stack: [capturedcontext, capturedcontext, array, array, int, string, type_name,
898-
// field_value]
899-
break;
900-
}
901-
case "dd.span_id":
902-
{
903-
invokeStatic(insnList, CORRELATION_ACCESS_TYPE, "instance", CORRELATION_ACCESS_TYPE);
904-
// stack: [capturedcontext, capturedcontext, array, array, int, string, type_name,
905-
// access]
906-
invokeVirtual(insnList, CORRELATION_ACCESS_TYPE, "getSpanId", STRING_TYPE);
907-
// stack: [capturedcontext, capturedcontext, array, array, int, string, type_name,
908-
// field_value]
909-
break;
910-
}
911-
default:
912-
{
913-
insnList.add(new VarInsnNode(Opcodes.ALOAD, 0));
914-
// stack: [capturedcontext, capturedcontext, array, array, int, string, type_name,
915-
// this]
916-
insnList.add(
917-
new FieldInsnNode(
918-
Opcodes.GETFIELD, classNode.name, fieldNode.name, fieldNode.desc));
919-
// stack: [capturedcontext, capturedcontext, array, array, int, string, type_name,
920-
// field_value]
921-
}
905+
if (Redaction.isRedactedKeyword(fieldNode.name)) {
906+
addCapturedValueRedacted(insnList);
907+
} else {
908+
switch (fieldNode.name) {
909+
case "dd.trace_id":
910+
{
911+
invokeStatic(insnList, CORRELATION_ACCESS_TYPE, "instance", CORRELATION_ACCESS_TYPE);
912+
// stack: [capturedcontext, capturedcontext, array, array, int, string, type_name,
913+
// access]
914+
invokeVirtual(insnList, CORRELATION_ACCESS_TYPE, "getTraceId", STRING_TYPE);
915+
// stack: [capturedcontext, capturedcontext, array, array, int, string, type_name,
916+
// field_value]
917+
break;
918+
}
919+
case "dd.span_id":
920+
{
921+
invokeStatic(insnList, CORRELATION_ACCESS_TYPE, "instance", CORRELATION_ACCESS_TYPE);
922+
// stack: [capturedcontext, capturedcontext, array, array, int, string, type_name,
923+
// access]
924+
invokeVirtual(insnList, CORRELATION_ACCESS_TYPE, "getSpanId", STRING_TYPE);
925+
// stack: [capturedcontext, capturedcontext, array, array, int, string, type_name,
926+
// field_value]
927+
break;
928+
}
929+
default:
930+
{
931+
insnList.add(new VarInsnNode(Opcodes.ALOAD, 0));
932+
// stack: [capturedcontext, capturedcontext, array, array, int, string, type_name,
933+
// this]
934+
insnList.add(
935+
new FieldInsnNode(
936+
Opcodes.GETFIELD, classNode.name, fieldNode.name, fieldNode.desc));
937+
// stack: [capturedcontext, capturedcontext, array, array, int, string, type_name,
938+
// field_value]
939+
}
940+
}
941+
tryBox(fieldType, insnList);
942+
// stack: [capturedcontext, capturedcontext, array, array, int, string, type_name, object]
943+
addCapturedValueOf(insnList, limits);
922944
}
923-
tryBox(fieldType, insnList);
924-
// stack: [capturedcontext, capturedcontext, array, array, int, type_name, object]
925-
addCapturedValueOf(insnList, limits);
926945
// stack: [capturedcontext, capturedcontext, array, array, int, CapturedValue]
927946
insnList.add(new InsnNode(Opcodes.AASTORE));
928947
// stack: [capturedcontext, capturedcontext, array]
@@ -1121,7 +1140,7 @@ private void addCapturedValueOf(InsnList insnList, Limits limits) {
11211140
ldc(insnList, limits.getMaxLength());
11221141
ldc(insnList, limits.getMaxFieldCount());
11231142
}
1124-
// expected stack: [type_name, value, int, int, int, int]
1143+
// expected stack: [name, type_name, value, int, int, int, int]
11251144
invokeStatic(
11261145
insnList,
11271146
CAPTURED_VALUE,
@@ -1136,4 +1155,10 @@ private void addCapturedValueOf(InsnList insnList, Limits limits) {
11361155
INT_TYPE);
11371156
// stack: [captured_value]
11381157
}
1158+
1159+
private void addCapturedValueRedacted(InsnList insnList) {
1160+
// expected stack: [name, type_name]
1161+
invokeStatic(insnList, CAPTURED_VALUE, "redacted", CAPTURED_VALUE, STRING_TYPE, STRING_TYPE);
1162+
// stack: [captured_value]
1163+
}
11391164
}

0 commit comments

Comments
 (0)