View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.log4j.rewrite;
18  
19  import org.apache.log4j.bridge.LogEventAdapter;
20  import org.apache.log4j.helpers.OptionConverter;
21  import org.apache.log4j.spi.LocationInfo;
22  import org.apache.log4j.spi.LoggingEvent;
23  import org.apache.logging.log4j.core.LogEvent;
24  import org.apache.logging.log4j.core.impl.Log4jLogEvent;
25  import org.apache.logging.log4j.message.SimpleMessage;
26  import org.apache.logging.log4j.util.SortedArrayStringMap;
27  
28  import java.util.Collections;
29  import java.util.HashMap;
30  import java.util.Map;
31  import java.util.StringTokenizer;
32  
33  /**
34   * This policy rewrites events by adding
35   * a user-specified list of properties to the event.
36   * Existing properties are not modified.
37   * <p>
38   * The combination of the RewriteAppender and this policy
39   * performs the same actions as the PropertyFilter from log4j 1.3.
40   * </p>
41   */
42  public class PropertyRewritePolicy implements RewritePolicy {
43      private Map<String, String> properties = Collections.EMPTY_MAP;
44  
45      public PropertyRewritePolicy() {
46      }
47  
48      /**
49       * Set a string representing the property name/value pairs.
50       * <p>
51       * Form:
52       * </p>
53       * <pre>
54       * propname1=propvalue1,propname2=propvalue2
55       * </pre>
56       *
57       * @param properties The properties.
58       */
59      public void setProperties(String properties) {
60          Map<String, String> newMap = new HashMap<>();
61          StringTokenizer pairs = new StringTokenizer(properties, ",");
62          while (pairs.hasMoreTokens()) {
63              StringTokenizer entry = new StringTokenizer(pairs.nextToken(), "=");
64              newMap.put(entry.nextElement().toString().trim(), entry.nextElement().toString().trim());
65          }
66          synchronized (this) {
67              this.properties = newMap;
68          }
69      }
70  
71      /**
72       * {@inheritDoc}
73       */
74      @Override
75      public LoggingEvent rewrite(final LoggingEvent source) {
76          if (!properties.isEmpty()) {
77              Map<String, String> rewriteProps = source.getProperties() != null ? new HashMap<>(source.getProperties())
78                      : new HashMap<>();
79              for (Map.Entry<String, String> entry : properties.entrySet()) {
80                  if (!rewriteProps.containsKey(entry.getKey())) {
81                      rewriteProps.put(entry.getKey(), entry.getValue());
82                  }
83              }
84              LogEvent event;
85              if (source instanceof LogEventAdapter) {
86                  event = new Log4jLogEvent.Builder(((LogEventAdapter) source).getEvent())
87                          .setContextData(new SortedArrayStringMap(rewriteProps))
88                          .build();
89              } else {
90                  LocationInfo info = source.getLocationInformation();
91                  StackTraceElement element = new StackTraceElement(info.getClassName(), info.getMethodName(),
92                          info.getFileName(), Integer.parseInt(info.getLineNumber()));
93                  Thread thread = getThread(source.getThreadName());
94                  long threadId = thread != null ? thread.getId() : 0;
95                  int threadPriority = thread != null ? thread.getPriority() : 0;
96                  event = Log4jLogEvent.newBuilder()
97                          .setContextData(new SortedArrayStringMap(rewriteProps))
98                          .setLevel(OptionConverter.convertLevel(source.getLevel()))
99                          .setLoggerFqcn(source.getFQNOfLoggerClass())
100                         .setMarker(null)
101                         .setMessage(new SimpleMessage(source.getRenderedMessage()))
102                         .setSource(element)
103                         .setLoggerName(source.getLoggerName())
104                         .setThreadName(source.getThreadName())
105                         .setThreadId(threadId)
106                         .setThreadPriority(threadPriority)
107                         .setThrown(source.getThrowableInformation().getThrowable())
108                         .setTimeMillis(source.getTimeStamp())
109                         .setNanoTime(0)
110                         .setThrownProxy(null)
111                         .build();
112             }
113             return new LogEventAdapter(event);
114         }
115         return source;
116     }
117 
118     private Thread getThread(String name) {
119         for (Thread thread : Thread.getAllStackTraces().keySet()) {
120             if (thread.getName().equals(name)) {
121                 return thread;
122             }
123         }
124         return null;
125     }
126 }