调试 Apex 时失去持续时间 CPU 超出时间限制

Lost Duration while Debugging Apex CPU time limit exceeded

我愿意发布本节中的代码以完成优化,但它有点长且复杂,因此我希望有人可以帮助我解决一些调试问题。我的目标是找出导致我的 Apex CPU 超出时间限制问题的原因。

在基本或正常布局中使用调试日志时,我收到消息

Maximum CPU Time: 15062 out of 10,000 ** Close to Limit

我已经多次优化和重写了各种循环和查询,在每种情况下,这个数字都在那里结束,这让我相信它在骗我,我的实际使用量远远超过这个数字。因此,在我的旅程中,我将开发人员控制台的日志面板切换到分析,希望准确地隔离出让我头疼的循环、方法或代码区域。

这引出了我的主要问题。

Execution Tree, Performance Tree & Executed Units

全部显示我的持续时间低于 10,000 毫秒限额。我最大的消耗是 3,556.19 毫秒,它被一个包装器使用 class 我在构造函数方法中创建和使用了其中有相当多的逻辑正在构建一个相当复杂的包装器 class 跨越 5 -7 个自定义对象。即使有这 3,000 毫秒,该过程的其余部分显示的时间也可以忽略不计,使我的总时间约为 4,000 毫秒。我的问题又是....为什么我看不到或找不到耗费我所有时间的东西?

Incorrect Iteration Data

除此之外,在性能树上有一列数据显示每种方法的迭代次数。我知道我的生产组织有 81 个对象,它们基本上会为我的自定义包装器对象调用构造函数。 IE。我的构造函数应该被调用 81 次,但它被调用了 32 次。所以我的另一个问题是我可以依赖列中的迭代数据吗?或者因为它迭代了很多次,它会在某个点停止计数吗?可能我的一个对象已损坏或以某种方式导致无限循环,但我不想挖掘所有数据来寻找该结论,如果它是一个已知问题,即迭代数据无论如何都不准确。

System.Debug in the Production org

最后一个问题是为什么我的 System.Debug() 行没有显示在生产组织的开发人员控制台中。我在整个代码中添加了几个面包屑,这将帮助我隔离哪些对象正在通过,哪些没有,但是,我不能在任何布局视图中 system.debug 我的沙箱之外的消息。

抱歉提出了这么多问题,但我确实想尽一份诚实的努力来更好地理解 Salesforce 中的调试过程。如果这是一个失败的原因,我也很乐意开始分享一些代码,但希望一些调试技巧可以帮助我找到解决方案。

您的调试日志可能被截断了,请参阅“每个调试日志必须为 20 MB 或更小。如果超过此数量,您将看不到所需的一切。 " 在 https://trailhead.salesforce.com/en/content/learn/modules/apex_basics_dotnet/debugging_diagnostics 下载日志并搜索类似于“skipped 123456 bytes of detailed log”的文本 以确认,某些 system.debug 语句将不会显示。

您可能需要微调日志级别(不记录验证规则和工作流程?不记录具有 "FINE" 级别的每个变量分配等)。您可能必须将所有标志设置为 NONE,然后仅跟踪您怀疑的 1 个特定 class/trigger(参见 https://help.salesforce.com/articleView?id=code_debug_log_classes.htm&type=5 and https://salesforce.stackexchange.com/questions/214380/how-are-we-supposed-to-use-debug-logs-for-a-specific-apex-class-only

如果它被截断,分析工具可能会放弃(老实说,我与控制台的运气参差不齐,有时 https://apextimeline.herokuapp.com/ 很适合提供概览 - 但它也无法解析 20 MB 的日志。 ..

当所有其他方法都失败时,您可以将日志加载到 Notepad++(或您选择的任何编辑器)中,找到与方法 entry/method exit 相关的行(您可能需要正则表达式搜索),将这些过滤行 excel,玩 "text to columns" 并手动查看时间,看看是否有导致尖峰的记录。因为它可能是第 10 个问题,所以它用尽了 81 个中的第 32 个限制的事实并不意味着什么。像 [METHOD_ENTRY|METHOD_EXIT]MyTriggerHandler.onBeforeUpdate 这样的搜索可能是一个好的开始。但首先要确保日志没有被截断。