0001: /*
0002: * File : $Source: /usr/local/cvs/opencms/src/org/opencms/monitor/CmsMemoryMonitor.java,v $
0003: * Date : $Date: 2008-02-27 12:05:49 $
0004: * Version: $Revision: 1.64 $
0005: *
0006: * This library is part of OpenCms -
0007: * the Open Source Content Management System
0008: *
0009: * Copyright (c) 2002 - 2008 Alkacon Software GmbH (http://www.alkacon.com)
0010: *
0011: * This library is free software; you can redistribute it and/or
0012: * modify it under the terms of the GNU Lesser General Public
0013: * License as published by the Free Software Foundation; either
0014: * version 2.1 of the License, or (at your option) any later version.
0015: *
0016: * This library is distributed in the hope that it will be useful,
0017: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0018: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0019: * Lesser General Public License for more details.
0020: *
0021: * For further information about Alkacon Software GmbH, please see the
0022: * company website: http://www.alkacon.com
0023: *
0024: * For further information about OpenCms, please see the
0025: * project website: http://www.opencms.org
0026: *
0027: * You should have received a copy of the GNU Lesser General Public
0028: * License along with this library; if not, write to the Free Software
0029: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0030: */
0031:
0032: package org.opencms.monitor;
0033:
0034: import org.opencms.cache.CmsLruCache;
0035: import org.opencms.cache.CmsMemoryObjectCache;
0036: import org.opencms.cache.CmsVfsMemoryObjectCache;
0037: import org.opencms.configuration.CmsSystemConfiguration;
0038: import org.opencms.db.CmsCacheSettings;
0039: import org.opencms.db.CmsDriverManager;
0040: import org.opencms.db.CmsSecurityManager;
0041: import org.opencms.file.CmsFile;
0042: import org.opencms.file.CmsGroup;
0043: import org.opencms.file.CmsObject;
0044: import org.opencms.file.CmsProject;
0045: import org.opencms.file.CmsProperty;
0046: import org.opencms.file.CmsPropertyDefinition;
0047: import org.opencms.file.CmsResource;
0048: import org.opencms.file.CmsUser;
0049: import org.opencms.flex.CmsFlexCache.CmsFlexCacheVariation;
0050: import org.opencms.i18n.CmsLocaleManager;
0051: import org.opencms.lock.CmsLock;
0052: import org.opencms.lock.CmsLockManager;
0053: import org.opencms.mail.CmsMailTransport;
0054: import org.opencms.mail.CmsSimpleMail;
0055: import org.opencms.main.CmsEvent;
0056: import org.opencms.main.CmsLog;
0057: import org.opencms.main.CmsSessionManager;
0058: import org.opencms.main.I_CmsEventListener;
0059: import org.opencms.main.OpenCms;
0060: import org.opencms.publish.CmsPublishHistory;
0061: import org.opencms.publish.CmsPublishJobInfoBean;
0062: import org.opencms.publish.CmsPublishQueue;
0063: import org.opencms.scheduler.I_CmsScheduledJob;
0064: import org.opencms.security.CmsAccessControlList;
0065: import org.opencms.security.CmsOrganizationalUnit;
0066: import org.opencms.security.CmsPermissionSet;
0067: import org.opencms.security.I_CmsPermissionHandler;
0068: import org.opencms.util.CmsDateUtil;
0069: import org.opencms.util.CmsStringUtil;
0070: import org.opencms.util.CmsUUID;
0071: import org.opencms.util.PrintfFormat;
0072: import org.opencms.xml.CmsXmlContentDefinition;
0073: import org.opencms.xml.CmsXmlEntityResolver;
0074:
0075: import java.util.ArrayList;
0076: import java.util.Arrays;
0077: import java.util.Collections;
0078: import java.util.ConcurrentModificationException;
0079: import java.util.Date;
0080: import java.util.HashMap;
0081: import java.util.Iterator;
0082: import java.util.List;
0083: import java.util.Locale;
0084: import java.util.Map;
0085:
0086: import javax.mail.internet.InternetAddress;
0087:
0088: import org.apache.commons.collections.Buffer;
0089: import org.apache.commons.collections.buffer.SynchronizedBuffer;
0090: import org.apache.commons.collections.map.LRUMap;
0091: import org.apache.commons.logging.Log;
0092:
0093: /**
0094: * Monitors OpenCms memory consumption.<p>
0095: *
0096: * The memory monitor also provides all kind of caches used in the OpenCms core.<p>
0097: *
0098: * @author Carsten Weinholz
0099: * @author Michael Emmerich
0100: * @author Alexander Kandzior
0101: * @author Michael Moossen
0102: *
0103: * @version $Revision: 1.64 $
0104: *
0105: * @since 6.0.0
0106: */
0107: public class CmsMemoryMonitor implements I_CmsScheduledJob {
0108:
0109: /** Set interval for clearing the caches to 10 minutes. */
0110: private static final int INTERVAL_CLEAR = 1000 * 60 * 10;
0111:
0112: /** The log object for this class. */
0113: private static final Log LOG = CmsLog
0114: .getLog(CmsMemoryMonitor.class);
0115:
0116: /** Flag indicating if monitor is currently running. */
0117: private static boolean m_currentlyRunning;
0118:
0119: /** Maximum depth for object size recursion. */
0120: private static final int MAX_DEPTH = 5;
0121:
0122: /** Cache for access control lists. */
0123: private Map m_accessControlListCache;
0124:
0125: /** The memory monitor configuration. */
0126: private CmsMemoryMonitorConfiguration m_configuration;
0127:
0128: /** A temporary cache for XML content definitions. */
0129: private Map m_contentDefinitionsCache;
0130:
0131: /** Cache for groups. */
0132: private Map m_groupCache;
0133:
0134: /** Interval in which emails are send. */
0135: private int m_intervalEmail;
0136:
0137: /** Interval in which the log is written. */
0138: private int m_intervalLog;
0139:
0140: /** Interval between 2 warnings. */
0141: private int m_intervalWarning;
0142:
0143: /** The time the caches were last cleared. */
0144: private long m_lastClearCache;
0145:
0146: /** The time the last status email was send. */
0147: private long m_lastEmailStatus;
0148:
0149: /** The time the last warning email was send. */
0150: private long m_lastEmailWarning;
0151:
0152: /** The time the last status log was written. */
0153: private long m_lastLogStatus;
0154:
0155: /** The time the last warning log was written. */
0156: private long m_lastLogWarning;
0157:
0158: /** A cache for accelerated locale lookup. */
0159: private Map m_localeCache;
0160:
0161: /** Cache for the resource locks. */
0162: private Map m_lockCache;
0163:
0164: /** The number of times the log entry was written. */
0165: private int m_logCount;
0166:
0167: /** Memory percentage to reach to go to warning level. */
0168: private int m_maxUsagePercent;
0169:
0170: /** The memory object cache map. */
0171: private Map m_memObjectCache;
0172:
0173: /** The average memory status. */
0174: private CmsMemoryStatus m_memoryAverage;
0175:
0176: /** The current memory status. */
0177: private CmsMemoryStatus m_memoryCurrent;
0178:
0179: /** Contains the object to be monitored. */
0180: private Map m_monitoredObjects;
0181:
0182: /** Cache for organizational units. */
0183: private Map m_orgUnitCache;
0184:
0185: /** Cache for permission checks. */
0186: private Map m_permissionCache;
0187:
0188: /** Cache for offline projects. */
0189: private Map m_projectCache;
0190:
0191: /** Cache for project resources. */
0192: private Map m_projectResourcesCache;
0193:
0194: /** Cache for properties. */
0195: private Map m_propertyCache;
0196:
0197: /** Cache for property lists. */
0198: private Map m_propertyListCache;
0199:
0200: /** Buffer for publish history. */
0201: private Buffer m_publishHistory;
0202:
0203: /** Buffer for publish jobs. */
0204: private Buffer m_publishQueue;
0205:
0206: /** Cache for resources. */
0207: private Map m_resourceCache;
0208:
0209: /** Cache for resource lists. */
0210: private Map m_resourceListCache;
0211:
0212: /** Cache for role lists. */
0213: private Map m_roleListsCache;
0214:
0215: /** Cache for roles. */
0216: private Map m_rolesCache;
0217:
0218: /** Cache for user data. */
0219: private Map m_userCache;
0220:
0221: /** Cache for user groups. */
0222: private Map m_userGroupsCache;
0223:
0224: /** The vfs memory cache map. */
0225: private Map m_vfsObjectCache;
0226:
0227: /** Flag for memory warning mail send. */
0228: private boolean m_warningLoggedSinceLastStatus;
0229:
0230: /** Flag for memory warning mail send. */
0231: private boolean m_warningSendSinceLastStatus;
0232:
0233: /** A permanent cache to avoid multiple readings of often used files from the VFS. */
0234: private Map m_xmlPermanentEntityCache;
0235:
0236: /** A temporary cache to avoid multiple readings of often used files from the VFS. */
0237: private Map m_xmlTemporaryEntityCache;
0238:
0239: /**
0240: * Empty constructor, required by OpenCms scheduler.<p>
0241: */
0242: public CmsMemoryMonitor() {
0243:
0244: m_monitoredObjects = new HashMap();
0245: }
0246:
0247: /**
0248: * Returns the size of objects that are instances of
0249: * <code>byte[]</code>, <code>String</code>, <code>CmsFile</code>,<code>I_CmsLruCacheObject</code>.<p>
0250: * For other objects, a size of 0 is returned.
0251: *
0252: * @param obj the object
0253: * @return the size of the object
0254: */
0255: public static int getMemorySize(Object obj) {
0256:
0257: if (obj instanceof I_CmsMemoryMonitorable) {
0258: return ((I_CmsMemoryMonitorable) obj).getMemorySize();
0259: }
0260:
0261: if (obj instanceof byte[]) {
0262: // will always be a total of 16 + 8
0263: return 8 + (int) (Math.ceil(((byte[]) obj).length / 16.0) * 16.0);
0264: }
0265:
0266: if (obj instanceof String) {
0267: // will always be a total of 16 + 24
0268: return 24 + (int) (Math.ceil(((String) obj).length() / 8.0) * 16.0);
0269: }
0270:
0271: if (obj instanceof CmsFile) {
0272: CmsFile f = (CmsFile) obj;
0273: if (f.getContents() != null) {
0274: return f.getContents().length + 1024;
0275: } else {
0276: return 1024;
0277: }
0278: }
0279:
0280: if (obj instanceof CmsUUID) {
0281: return 184; // worst case if UUID String has been generated
0282: }
0283:
0284: if (obj instanceof CmsPermissionSet) {
0285: return 16; // two ints
0286: }
0287:
0288: if (obj instanceof CmsResource) {
0289: return 1024; // estimated size
0290: }
0291:
0292: if (obj instanceof CmsUser) {
0293: return 2048; // estimated size
0294: }
0295:
0296: if (obj instanceof CmsGroup) {
0297: return 512; // estimated size
0298: }
0299:
0300: if (obj instanceof CmsProject) {
0301: return 512; // estimated size
0302: }
0303:
0304: if (obj instanceof Boolean) {
0305: return 8; // one boolean
0306: }
0307:
0308: if (obj instanceof CmsProperty) {
0309: int size = 8;
0310:
0311: CmsProperty property = (CmsProperty) obj;
0312: size += getMemorySize(property.getName());
0313:
0314: if (property.getResourceValue() != null) {
0315: size += getMemorySize(property.getResourceValue());
0316: }
0317:
0318: if (property.getStructureValue() != null) {
0319: size += getMemorySize(property.getStructureValue());
0320: }
0321:
0322: return size;
0323: }
0324:
0325: if (obj instanceof CmsPropertyDefinition) {
0326: int size = 8;
0327:
0328: CmsPropertyDefinition propDef = (CmsPropertyDefinition) obj;
0329: size += getMemorySize(propDef.getName());
0330: size += getMemorySize(propDef.getId());
0331:
0332: return size;
0333: }
0334:
0335: return 8;
0336: }
0337:
0338: /**
0339: * Caches the given acl under the given cache key.<p>
0340: *
0341: * @param key the cache key
0342: * @param acl the acl to cache
0343: */
0344: public void cacheACL(String key, CmsAccessControlList acl) {
0345:
0346: m_accessControlListCache.put(key, acl);
0347: }
0348:
0349: /**
0350: * Caches the given content definition under the given cache key.<p>
0351: *
0352: * @param key the cache key
0353: * @param contentDefinition the content definition to cache
0354: */
0355: public void cacheContentDefinition(String key,
0356: CmsXmlContentDefinition contentDefinition) {
0357:
0358: m_contentDefinitionsCache.put(key, contentDefinition);
0359: }
0360:
0361: /**
0362: * Caches the given group under its id AND fully qualified name.<p>
0363: *
0364: * @param group the group to cache
0365: */
0366: public void cacheGroup(CmsGroup group) {
0367:
0368: m_groupCache.put(group.getId().toString(), group);
0369: m_groupCache.put(group.getName(), group);
0370: }
0371:
0372: /**
0373: * Caches the given locale under the given cache key.<p>
0374: *
0375: * @param key the cache key
0376: * @param locale the locale to cache
0377: */
0378: public void cacheLocale(String key, Locale locale) {
0379:
0380: if (m_localeCache != null) {
0381: // this may be accessed before initialization
0382: m_localeCache.put(key, locale);
0383: }
0384: }
0385:
0386: /**
0387: * Caches the given lock.<p>
0388: *
0389: * The lock is cached by it resource's root path.<p>
0390: *
0391: * @param lock the lock to cache
0392: */
0393: public void cacheLock(CmsLock lock) {
0394:
0395: m_lockCache.put(lock.getResourceName(), lock);
0396: }
0397:
0398: /**
0399: * Caches the given object under the given cache key.<p>
0400: *
0401: * @param key the cache key
0402: * @param obj the object to cache
0403: */
0404: public void cacheMemObject(String key, Object obj) {
0405:
0406: m_memObjectCache.put(key, obj);
0407: }
0408:
0409: /**
0410: * Caches the given organizational under its id AND the fully qualified name.<p>
0411: *
0412: * @param orgUnit the organizational unit to cache
0413: */
0414: public void cacheOrgUnit(CmsOrganizationalUnit orgUnit) {
0415:
0416: m_orgUnitCache.put(orgUnit.getId().toString(), orgUnit);
0417: m_orgUnitCache.put(orgUnit.getName(), orgUnit);
0418: }
0419:
0420: /**
0421: * Caches the given permission check result under the given cache key.<p>
0422: *
0423: * @param key the cache key
0424: * @param permission the permission check result to cache
0425: */
0426: public void cachePermission(String key,
0427: I_CmsPermissionHandler.CmsPermissionCheckResult permission) {
0428:
0429: m_permissionCache.put(key, permission);
0430: }
0431:
0432: /**
0433: * Caches the given project under its id AND the fully qualified name.<p>
0434: *
0435: * @param project the project to cache
0436: */
0437: public void cacheProject(CmsProject project) {
0438:
0439: m_projectCache.put(project.getUuid().toString(), project);
0440: m_projectCache.put(project.getName(), project);
0441: }
0442:
0443: /**
0444: * Caches the given project resource list under the given cache key.<p>
0445: *
0446: * @param key the cache key
0447: * @param projectResources the project resources to cache
0448: */
0449: public void cacheProjectResources(String key, List projectResources) {
0450:
0451: m_projectResourcesCache.put(key, projectResources);
0452: }
0453:
0454: /**
0455: * Caches the given property under the given cache key.<p>
0456: *
0457: * @param key the cache key
0458: * @param property the property to cache
0459: */
0460: public void cacheProperty(String key, CmsProperty property) {
0461:
0462: m_propertyCache.put(key, property);
0463: }
0464:
0465: /**
0466: * Caches the given property list under the given cache key.<p>
0467: *
0468: * @param key the cache key
0469: * @param propertyList the property list to cache
0470: */
0471: public void cachePropertyList(String key, List propertyList) {
0472:
0473: m_propertyListCache.put(key, propertyList);
0474: }
0475:
0476: /**
0477: * Caches the given publish job.<p>
0478: *
0479: * @param publishJob the publish job
0480: */
0481: public void cachePublishJob(CmsPublishJobInfoBean publishJob) {
0482:
0483: m_publishQueue.add(publishJob);
0484: }
0485:
0486: /**
0487: * Caches the given publish job in the publish job history.<p>
0488: *
0489: * @param publishJob the publish job
0490: */
0491: public void cachePublishJobInHistory(
0492: CmsPublishJobInfoBean publishJob) {
0493:
0494: m_publishHistory.add(publishJob);
0495: }
0496:
0497: /**
0498: * Caches the given resource under the given cache key.<p>
0499: *
0500: * @param key the cache key
0501: * @param resource the resource to cache
0502: */
0503: public void cacheResource(String key, CmsResource resource) {
0504:
0505: m_resourceCache.put(key, resource);
0506: }
0507:
0508: /**
0509: * Caches the given resource list under the given cache key.<p>
0510: *
0511: * @param key the cache key
0512: * @param resourceList the resource list to cache
0513: */
0514: public void cacheResourceList(String key, List resourceList) {
0515:
0516: m_resourceListCache.put(key, resourceList);
0517: }
0518:
0519: /**
0520: * Caches the given value under the given cache key.<p>
0521: *
0522: * @param key the cache key
0523: * @param hasRole if the user has the given role
0524: */
0525: public void cacheRole(String key, boolean hasRole) {
0526:
0527: m_rolesCache.put(key, Boolean.valueOf(hasRole));
0528: }
0529:
0530: /**
0531: * Caches the given value under the given cache key.<p>
0532: *
0533: * @param key the cache key
0534: * @param roles the roles of the user
0535: */
0536: public void cacheRoleList(String key, List roles) {
0537:
0538: m_roleListsCache.put(key, roles);
0539: }
0540:
0541: /**
0542: * Caches the given user under its id AND the fully qualified name.<p>
0543: *
0544: * @param user the user to cache
0545: */
0546: public void cacheUser(CmsUser user) {
0547:
0548: m_userCache.put(user.getId().toString(), user);
0549: m_userCache.put(user.getName(), user);
0550: }
0551:
0552: /**
0553: * Caches the given list of user groups under the given cache key.<p>
0554: *
0555: * @param key the cache key
0556: * @param userGroups the list of user groups to cache
0557: */
0558: public void cacheUserGroups(String key, List userGroups) {
0559:
0560: m_userGroupsCache.put(key, userGroups);
0561: }
0562:
0563: /**
0564: * Caches the given vfs object under the given cache key.<p>
0565: *
0566: * @param key the cache key
0567: * @param obj the vfs object to cache
0568: */
0569: public void cacheVfsObject(String key, Object obj) {
0570:
0571: m_vfsObjectCache.put(key, obj);
0572: }
0573:
0574: /**
0575: * Caches the given xml entity under the given system id.<p>
0576: *
0577: * @param systemId the cache key
0578: * @param content the content to cache
0579: */
0580: public void cacheXmlPermanentEntity(String systemId, byte[] content) {
0581:
0582: m_xmlPermanentEntityCache.put(systemId, content);
0583: }
0584:
0585: /**
0586: * Caches the given xml entity under the given cache key.<p>
0587: *
0588: * @param key the cache key
0589: * @param content the content to cache
0590: */
0591: public void cacheXmlTemporaryEntity(String key, byte[] content) {
0592:
0593: m_xmlTemporaryEntityCache.put(key, content);
0594: }
0595:
0596: /**
0597: * Clears the access control list cache when access control entries are changed.<p>
0598: */
0599: public void clearAccessControlListCache() {
0600:
0601: flushACLs();
0602: flushPermissions();
0603: clearResourceCache();
0604: }
0605:
0606: /**
0607: * Clears almost all internal caches.<p>
0608: */
0609: public void clearCache() {
0610:
0611: clearPrincipalsCache();
0612:
0613: flushProjects();
0614: flushResources();
0615: flushResourceLists();
0616: flushProperties();
0617: flushPropertyLists();
0618: flushProjectResources();
0619: }
0620:
0621: /**
0622: * Clears all internal principal-related caches.<p>
0623: */
0624: public void clearPrincipalsCache() {
0625:
0626: flushUsers();
0627: flushGroups();
0628: flushOrgUnits();
0629: flushUserGroups();
0630: flushACLs();
0631: flushPermissions();
0632: flushRoles();
0633: flushRoleLists();
0634: }
0635:
0636: /**
0637: * Clears all the depending caches when a resource was changed.<p>
0638: */
0639: public void clearResourceCache() {
0640:
0641: flushResources();
0642: flushRoles();
0643: flushRoleLists();
0644: flushResourceLists();
0645: }
0646:
0647: /**
0648: * Clears the user cache for the given user.<p>
0649: *
0650: * @param user the user
0651: */
0652: public void clearUserCache(CmsUser user) {
0653:
0654: uncacheUser(user);
0655: flushResourceLists();
0656: }
0657:
0658: /**
0659: * Returns if monitoring is enabled.<p>
0660: *
0661: * @return true if monitoring is enabled
0662: */
0663: public boolean enabled() {
0664:
0665: return true;
0666: }
0667:
0668: /**
0669: * Flushes the ACL cache.<p>
0670: */
0671: public void flushACLs() {
0672:
0673: m_accessControlListCache.clear();
0674: }
0675:
0676: /**
0677: * Flushes the xml content definitions cache.<p>
0678: */
0679: public void flushContentDefinitions() {
0680:
0681: m_contentDefinitionsCache.clear();
0682: }
0683:
0684: /**
0685: * Flushes the group cache.<p>
0686: */
0687: public void flushGroups() {
0688:
0689: m_groupCache.clear();
0690: }
0691:
0692: /**
0693: * Flushes the locale cache.<p>
0694: */
0695: public void flushLocales() {
0696:
0697: m_localeCache.clear();
0698: }
0699:
0700: /**
0701: * Flushes the locks cache.<p>
0702: *
0703: * @param newLocks if not <code>null</code> the lock cache is replaced by the given map
0704: */
0705: public void flushLocks(Map newLocks) {
0706:
0707: if ((newLocks == null) || newLocks.isEmpty()) {
0708: m_lockCache.clear();
0709: return;
0710: }
0711: // initialize new lock cache
0712: Map newLockCache = Collections.synchronizedMap(newLocks);
0713: // register it
0714: register(CmsLockManager.class.getName(), newLockCache);
0715: // save the old cache
0716: Map oldCache = m_lockCache;
0717: // replace the old by the new cache
0718: m_lockCache = newLockCache;
0719: // clean up the old cache
0720: oldCache.clear();
0721: }
0722:
0723: /**
0724: * Flushes the memory object cache.<p>
0725: */
0726: public void flushMemObjects() {
0727:
0728: m_memObjectCache.clear();
0729: }
0730:
0731: /**
0732: * Flushes the organizational unit cache.<p>
0733: */
0734: public void flushOrgUnits() {
0735:
0736: m_orgUnitCache.clear();
0737: }
0738:
0739: /**
0740: * Flushes the permission check result cache.<p>
0741: */
0742: public void flushPermissions() {
0743:
0744: m_permissionCache.clear();
0745: }
0746:
0747: /**
0748: * Flushes the project resources cache.<p>
0749: */
0750: public void flushProjectResources() {
0751:
0752: m_projectResourcesCache.clear();
0753: }
0754:
0755: /**
0756: * Flushes the project cache.<p>
0757: */
0758: public void flushProjects() {
0759:
0760: m_projectCache.clear();
0761: }
0762:
0763: /**
0764: * Flushes the property cache.<p>
0765: */
0766: public void flushProperties() {
0767:
0768: m_propertyCache.clear();
0769: }
0770:
0771: /**
0772: * Flushes the property list cache.<p>
0773: */
0774: public void flushPropertyLists() {
0775:
0776: m_propertyListCache.clear();
0777: }
0778:
0779: /**
0780: * Flushes the publish history.<p>
0781: */
0782: public void flushPublishJobHistory() {
0783:
0784: m_publishHistory.clear();
0785: }
0786:
0787: /**
0788: * Flushes the publish queue.<p>
0789: */
0790: public void flushPublishJobs() {
0791:
0792: m_publishQueue.clear();
0793: }
0794:
0795: /**
0796: * Flushes the resource list cache.<p>
0797: */
0798: public void flushResourceLists() {
0799:
0800: m_resourceListCache.clear();
0801: }
0802:
0803: /**
0804: * Flushes the resource cache.<p>
0805: */
0806: public void flushResources() {
0807:
0808: m_resourceCache.clear();
0809: }
0810:
0811: /**
0812: * Flushes the role lists cache.<p>
0813: */
0814: public void flushRoleLists() {
0815:
0816: m_roleListsCache.clear();
0817: }
0818:
0819: /**
0820: * Flushes the roles cache.<p>
0821: */
0822: public void flushRoles() {
0823:
0824: m_rolesCache.clear();
0825: }
0826:
0827: /**
0828: * Flushes the user groups cache.<p>
0829: */
0830: public void flushUserGroups() {
0831:
0832: m_userGroupsCache.clear();
0833: }
0834:
0835: /**
0836: * Flushes the users cache.<p>
0837: */
0838: public void flushUsers() {
0839:
0840: m_userCache.clear();
0841: }
0842:
0843: /**
0844: * Flushes the vfs object cache.<p>
0845: */
0846: public void flushVfsObjects() {
0847:
0848: m_vfsObjectCache.clear();
0849: }
0850:
0851: /**
0852: * Flushes the xml permanent entities cache.<p>
0853: */
0854: public void flushXmlPermanentEntities() {
0855:
0856: m_xmlPermanentEntityCache.clear();
0857:
0858: }
0859:
0860: /**
0861: * Flushes the xml temporary entities cache.<p>
0862: */
0863: public void flushXmlTemporaryEntities() {
0864:
0865: m_xmlTemporaryEntityCache.clear();
0866:
0867: }
0868:
0869: /**
0870: * Returns all cached lock root paths.<p>
0871: *
0872: * @return a list of {@link String} objects
0873: */
0874: public List getAllCachedLockPaths() {
0875:
0876: return new ArrayList(m_lockCache.keySet());
0877: }
0878:
0879: /**
0880: * Returns all cached locks.<p>
0881: *
0882: * @return a list of {@link CmsLock} objects
0883: */
0884: public List getAllCachedLocks() {
0885:
0886: return new ArrayList(m_lockCache.values());
0887: }
0888:
0889: /**
0890: * Returns all cached publish jobs in the queue as ordered list.<p>
0891: *
0892: * @return all cached publish jobs
0893: */
0894: public List getAllCachedPublishJobs() {
0895:
0896: return new ArrayList(m_publishQueue);
0897: }
0898:
0899: /**
0900: * Returns all cached publish jobs in the history as ordered list.<p>
0901: *
0902: * @return all cached publish jobs
0903: */
0904: public List getAllCachedPublishJobsInHistory() {
0905:
0906: return new ArrayList(m_publishHistory);
0907: }
0908:
0909: /**
0910: * Returns the ACL cached with the given cache key or <code>null</code> if not found.<p>
0911: *
0912: * @param key the cache key to look for
0913: *
0914: * @return the ACL cached with the given cache key
0915: */
0916: public CmsAccessControlList getCachedACL(String key) {
0917:
0918: return (CmsAccessControlList) m_accessControlListCache.get(key);
0919: }
0920:
0921: /**
0922: * Returns the xml content definition cached with the given cache key or <code>null</code> if not found.<p>
0923: *
0924: * @param key the cache key to look for
0925: *
0926: * @return the xml content definition cached with the given cache key
0927: */
0928: public CmsXmlContentDefinition getCachedContentDefinition(String key) {
0929:
0930: return (CmsXmlContentDefinition) m_contentDefinitionsCache
0931: .get(key);
0932: }
0933:
0934: /**
0935: * Returns the group cached with the given cache key or <code>null</code> if not found.<p>
0936: *
0937: * @param key the cache key to look for, this may be the group's uuid or the fqn
0938: *
0939: * @return the group cached with the given cache key
0940: */
0941: public CmsGroup getCachedGroup(String key) {
0942:
0943: return (CmsGroup) m_groupCache.get(key);
0944: }
0945:
0946: /**
0947: * Returns the locale cached with the given cache key or <code>null</code> if not found.<p>
0948: *
0949: * @param key the cache key to look for
0950: *
0951: * @return the locale cached with the given cache key
0952: */
0953: public Locale getCachedLocale(String key) {
0954:
0955: if (m_localeCache == null) {
0956: // this may be accessed before initialization
0957: return null;
0958: }
0959: return (Locale) m_localeCache.get(key);
0960: }
0961:
0962: /**
0963: * Returns the lock cached with the given root path or <code>null</code> if not found.<p>
0964: *
0965: * @param rootPath the root path to look for
0966: *
0967: * @return the lock cached with the given root path
0968: */
0969: public CmsLock getCachedLock(String rootPath) {
0970:
0971: return (CmsLock) m_lockCache.get(rootPath);
0972: }
0973:
0974: /**
0975: * Returns the memory object cached with the given cache key or <code>null</code> if not found.<p>
0976: *
0977: * @param key the cache key to look for
0978: *
0979: * @return the memory object cached with the given cache key
0980: */
0981: public Object getCachedMemObject(String key) {
0982:
0983: return m_memObjectCache.get(key);
0984: }
0985:
0986: /**
0987: * Returns the organizational unit cached with the given cache key or <code>null</code> if not found.<p>
0988: *
0989: * @param key the cache key to look for, this may be the organizational unit's uuid or the fqn
0990: *
0991: * @return the organizational unit cached with the given cache key
0992: */
0993: public CmsOrganizationalUnit getCachedOrgUnit(String key) {
0994:
0995: return (CmsOrganizationalUnit) m_orgUnitCache.get(key);
0996: }
0997:
0998: /**
0999: * Returns the permission check result cached with the given cache key or <code>null</code> if not found.<p>
1000: *
1001: * @param key the cache key to look for
1002: *
1003: * @return the permission check result cached with the given cache key
1004: */
1005: public I_CmsPermissionHandler.CmsPermissionCheckResult getCachedPermission(
1006: String key) {
1007:
1008: return (I_CmsPermissionHandler.CmsPermissionCheckResult) m_permissionCache
1009: .get(key);
1010: }
1011:
1012: /**
1013: * Returns the project cached with the given cache key or <code>null</code> if not found.<p>
1014: *
1015: * @param key the cache key to look for, this may be the project's uuid or the fqn
1016: *
1017: * @return the project cached with the given cache key
1018: */
1019: public CmsProject getCachedProject(String key) {
1020:
1021: return (CmsProject) m_projectCache.get(key);
1022: }
1023:
1024: /**
1025: * Returns the project resources list cached with the given cache key or <code>null</code> if not found.<p>
1026: *
1027: * @param key the cache key to look for
1028: *
1029: * @return the project resources list cached with the given cache key
1030: */
1031: public List getCachedProjectResources(String key) {
1032:
1033: return (List) m_projectResourcesCache.get(key);
1034: }
1035:
1036: /**
1037: * Returns the property cached with the given cache key or <code>null</code> if not found.<p>
1038: *
1039: * @param key the cache key to look for
1040: *
1041: * @return the property cached with the given cache key
1042: */
1043: public CmsProperty getCachedProperty(String key) {
1044:
1045: return (CmsProperty) m_propertyCache.get(key);
1046: }
1047:
1048: /**
1049: * Returns the property list cached with the given cache key or <code>null</code> if not found.<p>
1050: *
1051: * @param key the cache key to look for
1052: *
1053: * @return the property list cached with the given cache key
1054: */
1055: public List getCachedPropertyList(String key) {
1056:
1057: return (List) m_propertyListCache.get(key);
1058: }
1059:
1060: /**
1061: * Returns the publish job with the given cache key or <code>null</code> if not found.<p>
1062: *
1063: * @param key the cache key to look for
1064: *
1065: * @return the publish job with the given cache key
1066: */
1067: public CmsPublishJobInfoBean getCachedPublishJob(String key) {
1068:
1069: for (Iterator i = m_publishQueue.iterator(); i.hasNext();) {
1070: CmsPublishJobInfoBean publishJob = (CmsPublishJobInfoBean) i
1071: .next();
1072: if (publishJob.getPublishHistoryId().toString().equals(key)) {
1073: return publishJob;
1074: }
1075: }
1076:
1077: return null;
1078: }
1079:
1080: /**
1081: * Returns the publish job from the history with the given cache key or <code>null</code> if not found.<p>
1082: *
1083: * @param key the cache key to look for
1084: *
1085: * @return the publish job with the given cache key
1086: */
1087: public CmsPublishJobInfoBean getCachedPublishJobInHistory(String key) {
1088:
1089: for (Iterator i = m_publishHistory.iterator(); i.hasNext();) {
1090: CmsPublishJobInfoBean publishJob = (CmsPublishJobInfoBean) i
1091: .next();
1092: if (publishJob.getPublishHistoryId().toString().equals(key)) {
1093: return publishJob;
1094: }
1095: }
1096:
1097: return null;
1098: }
1099:
1100: /**
1101: * Returns the resource cached with the given cache key or <code>null</code> if not found.<p>
1102: *
1103: * @param key the cache key to look for
1104: *
1105: * @return the resource cached with the given cache key
1106: */
1107: public CmsResource getCachedResource(String key) {
1108:
1109: return (CmsResource) m_resourceCache.get(key);
1110: }
1111:
1112: /**
1113: * Returns the resource list cached with the given cache key or <code>null</code> if not found.<p>
1114: *
1115: * @param key the cache key to look for
1116: *
1117: * @return the resource list cached with the given cache key
1118: */
1119: public List getCachedResourceList(String key) {
1120:
1121: return (List) m_resourceListCache.get(key);
1122: }
1123:
1124: /**
1125: * Returns the value cached with the given cache key or <code>null</code> if not found.<p>
1126: *
1127: * @param key the cache key to look for
1128: *
1129: * @return if the user has the given role
1130: */
1131: public Boolean getCachedRole(String key) {
1132:
1133: return (Boolean) m_rolesCache.get(key);
1134: }
1135:
1136: /**
1137: * Returns the value cached with the given cache key or <code>null</code> if not found.<p>
1138: *
1139: * @param key the cache key to look for
1140: *
1141: * @return list of roles
1142: */
1143: public List getCachedRoleList(String key) {
1144:
1145: return (List) m_roleListsCache.get(key);
1146: }
1147:
1148: /**
1149: * Returns the user cached with the given cache key or <code>null</code> if not found.<p>
1150: *
1151: * @param key the cache key to look for, this may be the user's uuid or the fqn
1152: *
1153: * @return the user cached with the given cache key
1154: */
1155: public CmsUser getCachedUser(String key) {
1156:
1157: return (CmsUser) m_userCache.get(key);
1158: }
1159:
1160: /**
1161: * Returns the user groups list cached with the given cache key or <code>null</code> if not found.<p>
1162: *
1163: * @param key the cache key to look for
1164: *
1165: * @return the user groups list cached with the given cache key
1166: */
1167: public List getCachedUserGroups(String key) {
1168:
1169: return (List) m_userGroupsCache.get(key);
1170: }
1171:
1172: /**
1173: * Returns the vfs object cached with the given cache key or <code>null</code> if not found.<p>
1174: *
1175: * @param key the cache key to look for
1176: *
1177: * @return the vfs object cached with the given cache key
1178: */
1179: public Object getCachedVfsObject(String key) {
1180:
1181: return m_vfsObjectCache.get(key);
1182: }
1183:
1184: /**
1185: * Returns the xml permanent entity content cached with the given systemId or <code>null</code> if not found.<p>
1186: *
1187: * @param systemId the cache key to look for
1188: *
1189: * @return the xml permanent entity content cached with the given cache key
1190: */
1191: public byte[] getCachedXmlPermanentEntity(String systemId) {
1192:
1193: return (byte[]) m_xmlPermanentEntityCache.get(systemId);
1194: }
1195:
1196: /**
1197: * Returns the xml temporary entity content cached with the given cache key or <code>null</code> if not found.<p>
1198: *
1199: * @param key the cache key to look for
1200: *
1201: * @return the xml temporary entity content cached with the given cache key
1202: */
1203: public byte[] getCachedXmlTemporaryEntity(String key) {
1204:
1205: return (byte[]) m_xmlTemporaryEntityCache.get(key);
1206: }
1207:
1208: /**
1209: * Returns the configuration.<p>
1210: *
1211: * @return the configuration
1212: */
1213: public CmsMemoryMonitorConfiguration getConfiguration() {
1214:
1215: return m_configuration;
1216: }
1217:
1218: /**
1219: * Returns the next publish job from the publish job queue.<p>
1220: *
1221: * @return the next publish job
1222: */
1223: public CmsPublishJobInfoBean getFirstCachedPublishJob() {
1224:
1225: if (!m_publishQueue.isEmpty()) {
1226: return (CmsPublishJobInfoBean) m_publishQueue.get();
1227: } else {
1228: return null;
1229: }
1230: }
1231:
1232: /**
1233: * Returns the log count.<p>
1234: *
1235: * @return the log count
1236: */
1237: public int getLogCount() {
1238:
1239: return m_logCount;
1240: }
1241:
1242: /**
1243: * Initializes the monitor with the provided configuration.<p>
1244: *
1245: * @param configuration the configuration to use
1246: */
1247: public void initialize(CmsSystemConfiguration configuration) {
1248:
1249: CmsCacheSettings cacheSettings = configuration
1250: .getCacheSettings();
1251:
1252: m_memoryAverage = new CmsMemoryStatus();
1253: m_memoryCurrent = new CmsMemoryStatus();
1254:
1255: m_warningSendSinceLastStatus = false;
1256: m_warningLoggedSinceLastStatus = false;
1257: m_lastEmailWarning = 0;
1258: m_lastEmailStatus = 0;
1259: m_lastLogStatus = 0;
1260: m_lastLogWarning = 0;
1261: m_lastClearCache = 0;
1262: m_configuration = configuration
1263: .getCmsMemoryMonitorConfiguration();
1264:
1265: m_intervalWarning = 720 * 60000;
1266: m_maxUsagePercent = 90;
1267:
1268: m_intervalEmail = m_configuration.getEmailInterval() * 1000;
1269: m_intervalLog = m_configuration.getLogInterval() * 1000;
1270:
1271: if (m_configuration.getWarningInterval() > 0) {
1272: m_intervalWarning = m_configuration.getWarningInterval();
1273: }
1274: m_intervalWarning *= 1000;
1275:
1276: if (m_configuration.getMaxUsagePercent() > 0) {
1277: m_maxUsagePercent = m_configuration.getMaxUsagePercent();
1278: }
1279:
1280: if (CmsLog.INIT.isInfoEnabled()) {
1281: CmsLog.INIT.info(Messages.get().getBundle().key(
1282: Messages.LOG_MM_INTERVAL_LOG_1,
1283: new Integer(m_intervalLog / 1000)));
1284: CmsLog.INIT.info(Messages.get().getBundle().key(
1285: Messages.LOG_MM_INTERVAL_EMAIL_1,
1286: new Integer(m_intervalEmail / 1000)));
1287: CmsLog.INIT.info(Messages.get().getBundle().key(
1288: Messages.LOG_MM_INTERVAL_WARNING_1,
1289: new Integer(m_intervalWarning / 1000)));
1290: CmsLog.INIT.info(Messages.get().getBundle().key(
1291: Messages.LOG_MM_INTERVAL_MAX_USAGE_1,
1292: new Integer(m_maxUsagePercent)));
1293:
1294: if ((m_configuration.getEmailReceiver() == null)
1295: || (m_configuration.getEmailSender() == null)) {
1296: CmsLog.INIT.info(Messages.get().getBundle().key(
1297: Messages.LOG_MM_EMAIL_DISABLED_0));
1298: } else {
1299: CmsLog.INIT.info(Messages.get().getBundle().key(
1300: Messages.LOG_MM_EMAIL_SENDER_1,
1301: m_configuration.getEmailSender()));
1302: Iterator i = m_configuration.getEmailReceiver()
1303: .iterator();
1304: int n = 0;
1305: while (i.hasNext()) {
1306: CmsLog.INIT.info(Messages.get().getBundle().key(
1307: Messages.LOG_MM_EMAIL_RECEIVER_2,
1308: new Integer(n + 1), i.next()));
1309: n++;
1310: }
1311: }
1312: }
1313:
1314: // create and register all system caches
1315:
1316: // temporary xml entities cache
1317: LRUMap xmlTemporaryCache = new LRUMap(128);
1318: m_xmlTemporaryEntityCache = Collections
1319: .synchronizedMap(xmlTemporaryCache);
1320: register(CmsXmlEntityResolver.class.getName()
1321: + ".xmlEntityTemporaryCache", m_xmlTemporaryEntityCache);
1322:
1323: // permanent xml entities cache
1324: Map xmlPermanentCache = new HashMap(32);
1325: m_xmlPermanentEntityCache = Collections
1326: .synchronizedMap(xmlPermanentCache);
1327: register(CmsXmlEntityResolver.class.getName()
1328: + ".xmlEntityPermanentCache", m_xmlPermanentEntityCache);
1329:
1330: // xml content definitions cache
1331: LRUMap contentDefinitionsCache = new LRUMap(64);
1332: m_contentDefinitionsCache = Collections
1333: .synchronizedMap(contentDefinitionsCache);
1334: register(CmsXmlEntityResolver.class.getName()
1335: + ".contentDefinitionsCache", m_contentDefinitionsCache);
1336:
1337: // lock cache
1338: Map lockCache = new HashMap();
1339: m_lockCache = Collections.synchronizedMap(lockCache);
1340: register(CmsLockManager.class.getName(), lockCache);
1341:
1342: // locale cache
1343: Map map = new HashMap();
1344: m_localeCache = Collections.synchronizedMap(map);
1345: register(CmsLocaleManager.class.getName(), map);
1346:
1347: // permissions cache
1348: LRUMap lruMap = new LRUMap(cacheSettings
1349: .getPermissionCacheSize());
1350: m_permissionCache = Collections.synchronizedMap(lruMap);
1351: register(CmsSecurityManager.class.getName(), lruMap);
1352:
1353: // user cache
1354: lruMap = new LRUMap(cacheSettings.getUserCacheSize());
1355: m_userCache = Collections.synchronizedMap(lruMap);
1356: register(CmsDriverManager.class.getName() + ".userCache",
1357: lruMap);
1358:
1359: // group cache
1360: lruMap = new LRUMap(cacheSettings.getGroupCacheSize());
1361: m_groupCache = Collections.synchronizedMap(lruMap);
1362: register(CmsDriverManager.class.getName() + ".groupCache",
1363: lruMap);
1364:
1365: // organizational unit cache
1366: lruMap = new LRUMap(cacheSettings.getOrgUnitCacheSize());
1367: m_orgUnitCache = Collections.synchronizedMap(lruMap);
1368: register(CmsDriverManager.class.getName() + ".orgUnitCache",
1369: lruMap);
1370:
1371: // user groups list cache
1372: lruMap = new LRUMap(cacheSettings.getUserGroupsCacheSize());
1373: m_userGroupsCache = Collections.synchronizedMap(lruMap);
1374: register(CmsDriverManager.class.getName() + ".userGroupsCache",
1375: lruMap);
1376:
1377: // project cache
1378: lruMap = new LRUMap(cacheSettings.getProjectCacheSize());
1379: m_projectCache = Collections.synchronizedMap(lruMap);
1380: register(CmsDriverManager.class.getName() + ".projectCache",
1381: lruMap);
1382:
1383: // project resources cache cache
1384: lruMap = new LRUMap(cacheSettings
1385: .getProjectResourcesCacheSize());
1386: m_projectResourcesCache = Collections.synchronizedMap(lruMap);
1387: register(CmsDriverManager.class.getName()
1388: + ".projectResourcesCache", lruMap);
1389:
1390: // publish history
1391: int size = configuration.getPublishManager()
1392: .getPublishHistorySize();
1393: Buffer buffer = CmsPublishHistory.getQueue(size);
1394: m_publishHistory = SynchronizedBuffer.decorate(buffer);
1395: register(CmsPublishHistory.class.getName() + ".publishHistory",
1396: buffer);
1397:
1398: // publish queue
1399: buffer = CmsPublishQueue.getQueue();
1400: m_publishQueue = SynchronizedBuffer.decorate(buffer);
1401: register(CmsPublishQueue.class.getName() + ".publishQueue",
1402: buffer);
1403:
1404: // resource cache
1405: lruMap = new LRUMap(cacheSettings.getResourceCacheSize());
1406: m_resourceCache = Collections.synchronizedMap(lruMap);
1407: register(CmsDriverManager.class.getName() + ".resourceCache",
1408: lruMap);
1409:
1410: // roles cache
1411: lruMap = new LRUMap(cacheSettings.getRolesCacheSize());
1412: m_rolesCache = Collections.synchronizedMap(lruMap);
1413: register(CmsDriverManager.class.getName() + ".rolesCache",
1414: lruMap);
1415:
1416: // role lists cache
1417: lruMap = new LRUMap(cacheSettings.getRolesCacheSize());
1418: m_roleListsCache = Collections.synchronizedMap(lruMap);
1419: register(CmsDriverManager.class.getName() + ".roleListsCache",
1420: lruMap);
1421:
1422: // resource list cache
1423: lruMap = new LRUMap(cacheSettings.getResourcelistCacheSize());
1424: m_resourceListCache = Collections.synchronizedMap(lruMap);
1425: register(CmsDriverManager.class.getName()
1426: + ".resourceListCache", lruMap);
1427:
1428: // property cache
1429: lruMap = new LRUMap(cacheSettings.getPropertyCacheSize());
1430: m_propertyCache = Collections.synchronizedMap(lruMap);
1431: register(CmsDriverManager.class.getName() + ".propertyCache",
1432: lruMap);
1433:
1434: // property list cache
1435: lruMap = new LRUMap(cacheSettings.getPropertyListsCacheSize());
1436: m_propertyListCache = Collections.synchronizedMap(lruMap);
1437: register(CmsDriverManager.class.getName()
1438: + ".propertyListCache", lruMap);
1439:
1440: // acl cache
1441: lruMap = new LRUMap(cacheSettings.getAclCacheSize());
1442: m_accessControlListCache = Collections.synchronizedMap(lruMap);
1443: register(CmsDriverManager.class.getName()
1444: + ".accessControlListCache", lruMap);
1445:
1446: // vfs object cache
1447: Map vfsObjectCache = new HashMap();
1448: m_vfsObjectCache = Collections.synchronizedMap(vfsObjectCache);
1449: register(CmsVfsMemoryObjectCache.class.getName(),
1450: vfsObjectCache);
1451:
1452: // memory object cache
1453: Map memObjectCache = new HashMap();
1454: m_memObjectCache = Collections.synchronizedMap(memObjectCache);
1455: register(CmsMemoryObjectCache.class.getName(), memObjectCache);
1456:
1457: if (LOG.isDebugEnabled()) {
1458: // this will happen only once during system startup
1459: LOG.debug(Messages.get().getBundle().key(
1460: Messages.LOG_MM_CREATED_1,
1461: new Date(System.currentTimeMillis())));
1462: }
1463: }
1464:
1465: /**
1466: * Checks if there is a registered monitored object with the given key.<p>
1467: *
1468: * @param key the key to look for
1469: *
1470: * @return <code>true</code> if there is a registered monitored object with the given key
1471: */
1472: public boolean isMonitoring(String key) {
1473:
1474: return (m_monitoredObjects.get(key) != null);
1475: }
1476:
1477: /**
1478: * @see org.opencms.scheduler.I_CmsScheduledJob#launch(CmsObject, Map)
1479: */
1480: public String launch(CmsObject cms, Map parameters)
1481: throws Exception {
1482:
1483: CmsMemoryMonitor monitor = OpenCms.getMemoryMonitor();
1484:
1485: // make sure job is not launched twice
1486: if (m_currentlyRunning) {
1487: return null;
1488: }
1489:
1490: try {
1491: m_currentlyRunning = true;
1492:
1493: // update the memory status
1494: monitor.updateStatus();
1495:
1496: // check if the system is in a low memory condition
1497: if (monitor.lowMemory()) {
1498: // log warning
1499: monitor.monitorWriteLog(true);
1500: // send warning email
1501: monitor.monitorSendEmail(true);
1502: // clean up caches
1503: monitor.clearCaches();
1504: }
1505:
1506: // check if regular a log entry must be written
1507: if ((System.currentTimeMillis() - monitor.m_lastLogStatus) > monitor.m_intervalLog) {
1508: monitor.monitorWriteLog(false);
1509: }
1510:
1511: // check if the memory status email must be send
1512: if ((System.currentTimeMillis() - monitor.m_lastEmailStatus) > monitor.m_intervalEmail) {
1513: monitor.monitorSendEmail(false);
1514: }
1515: } finally {
1516: // make sure state is reset even if an error occurs,
1517: // otherwise MM will not be executed after an error
1518: m_currentlyRunning = false;
1519: }
1520:
1521: return null;
1522: }
1523:
1524: /**
1525: * Returns true if the system runs low on memory.<p>
1526: *
1527: * @return true if the system runs low on memory
1528: */
1529: public boolean lowMemory() {
1530:
1531: return ((m_maxUsagePercent > 0) && (m_memoryCurrent.getUsage() > m_maxUsagePercent));
1532: }
1533:
1534: /**
1535: * Adds a new object to the monitor.<p>
1536: *
1537: * @param objectName name of the object
1538: * @param object the object for monitoring
1539: */
1540: public void register(String objectName, Object object) {
1541:
1542: if (enabled()) {
1543: m_monitoredObjects.put(objectName, object);
1544: }
1545: }
1546:
1547: /**
1548: * Checks if some kind of persistence is required.<p>
1549: *
1550: * This could be overwritten in a distributed environment.<p>
1551: *
1552: * @return <code>true</code> if some kind of persistence is required
1553: */
1554: public boolean requiresPersistency() {
1555:
1556: return true;
1557: }
1558:
1559: /**
1560: * Flushes all cached objects.<p>
1561: *
1562: * @throws Exception if something goes wrong
1563: */
1564: public void shutdown() throws Exception {
1565:
1566: flushACLs();
1567: flushGroups();
1568: flushLocales();
1569: flushMemObjects();
1570: flushOrgUnits();
1571: flushPermissions();
1572: flushProjectResources();
1573: flushProjects();
1574: flushProperties();
1575: flushPropertyLists();
1576: flushResourceLists();
1577: flushResources();
1578: flushUserGroups();
1579: flushUsers();
1580: flushVfsObjects();
1581: flushLocks(null);
1582: flushContentDefinitions();
1583: flushXmlPermanentEntities();
1584: flushXmlTemporaryEntities();
1585: flushRoles();
1586: flushRoleLists();
1587: }
1588:
1589: /**
1590: * Removes the given xml content definition from the cache.<p>
1591: *
1592: * @param key the cache key to remove from cache
1593: */
1594: public void uncacheContentDefinition(String key) {
1595:
1596: m_contentDefinitionsCache.remove(key);
1597: }
1598:
1599: /**
1600: * Removes the given group from the cache.<p>
1601: *
1602: * The group is removed by name AND also by uuid.<p>
1603: *
1604: * @param group the group to remove from cache
1605: */
1606: public void uncacheGroup(CmsGroup group) {
1607:
1608: m_groupCache.remove(group.getId().toString());
1609: m_groupCache.remove(group.getName());
1610: }
1611:
1612: /**
1613: * Removes the cached lock for the given root path from the cache.<p>
1614: *
1615: * @param rootPath the root path of the lock to remove from cache
1616: */
1617: public void uncacheLock(String rootPath) {
1618:
1619: m_lockCache.remove(rootPath);
1620: }
1621:
1622: /**
1623: * Removes the given organizational unit from the cache.<p>
1624: *
1625: * The organizational unit is removed by name AND also by uuid.<p>
1626: *
1627: * @param orgUnit the organizational unit to remove from cache
1628: */
1629: public void uncacheOrgUnit(CmsOrganizationalUnit orgUnit) {
1630:
1631: m_orgUnitCache.remove(orgUnit.getId().toString());
1632: m_orgUnitCache.remove(orgUnit.getName());
1633: }
1634:
1635: /**
1636: * Removes the given project from the cache.<p>
1637: *
1638: * The project is removed by name AND also by uuid.<p>
1639: *
1640: * @param project the project to remove from cache
1641: */
1642: public void uncacheProject(CmsProject project) {
1643:
1644: m_projectCache.remove(project.getUuid().toString());
1645: m_projectCache.remove(project.getName());
1646: }
1647:
1648: /**
1649: * Removes the given publish job from the cache.<p>
1650: *
1651: * @param publishJob the publish job to remove
1652: */
1653: public void uncachePublishJob(CmsPublishJobInfoBean publishJob) {
1654:
1655: m_publishQueue.remove(publishJob);
1656: }
1657:
1658: /**
1659: * Removes the given publish job from the history.<p>
1660: *
1661: * @param publishJob the publish job to remove
1662: */
1663: public void uncachePublishJobInHistory(
1664: CmsPublishJobInfoBean publishJob) {
1665:
1666: m_publishHistory.remove(publishJob);
1667: }
1668:
1669: /**
1670: * Removes the given user from the cache.<p>
1671: *
1672: * The user is removed by name AND also by uuid.<p>
1673: *
1674: * @param user the user to remove from cache
1675: */
1676: public void uncacheUser(CmsUser user) {
1677:
1678: m_userCache.remove(user.getId().toString());
1679: m_userCache.remove(user.getName());
1680: }
1681:
1682: /**
1683: * Removes the given vfs object from the cache.<p>
1684: *
1685: * @param key the cache key to remove from cache
1686: */
1687: public void uncacheVfsObject(String key) {
1688:
1689: m_vfsObjectCache.remove(key);
1690: }
1691:
1692: /**
1693: * Removes the given xml temporary entity from the cache.<p>
1694: *
1695: * @param key the cache key to remove from cache
1696: */
1697: public void uncacheXmlTemporaryEntity(String key) {
1698:
1699: m_xmlTemporaryEntityCache.remove(key);
1700: }
1701:
1702: /**
1703: * Clears the OpenCms caches.<p>
1704: */
1705: private void clearCaches() {
1706:
1707: if ((m_lastClearCache + INTERVAL_CLEAR) > System
1708: .currentTimeMillis()) {
1709: // if the cache has already been cleared less then 15 minutes ago we skip this because
1710: // clearing the caches to often will hurt system performance and the
1711: // setup seems to be in trouble anyway
1712: return;
1713: }
1714: m_lastClearCache = System.currentTimeMillis();
1715: if (LOG.isWarnEnabled()) {
1716: LOG.warn(Messages.get().getBundle().key(
1717: Messages.LOG_CLEAR_CACHE_MEM_CONS_0));
1718: }
1719: OpenCms.fireCmsEvent(new CmsEvent(
1720: I_CmsEventListener.EVENT_CLEAR_CACHES,
1721: Collections.EMPTY_MAP));
1722: System.gc();
1723: }
1724:
1725: /**
1726: * Returns the cache costs of a monitored object.<p>
1727: *
1728: * <code>obj</code> must be of type {@link CmsLruCache}.<p>
1729: *
1730: * @param obj the object
1731: *
1732: * @return the cache costs or "-"
1733: */
1734: private long getCosts(Object obj) {
1735:
1736: long costs = 0;
1737: if (obj instanceof CmsLruCache) {
1738: costs = ((CmsLruCache) obj).getObjectCosts();
1739: if (costs < 0) {
1740: costs = 0;
1741: }
1742: }
1743:
1744: return costs;
1745: }
1746:
1747: /**
1748: * Returns the number of items within a monitored object.<p>
1749: *
1750: * <code>obj</code> must be of type {@link CmsLruCache} or {@link Map}.<p>
1751: *
1752: * @param obj the object
1753: *
1754: * @return the number of items or "-"
1755: */
1756: private String getItems(Object obj) {
1757:
1758: if (obj instanceof CmsLruCache) {
1759: return Integer.toString(((CmsLruCache) obj).size());
1760: }
1761: if (obj instanceof Map) {
1762: return Integer.toString(((Map) obj).size());
1763: }
1764: return "-";
1765: }
1766:
1767: /**
1768: * Returns the total size of key strings within a monitored map.<p>
1769: *
1770: * The keys must be of type {@link String}.<p>
1771: *
1772: * @param map the map
1773: * @param depth the max recursion depth for calculation the size
1774: *
1775: * @return total size of key strings
1776: */
1777: private long getKeySize(Map map, int depth) {
1778:
1779: long keySize = 0;
1780: try {
1781: Object[] values = map.values().toArray();
1782: for (int i = 0, s = values.length; i < s; i++) {
1783:
1784: Object obj = values[i];
1785:
1786: if ((obj instanceof Map) && (depth < MAX_DEPTH)) {
1787: keySize += getKeySize((Map) obj, depth + 1);
1788: continue;
1789: }
1790: }
1791: values = null;
1792:
1793: Object[] keys = map.keySet().toArray();
1794: for (int i = 0, s = keys.length; i < s; i++) {
1795:
1796: Object obj = keys[i];
1797:
1798: if (obj instanceof String) {
1799: String st = (String) obj;
1800: keySize += (st.length() * 2);
1801: }
1802: }
1803: } catch (ConcurrentModificationException e) {
1804: // this might happen since even the .toArray() method internally creates an iterator
1805: } catch (Throwable t) {
1806: // catch all other exceptions otherwise the whole monitor will stop working
1807: if (LOG.isDebugEnabled()) {
1808: LOG.debug(Messages.get().getBundle()
1809: .key(Messages.LOG_CAUGHT_THROWABLE_1,
1810: t.getMessage()));
1811: }
1812: }
1813:
1814: return keySize;
1815: }
1816:
1817: /**
1818: * Returns the total size of key strings within a monitored object.<p>
1819: *
1820: * <code>obj</code> must be of type {@link Map}, the keys must be of type {@link String}.<p>
1821: *
1822: * @param obj the object
1823: *
1824: * @return the total size of key strings
1825: */
1826: private long getKeySize(Object obj) {
1827:
1828: if (obj instanceof Map) {
1829: return getKeySize((Map) obj, 1);
1830: }
1831:
1832: return 0;
1833: }
1834:
1835: /**
1836: * Returns the max costs for all items within a monitored object.<p>
1837: *
1838: * <code>obj</code> must be of type {@link CmsLruCache} or {@link LRUMap}.<p>
1839: *
1840: * @param obj the object
1841: *
1842: * @return max cost limit or "-"
1843: */
1844: private String getLimit(Object obj) {
1845:
1846: if (obj instanceof CmsLruCache) {
1847: return Integer.toString(((CmsLruCache) obj)
1848: .getMaxCacheCosts());
1849: }
1850: if (obj instanceof LRUMap) {
1851: return Integer.toString(((LRUMap) obj).maxSize());
1852: }
1853:
1854: return "-";
1855: }
1856:
1857: /**
1858: * Returns the total value size of a list object.<p>
1859: *
1860: * @param listValue the list object
1861: * @param depth the max recursion depth for calculation the size
1862: *
1863: * @return the size of the list object
1864: */
1865: private long getValueSize(List listValue, int depth) {
1866:
1867: long totalSize = 0;
1868: try {
1869: Object[] values = listValue.toArray();
1870: for (int i = 0, s = values.length; i < s; i++) {
1871:
1872: Object obj = values[i];
1873:
1874: if (obj instanceof CmsAccessControlList) {
1875: obj = ((CmsAccessControlList) obj)
1876: .getPermissionMap();
1877: }
1878:
1879: if (obj instanceof CmsFlexCacheVariation) {
1880: obj = ((CmsFlexCacheVariation) obj).m_map;
1881: }
1882:
1883: if ((obj instanceof Map) && (depth < MAX_DEPTH)) {
1884: totalSize += getValueSize((Map) obj, depth + 1);
1885: continue;
1886: }
1887:
1888: if ((obj instanceof List) && (depth < MAX_DEPTH)) {
1889: totalSize += getValueSize((List) obj, depth + 1);
1890: continue;
1891: }
1892:
1893: totalSize += getMemorySize(obj);
1894: }
1895: } catch (ConcurrentModificationException e) {
1896: // this might happen since even the .toArray() method internally creates an iterator
1897: } catch (Throwable t) {
1898: // catch all other exceptions otherwise the whole monitor will stop working
1899: if (LOG.isDebugEnabled()) {
1900: LOG.debug(Messages.get().getBundle()
1901: .key(Messages.LOG_CAUGHT_THROWABLE_1,
1902: t.getMessage()));
1903: }
1904: }
1905:
1906: return totalSize;
1907: }
1908:
1909: /**
1910: * Returns the total value size of a map object.<p>
1911: *
1912: * @param mapValue the map object
1913: * @param depth the max recursion depth for calculation the size
1914: *
1915: * @return the size of the map object
1916: */
1917: private long getValueSize(Map mapValue, int depth) {
1918:
1919: long totalSize = 0;
1920: try {
1921: Object[] values = mapValue.values().toArray();
1922: for (int i = 0, s = values.length; i < s; i++) {
1923:
1924: Object obj = values[i];
1925:
1926: if (obj instanceof CmsAccessControlList) {
1927: obj = ((CmsAccessControlList) obj)
1928: .getPermissionMap();
1929: }
1930:
1931: if (obj instanceof CmsFlexCacheVariation) {
1932: obj = ((CmsFlexCacheVariation) obj).m_map;
1933: }
1934:
1935: if ((obj instanceof Map) && (depth < MAX_DEPTH)) {
1936: totalSize += getValueSize((Map) obj, depth + 1);
1937: continue;
1938: }
1939:
1940: if ((obj instanceof List) && (depth < MAX_DEPTH)) {
1941: totalSize += getValueSize((List) obj, depth + 1);
1942: continue;
1943: }
1944:
1945: totalSize += getMemorySize(obj);
1946: }
1947: } catch (ConcurrentModificationException e) {
1948: // this might happen since even the .toArray() method internally creates an iterator
1949: } catch (Throwable t) {
1950: // catch all other exceptions otherwise the whole monitor will stop working
1951: if (LOG.isDebugEnabled()) {
1952: LOG.debug(Messages.get().getBundle()
1953: .key(Messages.LOG_CAUGHT_THROWABLE_1,
1954: t.getMessage()));
1955: }
1956: }
1957:
1958: return totalSize;
1959: }
1960:
1961: /**
1962: * Returns the value sizes of value objects within the monitored object.<p>
1963: *
1964: * @param obj the object
1965: *
1966: * @return the value sizes of value objects or "-"-fields
1967: */
1968: private long getValueSize(Object obj) {
1969:
1970: if (obj instanceof CmsLruCache) {
1971: return ((CmsLruCache) obj).size();
1972: }
1973:
1974: if (obj instanceof Map) {
1975: return getValueSize((Map) obj, 1);
1976: }
1977:
1978: if (obj instanceof List) {
1979: return getValueSize((List) obj, 1);
1980: }
1981:
1982: try {
1983: return getMemorySize(obj);
1984: } catch (Exception exc) {
1985: return 0;
1986: }
1987: }
1988:
1989: /**
1990: * Sends a warning or status email with OpenCms Memory information.<p>
1991: *
1992: * @param warning if true, send a memory warning email
1993: */
1994: private void monitorSendEmail(boolean warning) {
1995:
1996: if ((m_configuration.getEmailSender() == null)
1997: || (m_configuration.getEmailReceiver() == null)) {
1998: // send no mails if not fully configured
1999: return;
2000: } else if (warning
2001: && (m_warningSendSinceLastStatus && !((m_intervalEmail <= 0) && (System
2002: .currentTimeMillis() < (m_lastEmailWarning + m_intervalWarning))))) {
2003: // send no warning email if no status email has been send since the last warning
2004: // if status is disabled, send no warn email if warn interval has not passed
2005: return;
2006: } else if ((!warning) && (m_intervalEmail <= 0)) {
2007: // if email iterval is <= 0 status email is disabled
2008: return;
2009: }
2010: String date = CmsDateUtil.getDateTimeShort(System
2011: .currentTimeMillis());
2012: String subject;
2013: String content = "";
2014: if (warning) {
2015: m_warningSendSinceLastStatus = true;
2016: m_lastEmailWarning = System.currentTimeMillis();
2017: subject = "OpenCms Memory W A R N I N G ["
2018: + OpenCms.getSystemInfo().getServerName()
2019: .toUpperCase() + "/" + date + "]";
2020: content += "W A R N I N G !\nOpenCms memory consumption on server "
2021: + OpenCms.getSystemInfo().getServerName()
2022: .toUpperCase()
2023: + " has reached a critical level !\n\n"
2024: + "The configured limit is "
2025: + m_maxUsagePercent
2026: + "%\n\n";
2027: } else {
2028: m_warningSendSinceLastStatus = false;
2029: m_lastEmailStatus = System.currentTimeMillis();
2030: subject = "OpenCms Memory Status ["
2031: + OpenCms.getSystemInfo().getServerName()
2032: .toUpperCase() + "/" + date + "]";
2033: }
2034:
2035: content += "Memory usage report of OpenCms server "
2036: + OpenCms.getSystemInfo().getServerName().toUpperCase()
2037: + " at " + date + "\n\n" + "Memory maximum heap size: "
2038: + m_memoryCurrent.getMaxMemory() + " mb\n"
2039: + "Memory current heap size: "
2040: + m_memoryCurrent.getTotalMemory() + " mb\n\n"
2041: + "Memory currently used : "
2042: + m_memoryCurrent.getUsedMemory() + " mb ("
2043: + m_memoryCurrent.getUsage() + "%)\n"
2044: + "Memory currently unused : "
2045: + m_memoryCurrent.getFreeMemory() + " mb\n\n\n";
2046:
2047: if (warning) {
2048: content += "*** Please take action NOW to ensure that no OutOfMemoryException occurs.\n\n\n";
2049: }
2050:
2051: CmsSessionManager sm = OpenCms.getSessionManager();
2052:
2053: if (sm != null) {
2054: content += "Current status of the sessions:\n\n";
2055: content += "Logged in users : "
2056: + sm.getSessionCountAuthenticated() + "\n";
2057: content += "Currently active sessions: "
2058: + sm.getSessionCountCurrent() + "\n";
2059: content += "Total created sessions : "
2060: + sm.getSessionCountTotal() + "\n\n\n";
2061: }
2062:
2063: sm = null;
2064:
2065: content += "Current status of the caches:\n\n";
2066: List keyList = Arrays.asList(m_monitoredObjects.keySet()
2067: .toArray());
2068: Collections.sort(keyList);
2069: long totalSize = 0;
2070: for (Iterator keys = keyList.iterator(); keys.hasNext();) {
2071: String key = (String) keys.next();
2072: String[] shortKeys = key.split("\\.");
2073: String shortKey = shortKeys[shortKeys.length - 2] + '.'
2074: + shortKeys[shortKeys.length - 1];
2075: PrintfFormat form = new PrintfFormat("%9s");
2076: Object obj = m_monitoredObjects.get(key);
2077:
2078: long size = getKeySize(obj) + getValueSize(obj)
2079: + getCosts(obj);
2080: totalSize += size;
2081:
2082: content += new PrintfFormat("%-42.42s").sprintf(shortKey)
2083: + " " + "Entries: " + form.sprintf(getItems(obj))
2084: + " " + "Limit: " + form.sprintf(getLimit(obj))
2085: + " " + "Size: "
2086: + form.sprintf(Long.toString(size)) + "\n";
2087: }
2088: content += "\nTotal size of cache memory monitored: "
2089: + totalSize + " (" + totalSize / 1048576 + ")\n\n";
2090:
2091: String from = m_configuration.getEmailSender();
2092: List receivers = new ArrayList();
2093: List receiverEmails = m_configuration.getEmailReceiver();
2094: try {
2095: if ((from != null) && (receiverEmails != null)
2096: && !receiverEmails.isEmpty()) {
2097: Iterator i = receiverEmails.iterator();
2098: while (i.hasNext()) {
2099: receivers
2100: .add(new InternetAddress((String) i.next()));
2101: }
2102: CmsSimpleMail email = new CmsSimpleMail();
2103: email.setFrom(from);
2104: email.setTo(receivers);
2105: email.setSubject(subject);
2106: email.setMsg(content);
2107: new CmsMailTransport(email).send();
2108: }
2109: if (LOG.isInfoEnabled()) {
2110: if (warning) {
2111: LOG.info(Messages.get().getBundle().key(
2112: Messages.LOG_MM_WARNING_EMAIL_SENT_0));
2113: } else {
2114: LOG.info(Messages.get().getBundle().key(
2115: Messages.LOG_MM_STATUS_EMAIL_SENT_0));
2116: }
2117: }
2118: } catch (Exception e) {
2119: e.printStackTrace();
2120: }
2121: }
2122:
2123: /**
2124: * Write a warning or status log entry with OpenCms Memory information.<p>
2125: *
2126: * @param warning if true, write a memory warning log entry
2127: */
2128: private void monitorWriteLog(boolean warning) {
2129:
2130: if (!LOG.isWarnEnabled()) {
2131: // we need at last warn level for this output
2132: return;
2133: } else if ((!warning) && (!LOG.isInfoEnabled())) {
2134: // if not warning we need info level
2135: return;
2136: } else if (warning
2137: && (m_warningLoggedSinceLastStatus && !(((m_intervalLog <= 0) && (System
2138: .currentTimeMillis() < (m_lastLogWarning + m_intervalWarning)))))) {
2139: // write no warning log if no status log has been written since the last warning
2140: // if status is disabled, log no warn entry if warn interval has not passed
2141: return;
2142: } else if ((!warning) && (m_intervalLog <= 0)) {
2143: // if log interval is <= 0 status log is disabled
2144: return;
2145: }
2146:
2147: if (warning) {
2148: m_lastLogWarning = System.currentTimeMillis();
2149: m_warningLoggedSinceLastStatus = true;
2150: LOG.warn(Messages.get().getBundle().key(
2151: Messages.LOG_MM_WARNING_MEM_CONSUME_2,
2152: new Long(m_memoryCurrent.getUsage()),
2153: new Integer(m_maxUsagePercent)));
2154: } else {
2155: m_warningLoggedSinceLastStatus = false;
2156: m_lastLogStatus = System.currentTimeMillis();
2157: }
2158:
2159: if (warning) {
2160: LOG.warn(Messages.get().getBundle().key(
2161: Messages.LOG_MM_WARNING_MEM_STATUS_6,
2162: new Object[] {
2163: new Long(m_memoryCurrent.getMaxMemory()),
2164: new Long(m_memoryCurrent.getTotalMemory()),
2165: new Long(m_memoryCurrent.getFreeMemory()),
2166: new Long(m_memoryCurrent.getUsedMemory()),
2167: new Long(m_memoryCurrent.getUsage()),
2168: new Integer(m_maxUsagePercent) }));
2169: } else {
2170: m_logCount++;
2171: LOG
2172: .info(Messages.get().getBundle().key(
2173: Messages.LOG_MM_LOG_INFO_2,
2174: OpenCms.getSystemInfo().getServerName()
2175: .toUpperCase(),
2176: String.valueOf(m_logCount)));
2177:
2178: List keyList = Arrays.asList(m_monitoredObjects.keySet()
2179: .toArray());
2180: Collections.sort(keyList);
2181: long totalSize = 0;
2182: for (Iterator keys = keyList.iterator(); keys.hasNext();) {
2183:
2184: String key = (String) keys.next();
2185: Object obj = m_monitoredObjects.get(key);
2186:
2187: long size = getKeySize(obj) + getValueSize(obj)
2188: + getCosts(obj);
2189: totalSize += size;
2190:
2191: PrintfFormat name1 = new PrintfFormat("%-80s");
2192: PrintfFormat name2 = new PrintfFormat("%-50s");
2193: PrintfFormat form = new PrintfFormat("%9s");
2194: LOG.info(Messages.get().getBundle()
2195: .key(
2196: Messages.LOG_MM_NOWARN_STATUS_5,
2197: new Object[] {
2198: name1.sprintf(key),
2199: name2.sprintf(obj.getClass()
2200: .getName()),
2201: form.sprintf(getItems(obj)),
2202: form.sprintf(getLimit(obj)),
2203: form.sprintf(Long
2204: .toString(size)) }));
2205: }
2206:
2207: LOG.info(Messages.get().getBundle().key(
2208: Messages.LOG_MM_WARNING_MEM_STATUS_6,
2209: new Object[] {
2210: new Long(m_memoryCurrent.getMaxMemory()),
2211: new Long(m_memoryCurrent.getTotalMemory()),
2212: new Long(m_memoryCurrent.getFreeMemory()),
2213: new Long(m_memoryCurrent.getUsedMemory()),
2214: new Long(m_memoryCurrent.getUsage()),
2215: new Integer(m_maxUsagePercent),
2216: new Long(totalSize),
2217: new Long(totalSize / 1048576) })
2218:
2219: );
2220: LOG.info(Messages.get().getBundle().key(
2221: Messages.LOG_MM_WARNING_MEM_STATUS_AVG_6,
2222: new Object[] {
2223: new Long(m_memoryAverage.getMaxMemory()),
2224: new Long(m_memoryAverage.getTotalMemory()),
2225: new Long(m_memoryAverage.getFreeMemory()),
2226: new Long(m_memoryAverage.getUsedMemory()),
2227: new Long(m_memoryAverage.getUsage()),
2228: new Integer(m_memoryAverage.getCount()) }));
2229:
2230: CmsSessionManager sm = OpenCms.getSessionManager();
2231:
2232: if (sm != null) {
2233: LOG.info(Messages.get().getBundle().key(
2234: Messages.LOG_MM_SESSION_STAT_3,
2235: String.valueOf(sm
2236: .getSessionCountAuthenticated()),
2237: String.valueOf(sm.getSessionCountCurrent()),
2238: String.valueOf(sm.getSessionCountTotal())));
2239: }
2240: sm = null;
2241:
2242: for (Iterator i = OpenCms.getSqlManager().getDbPoolUrls()
2243: .iterator(); i.hasNext();) {
2244: String poolname = (String) i.next();
2245: try {
2246: LOG.info(Messages.get().getBundle().key(
2247: Messages.LOG_MM_CONNECTIONS_3,
2248: poolname,
2249: Integer.toString(OpenCms.getSqlManager()
2250: .getActiveConnections(poolname)),
2251: Integer.toString(OpenCms.getSqlManager()
2252: .getIdleConnections(poolname))));
2253: } catch (Exception exc) {
2254: LOG
2255: .info(Messages.get().getBundle().key(
2256: Messages.LOG_MM_CONNECTIONS_3,
2257: poolname, Integer.toString(-1),
2258: Integer.toString(-1)));
2259: }
2260: }
2261:
2262: LOG.info(Messages.get().getBundle().key(
2263: Messages.LOG_MM_STARTUP_TIME_2,
2264: CmsDateUtil.getDateTimeShort(OpenCms
2265: .getSystemInfo().getStartupTime()),
2266: CmsStringUtil.formatRuntime(OpenCms.getSystemInfo()
2267: .getRuntime())));
2268: }
2269: }
2270:
2271: /**
2272: * Updates the memory information of the memory monitor.<p>
2273: */
2274: private void updateStatus() {
2275:
2276: m_memoryCurrent.update();
2277: m_memoryAverage.calculateAverage(m_memoryCurrent);
2278: }
2279:
2280: }
|