[Coldbox 4] Adding LogBox to Modules

I currently have LogBox running on our application and write to the log file using something like: log.info(“The user #username# has now logged in.”);

I want to add logging to the modules as well. I tried just to use the log. notation but that did not work. I also tried to add the LogBox DSL to my ModuleConfig.cfc file as well as it’s own logs folder. Any ideas?

My ModuleConfig file has…

//LogBox DSL
logBox = {
appenders = {
coldboxTracer = {class=“coldbox.system.logging.appenders.ConsoleAppender”},
logFile = {class=“coldbox.system.logging.appenders.RollingFileAppender”,
properties = {fileMaxArchives=30, //Keep last 30 days
filename = “admin”,
filePath=“logs”,
async=“true”}
}
},
// Root Logger
root = { levelmax=“INFO”, appenders="*" },
// Implicit Level Categories
info = [ “coldbox.system” ]
};

“log” is a variable that contains a LogBox logger that is automatically injected into ColdBox handlers, etc. This is true in modules as well. LogBox settings are application wide, though it is possible for a module to programmatically modify the site-wide config.

I assume that your issue has nothing to do with modules, and is simply due to the fact that you are trying to log from a file that does not have LogBox appender already injected into it. Models are an example of this.

To fix, simply inject a logger at the top like so:

property name=“log” inject=“logbox:logger:{this}”;

That will give you a variables.log that is a logger named after the CFC you’re in, just like you’re used to having automatically in handlers and such.

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Yep, I was trying to log from a model. The inject allows me to log to our main log file now. Is it possible to log more than 1 log file. We are trying to have separate log files for each module.

Thanks,
Chad

Absolutely. LogBox is super powerful. What you need to do is create multiple appenders-- one for each log file. Then assign the appenders to the correct loggers (or logging categories as we sometimes call them).

By default (logbox:logger:{this}) will name each logger after the actual CFC path. So, an example name might be “modules.foo.models.myService”. LogBox’s config allows you to assign a list of appenders to a single category. You can also specify the first part of the logger name and it will be treated as a dot-delimited hierarchy. Ex from the docs:

categories = {
	"com.model.myservice" = {levelMax="ERROR",appenders="MyTwit" },
	"org.model.EmailService" = {appenders="MyLogFileAppender,Console"}
}

Note that struct above goes inside the “logbox” struct. I would dump out log.getCategory() to confirm what the category name is. Then your config can basically do something like this:

categories = {
“modules.module1” = {appenders=“module1Appender” },
“modules.module2” = {appenders=“module2Appender” },
“modules.module2” = {appenders=“module2Appender” }
}

So now, ALL loggers from within module1 (modules.module1.model.foo, modules.module1.models.bar, modules.module1.handlers.home, etc, etc) will now use the “module1appender” appender.

And finally, for extra credit you can wrap this all up nicely in your ModuleConfig.cfc for each module by programatically adding this config when each module loads so it’s truly encapsulated in your module. Check the docs for for how to programatically add config.

http://wiki.coldbox.org/wiki/LogBox.cfm#Programmatic_Configuration

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Cool, thanks!

OK, so I broke it out into multiple log files but it seems when I force an error in my admin module, it will log the error to ALL logs…

“ERROR”,“THELOGNAMEHERE”,“05/08/2015”,“08:09:15”,“coldbox.system.Bootstrap”,"Error: Error Executing Database Query…

I think it’s because the error is coming from “coldbox.system.Bootstrap” and I do not have a category for that since it is too generic to assign to a specific log. My ColdBox.cfc has…

//LogBox DSL
logBox = {
appenders = {
coldboxTracer = {class=“coldbox.system.logging.appenders.ConsoleAppender”},
systemLog = {class=“coldbox.system.logging.appenders.RollingFileAppender”,
properties = {fileMaxArchives=30, //Keep last 30 days
filename = “system”,
filePath=“logs”,
async=“true”}
},
login = {class=“coldbox.system.logging.appenders.RollingFileAppender”,
properties = {fileMaxArchives=30, //Keep last 30 days
filename = “login”,
filePath=“logs”,
async=“true”}
},
adminLog = {class=“coldbox.system.logging.appenders.RollingFileAppender”,
properties = {fileMaxArchives=30, //Keep last 30 days
filename = “admin”,
filePath=“logs/modules”,
async=“true”}
}
},
// Root Logger
root = { levelmax=“INFO”, appenders=“coldboxTracer,systemLog” },
// Implicit Level Categories
info = [“coldbox.system”],
// Granular Categories
categories = {
“coldbox.system” = {appenders=“systemLog”},
“coldbox.system.web.services.ModuleService” = {appenders=“systemLog”},
“coldbox.system.ioc.Injector” = {appenders=“systemLog”},
“myApp.handlers.security” = {appenders=“login”},
“modules.admin” = {appenders=“adminLog”}
}
};

Hmm, that should inherit from this line I think:

“coldbox.system” = {appenders=“systemLog”},

Just to confirm, you don’t have appenders="*" anywhere in your config, right?

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Nope, no appenders="*"

I had to add the following two lines as well or they showed up in all logs:

“coldbox.system.web.services.ModuleService” = {appenders=“systemLog”},

“coldbox.system.ioc.Injector” = {appenders=“systemLog”},

I was thinking “coldbox.system” = {appenders=“systemLog”} should have covered those but it did not

If this is something you can easily replicate in an empty application, can you put in a ticket with the test config so we can check for a bug?

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

I think it got it figured out now. Thanks for all the help!

Glad to hear. Can you share what the issue was?

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Well I wasn't actually using a log.error() to write to a log. I thought it would automatically throw an error I to a the log for that area. I created a response bean now which works with a try catch. On a catch I log the catch error in a response log and a log based on the handler/model which it came from.

There is an interceptor for missing handlers, that would probably be better than a try catch.

http://wiki.coldbox.org/wiki/Interceptors.cfm#Core_Interception_Points

Which means you can write an interceptor like this.

component extends=“coldbox.system.Interceptor” singleton {

property name=“log” inject=“logbox:logger:{this}”;

public void function onInvalidEvent(event, interceptData) {
log.info(“Something to log here…”);
}
}