diff --git a/jetty/kubernetes/nomulus-deployment.yaml b/jetty/kubernetes/nomulus-deployment.yaml index 910b11d4d..e64c869d4 100644 --- a/jetty/kubernetes/nomulus-deployment.yaml +++ b/jetty/kubernetes/nomulus-deployment.yaml @@ -13,6 +13,7 @@ spec: labels: app: nomulus spec: + serviceAccountName: nomulus containers: - name: nomulus image: gcr.io/GCP_PROJECT/nomulus diff --git a/util/src/main/java/google/registry/util/GcpJsonFormatter.java b/util/src/main/java/google/registry/util/GcpJsonFormatter.java index 4b6d9659d..b14f2e60f 100644 --- a/util/src/main/java/google/registry/util/GcpJsonFormatter.java +++ b/util/src/main/java/google/registry/util/GcpJsonFormatter.java @@ -57,6 +57,16 @@ public class GcpJsonFormatter extends Formatter { /** JSON field that contains the content, this will show up as the main entry in a log. */ private static final String MESSAGE = "message"; + /** + * JSON field that contains the stack trace, if any. + * + *

Note that this field is not part of the structured logging that stackdriver understands. + * Normally we'd just append the stack trace to the message itself. However, for unclear reasons, + * if we do that on GKE, the log entry containing a stack trace will be lumped together with + * several following log entries and makes it hard to read. + */ + private static final String STACKTRACE = "stacktrace"; + private static final String FILE = "file"; private static final String FUNCTION = "function"; @@ -99,16 +109,17 @@ public class GcpJsonFormatter extends Formatter { String severity = severityFor(record.getLevel()); // The rest is mostly lifted from java.util.logging.SimpleFormatter. - String stacktrace = ""; + String throwable = ""; if (record.getThrown() != null) { StringWriter sw = new StringWriter(); - try (PrintWriter pw = new PrintWriter(sw)) { - pw.println(); - record.getThrown().printStackTrace(pw); - } - stacktrace = sw.toString(); + PrintWriter pw = new PrintWriter(sw); + pw.println(); + record.getThrown().printStackTrace(pw); + pw.close(); + throwable = sw.toString(); } - String message = '\n' + record.getMessage() + stacktrace; + + String message = '\n' + formatMessage(record); String function = ""; if (record.getSourceClassName() != null) { @@ -144,6 +155,9 @@ public class GcpJsonFormatter extends Formatter { json.put(SEVERITY, severity); json.put(SOURCE_LOCATION, sourceLocation); json.put(MESSAGE, message); + if (!throwable.isEmpty()) { + json.put(STACKTRACE, throwable); + } if (traceId.get() != null) { json.put(TRACE, traceId.get()); } diff --git a/util/src/test/java/google/registry/util/GcpJsonFormatterTest.java b/util/src/test/java/google/registry/util/GcpJsonFormatterTest.java index afe24d1ef..c2f16f3ef 100644 --- a/util/src/test/java/google/registry/util/GcpJsonFormatterTest.java +++ b/util/src/test/java/google/registry/util/GcpJsonFormatterTest.java @@ -109,14 +109,11 @@ class GcpJsonFormatterTest { handler.close(); String output = ostream.toString(StandardCharsets.US_ASCII); String prefix = - makeJson( - "ERROR", - 108, - "testSuccess_withCause", - "Something went terribly wrong\\njava.lang.RuntimeException: boom!"); - // Remove the last three characters (", }, \n) from the template as the actual output contains + makeJson("ERROR", 108, "testSuccess_withCause", "Something went terribly wrong"); + // Remove the last two characters (}, \n) from the template as the actual output contains // the full stack trace. - prefix = prefix.substring(0, prefix.length() - 3); + prefix = prefix.substring(0, prefix.length() - 2); + prefix += ",\"stacktrace\":\"\\njava.lang.RuntimeException: boom!\\n"; assertThat(output).startsWith(prefix); } @@ -126,14 +123,11 @@ class GcpJsonFormatterTest { handler.close(); String output = ostream.toString(StandardCharsets.US_ASCII); String prefix = - makeJson( - "ERROR", - 125, - "testSuccess_withStackTrace", - "Something is worth checking\\ncom.google.common.flogger.LogSiteStackTrace: FULL"); - // Remove the last three characters (", }, \n) from the template as the actual output contains + makeJson("ERROR", 122, "testSuccess_withStackTrace", "Something is worth checking"); + // Remove the last three characters (}, \n) from the template as the actual output contains // the full stack trace. - prefix = prefix.substring(0, prefix.length() - 3); + prefix = prefix.substring(0, prefix.length() - 2); + prefix += ",\"stacktrace\":\"\\ncom.google.common.flogger.LogSiteStackTrace: FULL\\n"; assertThat(output).startsWith(prefix); }