Jakob Buchgraber | b4011da | 2017-08-07 11:00:04 +0200 | [diff] [blame] | 1 | --- |
| 2 | layout: documentation |
| 3 | title: Build Event Protocol |
| 4 | --- |
| 5 | |
| 6 | # Build Event Protocol |
| 7 | |
| 8 | The [Build Event Protocol] allows third party programs to gain insight into a |
| 9 | Bazel invocation. For example, you could use the Build Event Protocol to gather |
| 10 | information for an IDE plugin or a dashboard that displays build results. |
| 11 | |
| 12 | The protocol is a set of [protocol buffer] messages with some semantics defined |
| 13 | on top of it. It includes information about build and test results, build |
| 14 | progress, the build configuration and much more. The Build Event Protocol is |
| 15 | intended to be consumed programmatically and makes parsing Bazel’s command line |
| 16 | output a thing of the past. |
| 17 | |
| 18 | ## Contents |
| 19 | |
| 20 | * [Build Event Protocol Overview](#build-event-protocol-overview) |
| 21 | * [Build Event Graph](#build-event-graph) |
| 22 | * [The Build Event Protocol by Example](#the-build-event-protocol-by-example) |
| 23 | * [Consuming the Build Event Protocol](#consuming-the-build-event-protocol) |
| 24 | * [Consume in a Binary Format](#consume-in-a-binary-format) |
| 25 | * [Consume in Text Formats](#consume-in-text-formats) |
| 26 | * [The Build Event Service](#the-build-event-service) |
| 27 | * [Build Event Service Flags](#build-event-service-flags) |
| 28 | * [Authentication and Security](#authentication-and-security) |
| 29 | |
| 30 | ## Build Event Protocol Overview |
| 31 | |
| 32 | The [Build Event Protocol] represents information about a build as events. A |
| 33 | build event is a protocol buffer message consisting of a build event identifier, |
| 34 | a set of child event identifiers, and a payload. |
| 35 | |
| 36 | * __Build Event Identifier:__ Depending on the kind of build event, it might be |
| 37 | an [opaque string] or [structured information] revealing more about the build |
| 38 | event. A build event identifier is unique within a build. |
| 39 | |
| 40 | * __Children:__ A build event may announce other build events, by including |
| 41 | their build event identifiers in its [children field]. For example, the |
| 42 | `PatternExpanded` build event announces the targets it expands to as children. |
| 43 | The protocol guarantees that all events, except for the first event, are |
| 44 | announced by a previous event. |
| 45 | |
| 46 | * __Payload:__ The payload contains structured information about a build event, |
| 47 | encoded as a protocol buffer message specific to that event. Note, that the |
| 48 | payload might not be the expected type, but could be an `Aborted` message e.g. |
| 49 | if the build aborted prematurely. |
| 50 | |
| 51 | ### Build Event Graph |
| 52 | All build events form a directed acyclic graph through their parent and child |
| 53 | relationship. Every build event except for the initial build event has one or |
| 54 | more parent events. Please note that not all parent events of a child event must |
| 55 | necessarily be posted before it. When a build is complete (succeeded or failed) |
| 56 | all announced events will have been posted. In case of a Bazel crash or a failed |
| 57 | network transport, some announced build events may never be posted. |
| 58 | |
| 59 | ## The Build Event Protocol by Example |
| 60 | The full specification of the [Build Event Protocol] can be found in its |
| 61 | protocol buffer definition and describing it here is beyond the scope of this |
| 62 | document. However, it might be helpful to build up some intuition before looking |
| 63 | at the specification. |
| 64 | |
| 65 | Consider a simple Bazel workspace that consists of two empty shell scripts |
| 66 | `foo.sh` and `foo_test.sh` and the following BUILD file: |
| 67 | |
| 68 | ```bash |
| 69 | sh_binary( |
| 70 | name = "foo", |
| 71 | srcs = ["foo.sh"], |
| 72 | ) |
| 73 | |
| 74 | sh_library( |
| 75 | name = "foo_lib", |
| 76 | data = [":foo"], |
| 77 | ) |
| 78 | |
| 79 | sh_test( |
| 80 | name = "foo_test", |
| 81 | srcs = ["foo_test.sh"], |
| 82 | deps = [":foo_lib"], |
| 83 | ) |
| 84 | ``` |
| 85 | |
| 86 | When running `bazel test ...` on this project the build graph of the generated |
| 87 | build events will resemble the graph below. The arrows indicate the |
| 88 | aforementioned parent and child relationship. Note that some build events and |
| 89 | most fields have been omitted for brevity. |
| 90 | |
| 91 | ![bep-graph] |
| 92 | |
| 93 | Initially, a `BuildStarted` event is published. The event informs us that the |
| 94 | build was invoked through the `bazel test` command and it also announces five |
| 95 | child events: `OptionsParsed`, `WorkspaceStatus`, `CommandLine`, |
| 96 | `PatternExpanded` and `Progress`. The first three events provide information |
| 97 | about how Bazel was invoked. The `PatternExpanded` build event provides insight |
| 98 | into which specific targets the `...` pattern expanded to: `//:foo`, `//:foo_lib` |
| 99 | and `//:foo_test`. It does so by declaring three `TargetConfigured` events as |
| 100 | children. |
| 101 | |
| 102 | Note that the `TargetConfigured` event declares the `Configuration` event as a |
| 103 | child event, even though `Configuration` has been posted before the |
| 104 | `TargetConfigured` event. |
| 105 | |
| 106 | Besides the parent and child relationship, events may also refer to each other |
| 107 | using their build event identifiers. For example, in the above graph the |
| 108 | `TargetComplete` event refers to the `NamedSetOfFiles` event in its `fileSets` |
| 109 | field. |
| 110 | |
| 111 | Build events that refer to files (i.e. outputs) usually don’t embed the file |
| 112 | names and paths in the event. Instead, they contain the build event identifier |
| 113 | of a `NamedSetOfFiles` event, which will then contain the actual file names and |
| 114 | paths. The `NamedSetOfFiles` event allows a set of files to be reported once and |
| 115 | referred to by many targets. This structure is necessary because otherwise in |
| 116 | some cases the Build Event Protocol output size would grow quadratically with |
| 117 | the number of files. A `NamedSetOfFiles` event may also not have all its files |
| 118 | embedded, but instead refer to other `NamedSetOfFiles` events through their |
| 119 | build event identifiers. |
| 120 | |
| 121 | Below is an instance of the `TargetComplete` event for the `//:foo_lib` target |
| 122 | from the above graph, printed in protocol buffer’s JSON representation. The |
| 123 | build event identifier contains the target as an opaque string and refers to the |
| 124 | `Configuration` event using its build event identifier. The event does not |
| 125 | announce any child events. The payload contains information about whether the |
| 126 | target was built successfully, the set of output files, and the kind of target |
| 127 | built. |
| 128 | |
| 129 | ```json |
| 130 | { |
| 131 | "id": { |
| 132 | "targetCompleted": { |
| 133 | "label": "//:foo_lib", |
| 134 | "configuration": { |
| 135 | "id": "544e39a7f0abdb3efdd29d675a48bc6a" |
| 136 | } |
| 137 | } |
| 138 | }, |
| 139 | "completed": { |
| 140 | "success": true, |
| 141 | "outputGroup": [{ |
| 142 | "name": "default", |
| 143 | "fileSets": [{ |
| 144 | "id": "0" |
| 145 | }] |
| 146 | }], |
| 147 | "targetKind": "sh_library rule" |
| 148 | } |
| 149 | } |
| 150 | ``` |
| 151 | |
| 152 | ## Consuming the Build Event Protocol |
| 153 | |
| 154 | ### Consume in a Binary Format |
| 155 | |
| 156 | To consume the Build Event Protocol in a binary format: |
| 157 | |
| 158 | 1. Have Bazel serialize the protocol buffer messages to a file by specifying the |
| 159 | option `--build_event_binary_file=/path/to/file`. The file will contain |
| 160 | serialized protocol buffer messages with each message being length delimited. |
| 161 | Each message is prefixed with its length encoded as a variable length integer. |
| 162 | This format can be read using the protocol buffer library’s |
| 163 | [parseDelimitedFrom(InputStream)] method. |
| 164 | |
| 165 | 2. Then, write a program that extracts the relevant information from the |
| 166 | serialized protocol buffer message. |
| 167 | |
| 168 | ### Consume in Text Formats |
| 169 | |
| 170 | The following Bazel command line flags will output the Build Event Protocol in a |
| 171 | human-readable formats: |
| 172 | |
| 173 | ``` |
| 174 | --build_event_text_file |
| 175 | --build_event_json_file |
| 176 | ``` |
| 177 | |
| 178 | ## The Build Event Service |
| 179 | |
| 180 | The [Build Event Service] Protocol is a generic [gRPC] service for transmitting |
| 181 | build events. The Build Event Service protocol is independent of the Build Event |
| 182 | Protocol and treats the Build Event Protocol events as opaque bytes. Bazel ships |
| 183 | with a gRPC client implementation of the Build Event Service protocol that |
| 184 | transmits Build Event Protocol events. One can specify the endpoint to send the |
| 185 | events to using the `--bes_backend=HOST:PORT flag`. Bazel’s implementation also |
| 186 | supports TLS which can be enabled by specifying the `--tls_enabled flag`. |
| 187 | |
Ed Baunton | faad4b5 | 2019-03-06 03:25:25 -0800 | [diff] [blame] | 188 | There is currently an experimental open source implementation of the [Build Event |
| 189 | Service](https://github.com/buildbarn/bb-event-service/) in Go as part of the |
| 190 | Buildbarn suite of Remote Execution tools and services. |
Jakob Buchgraber | b4011da | 2017-08-07 11:00:04 +0200 | [diff] [blame] | 191 | |
| 192 | ### Build Event Service Flags |
| 193 | |
Ed Schouten | b4fc494 | 2019-02-27 04:16:01 -0800 | [diff] [blame] | 194 | Bazel has several flags related to the [Build Event Service] protocol, including: |
Jakob Buchgraber | b4011da | 2017-08-07 11:00:04 +0200 | [diff] [blame] | 195 | |
| 196 | * `--bes_backend` |
| 197 | * `--[no]bes_best_effort` |
| 198 | * `--[no]bes_lifecycle_events` |
Ed Schouten | b4fc494 | 2019-02-27 04:16:01 -0800 | [diff] [blame] | 199 | * `--bes_results_url` |
Jakob Buchgraber | b4011da | 2017-08-07 11:00:04 +0200 | [diff] [blame] | 200 | * `--bes_timeout` |
| 201 | * `--project_id` |
| 202 | |
| 203 | For a description of each of these flags, see the |
| 204 | [Command-Line Reference](command-line-reference.html). |
| 205 | |
| 206 | ### Authentication and Security |
| 207 | |
| 208 | Bazel’s [Build Event Service] implementation also supports authentication and |
| 209 | TLS. These settings can be controlled using the below flags. Please note that |
| 210 | these flags are also used for Bazel’s Remote Execution. This implies that the |
| 211 | Build Event Service and Remote Execution Endpoints need to share the same |
| 212 | authentication and TLS infrastructure. |
| 213 | |
Jakob Buchgraber | 8a7c63e | 2017-12-20 10:13:23 -0800 | [diff] [blame] | 214 | * `--[no]google_default_credentials` |
| 215 | * `--google_credentials` |
| 216 | * `--google_auth_scopes` |
Jakob Buchgraber | b4011da | 2017-08-07 11:00:04 +0200 | [diff] [blame] | 217 | * `--tls_certificate` |
| 218 | * `--[no]tls_enabled` |
| 219 | |
| 220 | For a description of each of these flags, see the |
| 221 | [Command-Line Reference](command-line-reference.html). |
| 222 | |
Jakob Buchgraber | b1d34be | 2017-09-11 15:19:28 +0200 | [diff] [blame] | 223 | ### Build Event Service and Remote Caching |
| 224 | |
| 225 | The BEP typically contains many references to log files (test.log, test.xml, |
| 226 | etc. ) stored on the machine where Bazel is running. A remote BES server |
| 227 | typically can't access these files as they are on different machines. A way |
| 228 | to work around this issue is to use Bazel with [remote caching]. Bazel will |
| 229 | upload all output files to the remote cache (including files referenced in |
| 230 | the BEP) and the BES server can then fetch the referenced files from the |
| 231 | cache. |
| 232 | |
| 233 | See [GitHub issue 3689] for more details. |
| 234 | |
Alex Vandiver | e10526a | 2017-09-27 05:22:44 -0400 | [diff] [blame] | 235 | [remote caching]: https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/remote/README.md |
Jakob Buchgraber | b1d34be | 2017-09-11 15:19:28 +0200 | [diff] [blame] | 236 | |
Alex Vandiver | e10526a | 2017-09-27 05:22:44 -0400 | [diff] [blame] | 237 | [GitHub issue 3689]: https://github.com/bazelbuild/bazel/issues/3689 |
Jakob Buchgraber | b1d34be | 2017-09-11 15:19:28 +0200 | [diff] [blame] | 238 | |
Jakob Buchgraber | b4011da | 2017-08-07 11:00:04 +0200 | [diff] [blame] | 239 | [Build Event Protocol]: |
| 240 | https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto |
| 241 | |
| 242 | [Build Event Service]: |
| 243 | https://github.com/googleapis/googleapis/blob/master/google/devtools/build/v1/publish_build_event.proto |
| 244 | |
| 245 | [gRPC]: https://www.grpc.io |
| 246 | |
| 247 | [protocol buffer]: https://developers.google.com/protocol-buffers/ |
| 248 | |
| 249 | [bep-graph]: /assets/bep-graph.svg |
| 250 | |
| 251 | [parseDelimitedFrom(InputStream)]: |
| 252 | https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/AbstractParser#parseDelimitedFrom-java.io.InputStream- |
| 253 | |
| 254 | [opaque string]: |
| 255 | https://github.com/bazelbuild/bazel/blob/16a107d/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto#L91 |
| 256 | |
| 257 | [structured information]: |
| 258 | https://github.com/bazelbuild/bazel/blob/16a107d/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto#L123 |
| 259 | |
| 260 | [children field]: |
| 261 | https://github.com/bazelbuild/bazel/blob/16a107d/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto#L469 |