Comments (11)
Yeah i'd been wondering about integrating with stuff like the query profiler, to let folks know if the rollup criteria is leveraging indexes or not, for example. What other examples do you have in mind?
from fflib-apex-common.
I was more thinking on the Debugging side, so creating a DiagnosticsMain class of sorts that would allow for being able to pop a class start and push diagnostic messages so that all details end up at the end of the log cycle. It would also be setup so that messages would happen at INFO or WARN so that individuals could reduce logging levels to see debug information (I think this would be super helpful in conjunction with debugging the queryfactory as it creates considerable log bloat). I'll fork out the project and do a pull request with some code for us to review. Hopefully we can get it hardened enough to release within the library.
from fflib-apex-common.
Sorry crossed projects earlier, i thought you where talking about DLRS diagnostic for a mo! Doh! Look forward to seeing some early ideas, please share early though, even rough mockup of the method signatures and some example usage would be good to get the conversation going.
from fflib-apex-common.
I was thinking something similar to the following:
public class fflib_Diagnostics
{
public static Boolean DiagnosticsEnabled = true;
private static List<DiagnosticEntry> DiagnosticLog;
private static Integer CurrentLevel = 0;
private static List<String> stacktrace = new List<String>();
public static string ExceptionTrace = '';
private class DiagnosticEntry
{
Integer level;
String description;
public DiagnosticEntry(string entrydescription)
{
level = CurrentLevel;
description = entrydescription;
}
}
public static void Push(String functionname)
{
Debug('Entering: ' + functionname);
CurrentLevel += 1;
Stacktrace.add(functionname);
}
public static void Debug(String debugstring)
{
if(!DiagnosticsEnabled)
{
return;
}
if(DiagnosticLog == null)
{
DiagnosticLog = new List<DiagnosticEntry>();
}
DiagnosticLog.add(new DiagnosticEntry(debugstring));
}
public static void DebugException(Exception ex, SObject debugObject, Schema.SObjectField debugField)
{
String exceptioninfo = 'Exception occurred line ' + ex.getLineNumber() + ' - ' + ex.getMessage() + ' stack: ' + ex.getStackTraceString();
Debug(exceptioninfo);
debugObject dbg = new debugObject.newSObject();
dbg.put(debugField.getDescribe().getName(), CurrentLog());
ExceptionTrace = ' Exception occurred line ' + ex.getLineNumber() + ' - ' + ex.getMessage();
for(String st : stacktrace)
{
ExceptionTrace += ' | ' + st;
}
ExceptionTrace += ' |\n ';
if(DiagnosticsEnabled)
{
insert dbg;
}
}
public static void Pop(String functionname)
{
if(CurrentLevel > 0)
{
Debug('Exiting: ' + functionname);
CurrentLevel-=1;
}
if(CurrentLevel == 0)
{
System.Debug(LoggingLevel.Info, 'Diagnostic Log\n' + CurrentLog());
}
if(StackTrace.size() > 0)
{
StackTrace.remove(StackTrace.size() - 1);
}
}
public static void PopAll()
{
CurrentLevel = 0;
Pop();
}
public static String CurrentLog()
{
if(DiagnosticLog == null)
{
return null;
}
String spaces = ' ';
String result = '';
for(DiagnosticEntry de : DiagnosticLog)
{
Integer endindex = 3 * de.level;
if(endindex >= spaces.length())
{
endindex = spaces.length() - 1;
}
result += spaces.substring(0,endindex) + de.description + '\n';
}
return result;
}
}
from fflib-apex-common.
Ah yes i see, interesting, do you have a demo use case / example, perhaps with a few classes?
@capeterson whats your thoughts?
from fflib-apex-common.
Hello,
Here are some examples of how this class could be used:
public class Accounts extends fflib_SObjectDomain
{
public Accounts(List<Contact> sObjectList)
{
super(sObjectList);
}
public override void onAfterInsert()
{
fflib_Diagnostics.Push('Accounts.onAfterInsert()');
testDiagnostics();
fflib_Diagnostics.Pop('Accounts.onAfterInsert()');
}
public void testDiagnostics()
{
fflib_Diagnostics.Push('Accounts.testDiagnostics()');
List<Account> myAccounts = new AccountsSelector().getAccountsByName(new Set<String>{'Archive'});
for(Account acc : myAccounts)
{
fflib_Diagnostics.Debug('Account.Name = ' + acc.Name);
}
fflib_Diagnostics.Pop('Accounts.testDiagnostics()');
}
public class Constructor implements fflib_SObjectDomain.IConstructable
{
public fflib_SObjectDomain construct(List<SObject> sObjectList)
{
return new Accounts(sObjectList);
}
}
}
@isTest
private class AccountsTest
{
@isTest
private static void testDiagnostics()
{
List<Account> accountsForInsert = new List<Account>();
for(Integer i = 0; i < 10; i++)
{
accountsForInsert.add(new Account(Name = 'Archive'));
}
test.startTest();
insert accountsForInsert;
test.stopTest();
}
}
You'll see the MainEntry lines which have been added to the fflib_SObjectDomain class before and after calling the trigger handler at about line 299.
This help centralize the debugging process so that any updates to standard text or additional logic that needs to happen pre and post debug scripts can happen in one location. We also see that this allows us to move all debugging up and down the logging levels thereby helping to decrease log size and making debugging cleaner and easier to use.
I did not do a test case for logging exceptions as I think the case is pretty straight forward. It allows for logging details of exceptions (including the entire stacktrace) to a custom object and field. This could be expanded to include the current user and other details. This would have far reaching effects for those creating managed packages as you can now find the entire exception stack in the subscriber org, when it happened, and for who without needing to have a user replicate the exact issue. It should also help those that are managing single and multiple orgs for those hard to diagnose errors as well as jump on issues proactively as you can suppress exceptions for the user, review logs and action fixes before they become larger issues.
I look forward to hearing back on thoughts and changes (I've also updated my original class post to add exit details in the pop method).
Might also be worth exploring some added functionality from https://github.com/scottbcovert/Centralized-Salesforce-Dev-Framework/blob/master/src/classes/DiagnosticsInstrumentation.cls
Tyler
from fflib-apex-common.
Thanks for sharing that debug stream does look cleaner for sure.
Keen to get some views also from @capeterson
from fflib-apex-common.
Thanks!
I've also found that adding the push/pop statements in the onhandleXXX methods helps quite a bit as well as adding the debugexception method within the QueryFactory try/catch for commit work. I'm sure there are various other area's it could be incorporated within the library.
from fflib-apex-common.
Just wanted to bump this post and see if there are further ideas or if I should continue on integrating this into the framework and then complete a pull request?
from fflib-apex-common.
I'm torn by this, i feel the need, but then also worry about the over head in Apex CPU, and the need to seed it around the library and other code in a solution. Compared to the benifits it's giving. Its true that the debug logs can be a pain at times, though Salesforce are taking steps to improve things with class level filters (and i'm seeing some new stuff in Winter'16 not yet explored). Then there is of course the Apex Interactive Debugger, which is getting more real.
As regards dumping stuff into a custom object also interesting, though if its a governor exception we never get a chance to route through this method. If we do, implementing logs via custom objects in apex requires some careful thought around savepoints to avoid allowing partially completed DML's to be committed along with the log. Finally there is also the sad fact that in a managed contexted in a subscriber org, even the managed code cannot get its own full stack dump, so that benefit is eroded also.
So i'm afraid, on this occasion i have to say, thank you very much, but no thanks regarding your submission idea. That said, please do feel if you want to chat more, please do, always open to be convinced otherwise on stuff! 👍
BTW, i did notice the other day that Salesforce captures full logs even when not logged into subscriber support, regular users appear to see the managed debug missing, but then when later a subscriber support login reviews them stuff magically reappears.
from fflib-apex-common.
Oh and really sorry for keeping you hanging this long! My bad.
from fflib-apex-common.
Related Issues (20)
- Unit test failure in multi-currency org HOT 4
- Deploy button doesn't deploy because there are test failures HOT 1
- Expected a QueryException due to read only user not having access to Opportunity HOT 7
- Switch to Inherited Sharing on SObjectDescribe and SObjectSelector HOT 2
- With latest fflib, do TriggerHandlers become service class consumers? If so what happens to UoW? HOT 6
- Selected tests in fflib_SObjectSelectorTest fail in an org with encryption enabled on Account.Name HOT 2
- Selector Mocks to Include SOQL Query Retrieve Check HOT 1
- fflib_SObjectUnitOfWork doCommitWork executes all dml for all registered types even if there are no changes
- Update README as session recordings are not available HOT 2
- fflib_SObjectDescribe.cls fails to resolve cross-object field paths for Person Accounts
- Aggregate SOQL support. HOT 2
- Disable Savepoint in tests HOT 4
- Inconsistent Code Coverage and Test Failures in fflib-apex-common HOT 1
- fflib_SObjectSelector and fflib_SObjectUnitOfWork have insufficient test code coverage. HOT 2
- Add queryWithBinds to Selector layer HOT 2
- Unit test failing fflib_SecurityUtilsTest & sysadmin_objectAndField_access HOT 8
- Coverage of UnitOfWork class HOT 1
- Versioning HOT 1
- fflib_SObjectSelectorTest failure with Lookup relationship and Person Type Accounts HOT 5
- fflib_SObjectSelectorTest Error: 'Assertion Failed: Expected: 12345.67, Actual: 9117.25' HOT 13
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from fflib-apex-common.