Source Code Cross Referenced for Log4jService.java in  » EJB-Server-JBoss-4.2.1 » server » org » jboss » logging » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » EJB Server JBoss 4.2.1 » server » org.jboss.logging 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * JBoss, Home of Professional Open Source.
003:         * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004:         * as indicated by the @author tags. See the copyright.txt file in the
005:         * distribution for a full listing of individual contributors.
006:         *
007:         * This is free software; you can redistribute it and/or modify it
008:         * under the terms of the GNU Lesser General Public License as
009:         * published by the Free Software Foundation; either version 2.1 of
010:         * the License, or (at your option) any later version.
011:         *
012:         * This software is distributed in the hope that it will be useful,
013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015:         * Lesser General Public License for more details.
016:         *
017:         * You should have received a copy of the GNU Lesser General Public
018:         * License along with this software; if not, write to the Free
019:         * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020:         * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021:         */
022:        package org.jboss.logging;
023:
024:        import java.io.IOException;
025:        import java.io.PrintStream;
026:        import java.net.MalformedURLException;
027:        import java.net.URL;
028:        import java.net.URLConnection;
029:        import java.util.StringTokenizer;
030:        import java.util.Timer;
031:        import java.util.TimerTask;
032:
033:        import javax.management.MBeanServer;
034:        import javax.management.MalformedObjectNameException;
035:        import javax.management.Notification;
036:        import javax.management.ObjectName;
037:
038:        import org.apache.log4j.Level;
039:        import org.apache.log4j.PropertyConfigurator;
040:        import org.apache.log4j.helpers.LogLog;
041:        import org.apache.log4j.xml.DOMConfigurator;
042:        import org.jboss.logging.util.LoggerStream;
043:        import org.jboss.logging.util.OnlyOnceErrorHandler;
044:        import org.jboss.system.ServiceMBeanSupport;
045:        import org.jboss.util.Strings;
046:        import org.jboss.util.ThrowableHandler;
047:        import org.jboss.util.ThrowableListener;
048:        import org.jboss.util.stream.Streams;
049:
050:        /**
051:         * Initializes the Log4j logging framework.  Supports XML and standard
052:         * configuration file formats.  Defaults to using 'log4j.xml' read
053:         * from a system resource.
054:         *
055:         * <p>Sets up a {@link ThrowableListener} to adapt unhandled
056:         *    throwables to a logger.
057:         *
058:         * <p>Installs {@link LoggerStream} adapters for <tt>System.out</tt> and 
059:         *    <tt>System.err</tt> to catch and redirect calls to Log4j.
060:         *
061:         * @jmx:mbean name="jboss.system:type=Log4jService,service=Logging"
062:         *            extends="org.jboss.system.ServiceMBean"
063:         *
064:         * @version <tt>$Revision: 57209 $</tt>
065:         * @author <a href="mailto:phox@galactica.it">Fulco Muriglio</a>
066:         * @author <a href="mailto:Scott_Stark@displayscape.com">Scott Stark</a>
067:         * @author <a href="mailto:davidjencks@earthlink.net">David Jencks</a>
068:         * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
069:         */
070:        public class Log4jService extends ServiceMBeanSupport implements 
071:                Log4jServiceMBean {
072:            /**
073:             * The default url for the configuration file.  Reads the value
074:             * from the system property <tt>org.jboss.logging.Log4jService.configURL</tt>
075:             * or if that is not set defaults to <tt>resource:log4j.xml</tt>.
076:             */
077:            public static final String DEFAULT_URL = System.getProperty(
078:                    Log4jService.class.getName() + ".configURL",
079:                    "resource:log4j.xml");
080:
081:            /**
082:             * Default flag to enable/disable cacthing System.out.  Reads the value
083:             * from the system property <tt>org.jboss.logging.Log4jService.catchSystemOut</tt>
084:             * or if not set defaults to <tt>true</tt>.
085:             */
086:            public static final boolean CATCH_SYSTEM_OUT = getBoolean(
087:                    Log4jService.class.getName() + ".catchSystemOut", true);
088:
089:            /**
090:             * Default flag to enable/disable cacthing System.err.  Reads the value
091:             * from the system property <tt>org.jboss.logging.Log4jService.catchSystemErr</tt>
092:             * or if not set defaults to <tt>true</tt>.
093:             */
094:            public static final boolean CATCH_SYSTEM_ERR = getBoolean(
095:                    Log4jService.class.getName() + ".catchSystemErr", true);
096:
097:            /** Helper to get boolean value from system property or use default if not set. */
098:            private static boolean getBoolean(String name, boolean defaultValue) {
099:                String value = System.getProperty(name, null);
100:                if (value == null)
101:                    return defaultValue;
102:                return new Boolean(value).booleanValue();
103:            }
104:
105:            /** The URL to the configuration file. */
106:            private URL configURL;
107:
108:            /** The time in seconds between checking for new config. */
109:            private int refreshPeriod;
110:
111:            private ThrowableListenerLoggingAdapter throwableAdapter;
112:
113:            /** The previous value of System.out. */
114:            private PrintStream out;
115:
116:            /** The previous value of System.err. */
117:            private PrintStream err;
118:
119:            /**
120:             * Flag to enable/disable adapting <tt>System.out</tt> to the
121:             * <tt>STDOUT</tt> logger.
122:             */
123:            private boolean catchSystemOut = CATCH_SYSTEM_OUT;
124:
125:            /**
126:             * Flag to enable/disable adapting <tt>System.out</tt> to the
127:             * <tt>STDERR</tt> logger.
128:             */
129:            private boolean catchSystemErr = CATCH_SYSTEM_ERR;
130:
131:            /** The org.apache.log4j.helpers.LogLog.setQuietMode flag setting */
132:            private boolean log4jQuietMode = true;
133:
134:            /** The URL watch timer (in daemon mode). */
135:            private Timer timer = new Timer(true);
136:
137:            /** The specialized timer task to watch our config file. */
138:            private URLWatchTimerTask timerTask;
139:
140:            /**
141:             * A flag to enable start/stop to work as expected,
142:             * but still use create to init early.
143:             */
144:            private boolean initialized;
145:
146:            /**
147:             * Uses defaults.
148:             *
149:             * @jmx:managed-constructor
150:             *
151:             * @throws MalformedURLException    Could not create URL from default (propbably
152:             *                                  a problem with overridden properties).
153:             */
154:            public Log4jService() throws MalformedURLException {
155:                this (DEFAULT_URL, 60);
156:            }
157:
158:            /**
159:             * @jmx:managed-constructor
160:             * 
161:             * @param url    The configuration URL.
162:             */
163:            public Log4jService(final URL url) {
164:                this (url, 60);
165:            }
166:
167:            /**
168:             * @jmx:managed-constructor
169:             * 
170:             * @param url    The configuration URL.
171:             */
172:            public Log4jService(final String url) throws MalformedURLException {
173:                this (Strings.toURL(url), 60);
174:            }
175:
176:            /**
177:             * @jmx:managed-constructor
178:             * 
179:             * @param url              The configuration URL.
180:             * @param refreshPeriod    The refreshPeriod in seconds to wait between each check.
181:             */
182:            public Log4jService(final String url, final int refreshPeriod)
183:                    throws MalformedURLException {
184:                this (Strings.toURL(url), refreshPeriod);
185:            }
186:
187:            /**
188:             * @jmx:managed-constructor
189:             * 
190:             * @param url              The configuration URL.
191:             * @param refreshPeriod    The refreshPeriod in seconds to wait between each check.
192:             */
193:            public Log4jService(final URL url, final int refreshPeriod) {
194:                this .configURL = url;
195:                this .refreshPeriod = refreshPeriod;
196:            }
197:
198:            /**
199:             * Set the catch <tt>System.out</tt> flag.
200:             *
201:             * @jmx:managed-attribute
202:             *
203:             * @param flag    True to enable, false to disable.
204:             */
205:            public void setCatchSystemOut(final boolean flag) {
206:                this .catchSystemOut = flag;
207:            }
208:
209:            /**
210:             * Get the catch <tt>System.out</tt> flag.
211:             *
212:             * @jmx:managed-attribute
213:             *
214:             * @return  True if enabled, false if disabled.
215:             */
216:            public boolean getCatchSystemOut() {
217:                return catchSystemOut;
218:            }
219:
220:            /**
221:             * Set the catch <tt>System.err</tt> flag.
222:             *
223:             * @jmx:managed-attribute
224:             *
225:             * @param flag    True to enable, false to disable.
226:             */
227:            public void setCatchSystemErr(final boolean flag) {
228:                this .catchSystemErr = flag;
229:            }
230:
231:            /**
232:             * Get the catch <tt>System.err</tt> flag.
233:             *
234:             * @jmx:managed-attribute
235:             *
236:             * @return  True if enabled, false if disabled.
237:             */
238:            public boolean getCatchSystemErr() {
239:                return catchSystemErr;
240:            }
241:
242:            /**
243:             * Get the org.apache.log4j.helpers.LogLog.setQuietMode flag
244:             *
245:             * @jmx:managed-attribute
246:             *
247:             * @return  True if enabled, false if disabled.
248:             */
249:            public boolean getLog4jQuietMode() {
250:                return log4jQuietMode;
251:            }
252:
253:            /**
254:             * Set the org.apache.log4j.helpers.LogLog.setQuietMode flag
255:             *
256:             * @jmx:managed-attribute
257:             *
258:             * @return  True if enabled, false if disabled.
259:             */
260:            public void setLog4jQuietMode(boolean flag) {
261:                this .log4jQuietMode = flag;
262:            }
263:
264:            /**
265:             * Get the refresh period.
266:             *
267:             * @jmx:managed-attribute
268:             */
269:            public int getRefreshPeriod() {
270:                return refreshPeriod;
271:            }
272:
273:            /**
274:             * Set the refresh period.
275:             *
276:             * @jmx:managed-attribute
277:             */
278:            public void setRefreshPeriod(final int refreshPeriod) {
279:                this .refreshPeriod = refreshPeriod;
280:            }
281:
282:            /**
283:             * Get the Log4j configuration URL.
284:             *
285:             * @jmx:managed-attribute
286:             */
287:            public URL getConfigurationURL() {
288:                return configURL;
289:            }
290:
291:            /**
292:             * Set the Log4j configuration URL.
293:             *
294:             * @jmx:managed-attribute
295:             */
296:            public void setConfigurationURL(final URL url) {
297:                this .configURL = url;
298:            }
299:
300:            /**
301:             * Sets the level for a logger of the give name.
302:             *
303:             * <p>Values are trimmed before used.
304:             *
305:             * @jmx:managed-operation
306:             *
307:             * @param name        The name of the logger to change level
308:             * @param levelName   The name of the level to change the logger to.
309:             */
310:            public void setLoggerLevel(final String name, final String levelName) {
311:                org.apache.log4j.Logger logger = org.apache.log4j.Logger
312:                        .getLogger(name.trim());
313:                Level level = XLevel.toLevel(levelName.trim());
314:
315:                logger.setLevel(level);
316:                log.info("Level set to " + level + " for " + name);
317:            }
318:
319:            /**
320:             * Sets the levels of each logger specified by the given comma
321:             * seperated list of logger names.
322:             *
323:             * @jmx:managed-operation
324:             *
325:             * @see #setLoggerLevel
326:             *
327:             * @param list        A comma seperated list of logger names.
328:             * @param levelName   The name of the level to change the logger to.
329:             */
330:            public void setLoggerLevels(final String list,
331:                    final String levelName) {
332:                StringTokenizer stok = new StringTokenizer(list, ",");
333:
334:                while (stok.hasMoreTokens()) {
335:                    String name = stok.nextToken();
336:                    setLoggerLevel(name, levelName);
337:                }
338:            }
339:
340:            /**
341:             * Gets the level of the logger of the give name.
342:             *
343:             * @jmx:managed-operation
344:             *
345:             * @param name       The name of the logger to inspect.
346:             */
347:            public String getLoggerLevel(final String name) {
348:                org.apache.log4j.Logger logger = org.apache.log4j.Logger
349:                        .getLogger(name);
350:                Level level = logger.getLevel();
351:
352:                if (level != null)
353:                    return level.toString();
354:
355:                return null;
356:            }
357:
358:            /**
359:             * Force the logging system to reconfigure.
360:             *
361:             * @jmx:managed-operation
362:             */
363:            public void reconfigure() throws IOException {
364:                if (timerTask == null)
365:                    throw new IllegalStateException(
366:                            "Service stopped or not started");
367:
368:                timerTask.reconfigure();
369:            }
370:
371:            /**
372:             * Hack to reconfigure and change the URL.  This is needed until we
373:             * have a JMX HTML Adapter that can use PropertyEditor to coerce.
374:             *
375:             * @jmx:managed-operation
376:             *
377:             * @param url   The new configuration url
378:             */
379:            public void reconfigure(final String url) throws IOException,
380:                    MalformedURLException {
381:                setConfigurationURL(Strings.toURL(url));
382:                reconfigure();
383:            }
384:
385:            private void installSystemAdapters() {
386:                org.apache.log4j.Logger logger;
387:
388:                // Install catchers
389:                if (catchSystemOut) {
390:                    logger = org.apache.log4j.Logger.getLogger("STDOUT");
391:                    out = System.out;
392:                    System.setOut(new LoggerStream(logger, Level.INFO, out));
393:                    log.debug("Installed System.out adapter");
394:                }
395:
396:                if (catchSystemErr) {
397:                    logger = org.apache.log4j.Logger.getLogger("STDERR");
398:                    err = System.err;
399:                    OnlyOnceErrorHandler.setOutput(err);
400:                    System.setErr(new LoggerStream(logger, Level.ERROR, err));
401:                    log.debug("Installed System.err adapter");
402:                }
403:            }
404:
405:            private void uninstallSystemAdapters() {
406:                // Remove System adapters
407:                if (out != null) {
408:                    System.out.flush();
409:                    System.setOut(out);
410:                    log.debug("Removed System.out adapter");
411:                    out = null;
412:                }
413:
414:                if (err != null) {
415:                    System.err.flush();
416:                    System.setErr(err);
417:                    log.debug("Removed System.err adapter");
418:                    err = null;
419:                }
420:            }
421:
422:            ///////////////////////////////////////////////////////////////////////////
423:            //                       Concrete Service Overrides                      //
424:            ///////////////////////////////////////////////////////////////////////////
425:
426:            protected ObjectName getObjectName(MBeanServer server,
427:                    ObjectName name) throws MalformedObjectNameException {
428:                return name == null ? OBJECT_NAME : name;
429:            }
430:
431:            private void setup() throws Exception {
432:                if (initialized)
433:                    return;
434:
435:                timerTask = new URLWatchTimerTask();
436:                timerTask.run();
437:                timer.schedule(timerTask, 1000 * refreshPeriod,
438:                        1000 * refreshPeriod);
439:
440:                // Make sure the root Logger has loaded
441:                org.apache.log4j.Logger.getRootLogger();
442:
443:                // Install listener for unhandled throwables to turn them into log messages
444:                throwableAdapter = new ThrowableListenerLoggingAdapter();
445:                ThrowableHandler.addThrowableListener(throwableAdapter);
446:                log.debug("Added ThrowableListener: " + throwableAdapter);
447:
448:                initialized = true;
449:            }
450:
451:            protected void createService() throws Exception {
452:                setup();
453:            }
454:
455:            protected void startService() throws Exception {
456:                setup();
457:            }
458:
459:            protected void stopService() throws Exception {
460:                timerTask.cancel();
461:                timerTask = null;
462:
463:                // Remove throwable adapter
464:                ThrowableHandler.removeThrowableListener(throwableAdapter);
465:                throwableAdapter = null;
466:
467:                uninstallSystemAdapters();
468:
469:                // allow start to re-initalize
470:                initialized = false;
471:            }
472:
473:            protected void emitReconfigureNotification() {
474:                // emit a reconfigure notification with the configURL
475:                Notification n = new Notification(
476:                        RECONFIGURE_NOTIFICATION_TYPE, this ,
477:                        getNextNotificationSequenceNumber(),
478:                        "Log4j subsystem reconfigured");
479:                n.setUserData(configURL);
480:
481:                super .sendNotification(n);
482:            }
483:
484:            ///////////////////////////////////////////////////////////////////////////
485:            //                       ThrowableListener Adapter                      //
486:            ///////////////////////////////////////////////////////////////////////////
487:
488:            /**
489:             * Adapts ThrowableHandler to the Loggger interface.  Using nested 
490:             * class instead of anoynmous class for better logger naming.
491:             */
492:            private static class ThrowableListenerLoggingAdapter implements 
493:                    ThrowableListener {
494:                private Logger log = Logger
495:                        .getLogger(ThrowableListenerLoggingAdapter.class);
496:
497:                public void onThrowable(int type, Throwable t) {
498:                    switch (type) {
499:                    default:
500:                        // if type is not valid then make it any error
501:
502:                    case ThrowableHandler.Type.ERROR:
503:                        log.error("Unhandled Throwable", t);
504:                        break;
505:
506:                    case ThrowableHandler.Type.WARNING:
507:                        log.warn("Unhandled Throwable", t);
508:                        break;
509:
510:                    case ThrowableHandler.Type.UNKNOWN:
511:                        // these could be red-herrings, so log them as trace
512:                        log.trace("Ynhandled Throwable; status is unknown", t);
513:                        break;
514:                    }
515:                }
516:            }
517:
518:            ///////////////////////////////////////////////////////////////////////////
519:            //                         URL Watching Timer Task                       //
520:            ///////////////////////////////////////////////////////////////////////////
521:
522:            /**
523:             * A timer task to check when a URL changes (based on 
524:             * last modified time) and reconfigure Log4j.
525:             */
526:            private class URLWatchTimerTask extends TimerTask {
527:                private Logger log = Logger.getLogger(URLWatchTimerTask.class);
528:
529:                private long lastConfigured = -1;
530:
531:                public void run() {
532:                    log.trace("Checking if configuration changed");
533:
534:                    boolean trace = log.isTraceEnabled();
535:
536:                    try {
537:                        URLConnection conn = configURL.openConnection();
538:                        if (trace)
539:                            log.trace("connection: " + conn);
540:
541:                        long lastModified = conn.getLastModified();
542:                        if (trace) {
543:                            log.trace("last configured: " + lastConfigured);
544:                            log.trace("last modified: " + lastModified);
545:                        }
546:
547:                        if (lastConfigured < lastModified) {
548:                            reconfigure(conn);
549:                        }
550:                    } catch (Exception e) {
551:                        log.warn("Failed to check URL: " + configURL, e);
552:                    }
553:                }
554:
555:                public void reconfigure() throws IOException {
556:                    URLConnection conn = configURL.openConnection();
557:                    reconfigure(conn);
558:                }
559:
560:                private void reconfigure(final URLConnection conn) {
561:                    log.info("Configuring from URL: " + configURL);
562:
563:                    boolean xml = false;
564:                    boolean trace = log.isTraceEnabled();
565:
566:                    // check if the url is xml
567:                    String contentType = conn.getContentType();
568:                    if (trace)
569:                        log.trace("content type: " + contentType);
570:
571:                    if (contentType == null) {
572:                        String filename = configURL.getFile().toLowerCase();
573:                        if (trace)
574:                            log.trace("filename: " + filename);
575:
576:                        xml = filename.endsWith(".xml");
577:                    } else {
578:                        xml = contentType.equalsIgnoreCase("text/xml");
579:                        xml |= contentType.equalsIgnoreCase("application/xml");
580:                    }
581:                    if (trace)
582:                        log.trace("reconfiguring; xml=" + xml);
583:
584:                    // Dump our config if trace is enabled
585:                    if (trace) {
586:                        try {
587:                            java.io.InputStream is = conn.getInputStream();
588:                            Streams.copy(is, System.out);
589:                        } catch (Exception e) {
590:                            log.error("Failed to dump config", e);
591:                        }
592:                    }
593:
594:                    // need to uninstall adapters to avoid problems
595:                    uninstallSystemAdapters();
596:
597:                    if (xml) {
598:                        DOMConfigurator.configure(configURL);
599:                    } else {
600:                        PropertyConfigurator.configure(configURL);
601:                    }
602:
603:                    /* Set the LogLog.QuietMode. As of log4j1.2.8 this needs to be set to
604:                    avoid deadlock on exception at the appender level. See bug#696819.
605:                     */
606:                    LogLog.setQuietMode(log4jQuietMode);
607:
608:                    // but make sure they get reinstalled again
609:                    installSystemAdapters();
610:
611:                    // and then remember when we were last changed
612:                    lastConfigured = System.currentTimeMillis();
613:
614:                    // notify other mbeans that might be interested
615:                    emitReconfigureNotification();
616:                }
617:            }
618:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.