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}




























































Copyright © 2010-2017, ForgeRock All Rights Reserved.