Logging in backup file using ETW - c#

Is there any way I can use Microsoft.Diagnostic.Tracing.EventSource package or any other .NET built in types to implement a back up logic for logging?
I have used an EventSession that directs all logs to an .ETL file but there are two problems with this:
The most important one is that, from what I understand, the logs are actually being written to the file when the processing stops. But what happens if the machine shuts down or the processor process gets killed? From my tests the logs are lost.
The second problem is less important and it's just that it would be more convenient for my solution to be able to read from the file as logs are coming in.
Basically I would like to have a file buffer for my logs and I was wondering if there's some built in implementation especially for this.

Yes, EventSource's WriteEvent methods are not blocking, so they do
not guarantee that logs actually have been saved.
And yes, you cannot
read ETL files while they are in use.
ETW is not the option for you in this case, you could use common TraceSource (with two listeners, one is configured to do auto-flush and another one is ETW adaptor, which you could listen to through a real-time ETW session) or log4net (you could choose appender that works for your case).

Related

System.Diagnostics.Trace on a live environment

Problems have been reported to me regarding the performance of a live site. I can't seem to replicate any of these issues on any dev or staging environments, and the profilers I have ran against dev has revealed nothing unusual.
This has led me to turn to a diagnostics trace for a simple timing trace so I can at least try and isolate the cause and try and narrow it down.
I'm quite happy to add
System.Diagnostics.Trace.WriteLine("....");
wherever necessary and add a listener (via web.config entry) to write out to a log file, but could this massively impact the performance of the live environment itself?
Is there anything else I need to consider when, potentially, leaving this to run over the weekend? i.e. is it best that I specify how large the log file is to get before closing and opening a new one?
It depends how much data you are going to log so turn on the logger and check if your application behaves normally. Also if logging to a log file slows down your application consider a faster TraceListener such as EventLogTraceListener (you may create a dedicated event log for this purpose with maximum size and log rolling). In case logging to a file is not a problem get EssentialDiagnostics RollingFileTraceListener. It has many options including setting maximum file size and the number of rolled files.
Use a logging framework like log4NET and make logging like:
LogManager.GetCurrentClassLogger().Debug("...");
When you disable logging afterwards in the configuration, these functions are not executed by the framework.
If you need to do string formatting for your messages: Use "DebugFormat()" which will not do the formatting if it is not needed by the level of logging desired.

Live log monitoring within the application generating the logs

I have an application in .NET that I need to log. I want to log certain events and exceptions. I saw online that log4net was being heavily recommended for this purpose. I set it up to quickly begin logging to a txt file.
But this is not good enough for my purposes. From within my application, I'd like to be able to pull up a monitor which has a live listing of all the logs being generated.
If log4net the best approach for this? If not, what is?
I have no problem consuming the log events and finding my own way to display the data, I just don't know what the best way is to send the logging events to my monitor form.
You may want to look at log2console, which is an excellent logging monitor compatible with log4net. It can listen to the log4net remoting appender and present the data quite nicely.
If you need to implement your own monitor from within the program, I would suggest trying out the MemoryAppender. There's some helpful info here (the question is actually a very nice tutorial)
As you can see, he has set up two appenders - one which is logging to file and one which is logging to the memory appender. In your monitor, you can get a handle to the appender using the following code:
Hierarchy hierarchy = LogManager.GetRepository() as Hierarchy;
MemoryAppender mappender = hierarchy.Root.GetAppender("MemoryAppender") as MemoryAppender;
And you can cycically get the new events in a background thread with mappender.GetEvents(), before clearing it with mappender.Clear(). Keep in mind that this is not thread safe, so creating a thread safe wrapper for your logging is probably a good idea.

Alternatives to Console.Writeline() for printing debug information from a console application?

