Friday, January 3, 2014

Debug statements stopped working on large sections of APEX

Working away as normal building APEX code and testing it on a sandbox.  As usual our only way to debug this code is through debug statements.  Here is what I put at the beginning of every method:

System.debug(Logginglevel.ERROR,'MonitoringUtilities.testProcessUpsertMonitoringItem ');

Notice the Logginglevel.ERROR? That is to make sure this statement appears in the debug logs no matter what the filtering level is set to.  I want to see my method entry statement.    (Yes, I know that the debug log also produces a  METHOD_ENTRY log entry on every method entry point. I typically add some more information to my entry statement.)

In any case, those debug statements are supposed to appear in the trace. BUT THEY STOPPED!?

Just to lay the ground work here.  To see debug logs in the Salesforce UI you log on and go to Settings. Then search for Debug in the settings area. Only one entry called "Debug Log" so select it.  I always start from a clean slate which means I delete any existing logs and existing users (myself in this situation as I am a solo administrator/developer for my company).  I then add myself back as a user.  Next I run whatever process I'm working on. In my case, I am mainly running an ANT build to push code back into the server. (Test instance first.)

Then return to the Salesforce UI and refresh the page.

Normally, I just view the log in the browser and just search for my method entry point and then go from there.

Most debug statements went missing

Today, after a break from Salesforce, I came and did some more development. All as usual until I tried to see my debug statements. They were not there.   Other methods that ran both before and after my new code have log entries but most entries are just not there.

I've spent several hours (remember that APEX development is mainly about waiting for the load process to finish) trying various things and searching the web but without any success.

Debug Filtering

On the Debug Logs screen beside the user name you will see a link to set "Filters" for a user.  This lets you get more or less information.  The default setting for System.debug is to log the entry at the Debug level and the default filter is to show this Debug level.

In the trace, on the first line you can see the current levels for each category.  Here is a sample from my log (showing some debug statements but not the ones around my new code.)


Solution Found

There seems to be a hidden governor limit on debug log statements.  Something that would allow a 10 or so and the beginning and a few at the end but all those in the middle are dropped.  The key is the size of the log file.  It's 2Gig.

Once I built a smaller workspace with just the classes and triggers underdevelopment and modified the build file ... the debug logs started to appear again.

Normally when I make just lightweight edits I retrieve and deploy and test the full set.  To get this smaller set to work I needed to add a runText element for the class under development.
<sf:deploy deployroot="${targetDir}" password="${sf.password}" serverurl="${sf.serverurl}" username="${sf.username}">

For more on the ant migration toolkit see my earlier posts or

Solution Only Partial Fix

So the above "works" in that the log file is now just showing the test results from deploying and testing the smaller set of files.  But none of the files actually got deployed on my sandbox because the build failed due to a long list of code coverage problems. Like this:

Code coverage issue, class: OpportunityUpsertTrigger -- Test coverage of selected Apex Trigger is 0%, at least 1% test coverage is required

Now all those classes have all the test coverage they needs in the system already.  The deployment does not mention any of these classes.   So why then does Salesforce even look at them?   

I don't have any more time for Salesforce just now. It is such a frustrating development environment.  All I am trying to do is write a simple trigger to copy values from one table to another and it has taken a long time to do get part way done.   I am very tempted to just push this work outside Salesforce like I do with so much else and just use Java and the partner API.  But I'm this deep into it and doing this work in a trigger is the most logical solution from a DB design point of view.

Solution?   Run the all the tests again and forgo the debug statements in my test class!   So, my process is (a) develop the code and use the deployment to run the tests; read the debug statements and adjust until things are working then (b) deploy with flag to run all tests.

Here, for the record, is the Ant deploy target in my build file.

<target name="deploy" depends="setup">
<if> <equals arg1="${allTests}" arg2="true" />
<echo>Deploy with all tests and rollback on error true</echo>
<sf:deploy username="${sf.username}" password="${sf.password}" serverurl="${sf.serverurl}" deployRoot="${targetDir}"
runAllTests="true"  rollbackOnError="true" />
<sf:deploy username="${sf.username}" password="${sf.password}" serverurl="${sf.serverurl}" deployRoot="${targetDir}" >

Here is step (a) command and then step (b)
ant -v -lib . -f build.xml -Dtarget=test -DtargetDir=workareaSmall -DallTests=false  deploy

ant -v -lib . -f build.xml -Dtarget=test -DtargetDir=workareaSmall -DallTests=true  deploy

Should mention that I also have to then

  1. retrieve a fresh download from production which goes in the main/full directory
  2. copy the files with changes from the small workspace directory to the main/full development workarea
  3. retest with all the files on the sandbox, if tests pass then
  4. deploy onto Production.
I always grab the latests contents from Production in case I made any changes there while developing the code.   I truly do not know what people do in the world of larger development teams.  I wish them luck!

No comments:

Post a Comment