Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to capture console output from a service C#?

We have a C# service that is deployed to a remote customer system. The application writes a substantial amount of "diagnostic" information to the console (i.e. Console.WriteLine()). The service isn't "doing what it should." How can we capture the console output from the service in another application?

A WinForm version the application can be loaded at the customer location. It, unfortunately, functions correctly.

Update:

We are able to change the change the service, but would prefer not to make major changes at this time.

We are also logging to MSMQ, but only for "important" events. This service does interact with MSMQ for its normal operations. Or, at least, it should. The service doesn't seem to be pulling items from MSMQ when the WinForm version does. So, writing the messages that are going to the console could be problematic.

like image 622
Mike Chess Avatar asked Oct 14 '08 15:10

Mike Chess


3 Answers

Are you able to change the service code at all? If so, using Console.SetOut to write to a file instead would be the most obvious first port of call. Then change to using a proper logging library for the next release :)

like image 191
Jon Skeet Avatar answered Nov 02 '22 10:11

Jon Skeet


In general, you should avoid writing diagnostic information directly to Console, the Event Log, MSMQ or elsewhere from your application code. Instead call a logging API, and use configuration to redirect the output wherever you want.

For example, you could replace all the Console.WriteLine by Trace.WriteLine (*). Then you can redirect output to the console, a file or elsewhere by modifying the application configuration file: for example to output to the console, use a ConsoleTraceListener, something like:

<configuration>
  <system.diagnostics>
    <trace autoflush="false" indentsize="4">
      <listeners>
        <add name="configConsoleListener"
             type="System.Diagnostics.ConsoleTraceListener" />
      </listeners>
    </trace>
  </system.diagnostics>
 </configuration>

While debugging, you'll get your output on the console - on the customer site you'd configure it to redirect the trace output to a file, to the event log or similar.

Even better, use a 3rd party logging framework (I'd recommend Log4Net) which will give you more options than System.Diagnostics.Trace.

(*) Trace.Write/Trace.WriteLine are the same as Debug.Write/Debug.WriteLine, except that the latter are only compiled if the DEBUG symbol is defined. So prefer Trace to Debug if you want the output to be available in Release builds.

like image 36
Joe Avatar answered Nov 02 '22 10:11

Joe


You've got a bunch of options; redirecting console output to a file and using a proper logging library as mentioned are two good ones. Here's a middle option: write to the event log.

EventLog log;
string logsource = "MyService";

// execute once per invocation
if (!System.Diagnostics.EventLog.SourceExists(logsource))
{
    System.Diagnostics.EventLog.CreateEventSource(
        logsource, "Application");
}
log = new EventLog();
log.Source = logsource;
log.Log = "Application";

// replace console logging with this
log.WriteEntry(message, EventLogEntryType.Information);

Then look for entries in the Application event log (Administrative Tools -> Event Viewer) where Source = "MyService".

like image 23
Michael Petrotta Avatar answered Nov 02 '22 10:11

Michael Petrotta