Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add configurable rules for advanced log retention policies #226

Open
jongpie opened this issue Oct 12, 2021 · 4 comments · Fixed by #298
Open

Add configurable rules for advanced log retention policies #226

jongpie opened this issue Oct 12, 2021 · 4 comments · Fixed by #298
Assignees
Labels
Feature: Log Retention Items related to LogBatchPurger or LogBatchPurgeScheduler Feature: Plugin Framework Items related to Nebula Logger's plugin framework Layer: Log Management Items related to the custom objects & Logger Console app Plugin: Log Retention Rules Items related to the plugin Log Retention Rules Type: Enhancement New feature or request

Comments

@jongpie
Copy link
Owner

jongpie commented Oct 12, 2021

Hey, @jongpie we discussed cases where we use the logger and came up with a similar idea. Potentially we will create a lot of logs per day and in most cases, they aren't really relevant to be stored for always. We looked into your Batch Deletion feature. But as far as we understand the feature does delete all logs after x days regardless of whether there is only info, an error, or in which context the log was created. What are your thoughts on setting up multiple retention rules depending on the scenario and included error?

For example:

  • We have feature A which is very important. Logs of this feature must not be deleted at all.
  • For Feature B we want to see the logs for 5 days. Then they can be deleted. Except there was an error. Then they should be deleted after 30 days.
  • Feature C isn't really important. Logs should be deleted after 3 days.

All of the features have an identifier using the scenario field. And then there could be a custom metadata type where you can define a scenario, a retention day, and whether error logs should be skipped. For all logs without any scenario, you can have a default setting.

We probably will develop such a feature, but wanted to discuss it with you before. Maybe you say, that it might be relevant in general, then we can find some synergies.

Originally posted by @fentes in #207 (comment)