I have a C# console application. It is gathering info from several data sources and centralising them in another. Occasionally, it hits some bugs - connection strings stop working; schemas change etc.
At the moment, I am simply printing out debug information using Console.WriteLine(); - this is obviously an awful idea...not least because the application is a scheduled task running every night, so I never see this debug information anyway!
What should I do to allow for simple debugging when the program fails? What is my best practice in this case ?
Thanks very much.
You can use a logging library. log4net seems to be the most popular choice.
Use Debug.WriteLine(). It'll print to the assigned listeners (default only your Visual Studio Output window, but you can hook it up to the Console). If this is for troubleshooting production issues, I'd strongly advise to implement logging in your application.
Check out System.Diagnostics. Debug class is a better choice than Console, for starters.
log4net (as linked by #Tim S.) is a useful framework for general diagnostics output, at different levels of severity.
You should read about different logging/error strategies.
I suggest that you start off by using a library like log4net where you can define what kind of format you want for your logs.
I would recommend using the EventLog class to write to the application event log (or your own custom log). You could alternatively write to a custom log file of your own choosing. The event log, however has the advantage of easily being viewable remotely from any machine. In addition, if this application is truly unattended, you could have it send an email notification when it fails to the system administrator.
You want a logging framework, such as log4net or the Enterprise Library Logging Block. These frameworks will allow you to log to a database, log file, or the Event Log for later viewing and retrieval.

log4net save buffer from BufferedAppender

we are using log4net with a AdoNetAppender to write critical logs into an database. Since the AdoNetAppender is a subclass of the BufferedAppender there is a possibility to enable queuing of log events.
What I'd like to do is to save the backup & restore the log buffer to a local file, so that no log entry can get lost it the database is down or the application crashes.
Does somebody know how to this?
Don't think you can save the buffer without writing some code yourself. What I rather would suggest is sending the logs to both a AdoNetAppender and a RollingFileAppender. The first will ensure your regular logging to database while the second will ensure that the latest logs are also written to disk.
Update: in light of your later comments I can see how logging to two different sources (one database and one local store, either a file or local database) gets tough to consolidate.
Imo you should absolutely use log4net for what it is best at: a tried and true framework for collection log data from the application and routing that data to receiving systems. Building a failover system on top of log4net though is not what it is designed for. For instance, there is no process model that can pick up the pieces after an application crash.
Instead, handle failover in the receiving system. Failover at the database level and the network level gets you a long way, still you are not guaranteed 100% uptime. By logging to a local store and then have a process picking up the logs and shipping it to the database would minimize the risk for log data being lost, and at the same time you avoid having to consolidate logs from two different stores. Even better, logging is still simple and fast and thus have a low impact on the application.
An alternative would be logging to a local database and having a database job pull the data into the master database. You could also use queuing. There is a sample MsmqAppender out there to get you started. If you're using MS SQL Server you could even use the Service Broker for its queuing abilities.

Logging from multiple processes to same file using Enterprise Library 4.1

I have several processes running concurrently that I want to log to the same file.
We have been using Enterprise Library 4.1 Logging Application Block (with a RollingFlatFileTraceListener), and it works fine, apart from the fact that it prepends a GUID to the log file name when two processes try to write to the log file at the same time (a quirk of System.Diagnostics.TextWriterTraceListener I believe).
I've tried various things, including calling Logger.Writer.Dispose() after writing to the log file, but it's not ideal to do a blocking call each time a log entry is being written.
The EntLib forums suggest using MSMQ with a Distributor Service, but that is not an option as MSMQ is not allowed at my company.
Is there another way I can quickly and easily log from multiple threads/processes to the same file?
Sorry to say but the answer is no. The File TraceListeners lock the output file so only one TraceListener can log to a file.
You can try other Trace Listeners that are not file based (e.g. Database, Event Log).
Another option I can think of would be to write your own logging service (out of process) that would log to the file and accepts LogEntries. Then create a custom trace listener that sends a message to your service.
It might not be a good idea since you would have a bit of custom development plus it could impact performance since it is an out of process call. Basically you are setting up your own simplified-pseudo-distributor-service.
EntLib locks the log file when it writes to it. Therefore, 2 processes cannot write to the same log file.
When we have had this problem, that we needed to log from many difference places, to the same place, we have used database logging.
If you are 100% stuck logging to a text file, then you could log to individual log files, and then write a program to merge these files.
I know this is old, but if you are still curious. log4net supports this:
http://logging.apache.org/log4net/release/faq.html#How do I get multiple process to log to the same file?
The problem occurs when the App Pool Recycles and allows for Overlapping Threads. The closing thread has it still open, and the new thread gets the error. Try disabling the overlapping recycling behavior in IIS, or create your own version of the text writer.

Categories