From 56502c9cadeb8e576ae1b901c5a8b77aa3c42a25 Mon Sep 17 00:00:00 2001 From: Dave L Date: Fri, 13 Oct 2023 06:03:44 -0700 Subject: [PATCH] Add Ability to Exclude LogBox Appenders to Root Logger and Categories (#585) LOGBOX-70 #resolve Add `Exclude` key to Logbox Categories to Easily Exclude Appenders --- system/logging/config/LogBoxConfig.cfc | 35 +++++++++++++++++++-- tests/specs/logging/LogBoxTest.cfc | 42 ++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/system/logging/config/LogBoxConfig.cfc b/system/logging/config/LogBoxConfig.cfc index 0a9bb7115..c7c564312 100644 --- a/system/logging/config/LogBoxConfig.cfc +++ b/system/logging/config/LogBoxConfig.cfc @@ -1,4 +1,4 @@ -/** +/** * Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp * www.ortussolutions.com * --- @@ -155,6 +155,10 @@ component accessors="true" { instance.rootLogger.appenders = structKeyList( getAllAppenders() ); } + if ( len( instance.rootLogger.exclude ) ) { + instance.rootLogger.appenders = excludeAppenders( instance.rootLogger.appenders, instance.rootLogger.exclude ); + } + // Check root's appenders for ( var x = 1; x lte listLen( instance.rootLogger.appenders ); x++ ) { if ( NOT structKeyExists( instance.appenders, listGetAt( instance.rootLogger.appenders, x ) ) ) { @@ -223,10 +227,16 @@ component accessors="true" { * @appenders A list of appenders to configure the root logger with. Send a * to add all appenders * @levelMin The default log level for the root logger, by default it is 0 (FATAL). Optional. ex: config.logLevels.WARN * @levelMax The default log level for the root logger, by default it is 4 (DEBUG). Optional. ex: config.logLevels.WARN + * @exclude a list of appenders to exclude from the root logger * * @throws InvalidAppenders */ - LogBoxConfig function root( required appenders, levelMin = 0, levelMax = 4 ){ + LogBoxConfig function root( + required appenders, + levelMin = 0, + levelMax = 4, + exclude = "" + ){ // Convert Levels convertLevels( arguments ); @@ -262,12 +272,14 @@ component accessors="true" { * @levelMin The default log level for the root logger, by default it is 0 (FATAL). Optional. ex: config.logLevels.WARN * @levelMax The default log level for the root logger, by default it is 4 (DEBUG). Optional. ex: config.logLevels.WARN * @appenders A list of appender names to configure this category with. By default it uses all the registered appenders + * @exclude A list of appender names to exclude from this category */ LogBoxConfig function category( required name, levelMin = 0, levelMax = 4, - appenders = "*" + appenders = "*", + exclude = "" ){ // Convert Levels convertLevels( arguments ); @@ -280,6 +292,11 @@ component accessors="true" { appenders = structKeyList( getAllAppenders() ); } + // filter appenders based on exclusion list + if ( len( arguments.exclude ) ) { + appenders = excludeAppenders( appenders, arguments.exclude ); + } + // Add category registration instance.categories[ arguments.name ] = arguments; @@ -318,6 +335,18 @@ component accessors="true" { return instance.appenders; } + /** + * Exclude appenders from a list of appenders + * + * @appenders A list of appenders to exclude from + * @exclude A list of appenders to exclude + */ + string function excludeAppenders( required string appenders, required string exclude ) { + return listToArray( appenders ).filter( function( item ) { + return !listFindNoCase( exclude, item ); + } ).toList(); + } + /** * Add categories to the DEBUG level. Send each category as an argument. */ diff --git a/tests/specs/logging/LogBoxTest.cfc b/tests/specs/logging/LogBoxTest.cfc index bd33ef5d5..ff8316a10 100755 --- a/tests/specs/logging/LogBoxTest.cfc +++ b/tests/specs/logging/LogBoxTest.cfc @@ -38,6 +38,48 @@ component extends="coldbox.system.testing.BaseModelTest" { logBox.getLogger( "postInitLogger" ).info( "My Test" ); // Fails if appender was not added to internal registry } ); + it( "can exclude appenders from categories", function(){ + var config = logBox.getConfig(); + config.category( name: "noLuis2", appenders: "*", exclude: "luis2" ); + var logger = logBox.getLogger( "noLuis2" ); + // expect luis2 to not be present in the logger + expect( logger.getAppenders().keyArray().findNoCase( "luis2" ) ).toBeFalse(); + } ); + + it( "can exclude appenders from the root", function() { + + logbox = createMock( "coldbox.system.logging.LogBox" ); + config = new coldbox.system.logging.config.LogBoxConfig(); + + // Appenders + config + .appender( name = "luis", class = "coldbox.system.logging.appenders.ConsoleAppender" ) + .appender( name = "luis2", class = "coldbox.system.logging.appenders.ConsoleAppender" ) + .root( appenders = "*", exclude = "luis2" ) + // Sample categories + .OFF( "coldbox.system" ) + .debug( "coldbox.system.async" ) + .category( name: "allAppenders", appenders: "*" ); + + // init logBox + logBox.init( config ); + + // add this configuration after the fact to test another code path + config.category( name = "coldbox.system.web", appenders = "*" ); + + var logger1 = logBox.getLogger( "allAppenders" ); + var logger2 = logBox.getLogger( "coldbox.system.web" ); + + // luis2 should not be in the root appenders + expect( listToArray( config.getRoot().appenders ).findNoCase( "luis2" ) ).toBeFalse(); + + // luis2 should be in the allAppenders and the coldbox.system.web categories + expect( logger1.getAppenders().keyArray().findNoCase( "luis2" ) ).toBeTrue(); + expect( logger2.getAppenders().keyArray().findNoCase( "luis2" ) ).toBeTrue(); + + } ); + + describe( "can retrieve loggers with different category names", function(){ given( "A valid category inheritance trail that is turned off", function(){ then( "it will retrieve the inherited category", function(){