From a85544b3f6008390ded814817f7e91da46ae405e Mon Sep 17 00:00:00 2001 From: jianglai Date: Fri, 7 Dec 2018 15:01:23 -0800 Subject: [PATCH] Use gson to make JSON string in proxy log formatter This is simpler than using fasterxml.jackson. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=224583713 --- gradle/core/build.gradle | 3 - gradle/proxy/build.gradle | 4 +- java/google/registry/proxy/BUILD | 2 +- .../registry/proxy/GcpJsonFormatter.java | 169 ++++++++---------- 4 files changed, 81 insertions(+), 97 deletions(-) diff --git a/gradle/core/build.gradle b/gradle/core/build.gradle index 00d4bf8c3..19c226b8d 100644 --- a/gradle/core/build.gradle +++ b/gradle/core/build.gradle @@ -79,9 +79,6 @@ dependencies { testImplementation project(':third_party') compile 'com.beust:jcommander:1.48' - maybeRuntime 'com.fasterxml.jackson.core:jackson-core:2.9.6' - maybeRuntime 'com.fasterxml.jackson.core:jackson-annotations:2.8.0' - maybeRuntime 'com.fasterxml.jackson.core:jackson-databind:2.8.5' compile 'com.google.api-client:google-api-client:1.22.0' maybeRuntime 'com.google.api-client:google-api-client-appengine:1.22.0' maybeRuntime 'com.google.api-client:google-api-client-jackson2:1.20.0' diff --git a/gradle/proxy/build.gradle b/gradle/proxy/build.gradle index 9c39ca44f..3c2a54b2f 100644 --- a/gradle/proxy/build.gradle +++ b/gradle/proxy/build.gradle @@ -45,9 +45,6 @@ task deployJar(type: Jar) { dependencies { compile 'com.beust:jcommander:1.48' - compile 'com.fasterxml.jackson.core:jackson-annotations:2.8.9' - compile 'com.fasterxml.jackson.core:jackson-core:2.9.6' - compile 'com.fasterxml.jackson.core:jackson-databind:2.8.9' compile 'com.google.api-client:google-api-client:1.27.0' compile 'com.google.api-client:google-api-client:1.27.0' compile 'com.google.apis:google-api-services-cloudkms:v1-rev12-1.22.0' @@ -55,6 +52,7 @@ dependencies { compile 'com.google.apis:google-api-services-storage:v1-rev86-1.22.0' compile 'com.google.auto.value:auto-value-annotations:1.6.2' compile 'com.google.code.findbugs:jsr305:3.0.2' + compile 'com.google.code.gson:gson:2.8.5' compile 'com.google.dagger:dagger:2.15' compile 'com.google.flogger:flogger:0.1' compile 'com.google.guava:guava:27.0-jre' diff --git a/java/google/registry/proxy/BUILD b/java/google/registry/proxy/BUILD index b785b1cb3..2d02ee8f3 100644 --- a/java/google/registry/proxy/BUILD +++ b/java/google/registry/proxy/BUILD @@ -19,7 +19,6 @@ java_library( ]), deps = [ "//java/google/registry/util", - "//third_party/java/jackson2:jackson2-databind", "@com_beust_jcommander", "@com_google_api_client", "@com_google_apis_google_api_services_cloudkms", @@ -27,6 +26,7 @@ java_library( "@com_google_apis_google_api_services_storage", "@com_google_auto_value", "@com_google_code_findbugs_jsr305", + "@com_google_code_gson", "@com_google_dagger", "@com_google_flogger", "@com_google_flogger_system_backend", diff --git a/java/google/registry/proxy/GcpJsonFormatter.java b/java/google/registry/proxy/GcpJsonFormatter.java index e7b2d391f..7fd3c0a53 100644 --- a/java/google/registry/proxy/GcpJsonFormatter.java +++ b/java/google/registry/proxy/GcpJsonFormatter.java @@ -14,10 +14,8 @@ package google.registry.proxy; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableMap; +import com.google.gson.Gson; import java.io.PrintWriter; import java.io.StringWriter; import java.util.logging.Formatter; @@ -41,98 +39,89 @@ import java.util.logging.LogRecord; */ class GcpJsonFormatter extends Formatter { - private static final ObjectMapper MAPPER = new ObjectMapper(); + /** JSON field that determines the log level. */ + private static final String SEVERITY = "severity"; + + /** + * JSON field that stores the calling class and function when the log occurs. + * + *

This field is not used by Stackdriver, but it is useful and can be found when the log + * entries are expanded + */ + private static final String SOURCE = "source"; + + /** JSON field that contains the content, this will show up as the main entry in a log. */ + private static final String MESSAGE = "message"; + + private static final Gson gson = new Gson(); @Override public String format(LogRecord record) { - try { - return MAPPER.writeValueAsString(LogEvent.create(record)) + "\n"; - } catch (JsonProcessingException e) { - throw new RuntimeException(e); + // Add an extra newline before the message. Stackdriver does not show newlines correctly, and + // treats them as whitespace. If you want to see correctly formatted log message, expand the + // log and look for the jsonPayload.message field. This newline makes sure that the entire + // message starts on its own line, so that indentation within the message is correct. + + String message = "\n" + record.getMessage(); + String severity = severityFor(record.getLevel()); + + // The rest is mostly lifted from java.util.logging.SimpleFormatter. + String stacktrace = ""; + if (record.getThrown() != null) { + StringWriter sw = new StringWriter(); + try (PrintWriter pw = new PrintWriter(sw)) { + pw.println(); + record.getThrown().printStackTrace(pw); + } + stacktrace = sw.toString(); } + + String source; + if (record.getSourceClassName() != null) { + source = record.getSourceClassName(); + if (record.getSourceMethodName() != null) { + source += " " + record.getSourceMethodName(); + } + } else { + source = record.getLoggerName(); + } + + return gson.toJson( + ImmutableMap.of(SEVERITY, severity, SOURCE, source, MESSAGE, message + stacktrace)) + + '\n'; } - @AutoValue - abstract static class LogEvent { - - /** Field that determines the log level. */ - @JsonProperty("severity") - abstract String severity(); - - /** - * Field that stores the calling class and function when the log occurs. - * - *

This field is not used by Stackdriver, but it is useful and can be found when the log - * entries are expanded - */ - @JsonProperty("source") - abstract String source(); - - /** Field that contains the content, this will show up as the main entry in a log. */ - @JsonProperty("message") - abstract String message(); - - static LogEvent create(LogRecord record) { - // Add an extra newline before the message. Stackdriver does not show newlines correctly, and - // treats them as whitespace. If you want to see correctly formatted log message, expand the - // log and look for the jsonPayload.message field. This newline makes sure that the entire - // message starts on its own line, so that indentation within the message is correct. - - String message = "\n" + record.getMessage(); - Level level = record.getLevel(); - // See - // https://github.com/GoogleCloudPlatform/google-cloud-java/blob/master/google-cloud-logging/src/main/java/com/google/cloud/logging/Severity.java - // on how {@code Level} is mapped to severity. - String severity; - switch (level.intValue()) { - // FINEST - case 300: - // FINER - case 400: - // FINE - case 500: - severity = "DEBUG"; - break; - // CONFIG - case 700: - // INFO - case 800: - severity = "INFO"; - break; - // WARNING - case 900: - severity = "WARNING"; - break; - // SEVERE - case 1000: - severity = "ERROR"; - break; - default: - severity = "DEFAULT"; - } - - // The rest is mostly lifted from java.util.logging.SimpleFormatter. - String stacktrace = ""; - if (record.getThrown() != null) { - StringWriter sw = new StringWriter(); - try (PrintWriter pw = new PrintWriter(sw)) { - pw.println(); - record.getThrown().printStackTrace(pw); - } - stacktrace = sw.toString(); - } - - String source; - if (record.getSourceClassName() != null) { - source = record.getSourceClassName(); - if (record.getSourceMethodName() != null) { - source += " " + record.getSourceMethodName(); - } - } else { - source = record.getLoggerName(); - } - - return new AutoValue_GcpJsonFormatter_LogEvent(severity, source, message + stacktrace); + /** + * Map {@link Level} to a severity string that Stackdriver understands. + * + * @see {@code LoggingHandler} + */ + private static String severityFor(Level level) { + switch (level.intValue()) { + // FINEST + case 300: + return "DEBUG"; + // FINER + case 400: + return "DEBUG"; + // FINE + case 500: + return "DEBUG"; + // CONFIG + case 700: + return "INFO"; + // INFO + case 800: + return "INFO"; + // WARNING + case 900: + return "WARNING"; + // SEVERE + case 1000: + return "ERROR"; + default: + return "DEFAULT"; } } }