Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat][sdk-105] Add telemetry #313

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
cd68393
feat(telemetry): add log events
christianbuon Jun 2, 2024
cf90645
feat(telemetry): add navigation events
christianbuon Jun 30, 2024
544830f
feat(telemetry): add Network events
christianbuon Jul 6, 2024
851c050
feat(telemetry): add Manual events
christianbuon Jul 7, 2024
f4bfe15
feat(telemetry): add maximum telemetry data
christianbuon Jul 9, 2024
b6e8176
feat(telemetry): describe usage for static factories
christianbuon Jul 9, 2024
49177f8
fix(telemetry): add maximumTelemetryData to Reactive Streams ConfigBu…
christianbuon Jul 10, 2024
935c933
refactor(telemetry): replace static factories for TelemetryEventTracker
christianbuon Jul 10, 2024
b459e2d
fix(telemetry): remove reference to TelemetryEventTracker in Body
christianbuon Jul 12, 2024
818453c
fix(telemetry): set source only as "client" or "server" for Telemetry…
christianbuon Jul 12, 2024
7220e58
test(telemetry): add tests for TelemetryEvent
christianbuon Jul 14, 2024
9dc8e10
refactor(telemetry): modify equals and hashcode, and create a new has…
christianbuon Jul 14, 2024
8796494
revert(notifier): previous reference
christianbuon Jul 21, 2024
e9645bc
Merge branch 'refs/heads/master' into rollbar-android/feat/SDK-105/ad…
christianbuon Aug 16, 2024
2fcb323
refactor: set source as an enum
christianbuon Aug 16, 2024
7477b41
refactor: docs
christianbuon Aug 16, 2024
19051b7
fix: test
christianbuon Aug 16, 2024
1309682
fix: checkstyle
christianbuon Aug 16, 2024
757f065
fix: checkstyle
christianbuon Aug 16, 2024
d21e120
fix: checkstyle
christianbuon Aug 16, 2024
ec3ebb5
fix: checkstyle
christianbuon Aug 16, 2024
1037c20
Merge branch 'refs/heads/master' into rollbar-android/feat/SDK-105/ad…
christianbuon Sep 20, 2024
c8fe4dc
fix: add revapi acceptedBreaks
christianbuon Sep 20, 2024
e36cd50
fix: checkstyles
christianbuon Sep 20, 2024
630f3af
fix(ci): set expected release configuration
christianbuon Sep 20, 2024
b0923c5
fix(ci): remove jdk7 condition
christianbuon Sep 20, 2024
0dd3b31
fix(ci): set release.sh new folder
christianbuon Sep 20, 2024
72345bf
fix(ci): suggested change
christianbuon Sep 25, 2024
52ae707
refactor(telemetry): move coerce in logic to RollbarTelemetryEventTra…
christianbuon Sep 29, 2024
ba343f8
refactor(telemetry): rename class
christianbuon Sep 29, 2024
5666940
fix(telemetry): checkstyle
christianbuon Sep 29, 2024
5540c08
refactor(telemetry): modify Telemetry queue capacity
christianbuon Oct 1, 2024
9968f7c
refactor(telemetry): modify Telemetry capacity default value
christianbuon Oct 1, 2024
78b2974
fix(telemetry): checkstyle
christianbuon Oct 1, 2024
92e4584
docs(telemetry): fix ConfigBuilder.telemetryEventTracker javadoc
christianbuon Oct 2, 2024
873bee3
docs(telemetry): fix ConfigBuilder.maximumTelemetryData javadoc
christianbuon Oct 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,4 @@ jobs:
NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }}
NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }}
run: |
./gradlew -Dorg.gradle.internal.http.socketTimeout=300000 -Dorg.gradle.internal.http.connectionTimeout=300000 publishToSonatype
./.github/scripts/release.sh
8 changes: 8 additions & 0 deletions .palantir/revapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,11 @@ acceptedBreaks:
justification: "This is a binary compatible change, which could only break custom\
\ implementations of our config interfaces, but those interfaces are not meant\
\ to be implemented by users"
"2.0.0":
com.rollbar:rollbar-java:
- code: "java.method.addedToInterface"
new: "method com.rollbar.notifier.telemetry.TelemetryEventTracker com.rollbar.notifier.config.CommonConfig::telemetryEventTracker()"
justification: "This is going to be added in a major version"
- code: "java.method.addedToInterface"
new: "method int com.rollbar.notifier.config.CommonConfig::maximumTelemetryData()"
justification: "This is going to be added in a major version"
44 changes: 44 additions & 0 deletions rollbar-android/src/main/java/com/rollbar/android/Rollbar.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import android.util.Log;
import com.rollbar.android.notifier.sender.ConnectionAwareSenderFailureStrategy;
import com.rollbar.android.provider.ClientProvider;
import com.rollbar.api.payload.data.TelemetryType;
import com.rollbar.notifier.config.ConfigProvider;
import com.rollbar.notifier.uncaughtexception.RollbarUncaughtExceptionHandler;
import com.rollbar.android.provider.NotifierProvider;
Expand Down Expand Up @@ -926,6 +927,49 @@ public void log(final Throwable error, final Map<String, Object> custom, final S
rollbar.log(error, custom, description, level);
}

