diff --git a/apiv3.properties b/apiv3.properties index 6a17242..6f20b7d 100644 --- a/apiv3.properties +++ b/apiv3.properties @@ -1,4 +1,3 @@ -general.id=main general.releaseStage=production logging.level=info mongo.address=ds055505.mongolab.com @@ -14,8 +13,6 @@ http.workerThreads=6 twillio.accountSID=AC9e2f88c5690134d29a56f698de3cd740 twillio.authToken=982592505a171d3be6b0722f5ecacc0e mandrill.apiKey=0OYtwymqJP6oqvszeJu0vQ -librato.email=cmcdonald.main@gmail.com -librato.apiKey=a818c3eca8a59d6d9cf76dc9f0d237c6aa97f257c482ce3363cf55a5431bc153 bugsnag.apiKey=0e47fba8b825416b7cbc839066184509 auth.permittedUserRanks=developer,owner auth.websiteApiKey=RVbp4hY6sCFVaf diff --git a/pom.xml b/pom.xml index 58fa9ee..a8c6cc6 100644 --- a/pom.xml +++ b/pom.xml @@ -79,9 +79,9 @@ 2.6.2 - com.librato.metrics - librato-java - 1.0.13 + com.indeed + java-dogstatsd-client + 2.0.12 com.bugsnag diff --git a/src/main/java/net/frozenorb/apiv3/APIv3.java b/src/main/java/net/frozenorb/apiv3/APIv3.java index b33cb81..1e1fddb 100644 --- a/src/main/java/net/frozenorb/apiv3/APIv3.java +++ b/src/main/java/net/frozenorb/apiv3/APIv3.java @@ -3,9 +3,10 @@ package net.frozenorb.apiv3; import com.bugsnag.Client; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import com.librato.metrics.*; import com.mongodb.MongoClient; import com.mongodb.ServerAddress; +import com.timgroup.statsd.NonBlockingStatsDClient; +import com.timgroup.statsd.StatsDClient; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import net.frozenorb.apiv3.filters.*; @@ -58,8 +59,7 @@ public final class APIv3 { @Getter private static Datastore datastore; @Getter private static Properties config = new Properties(); @Getter private static JedisPool redisPool; - @Getter private static HttpPoster libratoPoster; - @Getter private static Client bugsnagClient; + @Getter private static StatsDClient statsD; @Getter private static final Gson gson = new GsonBuilder() .registerTypeAdapter(ObjectId.class, new ObjectIdTypeAdapter()) .setExclusionStrategies(new FollowAnnotationExclusionStrategy()) @@ -71,11 +71,9 @@ public final class APIv3 { setupDatabase(); setupRedis(); - setupLibrato(); + setupMetrics(); setupBugsnag(); setupHttp(); - - log.info("APIv3 booted."); } private void setupConfig() { @@ -116,42 +114,24 @@ public final class APIv3 { ); } - private void setupLibrato() { - try { - libratoPoster = new DefaultHttpPoster( - "https://metrics-api.librato.com/v1/metrics", - config.getProperty("librato.email"), - config.getProperty("librato.apiKey") - ); - } catch (Exception e) { - e.printStackTrace(); - } + private void setupMetrics() { + statsD = new NonBlockingStatsDClient(null, "localhost", 8125); new Timer("Librato Post Task").scheduleAtFixedRate(new TimerTask() { @Override public void run() { - LibratoBatch batch = new LibratoBatch(300, Sanitizer.NO_OP, 10, TimeUnit.SECONDS, "qLib", libratoPoster); - - batch.addGaugeMeasurement("apiv3.memory.usage", Runtime.getRuntime().totalMemory() / (1024 * 1024)); - batch.addGaugeMeasurement("apiv3.memory.max", Runtime.getRuntime().maxMemory() / (1024 * 1024)); - - BatchResult result = batch.post(config.getProperty("general.id"), System.currentTimeMillis() / 1000L); - - if (!result.success()) { - for (PostResult post : result.getFailedPosts()) { - log.warn("Could not POST to Librato: " + post); - } - } + statsD.recordGaugeValue("apiv3.memory.usage", Runtime.getRuntime().totalMemory() / (1024 * 1024)); + statsD.recordGaugeValue("apiv3.memory.max", Runtime.getRuntime().maxMemory() / (1024 * 1024)); } - }, TimeUnit.SECONDS.toMillis(30), TimeUnit.MINUTES.toMillis(1)); + }, TimeUnit.SECONDS.toMillis(5), TimeUnit.SECONDS.toMillis(5)); } private void setupBugsnag() { - bugsnagClient = new Client(config.getProperty("bugsnag.apiKey")); - bugsnagClient.setReleaseStage(config.getProperty("general.releaseStage")); - bugsnagClient.setProjectPackages("net.frozenorb.apiv3"); + Client bugsnag = new Client(config.getProperty("bugsnag.apiKey")); + bugsnag.setReleaseStage(config.getProperty("general.releaseStage")); + bugsnag.setProjectPackages("net.frozenorb.apiv3"); // TODO: Use .setLogger to use slf4j with this } diff --git a/src/main/java/net/frozenorb/apiv3/filters/ActorAttributeFilter.java b/src/main/java/net/frozenorb/apiv3/filters/ActorAttributeFilter.java index 5609e0c..970bb4e 100644 --- a/src/main/java/net/frozenorb/apiv3/filters/ActorAttributeFilter.java +++ b/src/main/java/net/frozenorb/apiv3/filters/ActorAttributeFilter.java @@ -42,7 +42,7 @@ public final class ActorAttributeFilter implements Filter { } res.header("WWW-Authenticate", "Basic realm=\"MineHQ\""); - Spark.halt(401, APIv3.getGson().toJson(ErrorUtils.error("Failed to authorize."))); + Spark.halt(401, APIv3.getGson().toJson(ErrorUtils.error("Failed to authorize as " + credentials[0] + "."))); return null; } diff --git a/src/main/java/net/frozenorb/apiv3/filters/AuthorizationFilter.java b/src/main/java/net/frozenorb/apiv3/filters/AuthorizationFilter.java index 44f006f..611356f 100644 --- a/src/main/java/net/frozenorb/apiv3/filters/AuthorizationFilter.java +++ b/src/main/java/net/frozenorb/apiv3/filters/AuthorizationFilter.java @@ -14,6 +14,7 @@ public final class AuthorizationFilter implements Filter { Actor actor = req.attribute("actor"); if (!actor.isAuthorized()) { + APIv3.getStatsD().incrementCounter("apiv3.http.unauthorized"); res.header("WWW-Authenticate", "Basic realm=\"MineHQ\""); Spark.halt(401, APIv3.getGson().toJson(ErrorUtils.error("Unauthorized access: Please authenticate as either a server, the website, or an authorized user. You're currently authorized as " + actor.getName()))); } diff --git a/src/main/java/net/frozenorb/apiv3/filters/MetricsAfterFilter.java b/src/main/java/net/frozenorb/apiv3/filters/MetricsAfterFilter.java index 7020f4e..8bf5d4a 100644 --- a/src/main/java/net/frozenorb/apiv3/filters/MetricsAfterFilter.java +++ b/src/main/java/net/frozenorb/apiv3/filters/MetricsAfterFilter.java @@ -1,19 +1,16 @@ package net.frozenorb.apiv3.filters; +import net.frozenorb.apiv3.APIv3; import spark.Filter; import spark.Request; import spark.Response; public final class MetricsAfterFilter implements Filter { - /*private Histogram responseLengthMetric = APIv3.getMetrics().histogram(MetricRegistry.name("apiv3", "http", "responseLength")); - private Timer responseTimesMetric = APIv3.getMetrics().timer(MetricRegistry.name("apiv3", "http", "responseTimes"));*/ - public void handle(Request req, Response res) { - /*responseLengthMetric.update(req.contentLength()); - long started = req.attribute("requestStarted"); - responseTimesMetric.update(System.currentTimeMillis() - started, TimeUnit.MILLISECONDS);*/ + APIv3.getStatsD().recordExecutionTime("apiv3.http.executionTime", System.currentTimeMillis() - started); + APIv3.getStatsD().incrementCounter("apiv3.http.requests"); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/unsorted/LoggingExceptionHandler.java b/src/main/java/net/frozenorb/apiv3/unsorted/LoggingExceptionHandler.java index 7405a19..193fab4 100644 --- a/src/main/java/net/frozenorb/apiv3/unsorted/LoggingExceptionHandler.java +++ b/src/main/java/net/frozenorb/apiv3/unsorted/LoggingExceptionHandler.java @@ -12,8 +12,11 @@ import spark.Response; public final class LoggingExceptionHandler implements ExceptionHandler { public void handle(Exception ex, Request req, Response res) { - //Timer.Context timerMetric = req.attribute("timerMetric"); - //timerMetric.stop(); + long started = req.attribute("requestStarted"); + APIv3.getStatsD().recordExecutionTime("apiv3.http.executionTime", System.currentTimeMillis() - started); + APIv3.getStatsD().incrementCounter("apiv3.http.requests"); + + APIv3.getStatsD().incrementCounter("apiv3.http.errors"); String code = new ObjectId().toHexString();