From 1d287fc8582a693fe1b2b673663ab9952417e87c Mon Sep 17 00:00:00 2001 From: Klaus Aehlig Date: Thu, 11 May 2017 11:24:09 -0400 Subject: BEP: add a JSON transport As JSON is a widely supported format, also add a transport writing the build events in JSON format. This will allow more tools to get status reports about builds. Change-Id: I7e5901cc65d927b93c8fc9bcd2d2baa7e707f09e PiperOrigin-RevId: 155750964 --- .../build/lib/buildeventstream/transports/BUILD | 1 + .../transports/BuildEventStreamOptions.java | 27 +++++++++ .../transports/BuildEventTransportFactory.java | 15 +++++ .../transports/JsonFormatFileTransport.java | 69 ++++++++++++++++++++++ 4 files changed, 112 insertions(+) create mode 100644 src/main/java/com/google/devtools/build/lib/buildeventstream/transports/JsonFormatFileTransport.java (limited to 'src/main/java/com/google/devtools/build/lib/buildeventstream/transports') diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BUILD b/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BUILD index 661d416524..e75fb5c1b8 100644 --- a/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BUILD +++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BUILD @@ -15,5 +15,6 @@ java_library( "//src/main/java/com/google/devtools/common/options", "//third_party:guava", "//third_party/protobuf:protobuf_java", + "//third_party/protobuf:protobuf_java_util", ], ) diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventStreamOptions.java b/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventStreamOptions.java index da3805e22a..cdc966082b 100644 --- a/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventStreamOptions.java +++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventStreamOptions.java @@ -39,6 +39,14 @@ public class BuildEventStreamOptions extends OptionsBase { ) public String buildEventBinaryFile; + @Option( + name = "experimental_build_event_json_file", + defaultValue = "", + optionUsageRestrictions = OptionUsageRestrictions.HIDDEN, + help = "If non-empty, write a JOSN serialisation of the build event protocol to that file." + ) + public String buildEventJsonFile; + @Option( name = "experimental_build_event_text_file_path_conversion", defaultValue = "true", @@ -61,6 +69,17 @@ public class BuildEventStreamOptions extends OptionsBase { ) public boolean buildEventBinaryFilePathConversion; + @Option( + name = "experimental_build_event_json_file_path_conversion", + defaultValue = "true", + optionUsageRestrictions = OptionUsageRestrictions.HIDDEN, + help = + "Convert paths in the json file representation of the build event protocol to more " + + "globally valid URIs whenever possible; if disabled, the file:// uri scheme will " + + "always be used" + ) + public boolean buildEventJsonFilePathConversion; + public String getBuildEventTextFile() { return buildEventTextFile; } @@ -69,6 +88,10 @@ public class BuildEventStreamOptions extends OptionsBase { return buildEventBinaryFile; } + public String getBuildEventJsonFile() { + return buildEventJsonFile; + } + public boolean getBuildEventTextFilePathConversion() { return buildEventTextFilePathConversion; } @@ -76,4 +99,8 @@ public class BuildEventStreamOptions extends OptionsBase { public boolean getBuildEventBinaryFilePathConversion() { return buildEventBinaryFilePathConversion; } + + public boolean getBuildEventJsonFilePathConversion() { + return buildEventJsonFilePathConversion; + } } diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventTransportFactory.java b/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventTransportFactory.java index b89017adc7..a28645dedb 100644 --- a/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventTransportFactory.java +++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventTransportFactory.java @@ -55,6 +55,21 @@ public enum BuildEventTransportFactory { ? pathConverter : new NullPathConverter()); } + }, + + JSON_TRANSPORT { + @Override + protected boolean enabled(BuildEventStreamOptions options) { + return !isNullOrEmpty(options.getBuildEventJsonFile()); + } + + @Override + protected BuildEventTransport create( + BuildEventStreamOptions options, PathConverter pathConverter) throws IOException { + return new JsonFormatFileTransport( + options.getBuildEventJsonFile(), + options.getBuildEventJsonFilePathConversion() ? pathConverter : new NullPathConverter()); + } }; /** diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/JsonFormatFileTransport.java b/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/JsonFormatFileTransport.java new file mode 100644 index 0000000000..469319f6bb --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/transports/JsonFormatFileTransport.java @@ -0,0 +1,69 @@ +// 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.buildeventstream.transports; + +import com.google.devtools.build.lib.buildeventstream.ArtifactGroupNamer; +import com.google.devtools.build.lib.buildeventstream.BuildEvent; +import com.google.devtools.build.lib.buildeventstream.BuildEventConverters; +import com.google.devtools.build.lib.buildeventstream.BuildEventTransport; +import com.google.devtools.build.lib.buildeventstream.PathConverter; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.util.JsonFormat; +import java.io.IOException; + +/** + * A simple {@link BuildEventTransport} that writes the JSON representation of the protocol-buffer + * representation of the events to a file. + */ +public final class JsonFormatFileTransport extends FileTransport { + + private final PathConverter pathConverter; + + JsonFormatFileTransport(String path, PathConverter pathConverter) throws IOException { + super(path); + this.pathConverter = pathConverter; + } + + @Override + public String name() { + return this.getClass().getSimpleName(); + } + + @Override + public synchronized void sendBuildEvent(BuildEvent event, final ArtifactGroupNamer namer) { + BuildEventConverters converters = + new BuildEventConverters() { + @Override + public PathConverter pathConverter() { + return pathConverter; + } + + @Override + public ArtifactGroupNamer artifactGroupNamer() { + return namer; + } + }; + String protoJsonRepresentation; + try { + protoJsonRepresentation = JsonFormat.printer().print(event.asStreamProto(converters)) + "\n"; + } catch (InvalidProtocolBufferException e) { + // We don't expect any unknown Any fields in our protocol buffer. Nevertheless, handle + // the exception gracefully and, at least, return valid JSON with an id field. + protoJsonRepresentation = + "{\"id\" : \"unknown\", \"exception\" : \"InvlaidProtocolBufferException\"}\n"; + } + writeData(protoJsonRepresentation.getBytes()); + } +} -- cgit v1.2.3