Work in progress
diff --git a/audit-service-api/src/main/resources/catalog.json b/audit-service-api/src/main/resources/catalog.json
index 2bee559..6890287 100644
--- a/audit-service-api/src/main/resources/catalog.json
+++ b/audit-service-api/src/main/resources/catalog.json
@@ -37,7 +37,7 @@
     "displayName" : "Login",
     "description" : "User Login",
     "aliases" : null,
-    "attributes" : null
+    "attributes" : [{"name" : "userId", "required" : false}, {"name" : "accountNumber", "required" : false}]
   }, {
     "name" : "transfer",
     "displayName" : "Transfer",
diff --git a/pom.xml b/pom.xml
index bb82ff4..cc9b420 100644
--- a/pom.xml
+++ b/pom.xml
@@ -34,7 +34,7 @@
     <maven.javadoc.failOnError>false</maven.javadoc.failOnError>
     <classmate.version>1.2.0</classmate.version>
     <jackson.version>2.8.5</jackson.version>
-    <log4j.version>2.9.0</log4j.version>
+    <log4j.version>2.10.0</log4j.version>
     <log4j-audit.version>1.0.0-SNAPSHOT</log4j-audit.version>
     <slf4j.version>1.6.2</slf4j.version>
     <spring.version>4.3.3.RELEASE</spring.version>
@@ -407,5 +407,6 @@
   <modules>
     <module>audit-service-war</module>
     <module>audit-service-api</module>
+    <module>sample-app</module>
   </modules>
 </project>
diff --git a/sample-app/pom.xml b/sample-app/pom.xml
new file mode 100644
index 0000000..506ff8d
--- /dev/null
+++ b/sample-app/pom.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <!--
+  ~ 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.
+  -->
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.logging.log4j</groupId>
+    <artifactId>audit-sample-parent</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+  </parent>
+  <groupId>org.apache.logging.log4j</groupId>
+  <artifactId>sample-app</artifactId>
+
+  <description>Audit Logging Sample Application</description>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-audit-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>audit-service-api</artifactId>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+	
+    </plugins>
+  </build>
+</project>
diff --git a/sample-app/sample-app.sh b/sample-app/sample-app.sh
new file mode 100755
index 0000000..cab984e
--- /dev/null
+++ b/sample-app/sample-app.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+  
+# 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.
+
+
+DEBUG=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005 
+CLASSPATH=target/classes:$HOME/.m2/repository/org/apache/logging/log4j/log4j-api/2.10.0/log4j-api-2.10.0.jar:$HOME/.m2/repository/org/apache/logging/log4j/log4j-core/2.10.0/log4j-core-2.10.0.jar:$HOME/.m2/repository/org/apache/logging/log4j/log4j-audit-api/1.0.0-SNAPSHOT/log4j-audit-api-1.0.0-SNAPSHOT.jar:$HOME/.m2/repository/org/apache/logging/log4j/log4j-catalog-api/1.0.0-SNAPSHOT/log4j-catalog-api-1.0.0-SNAPSHOT.jar:$HOME/.m2/repository/io/springfox/springfox-swagger2/2.2.2/springfox-swagger2-2.2.2.jar:$HOME/.m2/repository/org/mapstruct/mapstruct/1.0.0.CR1/mapstruct-1.0.0.CR1.jar:$HOME/.m2/repository/io/swagger/swagger-annotations/1.5.3/swagger-annotations-1.5.3.jar:$HOME/.m2/repository/io/swagger/swagger-models/1.5.3/swagger-models-1.5.3.jar:$HOME/.m2/repository/io/springfox/springfox-spi/2.2.2/springfox-spi-2.2.2.jar:$HOME/.m2/repository/io/springfox/springfox-core/2.2.2/springfox-core-2.2.2.jar:$HOME/.m2/repository/io/springfox/springfox-schema/2.2.2/springfox-schema-2.2.2.jar:$HOME/.m2/repository/io/springfox/springfox-swagger-common/2.2.2/springfox-swagger-common-2.2.2.jar:$HOME/.m2/repository/io/springfox/springfox-spring-web/2.2.2/springfox-spring-web-2.2.2.jar:$HOME/.m2/repository/com/google/guava/guava/18.0/guava-18.0.jar:$HOME/.m2/repository/org/slf4j/slf4j-api/1.6.2/slf4j-api-1.6.2.jar:$HOME/.m2/repository/org/aspectj/aspectjweaver/1.8.6/aspectjweaver-1.8.6.jar:$HOME/.m2/repository/org/springframework/plugin/spring-plugin-core/1.2.0.RELEASE/spring-plugin-core-1.2.0.RELEASE.jar:$HOME/.m2/repository/org/springframework/plugin/spring-plugin-metadata/1.2.0.RELEASE/spring-plugin-metadata-1.2.0.RELEASE.jar:$HOME/.m2/repository/org/springframework/hateoas/spring-hateoas/0.18.0.RELEASE/spring-hateoas-0.18.0.RELEASE.jar:$HOME/.m2/repository/org/springframework/spring-web/4.3.3.RELEASE/spring-web-4.3.3.RELEASE.jar:$HOME/.m2/repository/org/springframework/spring-webmvc/4.3.3.RELEASE/spring-webmvc-4.3.3.RELEASE.jar:$HOME/.m2/repository/com/fasterxml/classmate/1.2.0/classmate-1.2.0.jar:$HOME/.m2/repository/org/apache/commons/commons-lang3/3.4/commons-lang3-3.4.jar:$HOME/.m2/repository/org/springframework/spring-context/4.3.3.RELEASE/spring-context-4.3.3.RELEASE.jar:$HOME/.m2/repository/org/springframework/spring-expression/4.3.3.RELEASE/spring-expression-4.3.3.RELEASE.jar:$HOME/.m2/repository/org/springframework/spring-context-support/4.3.3.RELEASE/spring-context-support-4.3.3.RELEASE.jar:$HOME/.m2/repository/org/springframework/spring-beans/4.3.3.RELEASE/spring-beans-4.3.3.RELEASE.jar:$HOME/.m2/repository/org/springframework/spring-core/4.3.3.RELEASE/spring-core-4.3.3.RELEASE.jar:$HOME/.m2/repository/org/springframework/spring-aop/4.3.3.RELEASE/spring-aop-4.3.3.RELEASE.jar:$HOME/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.8.5/jackson-core-2.8.5.jar:$HOME/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.8.5/jackson-databind-2.8.5.jar:$HOME/.m2/repository/com/fasterxml/jackson/core/jackson-annotations/2.8.5/jackson-annotations-2.8.5.jar:$HOME/.m2/repository/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.8.5/jackson-datatype-jsr310-2.8.5.jar:$HOME/.m2/repository/net/sf/jopt-simple/jopt-simple/4.9/jopt-simple-4.9.jar:$HOME/.m2/repository/org/apache/logging/log4j/log4j-jcl/2.10.0/log4j-jcl-2.10.0.jar:$HOME/.m2/repository/commons-logging/commons-logging/1.2/commons-logging-1.2.jar:$HOME/.m2/repository/org/apache/logging/log4j/audit-service-api/1.0.0-SNAPSHOT/audit-service-api-1.0.0-SNAPSHOT.jar
+$JAVA_HOME/bin/java -classpath $CLASSPATH org.apache.logging.audit.SampleApp
diff --git a/sample-app/src/main/java/org/apache/logging/audit/RequestContext.java b/sample-app/src/main/java/org/apache/logging/audit/RequestContext.java
new file mode 100644
index 0000000..5019001
--- /dev/null
+++ b/sample-app/src/main/java/org/apache/logging/audit/RequestContext.java
@@ -0,0 +1,136 @@
+/*
+ * 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.audit;
+
+import java.util.UUID;
+
+import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.audit.request.ChainedMapping;
+import org.apache.logging.log4j.audit.request.ClientServerMapping;
+import org.apache.logging.log4j.audit.request.LocalMapping;
+import org.apache.logging.log4j.audit.request.RequestContextBase;
+import org.apache.logging.log4j.audit.request.RequestContextMapping;
+import org.apache.logging.log4j.audit.request.RequestContextMappings;
+import org.apache.logging.log4j.core.util.UuidUtil;
+
+public class RequestContext extends RequestContextBase {
+    private static final String REQUEST_ID = "requestId";
+    private static final String SESSION_ID = "sessionId";
+    private static final String ACCOUNT_NUMBER = "accountNumber";
+    private static final String IP_ADDRESS = "ipAddress";
+    private static final String USER_ID = "userId";
+    private static final String LOGIN_ID = "loginId";
+    private static final String HOST_NAME = "hostName";
+    private static final String CALLING_HOST = "callingHost";
+
+    private static final String HEADER_PREFIX = "mycorp-context-";
+
+    private static RequestContextMapping[] mappingArray =
+            new RequestContextMapping[] { new ClientServerMapping(LOGIN_ID),
+            new ClientServerMapping(ACCOUNT_NUMBER), new ClientServerMapping(IP_ADDRESS),
+            new ClientServerMapping(USER_ID),
+            new ClientServerMapping(REQUEST_ID), new ClientServerMapping(SESSION_ID),
+            new ChainedMapping(HOST_NAME, CALLING_HOST), new LocalMapping(CALLING_HOST)};
+
+    static {
+        RequestContextBase.setMappings(new RequestContextMappings(mappingArray, HEADER_PREFIX));
+    }
+
+    public static String getRequestId() {
+        String uuidStr = ThreadContext.get(REQUEST_ID);
+        UUID uuid;
+        if (uuidStr == null) {
+            uuid = UuidUtil.getTimeBasedUuid();
+            ThreadContext.put(REQUEST_ID, uuid.toString());
+        }
+        return uuidStr;
+    }
+
+    private static void setRequestId(String requestId) {
+        if (requestId != null) {
+            ThreadContext.put(REQUEST_ID, requestId);
+        }
+    }
+
+    public static void setSessionId(UUID sessionId) {
+        if (sessionId != null) {
+            ThreadContext.put(SESSION_ID, sessionId.toString());
+        }
+    }
+
+    public static void setSessionId(String sessionId) {
+        if (sessionId != null) {
+            ThreadContext.put(SESSION_ID, sessionId);
+        }
+    }
+
+    public static void setAccountNumber(Long accountNumber) {
+        ThreadContext.put(ACCOUNT_NUMBER, accountNumber.toString());
+    }
+
+    public static Long getAccountNumber() {
+        String value = ThreadContext.get(ACCOUNT_NUMBER);
+        if (value == null || value.length() == 0) {
+            return 0L;
+        }
+        try {
+            return Long.parseLong(value);
+        } catch (Exception e) {
+            return 0L;
+        }
+    }
+
+    public static void setIpAddress(String address) {
+        ThreadContext.put(IP_ADDRESS, address);
+    }
+
+    public static String getIpAddress() {
+        return ThreadContext.get(IP_ADDRESS);
+    }
+
+    public static void setUserId(String userId) {
+        ThreadContext.put(USER_ID, userId);
+    }
+
+    public static String getUserId() {
+        return ThreadContext.get(USER_ID);
+    }
+
+    public static void setLoginId(String loginId) {
+        ThreadContext.put(LOGIN_ID, loginId);
+    }
+
+    public static String getLoginId() {
+        return ThreadContext.get(LOGIN_ID);
+    }
+
+    public static String getHostName() {
+        return ThreadContext.get(HOST_NAME);
+    }
+
+    public static void setHostName(String hostName) {
+        ThreadContext.put(HOST_NAME, hostName);
+    }
+
+    public static String getCallingHost() {
+        return ThreadContext.get(CALLING_HOST);
+    }
+
+    public static void setCallingHost(String hostName) {
+        ThreadContext.put(CALLING_HOST, hostName);
+    }
+}
diff --git a/sample-app/src/main/java/org/apache/logging/audit/SampleApp.java b/sample-app/src/main/java/org/apache/logging/audit/SampleApp.java
new file mode 100644
index 0000000..c3de8cc
--- /dev/null
+++ b/sample-app/src/main/java/org/apache/logging/audit/SampleApp.java
@@ -0,0 +1,59 @@
+/*
+ * 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.audit;
+
+import java.math.BigDecimal;
+import java.net.InetAddress;
+
+import org.apache.logging.log4j.audit.LogEventFactory;
+import org.apache.logging.log4j.audit.event.Deposit;
+import org.apache.logging.log4j.audit.event.Login;
+import org.apache.logging.log4j.core.util.NetUtils;
+
+public class SampleApp {
+
+    public static void main(String[] args) throws Exception {
+        String hostName = NetUtils.getLocalHostname();
+        RequestContext.setHostName(hostName);
+        String inetAddress = InetAddress.getLocalHost().getHostAddress();
+        RequestContext.setIpAddress(inetAddress);
+        RequestContext.setLoginId("testuser");
+        Login login = LogEventFactory.getEvent(Login.class);
+        login.logEvent();
+        String result = login("testuser");
+        login.setCompletionStatus(result);
+        login.logEvent();
+        Deposit deposit = LogEventFactory.getEvent(Deposit.class);
+        deposit.setAccount(123456);
+        deposit.setAmount(new BigDecimal(100.00));
+        deposit.logEvent();
+        result = deposit(deposit);
+        deposit.setCompletionStatus(result);
+        deposit.logEvent();
+        RequestContext.clear();
+    }
+
+    private static String login(String user) {
+        RequestContext.setUserId("1111");
+        RequestContext.setAccountNumber(12345L);
+        return "Success";
+    }
+
+    private static String deposit(Deposit deposit) {
+        return "Success";
+    }
+}
diff --git a/sample-app/src/main/resources/log4j2.xml b/sample-app/src/main/resources/log4j2.xml
new file mode 100644
index 0000000..87ff4e9
--- /dev/null
+++ b/sample-app/src/main/resources/log4j2.xml
@@ -0,0 +1,80 @@
+<?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="ERROR">
+  <properties>
+    <property name="LOG_DIR">target/logs</property>
+  </properties>
+  <MarkerFilter marker="FLOW" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
+  <MarkerFilter marker="Audit" onMatch="ACCEPT" onMisMatch="NEUTRAL"/>
+  <Appenders>
+    <Console name="Console" target="SYSTEM_OUT">
+      <PatternLayout pattern="%d{ABSOLUTE} %-5level # %class.%method %m%n" />
+    </Console>
+
+    <RollingFile name="log4j" fileName="${LOG_DIR}/log4j.txt" filePattern="${LOG_DIR}/archive/log4j.txt.%d{yyyyMMdd_HHmmss}-%i">
+      <PatternLayout>
+        <MarkerPatternSelector defaultPattern="%d [%t] %-5p %X{loginId, userId, ipAddress, corpAcctNumber} %C{1.}.%M:%L - %m%n">
+          <PatternMatch key="FLOW" pattern="%d [%t] %-5p %X{loginId, userId, ipAddress, corpAcctNumber} -------- %C{1.}.%M:%L %msg --------%n"/>
+        </MarkerPatternSelector>
+      </PatternLayout>
+      <Policies>
+        <SizeBasedTriggeringPolicy size="30 MB"/>
+      </Policies>
+      <!-- A max of 20 will allow 20 files per second with the date pattern specified on the RollingFile declaration.
+           Hopefully that is a ridiculous value -->
+      <DefaultRolloverStrategy min="1" max="20">
+        <Delete basePath="${LOG_DIR}/archive">
+          <!-- Nested conditions: the inner condition is only evaluated on files for which the outer conditions are true. -->
+          <IfFileName glob="log4j.txt.*">
+            <!-- Only allow 1 GB of files to accumulate -->
+            <IfAccumulatedFileSize exceeds="1 GB"/>
+          </IfFileName>
+        </Delete>
+      </DefaultRolloverStrategy>
+    </RollingFile>
+    <RollingFile name="audit" fileName="${LOG_DIR}/audit.log" filePattern="${LOG_DIR}/archive/audit.log.%d{yyyyMMdd_HHmmss}-%i">
+      <RFC5424Layout enterpriseNumber="18060" includeMDC="true" mdcId="RequestContext" appName="SampleApp"
+                     mdcPrefix="" newLine="true"/>
+      <Policies>
+        <SizeBasedTriggeringPolicy size="30 MB"/>
+      </Policies>
+      <!-- A max of 20 will allow 20 files per second with the date pattern specified on the RollingFile declaration.
+           Hopefully that is a ridiculous value -->
+      <DefaultRolloverStrategy min="1" max="20">
+        <Delete basePath="${LOG_DIR}/archive">
+          <!-- Nested conditions: the inner condition is only evaluated on files for which the outer conditions are true. -->
+          <IfFileName glob="audit.log.*">
+            <!-- Only allow 1 GB of files to accumulate -->
+            <IfAccumulatedFileSize exceeds="1 GB"/>
+          </IfFileName>
+        </Delete>
+      </DefaultRolloverStrategy>
+    </RollingFile>
+  </Appenders>
+  <Loggers>
+    <Logger name="org.apache.logging.log4j.audit" level="info" additivity="false">
+      <AppenderRef ref="log4j"/>
+    </Logger>
+    <Logger name="AuditLogger" level="trace" additivity="false">
+      <AppenderRef ref="audit"/>
+    </Logger>
+    <Root level="warn">
+      <AppenderRef ref="log4j" />
+    </Root>
+  </Loggers>
+</Configuration>
\ No newline at end of file