From: Kevin G. <ke...@go...> - 2003-02-27 16:57:35
|
Back in December, I quietly released the DOMConfigurator module, adding the ability to initialize log4perl via an XML file rather than a properties config file. This lets you validate the config syntax against a DTD, for instance using Xerces' "StdInParse -v -ns < yourconfig.xml". That release supported the log4j dtd, at least where the features had been implemented in log4perl. But we've added config options in log4perl that log4j doesn't have: #1) oneMessagePerAppender global setting log4perl.oneMessagePerAppender=1 #2) globally defined user conversion specifiers log4perl.PatternLayout.cspec.G=sub { return "UID $< GID $("; } #3) appender-local custom conversion specifiers log4j.appender.appndr1.layout.cspec.K = sub {return sprintf "%1x", $$ } #4) nested options log4j.appender.jabbender = Log::Dispatch::Jabber #(note how these are nested under 'login') log4j.appender.jabbender.login.hostname = a.jabber.server log4j.appender.jabbender.login.port = 5222 log4j.appender.jabbender.login.username = bobjones #5) not to mention Mike's new filter stuff!! So we needed to extend the log4j dtd to cover these additions. Now I could have just taken a 'steal this code' approach and mixed parts of the log4j dtd into a log4perl dtd, but that would be cut-n-paste programming. So I've used namespaces and *) replaced three elements: <log4perl:configuration> handles #1) and accepts <PatternLayout> <log4perl:appender> accepts <param-nested> and <param-text> <log4perl:layout> accepts custom cspecs for #3) *) added a <param-nested> element (complementing the <param> element) to handle #4) *) added a root <PatternLayout> element to handle #2) *) added <param-text> which lets you put things like perl code into escaped CDATA between the tags, so you don't have to worry about escaping characters and quotes *) added <cspec> In the name of code re-use the log4perl dtd links to the log4j dtd, which I've named "log4j-1.2.dtd" to protect us from changes on the log4j side. The benefit of this approach over cut-n-paste is that it re-uses the log4j dtd in situ. The drawback is that it requires an extra namespace prefix in the config--if you want to use log4perl features in an appender then you have to say <log4perl:appender...> instead of just <appender...>. Though that could also be a benefit--if you're in a situation where you're managing both log4j and log4perl configs (god forbid!) it would help to keep them straight. Now the parser I'm using, XML::DOM, isn't namespace aware, it's only DOM Level 1. XML::GDOME, on the other hand, is DOM Level 2 (with namespaces) but depends on libgdome, a requirement which sounds unecessarily cumbersome to me. So the namespace handling in the parser is pretty primitive and it presumes log4perl is the working prefix, as opposed to whatever prefix the URI is bound to. But since DTD's aren't really namespace URI aware either and a DTD is what's supplied to validate against, I don't see that as a huge problem. Attached for your convenience are the log4perl dtd the relevant parts of the log4j dtd a sample xml config The log4perl code in CVS is updated to handle all the new stuff. I'd be interesting in hearing about anything that looks like bad practice or not being flexible/scalable enough. Thanks. -- Happy Trails . . . Kevin M. Goess (and Anne and Frank) 904 Carmel Ave. Albany, CA 94706 (510) 525-5217 |