001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.log4j.rewrite; 018 019import org.apache.log4j.bridge.LogEventAdapter; 020import org.apache.log4j.helpers.OptionConverter; 021import org.apache.log4j.spi.LocationInfo; 022import org.apache.log4j.spi.LoggingEvent; 023import org.apache.logging.log4j.core.LogEvent; 024import org.apache.logging.log4j.core.impl.Log4jLogEvent; 025import org.apache.logging.log4j.message.SimpleMessage; 026import org.apache.logging.log4j.util.SortedArrayStringMap; 027 028import java.util.Collections; 029import java.util.HashMap; 030import java.util.Map; 031import java.util.StringTokenizer; 032 033/** 034 * This policy rewrites events by adding 035 * a user-specified list of properties to the event. 036 * Existing properties are not modified. 037 * <p> 038 * The combination of the RewriteAppender and this policy 039 * performs the same actions as the PropertyFilter from log4j 1.3. 040 * </p> 041 */ 042public class PropertyRewritePolicy implements RewritePolicy { 043 private Map<String, String> properties = Collections.EMPTY_MAP; 044 045 public PropertyRewritePolicy() { 046 } 047 048 /** 049 * Set a string representing the property name/value pairs. 050 * <p> 051 * Form: 052 * </p> 053 * <pre> 054 * propname1=propvalue1,propname2=propvalue2 055 * </pre> 056 * 057 * @param properties The properties. 058 */ 059 public void setProperties(String properties) { 060 Map<String, String> newMap = new HashMap<>(); 061 StringTokenizer pairs = new StringTokenizer(properties, ","); 062 while (pairs.hasMoreTokens()) { 063 StringTokenizer entry = new StringTokenizer(pairs.nextToken(), "="); 064 newMap.put(entry.nextElement().toString().trim(), entry.nextElement().toString().trim()); 065 } 066 synchronized (this) { 067 this.properties = newMap; 068 } 069 } 070 071 /** 072 * {@inheritDoc} 073 */ 074 @Override 075 public LoggingEvent rewrite(final LoggingEvent source) { 076 if (!properties.isEmpty()) { 077 Map<String, String> rewriteProps = source.getProperties() != null ? new HashMap<>(source.getProperties()) 078 : new HashMap<>(); 079 for (Map.Entry<String, String> entry : properties.entrySet()) { 080 if (!rewriteProps.containsKey(entry.getKey())) { 081 rewriteProps.put(entry.getKey(), entry.getValue()); 082 } 083 } 084 LogEvent event; 085 if (source instanceof LogEventAdapter) { 086 event = new Log4jLogEvent.Builder(((LogEventAdapter) source).getEvent()) 087 .setContextData(new SortedArrayStringMap(rewriteProps)) 088 .build(); 089 } else { 090 LocationInfo info = source.getLocationInformation(); 091 StackTraceElement element = new StackTraceElement(info.getClassName(), info.getMethodName(), 092 info.getFileName(), Integer.parseInt(info.getLineNumber())); 093 Thread thread = getThread(source.getThreadName()); 094 long threadId = thread != null ? thread.getId() : 0; 095 int threadPriority = thread != null ? thread.getPriority() : 0; 096 event = Log4jLogEvent.newBuilder() 097 .setContextData(new SortedArrayStringMap(rewriteProps)) 098 .setLevel(OptionConverter.convertLevel(source.getLevel())) 099 .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}