views:

406

answers:

7

What would be the best method of recording to a log(.txt) from a console program? My program loops multiple times always outputting different data based on what the user wants, so im searching for the best, most efficient way to achieve this.

i know i can always reopen a stream and then close it, but everytime i do that it would be writing just one line, then next time around (seconds later) the program reloops and needs tor write again, imo that doesnt seem very resourse friendly.

using c#; using .net2.2; :)

+13  A: 

Consider using log4net.

smink
+3  A: 

I accept the performance hit that comes with opening and closing every time I write a line. It is a reliability decision. If you are holding everything in memory and you have a hard crash, you have no log information at all to help troubleshoot. If this is not a concern for you, then holding it in memory will definitely provide better performance.

EBGreen
A: 

A simple approach would be to provide a TextWriterTraceListener and add it to the collection of TraceListeners on the Trace class. This will automatically write all your Trace.Write... calls to the corresponding file.

Matthias
A: 

I agree with using log4net.

But if you really need something simple consider just having a singleton that holds a reference to a StreamWriter that auto-flushes on every WriteLine.

So you keep the file open throughout the Session avoiding the close/open overhead while not risking to loose log data in case of a hard crash.

Tigraine
+3  A: 

You could hook into the tracing framework that forms part of the CLR. Using a simple class like: http://www.chaosink.co.uk/files/tracing.zip you can selectively log diagnostic information. To use it add the class to your application. Create an inistance of the tracer in your class like:

private Tracing trace = new Tracing("My.Namespace.Class");

and call it using:

MyClass()
{
    trace.Verbose("Entered MyClass");
    int x = 12;
    trace.Information("X is: {0}", x);
    trace.Verbose("Leaving MyClass");
}

There are 4 levels of information in the inbuilt tracing framework:

Verbose - To log program flow

Information - To log specific information of interest to monitors

Warning - To log an invalid state or recoverable exception

Error - To log an unrecoverable exception or state

To access the information from your application then add into the app.config (or web.config) the following:

<system.diagnostics>
    <trace autoflush="false" indentsize="4">
     <listeners>
      <add name="myListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="c:\mylogfile.log" />
     </listeners>
    </trace>
    <switches>
     <add name="My.Namespace.Class" value="4"/>  
    </switches>
</system.diagnostics>

You can also attach listeners for publishing to the eventlog or anywhere else that interests you. More information on the tracing framework can be found at:

http://msdn.microsoft.com/en-us/library/ms733025.aspx

Wolfwyrd
A: 

I forgot to mention that i'm using multiple threads that all have output data that i want to log,(opening/closing the same file or accessing the same file on different threads might be bad) the "holds a reference to a stream writer that auto-flushes" sounds like a good idea, however i don't know how to do that

Dacto
A: 

The logging frameworks like log4net should handle multi-threading correctly.

There might be also a useful hint: the logging significantly pollutes the code making it less readable. Did you consider using aspect for injecting logging functionality to the code at the compile time? See this article for an example.

Petr Macek