Skip to content

Commit 2aa5b77

Browse files
authored
Improve Log Attributes API (#4416)
* Improve logger attributes API * Review feedback
1 parent 4df31f7 commit 2aa5b77

File tree

10 files changed

+310
-60
lines changed

10 files changed

+310
-60
lines changed

sentry/api/sentry.api

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2658,6 +2658,34 @@ public final class io/sentry/SentryAppStartProfilingOptions$JsonKeys {
26582658
public fun <init> ()V
26592659
}
26602660

2661+
public final class io/sentry/SentryAttribute {
2662+
public static fun booleanAttribute (Ljava/lang/String;Ljava/lang/Boolean;)Lio/sentry/SentryAttribute;
2663+
public static fun doubleAttribute (Ljava/lang/String;Ljava/lang/Double;)Lio/sentry/SentryAttribute;
2664+
public fun getName ()Ljava/lang/String;
2665+
public fun getType ()Lio/sentry/SentryAttributeType;
2666+
public fun getValue ()Ljava/lang/Object;
2667+
public static fun integerAttribute (Ljava/lang/String;Ljava/lang/Integer;)Lio/sentry/SentryAttribute;
2668+
public static fun named (Ljava/lang/String;Ljava/lang/Object;)Lio/sentry/SentryAttribute;
2669+
public static fun stringAttribute (Ljava/lang/String;Ljava/lang/String;)Lio/sentry/SentryAttribute;
2670+
}
2671+
2672+
public final class io/sentry/SentryAttributeType : java/lang/Enum {
2673+
public static final field BOOLEAN Lio/sentry/SentryAttributeType;
2674+
public static final field DOUBLE Lio/sentry/SentryAttributeType;
2675+
public static final field INTEGER Lio/sentry/SentryAttributeType;
2676+
public static final field STRING Lio/sentry/SentryAttributeType;
2677+
public fun apiName ()Ljava/lang/String;
2678+
public static fun valueOf (Ljava/lang/String;)Lio/sentry/SentryAttributeType;
2679+
public static fun values ()[Lio/sentry/SentryAttributeType;
2680+
}
2681+
2682+
public final class io/sentry/SentryAttributes {
2683+
public fun add (Lio/sentry/SentryAttribute;)V
2684+
public static fun fromMap (Ljava/util/Map;)Lio/sentry/SentryAttributes;
2685+
public fun getAttributes ()Ljava/util/Map;
2686+
public static fun of ([Lio/sentry/SentryAttribute;)Lio/sentry/SentryAttributes;
2687+
}
2688+
26612689
public final class io/sentry/SentryAutoDateProvider : io/sentry/SentryDateProvider {
26622690
public fun <init> ()V
26632691
public fun now ()Lio/sentry/SentryDate;
@@ -3077,6 +3105,7 @@ public final class io/sentry/SentryLogEvent$JsonKeys {
30773105
}
30783106

30793107
public final class io/sentry/SentryLogEventAttributeValue : io/sentry/JsonSerializable, io/sentry/JsonUnknown {
3108+
public fun <init> (Lio/sentry/SentryAttributeType;Ljava/lang/Object;)V
30803109
public fun <init> (Ljava/lang/String;Ljava/lang/Object;)V
30813110
public fun getType ()Ljava/lang/String;
30823111
public fun getUnknown ()Ljava/util/Map;
@@ -4711,9 +4740,8 @@ public abstract interface class io/sentry/logger/ILoggerApi {
47114740
public abstract fun fatal (Ljava/lang/String;[Ljava/lang/Object;)V
47124741
public abstract fun info (Ljava/lang/String;[Ljava/lang/Object;)V
47134742
public abstract fun log (Lio/sentry/SentryLogLevel;Lio/sentry/SentryDate;Ljava/lang/String;[Ljava/lang/Object;)V
4743+
public abstract fun log (Lio/sentry/SentryLogLevel;Lio/sentry/logger/SentryLogParameters;Ljava/lang/String;[Ljava/lang/Object;)V
47144744
public abstract fun log (Lio/sentry/SentryLogLevel;Ljava/lang/String;[Ljava/lang/Object;)V
4715-
public abstract fun log (Ljava/util/Map;Lio/sentry/SentryLogLevel;Lio/sentry/SentryDate;Ljava/lang/String;[Ljava/lang/Object;)V
4716-
public abstract fun log (Ljava/util/Map;Lio/sentry/SentryLogLevel;Ljava/lang/String;[Ljava/lang/Object;)V
47174745
public abstract fun trace (Ljava/lang/String;[Ljava/lang/Object;)V
47184746
public abstract fun warn (Ljava/lang/String;[Ljava/lang/Object;)V
47194747
}
@@ -4730,9 +4758,8 @@ public final class io/sentry/logger/LoggerApi : io/sentry/logger/ILoggerApi {
47304758
public fun fatal (Ljava/lang/String;[Ljava/lang/Object;)V
47314759
public fun info (Ljava/lang/String;[Ljava/lang/Object;)V
47324760
public fun log (Lio/sentry/SentryLogLevel;Lio/sentry/SentryDate;Ljava/lang/String;[Ljava/lang/Object;)V
4761+
public fun log (Lio/sentry/SentryLogLevel;Lio/sentry/logger/SentryLogParameters;Ljava/lang/String;[Ljava/lang/Object;)V
47334762
public fun log (Lio/sentry/SentryLogLevel;Ljava/lang/String;[Ljava/lang/Object;)V
4734-
public fun log (Ljava/util/Map;Lio/sentry/SentryLogLevel;Lio/sentry/SentryDate;Ljava/lang/String;[Ljava/lang/Object;)V
4735-
public fun log (Ljava/util/Map;Lio/sentry/SentryLogLevel;Ljava/lang/String;[Ljava/lang/Object;)V
47364763
public fun trace (Ljava/lang/String;[Ljava/lang/Object;)V
47374764
public fun warn (Ljava/lang/String;[Ljava/lang/Object;)V
47384765
}
@@ -4752,9 +4779,8 @@ public final class io/sentry/logger/NoOpLoggerApi : io/sentry/logger/ILoggerApi
47524779
public static fun getInstance ()Lio/sentry/logger/NoOpLoggerApi;
47534780
public fun info (Ljava/lang/String;[Ljava/lang/Object;)V
47544781
public fun log (Lio/sentry/SentryLogLevel;Lio/sentry/SentryDate;Ljava/lang/String;[Ljava/lang/Object;)V
4782+
public fun log (Lio/sentry/SentryLogLevel;Lio/sentry/logger/SentryLogParameters;Ljava/lang/String;[Ljava/lang/Object;)V
47554783
public fun log (Lio/sentry/SentryLogLevel;Ljava/lang/String;[Ljava/lang/Object;)V
4756-
public fun log (Ljava/util/Map;Lio/sentry/SentryLogLevel;Lio/sentry/SentryDate;Ljava/lang/String;[Ljava/lang/Object;)V
4757-
public fun log (Ljava/util/Map;Lio/sentry/SentryLogLevel;Ljava/lang/String;[Ljava/lang/Object;)V
47584784
public fun trace (Ljava/lang/String;[Ljava/lang/Object;)V
47594785
public fun warn (Ljava/lang/String;[Ljava/lang/Object;)V
47604786
}
@@ -4765,6 +4791,16 @@ public final class io/sentry/logger/NoOpLoggerBatchProcessor : io/sentry/logger/
47654791
public static fun getInstance ()Lio/sentry/logger/NoOpLoggerBatchProcessor;
47664792
}
47674793

4794+
public final class io/sentry/logger/SentryLogParameters {
4795+
public fun <init> ()V
4796+
public static fun create (Lio/sentry/SentryAttributes;)Lio/sentry/logger/SentryLogParameters;
4797+
public static fun create (Lio/sentry/SentryDate;Lio/sentry/SentryAttributes;)Lio/sentry/logger/SentryLogParameters;
4798+
public fun getAttributes ()Lio/sentry/SentryAttributes;
4799+
public fun getTimestamp ()Lio/sentry/SentryDate;
4800+
public fun setAttributes (Lio/sentry/SentryAttributes;)V
4801+
public fun setTimestamp (Lio/sentry/SentryDate;)V
4802+
}
4803+
47684804
public final class io/sentry/opentelemetry/OpenTelemetryUtil {
47694805
public fun <init> ()V
47704806
public static fun applyIgnoredSpanOrigins (Lio/sentry/SentryOptions;)V
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package io.sentry;
2+
3+
import org.jetbrains.annotations.NotNull;
4+
import org.jetbrains.annotations.Nullable;
5+
6+
public final class SentryAttribute {
7+
8+
private final @NotNull String name;
9+
private final @Nullable SentryAttributeType type;
10+
private final @Nullable Object value;
11+
12+
private SentryAttribute(
13+
final @NotNull String name,
14+
final @Nullable SentryAttributeType type,
15+
final @Nullable Object value) {
16+
this.name = name;
17+
this.type = type;
18+
this.value = value;
19+
}
20+
21+
public @NotNull String getName() {
22+
return name;
23+
}
24+
25+
public @Nullable SentryAttributeType getType() {
26+
return type;
27+
}
28+
29+
public @Nullable Object getValue() {
30+
return value;
31+
}
32+
33+
public static @NotNull SentryAttribute named(
34+
final @NotNull String name, final @Nullable Object value) {
35+
return new SentryAttribute(name, null, value);
36+
}
37+
38+
public static @NotNull SentryAttribute booleanAttribute(
39+
final @NotNull String name, final @Nullable Boolean value) {
40+
return new SentryAttribute(name, SentryAttributeType.BOOLEAN, value);
41+
}
42+
43+
public static @NotNull SentryAttribute integerAttribute(
44+
final @NotNull String name, final @Nullable Integer value) {
45+
return new SentryAttribute(name, SentryAttributeType.INTEGER, value);
46+
}
47+
48+
public static @NotNull SentryAttribute doubleAttribute(
49+
final @NotNull String name, final @Nullable Double value) {
50+
return new SentryAttribute(name, SentryAttributeType.DOUBLE, value);
51+
}
52+
53+
public static @NotNull SentryAttribute stringAttribute(
54+
final @NotNull String name, final @Nullable String value) {
55+
return new SentryAttribute(name, SentryAttributeType.STRING, value);
56+
}
57+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package io.sentry;
2+
3+
import java.util.Locale;
4+
import org.jetbrains.annotations.NotNull;
5+
6+
public enum SentryAttributeType {
7+
STRING,
8+
BOOLEAN,
9+
INTEGER,
10+
DOUBLE;
11+
12+
public @NotNull String apiName() {
13+
return name().toLowerCase(Locale.ROOT);
14+
}
15+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package io.sentry;
2+
3+
import java.util.Map;
4+
import java.util.concurrent.ConcurrentHashMap;
5+
import org.jetbrains.annotations.NotNull;
6+
import org.jetbrains.annotations.Nullable;
7+
8+
public final class SentryAttributes {
9+
10+
private final @NotNull Map<String, SentryAttribute> attributes;
11+
12+
private SentryAttributes(final @NotNull Map<String, SentryAttribute> attributes) {
13+
this.attributes = attributes;
14+
}
15+
16+
public void add(final @Nullable SentryAttribute attribute) {
17+
if (attribute == null) {
18+
return;
19+
}
20+
attributes.put(attribute.getName(), attribute);
21+
}
22+
23+
public @NotNull Map<String, SentryAttribute> getAttributes() {
24+
return attributes;
25+
}
26+
27+
public static @NotNull SentryAttributes of(final @Nullable SentryAttribute... attributes) {
28+
if (attributes == null) {
29+
return new SentryAttributes(new ConcurrentHashMap<>());
30+
}
31+
final @NotNull SentryAttributes sentryAttributes =
32+
new SentryAttributes(new ConcurrentHashMap<>(attributes.length));
33+
for (SentryAttribute attribute : attributes) {
34+
sentryAttributes.add(attribute);
35+
}
36+
return sentryAttributes;
37+
}
38+
39+
public static @NotNull SentryAttributes fromMap(final @Nullable Map<String, Object> attributes) {
40+
if (attributes == null) {
41+
return new SentryAttributes(new ConcurrentHashMap<>());
42+
}
43+
final @NotNull SentryAttributes sentryAttributes =
44+
new SentryAttributes(new ConcurrentHashMap<>(attributes.size()));
45+
for (Map.Entry<String, Object> attribute : attributes.entrySet()) {
46+
final @Nullable String key = attribute.getKey();
47+
if (key != null) {
48+
sentryAttributes.add(SentryAttribute.named(key, attribute.getValue()));
49+
}
50+
}
51+
52+
return sentryAttributes;
53+
}
54+
}

sentry/src/main/java/io/sentry/SentryLogEventAttributeValue.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ public SentryLogEventAttributeValue(final @NotNull String type, final @Nullable
2222
}
2323
}
2424

25+
public SentryLogEventAttributeValue(
26+
final @NotNull SentryAttributeType type, final @Nullable Object value) {
27+
this.type = type.apiName();
28+
this.value = value;
29+
}
30+
2531
public @NotNull String getType() {
2632
return type;
2733
}

sentry/src/main/java/io/sentry/logger/ILoggerApi.java

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import io.sentry.SentryDate;
44
import io.sentry.SentryLogLevel;
5-
import java.util.Map;
65
import org.jetbrains.annotations.ApiStatus;
76
import org.jetbrains.annotations.NotNull;
87
import org.jetbrains.annotations.Nullable;
@@ -31,15 +30,8 @@ void log(
3130
@Nullable Object... args);
3231

3332
void log(
34-
@Nullable Map<String, Object> attributes,
3533
@NotNull SentryLogLevel level,
36-
@Nullable String message,
37-
@Nullable Object... args);
38-
39-
void log(
40-
@Nullable Map<String, Object> attributes,
41-
@NotNull SentryLogLevel level,
42-
@Nullable SentryDate timestamp,
34+
@NotNull SentryLogParameters params,
4335
@Nullable String message,
4436
@Nullable Object... args);
4537
}

sentry/src/main/java/io/sentry/logger/LoggerApi.java

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
import io.sentry.ISpan;
66
import io.sentry.PropagationContext;
77
import io.sentry.Scopes;
8+
import io.sentry.SentryAttribute;
9+
import io.sentry.SentryAttributeType;
10+
import io.sentry.SentryAttributes;
811
import io.sentry.SentryDate;
912
import io.sentry.SentryLevel;
1013
import io.sentry.SentryLogEvent;
@@ -17,7 +20,6 @@
1720
import io.sentry.util.Platform;
1821
import io.sentry.util.TracingUtils;
1922
import java.util.HashMap;
20-
import java.util.Map;
2123
import org.jetbrains.annotations.ApiStatus;
2224
import org.jetbrains.annotations.NotNull;
2325
import org.jetbrains.annotations.Nullable;
@@ -66,7 +68,7 @@ public void log(
6668
final @NotNull SentryLogLevel level,
6769
final @Nullable String message,
6870
final @Nullable Object... args) {
69-
captureLog(null, level, null, message, args);
71+
captureLog(level, SentryLogParameters.create(null, null), message, args);
7072
}
7173

7274
@Override
@@ -75,33 +77,22 @@ public void log(
7577
final @Nullable SentryDate timestamp,
7678
final @Nullable String message,
7779
final @Nullable Object... args) {
78-
captureLog(null, level, timestamp, message, args);
80+
captureLog(level, SentryLogParameters.create(timestamp, null), message, args);
7981
}
8082

8183
@Override
8284
public void log(
83-
final @Nullable Map<String, Object> attributes,
8485
final @NotNull SentryLogLevel level,
85-
final @Nullable SentryDate timestamp,
86+
final @NotNull SentryLogParameters params,
8687
final @Nullable String message,
8788
final @Nullable Object... args) {
88-
captureLog(attributes, level, timestamp, message, args);
89-
}
90-
91-
@Override
92-
public void log(
93-
final @Nullable Map<String, Object> attributes,
94-
final @NotNull SentryLogLevel level,
95-
final @Nullable String message,
96-
final @Nullable Object... args) {
97-
captureLog(attributes, level, null, message, args);
89+
captureLog(level, params, message, args);
9890
}
9991

10092
@SuppressWarnings("AnnotateFormatMethod")
10193
private void captureLog(
102-
final @Nullable Map<String, Object> attributes,
10394
final @NotNull SentryLogLevel level,
104-
final @Nullable SentryDate timestamp,
95+
final @NotNull SentryLogParameters params,
10596
final @Nullable String message,
10697
final @Nullable Object... args) {
10798
final @NotNull SentryOptions options = scopes.getOptions();
@@ -124,6 +115,7 @@ private void captureLog(
124115
return;
125116
}
126117

118+
final @Nullable SentryDate timestamp = params.getTimestamp();
127119
final @NotNull SentryDate timestampToUse =
128120
timestamp == null ? options.getDateProvider().now() : timestamp;
129121
final @NotNull String messageToUse = maybeFormatMessage(message, args);
@@ -140,7 +132,7 @@ private void captureLog(
140132
span == null ? propagationContext.getSpanId() : span.getSpanContext().getSpanId();
141133
final SentryLogEvent logEvent =
142134
new SentryLogEvent(traceId, timestampToUse, messageToUse, level);
143-
logEvent.setAttributes(createAttributes(attributes, message, spanId, args));
135+
logEvent.setAttributes(createAttributes(params.getAttributes(), message, spanId, args));
144136
logEvent.setSeverityNumber(level.getSeverityNumber());
145137

146138
scopes.getClient().captureLog(logEvent, combinedScope);
@@ -167,24 +159,25 @@ private void captureLog(
167159
}
168160

169161
private @NotNull HashMap<String, SentryLogEventAttributeValue> createAttributes(
170-
final @Nullable Map<String, Object> incomingAttributes,
162+
final @Nullable SentryAttributes incomingAttributes,
171163
final @NotNull String message,
172164
final @NotNull SpanId spanId,
173165
final @Nullable Object... args) {
174166
final @NotNull HashMap<String, SentryLogEventAttributeValue> attributes = new HashMap<>();
175167

176168
if (incomingAttributes != null) {
177-
for (Map.Entry<String, Object> attributeEntry : incomingAttributes.entrySet()) {
178-
final @Nullable Object value = attributeEntry.getValue();
179-
final @NotNull String type = getType(value);
180-
attributes.put(attributeEntry.getKey(), new SentryLogEventAttributeValue(type, value));
169+
for (SentryAttribute attribute : incomingAttributes.getAttributes().values()) {
170+
final @Nullable Object value = attribute.getValue();
171+
final @NotNull SentryAttributeType type =
172+
attribute.getType() == null ? getType(value) : attribute.getType();
173+
attributes.put(attribute.getName(), new SentryLogEventAttributeValue(type, value));
181174
}
182175
}
183176

184177
if (args != null) {
185178
int i = 0;
186179
for (Object arg : args) {
187-
final @NotNull String type = getType(arg);
180+
final @NotNull SentryAttributeType type = getType(arg);
188181
attributes.put(
189182
"sentry.message.parameter." + i, new SentryLogEventAttributeValue(type, arg));
190183
i++;
@@ -238,16 +231,16 @@ private void setServerName(
238231
}
239232
}
240233

241-
private @NotNull String getType(final @Nullable Object arg) {
234+
private @NotNull SentryAttributeType getType(final @Nullable Object arg) {
242235
if (arg instanceof Boolean) {
243-
return "boolean";
236+
return SentryAttributeType.BOOLEAN;
244237
}
245238
if (arg instanceof Integer) {
246-
return "integer";
239+
return SentryAttributeType.INTEGER;
247240
}
248241
if (arg instanceof Number) {
249-
return "double";
242+
return SentryAttributeType.DOUBLE;
250243
}
251-
return "string";
244+
return SentryAttributeType.STRING;
252245
}
253246
}

0 commit comments

Comments
 (0)