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: Logger.java,v 1.15 2009/12/09 00:34:21 bigfatrat Exp $ 026 * 027 */ 028 029/* 030 * Portions Copyrighted 2011 ForgeRock AS 031 */ 032package com.sun.identity.log; 033 034import java.io.File; 035import java.io.IOException; 036import java.lang.reflect.Constructor; 037import java.util.Enumeration; 038import java.util.MissingResourceException; 039import java.util.ResourceBundle; 040import java.util.logging.Filter; 041import java.util.logging.Formatter; 042import java.util.logging.Handler; 043import java.util.logging.Level; 044import java.util.logging.LogRecord; 045 046import com.iplanet.am.util.SystemProperties; 047import com.iplanet.sso.SSOException; 048import com.iplanet.sso.SSOToken; 049import com.sun.identity.common.ReaderWriterLock; 050import com.sun.identity.log.messageid.LogMessageProviderBase; 051import com.sun.identity.log.messageid.MessageProviderFactory; 052import com.sun.identity.log.spi.Authorizer; 053import com.sun.identity.log.spi.Debug; 054import com.sun.identity.monitoring.Agent; 055import com.sun.identity.monitoring.MonitoringUtil; 056import com.sun.identity.monitoring.SsoServerLoggingSvcImpl; 057import com.sun.identity.monitoring.SsoServerLoggingHdlrEntryImpl; 058import com.sun.identity.shared.Constants; 059import java.text.SimpleDateFormat; 060import java.util.Date; 061import java.util.Set; 062import javax.security.auth.Subject; 063 064/** 065 * OpenSSO extension to the jdk1.4 Logger 066 * This extension gives some functionality required by 067 * OpenSSO secure logger. 068 * For <code>JDK1.4</code> Logger please refer to 069 * <pre> 070 * http://java.sun.com/j2se/1.4.1/docs/api/java/util/logging/Logger.html 071 * </pre> 072 * @supported.all.api 073 */ 074public class Logger extends java.util.logging.Logger { 075 076 public static ThreadLocal token = new ThreadLocal(); 077 private String currentFileName = new String(); 078 private static LogManager lm; 079 private String logName; 080 protected static boolean resolveHostName; 081 082 /** 083 * Lock to prevent parallel writing and reading at the same time. 084 */ 085 public static ReaderWriterLock rwLock = new ReaderWriterLock(); 086 087 static { 088 lm = (com.sun.identity.log.LogManager) LogManagerUtil.getLogManager(); 089 try { 090 lm.readConfiguration(); 091 } catch (Exception ex) { 092 ex.printStackTrace(); 093 /* our Debug system will no be up now, so can't Debug */ 094 } 095 String location = lm.getProperty(LogConstants.LOG_LOCATION); 096 String type = lm.getProperty(LogConstants.BACKEND); 097 if ((location != null) && type.equals("File")) { 098 File dir = new File(location); 099 if (!dir.exists()) { 100 if (!dir.mkdirs()) { 101 Debug.error("Logger:Creation of Log Directory failed: " + 102 location); 103 } 104 } 105 } 106 107 /* Check if hostnames have to be resolved */ 108 resolveHostName = Boolean.valueOf( 109 lm.getProperty(LogConstants.LOG_RESOLVE_HOSTNAME_ATTR)). 110 booleanValue(); 111 } 112 113 /** 114 * Protected method to construct a logger for a named subsystem. 115 * <p> 116 * The logger will be initially configured with a null Level 117 * and with useParentHandlers true. 118 * 119 * @param name A name for the logger. This should be a 120 * dot-separated name and should normally be based on the 121 * package name or class name of the subsystem, such as java.net 122 * or javax.swing. It may be null for anonymous Loggers. 123 * @param resourceBundleName Name of the ResourceBundle to be used for 124 * localizing messages for this logger. May be null if none 125 * of the messages require localization. 126 * @throws MissingResourceException if the ResourceBundleName is 127 * non-null and no corresponding resource can be found. 128 */ 129 protected Logger(String name,String resourceBundleName) { 130 super(name,resourceBundleName); 131 } 132 133 /** 134 * To add handlers and formatters to the new logger object 135 */ 136 private static void processNewLoggerObject (Logger result) { 137 Formatter formatter = null; 138 String handlerClass = LogManager.HANDLER; 139 String formatterClass = LogManager.FORMATTER; 140 String levelProp = LogConstants.LOG_PROP_PREFIX + "." + 141 result.logName + ".level"; 142 143 /* 144 * see if logging level for this file already defined. 145 * if not, then check AMConfig.properties. 146 * if not, then use Logging service config value. 147 * if not, then use default ("INFO") 148 */ 149 String levelString = lm.getProperty(levelProp); 150 151 if ((levelString == null) || !(levelString.length() > 0)) { 152 levelString = SystemProperties.get (levelProp); 153 if ((levelString == null) || !(levelString.length() > 0)) { 154 levelString = lm.getProperty(LogConstants.LOGGING_LEVEL); 155 if ((levelString == null) || !(levelString.length() > 0)) { 156 levelString = LogConstants.DEFAULT_LOGGING_LEVEL_STR; 157 } 158 } 159 } 160 Level logLevel = null; 161 try { 162 logLevel = Level.parse(levelString); 163 } catch (IllegalArgumentException iaex) { 164 logLevel = LogConstants.DEFAULT_LOGGING_LEVEL; 165 } 166 167 result.setLevel(logLevel); 168 169 // but disabled logging in AMConfig.properties takes precedence 170 String logStatus = lm.getProperty(LogConstants.LOG_STATUS_ATTR); 171 if (logStatus != null && logStatus.startsWith("INACTIVE")) { 172 logLevel = Level.OFF; 173 } 174 result.setLevel(logLevel); 175 176 Class clz = null; 177 Class [] parameters = {String.class}; 178 Object [] parameterObjects = {result.logName}; 179 Constructor cons = null; 180 Handler handler = null; 181 182 if (handlerClass == null) { 183 Debug.error("Logger:processNewLoggerObject:" + 184 "HandlerClass not in classpath "); 185 return; 186 } 187 try { 188 clz = Class.forName(handlerClass); 189 } catch (Exception e) { 190 Debug.error("Logger:processNewLoggerObject:" + 191 "HandlerClass not in classpath: " + handlerClass, e); 192 return; 193 } 194 try { 195 if(clz != null) { 196 cons = clz.getDeclaredConstructor(parameters); 197 } 198 } catch (Exception e) { 199 Debug.error("Logger:processNewLoggerObject:" + 200 "constructor parameter mismatch ", e); 201 return; 202 } 203 try { 204 if(cons != null) { 205 handler = (Handler) cons.newInstance(parameterObjects); 206 } 207 } catch (Exception e) { 208 Debug.error("Logger:processNewLoggerObject:" + 209 "Could not instantiate handler: " + handlerClass, e); 210 return; 211 } 212 if (formatterClass == null) { 213 Debug.error("Logger:processNewLoggerObject:" + 214 "formatterClass not in classpath "); 215 return; 216 } 217 try { 218 clz = Thread.currentThread().getContextClassLoader(). 219 loadClass(formatterClass); 220 } catch (Exception e) { 221 Debug.error("Logger:processNewLoggerObject:" + 222 "Could not load Formatter Class: " + formatterClass, e); 223 return; 224 } 225 try { 226 if(clz != null) { 227 formatter = (Formatter) clz.newInstance(); 228 } 229 } catch (Exception e) { 230 Debug.error("Logger:processNewLoggerObject:" + 231 "Could not get Formatter instance " + formatterClass, e); 232 return; 233 } 234 try { 235 handler.setFormatter(formatter); 236 result.addHandler(handler); 237 } catch (Exception e) { 238 Debug.error("Logger:processNewLoggerObject:" + 239 "Unable to add Handler", e); 240 return; 241 } 242 String filterClassName = lm.getProperty(LogConstants.FILTER_CLASS_NAME); 243 try { 244 if (filterClassName != null) { 245 Filter filter = 246 (Filter)Class.forName(filterClassName).newInstance(); 247 result.setFilter(filter); 248 } 249 } catch (Exception e) { 250 Debug.error("Logger:processNewLoggerObject:" + 251 "Could not set Filter: "+ filterClassName, e); 252 } 253 254 result.setUseParentHandlers(false); 255 256 resolveHostName = Boolean.valueOf( 257 lm.getProperty(LogConstants.LOG_RESOLVE_HOSTNAME_ATTR)). 258 booleanValue(); 259 } 260 261 /** 262 * Directs every log call to <code>log(LogRecord, Object)</code> 263 * And thus the default authorization check does not allow logging 264 * when an application uses this interface. 265 * 266 * @param record The <code>LogRecord</code> to be logged. 267 */ 268 public void log(LogRecord record) { 269 if (record instanceof ILogRecord) { 270 log((ILogRecord)record); 271 } else { 272 Object obj = token.get(); 273 log(record, obj); 274 } 275 } 276 277 private boolean validateLogBy(Object cred) { 278 if (!LogManager.isLocal) { 279 if (cred == null) { 280 /* In case of remote sso token must be provide. */ 281 Debug.error("Logger.validateLogBy:" + logName + 282 ": remote logging, ssoToken is null; Will not log"); 283 return false; 284 } 285 } else { 286 /* Authorizer need not be called in the case of remote. */ 287 if (!Authorizer.isAuthorized(logName, "MODIFY", cred)) { 288 incMonReject(); // increment log svc and handler stats 289 Debug.error("Logger.validateLogBy:" + logName + 290 ": authorization failed; Will not log"); 291 throw new AMLogException(logName + ":" + 292 AMLogException.LOG_WRT_AUTH_FAILED); 293 } 294 } 295 return true; 296 } 297 298 private void addLogByInfo(ILogRecord record, Object cred) { 299 if (cred instanceof SSOToken) { 300 SSOToken ssoToken = (SSOToken) cred; 301 String loggedBySID = ssoToken.getTokenID().toString(); 302 record.addLogInfo(LogConstants.LOGGED_BY_SID, loggedBySID); 303 String clientID = null; 304 try { 305 clientID = ssoToken.getPrincipal().getName(); 306 } catch (SSOException ssoe) { 307 Debug.error("Logger:log:" + logName + 308 ": could not get clientID from ssoToken:", ssoe); 309 } 310 record.addLogInfo(LogConstants.LOGGED_BY, clientID); 311 } 312 } 313 314 private void addModuleName(ILogRecord record) { 315 String existModuleName = 316 (String)record.getLogInfoMap().get(LogConstants.MODULE_NAME); 317 if (existModuleName == null || existModuleName.length() <= 0) { 318 /* add module name only if it's already not added. */ 319 record.addLogInfo(LogConstants.MODULE_NAME, this.getName()); 320 } 321 322 } 323 324 /** 325 * Log entitlement log record. 326 * 327 * @param record Log record. 328 */ 329 public void log(ILogRecord record) { 330 try { 331 extractInfoFromLogFor(record); 332 } catch (SSOException e) { 333 Debug.error("Logger.log " + e.getMessage()); 334 } 335 336 if (record instanceof java.util.logging.LogRecord) { 337 Object logBy = record.getLogBy(); 338 Object cred = (logBy instanceof Subject) ? 339 getPrivateCred((Subject)logBy) : logBy; 340 log((java.util.logging.LogRecord)record, cred); 341 } else { 342 Debug.error( 343 "Logger.log: cannot log non java.util.logging.LogRecord class"); 344 } 345 } 346 347 private static Object getPrivateCred(Subject sbj) { 348 Set privCreds = sbj.getPrivateCredentials(); 349 return ((privCreds != null) && !privCreds.isEmpty()) ? 350 privCreds.iterator().next() : null; 351 } 352 353 /** 354 * Calls super.log after checking authorization. 355 * Data is not logged at all if this check fails. 356 * 357 * @param record The <code>LogRecord</code> to be logged. 358 * @param cred To prove authorization for log WRITE. 359 * The default authorization hook checks validity of the single 360 * sign on token which should be passed as the <code>cred</code>. 361 */ 362 public void log(LogRecord record, Object cred) { 363 validateLogBy(cred); 364 if (record instanceof com.sun.identity.log.ILogRecord) { 365 com.sun.identity.log.ILogRecord openssoLogRecord = 366 (com.sun.identity.log.ILogRecord)record; 367 addLogByInfo(openssoLogRecord, cred); 368 addModuleName(openssoLogRecord); 369 } 370 371 /* 372 * These are normally done by the LogManager private method 373 * doLog(). But since this record is not passing through that 374 * method we have to explicitly do this. 375 * ResourceBundle logic has been simplified. 376 */ 377 record.setLoggerName(getName()); 378 String rbName = this.getResourceBundleName(); 379 if (rbName != null) { 380 ResourceBundle bundle = ResourceBundle.getBundle(rbName); 381 record.setResourceBundle(bundle); 382 } 383 writeToLog(record); 384 } 385 386 private void writeToLog(LogRecord record) { 387 try { 388 rwLock.readRequest(); 389 /* 390 * this is to serialize logging,signing and verifying 391 * threads so that no signing or verification takes 392 * place once a logging thread has gone past this point 393 */ 394 if (lm.isSecure()) { 395 synchronized (this) { 396 super.log(record); 397 } 398 } else { 399 super.log(record); 400 } 401 } catch (Exception ex) { 402 Debug.error("Logger.writeToLog:" + logName + ":" + ex.getMessage()); 403 throw new AMLogException(logName + ":" + ex.getMessage()); 404 } finally { 405 rwLock.readDone(); 406 } 407 } 408 409 /** Writes all the buffered log records. 410 */ 411 public void flush() { 412 /* 413 * Post the LogRecord to all our Handlers, and then to 414 * our parents' handlers, all the way up the tree. 415 */ 416 Logger logger = this; 417 Handler targets[] = logger.getHandlers(); 418 if (targets != null) { 419 for (int i = 0; i < targets.length; i++) { 420 targets[i].flush(); 421 } 422 } 423 } 424 425 /** 426 * Find or create a logger for a named subsystem. If a logger has 427 * already been created with the given name it is returned. Otherwise 428 * a new logger is created. 429 * <p> 430 * If a new logger is created its log level will be configured 431 * based on the <code>LogManager</code> and it will be configured NOT to 432 * send logging output to its parent loggers Handlers. It will be 433 * registered in the <code>LogManager</code> global namespace. 434 * 435 * @param name A name for the logger. This should be a dot-separated name 436 * and should be the file name you want to have for your logs, 437 * such as <code>amSSO.access</code>, or audit. 438 * @return a suitable <code>Logger</code>. 439 */ 440 public static synchronized java.util.logging.Logger getLogger(String name) 441 { 442 if ((name == null) || (name.length() == 0) || name.indexOf("..") >= 0) 443 { 444 /* Do not allow logging if logName has "..". */ 445 return null; 446 } 447 Logger result; 448 449 boolean loggerExists = false; 450 Enumeration e = lm.getLoggerNames(); 451 while (e.hasMoreElements()) { 452 if (((String) e.nextElement()).equals(name)) { 453 loggerExists = true; 454 } 455 } 456 457 if (loggerExists) { 458 result = (Logger) lm.getLogger(name); 459 if (result != null) { 460 return result; 461 } 462 } 463 java.util.logging.Logger newLog = (java.util.logging.Logger) 464 java.util.logging.Logger.getLogger(name); 465 lm.addLogger(newLog); 466 result = (Logger) lm.getLogger(name); 467 468 result.logName = name; 469 processNewLoggerObject(result); 470 if (SystemProperties.isServerMode()) { 471 logStartRecord(result); 472 } 473 474 /* Logging service starts earlier than Monitoring. 475 * Because of this the first call to LogManager's readConfiguration() 476 * does not update the monitoring handle with the config information for 477 * logging. Hence we need to call updateMonitConfigForLogService() here 478 * to make sure the monitoring handle does get updated with the config 479 * information eventually. 480 */ 481 if(!lm.isMonitoringInit){ 482 lm.updateMonitConfigForLogService(); 483 } 484 return result; 485 } 486 487 /** Find or create a logger for a named subsystem. If a logger has 488 * already been created with the given name it is returned. Otherwise 489 * a new logger is created. 490 * <p> 491 * If a new logger is created, its log level will be configured 492 * based on the <code>LogManager</code> and it will configured to also 493 * send logging output to its parent logger's Handlers. It will be 494 * registered in the <code>LogManager</code> global namespace. 495 * <p> 496 * If the named Logger already exists and does not yet have a 497 * localization resource bundle then the given resource bundle 498 * name is used. If the named Logger already exists and has 499 * a different resource bundle name then an 500 * <code>IllegalArgumentException</code> is thrown. 501 * 502 * @param name A name for the logger. This should be a dot-separated name 503 * and should be the file name you want to have for your logs, such 504 * as <code>amSSO.access</code> or audit. 505 * @param rbName A resource bundle to be used for localizing the log 506 * messages. 507 * @return logger for a named subsystem. 508 */ 509 public static synchronized java.util.logging.Logger getLogger( 510 String name, String rbName) 511 { 512 if ((name == null) || (name.length() == 0) || name.indexOf("..") >= 0) { 513 /* Do not allow logging if logName has "..". */ 514 return null; 515 } 516 boolean loggerExists = false; 517 Enumeration e = lm.getLoggerNames(); 518 while (e.hasMoreElements()) { 519 if (((String) e.nextElement()).equals(name)) { 520 // The LoggerName is in the list, but we should check whether the 521 // referenced Logger still exists, see OPENAM-14 522 if (lm.getLogger(name) != null) { 523 loggerExists = true; 524 } 525 } 526 } 527 Logger result = (Logger) 528 java.util.logging.Logger.getLogger(name, rbName); 529 result.logName = name; 530 if (loggerExists) { 531 return result; 532 } 533 /* 534 * if the logger is a new object, we have to set the appropriate 535 * handlers and formatters to the logger before returning the result. 536 */ 537 538 processNewLoggerObject(result); 539 if (SystemProperties.isServerMode()) { 540 logStartRecord(result); 541 } 542 return result; 543 } 544 545 /** 546 * Log a LogRecord indicating the start of logging to this file 547 */ 548 private static void logStartRecord (Logger logger) { 549 /* 550 * SSOToken not required to instantiate a log file, so 551 * need one to say who's doing the logging of the record, 552 * and whose it "about". 553 */ 554 try { 555 LogMessageProviderBase provider = 556 (LogMessageProviderBase)MessageProviderFactory.getProvider( 557 "Logging"); 558 SSOToken ssot = LogManagerUtil.getLoggingSSOToken(); 559 String location = lm.getProperty(LogConstants.LOG_LOCATION); 560 String[] s = {location}; 561 com.sun.identity.log.LogRecord lr = 562 provider.createLogRecord(LogConstants.START_LOG_NEW_LOGGER_NAME, 563 s, ssot); 564 logger.log(lr, ssot); 565 } catch (IOException ioex) { 566 Debug.error("Logger.logStartRecord:could not log to " + 567 logger.getName() + ":" + ioex.getMessage()); 568 } 569 } 570 571 /** 572 * Returns the current file to which the logger's handler is writing. 573 * This is useful only in case of file.. 574 * 575 * @return the current file to which the logger's handler is writing. 576 */ 577 public String getCurrentFile() { 578 return currentFileName; 579 } 580 581 /** 582 * Set the current file to which the logger's handler is writing. 583 * 584 * @param fileName name of file. 585 */ 586 public void setCurrentFile(String fileName) { 587 currentFileName = fileName; 588 } 589 590 /** 591 * Return whether resolve host name is enabled 592 * 593 * @return <code>resolveHostName</code> 594 */ 595 public static boolean resolveHostNameEnabled() { 596 return resolveHostName; 597 } 598 599 static void extractInfoFromLogFor(ILogRecord rec) 600 throws SSOException { 601 Object logFor = rec.getLogFor(); 602 Object cred = (logFor instanceof Subject) ? 603 getPrivateCred((Subject)logFor) : logFor; 604 605 if (!(cred instanceof SSOToken)) { 606 return; 607 } 608 SSOToken ssoToken = (SSOToken)cred; 609 rec.addLogInfo(LogConstants.LOGIN_ID_SID, 610 ssoToken.getTokenID().toString()); 611 612 String ctxID = ssoToken.getProperty(Constants.AM_CTX_ID); 613 if ((ctxID != null) && (ctxID.length() > 0)) { 614 rec.addLogInfo(LogConstants.CONTEXT_ID, ctxID); 615 } 616 617 resolveHostName(rec, ssoToken); 618 String clientDomain = ssoToken.getProperty("Organization"); 619 if (clientDomain == null || clientDomain.length() == 0) { 620 clientDomain = ssoToken.getProperty("cdomain"); 621 } 622 rec.addLogInfo(LogConstants.DOMAIN, clientDomain); 623 rec.addLogInfo(LogConstants.LOGIN_ID, 624 ssoToken.getPrincipal().getName()); 625 626 Date date = new Date(); 627 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 628 629 /* 630 * these are the compulsory fields ... to be logged even if there are 631 * exceptions while getting domain, loginid, ipaddr, hostname 632 */ 633 rec.addLogInfo(LogConstants.TIME, sdf.format(date)); 634 635 if (rec instanceof java.util.logging.LogRecord) { 636 java.util.logging.LogRecord jLogRecord = 637 (java.util.logging.LogRecord)rec; 638 rec.addLogInfo(LogConstants.DATA, jLogRecord.getMessage()); 639 rec.addLogInfo(LogConstants.LOG_LEVEL, 640 jLogRecord.getLevel().toString()); 641 } 642 643 } 644 645 static void resolveHostName(ILogRecord rec, SSOToken ssoToken) 646 throws SSOException { 647 /* 648 * using the SSOToken, get the hostname first, as 649 * getting the IPAddr appears to use an Inet call using 650 * the hostname... 651 * 652 * if com.sun.identity.log.resolveHostName=false, then 653 * IPAddr field will end up "Not Available" 654 */ 655 String hostName = ssoToken.getHostName(); 656 String ipAddress = null; 657 658 if (Logger.resolveHostName) { 659 java.net.InetAddress ipAddr = ssoToken.getIPAddress(); 660 if (ipAddr != null) { 661 /* 662 * getting a leading "/" from InetAddress.getByName(host) 663 * in SSOTokenImpl.java when "host" is an IPaddress. 664 */ 665 ipAddress = ipAddr.getHostAddress(); 666 667 /* 668 * if no hostname returned, or only IP address, 669 * try getting hostname from InetAddr 670 */ 671 if ((hostName == null) || 672 ((ipAddress != null) && (ipAddress.equals(hostName)))) { 673 hostName = ipAddr.getHostName(); 674 } 675 } 676 } 677 rec.addLogInfo(LogConstants.HOST_NAME, hostName); 678 rec.addLogInfo(LogConstants.IP_ADDR, ipAddress); 679 } 680 681 /* 682 * increment the logging service LoggingRecsRejected attribute and 683 * the logging handler's (File, DB, and Secure only) LoggingHdlrFailureCt. 684 * this is for the count of rejections due to unauthorized userid trying 685 * to write to the log. 686 */ 687 private void incMonReject() { 688 if (LogManager.isLocal && MonitoringUtil.isRunning()) { 689 // logging service stat 690 SsoServerLoggingSvcImpl logSvcMon = 691 Agent.getLoggingSvcMBean(); 692 if (logSvcMon != null) { 693 logSvcMon.incSsoServerLoggingRecsRejected(); 694 } 695 696 // handler's stat 697 // if DB then database, else if secure then secure file, else file 698 SsoServerLoggingHdlrEntryImpl logH = null; 699 if (lm.isDBLogging()) { 700 logH = logSvcMon.getHandler( 701 SsoServerLoggingSvcImpl.DB_HANDLER_NAME); 702 } else if (lm.isSecure()) { 703 logH = logSvcMon.getHandler( 704 SsoServerLoggingSvcImpl.SECURE_FILE_HANDLER_NAME); 705 } else { 706 logH = logSvcMon.getHandler( 707 SsoServerLoggingSvcImpl.FILE_HANDLER_NAME); 708 } 709 if (logH != null) { 710 logH.incHandlerFailureCount(1); 711 /* 712 * also increment handler's request count. if it gets 713 * through the authorization check, it gets incremented 714 * in the handler itself. 715 */ 716 logH.incHandlerRequestCount(1); 717 } 718 } 719 } 720}