logging-log4j-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Gary Gregory <garydgreg...@gmail.com>
Subject Re: logging-log4j2 git commit: [LOG4J2-1578] RoutingAppender can be configured with scripts. Add Script in a Routes element.
Date Wed, 14 Sep 2016 21:24:51 GMT
Ralph: Thank you for the guidance on this topic.

I'll tackle the documentation update tonight.

WRT Lookups, that's YAGNI for me ATM. If you have a solution path on that,
I can take a look.

I am wondering in general about the performance difference from an app POV
between a plain appender and one appender nested in a RoutingAppender.

I am also wondering about any concurrency issue passing a LogEvent to a
Script. Can a LogEvent be skipped when multiple threads use the same
RoutingAppender?

Gary

On Wed, Sep 14, 2016 at 12:50 PM, Ralph Goers <ralph.goers@dslextreme.com>
wrote:

> Sounds good.
>
> When documenting that you should make it clear that the Map is shared so
> that every thread is seeing the same Map. Users need to be aware that they
> cannot put things in the map and expect it to only be available for that
> single event.
>
> The last, and probably trickiest part, is going to be making it so
> variables in the Map can be accessed via a Lookup. To be honest, I haven’t
> really figured out how to do that.
>
> Ralph
>
> On Sep 14, 2016, at 12:34 PM, Gary Gregory <garydgregory@gmail.com> wrote:
>
> The RoutingAppender Scripts now share a Bindings instance which contains a
> ConcurrentMap keyed under "staticVariables". The Bindings instance is
> tracked as a RoutingAppender and Routes ivar.
>
> I created an abstract superclass for (private) ScriptRunner
> implementations which holds on to the ConcurrentMap. The map can act as a
> set of static/global variables for that script and can be shared through a
> Bindings instance. The private ScriptRunner has new method
> ScriptManager.ScriptRunner.createBindings(). Right now there is no script
> specific data added to the Bindings, but there could be in the future.
>
> I'll add LogEvent support next...
>
> Gary
>
> On Wed, Sep 14, 2016 at 6:42 AM, Ralph Goers <ralph.goers@dslextreme.com>
> wrote:
>
>> OK - It wasn’t in there when I looked last night.
>>
>> A couple other things. A ConcurrentMap should be created and passed to
>> the init script and the routing script so that the init script can pass
>> variables to the routing script. Also, the routing script really needs to
>> be passed the logEvent so it can route based on data within it.
>>
>> Ralph
>>
>> On Sep 13, 2016, at 10:49 PM, Gary Gregory <garydgregory@gmail.com>
>> wrote:
>>
>> On Tue, Sep 13, 2016 at 10:33 PM, Ralph Goers <ralph.goers@dslextreme.com
>> > wrote:
>>
>>> Gary,
>>>
>>> RoutingAppender calls routes.getPattern().  Wouldn’t it make sense for
>>> the Routes class to execute the script in the call to getPattern and return
>>> the result if there is a script?
>>>
>>
>> That's what Routes.getPattern() does (see this very commit thread):
>>
>> @@ -90,12 +155,26 @@ public final class Routes {
>>       * @return the pattern.
>>       */
>>      public String getPattern() {
>> +        if (patternScript != null) {
>> +            final SimpleBindings bindings = new SimpleBindings();
>> +            bindings.put("configuration", configuration);
>> +            bindings.put("statusLogger", LOGGER);
>> +            final Object object = configuration.getScriptManager
>> ().execute(patternScript.getName(), bindings);
>> +            return Objects.toString(object, null);
>> +        }
>>          return pattern;
>>      }
>>
>> Gary
>>
>>
>>>
>>> Ralph
>>>
>>> > On Sep 13, 2016, at 10:00 PM, ggregory@apache.org wrote:
>>> >
>>> > Repository: logging-log4j2
>>> > Updated Branches:
>>> >  refs/heads/master 3846e2a87 -> e0f29d9ad
>>> >
>>> >
>>> > [LOG4J2-1578] RoutingAppender can be configured with scripts. Add
>>> Script
>>> > in a Routes element.
>>> >
>>> > Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
>>> > Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j
>>> 2/commit/e0f29d9a
>>> > Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/
>>> tree/e0f29d9a
>>> > Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/
>>> diff/e0f29d9a
>>> >
>>> > Branch: refs/heads/master
>>> > Commit: e0f29d9ad73aa4579cdc2d71ae5e8c01dd4f9f9c
>>> > Parents: 3846e2a
>>> > Author: Gary Gregory <ggregory@apache.org>
>>> > Authored: Tue Sep 13 21:59:59 2016 -0700
>>> > Committer: Gary Gregory <ggregory@apache.org>
>>> > Committed: Tue Sep 13 21:59:59 2016 -0700
>>> >
>>> > ----------------------------------------------------------------------
>>> > .../log4j/core/appender/routing/Routes.java     | 121
>>> ++++++++++++-----
>>> > .../core/appender/routing/RoutingAppender.java  |  19 ++-
>>> > .../routing/RoutesScriptAppenderTest.java       | 130
>>> +++++++++++++++++++
>>> > .../log4j-routing-routes-script-groovy.xml      |  43 ++++++
>>> > .../log4j-routing-routes-script-javascript.xml  |  40 ++++++
>>> > src/site/xdoc/manual/appenders.xml              |  27 +++-
>>> > 6 files changed, 340 insertions(+), 40 deletions(-)
>>> > ----------------------------------------------------------------------
>>> >
>>> >
>>> > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob
>>> /e0f29d9a/log4j-core/src/main/java/org/apache/logging/log4j/
>>> core/appender/routing/Routes.java
>>> > ----------------------------------------------------------------------
>>> > diff --git a/log4j-core/src/main/java/org
>>> /apache/logging/log4j/core/appender/routing/Routes.java
>>> b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>> ender/routing/Routes.java
>>> > index c95b64a..33fccd7 100644
>>> > --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>> ender/routing/Routes.java
>>> > +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>> ender/routing/Routes.java
>>> > @@ -18,11 +18,17 @@ package org.apache.logging.log4j.core.
>>> appender.routing;
>>> >
>>> > import java.util.Objects;
>>> >
>>> > +import javax.script.SimpleBindings;
>>> > +
>>> > import org.apache.logging.log4j.Logger;
>>> > +import org.apache.logging.log4j.core.config.Configuration;
>>> > import org.apache.logging.log4j.core.config.plugins.Plugin;
>>> > import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
>>> > import org.apache.logging.log4j.core.config.plugins.PluginBuilderFa
>>> ctory;
>>> > +import org.apache.logging.log4j.core.config.plugins.PluginConfigura
>>> tion;
>>> > import org.apache.logging.log4j.core.config.plugins.PluginElement;
>>> > +import org.apache.logging.log4j.core.config.plugins.validation.cons
>>> traints.Required;
>>> > +import org.apache.logging.log4j.core.script.AbstractScript;
>>> > import org.apache.logging.log4j.status.StatusLogger;
>>> >
>>> > /**
>>> > @@ -33,54 +39,113 @@ public final class Routes {
>>> >
>>> >     public static class Builder implements
>>> org.apache.logging.log4j.core.util.Builder<Routes>  {
>>> >
>>> > +        @PluginConfiguration
>>> > +        private Configuration configuration;
>>> > +
>>> >         @PluginAttribute("pattern")
>>> >         private String pattern;
>>> >
>>> > -        @PluginElement("Routes")
>>> > +        @PluginElement("Script")
>>> > +        private AbstractScript patternScript;
>>> > +
>>> > +        @PluginElement("Routes")
>>> > +        @Required
>>> >         private Route[] routes;
>>> >
>>> >         @Override
>>> >         public Routes build() {
>>> >             if (routes == null || routes.length == 0) {
>>> > -                LOGGER.error("No routes configured");
>>> > +                LOGGER.error("No Routes configured.");
>>> >                 return null;
>>> >             }
>>> > -            return new Routes(pattern, routes);
>>> > +            if (patternScript != null && pattern != null) {
>>> > +                LOGGER.warn("In a Routes element, you must configure
>>> either a Script element or a pattern attribute.");
>>> > +            }
>>> > +            if (patternScript != null) {
>>> > +                if (configuration == null) {
>>> > +                    LOGGER.error("No Configuration defined for
>>> Routes; required for Script");
>>> > +                } else {
>>> > +                    configuration.getScriptManager
>>> ().addScript(patternScript);
>>> > +                }
>>> > +            }
>>> > +            return new Routes(configuration, patternScript, pattern,
>>> routes);
>>> > +        }
>>> > +
>>> > +        public Configuration getConfiguration() {
>>> > +            return configuration;
>>> >         }
>>> >
>>> >         public String getPattern() {
>>> >             return pattern;
>>> >         }
>>> >
>>> > +        public AbstractScript getPatternScript() {
>>> > +            return patternScript;
>>> > +        }
>>> > +
>>> >         public Route[] getRoutes() {
>>> >             return routes;
>>> >         }
>>> >
>>> > -        public Builder withPattern(@SuppressWarnings("hiding")
>>> String pattern) {
>>> > +        public Builder withConfiguration(@SuppressWarnings("hiding")
>>> final Configuration configuration) {
>>> > +            this.configuration = configuration;
>>> > +            return this;
>>> > +        }
>>> > +
>>> > +        public Builder withPattern(@SuppressWarnings("hiding") final
>>> String pattern) {
>>> >             this.pattern = pattern;
>>> >             return this;
>>> >         }
>>> >
>>> > -        public Builder withRoutes(@SuppressWarnings("hiding")
>>> Route[] routes) {
>>> > +        public Builder withPatternScript(@SuppressWarnings("hiding")
>>> final AbstractScript patternScript) {
>>> > +            this.patternScript = patternScript;
>>> > +            return this;
>>> > +        }
>>> > +
>>> > +        public Builder withRoutes(@SuppressWarnings("hiding") final
>>> Route[] routes) {
>>> >             this.routes = routes;
>>> >             return this;
>>> >         }
>>> >
>>> >     }
>>> >
>>> > +    private static final Logger LOGGER = StatusLogger.getLogger();
>>> > +
>>> > +    /**
>>> > +     * Creates the Routes.
>>> > +     * @param pattern The pattern.
>>> > +     * @param routes An array of Route elements.
>>> > +     * @return The Routes container.
>>> > +     * @deprecated since 2.7; use {@link #newBuilder()}.
>>> > +     */
>>> > +    @Deprecated
>>> > +    public static Routes createRoutes(
>>> > +            final String pattern,
>>> > +            final Route... routes) {
>>> > +        if (routes == null || routes.length == 0) {
>>> > +            LOGGER.error("No routes configured");
>>> > +            return null;
>>> > +        }
>>> > +        return new Routes(null, null, pattern, routes);
>>> > +    }
>>> > +
>>> >     @PluginBuilderFactory
>>> >     public static Builder newBuilder() {
>>> >         return new Builder();
>>> >     }
>>> > -
>>> > -    private static final Logger LOGGER = StatusLogger.getLogger();
>>> > -
>>> > +
>>> > +    private final Configuration configuration;
>>> > +
>>> >     private final String pattern;
>>> >
>>> > +    private final AbstractScript patternScript;
>>> > +
>>> >     // TODO Why not make this a Map or add a Map.
>>> >     private final Route[] routes;
>>> >
>>> > -    private Routes(final String pattern, final Route... routes) {
>>> > +    private Routes(final Configuration configuration, final
>>> AbstractScript patternScript, final String pattern, final Route... routes) {
>>> > +        this.configuration = configuration;
>>> > +        this.patternScript = patternScript;
>>> >         this.pattern = pattern;
>>> >         this.routes = routes;
>>> >     }
>>> > @@ -90,12 +155,26 @@ public final class Routes {
>>> >      * @return the pattern.
>>> >      */
>>> >     public String getPattern() {
>>> > +        if (patternScript != null) {
>>> > +            final SimpleBindings bindings = new SimpleBindings();
>>> > +            bindings.put("configuration", configuration);
>>> > +            bindings.put("statusLogger", LOGGER);
>>> > +            final Object object = configuration.getScriptManager
>>> ().execute(patternScript.getName(), bindings);
>>> > +            return Objects.toString(object, null);
>>> > +        }
>>> >         return pattern;
>>> >     }
>>> >
>>> > -    public Route getRoute(String key) {
>>> > -        for (int i = 0; i < routes.length; i++) {
>>> > -            final Route route = routes[i];
>>> > +    /**
>>> > +     * Gets the optional script that decides which route to pick.
>>> > +     * @return the optional script that decides which route to pick.
>>> May be null.
>>> > +     */
>>> > +    public AbstractScript getPatternScript() {
>>> > +        return patternScript;
>>> > +    }
>>> > +
>>> > +    public Route getRoute(final String key) {
>>> > +        for (final Route route : routes) {
>>> >             if (Objects.equals(route.getKey(), key)) {
>>> >                 return route;
>>> >             }
>>> > @@ -127,22 +206,4 @@ public final class Routes {
>>> >
>>> >     }
>>> >
>>> > -    /**
>>> > -     * Creates the Routes.
>>> > -     * @param pattern The pattern.
>>> > -     * @param routes An array of Route elements.
>>> > -     * @return The Routes container.
>>> > -     * @deprecated since 2.7; use {@link #newBuilder()}.
>>> > -     */
>>> > -    @Deprecated
>>> > -    public static Routes createRoutes(
>>> > -            final String pattern,
>>> > -            final Route... routes) {
>>> > -        if (routes == null || routes.length == 0) {
>>> > -            LOGGER.error("No routes configured");
>>> > -            return null;
>>> > -        }
>>> > -        return new Routes(pattern, routes);
>>> > -    }
>>> > -
>>> > }
>>> >
>>> > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob
>>> /e0f29d9a/log4j-core/src/main/java/org/apache/logging/log4j/
>>> core/appender/routing/RoutingAppender.java
>>> > ----------------------------------------------------------------------
>>> > diff --git a/log4j-core/src/main/java/org
>>> /apache/logging/log4j/core/appender/routing/RoutingAppender.java
>>> b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>> ender/routing/RoutingAppender.java
>>> > index 4471333..78fddbc 100644
>>> > --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>> ender/routing/RoutingAppender.java
>>> > +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/app
>>> ender/routing/RoutingAppender.java
>>> > @@ -72,15 +72,16 @@ public final class RoutingAppender extends
>>> AbstractAppender {
>>> >
>>> >         @Override
>>> >         public RoutingAppender build() {
>>> > -            if (getName() == null) {
>>> > -                LOGGER.error("No name defined for RoutingAppender");
>>> > +            final String name = getName();
>>> > +            if (name == null) {
>>> > +                LOGGER.error("No name defined for this
>>> RoutingAppender");
>>> >                 return null;
>>> >             }
>>> >             if (routes == null) {
>>> > -                LOGGER.error("No routes defined for RoutingAppender");
>>> > +                LOGGER.error("No routes defined for RoutingAppender
>>> {}", name);
>>> >                 return null;
>>> >             }
>>> > -            return new RoutingAppender(getName(), getFilter(),
>>> isIgnoreExceptions(), routes, rewritePolicy,
>>> > +            return new RoutingAppender(name, getFilter(),
>>> isIgnoreExceptions(), routes, rewritePolicy,
>>> >                     configuration, purgePolicy, defaultRouteScript);
>>> >         }
>>> >
>>> > @@ -173,7 +174,7 @@ public final class RoutingAppender extends
>>> AbstractAppender {
>>> >     public void start() {
>>> >         if (defaultRouteScript != null) {
>>> >             if (configuration == null) {
>>> > -                error("No Configuration defined for RoutingAppender;
>>> required for DefaultRouteScript");
>>> > +                error("No Configuration defined for RoutingAppender;
>>> required for Script element.");
>>> >             } else {
>>> >                 configuration.getScriptManage
>>> r().addScript(defaultRouteScript);
>>> >                 final SimpleBindings bindings = new SimpleBindings();
>>> > @@ -352,4 +353,12 @@ public final class RoutingAppender extends
>>> AbstractAppender {
>>> >     public RewritePolicy getRewritePolicy() {
>>> >         return rewritePolicy;
>>> >     }
>>> > +
>>> > +    public Routes getRoutes() {
>>> > +        return routes;
>>> > +    }
>>> > +
>>> > +    public Configuration getConfiguration() {
>>> > +        return configuration;
>>> > +    }
>>> > }
>>> >
>>> > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob
>>> /e0f29d9a/log4j-core/src/test/java/org/apache/logging/log4j/
>>> core/appender/routing/RoutesScriptAppenderTest.java
>>> > ----------------------------------------------------------------------
>>> > diff --git a/log4j-core/src/test/java/org
>>> /apache/logging/log4j/core/appender/routing/RoutesScriptAppenderTest.java
>>> b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>> ender/routing/RoutesScriptAppenderTest.java
>>> > new file mode 100644
>>> > index 0000000..7d90f6b
>>> > --- /dev/null
>>> > +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/app
>>> ender/routing/RoutesScriptAppenderTest.java
>>> > @@ -0,0 +1,130 @@
>>> > +/*
>>> > + * Licensed to the Apache Software Foundation (ASF) under one or more
>>> > + * contributor license agreements. See the NOTICE file distributed
>>> with
>>> > + * this work for additional information regarding copyright ownership.
>>> > + * The ASF licenses this file to You under the Apache license,
>>> Version 2.0
>>> > + * (the "License"); you may not use this file except in compliance
>>> with
>>> > + * the License. You may obtain a copy of the License at
>>> > + *
>>> > + *      http://www.apache.org/licenses/LICENSE-2.0
>>> > + *
>>> > + * Unless required by applicable law or agreed to in writing, software
>>> > + * distributed under the License is distributed on an "AS IS" BASIS,
>>> > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
>>> implied.
>>> > + * See the license for the specific language governing permissions and
>>> > + * limitations under the license.
>>> > + */
>>> > +package org.apache.logging.log4j.core.appender.routing;
>>> > +
>>> > +import static org.junit.Assert.assertNotNull;
>>> > +import static org.junit.Assert.assertTrue;
>>> > +
>>> > +import java.util.List;
>>> > +import java.util.Map;
>>> > +
>>> > +import org.apache.logging.log4j.core.LogEvent;
>>> > +import org.apache.logging.log4j.core.Logger;
>>> > +import org.apache.logging.log4j.core.config.AppenderControl;
>>> > +import org.apache.logging.log4j.junit.LoggerContextRule;
>>> > +import org.apache.logging.log4j.test.appender.ListAppender;
>>> > +import org.junit.Assert;
>>> > +import org.junit.Rule;
>>> > +import org.junit.Test;
>>> > +import org.junit.runner.RunWith;
>>> > +import org.junit.runners.Parameterized;
>>> > +
>>> > +/**
>>> > + *
>>> > + */
>>> > +@RunWith(Parameterized.class)
>>> > +public class RoutesScriptAppenderTest {
>>> > +
>>> > +    @Parameterized.Parameters(name = "{0}")
>>> > +    public static String[] getParameters() {
>>> > +        return new String[] {
>>> > +                "log4j-routing-routes-script-groovy.xml",
>>> > +                "log4j-routing-routes-script-javascript.xml" };
>>> > +    }
>>> > +
>>> > +    @Rule
>>> > +    public final LoggerContextRule loggerContextRule;
>>> > +
>>> > +    public RoutesScriptAppenderTest(final String configLocation) {
>>> > +        this.loggerContextRule = new LoggerContextRule(configLocati
>>> on);
>>> > +    }
>>> > +
>>> > +    private ListAppender getListAppender() {
>>> > +        final String key = "Service2";
>>> > +        final RoutingAppender routingAppender = getRoutingAppender();
>>> > +        Assert.assertTrue(routingAppender.isStarted());
>>> > +        final Map<String, AppenderControl> appenders =
>>> routingAppender.getAppenders();
>>> > +        final AppenderControl appenderControl = appenders.get(key);
>>> > +        assertNotNull("No appender control generated for '" + key +
>>> "'; appenders = " + appenders, appenderControl);
>>> > +        final ListAppender listAppender = (ListAppender)
>>> appenderControl.getAppender();
>>> > +        return listAppender;
>>> > +    }
>>> > +
>>> > +    private RoutingAppender getRoutingAppender() {
>>> > +        return loggerContextRule.getRequiredAppender("Routing",
>>> RoutingAppender.class);
>>> > +    }
>>> > +
>>> > +    private void logAndCheck() {
>>> > +        final Logger logger = loggerContextRule.getLogger(Ro
>>> utesScriptAppenderTest.class);
>>> > +        logger.error("Hello");
>>> > +        final ListAppender listAppender = getListAppender();
>>> > +        final List<LogEvent> list = listAppender.getEvents();
>>> > +        assertNotNull("No events generated", list);
>>> > +        assertTrue("Incorrect number of events. Expected 1, got " +
>>> list.size(), list.size() == 1);
>>> > +        logger.error("World");
>>> > +        assertTrue("Incorrect number of events. Expected 2, got " +
>>> list.size(), list.size() == 2);
>>> > +    }
>>> > +
>>> > +    @Test(expected = AssertionError.class)
>>> > +    public void testAppenderAbsence() {
>>> > +        loggerContextRule.getListAppender("List1");
>>> > +    }
>>> > +
>>> > +    @Test
>>> > +    public void testListAppenderPresence() {
>>> > +        // No appender until an event is routed, even thought we
>>> initialized the default route on startup.
>>> > +        Assert.assertNull("No appender control generated",
>>> getRoutingAppender().getAppenders().get("Service2"));
>>> > +    }
>>> > +
>>> > +    @Test
>>> > +    public void testNoPurgePolicy() {
>>> > +        // No PurgePolicy in this test
>>> > +        Assert.assertNull("Unexpected PurgePolicy",
>>> getRoutingAppender().getPurgePolicy());
>>> > +    }
>>> > +
>>> > +    @Test
>>> > +    public void testNoRewritePolicy() {
>>> > +        // No RewritePolicy in this test
>>> > +        Assert.assertNull("Unexpected RewritePolicy",
>>> getRoutingAppender().getRewritePolicy());
>>> > +    }
>>> > +
>>> > +    @Test
>>> > +    public void testRoutingAppenderRoutes() {
>>> > +        final RoutingAppender routingAppender = getRoutingAppender();
>>> > +        Assert.assertNull(routingAppender.getDefaultRouteScript());
>>> > +        Assert.assertNull(routingAppender.getDefaultRoute());
>>> > +        final Routes routes = routingAppender.getRoutes();
>>> > +        Assert.assertNotNull(routes);
>>> > +        Assert.assertNotNull(routes.getPatternScript());
>>> > +        Assert.assertEquals("Service2", routes.getPattern());
>>> > +    }
>>> > +
>>> > +    @Test
>>> > +    public void testRoutingAppenderPresence() {
>>> > +        getRoutingAppender();
>>> > +    }
>>> > +
>>> > +    @Test
>>> > +    public void testRoutingPresence1() {
>>> > +        logAndCheck();
>>> > +    }
>>> > +
>>> > +    @Test
>>> > +    public void testRoutingPresence2() {
>>> > +        logAndCheck();
>>> > +    }
>>> > +}
>>> >
>>> > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob
>>> /e0f29d9a/log4j-core/src/test/resources/log4j-routing-routes
>>> -script-groovy.xml
>>> > ----------------------------------------------------------------------
>>> > diff --git a/log4j-core/src/test/resource
>>> s/log4j-routing-routes-script-groovy.xml b/log4j-core/src/test/resource
>>> s/log4j-routing-routes-script-groovy.xml
>>> > new file mode 100644
>>> > index 0000000..83121ea
>>> > --- /dev/null
>>> > +++ b/log4j-core/src/test/resources/log4j-routing-routes-script-
>>> groovy.xml
>>> > @@ -0,0 +1,43 @@
>>> > +<?xml version="1.0" encoding="UTF-8"?>
>>> > +<!--
>>> > + Licensed to the Apache Software Foundation (ASF) under one or more
>>> > + contributor license agreements.  See the NOTICE file distributed with
>>> > + this work for additional information regarding copyright ownership.
>>> > + The ASF licenses this file to You under the Apache License, Version
>>> 2.0
>>> > + (the "License"); you may not use this file except in compliance with
>>> > + the License.  You may obtain a copy of the License at
>>> > +
>>> > +      http://www.apache.org/licenses/LICENSE-2.0
>>> > +
>>> > + Unless required by applicable law or agreed to in writing, software
>>> > + distributed under the License is distributed on an "AS IS" BASIS,
>>> > + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
>>> implied.
>>> > + See the License for the specific language governing permissions and
>>> > + limitations under the License.
>>> > +
>>> > +-->
>>> > +<Configuration status="WARN" name="RoutingTest">
>>> > +  <Appenders>
>>> > +    <Routing name="Routing">
>>> > +      <Routes>
>>> > +        <Script name="RoutingInit" language="groovy"><![CDATA[
>>> > +          if ("OSNameFoo".contains("Foo")) {
>>> > +            return "Service2";
>>> > +          }
>>> > +          return "Service1";]]>
>>> > +        </Script>
>>> > +        <Route key="Service1">
>>> > +          <List name="List1" />
>>> > +        </Route>
>>> > +        <Route key="Service2">
>>> > +          <List name="List2" />
>>> > +        </Route>
>>> > +      </Routes>
>>> > +    </Routing>
>>> > +  </Appenders>
>>> > +  <Loggers>
>>> > +    <Root level="error">
>>> > +      <AppenderRef ref="Routing" />
>>> > +    </Root>
>>> > +  </Loggers>
>>> > +</Configuration>
>>> > \ No newline at end of file
>>> >
>>> > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob
>>> /e0f29d9a/log4j-core/src/test/resources/log4j-routing-routes
>>> -script-javascript.xml
>>> > ----------------------------------------------------------------------
>>> > diff --git a/log4j-core/src/test/resource
>>> s/log4j-routing-routes-script-javascript.xml
>>> b/log4j-core/src/test/resources/log4j-routing-routes-script-
>>> javascript.xml
>>> > new file mode 100644
>>> > index 0000000..e672aea
>>> > --- /dev/null
>>> > +++ b/log4j-core/src/test/resources/log4j-routing-routes-script-
>>> javascript.xml
>>> > @@ -0,0 +1,40 @@
>>> > +<?xml version="1.0" encoding="UTF-8"?>
>>> > +<!--
>>> > + Licensed to the Apache Software Foundation (ASF) under one or more
>>> > + contributor license agreements.  See the NOTICE file distributed with
>>> > + this work for additional information regarding copyright ownership.
>>> > + The ASF licenses this file to You under the Apache License, Version
>>> 2.0
>>> > + (the "License"); you may not use this file except in compliance with
>>> > + the License.  You may obtain a copy of the License at
>>> > +
>>> > +      http://www.apache.org/licenses/LICENSE-2.0
>>> > +
>>> > + Unless required by applicable law or agreed to in writing, software
>>> > + distributed under the License is distributed on an "AS IS" BASIS,
>>> > + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
>>> implied.
>>> > + See the License for the specific language governing permissions and
>>> > + limitations under the License.
>>> > +
>>> > +-->
>>> > +<Configuration status="WARN" name="RoutingTest">
>>> > +  <Appenders>
>>> > +    <Routing name="Routing">
>>> > +      <Routes>
>>> > +        <Script name="RoutingInit" language="JavaScript"><![CDATA[
>>> > +          "OSNameFoo".search("Foo") > -1 ? "Service2" : "Service1";]]>
>>> > +        </Script>
>>> > +        <Route key="Service1">
>>> > +          <List name="List1" />
>>> > +        </Route>
>>> > +        <Route key="Service2">
>>> > +          <List name="List2" />
>>> > +        </Route>
>>> > +      </Routes>
>>> > +    </Routing>
>>> > +  </Appenders>
>>> > +  <Loggers>
>>> > +    <Root level="error">
>>> > +      <AppenderRef ref="Routing" />
>>> > +    </Root>
>>> > +  </Loggers>
>>> > +</Configuration>
>>> > \ No newline at end of file
>>> >
>>> > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob
>>> /e0f29d9a/src/site/xdoc/manual/appenders.xml
>>> > ----------------------------------------------------------------------
>>> > diff --git a/src/site/xdoc/manual/appenders.xml
>>> b/src/site/xdoc/manual/appenders.xml
>>> > index 2d3d361..a87d9b7 100644
>>> > --- a/src/site/xdoc/manual/appenders.xml
>>> > +++ b/src/site/xdoc/manual/appenders.xml
>>> > @@ -3279,7 +3279,11 @@ public class JpaLogEntity extends
>>> AbstractLogEventWrapperEntity {
>>> >              Appender may be an appender previously configured and may
>>> be referenced by its name or the
>>> >              Appender can be dynamically created as needed. The
>>> RoutingAppender should be configured after any
>>> >              Appenders it references to allow it to shut down properly.
>>> > -          </p>
>>> > +           </p>
>>> > +           <p>
>>> > +             You can also configure a RoutingAppender with scripts:
>>> you can run a script when the appender starts
>>> > +             and when a route is chosen for an log event.
>>> > +           </p>
>>> >           <table>
>>> >             <caption align="top">RoutingAppender Parameters</caption>
>>> >             <tr>
>>> > @@ -3288,7 +3292,7 @@ public class JpaLogEntity extends
>>> AbstractLogEventWrapperEntity {
>>> >               <th>Description</th>
>>> >             </tr>
>>> >             <tr>
>>> > -              <td>filter</td>
>>> > +              <td>Filter</td>
>>> >               <td>Filter</td>
>>> >               <td>A Filter to determine if the event should be handled
>>> by this Appender. More than one Filter
>>> >               may be used by using a CompositeFilter.</td>
>>> > @@ -3299,16 +3303,22 @@ public class JpaLogEntity extends
>>> AbstractLogEventWrapperEntity {
>>> >               <td>The name of the Appender.</td>
>>> >             </tr>
>>> >             <tr>
>>> > -              <td>rewritePolicy</td>
>>> > +              <td>RewritePolicy</td>
>>> >               <td>RewritePolicy</td>
>>> >               <td>The RewritePolicy that will manipulate the
>>> LogEvent.</td>
>>> >             </tr>
>>> >             <tr>
>>> > -              <td>routes</td>
>>> > +              <td>Routes</td>
>>> >               <td>Routes</td>
>>> >               <td>Contains one or more Route declarations to identify
>>> the criteria for choosing Appenders.</td>
>>> >             </tr>
>>> >             <tr>
>>> > +              <td>Script</td>
>>> > +              <td>Script</td>
>>> > +              <td>This Script runs when Log4j starts the
>>> RoutingAppender and returns a String Route key to determine
>>> > +                the default Route.</td>
>>> > +            </tr>
>>> > +            <tr>
>>> >               <td>ignoreExceptions</td>
>>> >               <td>boolean</td>
>>> >               <td>The default is <code>true</code>, causing
exceptions
>>> encountered while appending events to be
>>> > @@ -3319,13 +3329,20 @@ public class JpaLogEntity extends
>>> AbstractLogEventWrapperEntity {
>>> >           </table>
>>> >           <h4>Routes</h4>
>>> >             <p>
>>> > -              The Routes element accepts a single, required attribute
>>> named "pattern". The pattern is evaluated
>>> > +              The Routes element accepts a single attribute named
>>> "pattern". The pattern is evaluated
>>> >               against all the registered Lookups and the result is
>>> used to select a Route. Each Route may be
>>> >               configured with a key. If the key matches the result of
>>> evaluating the pattern then that Route
>>> >               will be selected. If no key is specified on a Route then
>>> that Route is the default. Only one Route
>>> >               can be configured as the default.
>>> >             </p>
>>> >             <p>
>>> > +              The Routes element may contain a Script child element.
>>> If specified, the Script is run for each
>>> > +              log event and returns the String Route key to use.
>>> > +            </p>
>>> > +            <p>
>>> > +              You must specify either the pattern attribute or the
>>> Script element, but not both.
>>> > +            </p>
>>> > +            <p>
>>> >               Each Route must reference an Appender. If the Route
>>> contains a ref attribute then the
>>> >               Route will reference an Appender that was defined in the
>>> configuration. If the Route contains an
>>> >               Appender definition then an Appender will be created
>>> within the context of the RoutingAppender and
>>> >
>>> >
>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
>>> For additional commands, e-mail: log4j-dev-help@logging.apache.org
>>>
>>>
>>
>>
>> --
>> E-Mail: garydgregory@gmail.com | ggregory@apache.org
>> <ggregory@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: garydgregory@gmail.com | ggregory@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: garydgregory@gmail.com | ggregory@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

Mime
View raw message