Skip to content

Commit 2bbb12c

Browse files
[feat][sdk-105] Add telemetry (#313)
* feat(telemetry): add log events * feat(telemetry): add navigation events * feat(telemetry): add Network events * feat(telemetry): add Manual events * feat(telemetry): add maximum telemetry data * feat(telemetry): describe usage for static factories * fix(telemetry): add maximumTelemetryData to Reactive Streams ConfigBuilder * refactor(telemetry): replace static factories for TelemetryEventTracker * fix(telemetry): remove reference to TelemetryEventTracker in Body * fix(telemetry): set source only as "client" or "server" for Telemetry events * test(telemetry): add tests for TelemetryEvent * refactor(telemetry): modify equals and hashcode, and create a new hashmap in constructor * revert(notifier): previous reference * refactor: set source as an enum * refactor: docs * fix: test * fix: checkstyle * fix: checkstyle * fix: checkstyle * fix: checkstyle * fix: add revapi acceptedBreaks * fix: checkstyles * fix(ci): set expected release configuration * fix(ci): remove jdk7 condition * fix(ci): set release.sh new folder * fix(ci): suggested change * refactor(telemetry): move coerce in logic to RollbarTelemetryEventTracker * refactor(telemetry): rename class * fix(telemetry): checkstyle * refactor(telemetry): modify Telemetry queue capacity * refactor(telemetry): modify Telemetry capacity default value * fix(telemetry): checkstyle * docs(telemetry): fix ConfigBuilder.telemetryEventTracker javadoc * docs(telemetry): fix ConfigBuilder.maximumTelemetryData javadoc
1 parent 32abb9e commit 2bbb12c

File tree

18 files changed

+1197
-12
lines changed

18 files changed

+1197
-12
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,4 @@ jobs:
105105
NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }}
106106
NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }}
107107
run: |
108-
./gradlew -Dorg.gradle.internal.http.socketTimeout=300000 -Dorg.gradle.internal.http.connectionTimeout=300000 publishToSonatype
108+
./.github/scripts/release.sh

.palantir/revapi.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,11 @@ acceptedBreaks:
2525
justification: "This is a binary compatible change, which could only break custom\
2626
\ implementations of our config interfaces, but those interfaces are not meant\
2727
\ to be implemented by users"
28+
"2.0.0":
29+
com.rollbar:rollbar-java:
30+
- code: "java.method.addedToInterface"
31+
new: "method com.rollbar.notifier.telemetry.TelemetryEventTracker com.rollbar.notifier.config.CommonConfig::telemetryEventTracker()"
32+
justification: "This is going to be added in a major version"
33+
- code: "java.method.addedToInterface"
34+
new: "method int com.rollbar.notifier.config.CommonConfig::maximumTelemetryData()"
35+
justification: "This is going to be added in a major version"

rollbar-android/src/main/java/com/rollbar/android/Rollbar.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import android.util.Log;
1313
import com.rollbar.android.notifier.sender.ConnectionAwareSenderFailureStrategy;
1414
import com.rollbar.android.provider.ClientProvider;
15+
import com.rollbar.api.payload.data.TelemetryType;
1516
import com.rollbar.notifier.config.ConfigProvider;
1617
import com.rollbar.notifier.uncaughtexception.RollbarUncaughtExceptionHandler;
1718
import com.rollbar.android.provider.NotifierProvider;
@@ -926,6 +927,49 @@ public void log(final Throwable error, final Map<String, Object> custom, final S
926927
rollbar.log(error, custom, description, level);
927928
}
928929

