1 /*
2 * Copyright (c) 2002-2014, Mairie de 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 org.apache.log4j.BasicConfigurator;
37 import org.apache.log4j.Logger;
38 import org.apache.log4j.PropertyConfigurator;
39
40 import java.io.File;
41 import java.io.InputStream;
42
43 import java.util.Properties;
44
45
46 /**
47 * This class provides writing services in the application logs files
48 */
49 public final class AppLogService
50 {
51 // Constants
52 private static final String LOGGER_EVENTS = "lutece.event";
53 private static final String LOGGER_DEBUG = "lutece.debug";
54 private static final String LOGGER_ERRORS = "lutece.error";
55 private static final String SYSTEM_PROPERTY_LOG4J_CONFIGURATION = "log4j.configuration";
56
57 /** alternate log4j property file */
58 private static final String ALTERNATE_LOG_OVERRIDE_PATH = "override";
59 private static final String ALTERNATE_LOG_FILE = "log.properties";
60 private static Logger _loggerEvents = Logger.getLogger( LOGGER_EVENTS );
61 private static Logger _loggerErrors = Logger.getLogger( LOGGER_ERRORS );
62 private static Logger _loggerDebug = Logger.getLogger( LOGGER_DEBUG );
63
64 /**
65 * Creates a new AppLogService object.
66 */
67 private AppLogService( )
68 {
69 }
70
71 /**
72 * Initializes a very basic logging system (everything to stdout)
73 */
74 public static void preinit( )
75 {
76 BasicConfigurator.configure();
77 info("Lutece logs pre-initialized: sending all logs to stdout.");
78 }
79
80 /**
81 * initializes the errors log file and the application log file
82 * @param strConfigPath The strConfigPath
83 * @param strConfigFile The strConfigFile
84 */
85 public static void init( String strConfigPath, String strConfigFile )
86 {
87 BasicConfigurator.resetConfiguration();
88 //Initialize the logger and configures it with the values of the properties file : config.properties
89 try
90 {
91 _loggerEvents.setAdditivity( false );
92
93 _loggerDebug.setAdditivity( false );
94
95 String strAbsoluteConfigDirectoryPath = AppPathService.getAbsolutePathFromRelativePath( strConfigPath );
96
97 String strAlternateFilePath = strAbsoluteConfigDirectoryPath +
98 ( strAbsoluteConfigDirectoryPath.endsWith( "/" ) ? "" : "/" ) + ALTERNATE_LOG_OVERRIDE_PATH;
99
100 File alternateLogFile = new File( strAlternateFilePath + File.separator + ALTERNATE_LOG_FILE );
101
102 boolean bAlternateConfigFile = alternateLogFile.exists( );
103
104 InputStream is;
105 String strLog4jConfigFile;
106
107 if ( bAlternateConfigFile )
108 {
109 // Load loggers configuration from the log.properties
110 is = AppPathService.getResourceAsStream( strConfigPath + ( strConfigPath.endsWith( "/" ) ? "" : "/" ) +
111 ALTERNATE_LOG_OVERRIDE_PATH + "/", ALTERNATE_LOG_FILE );
112 strLog4jConfigFile = alternateLogFile.getAbsolutePath( );
113 }
114 else
115 {
116 // Load loggers configuration from the config.properties
117 is = AppPathService.getResourceAsStream( strConfigPath, strConfigFile );
118 strLog4jConfigFile = strAbsoluteConfigDirectoryPath +
119 ( ( strAbsoluteConfigDirectoryPath.endsWith( "/" ) ) ? "" : "/" ) + strConfigFile;
120 }
121
122 Properties props = new Properties( );
123 props.load( is );
124 PropertyConfigurator.configure( props );
125 is.close( );
126
127 // Define the config.properties as log4j configuration file for other libraries using
128 // the System property "log4j.configuration"
129 System.setProperty( SYSTEM_PROPERTY_LOG4J_CONFIGURATION, strLog4jConfigFile );
130
131 if ( bAlternateConfigFile )
132 {
133 debug( "Loaded log properties from alternate log.properties file " );
134 }
135 }
136 catch ( Exception e )
137 {
138 System.err.println( "Bad Configuration of Log4j : " + e );
139 }
140 info("Lutece logs initialized, using configured property files to define levels and appenders.");
141 }
142
143 ////////////////////////////////////////////////////////////////////////////
144 // Log4j wrappers
145
146 /**
147 * Tells if the logger accepts debug messages. If not it prevents to build
148 * consuming messages that will be ignored.
149 * @return True if the logger accepts debug messages, otherwise false.
150 */
151 public static boolean isDebugEnabled( )
152 {
153 return _loggerDebug.isDebugEnabled( );
154 }
155
156 /**
157 * Log a message object with the DEBUG level. It is logged in application.log
158 *
159 * @param objToLog the message object to log
160 */
161 public static void debug( Object objToLog )
162 {
163 if ( _loggerDebug.isDebugEnabled( ) )
164 {
165 _loggerDebug.debug( objToLog );
166 }
167 }
168
169 /**
170 * Tells if the logger accepts debug messages. If not it prevents to build
171 * consuming messages that will be ignored.
172 * @param strLogger The Logger name
173 * @return True if the logger accepts debug messages, otherwise false.
174 */
175 public static boolean isDebugEnabled( String strLogger )
176 {
177 Logger logger = Logger.getLogger( strLogger );
178
179 return logger.isDebugEnabled( );
180 }
181
182 /**
183 * Log a message object with the DEBUG level. It is logged in application.log
184 *
185 * @param strLogger The Logger name
186 * @param objToLog the message object to log
187 */
188 public static void debug( String strLogger, Object objToLog )
189 {
190 Logger logger = Logger.getLogger( strLogger );
191
192 if ( logger.isDebugEnabled( ) )
193 {
194 logger.debug( objToLog );
195 }
196 }
197
198 /**
199 * Log a message object with the ERROR Level. It is logged in error.log
200 *
201 * @param objToLog the message object to log
202 */
203 public static void error( Object objToLog )
204 {
205 if ( _loggerErrors != null )
206 {
207 _loggerErrors.error( objToLog );
208 }
209 }
210
211 /**
212 * Log a message object with the ERROR level including the stack trace of
213 * the Throwable t passed as parameter. It
214 * is logged in error.log
215 *
216 * @param message the message object to log
217 * @param t the exception to log, including its stack trace
218 */
219 public static void error( Object message, Throwable t )
220 {
221 if ( _loggerErrors != null )
222 {
223 _loggerErrors.error( message, t );
224 }
225 }
226
227 /**
228 * Log a message object with the INFO Level in application.log
229 *
230 * @param objToLog the message object to log
231 */
232 public static void info( Object objToLog )
233 {
234 if ( ( _loggerEvents != null ) && _loggerEvents.isInfoEnabled( ) )
235 {
236 _loggerEvents.info( objToLog );
237 }
238 }
239 }