Wait a sec, the DefaultRouteScript should return the Route key, not the Route ref. Right?
Gary On Mon, Sep 12, 2016 at 9:53 PM, Gary Gregory <garydgreg...@gmail.com> wrote: > "First, the init script changes the default route based on the OS." > > Maybe the tag should be called "DefaultRouteScript" since it's job is to > return the default route name? > > Gary > > On Mon, Sep 12, 2016 at 8:05 PM, Ralph Goers <ralph.go...@dslextreme.com> > wrote: > >> After reviewing what I wrote below and looking at the Routing Appender I >> think the best thing to do is just to add script support to it. It already >> has support for a default Route. The init script, if present, could >> override which Route to use as I described below. Then we could add a >> script attribute to the Routes plugin which could be used to select the >> Route instead of only matching on the ThreadContext key. >> >> With that I think you would have everything you want, plus it could be >> used as a more intelligent way to route to existing appenders. >> >> The configuration would then look like: >> >> <Appenders> >> <Console name="STDOUT" target="SYSTEM_OUT"> >> <PatternLayout pattern="%m%n"/> >> </Console> >> <Flume name="AuditLogger" compress="true"> >> <Agent host="192.168.10.101" port="8800"/> >> <Agent host="192.168.10.102" port="8800"/> >> <RFC5424Layout enterpriseNumber="18060" includeMDC="true" >> appName="MyApp"/> >> </Flume> >> <Routing name=?Routing?> >> <InitScript name=?RoutingInit" language="groovy"><![CDATA[ if >> (System.getProperty(?os.name?).contains(?OS/390") { return >> “OS390"; } return null;]]> >> </InitScript> >> <Routes> >> <Script name="Router" language="groovy"><![CDATA[ if >> (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("AUDIT")) >> { return "AUDIT"; } else if >> (logEvent.getContextMap().containsKey("UserId")) { return >> logEvent.getContextMap().get("UserId"); } return >> "STDOUT"; ]]> >> </Script> >> <Route> >> >> <OS390Appender name=“OS390-${mdc:UserId”/> >> <RollingFile name="Rolling-${mdc:UserId}" >> fileName="${mdc:UserId}.log" >> filePattern="${mdc:UserId}.%i.log.gz"> >> <PatternLayout> >> <pattern>%d %p %c{1.} [%t] %m%n</pattern> >> </PatternLayout> >> <SizeBasedTriggeringPolicy size="500" /> >> </RollingFile> >> </Route> >> <Route ref="AuditLogger" key="Audit"/> >> <Route ref="STDOUT" key="STDOUT"/> >> </Routes> >> <IdlePurgePolicy timeToLive="15" timeUnit="minutes"/> >> </Routing> >> </Appenders> >> >> First, the init script changes the default route based on the OS. >> Second, notice that “Routes” has a new Script element and does not have a >> pattern specified, so the script is determining the key instead of the >> pattern. >> Third, the real default route is now “STDOUT” since the actual default >> Route is only referenced when a UserId is present in the thread context map. >> >> What would also be nice is if there was a way to have the returned value >> be usable as a Lookup value in the default Appender definition, instead of >> relying on the MDC as the code above does. I should be able to pick >> something out of the message itself and use that as the key. That should be >> doable but I am still pondering how I would implement that. >> >> Ralph >> >> >> >> On Sep 12, 2016, at 6:06 PM, Ralph Goers <ralph.go...@dslextreme.com> >> wrote: >> >> I’ll try to describe it better but I’m not sure how good a job I’ll do if >> the dots aren’t clicking yet. Also, even though I might say to do it one >> way if I was coding I could very well change my mind as I implement it. >> That said: >> >> 1. Create an Appender plugin named ScriptSelector or >> ScriptAppenderSelector. It needs the following parameters >> - name, a String PluginAttribute >> - default, a String PluginAttribute >> - initScript or startupScript, an AbstractScript PluginElement >> - script, an AbstractScript PluginElement >> - appenderList, an AppenderList PluginElement. >> 2. As always, the builder (or factory) creates an instance of the >> ScriptAppenderSelector. >> - If there is an init script then the builder (or factory) >> executes it. >> - If the returned value is not null then instantiate the Appender >> with that name using the configuration in the AppenderList. >> - Whatever Appender the init script names should become the >> default Appender. >> - If no init script is present or the init script returns null use >> the value of the default setting as the name of the default Appender >> to use. >> - Create the default Appender and save it in the Map of created >> appenders wrapped by an AppenderControl. >> 3. When the append method is called check for a script setting. >> - If a script is found, run it. >> - If it returns a value see if that appender is saved in the >> AppenderMap. >> - If it is, call the appender and return. >> - If it is not, locate the configuration for the appender, >> create it and add it to the AppenderMap. Then call it and return. >> - If it returns null or no script is defined then call the default >> Appender and return. >> 4. When the stop method is called call the stop method on each of the >> Appenders in the AppenderMap. >> >> >> Note that signatures for scripts are defined by the components that use >> them. In this case both the init script and script return the name of the >> appender to execute. >> >> Ralph >> >> >> On Sep 12, 2016, at 12:54 PM, Gary Gregory <garydgreg...@gmail.com> >> wrote: >> >> On Sun, Sep 11, 2016 at 12:47 PM, Ralph Goers <ralph.go...@dslextreme.com >> > wrote: >> >>> Yes. The Appenders tag inside the ScriptSelector are the Appenders that >>> are to be created. But now that I think about it, we can’t use “Appenders” >>> for this. If you look at the RoutingAppender you will notice that Appenders >>> there are declared under a Route element. The Route plugin is defined with >>> deferChildren=true. This means that whatever is configured under the Route >>> will not be created during initial configuration. Instead the Route keeps a >>> reference to the Node and then configures the Appender when it is required. >>> So we would need a new plugin to wrap the Appenders that are to be created. >>> >> >> Can you please describe in more detail how this new plug fits in and what >> it does? I can't quite connect the dots with the parallel of the routing >> appender. I'm willing to implement this as I need the feature ASAP. >> >> Gary >> >> >>> Ralph >>> >>> On Sep 11, 2016, at 11:10 AM, Gary Gregory <garydgreg...@gmail.com> >>> wrote: >>> >>> Are the <Appenders> tags really meant to be nested? >>> >>> Gary >>> >>> On Sat, Sep 10, 2016 at 11:48 AM, Ralph Goers <ralph.goers@dslextreme. >>> com> wrote: >>> >>>> Oops. I forgot the closing CDATA tag in the script. >>>> >>>> Ralph >>>> >>>> On Sep 10, 2016, at 11:43 AM, Ralph Goers <ralph.go...@dslextreme.com> >>>> wrote: >>>> >>>> Interesting. OS/390. I worked on MVS, OS/370, z/OS, etc many moons ago >>>> but haven’t worked on a mainframe since 2001. >>>> >>>> This sort of sounds like you want an Appender Selector, which would be >>>> an Appender that uses a Selector to figure out which Appender to delegate >>>> to. This is a bit like the PatternSelector. I would imagine it would make >>>> sense to implement AppenderSelectors and LayoutSelectors. You probably >>>> would want to dynamically initialize the Appenders much like the >>>> RoutingAppender does. >>>> >>>> Maybe it would look like: >>>> >>>> <Appenders> >>>> <ScriptSelector name=“" default=“”> >>>> <Script language=“groovy”><![CDATA[ >>>> if (System.getProperty”os.name”).contains(“OS/390”)) then { >>>> return “Socket”; >>>> } else { >>>> return “File”; >>>> } >>>> </Script> >>>> <Appenders> >>>> <SocketAppender name=“Socket” …/> >>>> <FileAppender name=“File” …/> >>>> </Appenders> >>>> </ScriptSelector> >>>> </Appenders> >>>> >>>> The thing is that this script would run every time the Selector was >>>> accessed while it sounds like you would only want the script to run when >>>> the Selector is initialized. We could do that too but the script would need >>>> to be declared in a property that would only be used when the selector is >>>> initialized. I would want to support being able to do both. >>>> >>>> Ralph >>>> >>>> On Sep 10, 2016, at 11:04 AM, Gary Gregory <garydgreg...@gmail.com> >>>> wrote: >>>> >>>> <Appenders> >>>> <ScriptTest language="JavaScript"> >>>> <If>System.getProperty("os.name").contains("OS/390")</If> >>>> <True> >>>> <SocketAppender ...> >>>> </True> >>>> <False> >>>> <FileAppender ...> >>>> </False> >>>> </ScriptTest> >>>> </Appenders> >>>> >>>> ? >>>> >>>> >>>> On Sat, Sep 10, 2016 at 10:40 AM, Gary Gregory <garydgreg...@gmail.com> >>>> wrote: >>>> >>>>> OK, I found https://logging.apache.org/log4j/2.x/manual/configurat >>>>> ion.html#Scripts and I think I could use either: >>>>> >>>>> - Use composite configurations: One file for OS/390, one for all other >>>>> OSs; or >>>>> - Do it all in one configuration file (that seems simpler) >>>>> >>>>> It seems like there are some pieces missing to do what I want >>>>> conveniently. >>>>> >>>>> Should I define all appenders in <Appenders> and later use a script to >>>>> only add the one(s) I want in the <Root> section? >>>>> >>>>> Or, should the <Appenders> section itself be scripted to only add the >>>>> appenders I want? >>>>> >>>>> Since I expect the OS/390 appender will likely blow up running on a >>>>> different OK I do not want to create it unless I know it can run OK. >>>>> >>>>> I guess then I have a conditional section in both the Appenders and in >>>>> the Root section so that when I say <AppenderRef =...> we do not go look >>>>> for an appender that is not defined. >>>>> >>>>> Thoughts? >>>>> >>>>> A narrow solution would be to add an "os" attribute to all appenders >>>>> but that seems lame. os="OS/390" and os="!OS/390" means also knowing about >>>>> "not", yikes. >>>>> >>>>> Gary >>>>> >>>>> On Sat, Sep 10, 2016 at 10:05 AM, Gary Gregory <garydgreg...@gmail.com >>>>> > wrote: >>>>> >>>>>> Hi, >>>>>> >>>>>> I can't seem to find on our site the scripting support that was >>>>>> recently added (or is that only in master?). >>>>>> >>>>>> What I need to do is only add a specific appender when running on a >>>>>> specific OS (USS on OS/390 if you must know). Then only add a different >>>>>> appender when not running on that OS. >>>>>> >>>>>> I'd rather not have to hard-code this and make thing more complicated. >>>>>> >>>>>> Thoughts? >>>>>> >>>>>> Gary >>>>>> >>>>>> -- >>>>>> E-Mail: garydgreg...@gmail.com | ggreg...@apache.org >>>>>> <ggreg...@apache.org> >>>>>> Java Persistence with Hibernate, Second Edition >>>>>> <http://www.manning.com/bauer3/> >>>>>> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/> >>>>>> Spring Batch in Action <http://www.manning.com/templier/> >>>>>> Blog: http://garygregory.wordpress.com >>>>>> Home: http://garygregory.com/ >>>>>> Tweet! http://twitter.com/GaryGregory >>>>>> >>>>> >>>>> >>>>> >>>>> -- >>>>> E-Mail: garydgreg...@gmail.com | ggreg...@apache.org >>>>> <ggreg...@apache.org> >>>>> Java Persistence with Hibernate, Second Edition >>>>> <http://www.manning.com/bauer3/> >>>>> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/> >>>>> Spring Batch in Action <http://www.manning.com/templier/> >>>>> Blog: http://garygregory.wordpress.com >>>>> Home: http://garygregory.com/ >>>>> Tweet! http://twitter.com/GaryGregory >>>>> >>>> >>>> >>>> >>>> -- >>>> E-Mail: garydgreg...@gmail.com | ggreg...@apache.org >>>> <ggreg...@apache.org> >>>> Java Persistence with Hibernate, Second Edition >>>> <http://www.manning.com/bauer3/> >>>> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/> >>>> Spring Batch in Action <http://www.manning.com/templier/> >>>> Blog: http://garygregory.wordpress.com >>>> Home: http://garygregory.com/ >>>> Tweet! http://twitter.com/GaryGregory >>>> >>>> >>>> >>>> >>> >>> >>> -- >>> E-Mail: garydgreg...@gmail.com | ggreg...@apache.org >>> <ggreg...@apache.org> >>> Java Persistence with Hibernate, Second Edition >>> <http://www.manning.com/bauer3/> >>> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/> >>> Spring Batch in Action <http://www.manning.com/templier/> >>> Blog: http://garygregory.wordpress.com >>> Home: http://garygregory.com/ >>> Tweet! http://twitter.com/GaryGregory >>> >>> >>> >> >> >> -- >> E-Mail: garydgreg...@gmail.com | ggreg...@apache.org >> <ggreg...@apache.org> >> Java Persistence with Hibernate, Second Edition >> <http://www.manning.com/bauer3/> >> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/> >> Spring Batch in Action <http://www.manning.com/templier/> >> Blog: http://garygregory.wordpress.com >> Home: http://garygregory.com/ >> Tweet! http://twitter.com/GaryGregory >> >> >> >> > > > -- > E-Mail: garydgreg...@gmail.com | ggreg...@apache.org > Java Persistence with Hibernate, Second Edition > <http://www.manning.com/bauer3/> > JUnit in Action, Second Edition <http://www.manning.com/tahchiev/> > Spring Batch in Action <http://www.manning.com/templier/> > Blog: http://garygregory.wordpress.com > Home: http://garygregory.com/ > Tweet! http://twitter.com/GaryGregory > -- E-Mail: garydgreg...@gmail.com | ggreg...@apache.org Java Persistence with Hibernate, Second Edition <http://www.manning.com/bauer3/> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/> Spring Batch in Action <http://www.manning.com/templier/> Blog: http://garygregory.wordpress.com Home: http://garygregory.com/ Tweet! http://twitter.com/GaryGregory