Skip to content

Commit 0236229

Browse files
committed
Merge branch 'main' into duplicate-checker-fix
2 parents 54f34f9 + bc7ad6a commit 0236229

File tree

75 files changed

+796
-898
lines changed

Some content is hidden

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

75 files changed

+796
-898
lines changed

Diff for: .github/workflows/greetings.yml

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
name: Greetings
2+
3+
on: [pull_request, issues]
4+
5+
jobs:
6+
greeting:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/first-interaction@v1
10+
with:
11+
repo-token: ${{ secrets.GITHUB_TOKEN }}
12+
issue-message: 'Thanks for reporting this issue. We will get back to you in a while'
13+
pr-message: 'Great Job for your first PR in this repository'

Diff for: .github/workflows/stale.yml

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: Mark stale issues and pull requests
2+
3+
on:
4+
schedule:
5+
- cron: "30 1 * * *"
6+
7+
jobs:
8+
stale:
9+
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- uses: actions/stale@v3
14+
with:
15+
repo-token: ${{ secrets.GITHUB_TOKEN }}
16+
stale-issue-message: 'This issue is stale'
17+
stale-pr-message: 'This PR is stale'
18+
stale-issue-label: 'stale'
19+
stale-pr-label: 'stale'

Diff for: Readme.md renamed to README.md