930+
/**
931+
* Record log telemetry event. ({@link TelemetryType#LOG}).
932+
*
933+
* @param level the TelemetryEvent severity (e.g. {@link Level#DEBUG}).
934+
* @param message the message sent for this event (e.g. "hello world").
935+
*/
936+
public void recordLogEventFor(Level level, final String message) {
937+
rollbar.recordLogEventFor(level, message);
938+
}
939+
940+
/**
941+
* Record manual telemetry event. ({@link TelemetryType#MANUAL})
942+
*
943+
* @param level the TelemetryEvent severity (e.g. {@link Level#DEBUG}).
944+
* @param message the message sent for this event (e.g. "hello world").
945+
*/
946+
public void recordManualEventFor(Level level, final String message) {
947+
rollbar.recordManualEventFor(level, message);
948+
}
949+
950+
/**
951+
* Record navigation telemetry event with from (origin) and to (destination).({@link TelemetryType#NAVIGATION})
952+
*
953+
* @param level the TelemetryEvent severity (e.g. {@link Level#DEBUG}).
954+
* @param from the starting point (e.g. "SettingView").
955+
* @param to the destination point (e.g. "HomeView").
956+
*/
957+
public void recordNavigationEventFor(Level level, final String from, final String to) {
958+
rollbar.recordNavigationEventFor(level, from, to);
959+
}
960+
961+
/**
962+
* Record network telemetry event with method, url, and status code.({@link TelemetryType#NETWORK})
963+
*
964+
* @param level the TelemetryEvent severity (e.g. {@link Level#DEBUG}).
965+
* @param method the verb used (e.g. "POST").
966+
* @param url the api url (e.g. "<a href="http://rollbar.com/test/api">http://rollbar.com/test/api</a>").
967+
* @param statusCode the response status code (e.g. "404").
968+
*/
969+
public void recordNetworkEventFor(Level level, final String method, final String url, final String statusCode) {
970+
rollbar.recordNetworkEventFor(level, method, url, statusCode);
971+
}
972+
929973
/**
930974
* Send payload to Rollbar.
931975
*
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.rollbar.api.payload.data;
2+
3+
import com.rollbar.api.json.JsonSerializable;
4+
5+
/**
6+
* The Source of a payload.
7+
*/
8+
public enum Source implements JsonSerializable {
9+
10+
/**
11+
* A Client source (e.g. Android)
12+
*/
13+
CLIENT("client"),
14+
15+
/**
16+
* A Server source (e.g. Spring)
17+
*/
18+
SERVER("server");
19+
20+
private final String jsonName;
21+
22+
Source(String jsonName) {
23+
this.jsonName = jsonName;
24+
}
25+
26+
@Override
27+
public Object asJson() {
28+
return jsonName;
29+
}
30+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package com.rollbar.api.payload.data;
2+
3+
import com.rollbar.api.json.JsonSerializable;
4+
import com.rollbar.api.truncation.StringTruncatable;
5+
import com.rollbar.api.truncation.TruncationHelper;
6+
7+
import java.util.HashMap;
8+
import java.util.Map;
9+
import java.util.Objects;
10+
11+
/**
12+
* Represents an event that allows you to leave a 'breadcrumb' leading up to an exception.
13+
*/
14+
public class TelemetryEvent implements JsonSerializable, StringTruncatable<TelemetryEvent> {
15+
16+
private final TelemetryType type;
17+
private final Level level;
18+
private final Long timestamp;
19+
private final Map<String, String> body;
20+
private final Source source;
21+
private static final long serialVersionUID = 2843361810242481727L;
22+
23+
/**
24+
* Construct a TelemetryEvent.
25+
*
26+
* @param telemetryType {@link TelemetryType}
27+
* @param level {@link Level}
28+
* @param timestamp the timestamp for this TelemetryEvent
29+
* @param source {@link Source}
30+
* @param body a map containing all the data required by the {@link TelemetryType}
31+
*/
32+
public TelemetryEvent(
33+
TelemetryType telemetryType,
34+
Level level,
35+
Long timestamp,
36+
Source source,
37+
Map<String, String> body
38+
) {
39+
type = telemetryType;
40+
this.timestamp = timestamp;
41+
this.level = level;
42+
this.source = source;
43+
this.body = new HashMap<>(body);
44+
}
45+
46+
@Override
47+
public Map<String, Object> asJson() {
48+
Map<String, Object> values = new HashMap<>();
49+
values.put("type", type.asJson());
50+
values.put("level", level.asJson());
51+
values.put("source", source.asJson());
52+
values.put("timestamp_ms", timestamp);
53+
values.put("body", body);
54+
return values;
55+
}
56+
57+
@Override
58+
public TelemetryEvent truncateStrings(int maxLength) {
59+
Map<String, String> truncatedMap = new HashMap<>();
60+
for (Map.Entry<String, String> entry : body.entrySet()) {
61+
String truncatedValue = TruncationHelper.truncateString(entry.getValue(), maxLength);
62+
truncatedMap.put(entry.getKey(), truncatedValue);
63+
}
64+
return new TelemetryEvent(
65+
this.type,
66+
this.level,
67+
this.timestamp,
68+
this.source,
69+
truncatedMap
70+
);
71+
}
72+
73+
@Override
74+
public String toString() {
75+
return "TelemetryEvent{"
76+
+ "type='" + type.asJson() + '\''
77+
+ ", level='" + level.asJson() + '\''
78+
+ ", source='" + source + '\''
79+
+ ", timestamp_ms=" + timestamp
80+
+ ", body=" + body
81+
+ '}';
82+
}
83+
84+
@Override
85+
public boolean equals(Object o) {
86+
if (this == o) {
87+
return true;
88+
}
89+
if (o == null || getClass() != o.getClass()) {
90+
return false;
91+
}
92+
TelemetryEvent that = (TelemetryEvent) o;
93+
return type == that.type && level == that.level && Objects.equals(timestamp, that.timestamp)
94+
&& Objects.equals(body, that.body) && Objects.equals(source, that.source);
95+
}
96+
97+
@Override
98+
public int hashCode() {
99+
return Objects.hash(type, level, timestamp, body, source);
100+
}
101+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.rollbar.api.payload.data;
2+
3+
import com.rollbar.api.json.JsonSerializable;
4+
5+
/**
6+
* Represents the different types of {@link TelemetryEvent} available.
7+
*/
8+
public enum TelemetryType implements JsonSerializable {
9+
LOG("log"),
10+
MANUAL("manual"),
11+
NAVIGATION("navigation"),
12+
NETWORK("network");
13+
14+
private final String jsonName;
15+
16+
TelemetryType(String jsonName) {
17+
this.jsonName = jsonName;
18+
}
19+
20+
@Override
21+
public Object asJson() {
22+
return jsonName;
23+
}
24+
}

rollbar-api/src/main/java/com/rollbar/api/payload/data/body/Body.java

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package com.rollbar.api.payload.data.body;
22

33
import com.rollbar.api.json.JsonSerializable;
4+
import com.rollbar.api.payload.data.TelemetryEvent;
45
import com.rollbar.api.truncation.StringTruncatable;
56

67
import java.util.HashMap;
8+
import java.util.List;
9+
import java.util.Objects;
710

811
/**
912
* A container for the actual error(s), message, or crash report that caused this error.
@@ -14,8 +17,11 @@ public class Body implements JsonSerializable, StringTruncatable<Body> {
1417

1518
private final BodyContent bodyContent;
1619

20+
private final List<TelemetryEvent> telemetryEvents;
21+
1722
private Body(Builder builder) {
1823
this.bodyContent = builder.bodyContent;
24+
this.telemetryEvents = builder.telemetryEvents;
1925
}
2026

2127
/**
@@ -34,6 +40,10 @@ public Object asJson() {
3440
values.put(bodyContent.getKeyName(), bodyContent);
3541
}
3642

43+
if (telemetryEvents != null) {
44+
values.put("telemetry", telemetryEvents);
45+
}
46+
3747
return values;
3848
}
3949

@@ -53,24 +63,26 @@ public boolean equals(Object o) {
5363
if (this == o) {
5464
return true;
5565
}
56-
if (o == null || getClass() != o.getClass()) {
66+
67+
if (!(o instanceof Body)) {
5768
return false;
5869
}
5970

6071
Body body = (Body) o;
61-
62-
return bodyContent != null ? bodyContent.equals(body.bodyContent) : body.bodyContent == null;
72+
return Objects.equals(bodyContent, body.bodyContent)
73+
&& Objects.equals(telemetryEvents, body.telemetryEvents);
6374
}
6475

6576
@Override
6677
public int hashCode() {
67-
return bodyContent != null ? bodyContent.hashCode() : 0;
78+
return Objects.hash(bodyContent, telemetryEvents);
6879
}
6980

7081
@Override
7182
public String toString() {
7283
return "Body{"
7384
+ "bodyContent=" + bodyContent
85+
+ ", telemetry=" + telemetryEvents
7486
+ '}';
7587
}
7688

@@ -81,6 +93,8 @@ public static final class Builder {
8193

8294
private BodyContent bodyContent;
8395

96+
private List<TelemetryEvent> telemetryEvents;
97+
8498
/**
8599
* Constructor.
86100
*/
@@ -95,6 +109,7 @@ public Builder() {
95109
*/
96110
public Builder(Body body) {
97111
this.bodyContent = body.bodyContent;
112+
this.telemetryEvents = body.telemetryEvents;
98113
}
99114

100115
/**
@@ -109,6 +124,17 @@ public Builder bodyContent(BodyContent bodyContent) {
109124
return this;
110125
}
111126

127+
/**
128+
* The Telemetry events of this body.
129+
*
130+
* @param telemetryEvents the events captured until this payload;
131+
* @return the builder instance.
132+
*/
133+
public Builder telemetryEvents(List<TelemetryEvent> telemetryEvents) {
134+
this.telemetryEvents = telemetryEvents;
135+
return this;
136+
}
137+
112138
/**
113139
* Builds the {@link Body body}.
114140
*

0 commit comments

Comments
 (0)