001/** 002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 003 * 004 * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved 005 * 006 * The contents of this file are subject to the terms 007 * of the Common Development and Distribution License 008 * (the License). You may not use this file except in 009 * compliance with the License. 010 * 011 * You can obtain a copy of the License at 012 * https://opensso.dev.java.net/public/CDDLv1.0.html or 013 * opensso/legal/CDDLv1.0.txt 014 * See the License for the specific language governing 015 * permission and limitations under the License. 016 * 017 * When distributing Covered Code, include this CDDL 018 * Header Notice in each file and include the License file 019 * at opensso/legal/CDDLv1.0.txt. 020 * If applicable, add the following below the CDDL Header, 021 * with the fields enclosed by brackets [] replaced by 022 * your own identifying information: 023 * "Portions Copyrighted [year] [name of copyright owner]" 024 * 025 * $Id: LogManager.java,v 1.14 2009/12/09 00:34:22 bigfatrat Exp $ 026 * 027 * Portions Copyrighted 2011-2014 ForgeRock AS. 028 * Portions Copyrighted 2013 Cybernetica AS 029 */ 030package com.sun.identity.log; 031 032import java.io.IOException; 033import java.io.File; 034import java.lang.reflect.Constructor; 035import java.util.Hashtable; 036import java.util.Set; 037import java.util.logging.Level; 038import java.util.Enumeration; 039import java.util.StringTokenizer; 040import java.util.logging.Handler; 041import java.util.HashSet; 042import java.util.logging.Formatter; 043 044import com.iplanet.am.util.SystemProperties; 045import com.iplanet.sso.SSOToken; 046import com.sun.identity.log.messageid.LogMessageProviderBase; 047import com.sun.identity.log.messageid.MessageProviderFactory; 048import com.sun.identity.log.spi.Debug; 049import com.sun.identity.log.s1is.LogConfigReader; 050import com.sun.identity.monitoring.Agent; 051import com.sun.identity.monitoring.MonitoringUtil; 052import com.sun.identity.monitoring.SsoServerLoggingSvcImpl; 053 054/** 055 * This class keeps track of all the logger objects and does all the 056 * bookkeeping work. It is extended from JDK's <code>LogManager</code> to add 057 * functionalities, such as adding our logger listening to DS changes, etc. 058 * @supported.all.api 059 */ 060public class LogManager extends java.util.logging.LogManager { 061 062 /** 063 * Is the Log Service running locally or remotely 064 */ 065 public static boolean isLocal = false; 066 /** 067 * The handler which will be added to each logger object 068 */ 069 public static String HANDLER = "Handler"; 070 /** 071 * The formatter which depends on the log settings 072 */ 073 public static String FORMATTER = "Formatter"; 074 075 public static boolean isMonitoringInit = false; 076 077 /* 078 * A list to maintain strong references to all loggers that are added, 079 * workaround for the file handle issue in OPENAM-184. 080 */ 081 private static Hashtable loggersTable; 082 083 084 /** 085 * Indicator for whether the first readConfiguration has happened 086 */ 087 private static boolean didFirstReadConfig; 088 private static final String strDEFAULT = "DEFAULT"; 089 private static String oldLocation = strDEFAULT; 090 private static String oldLevel = strDEFAULT; 091 private static String oldSecurityStatus = strDEFAULT; 092 private static String oldBackend = strDEFAULT; 093 private static String oldStatus = strDEFAULT; 094 private static String newLocation; 095 private static String newLevel; 096 private static String newSecurityStatus; 097 private static String newBackend; 098 private static String newStatus; 099 private final int OLDLOCATION = 0; 100 private final int NEWLOCATION = 1; 101 private final int OLDBACKEND = 2; 102 private final int NEWBACKEND = 3; 103 private final int OLDSECURITYSTATUS = 4; 104 private final int NEWSECURITYSTATUS = 5; 105 private final int OLDSTATUS = 6; 106 private final int NEWSTATUS = 7; 107 private final int OLDLEVEL = 8; 108 private final int NEWLEVEL = 9; 109 private static SsoServerLoggingSvcImpl logServiceImplForMonitoring = null; 110 private static int loggerCount = 0; 111 private String inactive = "INACTIVE"; 112 113 /** 114 * Adds a logger to the Log Manager. 115 * 116 * @param logger Logger object to be added to the Log Manager. 117 * @return true if the logger is added. 118 */ 119 public boolean addLogger(java.util.logging.Logger logger) { 120 String name = logger.getName(); 121 /* we have to pass root logger and global logger */ 122 if (name != null && name.length() != 0 && !name.equals("global")) { 123 /* we have to take care of the resourcebundle logger may have */ 124 String rbName = logger.getResourceBundleName(); 125 logger = new Logger(name, rbName); 126 } 127 boolean addSuccess = super.addLogger(logger); 128 129 // OPENAM-1110, loggersTable may not get initialized immediately, since we extend. 130 if (loggersTable == null) { 131 loggersTable = new Hashtable(); 132 } 133 // Workaround for OPENAM-184, maintains strong reference to the loggers until this class is collected 134 // The Hashtable will never be used to retrieve loggers, only to keep then strongly referenced 135 loggersTable.put(name, logger); 136 137 if(addSuccess){ 138 Enumeration loggerNames = getLoggerNames(); 139 int lcnt = 0; 140 while (loggerNames.hasMoreElements()) { 141 String curEl = (String) loggerNames.nextElement(); 142 /* avoid root logger */ 143 if (curEl.length() != 0 && curEl.length() != 0 && 144 !curEl.equals("global")) 145 { 146 lcnt++; 147 } 148 } 149 loggerCount = lcnt; 150 if (SystemProperties.isServerMode() && MonitoringUtil.isRunning()) { 151 if (logServiceImplForMonitoring == null) { 152 logServiceImplForMonitoring = 153 Agent.getLoggingSvcMBean(); 154 } 155 if (logServiceImplForMonitoring != null) { 156 logServiceImplForMonitoring.setSsoServerLoggingLoggers( 157 new Integer(loggerCount)); 158 } 159 } 160 } 161 return addSuccess; 162 } 163 164 /* security status updated by readConfiguration */ 165 private boolean securityStatus = false; 166 167 /* all fields read during read configuration */ 168 private String[] allFields; 169 private Set selectedFieldSet; 170 protected Level loggingLevel = null; 171 172 /** 173 * Return whether secure logging is specified. 174 * 175 * @return <code>securityStatus</code> 176 */ 177 public final boolean isSecure() { 178 return securityStatus; 179 } 180 181 /** 182 * Return the array of all LogRecord fields available for selection. 183 * 184 * @return <code>allFields</code> 185 */ 186 public synchronized final String[] getAllFields() { 187 return allFields; 188 } 189 190 /** 191 * Return the LogRecord fields selected to be included. 192 * 193 * @return <code>selectedFieldSet</code> 194 */ 195 public synchronized final Set getSelectedFieldSet() { 196 return selectedFieldSet; 197 } 198 199 private synchronized final void readAllFields() { 200 String strAllFields = getProperty(LogConstants.ALL_FIELDS); 201 StringTokenizer strToken = new StringTokenizer(strAllFields, ", "); 202 int count = strToken.countTokens(); 203 String localAllFields[] = new String[count]; 204 count = 0; 205 while (strToken.hasMoreElements()) { 206 localAllFields[count++] = strToken.nextToken().trim(); 207 } 208 allFields = localAllFields; 209 } 210 211 private synchronized final void readSelectedFieldSet() { 212 HashSet fieldSet = new HashSet(); 213 214 String strSelectedFields = getProperty(LogConstants.LOG_FIELDS); 215 216 if ((strSelectedFields != null) && (strSelectedFields.length() != 0)) { 217 StringTokenizer stoken = 218 new StringTokenizer(strSelectedFields, ", "); 219 220 while (stoken.hasMoreElements()) { 221 fieldSet.add(stoken.nextToken()); 222 } 223 } 224 selectedFieldSet = fieldSet; 225 return; 226 } 227 228 /** 229 * This method overrides the <code>readConfiguration</code> method in 230 * JDK <code>LogManager</code> class. 231 * The base class method resets the loggers in memory. This method 232 * must add handlers to the loggers in memory according to the 233 * new configuration. 234 * 235 * @throws IOException if there are IO problems reading the configuration. 236 * @throws SecurityException if a security manager exists and if the caller 237 * does not have <code>LoggingPermission("control")</code>. 238 */ 239 public final void readConfiguration() 240 throws IOException, SecurityException { 241 String[] xlogData = null; 242 try { 243 /* 244 * This writeLock ensures that no logging threads will execute 245 * a logger.log call after this point since they request for 246 * a readLock. 247 */ 248 Logger.rwLock.writeRequest(); 249 250 /* 251 * This sync is for avoiding this thread snathing away 252 * time slice from a thread executing getLogger() method 253 * which is also sync on Logger.class 254 * which may lead to two handlers being added to the same logger. 255 */ 256 synchronized (Logger.class) { 257 Enumeration loggerNames = getLoggerNames(); 258 LogManagerUtil.setupEnv(); 259 260 if (didFirstReadConfig && SystemProperties.isServerMode()) { 261 oldLocation = getProperty(LogConstants.LOG_LOCATION); 262 oldLevel = getProperty(LogConstants.LOGGING_LEVEL); 263 oldSecurityStatus = 264 getProperty(LogConstants.SECURITY_STATUS); 265 oldBackend = getProperty(LogConstants.BACKEND); 266 oldStatus = getProperty(LogConstants.LOG_STATUS_ATTR); 267 } 268 269 try { 270 /* 271 * This change is done for deploying AM as a single 272 * war. In server mode we will always use our 273 * LogConfigReader. On the client side the 274 * the JVM property will define whether to use the 275 * LogConfigReader or the remote handlers. If no 276 * JVM property is set, the remote handlers will 277 * be used. 278 */ 279 if (SystemProperties.isServerMode()) { 280 LogConfigReader logConfigReader = 281 new LogConfigReader(); 282 } else { 283 super.readConfiguration(); 284 } 285 didFirstReadConfig = true; 286 } catch (Exception ex) { 287 /* no debug since our debugging system is not up. */ 288 } finally { 289 LogManagerUtil.resetEnv(); 290 } 291 292 if (isLocal) { 293 securityStatus = false; 294 readAllFields(); 295 readSelectedFieldSet(); 296 297 if (SystemProperties.isServerMode()) { 298 newLocation = getProperty(LogConstants.LOG_LOCATION); 299 newLevel = getProperty(LogConstants.LOGGING_LEVEL); 300 newSecurityStatus = 301 getProperty(LogConstants.SECURITY_STATUS); 302 newBackend = getProperty(LogConstants.BACKEND); 303 newStatus = getProperty(LogConstants.LOG_STATUS_ATTR); 304 } 305 306 /* 307 * give all the pertinent values to decide why 308 * logging to the file was terminated. still 309 * have to check that one of the attributes 310 * that changed would cause a "real" termination 311 * of logging to the files/tables in the current 312 * location (as opposed to just a buffer timer change, 313 * for instance). 314 */ 315 316 String[] logData = {oldLocation, newLocation, 317 oldBackend, newBackend, 318 oldSecurityStatus, newSecurityStatus, 319 oldStatus, newStatus, 320 oldLevel, newLevel}; 321 322 if (getProperty(LogConstants.BACKEND).equals("DB")) { 323 HANDLER = getProperty(LogConstants.DB_HANDLER); 324 FORMATTER = getProperty(LogConstants.DB_FORMATTER); 325 String driver = getProperty(LogConstants.DB_DRIVER); 326 } else if (getProperty(LogConstants.BACKEND).equals("Syslog")) { 327 HANDLER = getProperty(LogConstants.SYSLOG_HANDLER); 328 FORMATTER = getProperty(LogConstants.SYSLOG_FORMATTER); 329 } else if (getProperty( 330 LogConstants.SECURITY_STATUS).equalsIgnoreCase("ON")) 331 { 332 securityStatus = true; 333 HANDLER = getProperty(LogConstants.SECURE_FILE_HANDLER); 334 FORMATTER = 335 getProperty(LogConstants.SECURE_ELF_FORMATTER); 336 } else { 337 HANDLER = getProperty(LogConstants.FILE_HANDLER); 338 FORMATTER = getProperty(LogConstants.ELF_FORMATTER); 339 } 340 341 if (getProperty(LogConstants.BACKEND).equals("File")) { 342 /* 343 * create new log directory if it has changed and 344 * the new directory does not exist. 345 */ 346 347 if (SystemProperties.isServerMode() && 348 (newLocation != null) && 349 (oldLocation != null) && 350 !oldLocation.equals(newLocation)) { 351 File dir = new File(newLocation); 352 if (!dir.exists()) { 353 if (!dir.mkdirs()) { 354 Debug.error( 355 "LogManager:readConfiguration:" + 356 "Unable to create the new log " + 357 "directory. Verify that the " + 358 "process has necessary permissions"); 359 } 360 } 361 } 362 } 363 364 boolean loggingInactive = 365 (getProperty(LogConstants.LOG_STATUS_ATTR). 366 equals(inactive)); 367 368 String strLogLevel = 369 getProperty(LogConstants.LOGGING_LEVEL); 370 try { 371 loggingLevel = Level.parse(strLogLevel); 372 } catch (IllegalArgumentException iaex) { 373 loggingLevel = Level.INFO; // default 374 Debug.error("LogManager:readConfiguration:" + 375 "Log level '" + strLogLevel + 376 "' unknown; setting to Level.INFO."); 377 } 378 379 /* 380 * get the global logging level from the logging 381 * service config. however, if logging status is 382 * INACTIVE, the overriding level becomes OFF 383 */ 384 385 if (loggingInactive) { 386 loggingLevel = Level.OFF; 387 } 388 xlogData = logData; 389 } else { 390 HANDLER = getProperty(LogConstants.REMOTE_HANDLER); 391 if (HANDLER == null) { 392 HANDLER = LogConstants.DEFAULT_REMOTE_HANDER; 393 } 394 FORMATTER = getProperty(LogConstants.REMOTE_FORMATTER); 395 if (FORMATTER == null) { 396 FORMATTER = LogConstants.DEFAULT_REMOTE_FORMATTER; 397 } 398 } 399 400 Logger.resolveHostName = Boolean.valueOf( 401 getProperty(LogConstants.LOG_RESOLVE_HOSTNAME_ATTR)). 402 booleanValue(); 403 404 /* 405 * modify existing loggers in memory according 406 * to the new configuration 407 */ 408 loggerNames = getLoggerNames(); 409 410 while (loggerNames.hasMoreElements()) { 411 String curEl = (String) loggerNames.nextElement(); 412 /* avoid root logger */ 413 if (!curEl.isEmpty() && !curEl.equals("global")) { 414 if (Debug.messageEnabled()) { 415 Debug.message( 416 "LogManager:readConfiguration:" + 417 "Processing Logger: " + curEl); 418 } 419 420 /* 421 * remove all handlers and add new handlers for 422 * this logger 423 */ 424 Logger l = (Logger) Logger.getLogger(curEl); 425 Handler[] handlers = l.getHandlers(); 426 for (int i = 0; i < handlers.length; i++) { 427 handlers[i].close(); 428 l.removeHandler(handlers[i]); 429 } 430 431 String handlerClass = LogManager.HANDLER; 432 Class clz = null; 433 Class[] parameters = {String.class}; 434 Object[] parameterObjects = {l.getName()}; 435 Constructor cons = null; 436 Handler h = null; 437 try { 438 clz = Class.forName(handlerClass); 439 } catch (Exception e) { 440 Debug.error( 441 "LogManager.readConfiguration:could not load " + 442 handlerClass, e); 443 } 444 try { 445 cons = clz.getDeclaredConstructor(parameters); 446 } catch (Exception e) { 447 Debug.error( 448 "LogManager.readConfiguration:could not" + 449 " instantiate" + handlerClass, e); 450 } 451 try { 452 h = (Handler) cons.newInstance(parameterObjects); 453 } catch (Exception e) { 454 Debug.error( 455 "LogManager.readConfiguration:could not" + 456 " instantiate" + handlerClass, e); 457 } 458 String formatterClass = LogManager.FORMATTER; 459 Formatter f = null; 460 try { 461 f = (Formatter) Class.forName(formatterClass). 462 newInstance(); 463 } catch (Exception e) { 464 Debug.error( 465 "LogManager.readConfiguration:could not" + 466 " instantiate Formatter " + 467 formatterClass, e); 468 } 469 h.setFormatter(f); 470 l.addHandler(h); 471 472 /* 473 * get the "iplanet-am-logging.<logfilename>.level 474 * value for this file, if it's been added on the 475 * server's advanced config page. 476 * 477 * BUT: logging status set to Inactive means 478 * all logging is turned Level.OFF 479 */ 480 Level tlevel = loggingLevel; 481 if (loggingLevel != Level.OFF) { 482 String levelProp = 483 LogConstants.LOG_PROP_PREFIX + "." + 484 l.getName() + ".level"; 485 String lvlStr = SystemProperties.get(levelProp); 486 487 if ((lvlStr != null) && (lvlStr.length() > 0)) { 488 try { 489 tlevel = Level.parse(lvlStr); 490 } catch (IllegalArgumentException iaex) { 491 // use value for all others 492 } 493 } 494 } 495 if (loggingLevel != null) { // only if isLocal 496 // update logging level 497 l.setLevel(tlevel); 498 } 499 } /* end of avoid rootlogger */ 500 } /* end of while(loggerNames.hasMoreElements) */ 501 } /* end of synchronized(Logger.class) */ 502 } finally { 503 Logger.rwLock.writeDone(); 504 } 505 506 if (SystemProperties.isServerMode() && isLocal) { 507 checkStartLogs(xlogData); 508 //Update the new configuration info in Monitoring handle also 509 updateMonitConfigForLogService(); 510 } 511 } /* end of readConfiguration() */ 512 513 514 /** 515 * check the existing ("old") config and the new config for 516 * specific attribute changes that would mean logging has 517 * changed to a new location or has re-started. these are: 518 * 1. logging location 519 * 2. new Status == ACTIVE && old Level == OFF && 520 * new Level != OFF 521 * 3. old Status == INACTIVE && new Status == ACTIVE && 522 * new Level != OFF 523 * 4. old Backend != new Backend (File <-> DB) 524 * 5. old Security Status != new Security Status 525 * 526 * the String[] passed contains: 527 * [0] = old Location 528 * [1] = new Location 529 * [2] = old Backend 530 * [3] = new Backend 531 * [4] = old Security Status 532 * [5] = new Security Status 533 * [6] = old Status 534 * [7] = new Status 535 * [8] = old Level 536 * [9] = new Level 537 */ 538 private void checkStartLogs(String[] vals) { 539 Enumeration loggerNames = getLoggerNames(); 540 boolean loggingIsActive = false; 541 boolean levelIsOff = true; 542 543 // if the values array or any of its elements is null, just return 544 if (vals == null) { 545 return; 546 } 547 for (int i = 0; i <= NEWLEVEL; i++) { 548 if ((vals[i] == null) || (vals[i].length() == 0)) { 549 return; 550 } 551 } 552 553 if (vals[NEWSTATUS] != null) { 554 loggingIsActive = vals[NEWSTATUS].equals("ACTIVE"); 555 } 556 if (vals[NEWLEVEL] != null) { 557 levelIsOff = vals[NEWLEVEL].equals("OFF"); 558 } 559 560 /* 561 * if current status == ACTIVE and Level != OFF, 562 * and individual log's Level != OFF, 563 * then write a start record to the log. 564 * 565 * note that status == INACTIVE overrides any Level setting 566 * for the logging service, or an individual log file. 567 * 568 */ 569 if (loggingIsActive) { 570 // see if there's a reason to write the log record 571 if (!vals[OLDBACKEND].equals(vals[NEWBACKEND]) || 572 !vals[OLDLOCATION].equals(vals[NEWLOCATION]) || 573 !vals[OLDSECURITYSTATUS].equals(vals[NEWSECURITYSTATUS]) || 574 !vals[OLDSTATUS].equals(vals[NEWSTATUS]) || 575 !vals[OLDLEVEL].equals(vals[NEWLEVEL])) { 576 loggerNames = getLoggerNames(); 577 String saveLevel = vals[NEWLEVEL]; 578 Level level = Level.INFO; 579 try { 580 level = Level.parse(vals[NEWLEVEL]); 581 } catch (IllegalArgumentException iaex) { 582 // just leave it at "INFO" as a default 583 } 584 585 while (loggerNames.hasMoreElements()) { 586 vals[NEWLEVEL] = saveLevel; 587 String curEl = (String) loggerNames.nextElement(); 588 /* avoid root logger */ 589 if (curEl.length() != 0 && curEl.length() != 0 && 590 !curEl.equals("global")) { 591 Logger l = (Logger) Logger.getLogger(curEl); 592 593 /* 594 * additional reason to check if start record 595 * should be written: 596 * general Level is now "OFF", but this 597 * individual file's level != OFF 598 * then log to the individual file 599 * and 600 * general Level != OFF, but this 601 * individual file's level == oFF 602 * then don't log to the individual file 603 * the individual file's level is set 604 * in the readConfiguration stuff, above. 605 */ 606 607 // get this log's level 608 Level tlevel = l.getLevel(); 609 610 if (levelIsOff) { 611 if (tlevel != Level.OFF) { 612 vals[NEWLEVEL] = tlevel.toString(); 613 logIt(l, vals, 614 LogConstants.START_LOG_CONFIG_NAME); 615 } 616 } else { 617 logIt(l, vals, LogConstants.START_LOG_CONFIG_NAME); 618 } 619 } 620 } 621 } 622 } 623 } 624 625 private void logIt(Logger logger, String[] msg, String msgName) { 626 try { 627 LogMessageProviderBase provider = 628 (LogMessageProviderBase) MessageProviderFactory.getProvider( 629 "Logging"); 630 SSOToken ssot = LogManagerUtil.getLoggingSSOToken(); 631 com.sun.identity.log.LogRecord lr = 632 provider.createLogRecord(msgName, msg, ssot); 633 logger.log(lr, ssot); 634 logger.flush(); 635 } catch (IOException ioex) { 636 Debug.error("LogManager.logIt:could not log to " + 637 logger.getName() + ": " + ioex.getMessage()); 638 } 639 } 640 641 /** 642 * This method is called from two places, from readConfiguration() and from 643 * Logger.getLoggers(). 644 */ 645 public void updateMonitConfigForLogService() { 646 /* 647 * if haven't gotten the logging service monitoring handle 648 * yet, see if it's setup now 649 */ 650 if (SystemProperties.isServerMode() && MonitoringUtil.isRunning()) { 651 if (logServiceImplForMonitoring == null) { 652 logServiceImplForMonitoring = 653 Agent.getLoggingSvcMBean(); 654 } 655 if (logServiceImplForMonitoring == null) { 656 return; 657 } 658 659 logServiceImplForMonitoring.setSsoServerLoggingLoggers( 660 new Integer(loggerCount)); 661 logServiceImplForMonitoring.setSsoServerLoggingSecure( 662 newSecurityStatus); 663 logServiceImplForMonitoring.setSsoServerLoggingTimeBuffering( 664 getProperty(LogConstants.TIME_BUFFERING_STATUS)); 665 logServiceImplForMonitoring.setSsoServerLoggingBufferSize( 666 Long.valueOf(getProperty(LogConstants.BUFFER_SIZE)). 667 longValue()); 668 logServiceImplForMonitoring.setSsoServerLoggingBufferTime( 669 Long.valueOf(getProperty(LogConstants.BUFFER_TIME)). 670 longValue()); 671 logServiceImplForMonitoring.setSsoServerLoggingMaxLogSize( 672 Long.valueOf(getProperty( 673 LogConstants.MAX_FILE_SIZE)).longValue()); 674 logServiceImplForMonitoring. 675 setSsoServerLoggingNumberHistoryFiles(Long.valueOf( 676 getProperty(LogConstants.NUM_HISTORY_FILES)). 677 longValue()); 678 logServiceImplForMonitoring.setSsoServerLoggingLocation( 679 getProperty(LogConstants.LOG_LOCATION)); 680 logServiceImplForMonitoring.setSsoServerLoggingType( 681 getProperty(LogConstants.BACKEND)); 682 logServiceImplForMonitoring.setSsoServerLoggingRecsRejected( 683 (long)0); 684 685 isMonitoringInit = true; 686 } 687 } 688 689 public boolean getLoggingStatusIsActive() { 690 String oStatus = getProperty(LogConstants.LOG_STATUS_ATTR); 691 return (oStatus.equalsIgnoreCase("ACTIVE")); 692 } 693 694 protected String getBackend() { 695 return (newBackend); 696 } 697 698 protected boolean isDBLogging() { 699 return (newBackend.equals("DB")); 700 } 701 702 public boolean getDidFirstReadConfig() { 703 return didFirstReadConfig; 704 } 705 706 /* 707 * only meant to be called from s1is.LogConfigReader when 708 * logging status goes from ACTIVE to INACTIVE 709 */ 710 public synchronized void logStopLogs() { 711 String location = getProperty(LogConstants.LOG_LOCATION); 712 String level = getProperty(LogConstants.LOGGING_LEVEL); 713 String securityStatus = getProperty(LogConstants.SECURITY_STATUS); 714 String backend = getProperty(LogConstants.BACKEND); 715 String status = getProperty(LogConstants.LOG_STATUS_ATTR); 716 // only care about status going from ACTIVE to INACTIVE 717 String[] vals = {location, location, 718 backend, backend, 719 securityStatus, securityStatus, 720 status, inactive, 721 level, level}; 722 723 Enumeration loggerNames = getLoggerNames(); 724 while (loggerNames.hasMoreElements()) { 725 String curEl = (String) loggerNames.nextElement(); 726 /* avoid root logger */ 727 if (curEl.length() != 0 && curEl.length() != 0 && 728 !curEl.equals("global")) 729 { 730 Logger l = (Logger) Logger.getLogger(curEl); 731 732 /* 733 * additional reason to check if end record 734 * should be written: 735 * this individual file's level == oFF 736 * then don't log to the individual file 737 */ 738 739 // get this log's level 740 Level tlevel = l.getLevel(); 741 742 if (tlevel != Level.OFF) { 743 logIt(l, vals, LogConstants.END_LOG_CONFIG_NAME); 744 } 745 } 746 } 747 } 748} 749
Copyright © 2010-2017, ForgeRock All Rights Reserved.