blob: 40197b13c7ad8b86ab18acd393569da60a68cfe4 [file] [log] [blame]
ulfjack236635a2017-06-26 09:25:52 +02001// Copyright 2017 The Bazel Authors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14package com.google.devtools.build.lib.runtime;
15
16import static com.google.common.base.Preconditions.checkNotNull;
17
18import com.google.common.base.Supplier;
19import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
20import com.google.devtools.build.lib.runtime.commands.InfoItem;
21import com.google.devtools.build.lib.util.AbruptExitException;
22import com.google.devtools.build.lib.util.LoggingUtil;
23import com.google.devtools.build.lib.util.io.OutErr;
24import com.google.devtools.build.lib.vfs.Path;
juliexxiae91a4502018-08-15 14:42:29 -070025import com.google.devtools.common.options.OptionsParsingResult;
ulfjack236635a2017-06-26 09:25:52 +020026import java.io.IOException;
27import java.io.OutputStream;
28import java.util.logging.Level;
29
30/** This module logs complete stdout / stderr output of Bazel to a local file. */
31public class CommandLogModule extends BlazeModule {
32 private CommandEnvironment env;
33 private OutputStream logOutputStream;
34
35 @Override
juliexxiae91a4502018-08-15 14:42:29 -070036 public void serverInit(OptionsParsingResult startupOptions, ServerBuilder builder) {
ulfjack236635a2017-06-26 09:25:52 +020037 builder.addInfoItems(new CommandLogInfoItem());
38 }
39
40 @Override
41 public void beforeCommand(CommandEnvironment env) {
42 this.env = env;
43 }
44
45 @Override
46 public OutErr getOutputListener() {
47 Path commandLog = getCommandLogPath(env.getOutputBase());
48 // Unlink old command log from previous build, if present.
49 try {
50 commandLog.delete();
51 } catch (IOException ioException) {
52 LoggingUtil.logToRemote(Level.WARNING, "Unable to delete command.log", ioException);
53 }
54
55 try {
56 if (writeCommandLog(env.getRuntime()) && !"clean".equals(env.getCommandName())) {
57 logOutputStream = commandLog.getOutputStream();
58 return OutErr.create(logOutputStream, logOutputStream);
59 }
60 } catch (IOException ioException) {
61 LoggingUtil.logToRemote(Level.WARNING, "Unable to delete or open command.log", ioException);
62 }
63 return null;
64 }
65
66 static boolean writeCommandLog(BlazeRuntime runtime) {
juliexxiae91a4502018-08-15 14:42:29 -070067 OptionsParsingResult startupOptionsProvider = runtime.getStartupOptionsProvider();
ulfjack236635a2017-06-26 09:25:52 +020068 return startupOptionsProvider.getOptions(BlazeServerStartupOptions.class).writeCommandLog;
69 }
70
71 /**
72 * For a given output_base directory, returns the command log file path.
73 */
74 static Path getCommandLogPath(Path outputBase) {
75 return outputBase.getRelative("command.log");
76 }
77
78 @Override
buchgr0cf475a2018-10-08 11:20:22 -070079 public void commandComplete() {
ulfjack236635a2017-06-26 09:25:52 +020080 this.env = null;
81 if (logOutputStream != null) {
82 try {
83 logOutputStream.flush();
84 logOutputStream.close();
85 } catch (IOException e) {
86 throw new RuntimeException(e);
87 } finally {
88 logOutputStream = null;
89 }
90 }
91 }
92
93 /**
94 * Info item for the command log
95 */
96 public static final class CommandLogInfoItem extends InfoItem {
97 public CommandLogInfoItem() {
jingwen68c57f02018-11-21 16:17:17 -080098 super(
99 "command_log",
100 "Location of the log containing the output from the build commands.",
ulfjack236635a2017-06-26 09:25:52 +0200101 false);
102 }
103
104 @Override
105 public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env)
106 throws AbruptExitException {
107 checkNotNull(env);
108 return print(getCommandLogPath(env.getRuntime().getWorkspace().getOutputBase()));
109 }
110 }
111}