I was wondering what is the 'correct' way to log information messages; to files, or to a special log in the event viewer?
I like logging to files since I can use rolling flat file listener and see fresh new log from each day, plus in the event viewer I can only see one message at a time - where in a file I can scan through the day much easily. My colleague argues that files just take up space and he likes having his warnings, errors and information messages all in one place. What do you think? Is there a preferred way? If so, why?
Also, are there any concurrency issues in any of the methods? I have read that entlib is thread-safe and generates a Monitor.Enter behind if the listener is not thread safe, but I want to make sure (we're just using Logger.Write). We are using entlib 3.1.
Thank you in advance.
Here's the rule of thumb that I use when logging messages.
EventLog (if you have access of course)
- We always log Unhandled Exceptions
- In most cases we log Errors or Fatals
- In some cases we log Warnings
- In some very rare cases we log Information
- We will never log useless general messages like: "I'm here, blah, blah, blah"
Log File
- General rule, we log everthing but can chose the type of level or filter to use to turn down the volume of messages being logged
The EventLog is always a good option because its bound to WMI. This way products like Open View and alike, can monitor and alert ops if something went haywire. However, keep the messages to a minimum because its slow, its size limited on a per messaeg basis and it, entry limit as you can easily fill up the EventLog quite quickly and you application has to handle the dreaded "EventLog is Full" exception :)
Hope this helps...
There is no 'correct' way. It depends on your requirements.
You 'like' looking at flat files but how many (thousands) of lines can you really read every day?
What you seem to need is a plan (policy) and that ought to involve some tooling. Ask yourself how quickly will you notice an anomaly in the logs? And the absence of something normal?
The eventlog is a bit more work/overhead but it can be easily monitored remotely (multiples servers) by some tool. If you are using (only) manual inspection, don't bother.
In enterprise applications there are different types of logs such as -
Activity logs - Technical logs which instrument a process and are useful in debugging
Audit logs - logs used for auditing purpose. Availability of such logs is a legal requirements in some cases.
What to store where: -
As far as the Audit logs or any logs with sensitive information are concerned they should go to database where they can be stored safely.
For Activity logs my preference is to files. But we should also have different log levels such as Error, Info, Verbose etc which should be configurable. This will make it possible to save space and time required for logging when it is not needed.
You should write to event log only when you are not able to write to a file.
Consider asking your customer admins or technical support people where they want the logs to be placed.
As to being thread-safe, yes, EntLib is thread-safe.
I would recommend Event-viewer but in cases where you don't have admin rights or particular access to Event-viewer, Logging to normal files would be better option.
I prefer logging to a database, that way I can profile my logs and generate statistics and trends on errors occurring and fix the most frequent ones.
For external customers I use a web service called async to report the error. (I swallow any expections in it so any logging error's wouldn't affect the client - not that I've had any, using log4net and L4NDash).
Related
I have a Windows application and I want to log errors using Log4Net.
The issue I'm facing is where to log these errors. If I'm logging to a local folder then the logs will be on the clients' machine, which isn't conveniently accessible to us.
So, we thought of 2 options:
Log Error on a shared (network) location
Log Error in DB
The issue in logging errors in the DB is that if there is an issue in connecting to DB then logging obviously fails, so we decided to log on a shared location.
Now, someone informed me that it is not a good practice to log to a shared location.
What can you do to ensure logging when it's conceivable that every place you can log might be inaccessible or down?
What shared location?
Generally you are always at risk of not getting the log, because the client machine can lose network connectivity. In this case logging to shared location, database, web service, whatever else remote is not going to help you.
Possible the least amount of friction professional solution would be to use a service like https://raygun.io/ It's not the only one there are other similar services.
Failing that, logging to a database is usually quite adequate. In practice if you cant log in the database it's because of one of the following:
Connectivity problem. (Either the machine lost network connection or the DB server did or it's offline)
A bug in the logging code
Again, in practice, the probability of the latter is quite small given adequate testing, since the logging code do not tend to be all that complicated. The former is much more probable, so you need to handle this scenario separately. Usually it's a good idea to log locally (local file / event log) if the database logging failed. It is difficult to retrieve this data from the customer machine, but in the rare case you need to troubleshoot a connectivity issue it's a life saver.
Logging to a "shared location" as in "windows share" is not common and in my opinion provide no advantage over logging to a database. Both database and shared location can be down. Client computer might not have connection. In all these scenarios both options behave the same.
In certain scenarios, it makes sense to upload the saved locally logfile to the database when network connectivity is restored, but often it's an overkill.
What you're trying to accomplish is something that we call 'best effort' logging. It's a relatively language-agnostic practice that resembles:
try:
if [database]
log [database]
done // exit the logging method, database worked.
endif
if [rsyslog] // If we got here, [database] didn't work.
log [rsyslog]
done // exit the logging method, rsyslog worked.
endif
if [redis] // If we got here, both [database] *and* [rsyslog] didn't work.
log [redis]
done // exit the logging method, redis worked.
endif
finally: // nothing worked
panic // write anywhere it can, just open a file in the app directory if it must.
That's up to you to implement around whatever logging library you wish to use, though some might conceivably have that built in. It only begins to look fragmented if things go badly, however:
Most stuff will end up in the database
Database exceptions will go to rsyslog (or any logging server)
Using a third is just extra paranoia, watch redis for messages about rsyslog being existentially challenged (pub/sub might be ideal there)
.. or do it whatever way makes sense for you. If your ideal log location is the database, then just log to the database, while you ensure that you continue to make a 'best effort' if the database can't be reached. If all else fails, write to a file - you won't be doing it that often (or ideally, need to fish bits out of it) - so the location becomes much less of an issue.
The end result is, all you have to worry about doing is calling your logging method, since you know that it's going to make the best effort possible to log the data in one of several defined manners. If it gets to the point that it can't even open a file, well - you've probably got lots of other interesting logs to look into as well :)
I have implemented into my C# project Log4Net logging features.
Right now I'm using EventLogAppender to log all the errors, but I want to know if the FIleAppender is a better approach. I have my concerns about performance when saving to a file instead of logging into system events.
What are the benefits of using FileAppender vs EventLogAppender?
Performance wise, both are fast, but I suspect File based will be faster. If you are writing so many logs that this is a concern, then your program sounds pretty "chatty" and so I would go with the FileAppender--system logs are nice when logs are concise and occasional, but they quickly get tedious if they are long and/or frequent. File based logs are generally easier to archive, if that's a concern. EventLogs, on the other hand, are nice if you are already monitoring the event logs or if you want to put everything in a "standard" place--that is, the user will always know where to look.
Note that you don't have to choose just one or the other--you can do your short/occasional status updates in the event log and details in the file log--that's the approach I usually take.
I need to do logging in our application and would like to keep the time consumed due to logging as little as possible. I am thinking of using MSMQ so that the application will log into MSMQ and then I can log the messages from MSMQ to the database/files asynchronously.
Is this idea good in terms of performance? or logging to flat files synchronously using log4net is better.
Also , I am thinking of coding a logging abstraction layer so that I plug in any logging tools later without affecting other code.
Please advise.
Thanks,
sveerap
I would advise against this. This is a needlessly complex solution for a problem that doesn't really exist. I've used log4net in multiple projects and never saw any significant performance degradation because of it.
It's a better idea to take good care of selecting the right logging levels for each log message (DEBUG, INFO, WARN, etc). When you start your project and maybe during a short time when you're in production you log everything from DEBUG to higher levels. When you're confident everything works, you switch to INFO in the configuration. This should be enough to tackle any performance issues you may encounter with logging.
Concerning your abstraction layer, I wouldn't do this either. Log4net itself abstracts all details of the logging itself via its logger appenders. And if you really want this, you may also want to take a look at Common.Logging.
For what it's worth, there are scenarios where this isn't overkill. But, for most applications I would say that it is.
I work in an environment that is comprised of several z/OS mainframes and a variety of *nix midranges. The systems all write logging messages to a shared queue which is processed. Organisationally, it was found to provide better throughput and to ensure the consistency of the log.
With that said, I can see the advantage of using this approach for your applications. For example, developing a lot of internal applications and having a common log (for example, in the database - have a process which comes and reads the queue and writes it to the database) would allow you to aggregate all of your messages.
However, you will probably find that log4net or another .NET logging package will perfectly suit your needs.
There are advantages to both, but as everyone else has said - using MSMQ for logging is (probably) like going after a fly with a bazooka.
Honestly, MSMQ seems overkill for logging messages. Unless you absolutely need reliable delivery of the log messages, log4net seems to be a perfectly fit solution. keep also in mind that creating a message in MSMQ might take longer than actually writing to a buffered file.
You may also want to have a look at the System.Diagnostics.Trace object.
I am in need of filling the Windows Security Event Log to a near full state. Since write access to this log is not possible, could anybody please advise as to an action that could be programatically performed which would add an entry to this log? It does not need to be of any significance as long as it gives an entry (one with the least overhead would be desired as it will need to be executed thousands of times).
This is needed purely for testing purposes on a testing rig, any dirty solution will do. Only requirement is that it's .NET 2.0 (C#).
You can enable all the security auditing categories in local security policy (secpol.msc | Local Policies | Audit Policy). Object access tends to give plenty of events. Enabling file access auditing, then set audit for everyone on some frequently accesses files and folders will also generate lots of events.
And that's normal usage, and that includes any programmatic access to those resources being audited (its all programmatic in the end, just someone else's program).
Enable Login Auditing as Richard mentioned above. Success or Failure is dependent upon how you handle step 2:
Use LoginUser to impersonate a local user on the system - or FAIL to impersonate that local user on the system. Tons of samples via good for viable C# implementations.
Call in a tight loop, repeatedly.
Another approach you can take involves engaging object access, and doing a large number of file or register I/O operations. This will also cause the log to fill out completely in an extremely short period of time.
I have an application which can only have 1 instance running at each time, however if a 2nd instance is launched it needs to be logged to a common logfile that the first could also be using.
I have the check for how many instances are running and I was planning on simply logging it to the event logger initially but the application can be running in user or system context and exceptions are thrown when attempting to query the eventlog source as a user so that idea is scrapped as the security logs are inaccessible to the user.
So I wanted to find out what the safest method of have 2 seperate instances of the same application write to a log file would be that would ensure both get an opportunity to write to it.
I would prefer not to use an existing additional framework if avoidable
Any help appreciated.
A Mutex could be used for interprocess synchronization of a shared resource such as log file. Here's a sample.
You could always write to the system event log. No locking or anything needed and the event viewer is more robust than some give it credit for.
In response to your comment, another user asked the question about write permissions for the event log here on SO. The answer linked to the msdn article that describes how to perform that.
See that question here.
You can dodge the problem if you prefer...
If this is a windows app, you can send the first instance a message and then just quit. On receiving the message, the original instance can write to the log file without any issues.
Why not use syslog protocol ? This will allow you to deliver the logs in a very standards-based and flexible manner. The protocol itself is quite simple, but there are plenty of examples on the Net, e.g. here. If your app is destined for the enterprise use, having a standard way of logging could be a big plus. (And, you do not need to maintain the files either - it becomes a job of a specialized software that does just that)
One way to hack it would be to memory-map the log file. That way, both instances of the application are sharing the same virtual memory image of the file. Then there are a number of ways of implementing a mutex inside the file.