001/* 002 * Copyright 2010-2014 UnboundID Corp. 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2010-2014 UnboundID Corp. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021package com.unboundid.util; 022 023 024 025import java.io.Serializable; 026import java.text.SimpleDateFormat; 027import java.util.Date; 028import java.util.logging.Formatter; 029import java.util.logging.LogRecord; 030 031 032 033/** 034 * This class provides a log formatter for use in the Java logging framework 035 * that may be used to minimize the formatting applied to log messages. 036 */ 037@NotMutable() 038@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 039public final class MinimalLogFormatter 040 extends Formatter 041 implements Serializable 042{ 043 /** 044 * The default format string that will be used for generating timestamps. 045 */ 046 public static final String DEFAULT_TIMESTAMP_FORMAT = 047 "'['dd/MMM/yyyy:HH:mm:ss Z']'"; 048 049 050 051 /** 052 * The set of thread-local date formatters that will be used for generating 053 * message timestamps. 054 */ 055 private static final ThreadLocal<SimpleDateFormat> DATE_FORMATTERS = 056 new ThreadLocal<SimpleDateFormat>(); 057 058 059 060 /** 061 * The set of thread-local buffers that will be used for generating the 062 * message. 063 */ 064 private static final ThreadLocal<StringBuilder> BUFFERS = 065 new ThreadLocal<StringBuilder>(); 066 067 068 069 /** 070 * The serial version UID for this serializable class. 071 */ 072 private static final long serialVersionUID = -2884878613513769233L; 073 074 075 076 // Indicates whether to include the log level in the message header. 077 private final boolean includeLevel; 078 079 // Indicates whether to include a line break after the header. 080 private final boolean lineBreakAfterHeader; 081 082 // Indicates whether to include a line break after the message. 083 private final boolean lineBreakAfterMessage; 084 085 // The format string that will be used to generate timestamps, if appropriate. 086 private final String timestampFormat; 087 088 089 090 /** 091 * Creates a new instance of this log formatter with the default settings. 092 * Generated messages will include a timestamp generated using the format 093 * string "{@code '['dd/MMM/yyyy:HH:mm:ss Z']'}", will not include the log 094 * level, and will not include a line break after the timestamp or the 095 * message. 096 */ 097 public MinimalLogFormatter() 098 { 099 this(DEFAULT_TIMESTAMP_FORMAT, false, false, false); 100 } 101 102 103 104 /** 105 * Creates a new instance of this log formatter with the provided 106 * configuration. 107 * 108 * @param timestampFormat The format string used to generate 109 * timestamps. If this is {@code null}, then 110 * timestamps will not be included in log 111 * messages. 112 * @param includeLevel Indicates whether to include the log level 113 * in the generated messages. 114 * @param lineBreakAfterHeader Indicates whether to insert a line break 115 * after the timestamp and/or log level. 116 * @param lineBreakAfterMessage Indicates whether to insert aline break 117 * after the generated message. 118 */ 119 public MinimalLogFormatter(final String timestampFormat, 120 final boolean includeLevel, 121 final boolean lineBreakAfterHeader, 122 final boolean lineBreakAfterMessage) 123 { 124 this.timestampFormat = timestampFormat; 125 this.includeLevel = includeLevel; 126 this.lineBreakAfterHeader = lineBreakAfterHeader; 127 this.lineBreakAfterMessage = lineBreakAfterMessage; 128 } 129 130 131 132 /** 133 * Formats the provided log record. 134 * 135 * @param record The log record to be formatted. 136 * 137 * @return A string containing the formatted log record. 138 */ 139 @Override() 140 public String format(final LogRecord record) 141 { 142 StringBuilder b = BUFFERS.get(); 143 if (b == null) 144 { 145 b = new StringBuilder(); 146 BUFFERS.set(b); 147 } 148 else 149 { 150 b.setLength(0); 151 } 152 153 if (timestampFormat != null) 154 { 155 SimpleDateFormat f = DATE_FORMATTERS.get(); 156 if (f == null) 157 { 158 f = new SimpleDateFormat(timestampFormat); 159 DATE_FORMATTERS.set(f); 160 } 161 162 b.append(f.format(new Date())); 163 } 164 165 if (includeLevel) 166 { 167 if (b.length() > 0) 168 { 169 b.append(' '); 170 } 171 172 b.append(record.getLevel().toString()); 173 } 174 175 if (lineBreakAfterHeader) 176 { 177 b.append(StaticUtils.EOL); 178 } 179 else if (b.length() > 0) 180 { 181 b.append(' '); 182 } 183 184 b.append(formatMessage(record)); 185 186 if (lineBreakAfterMessage) 187 { 188 b.append(StaticUtils.EOL); 189 } 190 191 return b.toString(); 192 } 193}