Live log monitoring within the application generating the logs - c#

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.

Related

Logging in backup file using ETW

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).

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.

Creating a Logger

It's not really a coding problem, but i'm after some feedback from the community regarding some issues that I'm having, while developing a new Logger implementation.
Background
our ASP.NET Application originally worked with log4net. While log4net is a great logging tool, it does not suit our needs and in some cases it even causes problems for our application by the way the logging is done. We currently are implementing our own logging system that is mimicing some behavior of log4net, but also tailored to suit our needs. I'm not here to discuss about the usage of log4net or how to config it.
System
Currently we have a system that's beeing developed. The system has a logger class, which is a Singleton (design flaw, I know...) and this class has a collection of IReporter objects.
Everytime the application calls Logger.Instance.Log(message) the logger will direct these messages to every IReporter inside the queue, and the reporters have the responsibility of logging the message in their destination/storage/whatever.
Currently we've chosen that each IReporter has a backgroundthread and a message queue to process the messages at their own speed. The danger here is that when the app dies suddenly we could lose some of the messages.
Another approach we had in mind was to have a thread pool on the logger and let these threads run over the queue and then delegate the messages to the reporters.
What I'm concerned about is the performance. We first implemented this using events in the logger, but the threads spawned went haywire fast when accessing the file. So now with this approach we hope to limit the access to the resources
What I'm lookign for is people who had similar situations and how they approached this issue.
Did I understand it correctly, and all those processes access the same set of files? On Windows?
You shouldn't do that, as the OS will do some complex locking that will take time, or worse, depending on how you access the files, you can get a deadlock. It would be better to do all the logging on one single thread, and running the IReporters sequentialy.
If you are concerned that your software may die during a log operation, put the logger in another process, communicate by IPC. But are you sure you want to reinvent syslogd?
Your design sounds an awful lot like Log4Net with a bunch of FileAppenders. You should really reconsider your decision, unless there are requirements on you that you haven't shared. Log4Net has a lot more use in the field than your logger ever will, and it's had lots of bugs and performance issues already shaken out of it.

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.

A method for high-load web site logging to file?

I need to build in click and conversion tracking (more specific and focused than IIS log files) to an existing web site. I am expecting pretty high load. I have investigated using log4net, specifically the FileAppender Class, but the docs explicitly state: "This type is not safe for multithreaded operations."
Can someone suggest a robust approach for a solution for this type of heavy logging? I really like the flexibility log4net would give me. Can I get around the lack of safe multi-threading using lock? Would this introduce performance/contention concerns?
While FileAppender itself may not be safe for logging, I'd certainly expect the normal access routes to it via log4net to be thread-safe.
From the FAQ:
log4net is thread-safe.
In other words, either the main log4net framework does enough locking, or it has a dedicated logging thread servicing a producer/consumer queue of log messages.
Any logging framework which wasn't thread-safe wouldn't survive for long.
You could check out the Logging Application Block available in the Microsoft Enterprise Library. It offers a whole host of different types of loggers, as well as a handy GUI configurator that you can point to your app.config\web.config in order to modify it. So there's not need to sift through the XML yourself.
Here's a link to a nice tutorial on how to get started with it:
http://elegantcode.com/2009/01/20/enterprise-library-logging-101/
I'm also interested in the answer, but I'll tell you what I was told when I tried to find a solution.
An easy way around it would be to use something like an SQL database. If the data you want isn't well suited for that, you could have each page access write it's own log file and then periodically merge the log files.
However, I'm sure there's a better solution.
When using syslog, you won't be having any threading issues. Syslog, sends the loglines using UDP to a logdaemon (could potentially be on the same machine).
Works especially great if you have more running processes/services, since all log lines are aggregated in 1 viewing tool.
if you expect really heavy loads, look at how the guys from facebook do it: http://developers.facebook.com/scribe/ You can use their opensource logtool. I don't think you'll hit their kind of load just yet, so you should be safe for some time to come!
R

Categories