aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java
diff options
context:
space:
mode:
authorGravatar schmitt <schmitt@google.com>2017-04-12 17:25:09 +0000
committerGravatar Jakob Buchgraber <buchgr@google.com>2017-04-13 09:36:48 +0200
commit2d5d17b221574583f3503fe536c7240c168311da (patch)
tree8af68712b9aa8e0e3b7450106b0f5cb9ca351c60 /src/main/java
parent7d0bcf93e518065f0458aa215db9487e25e1be4a (diff)
Add a custom single-line formatter for java.log.
This logger makes it easier to parse log statements and is now enabled for Bazel's java.log. RELNOTES[INC]: Bazel now prints logs in single lines to java.log PiperOrigin-RevId: 152954337
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/BUILD11
-rw-r--r--src/main/java/com/google/devtools/build/lib/util/SingleLineFormatter.java87
2 files changed, 98 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD
index cd90d661d8..51b444d586 100644
--- a/src/main/java/com/google/devtools/build/lib/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/BUILD
@@ -275,6 +275,15 @@ java_library(
)
java_library(
+ name = "single-line-formatter",
+ srcs = ["util/SingleLineFormatter.java"],
+ deps = [
+ "//third_party:guava",
+ "//third_party:joda_time",
+ ],
+)
+
+java_library(
name = "util",
srcs = glob(
["util/*.java"],
@@ -286,6 +295,7 @@ java_library(
"util/OS.java",
"util/Preconditions.java",
"util/ProcessUtils.java",
+ "util/SingleLineFormatter.java",
"util/StringCanonicalizer.java",
"util/StringTrie.java",
"util/VarInt.java",
@@ -1192,6 +1202,7 @@ java_binary(
main_class = "com.google.devtools.build.lib.bazel.BazelMain",
runtime_deps = [
":bazel-main",
+ ":single-line-formatter", # See startup_options.cc
],
)
diff --git a/src/main/java/com/google/devtools/build/lib/util/SingleLineFormatter.java b/src/main/java/com/google/devtools/build/lib/util/SingleLineFormatter.java
new file mode 100644
index 0000000000..6748917bdc
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/util/SingleLineFormatter.java
@@ -0,0 +1,87 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.util;
+
+import com.google.common.collect.ImmutableRangeMap;
+import com.google.common.collect.Range;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.logging.Formatter;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+
+/**
+ * Formatter to write java.util.logging messages out in single-line format.
+ *
+ * <p>Log entries contain the date and time (in UTC), log level (as letter and numerical value),
+ * source location, thread ID, message and, if applicable, a stack trace.
+ */
+public class SingleLineFormatter extends Formatter {
+
+ /** Single-character codes based on {@link Level}s. */
+ private static final ImmutableRangeMap<Integer, Character> CODES_BY_LEVEL =
+ ImmutableRangeMap.<Integer, Character>builder()
+ .put(Range.atMost(Level.FINE.intValue()), 'D')
+ .put(Range.open(Level.FINE.intValue(), Level.WARNING.intValue()), 'I')
+ .put(Range.closedOpen(Level.WARNING.intValue(), Level.SEVERE.intValue()), 'W')
+ .put(Range.atLeast(Level.SEVERE.intValue()), 'X')
+ .build();
+
+ /** A thread safe, immutable formatter that can be used by all without contention. */
+ private static final DateTimeFormatter DATE_TIME_FORMAT =
+ DateTimeFormat.forPattern("yyMMdd HH:mm:ss.SSS").withZoneUTC();
+
+ @Override
+ public String format(LogRecord rec) {
+ StringBuilder buf = new StringBuilder();
+
+ // Timestamp
+ buf.append(DATE_TIME_FORMAT.print(rec.getMillis()))
+ .append(':');
+
+ // One character code for level
+ buf.append(CODES_BY_LEVEL.get(rec.getLevel().intValue()));
+
+ // The stack trace, if any
+ Throwable thrown = rec.getThrown();
+ if (thrown != null) {
+ buf.append('T');
+ }
+
+ buf.append(' ');
+
+ // Information about the source of the exception
+ buf.append(rec.getThreadID())
+ .append(" [")
+ .append(rec.getSourceClassName())
+ .append('.')
+ .append(rec.getSourceMethodName())
+ .append("] ");
+
+ // The actual message
+ buf.append(formatMessage(rec)).append('\n');
+
+ if (thrown != null) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ thrown.printStackTrace(pw);
+ pw.flush();
+ buf.append(sw.toString());
+ }
+
+ return buf.toString();
+ }
+}