Send a LargeBuildEventSerializedEvent to the event bus associated to the command when BuildEvents are larger than 10MB.

PiperOrigin-RevId: 210718668
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventservice/BuildEventServiceModule.java b/src/main/java/com/google/devtools/build/lib/buildeventservice/BuildEventServiceModule.java
index 20a5446..1b78cf8 100644
--- a/src/main/java/com/google/devtools/build/lib/buildeventservice/BuildEventServiceModule.java
+++ b/src/main/java/com/google/devtools/build/lib/buildeventservice/BuildEventServiceModule.java
@@ -23,6 +23,7 @@
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
+import com.google.common.eventbus.EventBus;
 import com.google.devtools.build.lib.authandtls.AuthAndTLSOptions;
 import com.google.devtools.build.lib.buildeventservice.client.BuildEventServiceClient;
 import com.google.devtools.build.lib.buildeventstream.BuildEventArtifactUploader;
@@ -105,7 +106,8 @@
             commandEnvironment.getReporter(),
             commandEnvironment.getBuildRequestId().toString(),
             commandEnvironment.getCommandId().toString(),
-            commandEnvironment.getCommandName());
+            commandEnvironment.getCommandName(),
+            commandEnvironment.getEventBus());
     if (streamer != null) {
       commandEnvironment.getReporter().addHandler(streamer);
       commandEnvironment.getEventBus().register(streamer);
@@ -156,7 +158,8 @@
       Reporter reporter,
       String buildRequestId,
       String invocationId,
-      String commandName) {
+      String commandName,
+      EventBus internalEventBus) {
     Preconditions.checkNotNull(buildEventArtifactUploaderFactoryMap);
 
     try {
@@ -172,7 +175,8 @@
                 buildEventArtifactUploaderFactoryMap,
                 commandLineReporter,
                 startupOptionsProvider,
-                optionsProvider);
+                optionsProvider,
+                internalEventBus);
       } catch (Exception e) {
         reportError(
             commandLineReporter,
@@ -217,7 +221,8 @@
       BuildEventArtifactUploaderFactoryMap buildEventArtifactUploaderFactoryMap,
       EventHandler commandLineReporter,
       OptionsParsingResult startupOptionsProvider,
-      OptionsParsingResult optionsProvider)
+      OptionsParsingResult optionsProvider,
+      EventBus internalEventBus)
       throws IOException, OptionsParsingException {
     T besOptions =
         checkNotNull(
@@ -279,7 +284,8 @@
               keywords(besOptions, startupOptionsProvider),
               besResultsUrl,
               artifactUploader,
-              errorsShouldFailTheBuild());
+              errorsShouldFailTheBuild(),
+              internalEventBus);
       logger.fine("BuildEventServiceTransport was created successfully");
       return besTransport;
     }
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventservice/BuildEventServiceTransport.java b/src/main/java/com/google/devtools/build/lib/buildeventservice/BuildEventServiceTransport.java
index dfb4bde..b56f16f 100644
--- a/src/main/java/com/google/devtools/build/lib/buildeventservice/BuildEventServiceTransport.java
+++ b/src/main/java/com/google/devtools/build/lib/buildeventservice/BuildEventServiceTransport.java
@@ -26,6 +26,7 @@
 import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
 import com.google.common.collect.Sets;
+import com.google.common.eventbus.EventBus;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.ListeningExecutorService;
@@ -40,6 +41,7 @@
 import com.google.devtools.build.lib.buildeventstream.BuildEventProtocolOptions;
 import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos;
 import com.google.devtools.build.lib.buildeventstream.BuildEventTransport;
+import com.google.devtools.build.lib.buildeventstream.LargeBuildEventSerializedEvent;
 import com.google.devtools.build.lib.buildeventstream.PathConverter;
 import com.google.devtools.build.lib.clock.Clock;
 import com.google.devtools.build.lib.events.Event;
@@ -137,6 +139,8 @@
    */
   private final AtomicInteger acksReceivedSinceLastRetry = new AtomicInteger();
 
+  private final EventBus internalEventBus;
+
   public BuildEventServiceTransport(
       BuildEventServiceClient besClient,
       Duration uploadTimeout,
@@ -152,7 +156,8 @@
       Set<String> keywords,
       @Nullable String besResultsUrl,
       BuildEventArtifactUploader artifactUploader,
-      boolean errorsShouldFailTheBuild) {
+      boolean errorsShouldFailTheBuild,
+      EventBus internalEventBus) {
     this(
         besClient,
         uploadTimeout,
@@ -169,7 +174,8 @@
         besResultsUrl,
         artifactUploader,
         new JavaSleeper(),
-        errorsShouldFailTheBuild);
+        errorsShouldFailTheBuild,
+        internalEventBus);
   }
 
   @VisibleForTesting
