[C#]Properly Separating Logs and Error Outputs in Console Applications

目次

Overview

In console application development, it is not recommended to mix normal execution logs and error information in the same output destination (standard output). In .NET, you can use the Console.Error property to send data to “Standard Error (stderr)” provided at the OS level. This allows for flexible control, such as leaving only errors on the screen when redirecting logs to a file or recording them in a separate file.

Specifications (Input/Output)

  • Input: The message you want to output as an error (string).
  • Output: Writing to the standard error output stream.
  • Characteristics: While the visual appearance on the screen is the same as standard output by default, the handling is different during pipeline processing or redirection.

Basic Usage

While the standard Console.WriteLine writes to standard output (stdout), Console.Error.WriteLine writes to standard error (stderr).

// Normal execution logs (stdout)
Console.WriteLine("Process started.");

// Error logs (stderr)
Console.Error.WriteLine("File not found.");

Full Code

The following is an implementation of a console application that separates messages for normal process flows and error messages for exceptions into their appropriate streams.

using System;

class Program
{
    static void Main()
    {
        Console.WriteLine("--- Data Processing Batch ---");

        try
        {
            // 1. Write to Standard Output (stdout)
            // Outputs normal logs, such as process progress.
            // If redirected using "> log.txt" in a shell, these will be saved to the file.
            Console.WriteLine("[INFO] Reading configuration file...");
            Console.WriteLine("[INFO] Checking database connection...");

            // Method call to simulate an error
            ProcessData();

            Console.WriteLine("[INFO] All processes completed successfully.");
        }
        catch (Exception ex)
        {
            // 2. Write to Standard Error (stderr)
            // Outputs abnormal terminations or warnings.
            // Messages remain on the console screen even during redirection, making it easier for operators to notice.
            Console.Error.WriteLine($"[ERROR] An unexpected failure occurred: {ex.Message}");
            
            // Set the exit code to 1 to indicate abnormal termination
            Environment.ExitCode = 1;
        }
    }

    static void ProcessData()
    {
        // Simulation of a heavy process or external call
        // Here, we forcibly throw an exception
        throw new InvalidOperationException("Connection to the external API timed out.");
    }
}

Execution Result Example

--- Data Processing Batch ---
[INFO] Reading configuration file...
[INFO] Checking database connection...
[ERROR] An unexpected failure occurred: Connection to the external API timed out.

Customization Points

  • Immediate Reflection of Output: Setting Console.Error.AutoFlush = true; flushes the buffer every time a write occurs. This is useful for ensuring logs are recorded immediately before an application crashes.
  • Verifying Redirection Behavior: If you run your application as MyApp.exe > output.log, the [INFO] lines go to the file, and only the [ERROR] line remains on the screen. To include errors in the same file, use MyApp.exe > output.log 2>&1.

Points of Caution

  • Limitations of Visibility: In a default console, both standard output and standard error use the same text color, making them hard to distinguish visually. You must change the color manually if visual distinction is needed.
  • Performance: Writing large volumes of data to Console.Error can affect processing speed because it is synchronous I/O. Use it carefully for high-volume debug logs.

Application

Extension Method to Use Red Text for Error Output

This helper implementation automatically changes the console text color when writing to standard error, helping operators recognize errors visually.

using System;

public static class ConsoleHelper
{
    public static void WriteError(string message)
    {
        // Save the current foreground color
        var originalColor = Console.ForegroundColor;
        
        // Change to error color (Red) and output to stderr
        Console.ForegroundColor = ConsoleColor.Red;
        Console.Error.WriteLine(message);
        
        // Restore the original color
        Console.ForegroundColor = originalColor;
    }
}

// Usage Example: ConsoleHelper.WriteError("Critical failure occurred");

Summary

By using Console.Error.WriteLine, you can clearly separate normal logs and error logs for better system monitoring and log collection. In cloud environments or container platforms like Docker and Kubernetes, it is standard practice to collect stdout and stderr separately, so using this method to route outputs correctly is highly recommended.

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次