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.pattern; 018 019import org.apache.logging.log4j.core.LogEvent; 020import org.apache.logging.log4j.core.config.plugins.Plugin; 021import org.apache.logging.log4j.core.pattern.ConverterKeys; 022import org.apache.logging.log4j.core.pattern.LogEventPatternConverter; 023import org.apache.logging.log4j.core.pattern.PatternConverter; 024import org.apache.logging.log4j.util.TriConsumer; 025 026/** 027 * Able to handle the contents of the LogEvent's MDC and either 028 * output the entire contents of the properties, or to output the value of a specific key 029 * within the property bundle when this pattern converter has the option set. 030 */ 031@Plugin(name = "Log4j1MdcPatternConverter", category = PatternConverter.CATEGORY) 032@ConverterKeys({ "properties" }) 033public final class Log4j1MdcPatternConverter extends LogEventPatternConverter { 034 /** 035 * Name of property to output. 036 */ 037 private final String key; 038 039 /** 040 * Private constructor. 041 * 042 * @param options options, may be null. 043 */ 044 private Log4j1MdcPatternConverter(final String[] options) { 045 super(options != null && options.length > 0 ? "Log4j1MDC{" + options[0] + '}' : "Log4j1MDC", "property"); 046 if (options != null && options.length > 0) { 047 key = options[0]; 048 } else { 049 key = null; 050 } 051 } 052 053 /** 054 * Obtains an instance of PropertiesPatternConverter. 055 * 056 * @param options options, may be null or first element contains name of property to format. 057 * @return instance of PropertiesPatternConverter. 058 */ 059 public static Log4j1MdcPatternConverter newInstance(final String[] options) { 060 return new Log4j1MdcPatternConverter(options); 061 } 062 063 /** 064 * {@inheritDoc} 065 */ 066 @Override 067 public void format(final LogEvent event, final StringBuilder toAppendTo) { 068 if (key == null) { 069 // if there is no additional options, we output every single Key/Value pair for the MDC 070 toAppendTo.append('{'); 071 event.getContextData().forEach(APPEND_EACH, toAppendTo); 072 toAppendTo.append('}'); 073 } else { 074 // otherwise they just want a single key output 075 final Object val = event.getContextData().getValue(key); 076 if (val != null) { 077 toAppendTo.append(val); 078 } 079 } 080 } 081 082 private static TriConsumer<String, Object, StringBuilder> APPEND_EACH = (key, value, toAppendTo) -> toAppendTo.append('{').append(key).append(',').append(value).append('}'); 083}