1 16 17 18 22 package org.apache.log4j; 23 24 import org.apache.log4j.DefaultCategoryFactory; 25 import org.apache.log4j.config.PropertySetter; 26 import org.apache.log4j.spi.OptionHandler; 28 import org.apache.log4j.spi.Configurator; 29 import org.apache.log4j.spi.LoggerFactory; 30 import org.apache.log4j.spi.LoggerRepository; 31 import org.apache.log4j.spi.RendererSupport; 32 import org.apache.log4j.or.RendererMap; 33 import org.apache.log4j.helpers.LogLog; 34 import org.apache.log4j.helpers.OptionConverter; 35 import org.apache.log4j.helpers.FileWatchdog; 36 37 import java.util.Enumeration ; 38 import java.util.Properties ; 39 import java.io.FileInputStream ; 40 import java.io.IOException ; 41 import java.util.StringTokenizer ; 42 import java.util.Hashtable ; 43 44 85 public class PropertyConfigurator implements Configurator { 86 87 90 protected Hashtable registry = new Hashtable (11); 91 protected LoggerFactory loggerFactory = new DefaultCategoryFactory(); 92 93 static final String CATEGORY_PREFIX = "log4j.category."; 94 static final String LOGGER_PREFIX = "log4j.logger."; 95 static final String FACTORY_PREFIX = "log4j.factory"; 96 static final String ADDITIVITY_PREFIX = "log4j.additivity."; 97 static final String ROOT_CATEGORY_PREFIX = "log4j.rootCategory"; 98 static final String ROOT_LOGGER_PREFIX = "log4j.rootLogger"; 99 static final String APPENDER_PREFIX = "log4j.appender."; 100 static final String RENDERER_PREFIX = "log4j.renderer."; 101 static final String THRESHOLD_PREFIX = "log4j.threshold"; 102 103 105 public static final String LOGGER_FACTORY_KEY = "log4j.loggerFactory"; 106 107 static final private String INTERNAL_ROOT_NAME = "root"; 108 109 302 public 303 void doConfigure(String configFileName, LoggerRepository hierarchy) { 304 Properties props = new Properties (); 305 try { 306 FileInputStream istream = new FileInputStream (configFileName); 307 props.load(istream); 308 istream.close(); 309 } 310 catch (IOException e) { 311 LogLog.error("Could not read configuration file ["+configFileName+"].", e); 312 LogLog.error("Ignoring configuration file [" + configFileName+"]."); 313 return; 314 } 315 doConfigure(props, hierarchy); 317 } 318 319 321 static 322 public 323 void configure(String configFilename) { 324 new PropertyConfigurator().doConfigure(configFilename, 325 LogManager.getLoggerRepository()); 326 } 327 328 333 public 334 static 335 void configure(java.net.URL configURL) { 336 new PropertyConfigurator().doConfigure(configURL, 337 LogManager.getLoggerRepository()); 338 } 339 340 341 346 static 347 public 348 void configure(Properties properties) { 349 new PropertyConfigurator().doConfigure(properties, 350 LogManager.getLoggerRepository()); 351 } 352 353 361 static 362 public 363 void configureAndWatch(String configFilename) { 364 configureAndWatch(configFilename, FileWatchdog.DEFAULT_DELAY); 365 } 366 367 368 379 static 380 public 381 void configureAndWatch(String configFilename, long delay) { 382 PropertyWatchdog pdog = new PropertyWatchdog(configFilename); 383 pdog.setDelay(delay); 384 pdog.start(); 385 } 386 387 388 393 public 394 void doConfigure(Properties properties, LoggerRepository hierarchy) { 395 396 String value = properties.getProperty(LogLog.DEBUG_KEY); 397 if(value == null) { 398 value = properties.getProperty(LogLog.CONFIG_DEBUG_KEY); 399 if(value != null) 400 LogLog.warn("[log4j.configDebug] is deprecated. Use [log4j.debug] instead."); 401 } 402 403 if(value != null) { 404 LogLog.setInternalDebugging(OptionConverter.toBoolean(value, true)); 405 } 406 407 String thresholdStr = OptionConverter.findAndSubst(THRESHOLD_PREFIX, 408 properties); 409 if(thresholdStr != null) { 410 hierarchy.setThreshold(OptionConverter.toLevel(thresholdStr, 411 (Level) Level.ALL)); 412 LogLog.debug("Hierarchy threshold set to ["+hierarchy.getThreshold()+"]."); 413 } 414 415 configureRootCategory(properties, hierarchy); 416 configureLoggerFactory(properties); 417 parseCatsAndRenderers(properties, hierarchy); 418 419 LogLog.debug("Finished configuring."); 420 registry.clear(); 423 } 424 425 428 public 429 void doConfigure(java.net.URL configURL, LoggerRepository hierarchy) { 430 Properties props = new Properties (); 431 LogLog.debug("Reading configuration from URL " + configURL); 432 try { 433 props.load(configURL.openStream()); 434 } 435 catch (java.io.IOException e) { 436 LogLog.error("Could not read configuration file from URL [" + configURL 437 + "].", e); 438 LogLog.error("Ignoring configuration file [" + configURL +"]."); 439 return; 440 } 441 doConfigure(props, hierarchy); 442 } 443 444 445 449 459 protected void configureLoggerFactory(Properties props) { 460 String factoryClassName = OptionConverter.findAndSubst(LOGGER_FACTORY_KEY, 461 props); 462 if(factoryClassName != null) { 463 LogLog.debug("Setting category factory to ["+factoryClassName+"]."); 464 loggerFactory = (LoggerFactory) 465 OptionConverter.instantiateByClassName(factoryClassName, 466 LoggerFactory.class, 467 loggerFactory); 468 PropertySetter.setProperties(loggerFactory, props, FACTORY_PREFIX + "."); 469 } 470 } 471 472 493 494 495 void configureRootCategory(Properties props, LoggerRepository hierarchy) { 496 String effectiveFrefix = ROOT_LOGGER_PREFIX; 497 String value = OptionConverter.findAndSubst(ROOT_LOGGER_PREFIX, props); 498 499 if(value == null) { 500 value = OptionConverter.findAndSubst(ROOT_CATEGORY_PREFIX, props); 501 effectiveFrefix = ROOT_CATEGORY_PREFIX; 502 } 503 504 if(value == null) 505 LogLog.debug("Could not find root logger information. Is this OK?"); 506 else { 507 Logger root = hierarchy.getRootLogger(); 508 synchronized(root) { 509 parseCategory(props, root, effectiveFrefix, INTERNAL_ROOT_NAME, value); 510 } 511 } 512 } 513 514 515 518 protected 519 void parseCatsAndRenderers(Properties props, LoggerRepository hierarchy) { 520 Enumeration enumeration = props.propertyNames(); 521 while(enumeration.hasMoreElements()) { 522 String key = (String ) enumeration.nextElement(); 523 if(key.startsWith(CATEGORY_PREFIX) || key.startsWith(LOGGER_PREFIX)) { 524 String loggerName = null; 525 if(key.startsWith(CATEGORY_PREFIX)) { 526 loggerName = key.substring(CATEGORY_PREFIX.length()); 527 } else if(key.startsWith(LOGGER_PREFIX)) { 528 loggerName = key.substring(LOGGER_PREFIX.length()); 529 } 530 String value = OptionConverter.findAndSubst(key, props); 531 Logger logger = hierarchy.getLogger(loggerName, loggerFactory); 532 synchronized(logger) { 533 parseCategory(props, logger, key, loggerName, value); 534 parseAdditivityForLogger(props, logger, loggerName); 535 } 536 } else if(key.startsWith(RENDERER_PREFIX)) { 537 String renderedClass = key.substring(RENDERER_PREFIX.length()); 538 String renderingClass = OptionConverter.findAndSubst(key, props); 539 if(hierarchy instanceof RendererSupport) { 540 RendererMap.addRenderer((RendererSupport) hierarchy, renderedClass, 541 renderingClass); 542 } 543 } 544 } 545 } 546 547 550 void parseAdditivityForLogger(Properties props, Logger cat, 551 String loggerName) { 552 String value = OptionConverter.findAndSubst(ADDITIVITY_PREFIX + loggerName, 553 props); 554 LogLog.debug("Handling "+ADDITIVITY_PREFIX + loggerName+"=["+value+"]"); 555 if((value != null) && (!value.equals(""))) { 557 boolean additivity = OptionConverter.toBoolean(value, true); 558 LogLog.debug("Setting additivity for \""+loggerName+"\" to "+ 559 additivity); 560 cat.setAdditivity(additivity); 561 } 562 } 563 564 567 void parseCategory(Properties props, Logger logger, String optionKey, 568 String loggerName, String value) { 569 570 LogLog.debug("Parsing for [" +loggerName +"] with value=[" + value+"]."); 571 StringTokenizer st = new StringTokenizer (value, ","); 573 574 577 if(!(value.startsWith(",") || value.equals(""))) { 578 579 if(!st.hasMoreTokens()) 581 return; 582 583 String levelStr = st.nextToken(); 584 LogLog.debug("Level token is [" + levelStr + "]."); 585 586 if(INHERITED.equalsIgnoreCase(levelStr) || 590 NULL.equalsIgnoreCase(levelStr)) { 591 if(loggerName.equals(INTERNAL_ROOT_NAME)) { 592 LogLog.warn("The root logger cannot be set to null."); 593 } else { 594 logger.setLevel(null); 595 } 596 } else { 597 logger.setLevel(OptionConverter.toLevel(levelStr, (Level) Level.DEBUG)); 598 } 599 LogLog.debug("Category " + loggerName + " set to " + logger.getLevel()); 600 } 601 602 logger.removeAllAppenders(); 604 605 Appender appender; 606 String appenderName; 607 while(st.hasMoreTokens()) { 608 appenderName = st.nextToken().trim(); 609 if(appenderName == null || appenderName.equals(",")) 610 continue; 611 LogLog.debug("Parsing appender named \"" + appenderName +"\"."); 612 appender = parseAppender(props, appenderName); 613 if(appender != null) { 614 logger.addAppender(appender); 615 } 616 } 617 } 618 619 Appender parseAppender(Properties props, String appenderName) { 620 Appender appender = registryGet(appenderName); 621 if((appender != null)) { 622 LogLog.debug("Appender \"" + appenderName + "\" was already parsed."); 623 return appender; 624 } 625 String prefix = APPENDER_PREFIX + appenderName; 627 String layoutPrefix = prefix + ".layout"; 628 629 appender = (Appender) OptionConverter.instantiateByKey(props, prefix, 630 org.apache.log4j.Appender.class, 631 null); 632 if(appender == null) { 633 LogLog.error( 634 "Could not instantiate appender named \"" + appenderName+"\"."); 635 return null; 636 } 637 appender.setName(appenderName); 638 639 if(appender instanceof OptionHandler) { 640 if(appender.requiresLayout()) { 641 Layout layout = (Layout) OptionConverter.instantiateByKey(props, 642 layoutPrefix, 643 Layout.class, 644 null); 645 if(layout != null) { 646 appender.setLayout(layout); 647 LogLog.debug("Parsing layout options for \"" + appenderName +"\"."); 648 PropertySetter.setProperties(layout, props, layoutPrefix + "."); 650 LogLog.debug("End of parsing for \"" + appenderName +"\"."); 651 } 652 } 653 PropertySetter.setProperties(appender, props, prefix + "."); 655 LogLog.debug("Parsed \"" + appenderName +"\" options."); 656 } 657 registryPut(appender); 658 return appender; 659 } 660 661 662 void registryPut(Appender appender) { 663 registry.put(appender.getName(), appender); 664 } 665 666 Appender registryGet(String name) { 667 return (Appender) registry.get(name); 668 } 669 } 670 671 class PropertyWatchdog extends FileWatchdog { 672 673 PropertyWatchdog(String filename) { 674 super(filename); 675 } 676 677 680 public 681 void doOnChange() { 682 new PropertyConfigurator().doConfigure(filename, 683 LogManager.getLoggerRepository()); 684 } 685 } 686 | Popular Tags |