diff options
6 files changed, 113 insertions, 50 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java b/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java index 58a2b87b82..b860bda7dc 100644 --- a/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java +++ b/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java @@ -390,23 +390,6 @@ public class BlazeCommandDispatcher { } } - try { - Path commandLog = getCommandLogPath(workspace.getOutputBase()); - - // Unlink old command log from previous build, if present, so scripts - // reading it don't conflate it with the command log we're about to write. - closeSilently(logOutputStream); - logOutputStream = null; - commandLog.delete(); - - if (workspace.getRuntime().writeCommandLog() && commandAnnotation.writeCommandLog()) { - logOutputStream = commandLog.getOutputStream(); - outErr = tee(outErr, OutErr.create(logOutputStream, logOutputStream)); - } - } catch (IOException ioException) { - LoggingUtil.logToRemote(Level.WARNING, "Unable to delete or open command.log", ioException); - } - EventHandler eventHandler = new PrintingEventHandler(outErr, EventKind.ALL_EVENTS); ExitCode result = checkCwdInWorkspace(workspace, commandAnnotation, commandName, eventHandler); if (!result.equals(ExitCode.SUCCESS)) { @@ -721,13 +704,6 @@ public class BlazeCommandDispatcher { return message; } - /** - * For a given output_base directory, returns the command log file path. - */ - public static Path getCommandLogPath(Path outputBase) { - return outputBase.getRelative("command.log"); - } - private OutErr tee(OutErr outErr1, OutErr outErr2) { DelegatingOutErr outErr = new DelegatingOutErr(); outErr.addSink(outErr1); diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java b/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java index 15f22206e3..19a9e43f87 100644 --- a/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java +++ b/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java @@ -293,10 +293,6 @@ public final class BlazeRuntime { return getWorkspace().getDirectories().getOutputBase().getChild("server"); } - public boolean writeCommandLog() { - return startupOptionsProvider.getOptions(BlazeServerStartupOptions.class).writeCommandLog; - } - /** * Returns the {@link QueryEnvironmentFactory} that should be used to create a * {@link AbstractBlazeQueryEnvironment}, whenever one is needed. @@ -988,6 +984,7 @@ public final class BlazeRuntime { } runtimeBuilder.addBlazeModule(new BuiltinCommandModule()); + runtimeBuilder.addBlazeModule(new CommandLogModule()); for (BlazeModule blazeModule : blazeModules) { runtimeBuilder.addBlazeModule(blazeModule); } diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BlazeServerStartupOptions.java b/src/main/java/com/google/devtools/build/lib/runtime/BlazeServerStartupOptions.java index abfad43dff..02933499d4 100644 --- a/src/main/java/com/google/devtools/build/lib/runtime/BlazeServerStartupOptions.java +++ b/src/main/java/com/google/devtools/build/lib/runtime/BlazeServerStartupOptions.java @@ -323,6 +323,7 @@ public class BlazeServerStartupOptions extends OptionsBase { ) public boolean exoblaze; + // TODO(ulfjack): Make this a command option. @Option( name = "write_command_log", defaultValue = "true", diff --git a/src/main/java/com/google/devtools/build/lib/runtime/CommandLogModule.java b/src/main/java/com/google/devtools/build/lib/runtime/CommandLogModule.java new file mode 100644 index 0000000000..e0b3b60a34 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/runtime/CommandLogModule.java @@ -0,0 +1,110 @@ +// 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.runtime; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Supplier; +import com.google.devtools.build.lib.analysis.config.BuildConfiguration; +import com.google.devtools.build.lib.runtime.commands.InfoItem; +import com.google.devtools.build.lib.util.AbruptExitException; +import com.google.devtools.build.lib.util.LoggingUtil; +import com.google.devtools.build.lib.util.io.OutErr; +import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.common.options.OptionsProvider; +import java.io.IOException; +import java.io.OutputStream; +import java.util.logging.Level; + +/** This module logs complete stdout / stderr output of Bazel to a local file. */ +public class CommandLogModule extends BlazeModule { + private CommandEnvironment env; + private OutputStream logOutputStream; + + @Override + public void serverInit(OptionsProvider startupOptions, ServerBuilder builder) { + builder.addInfoItems(new CommandLogInfoItem()); + } + + @Override + public void beforeCommand(CommandEnvironment env) { + this.env = env; + } + + @Override + public OutErr getOutputListener() { + Path commandLog = getCommandLogPath(env.getOutputBase()); + // Unlink old command log from previous build, if present. + try { + commandLog.delete(); + } catch (IOException ioException) { + LoggingUtil.logToRemote(Level.WARNING, "Unable to delete command.log", ioException); + } + + try { + if (writeCommandLog(env.getRuntime()) && !"clean".equals(env.getCommandName())) { + logOutputStream = commandLog.getOutputStream(); + return OutErr.create(logOutputStream, logOutputStream); + } + } catch (IOException ioException) { + LoggingUtil.logToRemote(Level.WARNING, "Unable to delete or open command.log", ioException); + } + return null; + } + + static boolean writeCommandLog(BlazeRuntime runtime) { + OptionsProvider startupOptionsProvider = runtime.getStartupOptionsProvider(); + return startupOptionsProvider.getOptions(BlazeServerStartupOptions.class).writeCommandLog; + } + + /** + * For a given output_base directory, returns the command log file path. + */ + static Path getCommandLogPath(Path outputBase) { + return outputBase.getRelative("command.log"); + } + + @Override + public void afterCommand() { + this.env = null; + if (logOutputStream != null) { + try { + logOutputStream.flush(); + logOutputStream.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + logOutputStream = null; + } + } + } + + /** + * Info item for the command log + */ + public static final class CommandLogInfoItem extends InfoItem { + public CommandLogInfoItem() { + super("command_log", + "Location of the log containg the output from the build commands.", + false); + } + + @Override + public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) + throws AbruptExitException { + checkNotNull(env); + return print(getCommandLogPath(env.getRuntime().getWorkspace().getOutputBase())); + } + } +}
\ No newline at end of file diff --git a/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoCommand.java b/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoCommand.java index e62d65a6f6..27eb32c3fc 100644 --- a/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoCommand.java +++ b/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoCommand.java @@ -202,7 +202,6 @@ public class InfoCommand implements BlazeCommand { new InfoItem.BlazeBinInfoItem(productName), new InfoItem.BlazeGenfilesInfoItem(productName), new InfoItem.BlazeTestlogsInfoItem(productName), - new InfoItem.CommandLogInfoItem(), new InfoItem.MessageLogInfoItem(), new InfoItem.ReleaseInfoItem(productName), new InfoItem.ServerPidInfoItem(productName), diff --git a/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoItem.java b/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoItem.java index 52894e7a73..57de6f87b1 100644 --- a/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoItem.java +++ b/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoItem.java @@ -33,7 +33,6 @@ import com.google.devtools.build.lib.query2.proto.proto2api.Build.AllowedRuleCla import com.google.devtools.build.lib.query2.proto.proto2api.Build.AttributeDefinition; import com.google.devtools.build.lib.query2.proto.proto2api.Build.BuildLanguage; import com.google.devtools.build.lib.query2.proto.proto2api.Build.RuleDefinition; -import com.google.devtools.build.lib.runtime.BlazeCommandDispatcher; import com.google.devtools.build.lib.runtime.CommandEnvironment; import com.google.devtools.build.lib.util.AbruptExitException; import com.google.devtools.build.lib.util.ProcessUtils; @@ -102,7 +101,7 @@ public abstract class InfoItem { Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) throws AbruptExitException, InterruptedException; - private static byte[] print(Object value) { + protected static byte[] print(Object value) { if (value instanceof byte[]) { return (byte[]) value; } @@ -270,25 +269,6 @@ public abstract class InfoItem { } /** - * Info item for the command log - */ - public static final class CommandLogInfoItem extends InfoItem { - public CommandLogInfoItem() { - super("command_log", - "Location of the log containg the output from the build commands.", - false); - } - - @Override - public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) - throws AbruptExitException { - checkNotNull(env); - return print(BlazeCommandDispatcher.getCommandLogPath( - env.getRuntime().getWorkspace().getOutputBase())); - } - } - - /** * Info item for the message log */ public static final class MessageLogInfoItem extends InfoItem { |