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

Routes and TDigest #72

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ bin
**target
**.DS_Store
**.vscode
Main.java
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ repositories {
dependencies {
implementation 'com.squareup.okhttp3:okhttp:4.9.2'
implementation 'com.google.code.gson:gson:2.8.6'
// https://mvnrepository.com/artifact/com.tdunning/t-digest
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please indent this one at the same level as the other lines.

implementation group: 'com.tdunning', name: 't-digest', version: '3.3'
api 'com.google.code.findbugs:jsr305:3.0.2'
testImplementation 'com.github.tomakehurst:wiremock:2.27.2'
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/io/airbrake/javabrake/AsyncSender.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

import java.util.concurrent.CompletableFuture;

import okhttp3.Response;

public interface AsyncSender {
void setHost(String host);
void setErrorHost(String host);
void setAPMHost(String host);

CompletableFuture<Notice> send(Notice notice);
CompletableFuture<Response> sendRouteStats(Routes object);
}
3 changes: 3 additions & 0 deletions src/main/java/io/airbrake/javabrake/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ public class Config {
public int projectId;
public String projectKey;
public String errorHost = DEFAULT_ERROR_HOST;
public String apmHost = DEFAULT_ERROR_HOST;
public Boolean errorNotifications = true;
public Boolean apmNotifications = false;
public Boolean remoteConfig = true;
public String environment = "";
}
128 changes: 128 additions & 0 deletions src/main/java/io/airbrake/javabrake/Metrics.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package io.airbrake.javabrake;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class Metrics {
public static int FLUSH_PERIOD = 15;

Date startTime = new Date();
Date endTime;
Map<String, Span> spans = new HashMap<>();
Span currSpan;
Map<String, Long> groups = new HashMap<>();

public void end() {
if (endTime == null)
endTime = new Date();
}

protected Span newSpan(String name, Date startTime) {
return new Span(this, name, startTime);
}

public void startSpan(String name, Date startTime) {
if (this.currSpan != null) {
if (this.currSpan.name == name) {
this.currSpan.level += 1;
return;
}
this.currSpan.pause();
}

Span span = this.spans.get(name);
if (span == null) {
span = this.newSpan(name, startTime);
this.spans.put(name, span);
} else
span.resume();

span.parent = this.currSpan;
this.currSpan = span;
}

public void endSpan(String name, Date endTime) {
if (this.currSpan != null && this.currSpan.name == name) {
if (this._endSpan(this.currSpan, endTime)) {
this.currSpan = this.currSpan.parent;
if (this.currSpan != null)
this.currSpan.resume();
return;
}
}

Span span = this.spans.get(name);
if (span == null)
return;
this._endSpan(span, endTime);
}

protected boolean _endSpan(Span span, Date endTime) {

if (span.level > 0) {
span.level -= 1;
return false;
}

span.end(endTime);
this.spans.get(span.name);
return true;

}

protected void _inc_group(String name, long ms) {
this.groups.put(name, (this.groups.getOrDefault(name, (long) 0) + ms));
}
}

class Span {

Metrics metric;
Span parent;
Date startTime;
Date endTime;
String name;
long dur = 0;
int level = 0;

public Span(Metrics metric, String name, Date startTime) {
this.metric = metric;
this.startTime = startTime;
this.name = name;
}

public void init() {
this.startTime = new Date();
this.endTime = null;
}

public void end(Date endTime) {
if (endTime != null)
this.endTime = endTime;
else {
this.endTime = new Date();
}

this.dur += (this.endTime.getTime() - this.metric.spans.get(this.name).startTime.getTime());
this.metric._inc_group(this.name, this.dur);
this.metric = null;
}

protected void pause() {
if (this.paused())
return;
this.dur += (new Date().getTime() - this.startTime.getTime());
this.startTime = null;
}

protected boolean paused() {
return this.startTime == null;
}

protected void resume() {
if (!this.paused())
return;
this.startTime = new Date();
}
}
31 changes: 23 additions & 8 deletions src/main/java/io/airbrake/javabrake/Notifier.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
package io.airbrake.javabrake;

import java.util.concurrent.Future;
// import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
// import java.util.HashMap;
// import javax.annotation.Nullable;
import java.util.concurrent.CompletableFuture;

/** Airbrake notifier. */
//** Airbrake notifier. */
public class Notifier {
AsyncSender asyncSender;
SyncSender syncSender;

protected static List<Object> routes = new ArrayList<>();

final List<NoticeHook> hooks = new ArrayList<>();
final List<NoticeFilter> filters = new ArrayList<>();

Expand All @@ -28,7 +27,11 @@ public Notifier(Config config) {
this.syncSender = new OkSyncSender(config);

if (config.errorHost != null) {
this.setHost(config.errorHost);
this.setErrorHost(config.errorHost);
}

if (config.apmHost != null) {
this.setAPMHost(config.apmHost);
}

if (Airbrake.notifier == null) {
Expand All @@ -46,9 +49,21 @@ public Notifier(Config config) {
}
}

public Notifier setHost(String host) {
this.asyncSender.setHost(host);
this.syncSender.setHost(host);
// public Config getConfig() {
// return config;
// }

public Notifier setErrorHost(String host) {
this.config.errorHost = host;
this.asyncSender.setErrorHost(host);
this.syncSender.setErrorHost(host);
return this;
}

public Notifier setAPMHost(String host) {
this.config.apmHost = host;
this.asyncSender.setAPMHost(host);
this.syncSender.setAPMHost(host);
return this;
}

Expand Down
57 changes: 56 additions & 1 deletion src/main/java/io/airbrake/javabrake/OkAsyncSender.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package io.airbrake.javabrake;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
Expand All @@ -10,6 +16,9 @@ public class OkAsyncSender extends OkSender implements AsyncSender {
static final int queuedCallsLimit = 1000;
static final IOException queuedCallsLimitException =
new IOException("too many HTTP requests queued for execution");

List<Object> routeList = new ArrayList<>();
Gson gson = new GsonBuilder().disableHtmlEscaping().create();

public OkAsyncSender(Config config) {
super(config);
Expand Down Expand Up @@ -44,7 +53,7 @@ public CompletableFuture<Notice> send(Notice notice) {

OkAsyncSender sender = this;
okhttp
.newCall(this.buildRequest(notice))
.newCall(this.buildErrorRequest(notice))
.enqueue(
new Callback() {
@Override
Expand All @@ -66,4 +75,50 @@ public void onResponse(Call call, Response resp) {
});
return future;
}

@Override
public CompletableFuture<Response> sendRouteStats(Routes object) {
CompletableFuture<Response> future = new CompletableFuture<>();

if (!config.apmNotifications) {
future.completeExceptionally(new IOException("apmNotifications is disabled"));
return future;
}

if (object == null) {
future.completeExceptionally(new IOException("Route is null"));
return future;
}

if (object.routes == null || object.routes.size() == 0 ) {
future.completeExceptionally(new IOException("Route is null"));
return future;
}

//OkAsyncSender sender = this;
okhttp
.newCall(this.buildAPMRequest(gson.toJson(object,Routes.class),"routes-stats"))
.enqueue(
new Callback() {
@Override
public void onFailure(Call call, IOException e) {

future.completeExceptionally(e);
}

@Override
public void onResponse(Call call, Response resp) {
// try {
// NoticeCode data = sender.parseJson(resp, NoticeCode.class);
// System.out.println(data.message);
// // Notifier.routes.clear();
// } catch (Exception e) {

// }
future.complete(resp);

}
});
return future;
}
}
Loading