Logging in Force.com can be somewhat of a challenge. Since there's no log file you can write to, we need to develop another mechanism to record events and exceptions that we can inspect later. Sending emails with exceptions information is fine, but it may become overwhelming. So let's implement a Custom Object called
Log__c that we can dump events and exception info into. We can then run reports, implement workflow, write triggers and do all kinds of cool stuff for this object. We've been using this methodology (sparingly for certain situations) for a couple of years at CloudSpokes and it's worked quite well for us.
Disclaimer: This may not work for all use cases as exceptions will cause all commits to rollback, including your log inserts. Another route may be to insert these log records asynchronously (using @future) but you need to ensure that this method is not being called from another asynchronous method. Also you may bump into some governor limits so check the docs for specifics.
So, first create a Custom Object (
Log__c) to hold all of your entries.
I added a lookup relationship to our Challenge object as I'm just recording events from these records. The Class__c field simply allows me to record from which Apex class the event or exception occurred. Message__c is the actual message being logged while Priority__c is essentially the severity of the message. You can pass values such as
FATAL and then write workflow notifications based upon this severity.
So here's a little helper class that you can call from your Apex code to make logging easier. You essentially pass it the info you want to log and it will do the rest for you. You may want to add some exception and bulk handling. In our case at CloudSpokes we ensure that these transactions are not occurring in bulk. You may want to write a log method that accepts an Array of LogMessages or something similar.
So now in your code you can do something like the following to log an event: