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