-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit ab24759
Showing
33 changed files
with
875 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
# debug_logger | ||
|
||
This package provides the objects and methods to store logs generated by other Apex | ||
classes so they are logged for later analysis. Log data is stored in a custom object and can also be published as Platform Events for live monitoring. | ||
|
||
Also included is a scheduable cleanup process that should be configured to run | ||
on a nightly basis to delete old logs, keeping the number of records down. The number of days that records should be kept is configurable | ||
via a custom metadata setting. | ||
|
||
If you want to monitor the Platform Events that can be generated, a package that I like can be found at https://github.com/pozil/streaming-monitor, but others are also available | ||
|
||
# Methods | ||
|
||
* DebugLog(String CallerIdentification) | ||
* CallerIdentification is a string that identifies the process that created the entry | ||
* saveLog(String LogEntry) | ||
* LogEntry is a string that provides the data to be logged | ||
can be called multiple times to append to the log | ||
(but it does not commit the data) | ||
* commitLog(String LogEntry) | ||
* LogEntry is a string that provides data to be logged | ||
* Calling this method saves the data in the custom object and clears the log string | ||
(but leaves the CallerIdentification intact) | ||
|
||
# Variables | ||
|
||
* endPoint | ||
* used to define the REST endpoint or method [optional] | ||
|
||
# Configuration | ||
|
||
You can control part of the operation of the package via several Custom Metadata (CMD) settings. The CMD is named 'Debug Logger Setting' and there are 2 fields that you can create in a record called 'Local' | ||
|
||
* 'Days To Keep' | ||
* defines the number of days of logs that should be kept during the cleanup processing. Logs older that the specified number of days will be deleted if you schedule the DebugLoggerCleanupScheduler to run as describe on the 'Post Install Steps' below. | ||
* 'Publish Events' | ||
* If this is set to true, will publish a event on the 'Debug_Log' platform event bus. This can be received by other processes for additional handling of the errors if desired. | ||
|
||
# Example usage | ||
|
||
*** | ||
|
||
static void myMethod() { | ||
private static string commentString = 'random string'; | ||
|
||
DebugLog log = new DebugLog('className'); // inits the class with the caller info | ||
log.endPoint = 'myMethod'; // define the calling method | ||
log.saveLog('some comment '+ commentString); // saves some string (but does not commit) | ||
|
||
[...] | ||
|
||
log.commitLog('Exception caught '); // commits the log entry | ||
} | ||
|
||
*** | ||
|
||
# Post Install Steps | ||
|
||
Once the package is installed, you need to schedule the DebugCleanupScheduler job. | ||
Under the Setup menu, look for Custom Code -> Apex Classes. There you will see | ||
a button 'Schedule Apex'. After clicking that button, create a job name and | ||
select the Apex Class "DebugLoggerCleanupScheduler". Specify that it should run | ||
weekly, on everyday of the week, and specify a start and end date as well as a | ||
time (suggested 3:00 AM). | ||
|
||
You can also change how many days of logs are kept during the cleanup job | ||
by modifying the Custom Metadata 'Local' settings called 'Debug Logger Settings'. | ||
If this value is changed, it will be used the next time the cleanup job runs. | ||
|
||
You should also assign the 'Debug Log Viewer' permission set to any user that will need | ||
to be able to view the logs. | ||
|
||
|
||
# Single line sfdx set up | ||
|
||
```sfdx force:org:create -a logger -n -f config/project-scratch-def.json && sleep 2 ; sfdx force:source:push -u logger && sfdx force:user:permset:assign -u logger -n Debug_Log_Viewer ; sfdx force:org:open -u logger ``` | ||
|
||
|
||
# Credit | ||
|
||
Written by Marc D Behr in 2015 with numerous updates over the years |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"orgName": "Emerson", | ||
"edition": "Enterprise", | ||
"hasSampleData": false, | ||
"features": "API;AuthorApex;ServiceCloud;DebugApex", | ||
"settings": { | ||
"orgPreferenceSettings": { | ||
"s1DesktopEnabled": true | ||
}, | ||
"securitySettings": { | ||
"sessionSettings": { | ||
"sessionTimeout": "TwelveHours" | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# TODO: data | ||
|
||
### What type of files should be kept in this directory? | ||
|
||
This directory should contain only the following files or file types. | ||
|
||
``` | ||
README.md -- This file | ||
*-meta.xml -- Specific metadata type files | ||
.gitignore -- Configured to exclude all other files | ||
``` | ||
|
||
### How are these files used? | ||
|
||
The files in this directory are used in the following ways. | ||
|
||
* Used like this | ||
* Used like that | ||
* Used like this | ||
|
||
### Why are these files located here within the SFDX-Falcon project framework? | ||
|
||
This directory and the files it contains are located here within the SFDX-Falcon project framework because... | ||
|
||
* Reason one | ||
* Reason two | ||
* Reason three | ||
|
||
## Relevant Documentation | ||
|
||
* [FlexiPage Type][1] - Specific Metadata Type Reference | ||
* [Metadata Types][2] - General Metadata Type Reference | ||
* [Metadata Components and Types][3] - Supplemental Reference | ||
* [Unsupported Metadata Types][4] - Supplemental Reference | ||
|
||
[1]: https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_flexipage.htm | ||
[2]: https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_types_list.htm | ||
[3]: https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_objects_intro.htm | ||
[4]: https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_unsupported_types.htm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/* | ||
debug_logger cleanup processor | ||
Cleans old records from the system | ||
Marc D Behr | ||
*/ | ||
|
||
global class DebugCleanup implements Database.batchable<sObject> { | ||
|
||
global Database.QueryLocator start(Database.BatchableContext BC) { | ||
Integer daysToKeep; | ||
if(Test.isRunningTest()) { | ||
daysToKeep = 2; // in the future to ensure that all logs will be deleted when running tests | ||
} else { | ||
// look for the local settings | ||
Debug_Logger_Setting__mdt[] localSettings = [Select Days_To_Keep__c from Debug_Logger_Setting__mdt where DeveloperName = 'Local']; | ||
if(null != localSettings) { | ||
daysToKeep = Integer.valueOf(-(localSettings[0].Days_To_Keep__c)); | ||
} else { | ||
daysToKeep = -2; // default to 2 days ago | ||
} | ||
} | ||
|
||
String dateString = String.valueof(Date.today().adddays(daysToKeep)).substringBefore(' ')+'T00:00:00Z'; | ||
system.debug('Selecting records before ' + dateString); | ||
|
||
String query = 'select id from debuginfo__c where Created_Time__c < '+dateString ; | ||
return Database.getQueryLocator(query); | ||
} | ||
|
||
global void execute(Database.BatchableContext BC, List<debuginfo__c> scope){ | ||
delete scope; | ||
DataBase.emptyRecycleBin(scope); | ||
} | ||
|
||
global void finish(Database.BatchableContext BC) | ||
{ | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata"> | ||
<apiVersion>47.0</apiVersion> | ||
<status>Active</status> | ||
</ApexClass> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/* | ||
debug_logger cleanup processor | ||
Tests the class that cleans old records from the system | ||
Marc D Behr | ||
*/ | ||
|
||
@isTest | ||
private class DebugCleanupTest { | ||
static list<DebugInfo__c> debugInfoList ; | ||
|
||
@TestSetup static void createRecords() { | ||
debugInfoList = new list<DebugInfo__c> (); | ||
|
||
for (integer i = 0; i < 200; i++) { | ||
debugInfoList.add(new DebugInfo__c(DebugData__c = 'Test ' + i)); | ||
} | ||
insert debugInfoList; | ||
} | ||
|
||
static testMethod void DebugLogsAreDeletedWhenBatchIsRun() { | ||
debugInfoList = [Select Id from DebugInfo__c]; | ||
system.AssertEquals(200,debugInfoList.size()); | ||
Test.startTest(); | ||
Database.executeBatch(new DebugCleanup()); | ||
Test.stopTest(); | ||
debugInfoList = [Select Id from DebugInfo__c]; | ||
system.AssertEquals(0,debugInfoList.size()); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata"> | ||
<apiVersion>47.0</apiVersion> | ||
<status>Active</status> | ||
</ApexClass> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/* | ||
DebugLog class | ||
provides a method of saving logs in a custom object | ||
Methods: | ||
DebugLog(String CallerIdentification) | ||
CallerIdentification is a string that identifies the process that created the entry | ||
saveLog(String LogEntry) | ||
LogEntry is a string that provides the data to be logged | ||
can be called multiple times to append to the log | ||
commitLog(String LogEntry) | ||
LogEntry is a string that provides data to be logged | ||
Calling this method saves the data in the custom object and clears the log string | ||
(but leaves the CallerIdentification intact) | ||
Marc D Behr | ||
*/ | ||
|
||
public with sharing class DebugLog { | ||
|
||
private String logData { set; get { if (logData == null) { logData = ''; } return logData; } } | ||
private string caller { set; get; } | ||
private Boolean publishEvent { set; get; } | ||
public string endPoint { public set; private get { if (endPoint == null) { endPoint = 'undefined'; } return endPoint; } } | ||
|
||
|
||
public DebugLog(String procedure) { | ||
caller = procedure; | ||
Debug_Logger_Setting__mdt[] localSettings = [Select Publish_Events__c from Debug_Logger_Setting__mdt where DeveloperName = 'Local']; | ||
if(null != localSettings) { | ||
publishEvent = true; // publish by default | ||
} else { | ||
publishEvent = localSettings[0].Publish_Events__c; | ||
} | ||
} | ||
|
||
public void saveLog(String entry) { | ||
logData += entry + '\n'; | ||
} | ||
|
||
public void commitLog(String entry) { | ||
logData += entry + '\n'; | ||
try { | ||
DebugInfo__c debugInfo = new DebugInfo__c( | ||
Caller__c = caller.abbreviate(SObjectType.DebugInfo__c.Fields.Caller__c.Length), | ||
DebugData__c = obscurePasswords(logData).abbreviate(SObjectType.DebugInfo__c.Fields.DebugData__c.Length), | ||
EndPoint__c = endPoint.abbreviate(SObjectType.DebugInfo__c.Fields.EndPoint__c.Length) | ||
); | ||
insert debugInfo; | ||
|
||
if (publishEvent) { | ||
// publish the platform event | ||
Debug_Log__e debugEvent = new Debug_Log__e( | ||
Caller__c = caller.abbreviate(SObjectType.Debug_Log__e.Fields.Caller__c.Length), | ||
DebugData__c = obscurePasswords(logData).abbreviate(SObjectType.Debug_Log__e.Fields.DebugData__c.Length), | ||
EndPoint__c = endPoint.abbreviate(SObjectType.Debug_Log__e.Fields.EndPoint__c.Length) | ||
); | ||
system.debug(debugEvent); | ||
EventBus.publish(debugEvent); | ||
} | ||
|
||
logData = ''; | ||
|
||
} | ||
|
||
catch(Exception e) { | ||
//silently ignore | ||
system.debug('Exception occurred: ' + e.getMessage()); | ||
} | ||
} | ||
|
||
private string obscurePasswords(string input) { | ||
// replace any passwords with *'s in the logged messages | ||
return input.replaceAll('([pP]assword)=([^,\\s]+)\\s?', '$1=******'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata"> | ||
<apiVersion>47.0</apiVersion> | ||
<status>Active</status> | ||
</ApexClass> |
13 changes: 13 additions & 0 deletions
13
force-app/main/default/classes/DebugLoggerCleanupScheduler.cls
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/* | ||
debug_log cleanup scheduler | ||
Schedules the job that cleans old records from the system | ||
Marc D Behr | ||
*/ | ||
|
||
public with sharing class DebugLoggerCleanupScheduler implements Schedulable { | ||
public void execute(SchedulableContext sc) { | ||
database.executebatch(new DebugCleanup()); | ||
} | ||
} |
5 changes: 5 additions & 0 deletions
5
force-app/main/default/classes/DebugLoggerCleanupScheduler.cls-meta.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<ApexClass xmlns="urn:metadata.tooling.soap.sforce.com" fqn="DebugLoggerCleanupScheduler"> | ||
<apiVersion>47.0</apiVersion> | ||
<status>Active</status> | ||
</ApexClass> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
debug_logger test classes | ||
Test the functionality of the main logger | ||
Marc D Behr | ||
*/ | ||
|
||
@isTest | ||
private class DebugTest { | ||
static list<DebugInfo__c> debugInfoList = new list<DebugInfo__c> (); | ||
static DebugLog debugLogs; | ||
static String realyBigString = '01234567890 error '.repeat(2200); // oversized string | ||
static String debugLogQuery = 'Select Id,DebugData__c from DebugInfo__c'; | ||
|
||
static testMethod void LoggedPasswordsAreObscured() { | ||
Test.startTest(); | ||
debugLogs = new DebugLog('DebugTest'); | ||
debugLogs.commitLog('Test0,Password=ABc123,'); | ||
Test.stopTest(); | ||
debugInfoList = (list<DebugInfo__c>) database.query(debugLogQuery); | ||
system.assertequals(1, debugInfoList.size()); | ||
system.assert(debugInfoList[0].DebugData__c.contains('Test0')); | ||
system.assert(debugInfoList[0].DebugData__c.contains('Password=*****')); | ||
} | ||
|
||
static testMethod void LongStringsAreTruncated() { | ||
Test.startTest(); | ||
debugLogs = new DebugLog('DebugTest'); | ||
debugLogs.saveLog('Test'); | ||
debugLogs.commitLog(realyBigString); | ||
Test.stopTest(); | ||
debugInfoList = (list<DebugInfo__c>) database.query(debugLogQuery); | ||
system.assertequals(1, debugInfoList.size()); | ||
system.assertequals('...', debugInfoList[0].DebugData__c.right(3)); | ||
system.assertequals(SObjectType.DebugInfo__c.Fields.DebugData__c.Length, debugInfoList[0].DebugData__c.length()); | ||
} | ||
|
||
static testMethod void LogsAreNotWrittenDuringReadOnlyMode() { | ||
// Set the application read only mode. | ||
Test.setReadOnlyApplicationMode(true); | ||
Test.startTest(); | ||
debugLogs = new DebugLog('DebugTest'); | ||
debugLogs.commitLog('ReadOnlyModeTest'); | ||
Test.stopTest(); | ||
debugInfoList = (list<DebugInfo__c>) database.query(debugLogQuery); | ||
system.assertequals(0, debugInfoList.size()); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata"> | ||
<apiVersion>47.0</apiVersion> | ||
<status>Active</status> | ||
</ApexClass> |
Oops, something went wrong.