· 8 years ago · Dec 24, 2017, 12:14 AM
1package org.jbjf.core;
2
3import java.io.File;
4import java.net.URL;
5import java.util.Enumeration;
6
7import org.apache.log4j.ConsoleAppender;
8import org.apache.log4j.FileAppender;
9import org.apache.log4j.Level;
10import org.apache.log4j.LogManager;
11import org.apache.log4j.Logger;
12import org.apache.log4j.PatternLayout;
13import org.apache.log4j.xml.DOMConfigurator;
14
15/**
16 * <p>
17 * The <code>RootLogger</code> is a simple log4j singleton class
18 * that provides an easy management interface to configure, get, set,
19 * re-configure the log4j framework for your application.
20 * </p>
21 * <p>
22 * <h3>Dependencies:</h3>
23 * <ul>
24 * <li>JRE/JDK 6(+)</li>
25 * </ul>
26 * </p>
27 * <p>
28 * <h3>Details</h3>
29 * <hr>
30 * <h4>Input Resources</h4>
31 * <table border='1' width='100%'>
32 * <thead>
33 * <tr>
34 * <td width='15%'>Method</td>
35 * <td width='1%'> </td>
36 * <td width='15%'>Usage</td>
37 * <td width='1%'> </td>
38 * <td>Description/Comments</td>
39 * </tr>
40 * </thead>
41 * <tr valign='top'>
42 * <td>getEndTime/setEndTime</td>
43 * <td> </td>
44 * <td>Runtime</td>
45 * <td> </td>
46 * <td>
47 * Provides a JBJF ...
48 * </td>
49 * </tr>
50 * </table>
51 * </p>
52 * <p>
53 * <h3>Example(s)</h3>
54 * <hr>
55 * <pre>
56 * </pre>
57 * </p>
58 * <p>
59 * @author Adym S. Lincoln<br>
60 * Copyright (C) 2006-2017. JBJF, All rights reserved.
61 * @version 1.0.0
62 * @since 1.0.0
63 * </p>
64 * <p>
65 * @see org.jbjf
66 * </p>
67 */
68
69public final class RootLogger {
70
71 /**
72 * Stores a fully qualified class name. Used for debugging and
73 * auditing.
74 * @since 1.0.0
75 */
76 public static final String ID = RootLogger.class.getName ();
77
78 /**
79 * Stores the class name, primarily used for debugging and so
80 * forth. Used for debugging and auditing.
81 * @since 1.0.0
82 */
83 @SuppressWarnings("unused")
84 private static String SHORT_NAME = "RootLogger()";
85
86 /**
87 * Stores a <code>SYSTEM IDENTITY HASHCODE</code>. Used for
88 * debugging and auditing.
89 * @since 1.0.0
90 */
91 @SuppressWarnings("unused")
92 private String SYSTEM_IDENTITY = String.valueOf ( System.identityHashCode ( this ) );
93
94 /**
95 * Class property that contains the log4j XML file. Defaults
96 * to DEFAULT_LOG4J_XML... ./etc/app-log4j.xml.
97 */
98 private static String log4jXML = null;
99
100 /**
101 * Class property that stores the log4j object/instance.
102 */
103 private static Logger log = null;
104
105 /**
106 * Class property that stores the singleton object/instance.
107 */
108 private static RootLogger instance = null;
109
110 /**
111 * Singleton constructor.
112 */
113 private RootLogger() {
114 }
115
116 /**
117 * <p>
118 * Global access point for the Log4j object/instance...
119 * Logger myLog = RootLogger.getInstance().getLog();
120 * </p>
121 * @return The <code>RootLogger</code> object/instance.
122 */
123 public static RootLogger getInstance() {
124 if( instance == null) {
125 instance = new RootLogger();
126 initInstance ();
127 }
128 return instance;
129 }
130
131 /**
132 * <p>
133 * Returns the current <code>Logger</code>.
134 * </p>
135 * @return Returns the current <code>Logger</code>.
136 */
137 public static Logger getLog() {
138 return log;
139 }
140
141 /**
142 * <p>
143 * Traditional getter that returns the Logger with the given
144 * name...if no Logger is found, then null is returned.
145 * </p>
146 * @param theLoggerName The name of the Logger.
147 * @return A <code>Logger</code> if it exists or null.
148 */
149 public static Logger getLog ( String theLoggerName ) {
150 Logger ltheResults = null;
151 if ( theLoggerName != null ) {
152 for (Enumeration loggers=LogManager.getCurrentLoggers(); loggers.hasMoreElements(); ) {
153 Logger logger = (Logger) loggers.nextElement();
154 if ( logger.getName ().equals ( theLoggerName ) ) {
155 ltheResults = logger;
156 }
157 getLog().debug ( SHORT_NAME + ".setLog () - FOUND Logger......[" + logger.getName () + "]" );
158
159 }
160
161 }
162 return ltheResults;
163 }
164
165 public static void setLog(Logger theLog) {
166 log = theLog;
167 }
168
169 /**
170 * <p>
171 * A traditional setter method that allows you to set a specific
172 * logger as the new logger object/instance. By default, the
173 * rootLogger is set when the instance is initialized.
174 * </p>
175 * @param theLoggerName The name of the logger you wish to
176 * promote as the new logger...if the name is NOT FOUND, then
177 * the existing logger is left untouched.
178 */
179 public static void setLog ( String theLoggerName ) {
180 if ( theLoggerName != null ) {
181 for (Enumeration<Logger> loggers=LogManager.getCurrentLoggers(); loggers.hasMoreElements(); ) {
182 Logger logger = loggers.nextElement();
183 if ( logger.getName ().equals ( theLoggerName ) ) {
184 getLog().debug ( SHORT_NAME + ".setLog () - NEW Logger......[" + logger.getName () + "]" );
185 log = logger;
186 getLog().debug ( SHORT_NAME + ".setLog () - NEW Logger......[" + logger.getName () + "]" );
187 }
188
189 }
190
191 }
192
193 }
194
195 /**
196 * <p>
197 * A secondary initialization that allows you to re-configure
198 * the log4j framework using a different XML file. The log4j
199 * object/instance is reset to the new rootLogger defined in
200 * the given XML file. Unlike the startup initialization, this
201 * initialization will only do the following search and resolve
202 * steps :
203 * </p>
204 * <ul>
205 * <li>Use the file path and filename.xml in getLog4jXML().</li>
206 * <li>Use getLog4jXML() as a resource on the CLASSPATH...
207 * ClassLoader.getResource ( getLog4jXML() );</li>
208 * <li>Use getLog4jXML() as a resource next to this class...
209 * this.class.getResource ( "/"+getLog4jXML() );</li>
210 * </ul>
211 * <p>
212 * If all of the configuration attempts fail, then the log4j
213 * object/instance is left untouched.
214 * </p>
215 */
216 public static void initInstance ( String theLog4jPath ) {
217 // INFINITE LOOP : Causes an infinite loop...
218 //setLog4jXML ( theLog4jPath );
219
220 File theLog4jFile = null;
221
222 try {
223 // FILE : First try and resolve and configure log4j
224 // using a direct file path/name.
225 //
226 if ( getLog4jXML() != null ) {
227 theLog4jFile = new File ( getLog4jXML() );
228 if ( theLog4jFile != null ) {
229 if ( theLog4jFile.exists () ) {
230 if ( theLog4jFile.canRead () ) {
231 System.out.println ( SHORT_NAME + ".setLog () Log4j XML Path [" + getLog4jXML() + "]" );
232 System.out.println ( SHORT_NAME + ".setLog () Log4j File Path [" + theLog4jFile.getAbsolutePath () + "]" );
233 DOMConfigurator.configureAndWatch ( getLog4jXML() );
234 log = Logger.getRootLogger ();
235
236 theLog4jFile = null;
237
238 }
239 else {
240 System.out.println ( SHORT_NAME + ".setLog () Log4j XML Path [" + getLog4jXML() + "] - CAN NOT BE READ!" );
241 }
242 }
243 else {
244 System.out.println ( SHORT_NAME + ".setLog () Log4j XML Path [" + getLog4jXML() + "] - DOES NOT EXIST!" );
245 }
246 }
247 }
248
249 // URL : Second, try and resolve and configure log4j
250 // using a URL on the CLASSPATH.
251 //
252 URL lclsLoaderResource = RootLogger.class.getClassLoader().getResource ( getLog4jXML() );
253 if ( ( lclsLoaderResource != null ) ) {
254 System.out.println ( SHORT_NAME + ".setLog () classLoaderResource URL [" + lclsLoaderResource.getFile () + "]" );
255 DOMConfigurator.configure ( lclsLoaderResource );
256 log = Logger.getRootLogger ();
257 }
258
259 // URL : Third, try and resolve and configure log4j
260 // using a URL on the class resource.
261 //
262 URL lclassResource = RootLogger.class.getResource ( "/"+getLog4jXML() );
263 if ( ( lclassResource != null ) ) {
264 System.out.println ( SHORT_NAME + ".setLog () classResource URL [" + lclassResource.getFile () + "]" );
265 DOMConfigurator.configure ( lclassResource );
266 log = Logger.getRootLogger ();
267 }
268
269 }
270 catch ( Exception lioXcp ) {
271 lioXcp.printStackTrace();
272 }
273
274 getLog ().debug ( SHORT_NAME + ".setLog() - COMPLETE! [" + getLog ().getName () + "]" );
275
276 }
277
278 /**
279 * <p>
280 * The primary method that will do an exhaustive search and resolve
281 * to identify and establish the log4j object/instance. If all
282 * search and resolves fails, then a default console and file
283 * appender are created and assigned.
284 * </p>
285 * <ul>
286 * <li>Use the file path and name.ext in getLog4jXML().</li>
287 * <li>Use getLog4jXML() as a resource on the CLASSPATH.</li>
288 * <li>Use getLog4jXML() as a resource next to this class.</li>
289 * <li>Use /log4j.xml as a resource next to this class.</li>
290 * <li>If all else, hard-code a console and single file appender (./jbjf-default.log) to teh rootLogger.</li>
291 * </ul>
292 */
293 public static void initInstance() {
294 File theLog4jFile = null;
295
296 if ( System.getProperty ( JBJFBaseGlobals.JVM_LOG4J_ARGUMENT ) != null ) {
297 setLog4jXML ( System.getProperty ( JBJFBaseGlobals.JVM_LOG4J_ARGUMENT ) );
298 System.out.println ( SHORT_NAME + ".initInstance () - JVM Argument......[" + JBJFBaseGlobals.JVM_LOG4J_ARGUMENT + "] Value [" + getLog4jXML () + "]" );
299 }
300
301 if ( getLog4jXML () == null ) {
302 setLog4jXML ( JBJFBaseGlobals.DEFAULT_LOG4J_XML );
303 System.out.println ( SHORT_NAME + ".initInstance () - Default Log4j.....[" + JBJFBaseGlobals.DEFAULT_LOG4J_XML + "] Value [" + getLog4jXML () + "]" );
304 }
305
306 try {
307
308 // FILE : First try and resolve and configure log4j
309 // using a direct file path/name.
310 //
311 if ( getLog4jXML() != null ) {
312 theLog4jFile = new File ( getLog4jXML() );
313 if ( theLog4jFile != null ) {
314 if ( theLog4jFile.exists () ) {
315 if ( theLog4jFile.canRead () ) {
316 System.out.println ( SHORT_NAME + ".initInstance () Log4j XML Path [" + getLog4jXML() + "]" );
317 System.out.println ( SHORT_NAME + ".initInstance () Log4j File Path [" + theLog4jFile.getAbsolutePath () + "]" );
318 DOMConfigurator.configureAndWatch ( getLog4jXML() );
319 log = Logger.getRootLogger ();
320
321 }
322 else {
323 System.out.println ( SHORT_NAME + ".initInstance () Log4j XML Path [" + getLog4jXML() + "] - CAN NOT BE READ!" );
324 }
325 }
326 else {
327 System.out.println ( SHORT_NAME + ".initInstance () Log4j XML Path [" + getLog4jXML() + "] - DOES NOT EXIST!" );
328 }
329 }
330 }
331
332 // URL : Second, try and resolve and configure log4j
333 // using a URL on the CLASSPATH.
334 //
335 URL lclsLoaderResource = RootLogger.class.getClassLoader().getResource ( getLog4jXML() );
336 if ( ( lclsLoaderResource != null ) && ( log == null ) ) {
337 System.out.println ( SHORT_NAME + ".initInstance () classLoaderResource URL [" + lclsLoaderResource.getFile () + "]" );
338 DOMConfigurator.configure ( lclsLoaderResource );
339 log = Logger.getRootLogger ();
340 }
341
342 // URL : Third, try and resolve and configure log4j
343 // using a URL on the class resource.
344 //
345 URL lclassResource = RootLogger.class.getResource ( "/"+getLog4jXML() );
346 if ( ( lclassResource != null ) && ( log == null ) ) {
347 System.out.println ( SHORT_NAME + ".initInstance () classResource URL [" + lclassResource.getFile () + "]" );
348 DOMConfigurator.configure ( lclassResource );
349 log = Logger.getRootLogger ();
350 }
351
352 // URL : Next, try and see if a default log4j XML file
353 // is on the CLASSPATH
354 //
355 URL ldefaultLog4j = RootLogger.class.getResource ( "/log4j.xml" );
356 if ( ( ldefaultLog4j != null ) && ( log == null ) ) {
357 System.out.println ( SHORT_NAME + ".initInstance () default log4j XML [" + lclassResource.getFile () + "]" );
358 DOMConfigurator.configure ( ldefaultLog4j );
359 log = Logger.getRootLogger ();
360 }
361
362 }
363 catch ( Exception lioXcp ) {
364 // TODO Auto-generated catch block
365 lioXcp.printStackTrace();
366 }
367
368 if ( log == null ) {
369 ConsoleAppender console = new ConsoleAppender(); //create appender
370 //configure the appender
371 String PATTERN = "%d [%p|%c|%C{1}] %m%n";
372 console.setLayout(new PatternLayout(PATTERN));
373 console.setThreshold(Level.DEBUG);
374 console.activateOptions();
375 //add appender to any Logger (here is root)
376 Logger.getRootLogger().addAppender(console);
377
378 FileAppender fa = new FileAppender();
379 fa.setName("DefaultLogger");
380 fa.setFile("jbjf-default.log");
381 fa.setLayout(new PatternLayout("%d %-5p [%c{1}] %m%n"));
382 fa.setThreshold(Level.DEBUG);
383 fa.setAppend(true);
384 fa.activateOptions();
385
386 //add appender to any Logger (here is root)
387 Logger.getRootLogger().addAppender(fa);
388 log = Logger.getRootLogger ();
389
390 }
391
392 getLog ().debug ( SHORT_NAME + ".setLog() - COMPLETE! [" + getLog ().getName () + "]" );
393
394 }
395
396 /**
397 * <p>
398 * Traditional getter method that returns the current log4j XML
399 * directory path and filename.ext.
400 * </p>
401 * @return The current log4j XML directory path and filename.ext
402 */
403 public static String getLog4jXML() {
404 return log4jXML;
405 }
406
407 /**
408 * <p>
409 * Traditional setter method that accepts a new log4j XML file.
410 * Call the initInstance ( getLog4jXML() ) to re-configure the
411 * log4j framework using the new file.
412 * </p>
413 * @param theLog4jXML A new log4j XML file.
414 */
415 public static void setLog4jXML(String theLog4jXML) {
416 log4jXML = theLog4jXML;
417 // INFINITE LOOP : Causes an infinite loop...
418 //initInstance ( theLog4jXML );
419 }
420
421}