Skip to content

Commit 907047c

Browse files
authored
Merge pull request #8 from pc9795/main
Basic client migrated from Exceptionless.JavaScript [WIP]
2 parents cddb1f0 + e888c2d commit 907047c

File tree

72 files changed

+2718
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+2718
-2
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,7 @@
2121

2222
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
2323
hs_err_pid*
24+
25+
.idea/
26+
*.iml
27+
target/

README.md

Lines changed: 0 additions & 2 deletions
This file was deleted.

Readme.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Exceptionless.Java [In Progress...]
2+
3+
Java cleint for [Exceptionless](https://exceptionless.com/)
4+
5+
`google-java-format` is used for code-formatting

pom.xml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>com.prashantchaubey</groupId>
8+
<artifactId>exceptionless-client</artifactId>
9+
<version>1.0</version>
10+
11+
<dependencies>
12+
<dependency>
13+
<groupId>org.projectlombok</groupId>
14+
<artifactId>lombok</artifactId>
15+
<version>1.18.10</version>
16+
</dependency>
17+
<dependency>
18+
<groupId>ch.qos.logback</groupId>
19+
<artifactId>logback-classic</artifactId>
20+
<version>1.1.7</version>
21+
</dependency>
22+
<dependency>
23+
<groupId>com.fasterxml.jackson.core</groupId>
24+
<artifactId>jackson-databind</artifactId>
25+
<version>2.9.5</version>
26+
</dependency>
27+
</dependencies>
28+
29+
<build>
30+
<plugins>
31+
<plugin>
32+
<groupId>org.apache.maven.plugins</groupId>
33+
<artifactId>maven-compiler-plugin</artifactId>
34+
<version>3.5.1</version>
35+
<configuration>
36+
<source>11</source>
37+
<target>11</target>
38+
<annotationProcessorPaths>
39+
<path>
40+
<groupId>org.projectlombok</groupId>
41+
<artifactId>lombok</artifactId>
42+
<version>1.18.10</version>
43+
</path>
44+
</annotationProcessorPaths>
45+
</configuration>
46+
</plugin>
47+
</plugins>
48+
</build>
49+
</project>

samples/example-app/pom.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>com.prashantchaubey</groupId>
8+
<artifactId>example-app</artifactId>
9+
<version>1.0</version>
10+
11+
12+
</project>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>com.prashantchaubey</groupId>
8+
<artifactId>example-spring-boot-app</artifactId>
9+
<version>1.0-SNAPSHOT</version>
10+
11+
12+
</project>
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
package com.prashantchaubey.exceptionlessclient;
2+
3+
import com.prashantchaubey.exceptionlessclient.configuration.ConfigurationManager;
4+
import com.prashantchaubey.exceptionlessclient.models.Event;
5+
import com.prashantchaubey.exceptionlessclient.models.EventPluginContext;
6+
import com.prashantchaubey.exceptionlessclient.models.PluginContext;
7+
import com.prashantchaubey.exceptionlessclient.models.UserDescription;
8+
import com.prashantchaubey.exceptionlessclient.models.enums.EventPropertyKey;
9+
import com.prashantchaubey.exceptionlessclient.models.enums.EventType;
10+
import com.prashantchaubey.exceptionlessclient.models.submission.SubmissionResponse;
11+
import com.prashantchaubey.exceptionlessclient.plugins.EventPluginManager;
12+
import lombok.Builder;
13+
import lombok.Getter;
14+
15+
import java.time.LocalDate;
16+
import java.util.Timer;
17+
import java.util.TimerTask;
18+
import java.util.function.Consumer;
19+
20+
@Builder(builderClassName = "ExceptionlessClientInternalBuilder")
21+
@Getter
22+
public class ExceptionlessClient {
23+
private static final int UPDATE_SETTINGS_TIMER_INITIAL_DELAY = 5000;
24+
25+
private ConfigurationManager configurationManager;
26+
27+
// lombok ignored fields
28+
private EventPluginManager $eventPluginManager;
29+
private Timer $updateSettingsTimer = new Timer();
30+
31+
public static ExceptionlessClient from(String apiKey, String serverUrl) {
32+
return ExceptionlessClient.builder()
33+
.configurationManager(ConfigurationManager.from(apiKey, serverUrl))
34+
.build();
35+
}
36+
37+
public void submitException(Exception exception, Consumer<EventPluginContext> handler) {
38+
Event event = createException().build();
39+
PluginContext pluginContext = PluginContext.builder().exception(exception).build();
40+
submitEvent(EventPluginContext.builder().event(event).context(pluginContext).build(), handler);
41+
}
42+
43+
private Event.EventBuilderImpl createException() {
44+
return createEvent().type(EventType.ERROR.value());
45+
}
46+
47+
public void submitUnhandledException(
48+
Exception exception, String submissionMethod, Consumer<EventPluginContext> handler) {
49+
Event event = createException().build();
50+
PluginContext pluginContext =
51+
PluginContext.builder()
52+
.exception(exception)
53+
.markAsUnhandledError()
54+
.submissionMethod(submissionMethod)
55+
.build();
56+
submitEvent(EventPluginContext.builder().event(event).context(pluginContext).build(), handler);
57+
}
58+
59+
public void submitFeatureUsage(String feature, Consumer<EventPluginContext> handler) {
60+
Event event = createFeatureUsage(feature).build();
61+
submitEvent(EventPluginContext.from(event), handler);
62+
}
63+
64+
private Event.EventBuilderImpl createFeatureUsage(String feature) {
65+
return createEvent().type(EventType.USAGE.value()).source(feature);
66+
}
67+
68+
public void submitLog(String message, Consumer<EventPluginContext> handler) {
69+
submitLog(message, null, null, handler);
70+
}
71+
72+
public void submitLog(String message, String source, Consumer<EventPluginContext> handler) {
73+
submitLog(message, source, null, handler);
74+
}
75+
76+
public void submitLog(
77+
String message, String source, String level, Consumer<EventPluginContext> handler) {
78+
Event event = createLog(message, source, level).build();
79+
submitEvent(EventPluginContext.from(event), handler);
80+
}
81+
82+
private Event.EventBuilderImpl createLog(String message, String source, String level) {
83+
if (source == null) {
84+
// Calling method
85+
source = Thread.currentThread().getStackTrace()[2].getMethodName();
86+
}
87+
88+
Event.EventBuilderImpl builder =
89+
createEvent().type(EventType.LOG.value()).source(source).message(message);
90+
if (level == null) {
91+
return builder;
92+
}
93+
94+
return builder.property(EventPropertyKey.LOG_LEVEL.value(), level);
95+
}
96+
97+
public void submitNotFound(String resource, Consumer<EventPluginContext> handler) {
98+
Event event = createNotFound(resource).build();
99+
submitEvent(EventPluginContext.from(event), handler);
100+
}
101+
102+
private Event.EventBuilderImpl createNotFound(String resource) {
103+
return createEvent().type(EventType.NOT_FOUND.value()).source(resource);
104+
}
105+
106+
public void submitSessionStart(Consumer<EventPluginContext> handler) {
107+
Event event = createSessionStart().build();
108+
submitEvent(EventPluginContext.from(event), handler);
109+
}
110+
111+
private Event.EventBuilderImpl createSessionStart() {
112+
return createEvent().type(EventType.SESSION.value());
113+
}
114+
115+
private Event.EventBuilderImpl createEvent() {
116+
return Event.builder(configurationManager.getDataExclusions()).date(LocalDate.now());
117+
}
118+
119+
private void submitEvent(
120+
EventPluginContext eventPluginContext, Consumer<EventPluginContext> handler) {
121+
$eventPluginManager.run(
122+
eventPluginContext,
123+
evc -> {
124+
if (evc.getContext().isEventCancelled()) {
125+
return;
126+
}
127+
configurationManager.getQueue().enqueue(evc.getEvent());
128+
if (evc.getEvent().getReferenceId() != null) {
129+
configurationManager
130+
.getLastReferenceIdManager()
131+
.setLast(evc.getEvent().getReferenceId());
132+
}
133+
handler.accept(evc);
134+
});
135+
}
136+
137+
public void submitSessionEnd(String sessionOrUserId) {
138+
configurationManager
139+
.getLog()
140+
.info(String.format("Submitting session end: %s", sessionOrUserId));
141+
configurationManager.getSubmissionClient().sendHeartBeat(sessionOrUserId, true);
142+
}
143+
144+
public void submitSessionHeartbeat(String sessionOrUserId) {
145+
configurationManager.submitSessionHeartbeat(sessionOrUserId);
146+
}
147+
148+
public void updateEmailAndDescription(
149+
String referenceId, String email, String description, Consumer<SubmissionResponse> handler) {
150+
SubmissionResponse response =
151+
configurationManager
152+
.getSubmissionClient()
153+
.postUserDescription(
154+
referenceId,
155+
UserDescription.builder().description(description).emailAddress(email).build());
156+
if (!response.isSuccess()) {
157+
configurationManager
158+
.getLog()
159+
.error(
160+
String.format(
161+
"Failed to submit user email and description for event: %s", referenceId));
162+
}
163+
handler.accept(response);
164+
}
165+
166+
public String getLastReferenceId() {
167+
return configurationManager.getLastReferenceIdManager().getLast();
168+
}
169+
170+
public static ExceptionlessClientBuilder builder() {
171+
return new ExceptionlessClientBuilder();
172+
}
173+
174+
public static class ExceptionlessClientBuilder extends ExceptionlessClientInternalBuilder {
175+
@Override
176+
public ExceptionlessClient build() {
177+
ExceptionlessClient client = super.build();
178+
client.init();
179+
180+
return client;
181+
}
182+
}
183+
184+
private void init() {
185+
$updateSettingsTimer.schedule(
186+
new TimerTask() {
187+
@Override
188+
public void run() {
189+
configurationManager.getSettingsManager().updateSettingsThreadSafe();
190+
}
191+
},
192+
UPDATE_SETTINGS_TIMER_INITIAL_DELAY,
193+
configurationManager.getConfiguration().getUpdateSettingsWhenIdleInterval());
194+
$eventPluginManager =
195+
EventPluginManager.builder().configurationManager(configurationManager).build();
196+
}
197+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.prashantchaubey.exceptionlessclient.configuration;
2+
3+
import lombok.Builder;
4+
import lombok.Getter;
5+
6+
@Builder
7+
@Getter
8+
public class Configuration {
9+
public static final String USER_AGENT = "exceptionless-java/1.0";
10+
11+
private String apiKey;
12+
@Builder.Default private String serverUrl = "https://collector.exceptionless.io";
13+
@Builder.Default private String configServerUrl = "https://config.exceptionless.io";
14+
@Builder.Default private String heartbeatServerUrl = "https://heartbeat.exceptionless.io";
15+
@Builder.Default private long updateSettingsWhenIdleInterval = 120000;
16+
@Builder.Default private boolean includePrivateInformation = true;
17+
@Builder.Default private int submissionBatchSize = 50;
18+
@Builder.Default private int submissionClientTimeoutInMillis = 100;
19+
@Builder.Default private int settingsClientTimeoutInMillis = 100;
20+
21+
public boolean isApiKeyValid() {
22+
return apiKey != null && apiKey.length() > 10;
23+
}
24+
25+
public static Configuration defaultConfiguration() {
26+
return Configuration.builder().build();
27+
}
28+
}

0 commit comments

Comments
 (0)