/**
* Record log telemetry event. ({@link TelemetryType#LOG}).
*
* @param level the TelemetryEvent severity (e.g. {@link Level#DEBUG}).
* @param message the message sent for this event (e.g. "hello world").
*/
public void recordLogEventFor(Level level, final String message) {
rollbar.recordLogEventFor(level, message);
}

/**
* Record manual telemetry event. ({@link TelemetryType#MANUAL})
*
* @param level the TelemetryEvent severity (e.g. {@link Level#DEBUG}).
* @param message the message sent for this event (e.g. "hello world").
*/
public void recordManualEventFor(Level level, final String message) {
rollbar.recordManualEventFor(level, message);
}

/**
* Record navigation telemetry event with from (origin) and to (destination).({@link TelemetryType#NAVIGATION})
*
* @param level the TelemetryEvent severity (e.g. {@link Level#DEBUG}).
* @param from the starting point (e.g. "SettingView").
* @param to the destination point (e.g. "HomeView").
*/
public void recordNavigationEventFor(Level level, final String from, final String to) {
rollbar.recordNavigationEventFor(level, from, to);
}

/**
* Record network telemetry event with method, url, and status code.({@link TelemetryType#NETWORK})
*
* @param level the TelemetryEvent severity (e.g. {@link Level#DEBUG}).
* @param method the verb used (e.g. "POST").
* @param url the api url (e.g. "<a href="http://rollbar.com/test/api">http://rollbar.com/test/api</a>").
* @param statusCode the response status code (e.g. "404").
*/
public void recordNetworkEventFor(Level level, final String method, final String url, final String statusCode) {
rollbar.recordNetworkEventFor(level, method, url, statusCode);
}