@@ -189,7 +195,8 @@
       @Nullable String besResultsUrl,
       BuildEventArtifactUploader artifactUploader,
       Sleeper sleeper,
-      boolean errorsShouldFailTheBuild) {
+      boolean errorsShouldFailTheBuild,
+      EventBus internalEventBus) {
     this.besClient = besClient;
     this.besProtoUtil =
         new BuildEventServiceProtoUtil(
@@ -225,6 +232,7 @@
     this.besResultsUrl = besResultsUrl;
     this.errorsShouldFailTheBuild = errorsShouldFailTheBuild;
     this.clock = clock;
+    this.internalEventBus = internalEventBus;
   }
 
   public boolean isStreaming() {
@@ -745,6 +753,11 @@
                   return protocolOptions;
                 }
               });
+      if (eventProto.getSerializedSize()
+          > LargeBuildEventSerializedEvent.SIZE_OF_LARGE_BUILD_EVENTS_IN_BYTES) {
+        internalEventBus.post(new LargeBuildEventSerializedEvent(
+            event.getEventId().toString(), eventProto.getSerializedSize()));
+      }
       return besProtoUtil.bazelEvent(getSequenceNumber(), getTimestamp(), Any.pack(eventProto));
     }
   }
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/BUILD b/src/main/java/com/google/devtools/build/lib/buildeventstream/BUILD
index 0891970..4bb7f32 100644
--- a/src/main/java/com/google/devtools/build/lib/buildeventstream/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/BUILD
@@ -16,6 +16,7 @@
         "//src/main/java/com/google/devtools/build/lib/buildeventstream/proto:build_event_stream_java_proto",
         "//src/main/java/com/google/devtools/build/lib/causes",
         "//src/main/java/com/google/devtools/build/lib/cmdline",
+        "//src/main/java/com/google/devtools/build/lib/concurrent",
         "//src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec",
         "//src/main/java/com/google/devtools/build/lib/vfs",
         "//src/main/java/com/google/devtools/common/options",
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/LargeBuildEventSerializedEvent.java b/src/main/java/com/google/devtools/build/lib/buildeventstream/LargeBuildEventSerializedEvent.java
new file mode 100644
index 0000000..b61a310
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/LargeBuildEventSerializedEvent.java
@@ -0,0 +1,47 @@
+// Copyright 2018 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;
+
+import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+
+/**
+ * Event used to log when a "large" build event was serialized by the Build Event Service transport.
+ * The threshold for large event is defined by
+ * {@link LargeBuildEventSerializedEvent#SIZE_OF_LARGE_BUILD_EVENTS_IN_BYTES}.
+ */
+@Immutable
+public final class LargeBuildEventSerializedEvent {
+  /**
+   * Size of events considered 'large'.
+   * TODO(lpino): This size should be 1MB as recommended by
+   * protobuf (https://developers.google.com/protocol-buffers/docs/techniques).
+   */
+  public static final int SIZE_OF_LARGE_BUILD_EVENTS_IN_BYTES = 10000000;
+
+  private final String buildEventId;
+  private final int serializedSizeInBytes;
+
+  public LargeBuildEventSerializedEvent(String buildEventId, int size) {
+    this.buildEventId = buildEventId;
+    this.serializedSizeInBytes = size;
+  }
+
+  public String getBuildEventId() {
+    return buildEventId;
+  }
+
+  public int getSerializedSizeInBytes() {
+    return serializedSizeInBytes;
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/buildeventservice/BazelBuildEventServiceModuleTest.java b/src/test/java/com/google/devtools/build/lib/buildeventservice/BazelBuildEventServiceModuleTest.java
index 6abd99d..d1078fc 100644
--- a/src/test/java/com/google/devtools/build/lib/buildeventservice/BazelBuildEventServiceModuleTest.java
+++ b/src/test/java/com/google/devtools/build/lib/buildeventservice/BazelBuildEventServiceModuleTest.java
@@ -145,7 +145,8 @@
         reporter,
         /* buildRequestId= */ "foo",
         /* invocationId= */ "bar",
-        commandName);
+        commandName,
+        /*internalEventBus =*/new EventBus());
   }
 
   @Test