1 /* 2 * Copyright (c) 2002-2022, City of Paris 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright notice 10 * and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright notice 13 * and the following disclaimer in the documentation and/or other materials 14 * provided with the distribution. 15 * 16 * 3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its 17 * contributors may be used to endorse or promote products derived from 18 * this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE 24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 * 32 * License 1.0 33 */ 34 package fr.paris.lutece.portal.service.util; 35 36 import java.util.ArrayList; 37 import java.util.Collection; 38 import org.apache.logging.log4j.Level; 39 import org.apache.logging.log4j.LogManager; 40 import org.apache.logging.log4j.Logger; 41 import org.apache.logging.log4j.core.LoggerContext; 42 import org.apache.logging.log4j.util.Supplier; 43 44 /** 45 * This class provides writing services in the application logs files 46 */ 47 public final class AppLogService 48 { 49 // Constants 50 private static final String LOGGER_EVENTS = "lutece.event"; 51 private static final String LOGGER_DEBUG = "lutece.debug"; 52 private static final String LOGGER_ERRORS = "lutece.error"; 53 private static Logger _loggerEvents = LogManager.getLogger( LOGGER_EVENTS ); 54 private static Logger _loggerErrors = LogManager.getLogger( LOGGER_ERRORS ); 55 private static Logger _loggerDebug = LogManager.getLogger( LOGGER_DEBUG ); 56 57 /** 58 * Creates a new AppLogService object. 59 */ 60 private AppLogService( ) 61 { 62 } 63 // ////////////////////////////////////////////////////////////////////////// 64 // Log4j wrappers 65 66 /** 67 * Tells if the logger accepts debug messages. If not it prevents to build consuming messages that will be ignored. 68 * 69 * @return True if the logger accepts debug messages, otherwise false. 70 */ 71 public static boolean isDebugEnabled( ) 72 { 73 return _loggerDebug.isDebugEnabled( ); 74 } 75 76 /** 77 * Log a message object with the DEBUG level. It is logged in application.log 78 * 79 * @param objToLog 80 * the message object to log 81 */ 82 public static void debug( Object objToLog ) 83 { 84 _loggerDebug.debug( objToLog ); 85 } 86 87 /** 88 * Logs a message with parameters at the {@link Level#DEBUG DEBUG} level. 89 * 90 * To improve performance, do not use String concatenation such as : AppLogService.error( "my message with param1 " + param1 + " and " + param2, myexception 91 * ); Recommended use : AppLogService.error( "my message with param1 {} and param2 {}", param1, param2, myexception ); 92 * 93 * @param message 94 * the message to log; the format depends on the message factory. 95 * @param params 96 * parameters to the message. 97 * @see Logger##getMessageFactory() 98 */ 99 public static void debug( String message, Object... params ) 100 { 101 _loggerDebug.debug( message, params ); 102 } 103 104 /** 105 * Logs a message with parameters which are only to be constructed if the logging level is the {@link Level#DEBUG DEBUG} level. 106 * 107 * @param message 108 * the message to log; the format depends on the message factory. 109 * @param paramSuppliers 110 * An array of functions, which when called, produce the desired log message parameters. 111 */ 112 public static void debug( String message, Supplier<?>... paramSuppliers ) 113 { 114 _loggerDebug.debug( message, paramSuppliers ); 115 } 116 117 /** 118 * Tells if the logger accepts debug messages. If not it prevents to build consuming messages that will be ignored. 119 * 120 * @param strLogger 121 * The Logger name 122 * @return True if the logger accepts debug messages, otherwise false. 123 */ 124 public static boolean isDebugEnabled( String strLogger ) 125 { 126 Logger logger = LogManager.getLogger( strLogger ); 127 128 return logger.isDebugEnabled( ); 129 } 130 131 /** 132 * Log a message object with the ERROR Level. It is logged in error.log 133 * 134 * @param objToLog 135 * the message object to log 136 */ 137 public static void error( Object objToLog ) 138 { 139 _loggerErrors.error( objToLog ); 140 } 141 142 /** 143 * Log a message object with the ERROR level including the stack trace of the Throwable t passed as parameter. It is logged in error.log 144 * 145 * @param message 146 * the message object to log 147 * @param t 148 * the exception to log, including its stack trace 149 */ 150 public static void error( Object message, Throwable t ) 151 { 152 _loggerErrors.error( message, t ); 153 } 154 155 /** 156 * Logs a message with parameters at the {@link Level#ERROR ERROR} level. 157 * 158 * To improve performance, do not use String concatenation such as : AppLogService.error( "my message with param1 " + param1 + " and " + param2, 159 * myexception); Recommended use : AppLogService.error( "my message with param1 {} and param2 {}", param1, param2, myexception ); 160 * 161 * @param message 162 * the message to log; the format depends on the message factory. 163 * @param params 164 * parameters to the message. 165 * @see Logger#getMessageFactory() 166 */ 167 public static void error( String message, Object... params ) 168 { 169 170 _loggerErrors.error( message, params ); 171 } 172 173 /** 174 * Logs a message with parameters which are only to be constructed if the logging level is the {@link Level#ERROR ERROR} level. 175 * 176 * @param message 177 * the message to log; the format depends on the message factory. 178 * @param paramSuppliers 179 * An array of functions, which when called, produce the desired log message parameters. 180 */ 181 public static void error( String message, Supplier<?>... paramSuppliers ) 182 { 183 184 _loggerErrors.error( message, paramSuppliers ); 185 } 186 187 /** 188 * Tells if the logger accepts error messages. If not it prevents to build consuming messages that will be ignored. 189 * 190 * @return True if the logger accepts error messages, otherwise false. 191 */ 192 public static boolean isErrorEnabled( ) 193 { 194 return _loggerErrors.isErrorEnabled( ); 195 } 196 197 /** 198 * Log a message object with the INFO Level in application.log 199 * 200 * @param objToLog 201 * the message object to log 202 */ 203 public static void info( Object objToLog ) 204 { 205 _loggerEvents.info( objToLog ); 206 207 } 208 209 /** 210 * Logs a message with parameters at the {@link Level#INFO INFO} level. 211 * 212 * To improve performance, do not use String concatenation such as : AppLogService.error( "my message with param1 " + param1 + " and " + param2, myexception 213 * ); Recommended use : AppLogService.error( "my message with param1 {} and param2 {}", param1, param2, myexception ); 214 * 215 * @param message 216 * the message to log; the format depends on the message factory. 217 * @param params 218 * parameters to the message. 219 * @see Logger##getMessageFactory() 220 */ 221 public static void info( String message, Object... params ) 222 { 223 _loggerEvents.info( message, params ); 224 } 225 226 /** 227 * Logs a message with parameters which are only to be constructed if the logging level is the {@link Level#INFO INFO} level. 228 * 229 * @param message 230 * the message to log; the format depends on the message factory. 231 * @param paramSuppliers 232 * An array of functions, which when called, produce the desired log message parameters. 233 */ 234 public static void info( String message, Supplier<?>... paramSuppliers ) 235 { 236 _loggerEvents.info( message, paramSuppliers ); 237 } 238 239 /** 240 * Tells if the logger accepts info messages. If not it prevents to build consuming messages that will be ignored. 241 * 242 * @return True if the logger accepts info messages, otherwise false. 243 */ 244 public static boolean isInfoEnabled( ) 245 { 246 return _loggerEvents.isInfoEnabled( ); 247 } 248 249 /** 250 * Gets the all the loggers. 251 * 252 * @return the all the loggers 253 */ 254 public static Collection<LoggerInfo> getLoggersInfo( ) 255 { 256 Collection<LoggerInfo> allLoggersInfo = new ArrayList<>( ); 257 Collection<org.apache.logging.log4j.core.Logger> allLoggers = LoggerContext.getContext( ).getLoggers( ); 258 LoggerContext logContext = LoggerContext.getContext( ); 259 for ( org.apache.logging.log4j.core.Logger logger : allLoggers ) 260 { 261 LoggerInfo log = new LoggerInfo( ); 262 log.setName( logger.getName( ) ); 263 log.setLevel( logger.getLevel( ).name( ) ); 264 log.setPath( logContext.getConfigLocation( ).getPath( ) ); 265 allLoggersInfo.add( log ); 266 } 267 268 return allLoggersInfo; 269 } 270 }