/**
* Send payload to Rollbar.
*
Expand Down
30 changes: 30 additions & 0 deletions rollbar-api/src/main/java/com/rollbar/api/payload/data/Source.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.rollbar.api.payload.data;

import com.rollbar.api.json.JsonSerializable;

/**
* The Source of a payload.
*/
public enum Source implements JsonSerializable {

/**
* A Client source (e.g. Android)
*/
CLIENT("client"),

/**
* A Server source (e.g. Spring)
*/
SERVER("server");

private final String jsonName;

Source(String jsonName) {
this.jsonName = jsonName;
}

@Override
public Object asJson() {
return jsonName;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package com.rollbar.api.payload.data;

import com.rollbar.api.json.JsonSerializable;
import com.rollbar.api.truncation.StringTruncatable;
import com.rollbar.api.truncation.TruncationHelper;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
* Represents an event that allows you to leave a 'breadcrumb' leading up to an exception.
*/
public class TelemetryEvent implements JsonSerializable, StringTruncatable<TelemetryEvent> {

private final TelemetryType type;
private final Level level;
private final Long timestamp;
private final Map<String, String> body;
private final Source source;
private static final long serialVersionUID = 2843361810242481727L;

/**
* Construct a TelemetryEvent.
*
* @param telemetryType {@link TelemetryType}
* @param level {@link Level}
* @param timestamp the timestamp for this TelemetryEvent
* @param source {@link Source}
* @param body a map containing all the data required by the {@link TelemetryType}
*/
public TelemetryEvent(
TelemetryType telemetryType,
Level level,
Long timestamp,
Source source,
Map<String, String> body
) {
type = telemetryType;
this.timestamp = timestamp;
this.level = level;
this.source = source;
this.body = new HashMap<>(body);
}

@Override
public Map<String, Object> asJson() {
Map<String, Object> values = new HashMap<>();
values.put("type", type.asJson());
values.put("level", level.asJson());
values.put("source", source.asJson());
values.put("timestamp_ms", timestamp);
values.put("body", body);
return values;
}

@Override
public TelemetryEvent truncateStrings(int maxLength) {
Map<String, String> truncatedMap = new HashMap<>();
for (Map.Entry<String, String> entry : body.entrySet()) {
String truncatedValue = TruncationHelper.truncateString(entry.getValue(), maxLength);
truncatedMap.put(entry.getKey(), truncatedValue);
}
return new TelemetryEvent(
this.type,
this.level,
this.timestamp,
this.source,
truncatedMap
);
}

@Override
public String toString() {
return "TelemetryEvent{"
+ "type='" + type.asJson() + '\''
+ ", level='" + level.asJson() + '\''
+ ", source='" + source + '\''
+ ", timestamp_ms=" + timestamp
+ ", body=" + body
+ '}';
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
TelemetryEvent that = (TelemetryEvent) o;
return type == that.type && level == that.level && Objects.equals(timestamp, that.timestamp)
&& Objects.equals(body, that.body) && Objects.equals(source, that.source);
}

@Override
public int hashCode() {
return Objects.hash(type, level, timestamp, body, source);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.rollbar.api.payload.data;

import com.rollbar.api.json.JsonSerializable;

/**
* Represents the different types of {@link TelemetryEvent} available.
*/
public enum TelemetryType implements JsonSerializable {
LOG("log"),
MANUAL("manual"),
NAVIGATION("navigation"),
NETWORK("network");

private final String jsonName;

TelemetryType(String jsonName) {
this.jsonName = jsonName;
}

@Override
public Object asJson() {
return jsonName;
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.rollbar.api.payload.data.body;

import com.rollbar.api.json.JsonSerializable;
import com.rollbar.api.payload.data.TelemetryEvent;
import com.rollbar.api.truncation.StringTruncatable;

import java.util.HashMap;
import java.util.List;
import java.util.Objects;

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

private final BodyContent bodyContent;

private final List<TelemetryEvent> telemetryEvents;

private Body(Builder builder) {
this.bodyContent = builder.bodyContent;
this.telemetryEvents = builder.telemetryEvents;
}

/**
Expand All @@ -34,6 +40,10 @@ public Object asJson() {
values.put(bodyContent.getKeyName(), bodyContent);
}

if (telemetryEvents != null) {
values.put("telemetry", telemetryEvents);
}

return values;
}

Expand All @@ -53,24 +63,26 @@ public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {

if (!(o instanceof Body)) {
return false;
}

Body body = (Body) o;

return bodyContent != null ? bodyContent.equals(body.bodyContent) : body.bodyContent == null;
return Objects.equals(bodyContent, body.bodyContent)
&& Objects.equals(telemetryEvents, body.telemetryEvents);
}

@Override
public int hashCode() {
return bodyContent != null ? bodyContent.hashCode() : 0;
return Objects.hash(bodyContent, telemetryEvents);
}

@Override
public String toString() {
return "Body{"
+ "bodyContent=" + bodyContent
+ ", telemetry=" + telemetryEvents
+ '}';
}

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

private BodyContent bodyContent;

private List<TelemetryEvent> telemetryEvents;

/**
* Constructor.
*/
Expand All @@ -95,6 +109,7 @@ public Builder() {
*/
public Builder(Body body) {
this.bodyContent = body.bodyContent;
this.telemetryEvents = body.telemetryEvents;
}

/**
Expand All @@ -109,6 +124,17 @@ public Builder bodyContent(BodyContent bodyContent) {
return this;
}

/**
* The Telemetry events of this body.
*
* @param telemetryEvents the events captured until this payload;
* @return the builder instance.
*/
public Builder telemetryEvents(List<TelemetryEvent> telemetryEvents) {
this.telemetryEvents = telemetryEvents;
return this;
}

/**
* Builds the {@link Body body}.
*
Expand Down
Loading
Loading