5

When single batch jobs fail only the last one is party shown in the Apex Logs page. This is not enough for debugging.

A better way ist to check the log entries that are written per batch execute.

The problem is: this does not work reliably as:

  1. Logs seem to be written only when you have an open Developer console
  2. The Developer console does not fail to reload due to strange "Server timeout errors"
  3. The Developer console doesn't stop keep track of the new logs (sometimes it just stoppes without "Resume Updating" being available.

How can I guarantee that I have ALL the logs produced by a 10h batch available when I log in after it finished?

1
  • 1
    Have you tried not using Developer Console, and while logged in as the user setting up Debug Logs via Setup, click Monitoring | Debug Logs or Logs | Debug Logs? – Andrew Fawcett Jul 5 '13 at 10:06
2

Another option could be to create a custom "error" object and then in your batch code you can use try / catch to trap errors and to write a row to the table. This lets you capture the error, the stack trace, plus you can add your own custom information such as what record was being processed at the time, which function you are in etc.

1

Have you tried not using Developer Console, and while logged in as the user setting up Debug Logs via Setup, click Monitoring | Debug Logs or Logs | Debug Logs.

With this you can configure upto 20 debug logs to be captured. The downside is that other Apex / VF activity they perform in the mean time will also be captured. If however its a dedicated user or the job runs at a time the user is not on the system this should give you what you need.

1
  • In my case I have a Batch that produces 29.999 batch logs without and ONE with error. Until now when I logged into the org with granted login access this single log was NOT there. Even if I had setup logs like you propose. – Robert Sösemann Jul 8 '13 at 12:46
1

I often have a batch send me an email with all of the pertinent information I want from the batch run. I declare a string variable that I add to whenever I need to, then put that string into the body of the final email.

String debuglog = '';

...
debuglog += '\nReceived list of objects size ' + scope.size();
...
catch (Exception e)
{
    debuglog += '\ncaught exception ' + e.getMessage();
}
//etc.
...

global void finish(Database.BatchableContext BC)
{

String emailMessage = 
    'Your batch job \"Batch_ClassName\" has finished.  <br/>Log of process:<br/>'
    + debuglog;

Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
String[] toAddresses = new String[] {a.CreatedBy.email};

mail.setToAddresses(toAddresses);
mail.setReplyTo('noreply@salesforce.com');
mail.setSenderDisplayName('Salesforce Batch'); 
mail.setSubject('Batch_ClassName job completed');
mail.setPlainTextBody(emailMessage);
mail.setHtmlBody(emailMessage);
}

For most purposes a single email is fine. If you're collecting a lot of information, you could send a separate email for each batch execution as well.

The disadvantage is that you need to explicitly echo everything you need out to the reporting log string, which isn't so bad once you get used to it.

1
  • I have batches with 100.000 batch jobs. Adding that to a single stateful string will break the heap, I guess. I tried to send out emails from failing execute() calls but ran into another error. If you send an email from catch or finally and the rethrow the exeception it is never thrown. – Robert Sösemann Jul 8 '13 at 12:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.