+25
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,31 @@ class ExampleApp{
3232
}
3333
```
3434

35+
**Builder Pattern**
36+
37+
We love our builders!!! This project heavily utilized the use of builders instead of traditional object creation
38+
using `new`. We do this with the help of Project Lombok's `@Builder` annotation. Read more about the
39+
project [here](https://projectlombok.org/features/all). Read more about the
40+
annotation [here](https://projectlombok.org/features/Builder). Read more about the builder
41+
pattern [here](https://refactoring.guru/design-patterns/builder).
42+
43+
_Example: Customizing your Event Queue implementation_
44+
45+
```
46+
EventQueueIF queue = //get your implementation
47+
Configuration configuration =
48+
Configuration.builder().serverUrl("http://your-server-url").apiKey("your-api-key").build();
49+
ConfigurationManager configurationManager =
50+
ConfigurationManager.builder().queue(queue).configuration(configuration).build();
51+
ExceptionlessClient client =
52+
ExceptionlessClient.builder().configurationManager(configurationManager).build();
53+
```
54+
55+
In this library we have made sure that all the values which are not set by builders fallback to reasonable defaults. So
56+
don't feel the pressure to supply values for all the fields. **Note:** Whenever customizing the client
57+
using `ConfigurationManager` never forget to supply your `serverUrl` and `apiKey` using a `Configuration` object as
58+
shown above.
59+
3560
## Spring Boot Users
3661

3762
You can observe `NoClassDefFoundError` in your Spring-boot apps because Spring-boot uses v3 of `OkHttpClient` while this client uses v4. In that case you have to explicitly declare v4 of the library in you `pom.xml/build.gradle`.

Diff for: samples/example-app/src/main/java/com/exceptionless/example/app/ExampleApp.java

+2-5
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,12 @@ public static void sampleEventSubmissions() {
2020

2121
public static void sampleUseOfSessions() {
2222
client.getConfigurationManager().useSessions();
23-
client.submitEvent(
24-
EventPluginContext.from(client.createSessionStart().userIdentity("test-user").build()));
23+
client.submitEvent(client.createSessionStart().userIdentity("test-user").build());
2524
client.submitSessionEnd("test-user");
2625
}
2726

2827
public static void sampleUseOfUpdatingEmailAndDescription() {
29-
client.submitEvent(
30-
EventPluginContext.from(
31-
client.createLog("test-log").referenceId("test-reference-id").build()));
28+
client.submitEvent(client.createLog("test-log").referenceId("test-reference-id").build());
3229
client.updateEmailAndDescription("test-reference-id", "[email protected]", "test-description");
3330
}
3431

Diff for: src/main/java/com/exceptionless/exceptionlessclient/ExceptionlessClient.java

+62-33
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,18 @@
22

33
import com.exceptionless.exceptionlessclient.configuration.Configuration;
44
import com.exceptionless.exceptionlessclient.configuration.ConfigurationManager;
5+
import com.exceptionless.exceptionlessclient.enums.EventPropertyKey;
6+
import com.exceptionless.exceptionlessclient.enums.EventType;
57
import com.exceptionless.exceptionlessclient.models.Event;
68
import com.exceptionless.exceptionlessclient.models.EventPluginContext;
79
import com.exceptionless.exceptionlessclient.models.PluginContext;
810
import com.exceptionless.exceptionlessclient.models.UserDescription;
9-
import com.exceptionless.exceptionlessclient.models.enums.EventPropertyKey;
10-
import com.exceptionless.exceptionlessclient.models.enums.EventType;
11-
import com.exceptionless.exceptionlessclient.models.submission.SubmissionResponse;
1211
import com.exceptionless.exceptionlessclient.plugins.EventPluginRunner;
12+
import com.exceptionless.exceptionlessclient.submission.SubmissionResponse;
1313
import com.exceptionless.exceptionlessclient.utils.VisibleForTesting;
1414
import lombok.Builder;
1515
import lombok.Getter;
16-
import org.slf4j.Logger;
17-
import org.slf4j.LoggerFactory;
16+
import lombok.extern.slf4j.Slf4j;
1817

1918
import java.time.LocalDate;
2019
import java.util.Timer;
@@ -23,8 +22,8 @@
2322
import java.util.concurrent.ExecutorService;
2423
import java.util.concurrent.Executors;
2524

25+
@Slf4j
2626
public class ExceptionlessClient {
27-
private static final Logger LOG = LoggerFactory.getLogger(ExceptionlessClient.class);
2827
private static final String UPDATE_SETTINGS_TIMER_NAME = "update-settings-timer";
2928
private static final int UPDATE_SETTINGS_TIMER_INITIAL_DELAY = 5000;
3029
private static final Integer DEFAULT_NTHREADS = 10;
@@ -63,7 +62,7 @@ public void run() {
6362
try {
6463
configurationManager.getSettingsManager().updateSettings();
6564
} catch (Exception e) {
66-
LOG.error("Error in updating settings", e);
65+
log.error("Error in updating settings", e);
6766
}
6867
}
6968
},
@@ -92,12 +91,26 @@ public CompletableFuture<Void> submitExceptionAsync(Exception exception) {
9291
}
9392

9493
public void submitException(Exception exception) {
95-
Event event = createException().build();
94+
submitException(null, exception);
95+
}
96+
97+
public CompletableFuture<Void> submitExceptionAsync(String message, Exception exception) {
98+
return CompletableFuture.runAsync(() -> submitException(message, exception), executorService);
99+
}
100+
101+
public void submitException(String message, Exception exception) {
102+
Event event;
103+
if (message == null) {
104+
event = createError().build();
105+
} else {
106+
event = createError().message(message).build();
107+
}
96108
PluginContext pluginContext = PluginContext.builder().exception(exception).build();
97-
submitEvent(EventPluginContext.builder().event(event).context(pluginContext).build());
109+
submitEventWithContext(
110+
EventPluginContext.builder().event(event).context(pluginContext).build());
98111
}
99112

100-
public Event.EventBuilder createException() {
113+
public Event.EventBuilder createError() {
101114
return createEvent().type(EventType.ERROR.value());
102115
}
103116

@@ -108,23 +121,23 @@ public CompletableFuture<Void> submitUnhandledExceptionAsync(
108121
}
109122

110123
public void submitUnhandledException(Exception exception, String submissionMethod) {
111-
Event event = createException().build();
124+
Event event = createError().build();
112125
PluginContext pluginContext =
113126
PluginContext.builder()
114127
.exception(exception)
115128
.unhandledError(true)
116129
.submissionMethod(submissionMethod)
117130
.build();
118-
submitEvent(EventPluginContext.builder().event(event).context(pluginContext).build());
131+
submitEventWithContext(
132+
EventPluginContext.builder().event(event).context(pluginContext).build());
119133
}
120134

121135
public CompletableFuture<Void> submitFeatureUsageAsync(String feature) {
122136
return CompletableFuture.runAsync(() -> submitFeatureUsage(feature), executorService);
123137
}
124138

125139
public void submitFeatureUsage(String feature) {
126-
Event event = createFeatureUsage(feature).build();
127-
submitEvent(EventPluginContext.from(event));
140+
submitEvent(createFeatureUsage(feature).build());
128141
}
129142

130143
public Event.EventBuilder createFeatureUsage(String feature) {
@@ -152,8 +165,7 @@ public CompletableFuture<Void> submitLogAsync(String message, String source, Str
152165
}
153166

154167
public void submitLog(String message, String source, String level) {
155-
Event event = createLog(message, source, level).build();
156-
submitEvent(EventPluginContext.from(event));
168+
submitEvent(createLog(message, source, level).build());
157169
}
158170

159171
public Event.EventBuilder createLog(String message) {
@@ -166,13 +178,7 @@ public Event.EventBuilder createLog(String message, String source) {
166178

167179
public Event.EventBuilder createLog(String message, String source, String level) {
168180
if (source == null) {
169-
// Calling method
170-
StackTraceElement[] traceElements = Thread.currentThread().getStackTrace();
171-
source = traceElements[2].getMethodName();
172-
// Came from the overrided method
173-
if (source.equals("createLog")) {
174-
source = traceElements[3].getMethodName();
175-
}
181+
source = getCallingMethod();
176182
}
177183

178184
Event.EventBuilder builder =
@@ -184,13 +190,20 @@ public Event.EventBuilder createLog(String message, String source, String level)
184190
return builder.property(EventPropertyKey.LOG_LEVEL.value(), level);
185191
}
186192

193+
private String getCallingMethod() {
194+
StackTraceElement[] traceElements = Thread.currentThread().getStackTrace();
195+
String source = traceElements[3].getMethodName();
196+
boolean cameFromOverridenMethod = source.equals("createLog");
197+
198+
return cameFromOverridenMethod ? traceElements[4].getMethodName() : source;
199+
}
200+
187201
public CompletableFuture<Void> submitNotFoundAsync(String resource) {
188202
return CompletableFuture.runAsync(() -> submitNotFound(resource), executorService);
189203
}
190204

191205
public void submitNotFound(String resource) {
192-
Event event = createNotFound(resource).build();
193-
submitEvent(EventPluginContext.from(event));
206+
submitEvent(createNotFound(resource).build());
194207
}
195208

196209
public Event.EventBuilder createNotFound(String resource) {
@@ -202,8 +215,7 @@ public CompletableFuture<Void> submitSessionStartAsync() {
202215
}
203216

204217
public void submitSessionStart() {
205-
Event event = createSessionStart().build();
206-
submitEvent(EventPluginContext.from(event));
218+
submitEvent(createSessionStart().build());
207219
}
208220

209221
public Event.EventBuilder createSessionStart() {
@@ -216,11 +228,21 @@ public Event.EventBuilder createEvent() {
216228
.date(LocalDate.now());
217229
}
218230

219-
public CompletableFuture<Void> submitEventAsync(EventPluginContext eventPluginContext) {
220-
return CompletableFuture.runAsync(() -> submitEvent(eventPluginContext), executorService);
231+
public CompletableFuture<Void> submitEventAsync(Event event) {
232+
return CompletableFuture.runAsync(() -> submitEvent(event), executorService);
233+
}
234+
235+
public void submitEvent(Event event) {
236+
eventPluginRunner.run(EventPluginContext.from(event));
221237
}
222238

223-
public void submitEvent(EventPluginContext eventPluginContext) {
239+
public CompletableFuture<Void> submitEventWithContextAsync(
240+
EventPluginContext eventPluginContext) {
241+
return CompletableFuture.runAsync(
242+
() -> submitEventWithContext(eventPluginContext), executorService);
243+
}
244+
245+
public void submitEventWithContext(EventPluginContext eventPluginContext) {
224246
eventPluginRunner.run(eventPluginContext);
225247
}
226248

@@ -229,7 +251,7 @@ public CompletableFuture<Void> submitSessionEndAsync(String sessionOrUserId) {
229251
}
230252

231253
public void submitSessionEnd(String sessionOrUserId) {
232-
LOG.info(String.format("Submitting session end: %s", sessionOrUserId));
254+
log.info(String.format("Submitting session end: %s", sessionOrUserId));
233255
configurationManager.getSubmissionClient().sendHeartBeat(sessionOrUserId, true);
234256
}
235257

@@ -247,9 +269,16 @@ public SubmissionResponse updateEmailAndDescription(
247269
.postUserDescription(
248270
referenceId,
249271
UserDescription.builder().description(description).emailAddress(email).build());
272+
if (response.hasException()) {
273+
log.error(
274+
String.format("Failed to submit user email and description for event: %s", referenceId),
275+
response.getException());
276+
}
250277
if (!response.isSuccess()) {
251-
LOG.error(
252-
String.format("Failed to submit user email and description for event: %s", referenceId));
278+
log.error(
279+
String.format(
280+
"Failed to submit user email and description for event: %s, code: %s",
281+
referenceId, response.getCode()));
253282
}
254283

255284
return response;

Diff for: src/main/java/com/exceptionless/exceptionlessclient/configuration/Configuration.java

+14
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
public class Configuration {
1010
private static final String DEFAULT_SERVER_URL = "https://collector.exceptionless.io";
1111
private static final String DEFAULT_HEARTBEAT_SERVER_URL = "https://heartbeat.exceptionless.io";
12+
private static final String DEFAULT_CONFIG_SERVER_URL = "https://config.exceptionless.io";
1213
private static final Long DEFAULT_UPDATE_SETTINGS_WHEN_IDLE_INTERVAL = 12000L;
1314
private static final Integer DEFAULT_SUBMISSION_BATCH_SIZE = 50;
1415
private static final Integer DEFAULT_SUBMISSION_CLIENT_TIMEOUT_IN_MILLIS = 500;
@@ -17,6 +18,7 @@ public class Configuration {
1718
public static class Property {
1819
public static final String API_KEY = "apiKey";
1920
public static final String SERVER_URL = "serverUrl";
21+
public static final String CONFIG_SERVER_URL = "configServerUrl";
2022
public static final String HEART_BEAT_SERVER_URL = "heartbeatServerUrl";
2123
public static final String UPDATE_SETTINGS_WHEN_IDLE_INTERVAL =
2224
"updateSettingsWhenIdleInterval";
@@ -29,6 +31,7 @@ public static class Property {
2931
@Getter private String apiKey;
3032
@Getter private String serverUrl;
3133
@Getter private String heartbeatServerUrl;
34+
@Getter private String configServerUrl;
3235
@Getter private Long updateSettingsWhenIdleInterval;
3336
@Getter private Integer submissionBatchSize;
3437
@Getter private Integer submissionClientTimeoutInMillis;
@@ -51,6 +54,10 @@ public Configuration(
5154
heartbeatServerUrl == null
5255
? (serverUrl == null ? DEFAULT_HEARTBEAT_SERVER_URL : serverUrl)
5356
: heartbeatServerUrl;
57+
this.configServerUrl =
58+
configServerUrl == null
59+
? (serverUrl == null ? DEFAULT_CONFIG_SERVER_URL : serverUrl)
60+
: configServerUrl;
5461
this.updateSettingsWhenIdleInterval =
5562
updateSettingsWhenIdleInterval == null
5663
? DEFAULT_UPDATE_SETTINGS_WHEN_IDLE_INTERVAL
@@ -88,6 +95,13 @@ public void setServerUrl(String serverUrl) {
8895
propertyChangeSupport.firePropertyChange(Property.SERVER_URL, prevValue, serverUrl);
8996
}
9097

98+
public void setConfigServerUrl(String configServerUrl) {
99+
String prevValue = this.configServerUrl;
100+
this.configServerUrl = configServerUrl;
101+
propertyChangeSupport.firePropertyChange(
102+
Property.CONFIG_SERVER_URL, prevValue, configServerUrl);
103+
}
104+
91105
public void setHeartbeatServerUrl(String heartbeatServerUrl) {
92106
String prevValue = this.heartbeatServerUrl;
93107
this.heartbeatServerUrl = heartbeatServerUrl;

0 commit comments

Comments
 (0)