Redirecting standard output using the -logFile parameter when in batchmode

Hi,

I am trying to redirect the standard output when running batch mode but it does not output, am i missing something out? I was under the impression that if i the executable was started with the -logFile parameter withput specifying a filename it would use StandardOutput. If that is the case i am doing something wrong, if not, how can i accomplish with i need?

I have a simple project setup in Visual Studio where i spawn a process of a unity game called Rust, or rather, its dedicated server.

As of now the only thing that shows up in the console (in VS) is these three lines:

Mono path[0] = 'E:/SteamCMD/servers/rust/RustDedicated_Data/Managed'
Mono path[1] = 'E:/SteamCMD/servers/rust/RustDedicated_Data/Mono'
Mono config path = 'E:/SteamCMD/servers/rust/RustDedicated_Data/Mono/etc'

Here are some code:

Process serverProcess;
private void StartServerThread()
{
    var serverArguments = GenerateServerArguments();
    var serverExecutable = Properties.Settings.Default.Rustserverexecutable;
    try
    {
        serverProcess = new Process {
            StartInfo = new ProcessStartInfo
            {
                WorkingDirectory = System.IO.Path.GetDirectoryName(serverExecutable),
                FileName = serverExecutable,
                Arguments = serverArguments,
                RedirectStandardInput = true,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                UseShellExecute = false
            }
        };
        serverProcess.OutputDataReceived += ServerProcess_OutputDataReceived;
        serverProcess.ErrorDataReceived += ServerProcess_ErrorDataReceived;
        serverProcess.Start();
        serverProcess.BeginOutputReadLine();
        serverProcess.BeginErrorReadLine();
        }
    catch (Exception e)
    {
        Console.WriteLine("Exception: " + e.Message);
    }
}

private void ServerProcess_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
    OutputToConsole(e.Data);
}
private void ServerProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
    OutputToConsole(e.Data);
}
void OutputToConsole(string msg)
{
    if (!string.IsNullOrEmpty(msg))
    {
        Console.WriteLine(msg);
    }  
}
1 Like

Hi,

passing “-logPath” argument without any path has no effect.

There isn’t a parameter that you can make Unity print everything to stdout by default, but you can subscribe to Application.logMessageReceivedThreaded callback and then print it anywhere you want.

Can you confirm that attaching to Application.logMessageReceived (the non-threaded version) will NOT trigger for Debug.Log calls performed on a background thread? That seems to be what I’m observing. If this is intended behaviour, the documentation should make it clear that you will miss background thread messages using Application.logMessageReceived.

1 Like

Correct.

I have this exact problem. Three mono lines and then nothing. What is the solution?

When I use console.writeline it outputs to the log file and not the starting process.

Setting the console to OpenStandardOutput does not appear to work either.

There is no way to redirect output to actual stdout. But as I mentioned, you can subscribe to that event and then send the output to your parent process whatever way you want.

Apart from the method that you suggested, is there going to be a way to output Unity’s log to stdout by default with Unity? Because many different forum posts, answers and blogs say that adding -logFile with no path produces this. As we are running TeamCity under the SYSTEM account on our build server, this makes the log inaccessible. We’ve redirected the path to the checkout directory, but it would make more sense if we could output to stdout so that the log is collected in TeamCity’s build log.
Cheers
Stormy

You can submit a feature request if you wish, but I don’t think we had anything planned.

For a short term solution, you subscribe to Application.logMessageReceivedThreaded and write to stdout from the callback.

1 Like

Thanks for the suggestion @Tautvydas-Zilys

Has anybody gotten

to work?

Ive tried putting the following code in my -executeMethod method:

Application.logMessageReceivedThreaded += (logString, stackTrace, logType) =>
        {
            System.IO.TextWriter writer = Console.Out;
            writer.WriteLine(logString);
            writer.WriteLine(stackTrace);
        };

I get no build logs to print out in the TeamCity build log window.

Passing “-logPath” in as an argument does work on Mac build machines. I get full logs in TC on mac with that.

