I committed a first cut, see comments in
https://issues.apache.org/jira/browse/LOG4J2-1578

Gary

On Mon, Sep 12, 2016 at 11:40 PM, Ralph Goers <[email protected]>
wrote:

> Yes, it returns the key. Remember, a Route can dynamically create an
> Appender so it isn’t required to be a reference.  At the same time we can
> (and probably should) pass variables and/or a Map to the script that it can
> update in any way it wants for later usage by the Routing script. As is
> shown, it can also return null which leaves the default route in place. So
> it need not be strictly for returning the default route.
>
> Ralph
>
> On Sep 12, 2016, at 10:30 PM, Gary Gregory <[email protected]> wrote:
>
> 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 <[email protected]>
> 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 <[email protected]>
>> 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 
>>> <http://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 <[email protected]>
>>> 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 <[email protected]>
>>> wrote:
>>>
>>> On Sun, Sep 11, 2016 at 12:47 PM, Ralph Goers <ralph.goers@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 <[email protected]>
>>>> 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 <[email protected]>
>>>>> 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 <[email protected]>
>>>>> 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 <[email protected]
>>>>> > 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 <[email protected]
>>>>>> m> 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: [email protected] | [email protected]
>>>>>>> <[email protected]>
>>>>>>> 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: [email protected] | [email protected]
>>>>>> <[email protected]>
>>>>>> 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: [email protected] | [email protected]
>>>>> <[email protected]>
>>>>> 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: [email protected] | [email protected]
>>>> <[email protected]>
>>>> 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: [email protected] | [email protected]
>>> <[email protected]>
>>> 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: [email protected] | [email protected]
>> 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: [email protected] | [email protected]
> 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: [email protected] | [email protected]
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

Reply via email to