@jongpie jongpie added Type: Enhancement New feature or request Layer: Log Management Items related to the custom objects & Logger Console app Layer: Configuration Items related to the custom hierarchy setting LoggerSettings__c or any included custom metadata type labels Oct 12, 2021
@jongpie jongpie self-assigned this Oct 12, 2021
@jongpie jongpie added the Feature: Log Retention Items related to LogBatchPurger or LogBatchPurgeScheduler label Oct 15, 2021
@jongpie jongpie changed the title Add configurable rules for advanced log retention policies Add configurable rules for log scenario logging levels Oct 25, 2021
@jongpie jongpie changed the title Add configurable rules for log scenario logging levels Add configurable rules for advanced log retention policies Oct 25, 2021
jongpie added a commit that referenced this issue Oct 28, 2021
This plugin complements the log retention functionality in LoggerSettings__c & the LoggerScenarioRule__mdt objects
The plugin's code is based on my other repo, ApexValidationRules - I've repurposed the core code to be used for configuring log retention rules & conditions
jongpie added a commit that referenced this issue Oct 28, 2021
This plugin complements the log retention functionality in LoggerSettings__c & the LoggerScenarioRule__mdt objects
The plugin's code is based on my other repo, ApexValidationRules - I've repurposed the core code to be used for configuring log retention rules & conditions
@jongpie jongpie added Feature: Plugin Framework Items related to Nebula Logger's plugin framework and removed Layer: Configuration Items related to the custom hierarchy setting LoggerSettings__c or any included custom metadata type labels Jan 11, 2022
jongpie added a commit that referenced this issue May 2, 2022
…on Rules plugin (#298)

- Replaced `LoggerSObjectHandlerPlugin` abstract class with new class `LoggerPlugin` that contains 2 interfaces + helper methods, switched to using multiple fields on `LoggerPlugin__mdt` to indicate Apex classes & Flows to run for a plugin, removed SObject-specific fields on `LoggerPlugin__mdt`, added new fields `Log__c.LogPurgeAction__c` and `LoggerSettings__c.DefaultLogPurgeAction__c`

- Added support for plugins within LogBatchPurger + added archiving in BigObject plugin (#288)

- Added SObject-specific 'execution order' fields on `LoggerPlugin__mdt`

- Added picklist values for API versions in calendar year 2022

- Reintroduced the ability to disable trigger handler classes by adding new `LoggerParameter__mdt` records to control via configuration

- Renamed CMDT records that control each trigger handler

- Added new abstract methods in LoggerSObjectHandler for retrieving each handler's related records in `LoggerParameter__mdt` & `LoggerPlugin__mdt`

- Added the ability to configure the list of save methods shown in `loggerSettings` LWC via `LoggerParameter__mdt`, using the prefix 'CustomSaveMethod'

- Standardized test-visible method naming conventions to start with `setMock` & updated approaches to use a Map instead of List for CMDT records

- Fixed issues in LoggerSObjectHandler for invalid Apex & Flow plugins, started new test class LoggerSObjectHandler_Tests

- Added `Log__c` list view to show logs that will be purged in the next 10 days, fixed LogEntryArchiveBuilder using the wrong value for LoggedById**c, updated index on LogEntryArchive**b again (still a WIP), retrieved & formatted metadata for LogEntryArchive\*\*b, updated Admin.profile

- Closed #226 by adding new "Log Retentions Rule" plugin, based on my other project, ApexValidationRules

- @jamessimone closed #117, and I closed #228 by adding new "Big Object Archiving" plugin

- Lowercased the plugin directories

- Added plugins folder to the script for generating apex doc files, generated updated docs for Apex

- Bumped package version number for the managed package

- Added 5 minute wait between unlocked package version creation & package installation, added deprecated `LoggerPlugin__mdt` validation rule & field back into the managed-package folder, cleaned up some docs markdown files

- Added tests in LoggerSettingsController_Tests & LogHandler_Tests for new custom setting LoggerSettings**c.DefaultLogPurgeAction**c

- Added 'deprecated' to the label of several deprecated fields on `LoggerPlugin__mdt` & removed the related handler methods

- More improvements for CMDT records used in the classes LoggerParameter & LoggerPlugin

  - Added LoggerParameter.matchOnPrefix() to return CMDT records with a specified prefix in the DeveloperName field
  - Added inner Comparable class in LoggerPlugin to handle custom sorting, since there are some limitations with SOQL queries for CMDT
  - Classes like LogBatchPurger, LoggerSObjectHandler, and LoggerSettingsController no longer need to track their own mock CMDT records, the LoggerPlugin & LoggerParameter classes now fully handle mocks for their corresponding CMDT objects
  - LoggerParameter & LoggerPlugin now require mock CMDT records to have DeveloperName populated - they'll throw errors if the field is null
  - Also added System namespace to some calls for Test.isRunningTest() to handle crazy orgs that have a custom Test class deployed

- Added the ability to disable all triggers during tests via new @testvisible method LoggerSObjectHandler.shouldExecute(Boolean)

- Moved LoggerTestUtils to the configuration folder, added public methods for mocking all CMDT records

- Consolidated plugin-framework folders back into the configuration folders

- Moved demo experience cloud metadata under config, instead of under nebula-logger, updated build.yml to deploy instead of push metadata

- Updated test classes to use new overloads for LoggerTestUtils.setMock()

- Added new class LoggerDataStore to centralize all database, event bus & queueable operations

- Closed #193 by adding classes `LoggerMockDataCreator` for generic mock & data creation (part of configuration layer), `LoggerTestConfigurator` forNebula Logger-specific mocking & setup (part of the log-management layer), and `LoggerMockDataStore` for mocking database & event bus operations throughout the codebase

- Started work on #292 by adding businessStatus, complianceGroup & securityClassification nodes to several custom fields (still a WIP)

- Rewrote tests in `LogEntryEventBuilder_Tests` to use new methods in `LoggerMockDataCreator` for creating mock instances of database result classes

- Scope creep: added fallback fields for setting `RecordName__c` in LogEntryHandler on objects that don't have a display name field, also added some caching

- Moved permissionSets and customPermissions folders from configuration to log-management

  - This should make the configuration folder fully standalone (i.e., it could be deployed by itself)
  - The perm sets were already referencing all of the objects within log-management, so it seems like it's better to keep the perm sets organized with

- Changed labels to just "Entry #" on both `LogEntryEvent__e` and `LogEntryArchive__b`

- Fixed an issue in `LogEntryEventBuilder` where some stack trace lines would be duplicated

- Scope creeped a bit by adding new fields `DatabaseResultCollectionSize__c` and `RecordCollectionSize__c` - I had planned to add these as part of #222, but decided to add them now so I could duplicate the fields to the `LogEntryArchive__b` big object as well. This also helped to identify (and fix) some issues with missing asserts in LogEntryEventHandler_Tests.

- Replaced settings field `IsPlatformEventStorageEnabled__c` with new field `DefaultPlatformEventStorageLocation__**__c`, providing a way for plugins (big object plugin in particular) to provide additional storage location. The big object plugin provides a custom option BIG_OBJECT, in addition to the default value CUSTOM_OBJECTS that will now be used out of the box

- Added stack trace fields to the Slack message created via SlackLoggerPlugin

- Updated most test classes to use `@IsTest(isParallel=true)`. A few tests (especially integration tests) that do DML on User can't use parallel testing, but most test classes are now using it

- Partially implemented #240 by adding HTTP Request & HTTP Response fields to `LogEntryEvent__e`, `LogEntry__c` and `LogEntryArchive__b`. More scope creep yet again, but this will save some headaches long term - since Big Objects can't (easily) have new fields added, I wanted to go ahead and get these new fields added to the data model before the first release of the Big Object plugin. I'll probably add some logging overloads in Logger for these items in a future release, but for now, only LogEntryEventBuilder has new methods for HttpRequest & HttpResponse

- Updated some internal debug messages in various places to use Logger's logging methods, instead of `System.debug()`

- Deprecated the fields `LogEntryDataMaskRule__mdt.ApplyToMessage__c` and `LogEntryDataMaskRule__mdt.ApplyToRecordJson__c`

- Fixed test failures that occur when email deliverability is disabled in an org

Co-authored-by: James Simone <[email protected]>
@jongpie jongpie added the Plugin: Log Retention Rules Items related to the plugin Log Retention Rules label Jun 28, 2022
@fentes
Copy link

fentes commented Aug 26, 2022

Hey @jongpie,

as promised, I wanted to share my feedback to the new plugin. Currently we have the issue, that the rules are not working (see #354 ), but a few weeks ago I was able to test it and there it was working.

In general, this feature is amazing and really helps to keep overview of everything and not blowing up the database with tons of logs. Since we are logging user inputs as part of the customer community, we need to keep these logs forever, if there are any discussions with user. But other logs are just interesting for debugging purposes and can be deleted aber some days.

Together with the rest of my team, we brainstormed about setting up the rules:

  • Technically a rule consists of at least 2 metadata records (rule & 1+ rules). Since the management of custom metadata is not as easy as inserting everything via data loader, the setup is hard work, when doing by hand
  • We defined our rules in a csv file, based on Scenario and Errors, converted the csv to JSON, installed your CustomMetadataSaver and wrote a small script to insert everything. It worked fine for us, but I guess users without coding skills have to do it manually then.
  • Since we have many different scenarios used, it will be a many rules. But we discovered, that most of them are quite similar. As mentioned above, we want to keep logs about user inputs of the customer portal forever, Error logs from the portal maybe for a year, some features some days, and a specific feature some other days. So our idea was, to combine rules

Currently we don't completly understand all capabilities of this tool. Maybe you can give some insights, of what is possible 😉

  • What happens, if a log is matching with multiple rules? Which rule is used then? Can we influence the order?
  • To combine some rules, I was trying to use tags instead of scenarios. Is that somehow possible? Workaround we discovered is to add a prefix to the scenario and use the contains operator: "Portal: Feature A" + "Portal: Feature B" to group all Portal stuff
  • At which time, the date is calculated? So Rollup Summaries are working, but are also formula fields possible? Would it be possible to use Apex Rollup, to get the tag to the log and use the rules then? Maybe it is possible to rerun the calculation for some logs (Or am I thinking to complex?)
  • Is it easily possible to define the days in the call. For example: Logger.setRetentionDays(30);
  • Which objects can be used: Log__c (of course), but also LogEntry__c (the documentation sounded a bit like that)
  • The conditions have a mandatory relationship to to the rule. Are there some ways to reuse conditions? For example: "Is there an error" will be used quite often, and creating 30 conditions that all look the same, just with different rule assigned

@jongpie
Copy link
Owner Author

jongpie commented Aug 31, 2022

Hi @fentes - this is some incredible feedback, thanks so much for brainstorming with your team & sharing everyone thoughts! I have a couple of follow up thoughts & questions for you & your team

  • In general, this type of configuration data feels like it should be stored in a custom metadata type, especially since custom metadata type records can be deployed easily between environments. But since this is a plugin, I'm open to doing things a bit differently for this - do you think it would be better to use some custom objects to store the rules & conditions? Salesforce has a much better UI for custom objects, and the data could be exported/imported between environments (not quite as easily as deploying custom metadata types, but it's still feasbile)
    • Another possible option is to only have a LogRetentionRule__mdt record, and instead of using the child object LogRetentionRuleCondition__mdt, it could do something similar to the cleverness that @jamessimone has implemented for Apex Rollup, and just use a single WHERE clause field that the code parses. This would let you create a single, deployable custom metadata record with all of the relevant conditions (using SOQL syntax), although there would be some additional effort needed to implement the parsing logic
  • I think it's great to hear that you were able to use my CustomMetadataSaver repo to help with this - I think the better option would of course be for Salesforce to improve the UI for creating custom metadata type records, but glad that you were able to find a workaround to make it a little easier.

Regarding your other questions, I've added my responses below each question - hopefully this format is readable, but let me know if you have any follow up questions

  • What happens, if a log is matching with multiple rules? Which rule is used then? Can we influence the order?
  • To combine some rules, I was trying to use tags instead of scenarios. Is that somehow possible? Workaround we discovered is to add a prefix to the scenario and use the contains operator: "Portal: Feature A" + "Portal: Feature B" to group all Portal stuff
    • At the moment, tags cannot be used for the log retention rules plugin. It might be possible to incorporate that in the future, but it would involve some bigger changes to how the plugin is currently built. Let me know if you think this would be useful, I'm happy to explore this idea (I think it's a great idea).
  • At which time, the date is calculated? So Rollup Summaries are working, but are also formula fields possible? Would it be possible to use Apex Rollup, to get the tag to the log and use the rules then? Maybe it is possible to rerun the calculation for some logs (Or am I thinking to complex?)
    • This would require some small changes to the log retention rules plugin - it currently only runs AFTER_INSERT for the LogEntry__c object - in order to work like you're suggesting, the plugin would need to also run for the LogEntryTag__c object and/or run on AFTER_UPDATE on the LogEntry__c object
  • Is it easily possible to define the days in the call. For example: Logger.setRetentionDays(30);
    • This isn't currently possible, but I like the idea. I'll do some exploration on if this could be implemented.
  • Which objects can be used: Log__c (of course), but also LogEntry__c (the documentation sounded a bit like that)
    • Both LogEntry__c and Log__c should work. In your screenshot on Log Retention Rules are not working #354, you are already specifying Log__r.Scenario__c to use the Log__c object, so if you want to use a field on LogEntry__c, you would just specify the condition's field with the API name of the LogEntry__c field (such as OriginType__c, etc.)
  • The conditions have a mandatory relationship to to the rule. Are there some ways to reuse conditions? For example: "Is there an error" will be used quite often, and creating 30 conditions that all look the same, just with different rule assigned
    • At the moment, there's not a way to re-use them. I could possibly add a third custom metadata type object to act as a junction object between LogRetentionRule__mdt and LogRetentionRuleCondition__mdt, but that would make the initial setup even more cumbersome for all of the rules. Let me know what you think of this idea

Thanks again for all of your feedback!

@fentes
Copy link

fentes commented Aug 31, 2022

Hey @jongpie,

  • Single rule record + Where clause:
    • I really like that approach! Then I guess you need a picklist field to define the object (Log, Entry,...). I'm quite interested in how the logic behind looks like, because I can use it for something else as well 😁
    • I totally agree with you, that these rules should be custom metadata. Storing logic in custom objects is always a pain in the ass, both when deploying to production and refreshing a sandbox.
  • Order of Execution
    • Ok cool, that is helpful
  • Using tags in rules
    • If you need to change a lot in the background, I would leave it out then
  • Logger.setRetentionDays(30);
    • If you think that this is easier to achieve than using tags, it might be solving a similar problem and is then fine enough
    • Maybe it is then also possible to not set the days as an integer but the name of a rule, to easily adjust the days, without changing the code.
  • Time of calculation
    • Running the calculation also in AFTER_UPDATE could solve some issues. Would that have some bad impact on performance? Not sure whether BEFORE_UPDATE (in case of Log__c) would do behave the same with less impact (saving update one DML)
  • Reusing rule conditions
    • when going with the approach of WHERE clauses, this becomes obsolet (at least of the where allows OR)
    • I wouldn't go with a separate junction object. If the rules would be stored in a custom object, that might be okay, but for custom metadata, it would be too complex for too less benefits.

@jongpie
Copy link
Owner Author

jongpie commented Aug 31, 2022

@fentes thanks for the feedback! I'm going to try to do 3 things:

  1. Over the next few weeks, I'm going to try to fix the existing implementation so that it works as intended (to resolve Log Retention Rules are not working #354)
  2. I'll also try to make some small enhancements to support more trigger events (at least BEFORE_UPDATE and/or AFTER_UPDATE), and try to add support for additional objects like LogEntryTag__c
  3. Over the next few months, I'm going to see about eliminating LogRetentionRuleCondition__mdt altogether, and instead changing the implementation to use a single field on LogRetentionRule__mdt to specify SOQL-style filtering syntax (like @jamessimone does for Apex Rollup). This will be a fairly complex change, but I'd like to try to at least create a proof of concept of this idea, as I think this would be a nicer setup.

I have a few other releases that I need to finish before I can work on this, but I'll keep you updated on my progress.

And since we're having some great discussions here, I'm re-opening this issue for now - I'll close it again once I've implemented some of the above items.

@jongpie jongpie reopened this Aug 31, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature: Log Retention Items related to LogBatchPurger or LogBatchPurgeScheduler Feature: Plugin Framework Items related to Nebula Logger's plugin framework Layer: Log Management Items related to the custom objects & Logger Console app Plugin: Log Retention Rules Items related to the plugin Log Retention Rules Type: Enhancement New feature or request
Projects
None yet
2 participants