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.logging.log4j.internal; 018 019import org.apache.logging.log4j.Level; 020import org.apache.logging.log4j.LogBuilder; 021import org.apache.logging.log4j.Logger; 022import org.apache.logging.log4j.Marker; 023import org.apache.logging.log4j.message.Message; 024import org.apache.logging.log4j.message.SimpleMessage; 025import org.apache.logging.log4j.status.StatusLogger; 026import org.apache.logging.log4j.util.LambdaUtil; 027import org.apache.logging.log4j.util.StackLocatorUtil; 028import org.apache.logging.log4j.util.Supplier; 029 030 031/** 032 * Collects data for a log event and then logs it. This class should be considered private. 033 */ 034public class DefaultLogBuilder implements LogBuilder { 035 036 private static Message EMPTY_MESSAGE = new SimpleMessage(""); 037 private static final String FQCN = DefaultLogBuilder.class.getName(); 038 private static final Logger LOGGER = StatusLogger.getLogger(); 039 040 private final Logger logger; 041 private Level level; 042 private Marker marker; 043 private Throwable throwable; 044 private StackTraceElement location; 045 private volatile boolean inUse; 046 private long threadId; 047 048 public DefaultLogBuilder(Logger logger, Level level) { 049 this.logger = logger; 050 this.level = level; 051 this.threadId = Thread.currentThread().getId(); 052 this.inUse = true; 053 } 054 055 public DefaultLogBuilder(Logger logger) { 056 this.logger = logger; 057 this.inUse = false; 058 this.threadId = Thread.currentThread().getId(); 059 } 060 061 /** 062 * This method should be considered internal. It is used to reset the LogBuilder for a new log message. 063 * @param level The logging level for this event. 064 * @return This LogBuilder instance. 065 */ 066 public LogBuilder reset(Level level) { 067 this.inUse = true; 068 this.level = level; 069 this.marker = null; 070 this.throwable = null; 071 this.location = null; 072 return this; 073 } 074 075 @Override 076 public LogBuilder withMarker(Marker marker) { 077 this.marker = marker; 078 return this; 079 } 080 081 @Override 082 public LogBuilder withThrowable(Throwable throwable) { 083 this.throwable = throwable; 084 return this; 085 } 086 087 @Override 088 public LogBuilder withLocation() { 089 location = StackLocatorUtil.getStackTraceElement(2); 090 return this; 091 } 092 093 @Override 094 public LogBuilder withLocation(StackTraceElement location) { 095 this.location = location; 096 return this; 097 } 098 099 public boolean isInUse() { 100 return inUse; 101 } 102 103 @Override 104 public void log(Message message) { 105 if (isValid()) { 106 logMessage(message); 107 } 108 } 109 110 @Override 111 public void log(CharSequence message) { 112 if (isValid()) { 113 logMessage(logger.getMessageFactory().newMessage(message)); 114 } 115 } 116 117 @Override 118 public void log(String message) { 119 if (isValid()) { 120 logMessage(logger.getMessageFactory().newMessage(message)); 121 } 122 } 123 124 @Override 125 public void log(String message, Object... params) { 126 if (isValid()) { 127 logMessage(logger.getMessageFactory().newMessage(message, params)); 128 } 129 } 130 131 @Override 132 public void log(String message, Supplier<?>... params) { 133 if (isValid()) { 134 logMessage(logger.getMessageFactory().newMessage(message, LambdaUtil.getAll(params))); 135 } 136 } 137 138 @Override 139 public void log(Supplier<Message> messageSupplier) { 140 if (isValid()) { 141 logMessage(messageSupplier.get()); 142 } 143 } 144 145 @Override 146 public void log(Object message) { 147 if (isValid()) { 148 logMessage(logger.getMessageFactory().newMessage(message)); 149 } 150 } 151 152 @Override 153 public void log(String message, Object p0) { 154 if (isValid()) { 155 logMessage(logger.getMessageFactory().newMessage(message, p0)); 156 } 157 } 158 159 @Override 160 public void log(String message, Object p0, Object p1) { 161 if (isValid()) { 162 logMessage(logger.getMessageFactory().newMessage(message, p0, p1)); 163 } 164 } 165 166 @Override 167 public void log(String message, Object p0, Object p1, Object p2) { 168 if (isValid()) { 169 logMessage(logger.getMessageFactory().newMessage(message, p0, p1, p2)); 170 } 171 } 172 173 @Override 174 public void log(String message, Object p0, Object p1, Object p2, Object p3) { 175 if (isValid()) { 176 logMessage(logger.getMessageFactory().newMessage(message, p0, p1, p2, p3)); 177 } 178 } 179 180 @Override 181 public void log(String message, Object p0, Object p1, Object p2, Object p3, Object p4) { 182 if (isValid()) { 183 logMessage(logger.getMessageFactory().newMessage(message, p0, p1, p2, p3, p4)); 184 } 185 } 186 187 @Override 188 public void log(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5) { 189 if (isValid()) { 190 logMessage(logger.getMessageFactory().newMessage(message, p0, p1, p2, p3, p4, p5)); 191 } 192 } 193 194 @Override 195 public void log(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6) { 196 if (isValid()) { 197 logMessage(logger.getMessageFactory().newMessage(message, p0, p1, p2, p3, p4, p5, p6)); 198 } 199 } 200 201 @Override 202 public void log(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, 203 Object p7) { 204 if (isValid()) { 205 logMessage(logger.getMessageFactory().newMessage(message, p0, p1, p2, p3, p4, p5, p6, p7)); 206 } 207 } 208 209 @Override 210 public void log(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, 211 Object p7, Object p8) { 212 if (isValid()) { 213 logMessage(logger.getMessageFactory().newMessage(message, p0, p1, p2, p3, p4, p5, p6, p7, p8)); 214 } 215 } 216 217 @Override 218 public void log(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, 219 Object p7, Object p8, Object p9) { 220 if (isValid()) { 221 logMessage(logger.getMessageFactory().newMessage(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)); 222 } 223 } 224 225 @Override 226 public void log() { 227 if (isValid()) { 228 logMessage(EMPTY_MESSAGE); 229 } 230 } 231 232 private void logMessage(Message message) { 233 try { 234 logger.logMessage(level, marker, FQCN, location, message, throwable); 235 } finally { 236 inUse = false; 237 } 238 } 239 240 private boolean isValid() { 241 if (!inUse) { 242 LOGGER.warn("Attempt to reuse LogBuilder was ignored. {}", 243 StackLocatorUtil.getCallerClass(2)); 244 return false ; 245 } 246 if (this.threadId != Thread.currentThread().getId()) { 247 LOGGER.warn("LogBuilder can only be used on the owning thread. {}", 248 StackLocatorUtil.getCallerClass(2)); 249 return false; 250 } 251 return true; 252 } 253}