Cleaned up logging in build server
This commit is contained in:
parent
f991b9ae48
commit
8b78b4f421
|
|
@ -71,6 +71,7 @@
|
|||
DebugTool="$(_RazorDebugTagHelperTool)"
|
||||
ToolAssembly="$(_RazorToolAssembly)"
|
||||
UseServer="$(UseRazorBuildServer)"
|
||||
ForceServer="$(_RazorForceBuildServer)"
|
||||
PipeName="$(_RazorBuildServerPipeName)"
|
||||
Assemblies="@(RazorReferencePath)"
|
||||
ProjectRoot="$(MSBuildProjectDirectory)"
|
||||
|
|
@ -118,6 +119,7 @@
|
|||
DebugTool="$(_RazorDebugGenerateCodeTool)"
|
||||
ToolAssembly="$(_RazorToolAssembly)"
|
||||
UseServer="$(UseRazorBuildServer)"
|
||||
ForceServer="$(_RazorForceBuildServer)"
|
||||
PipeName="$(_RazorBuildServerPipeName)"
|
||||
Sources="@(RazorGenerateWithTargetPath)"
|
||||
ProjectRoot="$(MSBuildProjectDirectory)"
|
||||
|
|
|
|||
|
|
@ -5,14 +5,11 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Microsoft.AspNetCore.Razor.Tools;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
using Microsoft.CodeAnalysis.CommandLine;
|
||||
using Microsoft.Extensions.CommandLineUtils;
|
||||
using Roslyn.Utilities;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Tasks
|
||||
{
|
||||
|
|
@ -29,6 +26,9 @@ namespace Microsoft.AspNetCore.Razor.Tasks
|
|||
|
||||
public bool UseServer { get; set; }
|
||||
|
||||
// Specifies whether we should fallback to in-process execution if server execution fails.
|
||||
public bool ForceServer { get; set; }
|
||||
|
||||
public string PipeName { get; set; }
|
||||
|
||||
protected override string ToolName => "dotnet";
|
||||
|
|
@ -115,11 +115,11 @@ namespace Microsoft.AspNetCore.Razor.Tasks
|
|||
string commandLineCommands,
|
||||
out int result)
|
||||
{
|
||||
CompilerServerLogger.Log("Server execution started.");
|
||||
Log.LogMessage(StandardOutputLoggingImportance, "Server execution started.");
|
||||
using (_razorServerCts = new CancellationTokenSource())
|
||||
{
|
||||
CompilerServerLogger.Log($"CommandLine = '{commandLineCommands}'");
|
||||
CompilerServerLogger.Log($"ServerResponseFile = '{responseFileCommands}'");
|
||||
Log.LogMessage(StandardOutputLoggingImportance, $"CommandLine = '{commandLineCommands}'");
|
||||
Log.LogMessage(StandardOutputLoggingImportance, $"ServerResponseFile = '{responseFileCommands}'");
|
||||
|
||||
// The server contains the tools for discovering tag helpers and generating Razor code.
|
||||
var clientDir = Path.GetDirectoryName(ToolAssembly);
|
||||
|
|
@ -141,14 +141,35 @@ namespace Microsoft.AspNetCore.Razor.Tasks
|
|||
{
|
||||
result = completedResponse.ReturnCode;
|
||||
|
||||
CompilerServerLogger.Log($"Server execution completed with return code {result}.");
|
||||
if (result == 0)
|
||||
{
|
||||
Log.LogMessage(StandardOutputLoggingImportance, $"Server execution completed with return code {result}.");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.LogMessage(
|
||||
StandardOutputLoggingImportance,
|
||||
$"Server execution completed with return code {result}. For more info, check the server log file in the location specified by the RAZORBUILDSERVER_LOG environment variable.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.LogMessage(
|
||||
StandardOutputLoggingImportance,
|
||||
$"Server execution failed with response {response.Type}. For more info, check the server log file in the location specified by the RAZORBUILDSERVER_LOG environment variable.");
|
||||
}
|
||||
|
||||
result = -1;
|
||||
|
||||
if (ForceServer)
|
||||
{
|
||||
// We don't want to fallback to in-process execution.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
CompilerServerLogger.Log("Server execution failed.");
|
||||
result = -1;
|
||||
Log.LogMessage(StandardOutputLoggingImportance, "Fallback to in-process execution.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,12 +16,6 @@
|
|||
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="$(MicrosoftBuildUtilitiesCorePackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.CommandLineUtils.Sources" Version="$(MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion)" />
|
||||
|
||||
<Compile Include="..\Microsoft.AspNetCore.Razor.Tools\Roslyn\CompilerServerLogger.cs">
|
||||
<Link>Shared\CompilerServerLogger.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Microsoft.AspNetCore.Razor.Tools\Roslyn\PlatformInformation.cs">
|
||||
<Link>Shared\PlatformInformation.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Microsoft.AspNetCore.Razor.Tools\ServerProtocol\*.cs">
|
||||
<Link>Shared\ServerProtocol\%(FileName)</Link>
|
||||
</Compile>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ using System.IO;
|
|||
using System.IO.Pipes;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.CodeAnalysis.CommandLine;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Tools
|
||||
{
|
||||
|
|
@ -39,12 +38,12 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
// Machine-local named pipes are named "\\.\pipe\<pipename>".
|
||||
// We use the SHA1 of the directory the compiler exes live in as the pipe name.
|
||||
// The NamedPipeClientStream class handles the "\\.\pipe\" part for us.
|
||||
CompilerServerLogger.Log("Attempt to open named pipe '{0}'", pipeName);
|
||||
ServerLogger.Log("Attempt to open named pipe '{0}'", pipeName);
|
||||
|
||||
var stream = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.Asynchronous);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
CompilerServerLogger.Log("Attempt to connect named pipe '{0}'", pipeName);
|
||||
ServerLogger.Log("Attempt to connect named pipe '{0}'", pipeName);
|
||||
try
|
||||
{
|
||||
await stream.ConnectAsync(timeoutMilliseconds, cancellationToken);
|
||||
|
|
@ -55,11 +54,11 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
// From docs:
|
||||
// - TimeoutException: Could not connect to the server within the specified timeout period.
|
||||
// - IOException: The server is connected to another client and the time-out period has expired.
|
||||
CompilerServerLogger.Log($"Connecting to server timed out after {timeoutMilliseconds} ms");
|
||||
ServerLogger.Log($"Connecting to server timed out after {timeoutMilliseconds} ms");
|
||||
return null;
|
||||
}
|
||||
|
||||
CompilerServerLogger.Log("Named pipe '{0}' connected", pipeName);
|
||||
ServerLogger.Log("Named pipe '{0}' connected", pipeName);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
// The original code in Roslyn checks that the server pipe is owned by the same user for security.
|
||||
|
|
@ -70,7 +69,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
}
|
||||
catch (Exception e) when (!(e is TaskCanceledException || e is OperationCanceledException))
|
||||
{
|
||||
CompilerServerLogger.LogException(e, "Exception while connecting to process");
|
||||
ServerLogger.LogException(e, "Exception while connecting to process");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -108,9 +107,9 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
|
||||
try
|
||||
{
|
||||
CompilerServerLogger.Log($"Before poking pipe {Identifier}.");
|
||||
ServerLogger.Log($"Before poking pipe {Identifier}.");
|
||||
await Stream.ReadAsync(Array.Empty<byte>(), 0, 0, cancellationToken);
|
||||
CompilerServerLogger.Log($"After poking pipe {Identifier}.");
|
||||
ServerLogger.Log($"After poking pipe {Identifier}.");
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
|
|
@ -119,7 +118,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
{
|
||||
// It is okay for this call to fail. Errors will be reflected in the
|
||||
// IsConnected property which will be read on the next iteration.
|
||||
CompilerServerLogger.LogException(e, $"Error poking pipe {Identifier}.");
|
||||
ServerLogger.LogException(e, $"Error poking pipe {Identifier}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Microsoft.CodeAnalysis.CommandLine;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Tools
|
||||
{
|
||||
|
|
@ -26,13 +26,33 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
return new RejectedServerResponse();
|
||||
}
|
||||
|
||||
var exitCode = 0;
|
||||
var output = string.Empty;
|
||||
var app = new Application(cancellationToken);
|
||||
var commandArgs = parsed.args.ToArray();
|
||||
|
||||
var exitCode = app.Execute(commandArgs);
|
||||
var output = app.Out.ToString() ?? string.Empty;
|
||||
if (ServerLogger.IsLoggingEnabled)
|
||||
{
|
||||
using (var writer = new StringWriter())
|
||||
{
|
||||
app.Out = writer;
|
||||
app.Error = writer;
|
||||
exitCode = app.Execute(commandArgs);
|
||||
output = writer.ToString();
|
||||
ServerLogger.Log(output);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var writer = new StreamWriter(Stream.Null))
|
||||
{
|
||||
app.Out = writer;
|
||||
app.Error = writer;
|
||||
exitCode = app.Execute(commandArgs);
|
||||
}
|
||||
}
|
||||
|
||||
return new CompletedServerResponse(exitCode, utf8output: false, output: output);
|
||||
return new CompletedServerResponse(exitCode, utf8output: false, output: string.Empty);
|
||||
}
|
||||
|
||||
private bool TryParseArguments(ServerRequest request, out (string workingDirectory, string tempDirectory, string[] args) parsed)
|
||||
|
|
@ -59,16 +79,16 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
}
|
||||
}
|
||||
|
||||
CompilerServerLogger.Log($"WorkingDirectory = '{workingDirectory}'");
|
||||
CompilerServerLogger.Log($"TempDirectory = '{tempDirectory}'");
|
||||
ServerLogger.Log($"WorkingDirectory = '{workingDirectory}'");
|
||||
ServerLogger.Log($"TempDirectory = '{tempDirectory}'");
|
||||
for (var i = 0; i < args.Count; i++)
|
||||
{
|
||||
CompilerServerLogger.Log($"Argument[{i}] = '{request.Arguments[i]}'");
|
||||
ServerLogger.Log($"Argument[{i}] = '{request.Arguments[i]}'");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(workingDirectory))
|
||||
{
|
||||
CompilerServerLogger.Log($"Rejecting build due to missing working directory");
|
||||
ServerLogger.Log($"Rejecting build due to missing working directory");
|
||||
|
||||
parsed = default;
|
||||
return false;
|
||||
|
|
@ -76,7 +96,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
|
||||
if (string.IsNullOrEmpty(tempDirectory))
|
||||
{
|
||||
CompilerServerLogger.Log($"Rejecting build due to missing temp directory");
|
||||
ServerLogger.Log($"Rejecting build due to missing temp directory");
|
||||
|
||||
parsed = default;
|
||||
return false;
|
||||
|
|
@ -84,7 +104,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
|
||||
if (string.IsNullOrEmpty(tempDirectory))
|
||||
{
|
||||
CompilerServerLogger.Log($"Rejecting build due to missing temp directory");
|
||||
ServerLogger.Log($"Rejecting build due to missing temp directory");
|
||||
|
||||
parsed = default;
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ using System.IO;
|
|||
using System.IO.Pipes;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.CodeAnalysis.CommandLine;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Tools
|
||||
{
|
||||
|
|
@ -58,13 +57,13 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
PipeBufferSize, // Default input buffer
|
||||
PipeBufferSize);// Default output buffer
|
||||
|
||||
CompilerServerLogger.Log("Waiting for new connection");
|
||||
ServerLogger.Log("Waiting for new connection");
|
||||
await pipeStream.WaitForConnectionAsync(cancellationToken);
|
||||
CompilerServerLogger.Log("Pipe connection detected.");
|
||||
ServerLogger.Log("Pipe connection detected.");
|
||||
|
||||
if (Environment.Is64BitProcess || Memory.IsMemoryAvailable())
|
||||
{
|
||||
CompilerServerLogger.Log("Memory available - accepting connection");
|
||||
ServerLogger.Log("Memory available - accepting connection");
|
||||
return new NamedPipeConnection(pipeStream, GetNextIdentifier());
|
||||
}
|
||||
|
||||
|
|
@ -96,9 +95,9 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
|
||||
try
|
||||
{
|
||||
CompilerServerLogger.Log($"Before poking pipe {Identifier}.");
|
||||
ServerLogger.Log($"Before poking pipe {Identifier}.");
|
||||
await Stream.ReadAsync(Array.Empty<byte>(), 0, 0, cancellationToken);
|
||||
CompilerServerLogger.Log($"After poking pipe {Identifier}.");
|
||||
ServerLogger.Log($"After poking pipe {Identifier}.");
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
|
|
@ -107,14 +106,14 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
{
|
||||
// It is okay for this call to fail. Errors will be reflected in the
|
||||
// IsConnected property which will be read on the next iteration.
|
||||
CompilerServerLogger.LogException(e, $"Error poking pipe {Identifier}.");
|
||||
ServerLogger.LogException(e, $"Error poking pipe {Identifier}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
CompilerServerLogger.Log($"Pipe {Identifier}: Closing.");
|
||||
ServerLogger.Log($"Pipe {Identifier}: Closing.");
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -126,7 +125,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
// for which we can no longer communicate and that's okay because the Close method indicates we are
|
||||
// done with the client already.
|
||||
var message = string.Format($"Pipe {Identifier}: Error closing pipe.");
|
||||
CompilerServerLogger.LogException(ex, message);
|
||||
ServerLogger.LogException(ex, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ using System.Linq;
|
|||
using System.Runtime;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.CodeAnalysis.CommandLine;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Tools
|
||||
{
|
||||
|
|
@ -318,7 +317,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
{
|
||||
// Unable to establish a connection with the client. The client is responsible for
|
||||
// handling this case. Nothing else for us to do here.
|
||||
CompilerServerLogger.LogException(ex, "Error creating client named pipe");
|
||||
ServerLogger.LogException(ex, "Error creating client named pipe");
|
||||
return new ConnectionResult(ConnectionResult.Reason.CompilationNotStarted);
|
||||
}
|
||||
|
||||
|
|
@ -329,13 +328,13 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
ServerRequest request;
|
||||
try
|
||||
{
|
||||
CompilerServerLogger.Log("Begin reading request.");
|
||||
ServerLogger.Log("Begin reading request.");
|
||||
request = await ServerRequest.ReadAsync(connection.Stream, cancellationToken).ConfigureAwait(false);
|
||||
CompilerServerLogger.Log("End reading request.");
|
||||
ServerLogger.Log("End reading request.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
CompilerServerLogger.LogException(e, "Error reading build request.");
|
||||
ServerLogger.LogException(e, "Error reading build request.");
|
||||
return new ConnectionResult(ConnectionResult.Reason.CompilationNotStarted);
|
||||
}
|
||||
|
||||
|
|
@ -379,9 +378,9 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
|
||||
try
|
||||
{
|
||||
CompilerServerLogger.Log("Begin writing response.");
|
||||
ServerLogger.Log("Begin writing response.");
|
||||
await response.WriteAsync(connection.Stream, cancellationToken);
|
||||
CompilerServerLogger.Log("End writing response.");
|
||||
ServerLogger.Log("End writing response.");
|
||||
|
||||
reason = ConnectionResult.Reason.CompilationCompleted;
|
||||
}
|
||||
|
|
@ -405,7 +404,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CompilerServerLogger.LogException(ex, "Error handling connection");
|
||||
ServerLogger.LogException(ex, "Error handling connection");
|
||||
return new ConnectionResult(ConnectionResult.Reason.ClientException);
|
||||
}
|
||||
}
|
||||
|
|
@ -414,11 +413,11 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
{
|
||||
Func<ServerResponse> func = () =>
|
||||
{
|
||||
CompilerServerLogger.Log("Begin processing request");
|
||||
ServerLogger.Log("Begin processing request");
|
||||
|
||||
var response = _compilerHost.Execute(buildRequest, cancellationToken);
|
||||
|
||||
CompilerServerLogger.Log("End processing request");
|
||||
ServerLogger.Log("End processing request");
|
||||
return response;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace Roslyn.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// This class provides simple properties for determining whether the current platform is Windows or Unix-based.
|
||||
/// We intentionally do not use System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(...) because
|
||||
/// it incorrectly reports 'true' for 'Windows' in desktop builds running on Unix-based platforms via Mono.
|
||||
/// </summary>
|
||||
internal static class PlatformInformation
|
||||
{
|
||||
public static bool IsWindows => Path.DirectorySeparatorChar == '\\';
|
||||
public static bool IsUnix => Path.DirectorySeparatorChar == '/';
|
||||
}
|
||||
}
|
||||
|
|
@ -8,8 +8,6 @@ using System.Runtime.InteropServices;
|
|||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Roslyn.Utilities;
|
||||
using static Microsoft.CodeAnalysis.CommandLine.CompilerServerLogger;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Tools
|
||||
{
|
||||
|
|
@ -204,26 +202,26 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
// Write the request
|
||||
try
|
||||
{
|
||||
Log("Begin writing request");
|
||||
ServerLogger.Log("Begin writing request");
|
||||
await request.WriteAsync(client.Stream, cancellationToken).ConfigureAwait(false);
|
||||
Log("End writing request");
|
||||
ServerLogger.Log("End writing request");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogException(e, "Error writing build request.");
|
||||
ServerLogger.LogException(e, "Error writing build request.");
|
||||
return new RejectedServerResponse();
|
||||
}
|
||||
|
||||
// Wait for the compilation and a monitor to detect if the server disconnects
|
||||
var serverCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
|
||||
|
||||
Log("Begin reading response");
|
||||
ServerLogger.Log("Begin reading response");
|
||||
|
||||
var responseTask = ServerResponse.ReadAsync(client.Stream, serverCts.Token);
|
||||
var monitorTask = client.WaitForDisconnectAsync(serverCts.Token);
|
||||
await Task.WhenAny(responseTask, monitorTask).ConfigureAwait(false);
|
||||
|
||||
Log("End reading response");
|
||||
ServerLogger.Log("End reading response");
|
||||
|
||||
if (responseTask.IsCompleted)
|
||||
{
|
||||
|
|
@ -234,13 +232,13 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogException(e, "Error reading response");
|
||||
ServerLogger.LogException(e, "Error reading response");
|
||||
response = new RejectedServerResponse();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("Server disconnect");
|
||||
ServerLogger.Log("Server disconnect");
|
||||
response = new RejectedServerResponse();
|
||||
}
|
||||
|
||||
|
|
@ -282,7 +280,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
startInfo.dwFlags = NativeMethods.STARTF_USESTDHANDLES;
|
||||
var dwCreationFlags = NativeMethods.NORMAL_PRIORITY_CLASS | NativeMethods.CREATE_NO_WINDOW;
|
||||
|
||||
Log("Attempting to create process '{0}'", expectedPath);
|
||||
ServerLogger.Log("Attempting to create process '{0}'", expectedPath);
|
||||
|
||||
var builder = new StringBuilder($@"""{expectedPath}"" {processArguments}");
|
||||
|
||||
|
|
@ -300,13 +298,13 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
|
||||
if (success)
|
||||
{
|
||||
Log("Successfully created process with process id {0}", processInfo.dwProcessId);
|
||||
ServerLogger.Log("Successfully created process with process id {0}", processInfo.dwProcessId);
|
||||
NativeMethods.CloseHandle(processInfo.hProcess);
|
||||
NativeMethods.CloseHandle(processInfo.hThread);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("Failed to create process. GetLastError={0}", Marshal.GetLastWin32Error());
|
||||
ServerLogger.Log("Failed to create process. GetLastError={0}", Marshal.GetLastWin32Error());
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
|
@ -336,4 +334,15 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This class provides simple properties for determining whether the current platform is Windows or Unix-based.
|
||||
/// We intentionally do not use System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(...) because
|
||||
/// it incorrectly reports 'true' for 'Windows' in desktop builds running on Unix-based platforms via Mono.
|
||||
/// </summary>
|
||||
internal static class PlatformInformation
|
||||
{
|
||||
public static bool IsWindows => Path.DirectorySeparatorChar == '\\';
|
||||
public static bool IsUnix => Path.DirectorySeparatorChar == '/';
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +1,22 @@
|
|||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Roslyn.Utilities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.CommandLine
|
||||
namespace Microsoft.AspNetCore.Razor.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// Class for logging information about what happens in the server and client parts of the
|
||||
/// Roslyn command line compiler and build tasks. Useful for debugging what is going on.
|
||||
/// Razor command line compiler and build tasks. Useful for debugging what is going on.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// To use the logging, set the environment variable RoslynCommandLineLogFile to the name
|
||||
/// To use the logging, set the environment variable RAZORBUILDSERVER_LOG to the name
|
||||
/// of a file to log to. This file is logged to by both client and server components.
|
||||
/// </remarks>
|
||||
internal class CompilerServerLogger
|
||||
internal class ServerLogger
|
||||
{
|
||||
// Environment variable, if set, to enable logging and set the file to log to.
|
||||
private const string EnvironmentVariable = "RAZORBUILDSERVER_LOG";
|
||||
|
|
@ -30,17 +27,19 @@ namespace Microsoft.CodeAnalysis.CommandLine
|
|||
/// <summary>
|
||||
/// Static class initializer that initializes logging.
|
||||
/// </summary>
|
||||
static CompilerServerLogger()
|
||||
static ServerLogger()
|
||||
{
|
||||
s_loggingStream = null;
|
||||
|
||||
try
|
||||
{
|
||||
// Check if the environment
|
||||
string loggingFileName = Environment.GetEnvironmentVariable(EnvironmentVariable);
|
||||
var loggingFileName = Environment.GetEnvironmentVariable(EnvironmentVariable);
|
||||
|
||||
if (loggingFileName != null)
|
||||
{
|
||||
IsLoggingEnabled = true;
|
||||
|
||||
// If the environment variable contains the path of a currently existing directory,
|
||||
// then use a process-specific name for the log file and put it in that directory.
|
||||
// Otherwise, assume that the environment variable specifies the name of the log file.
|
||||
|
|
@ -59,6 +58,8 @@ namespace Microsoft.CodeAnalysis.CommandLine
|
|||
}
|
||||
}
|
||||
|
||||
public static bool IsLoggingEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Set the logging prefix that describes our role.
|
||||
/// Typically a 3-letter abbreviation. If logging happens before this, it's logged with "---".
|
||||
|
|
@ -73,11 +74,11 @@ namespace Microsoft.CodeAnalysis.CommandLine
|
|||
/// </summary>
|
||||
public static void LogException(Exception e, string reason)
|
||||
{
|
||||
if (s_loggingStream != null)
|
||||
if (IsLoggingEnabled)
|
||||
{
|
||||
Log("Exception '{0}' occurred during '{1}'. Stack trace:\r\n{2}", e.Message, reason, e.StackTrace);
|
||||
|
||||
int innerExceptionLevel = 0;
|
||||
var innerExceptionLevel = 0;
|
||||
|
||||
e = e.InnerException;
|
||||
while (e != null)
|
||||
|
|
@ -94,7 +95,7 @@ namespace Microsoft.CodeAnalysis.CommandLine
|
|||
/// </summary>
|
||||
public static void Log(string format, params object[] arguments)
|
||||
{
|
||||
if (s_loggingStream != null)
|
||||
if (IsLoggingEnabled)
|
||||
{
|
||||
Log(string.Format(format, arguments));
|
||||
}
|
||||
|
|
@ -106,12 +107,12 @@ namespace Microsoft.CodeAnalysis.CommandLine
|
|||
/// <param name="message"></param>
|
||||
public static void Log(string message)
|
||||
{
|
||||
if (s_loggingStream != null)
|
||||
if (IsLoggingEnabled)
|
||||
{
|
||||
string prefix = GetLoggingPrefix();
|
||||
var prefix = GetLoggingPrefix();
|
||||
|
||||
string output = prefix + message + "\r\n";
|
||||
byte[] bytes = Encoding.UTF8.GetBytes(output);
|
||||
var output = prefix + message + "\r\n";
|
||||
var bytes = Encoding.UTF8.GetBytes(output);
|
||||
|
||||
// Because multiple processes might be logging to the same file, we always seek to the end,
|
||||
// write, and flush.
|
||||
|
|
@ -4,7 +4,6 @@
|
|||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.CodeAnalysis.CommandLine;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Tools
|
||||
{
|
||||
|
|
@ -49,7 +48,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
var totalBytesRead = 0;
|
||||
do
|
||||
{
|
||||
CompilerServerLogger.Log("Attempting to read {0} bytes from the stream", count - totalBytesRead);
|
||||
ServerLogger.Log("Attempting to read {0} bytes from the stream", count - totalBytesRead);
|
||||
var bytesRead = await stream.ReadAsync(
|
||||
buffer,
|
||||
totalBytesRead,
|
||||
|
|
@ -59,13 +58,13 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
|
||||
if (bytesRead == 0)
|
||||
{
|
||||
CompilerServerLogger.Log("Unexpected -- read 0 bytes from the stream.");
|
||||
ServerLogger.Log("Unexpected -- read 0 bytes from the stream.");
|
||||
throw new EndOfStreamException("Reached end of stream before end of read.");
|
||||
}
|
||||
CompilerServerLogger.Log("Read {0} bytes", bytesRead);
|
||||
ServerLogger.Log("Read {0} bytes", bytesRead);
|
||||
totalBytesRead += bytesRead;
|
||||
} while (totalBytesRead < count);
|
||||
CompilerServerLogger.Log("Finished read");
|
||||
ServerLogger.Log("Finished read");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ using System.Linq;
|
|||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using static Microsoft.CodeAnalysis.CommandLine.CompilerServerLogger;
|
||||
|
||||
// After the server pipe is connected, it forks off a thread to handle the connection, and creates
|
||||
// a new instance of the pipe to listen for new clients. When it gets a request, it validates
|
||||
|
|
@ -84,9 +83,9 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
IList<string> args,
|
||||
string keepAlive = null)
|
||||
{
|
||||
Log("Creating ServerRequest");
|
||||
Log($"Working directory: {workingDirectory}");
|
||||
Log($"Temp directory: {tempDirectory}");
|
||||
ServerLogger.Log("Creating ServerRequest");
|
||||
ServerLogger.Log($"Working directory: {workingDirectory}");
|
||||
ServerLogger.Log($"Temp directory: {tempDirectory}");
|
||||
|
||||
var requestLength = args.Count + 1;
|
||||
var requestArgs = new List<RequestArgument>(requestLength)
|
||||
|
|
@ -103,7 +102,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
for (var i = 0; i < args.Count; ++i)
|
||||
{
|
||||
var arg = args[i];
|
||||
Log($"argument[{i}] = {arg}");
|
||||
ServerLogger.Log($"argument[{i}] = {arg}");
|
||||
requestArgs.Add(new RequestArgument(RequestArgument.ArgumentId.CommandLineArgument, i, arg));
|
||||
}
|
||||
|
||||
|
|
@ -130,14 +129,14 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
{
|
||||
// Read the length of the request
|
||||
var lengthBuffer = new byte[4];
|
||||
Log("Reading length of request");
|
||||
ServerLogger.Log("Reading length of request");
|
||||
await ServerProtocol.ReadAllAsync(inStream, lengthBuffer, 4, cancellationToken).ConfigureAwait(false);
|
||||
var length = BitConverter.ToInt32(lengthBuffer, 0);
|
||||
|
||||
// Back out if the request is > 1MB
|
||||
if (length > 0x100000)
|
||||
{
|
||||
Log("Request is over 1MB in length, cancelling read.");
|
||||
ServerLogger.Log("Request is over 1MB in length, cancelling read.");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -149,7 +148,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
Log("Parsing request");
|
||||
ServerLogger.Log("Parsing request");
|
||||
// Parse the request into the Request data structure.
|
||||
using (var reader = new BinaryReader(new MemoryStream(requestBuffer), Encoding.Unicode))
|
||||
{
|
||||
|
|
@ -177,7 +176,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
using (var writer = new BinaryWriter(memoryStream, Encoding.Unicode))
|
||||
{
|
||||
// Format the request.
|
||||
Log("Formatting request");
|
||||
ServerLogger.Log("Formatting request");
|
||||
writer.Write(ProtocolVersion);
|
||||
writer.Write(Arguments.Count);
|
||||
foreach (var arg in Arguments)
|
||||
|
|
@ -195,17 +194,17 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
// Back out if the request is > 1 MB
|
||||
if (memoryStream.Length > 0x100000)
|
||||
{
|
||||
Log("Request is over 1MB in length, cancelling write");
|
||||
ServerLogger.Log("Request is over 1MB in length, cancelling write");
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
// Send the request to the server
|
||||
Log("Writing length of request.");
|
||||
ServerLogger.Log("Writing length of request.");
|
||||
await outStream
|
||||
.WriteAsync(BitConverter.GetBytes(length), 0, 4, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
Log("Writing request of size {0}", length);
|
||||
ServerLogger.Log("Writing request of size {0}", length);
|
||||
// Write the request
|
||||
memoryStream.Position = 0;
|
||||
await memoryStream
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ using System.IO;
|
|||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using static Microsoft.CodeAnalysis.CommandLine.CompilerServerLogger;
|
||||
|
||||
// After the server pipe is connected, it forks off a thread to handle the connection, and creates
|
||||
// a new instance of the pipe to listen for new clients. When it gets a request, it validates
|
||||
|
|
@ -55,7 +54,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
using (var writer = new BinaryWriter(memoryStream, Encoding.Unicode))
|
||||
{
|
||||
// Format the response
|
||||
Log("Formatting Response");
|
||||
ServerLogger.Log("Formatting Response");
|
||||
writer.Write((int)Type);
|
||||
|
||||
AddResponseBody(writer);
|
||||
|
|
@ -68,7 +67,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
// Write the length of the response
|
||||
var length = checked((int)memoryStream.Length);
|
||||
|
||||
Log("Writing response length");
|
||||
ServerLogger.Log("Writing response length");
|
||||
// There is no way to know the number of bytes written to
|
||||
// the pipe stream. We just have to assume all of them are written.
|
||||
await outStream
|
||||
|
|
@ -76,7 +75,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
.ConfigureAwait(false);
|
||||
|
||||
// Write the response
|
||||
Log("Writing response of size {0}", length);
|
||||
ServerLogger.Log("Writing response of size {0}", length);
|
||||
memoryStream.Position = 0;
|
||||
await memoryStream
|
||||
.CopyToAsync(outStream, bufferSize: length, cancellationToken: cancellationToken)
|
||||
|
|
@ -94,14 +93,14 @@ namespace Microsoft.AspNetCore.Razor.Tools
|
|||
/// <returns></returns>
|
||||
public static async Task<ServerResponse> ReadAsync(Stream stream, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
Log("Reading response length");
|
||||
ServerLogger.Log("Reading response length");
|
||||
// Read the response length
|
||||
var lengthBuffer = new byte[4];
|
||||
await ServerProtocol.ReadAllAsync(stream, lengthBuffer, 4, cancellationToken).ConfigureAwait(false);
|
||||
var length = BitConverter.ToUInt32(lengthBuffer, 0);
|
||||
|
||||
// Read the response
|
||||
Log("Reading response of length {0}", length);
|
||||
ServerLogger.Log("Reading response of length {0}", length);
|
||||
var responseBuffer = new byte[length];
|
||||
await ServerProtocol.ReadAllAsync(
|
||||
stream,
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
{
|
||||
var result = await DotnetMSBuild(
|
||||
"Build",
|
||||
$"/p:RazorCompileOnBuild=true /p:UseRazorBuildServer=true /p:_RazorBuildServerPipeName={_pipeName}",
|
||||
$"/p:RazorCompileOnBuild=true /p:UseRazorBuildServer=true /p:_RazorBuildServerPipeName={_pipeName} /p:_RazorForceBuildServer=true",
|
||||
msBuildProcessKind: msBuildProcessKind);
|
||||
|
||||
Assert.BuildPassed(result);
|
||||
|
|
@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
{
|
||||
var result = await DotnetMSBuild(
|
||||
"Build",
|
||||
$"/p:RazorCompileOnBuild=true /p:UseRazorBuildServer=true /p:_RazorBuildServerPipeName={_pipeName}");
|
||||
$"/p:RazorCompileOnBuild=true /p:UseRazorBuildServer=true /p:_RazorBuildServerPipeName={_pipeName} /p:_RazorForceBuildServer=true");
|
||||
|
||||
Assert.BuildPassed(result);
|
||||
Assert.FileExists(result, OutputPath, "SimpleMvc.dll");
|
||||
|
|
@ -55,7 +55,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
|
|||
{
|
||||
var result = await DotnetMSBuild(
|
||||
"Build",
|
||||
$"/p:RazorCompileOnBuild=true /p:UseRazorBuildServer=true /p:_RazorBuildServerPipeName={_pipeName}");
|
||||
$"/p:RazorCompileOnBuild=true /p:UseRazorBuildServer=true /p:_RazorBuildServerPipeName={_pipeName} /p:_RazorForceBuildServer=true");
|
||||
|
||||
Assert.BuildPassed(result);
|
||||
Assert.FileExists(result, OutputPath, "Whitespace in name.dll");
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.CodeAnalysis.CommandLine;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Tools
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue