001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2010–2011 ApexIdentity Inc. 015 * Portions Copyright 2011-2014 ForgeRock AS. 016 */ 017 018package org.forgerock.openig.log; 019 020import org.forgerock.openig.heap.Name; 021 022/** 023 * Wraps a log sink and exposes a set of convenience methods for various logging activities. 024 */ 025public class Logger { 026 027 /** The sink to write log entries to. */ 028 private final LogSink sink; 029 030 /** The base source to write all log entries with. */ 031 private final Name source; 032 033 /** 034 * Constructs a new logger. If the supplied sink is {@code null}, then a 035 * {@link NullLogSink} will be used. 036 * @param sink the sink to write log entries to. 037 * @param source the base source to write all log entries with. 038 */ 039 public Logger(LogSink sink, Name source) { 040 this.sink = (sink != null ? sink : new NullLogSink()); 041 this.source = source; 042 } 043 044 /** 045 * Logs the message at the specified log level. 046 * 047 * @param level the log level to set in the log entry. 048 * @param message the message to be logged. 049 */ 050 public void logMessage(LogLevel level, String message) { 051 log(createEntry("log", level, message)); 052 } 053 054 /** 055 * Logs the specified exception. 056 * 057 * @param level the log level to set in the log entry. 058 * @param throwable the exception to be logged. 059 * @param <T> type of logged throwable 060 * @return the exception being logged. 061 */ 062 public <T extends Throwable> T logException(LogLevel level, T throwable) { 063 log(createEntry("throwable", level, throwable.getMessage(), throwable)); 064 return throwable; 065 } 066 067 /** 068 * Logs the specified message at the {@code ERROR} log level. 069 * 070 * @param message the message to be logged. 071 */ 072 public void error(String message) { 073 logMessage(LogLevel.ERROR, message); 074 } 075 076 /** 077 * Logs the specified exception at the {@code ERROR} log level. 078 * 079 * @param throwable the exception to be logged. 080 * @param <T> type of logged throwable 081 * @return the exception being logged. 082 */ 083 public <T extends Throwable> T error(T throwable) { 084 return logException(LogLevel.ERROR, throwable); 085 } 086 087 /** 088 * Logs the specified message at the {@code WARNING} log level. 089 * 090 * @param message the message to be logged. 091 */ 092 public void warning(String message) { 093 logMessage(LogLevel.WARNING, message); 094 } 095 096 /** 097 * Logs the specified exception at the {@code WARNING} log level. 098 * 099 * @param throwable the exception to be logged. 100 * @param <T> type of logged throwable 101 * @return the exception being logged. 102 */ 103 public <T extends Throwable> T warning(T throwable) { 104 return logException(LogLevel.WARNING, throwable); 105 } 106 107 /** 108 * Logs the specified message at the {@code INFO} log level. 109 * 110 * @param message the message to be logged. 111 */ 112 public void info(String message) { 113 logMessage(LogLevel.INFO, message); 114 } 115 116 /** 117 * Logs the specified exception at the {@code INFO} log level. 118 * 119 * @param throwable the exception to be logged. 120 * @param <T> type of logged throwable 121 * @return the exception being logged. 122 */ 123 public <T extends Throwable> T info(T throwable) { 124 return logException(LogLevel.INFO, throwable); 125 } 126 127 /** 128 * Logs the specified message at the {@code CONFIG} log level. 129 * 130 * @param message the message to be logged. 131 */ 132 public void config(String message) { 133 logMessage(LogLevel.CONFIG, message); 134 } 135 136 /** 137 * Logs the specified exception at the {@code CONFIG} log level. 138 * 139 * @param throwable the exception to be logged. 140 * @param <T> type of logged throwable 141 * @return the exception being logged. 142 */ 143 public <T extends Throwable> T config(T throwable) { 144 return logException(LogLevel.CONFIG, throwable); 145 } 146 147 /** 148 * Logs the specified message at the {@code DEBUG} log level. 149 * 150 * @param message the message to be logged. 151 */ 152 public void debug(String message) { 153 logMessage(LogLevel.DEBUG, message); 154 } 155 156 /** 157 * Logs the specified exception at the {@code DEBUG} log level. 158 * 159 * @param throwable the exception to be logged. 160 * @param <T> type of logged throwable 161 * @return the exception being logged. 162 */ 163 public <T extends Throwable> T debug(T throwable) { 164 return logException(LogLevel.DEBUG, throwable); 165 } 166 167 /** 168 * Logs the specified message at the {@code TRACE} log level. 169 * 170 * @param message the message to be logged. 171 */ 172 public void trace(String message) { 173 logMessage(LogLevel.TRACE, message); 174 } 175 176 /** 177 * Logs the specified exception at the {@code TRACE} log level. 178 * 179 * @param throwable the exception to be logged. 180 * @param <T> type of logged throwable 181 * @return the exception being logged. 182 */ 183 public <T extends Throwable> T trace(T throwable) { 184 return logException(LogLevel.TRACE, throwable); 185 } 186 187 /** 188 * Returns a new timer to measure elapsed time. Entries are written to the log with a 189 * {@code STAT} log level. 190 * @return A timer to measure elapsed time. 191 */ 192 public LogTimer getTimer() { 193 return new LogTimer(this, LogLevel.STAT); 194 } 195 196 /** 197 * Returns a new timer to measure elapsed time for a specified event. The event is 198 * appended to the source in hierarchical fashion. Entries are written to the log with a 199 * {@code STAT} log level. 200 * 201 * @param event the event that is being timed. 202 * @return A timer to measure elapsed time for a specified event. 203 */ 204 public LogTimer getTimer(String event) { 205 return new LogTimer(this, LogLevel.STAT, event); 206 } 207 208 /** 209 * Creates a {@link LogEntry} with the given parameters and no attached data. 210 * The created entry will inherit the source name of this logger. 211 * 212 * @param type 213 * entry type (free form tag String like {@literal log}, {@literal started} or {@literal elapsed}). 214 * @param level 215 * entry's level 216 * @param message 217 * entry's message 218 * @return a new entry with no attached data 219 */ 220 LogEntry createEntry(final String type, final LogLevel level, final String message) { 221 return createEntry(type, level, message, null); 222 } 223 224 /** 225 * Creates a {@link LogEntry} with the given parameters and attached data (possibly {@code null} data). 226 * The created entry will inherit the source name of this logger. 227 * 228 * @param type 229 * entry type (free form tag String like {@literal log}, {@literal started} or {@literal elapsed}). 230 * @param level 231 * entry's level 232 * @param message 233 * entry's message 234 * @param data 235 * entry's attached data 236 * @return a new entry with attached data (possibly {@code null} data) 237 */ 238 LogEntry createEntry(final String type, final LogLevel level, final String message, final Object data) { 239 return new LogEntry(source, type, level, message, data); 240 } 241 242 /** 243 * Logs an entry. This implementation will prepend the logger source to all log entries. 244 * 245 * @param entry the entry to be logged. 246 */ 247 public void log(LogEntry entry) { 248 sink.log(entry); 249 } 250 251 /** 252 * Returns {@code true} if the entry may be logged, given the specified source name and log 253 * level. 254 * 255 * @param source the source name that is intended to be logged. 256 * @param level the log level of the entry to be logged. 257 * @return {@code true} if the entry may be logged. 258 */ 259 public boolean isLoggable(Name source, LogLevel level) { 260 return sink.isLoggable(source, level); 261 } 262 263 /** 264 * Returns {@code true} if the entry may be logged, given the source of this logger and 265 * the specified log level. 266 * 267 * @param level the log level of the entry to be logged. 268 * @return {@code true} if the entry may be logged. 269 */ 270 public boolean isLoggable(LogLevel level) { 271 return sink.isLoggable(this.source, level); 272 } 273}