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.simple; 018 019import java.io.PrintStream; 020import java.text.DateFormat; 021import java.text.SimpleDateFormat; 022import java.util.Date; 023import java.util.Map; 024 025import org.apache.logging.log4j.Level; 026import org.apache.logging.log4j.Marker; 027import org.apache.logging.log4j.ThreadContext; 028import org.apache.logging.log4j.message.Message; 029import org.apache.logging.log4j.message.MessageFactory; 030import org.apache.logging.log4j.spi.AbstractLogger; 031import org.apache.logging.log4j.util.PropertiesUtil; 032import org.apache.logging.log4j.util.Strings; 033 034/** 035 * This is the default logger that is used when no suitable logging implementation is available. 036 */ 037public class SimpleLogger extends AbstractLogger { 038 039 private static final long serialVersionUID = 1L; 040 041 private static final char SPACE = ' '; 042 043 /** 044 * Used to format times. 045 * <p> 046 * Note that DateFormat is not Thread-safe. 047 * </p> 048 */ 049 private final DateFormat dateFormatter; 050 051 private Level level; 052 053 private final boolean showDateTime; 054 055 private final boolean showContextMap; 056 057 private PrintStream stream; 058 059 private final String logName; 060 061 public SimpleLogger(final String name, final Level defaultLevel, final boolean showLogName, 062 final boolean showShortLogName, final boolean showDateTime, final boolean showContextMap, 063 final String dateTimeFormat, final MessageFactory messageFactory, final PropertiesUtil props, 064 final PrintStream stream) { 065 super(name, messageFactory); 066 final String lvl = props.getStringProperty(SimpleLoggerContext.SYSTEM_PREFIX + name + ".level"); 067 this.level = Level.toLevel(lvl, defaultLevel); 068 if (showShortLogName) { 069 final int index = name.lastIndexOf("."); 070 if (index > 0 && index < name.length()) { 071 this.logName = name.substring(index + 1); 072 } else { 073 this.logName = name; 074 } 075 } else if (showLogName) { 076 this.logName = name; 077 } else { 078 this.logName = null; 079 } 080 this.showDateTime = showDateTime; 081 this.showContextMap = showContextMap; 082 this.stream = stream; 083 084 if (showDateTime) { 085 DateFormat format; 086 try { 087 format = new SimpleDateFormat(dateTimeFormat); 088 } catch (final IllegalArgumentException e) { 089 // If the format pattern is invalid - use the default format 090 format = new SimpleDateFormat(SimpleLoggerContext.DEFAULT_DATE_TIME_FORMAT); 091 } 092 this.dateFormatter = format; 093 } else { 094 this.dateFormatter = null; 095 } 096 } 097 098 @Override 099 public Level getLevel() { 100 return level; 101 } 102 103 @Override 104 public boolean isEnabled(final Level testLevel, final Marker marker, final Message msg, final Throwable t) { 105 return this.level.intLevel() >= testLevel.intLevel(); 106 } 107 108 @Override 109 public boolean isEnabled(final Level testLevel, final Marker marker, final CharSequence msg, final Throwable t) { 110 return this.level.intLevel() >= testLevel.intLevel(); 111 } 112 113 @Override 114 public boolean isEnabled(final Level testLevel, final Marker marker, final Object msg, final Throwable t) { 115 return this.level.intLevel() >= testLevel.intLevel(); 116 } 117 118 @Override 119 public boolean isEnabled(final Level testLevel, final Marker marker, final String msg) { 120 return this.level.intLevel() >= testLevel.intLevel(); 121 } 122 123 @Override 124 public boolean isEnabled(final Level testLevel, final Marker marker, final String msg, final Object... p1) { 125 return this.level.intLevel() >= testLevel.intLevel(); 126 } 127 128 @Override 129 public boolean isEnabled(final Level testLevel, final Marker marker, final String message, final Object p0) { 130 return this.level.intLevel() >= testLevel.intLevel(); 131 } 132 133 @Override 134 public boolean isEnabled(final Level testLevel, final Marker marker, final String message, final Object p0, 135 final Object p1) { 136 return this.level.intLevel() >= testLevel.intLevel(); 137 } 138 139 @Override 140 public boolean isEnabled(final Level testLevel, final Marker marker, final String message, final Object p0, 141 final Object p1, final Object p2) { 142 return this.level.intLevel() >= testLevel.intLevel(); 143 } 144 145 @Override 146 public boolean isEnabled(final Level testLevel, final Marker marker, final String message, final Object p0, 147 final Object p1, final Object p2, final Object p3) { 148 return this.level.intLevel() >= testLevel.intLevel(); 149 } 150 151 @Override 152 public boolean isEnabled(final Level testLevel, final Marker marker, final String message, final Object p0, 153 final Object p1, final Object p2, final Object p3, 154 final Object p4) { 155 return this.level.intLevel() >= testLevel.intLevel(); 156 } 157 158 @Override 159 public boolean isEnabled(final Level testLevel, final Marker marker, final String message, final Object p0, 160 final Object p1, final Object p2, final Object p3, 161 final Object p4, final Object p5) { 162 return this.level.intLevel() >= testLevel.intLevel(); 163 } 164 165 @Override 166 public boolean isEnabled(final Level testLevel, final Marker marker, final String message, final Object p0, 167 final Object p1, final Object p2, final Object p3, 168 final Object p4, final Object p5, final Object p6) { 169 return this.level.intLevel() >= testLevel.intLevel(); 170 } 171 172 @Override 173 public boolean isEnabled(final Level testLevel, final Marker marker, final String message, final Object p0, 174 final Object p1, final Object p2, final Object p3, 175 final Object p4, final Object p5, final Object p6, 176 final Object p7) { 177 return this.level.intLevel() >= testLevel.intLevel(); 178 } 179 180 @Override 181 public boolean isEnabled(final Level testLevel, final Marker marker, final String message, final Object p0, 182 final Object p1, final Object p2, final Object p3, 183 final Object p4, final Object p5, final Object p6, 184 final Object p7, final Object p8) { 185 return this.level.intLevel() >= testLevel.intLevel(); 186 } 187 188 @Override 189 public boolean isEnabled(final Level testLevel, final Marker marker, final String message, final Object p0, 190 final Object p1, final Object p2, final Object p3, 191 final Object p4, final Object p5, final Object p6, 192 final Object p7, final Object p8, final Object p9) { 193 return this.level.intLevel() >= testLevel.intLevel(); 194 } 195 196 @Override 197 public boolean isEnabled(final Level testLevel, final Marker marker, final String msg, final Throwable t) { 198 return this.level.intLevel() >= testLevel.intLevel(); 199 } 200 201 @Override 202 public void logMessage(final String fqcn, final Level mgsLevel, final Marker marker, final Message msg, 203 final Throwable throwable) { 204 final StringBuilder sb = new StringBuilder(); 205 // Append date-time if so configured 206 if (showDateTime) { 207 final Date now = new Date(); 208 String dateText; 209 synchronized (dateFormatter) { 210 dateText = dateFormatter.format(now); 211 } 212 sb.append(dateText); 213 sb.append(SPACE); 214 } 215 216 sb.append(mgsLevel.toString()); 217 sb.append(SPACE); 218 if (Strings.isNotEmpty(logName)) { 219 sb.append(logName); 220 sb.append(SPACE); 221 } 222 sb.append(msg.getFormattedMessage()); 223 if (showContextMap) { 224 final Map<String, String> mdc = ThreadContext.getImmutableContext(); 225 if (mdc.size() > 0) { 226 sb.append(SPACE); 227 sb.append(mdc.toString()); 228 sb.append(SPACE); 229 } 230 } 231 final Object[] params = msg.getParameters(); 232 Throwable t; 233 if (throwable == null && params != null && params.length > 0 234 && params[params.length - 1] instanceof Throwable) { 235 t = (Throwable) params[params.length - 1]; 236 } else { 237 t = throwable; 238 } 239 stream.println(sb.toString()); 240 if (t != null) { 241 stream.print(SPACE); 242 t.printStackTrace(stream); 243 } 244 } 245 246 public void setLevel(final Level level) { 247 if (level != null) { 248 this.level = level; 249 } 250 } 251 252 public void setStream(final PrintStream stream) { 253 this.stream = stream; 254 } 255 256}