-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
213 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||
From: Kevin Raneri <[email protected]> | ||
Date: Tue, 9 Nov 2021 14:08:14 -0500 | ||
Subject: [PATCH] Add Sentry | ||
|
||
|
||
diff --git a/src/main/java/in/bloodred/sakura/SakuraConfig.java b/src/main/java/in/bloodred/sakura/SakuraConfig.java | ||
index d1a8bfb29817d2b73689713b4d5f04d7f2c0eaf4..5b7fe3d6c2169d07b79a0937e889fc847962fdfe 100644 | ||
--- a/src/main/java/in/bloodred/sakura/SakuraConfig.java | ||
+++ b/src/main/java/in/bloodred/sakura/SakuraConfig.java | ||
@@ -152,4 +152,15 @@ public class SakuraConfig { | ||
return config.getStringList(key); | ||
} | ||
|
||
+ public static String sentryDsn; | ||
+ private static void sentry() { | ||
+ String sentryEnvironment = System.getenv("SENTRY_DSN"); | ||
+ String sentryConfig = getString("sentry-dsn", "", "Sentry DSN for improved error logging, leave blank to disable", "Obtain from https://sentry.io/"); | ||
+ | ||
+ sentryDsn = sentryEnvironment == null ? sentryConfig : sentryEnvironment; | ||
+ if (sentryDsn != null && !sentryDsn.isBlank()) { | ||
+ in.bloodred.sakura.sentry.SentryManager.init(); | ||
+ } | ||
+ } | ||
+ | ||
} | ||
diff --git a/src/main/java/in/bloodred/sakura/sentry/PufferfishSentryAppender.java b/src/main/java/in/bloodred/sakura/sentry/PufferfishSentryAppender.java | ||
new file mode 100644 | ||
index 0000000000000000000000000000000000000000..731ef11c7a025ae95ed8a757b530d834733d0621 | ||
--- /dev/null | ||
+++ b/src/main/java/in/bloodred/sakura/sentry/PufferfishSentryAppender.java | ||
@@ -0,0 +1,135 @@ | ||
+package in.bloodred.sakura.sentry; | ||
+ | ||
+import com.google.common.reflect.TypeToken; | ||
+import com.google.gson.Gson; | ||
+import io.sentry.Breadcrumb; | ||
+import io.sentry.Sentry; | ||
+import io.sentry.SentryEvent; | ||
+import io.sentry.SentryLevel; | ||
+import io.sentry.protocol.Message; | ||
+import io.sentry.protocol.User; | ||
+import java.util.Map; | ||
+import org.apache.logging.log4j.Level; | ||
+import org.apache.logging.log4j.LogManager; | ||
+import org.apache.logging.log4j.Marker; | ||
+import org.apache.logging.log4j.core.LogEvent; | ||
+import org.apache.logging.log4j.core.Logger; | ||
+import org.apache.logging.log4j.core.appender.AbstractAppender; | ||
+import org.apache.logging.log4j.core.filter.AbstractFilter; | ||
+ | ||
+public class PufferfishSentryAppender extends AbstractAppender { | ||
+ | ||
+ private static final org.apache.logging.log4j.Logger logger = LogManager.getLogger(PufferfishSentryAppender.class); | ||
+ private static final Gson GSON = new Gson(); | ||
+ | ||
+ public PufferfishSentryAppender() { | ||
+ super("PufferfishSentryAdapter", new SentryFilter(), null); | ||
+ } | ||
+ | ||
+ @Override | ||
+ public void append(LogEvent logEvent) { | ||
+ if (logEvent.getThrown() != null && logEvent.getLevel().isMoreSpecificThan(Level.WARN)) { | ||
+ try { | ||
+ logException(logEvent); | ||
+ } catch (Exception e) { | ||
+ logger.warn("Failed to log event with sentry", e); | ||
+ } | ||
+ } else { | ||
+ try { | ||
+ logBreadcrumb(logEvent); | ||
+ } catch (Exception e) { | ||
+ logger.warn("Failed to log event with sentry", e); | ||
+ } | ||
+ } | ||
+ } | ||
+ | ||
+ private void logException(LogEvent e) { | ||
+ SentryEvent event = new SentryEvent(e.getThrown()); | ||
+ | ||
+ Message sentryMessage = new Message(); | ||
+ sentryMessage.setMessage(e.getMessage().getFormattedMessage()); | ||
+ | ||
+ event.setThrowable(e.getThrown()); | ||
+ event.setLevel(getLevel(e.getLevel())); | ||
+ event.setLogger(e.getLoggerName()); | ||
+ event.setTransaction(e.getLoggerName()); | ||
+ event.setExtra("thread_name", e.getThreadName()); | ||
+ | ||
+ boolean hasContext = e.getContextData() != null; | ||
+ | ||
+ if (hasContext && e.getContextData().containsKey("pufferfishsentry_playerid")) { | ||
+ User user = new User(); | ||
+ user.setId(e.getContextData().getValue("pufferfishsentry_playerid")); | ||
+ user.setUsername(e.getContextData().getValue("pufferfishsentry_playername")); | ||
+ event.setUser(user); | ||
+ } | ||
+ | ||
+ if (hasContext && e.getContextData().containsKey("pufferfishsentry_pluginname")) { | ||
+ event.setExtra("plugin.name", e.getContextData().getValue("pufferfishsentry_pluginname")); | ||
+ event.setExtra("plugin.version", e.getContextData().getValue("pufferfishsentry_pluginversion")); | ||
+ event.setTransaction(e.getContextData().getValue("pufferfishsentry_pluginname")); | ||
+ } | ||
+ | ||
+ if (hasContext && e.getContextData().containsKey("pufferfishsentry_eventdata")) { | ||
+ Map<String, String> eventFields = GSON.fromJson((String) e.getContextData().getValue("pufferfishsentry_eventdata"), new TypeToken<Map<String, String>>() {}.getType()); | ||
+ if (eventFields != null) { | ||
+ event.setExtra("event", eventFields); | ||
+ } | ||
+ } | ||
+ | ||
+ Sentry.captureEvent(event); | ||
+ } | ||
+ | ||
+ private void logBreadcrumb(LogEvent e) { | ||
+ Breadcrumb breadcrumb = new Breadcrumb(); | ||
+ | ||
+ breadcrumb.setLevel(getLevel(e.getLevel())); | ||
+ breadcrumb.setCategory(e.getLoggerName()); | ||
+ breadcrumb.setType(e.getLoggerName()); | ||
+ breadcrumb.setMessage(e.getMessage().getFormattedMessage()); | ||
+ | ||
+ Sentry.addBreadcrumb(breadcrumb); | ||
+ } | ||
+ | ||
+ private SentryLevel getLevel(Level level) { | ||
+ switch (level.getStandardLevel()) { | ||
+ case TRACE: | ||
+ case DEBUG: | ||
+ return SentryLevel.DEBUG; | ||
+ case WARN: | ||
+ return SentryLevel.WARNING; | ||
+ case ERROR: | ||
+ return SentryLevel.ERROR; | ||
+ case FATAL: | ||
+ return SentryLevel.FATAL; | ||
+ case INFO: | ||
+ default: | ||
+ return SentryLevel.INFO; | ||
+ } | ||
+ } | ||
+ | ||
+ private static class SentryFilter extends AbstractFilter { | ||
+ | ||
+ @Override | ||
+ public Result filter(Logger logger, org.apache.logging.log4j.Level level, Marker marker, String msg, | ||
+ Object... params) { | ||
+ return this.filter(logger.getName()); | ||
+ } | ||
+ | ||
+ @Override | ||
+ public Result filter(Logger logger, org.apache.logging.log4j.Level level, Marker marker, Object msg, Throwable t) { | ||
+ return this.filter(logger.getName()); | ||
+ } | ||
+ | ||
+ @Override | ||
+ public Result filter(LogEvent event) { | ||
+ return this.filter(event == null ? null : event.getLoggerName()); | ||
+ } | ||
+ | ||
+ private Result filter(String loggerName) { | ||
+ return loggerName != null && loggerName.startsWith("gg.castaway.pufferfish.sentry") ? Result.DENY | ||
+ : Result.NEUTRAL; | ||
+ } | ||
+ | ||
+ } | ||
+} | ||
diff --git a/src/main/java/in/bloodred/sakura/sentry/SentryManager.java b/src/main/java/in/bloodred/sakura/sentry/SentryManager.java | ||
new file mode 100644 | ||
index 0000000000000000000000000000000000000000..1b29210ad0bbb4ada150f23357f0c80d331c996d | ||
--- /dev/null | ||
+++ b/src/main/java/in/bloodred/sakura/sentry/SentryManager.java | ||
@@ -0,0 +1,40 @@ | ||
+package in.bloodred.sakura.sentry; | ||
+ | ||
+import in.bloodred.sakura.SakuraConfig; | ||
+import io.sentry.Sentry; | ||
+import org.apache.logging.log4j.LogManager; | ||
+import org.apache.logging.log4j.Logger; | ||
+ | ||
+public class SentryManager { | ||
+ | ||
+ private static final Logger logger = LogManager.getLogger(SentryManager.class); | ||
+ | ||
+ private SentryManager() { | ||
+ | ||
+ } | ||
+ | ||
+ private static boolean initialized = false; | ||
+ | ||
+ public static synchronized void init() { | ||
+ if (initialized) { | ||
+ return; | ||
+ } | ||
+ try { | ||
+ initialized = true; | ||
+ | ||
+ Sentry.init(options -> { | ||
+ options.setDsn(SakuraConfig.sentryDsn); | ||
+ options.setMaxBreadcrumbs(100); | ||
+ }); | ||
+ | ||
+ PufferfishSentryAppender appender = new PufferfishSentryAppender(); | ||
+ appender.start(); | ||
+ ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()).addAppender(appender); | ||
+ logger.info("Sentry logging started!"); | ||
+ } catch (Exception e) { | ||
+ logger.warn("Failed to initialize sentry!", e); | ||
+ initialized = false; | ||
+ } | ||
+ } | ||
+ | ||
+} |