Passing “-logPath -” will print build logs within a command window or powerShell window on a Windows machine, but I cant get any output to TeamCity on those Windows machines.

Anyone have any suggestions?

Thanks

3 Likes

https://github.com/Facepunch/Facepunch.UnityBatch
Try taking this and modifying it to your own needs. It means wrapping Unity’s output in a custom executable, but tbh it’s the easy way without having to do some seriously dodgy code within Unity :stuck_out_tongue:

Thanks @Stormy102 . Will give it a shot.

1 Like

I’m necroing this, now that the -logfile bug is reported fixed for 2019.1:

I’ve got some questions:

  1. They say “Logging now defaults to stdout on all platforms when running in batchmode. Note that on Windows, this still means output won’t go to console by default as Windows applications don’t have stdout handle by default. Output will, however, go to stdout if you launch Unity with a valid stdout handle. I.e. launching as a child process of a build system with redirected handles” Is there a way to launch Unity with a valid stdout handle from the Windows console or from a batch file, or is this feature only usable by writing a Windows application that spawns Unity as a child process?

  2. As implied by one of the comments on that page, is this feature only usable if the “-nographics” command line parameter is also used?

  1. Depends if you mean editor or player? For editor, I don’t know of an easy way to do this from Windows without spawning as a child process. We do have some ideas how to solve for this scenario in the future, so stay tuned on that. For player, if you build with “server build” option, the entry point executable used is built with /SUBSYSTEM:CONSOLE so Windows will create std handles for you by default, that direct to the console

  2. No, you can use logfile parameter on it’s own.

I did mean the editor. Thanks for the clarification!

I was able to tail an output file on my windows script:

“C:\Program Files\Unity\Hub\Editor\2019.2.21f1\Editor\Unity.exe” ^
-projectPath …/unity ^
-quit ^
-batchmode ^
-buildTarget %BUILD_TARGET% ^
-customBuildTarget %BUILD_TARGET% ^
-customBuildName %BUILD_NAME% ^
-customBuildPath %BUILD_PATH% ^
-executeMethod BuildCommand.PerformBuild ^
-logFile myTestLog.log | powershell -Command “& {Get-Content myTestLog.log -Wait}”

1 Like

This worked for me in my pipeline in an Azure DevOps build agent, my script included this to write logs to the output window:
Redirect STDOUT and STDERR on the Unity process when launching the build job:

$unityArgs = @{
            'FilePath' = $editor
            'PassThru' = $true
            'ArgumentList' = $psi.Arguments
            'ErrorAction' = 'Stop'
            'RedirectStandardOutput' = New-TemporaryFile
            'RedirectStandardError' = New-TemporaryFile
        }

Then added the PowerShell command after the process starts to read out to the Azure DevOps log window:

while ((Get-Process -Id $process.Id -ErrorAction SilentlyContinue) -ne ( $null )) {
            powershell -Command "& {Get-Content $logFile -Wait}"
            }

Specify where Unity writes the Editor or Windows/Linux/OSX standalone log file. To output to the console, specify - for the path name. On Windows, specify the - option to direct the output to stdout, which by default is not the console.

Unity Command line help says this is possible…but cannot get it to work.

Can you elaborate on this? What are you doing and what happens?

I was trying to test this via a simple Windows cmd. And with the -logFile - theres no redirect to stdout as the picture shows…8035808--1036172--CL1.jpg

I put the same args thru a C# console app and now it works…note how with C# I can change the RedirectStandardOutput.

Process p = new Process();
p.StartInfo.FileName = ConfigurationManager.AppSettings[“UnityEditorPath”];
p.StartInfo.Arguments = Arguments;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.OutputDataReceived += (sender, a) => ConsoleHelper.WriteText(" " + a.Data);
p.Start();
p.BeginOutputReadLine();
p.WaitForExit(); // This waits until the program called is closed

8035808--1036175--CL2.jpg

It really should be the default output to stdout - it’s what most command line utilities I’ve worked with do by default.

I hope this helps someone!