Reputation: 2911
What would be the most efficient way of recording to a log (.txt) from a console program on C# and .NET 2.2? My program loops multiple times always outputting different data based on what the user wants, so I'm searching for the 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. In my opinion, that doesn't seem very resourse friendly.
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.
Upvotes: 4
Views: 2721
Reputation: 97997
Consider using log4net:
a tool to help the programmer output log statements to a variety of output targets... We have kept the framework similar in spirit to the original log4j while taking advantage of new features in the .NET runtime. For more information on log4net see the features document...
Upvotes: 16
Reputation: 1473
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.
Upvotes: 0
Reputation: 15916
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
Upvotes: 3
Reputation: 23678
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.
Upvotes: 2
Reputation: 14827
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.
Upvotes: 0
Reputation: 37830
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.
Upvotes: 3