All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opencms.monitor.CmsMemoryMonitor Maven / Gradle / Ivy

Go to download

OpenCms is an enterprise-ready, easy to use website content management system based on Java and XML technology. Offering a complete set of features, OpenCms helps content managers worldwide to create and maintain beautiful websites fast and efficiently.

There is a newer version: 18.0
Show newest version
/*
 * This library is part of OpenCms -
 * the Open Source Content Management System
 *
 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * For further information about Alkacon Software GmbH & Co. KG, please see the
 * company website: http://www.alkacon.com
 *
 * For further information about OpenCms, please see the
 * project website: http://www.opencms.org
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.opencms.monitor;

import org.opencms.cache.CmsLruCache;
import org.opencms.cache.CmsMemoryObjectCache;
import org.opencms.cache.CmsVfsMemoryObjectCache;
import org.opencms.configuration.CmsSystemConfiguration;
import org.opencms.db.CmsCacheSettings;
import org.opencms.db.CmsDriverManager;
import org.opencms.db.CmsPublishedResource;
import org.opencms.db.CmsSecurityManager;
import org.opencms.file.CmsFile;
import org.opencms.file.CmsGroup;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsProject;
import org.opencms.file.CmsProperty;
import org.opencms.file.CmsPropertyDefinition;
import org.opencms.file.CmsResource;
import org.opencms.file.CmsUser;
import org.opencms.flex.CmsFlexCache.CmsFlexCacheVariation;
import org.opencms.i18n.CmsLocaleManager;
import org.opencms.lock.CmsLock;
import org.opencms.lock.CmsLockManager;
import org.opencms.mail.CmsMailTransport;
import org.opencms.mail.CmsSimpleMail;
import org.opencms.main.CmsEvent;
import org.opencms.main.CmsLog;
import org.opencms.main.CmsSessionManager;
import org.opencms.main.I_CmsEventListener;
import org.opencms.main.OpenCms;
import org.opencms.publish.CmsPublishHistory;
import org.opencms.publish.CmsPublishJobInfoBean;
import org.opencms.publish.CmsPublishQueue;
import org.opencms.scheduler.I_CmsScheduledJob;
import org.opencms.security.CmsAccessControlList;
import org.opencms.security.CmsOrganizationalUnit;
import org.opencms.security.CmsPermissionSet;
import org.opencms.security.CmsRole;
import org.opencms.security.I_CmsPermissionHandler;
import org.opencms.util.CmsDateUtil;
import org.opencms.util.CmsStringUtil;
import org.opencms.util.CmsUUID;
import org.opencms.util.PrintfFormat;
import org.opencms.xml.CmsXmlContentDefinition;
import org.opencms.xml.CmsXmlEntityResolver;

import java.util.ArrayList;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.mail.internet.InternetAddress;

import org.apache.commons.collections.Buffer;
import org.apache.commons.collections.buffer.SynchronizedBuffer;
import org.apache.commons.collections.map.LRUMap;
import org.apache.commons.logging.Log;

import com.google.common.cache.CacheBuilder;

/**
 * Monitors OpenCms memory consumption.

* * The memory monitor also provides all kind of caches used in the OpenCms core.

* * @since 6.0.0 */ public class CmsMemoryMonitor implements I_CmsScheduledJob { /** Cache types. */ public enum CacheType { /** Access Control Lists cache. */ ACL, /** Content Definition cache. */ CONTENT_DEFINITION, /** Group cache. */ GROUP, /** Has Role cache. */ HAS_ROLE, /** Locale cache. */ LOCALE, /** Lock cache. */ LOCK, /** Memory Object cache. */ MEMORY_OBJECT, /** Organizational Unit cache. */ ORG_UNIT, /** Permission cache. */ PERMISSION, /** Offline Project cache. */ PROJECT, /** Project resources cache. */ PROJECT_RESOURCES, /** Property cache. */ PROPERTY, /** Property List cache. */ PROPERTY_LIST, /** Publish history cache. */ PUBLISH_HISTORY, /** Publish queue cache. */ PUBLISH_QUEUE, /** Published resources cache. */ PUBLISHED_RESOURCES, /** Resource cache. */ RESOURCE, /** Resource List cache. */ RESOURCE_LIST, /** Role List cache. */ ROLE_LIST, /** User cache. */ USER, /** User list cache. */ USER_LIST, /** User Groups cache. */ USERGROUPS, /** VFS Object cache. */ VFS_OBJECT, /** XML Entity Permanent cache. */ XML_ENTITY_PERM, /** XML Entity Temporary cache. */ XML_ENTITY_TEMP; } /** The concurrency level for the guava caches. */ private static final int CONCURRENCY_LEVEL = 8; /** Set interval for clearing the caches to 10 minutes. */ private static final int INTERVAL_CLEAR = 1000 * 60 * 10; /** The log object for this class. */ private static final Log LOG = CmsLog.getLog(CmsMemoryMonitor.class); /** Flag indicating if monitor is currently running. */ private static boolean m_currentlyRunning; /** Maximum depth for object size recursion. */ private static final int MAX_DEPTH = 5; /** Cache for access control lists. */ private Map m_cacheAccessControlList; /** A temporary cache for XML content definitions. */ private Map m_cacheContentDefinitions; /** Cache for groups. */ private Map m_cacheGroup; /** Cache for roles. */ private Map m_cacheHasRoles; /** A cache for accelerated locale lookup. */ private Map m_cacheLocale; /** Cache for the resource locks. */ private Map m_cacheLock; /** The memory object cache map. */ private Map m_cacheMemObject; /** Cache for organizational units. */ private Map m_cacheOrgUnit; /** Cache for permission checks. */ private Map m_cachePermission; /** Cache for offline projects. */ private Map m_cacheProject; /** Cache for project resources. */ private Map> m_cacheProjectResources; /** Cache for properties. */ private Map m_cacheProperty; /** Cache for property lists. */ private Map> m_cachePropertyList; /** Cache for published resources. */ private Map> m_cachePublishedResources; /** Cache for resources. */ private Map m_cacheResource; /** Cache for resource lists. */ private Map> m_cacheResourceList; /** Cache for role lists. */ private Map> m_cacheRoleLists; /** Cache for user data. */ private Map m_cacheUser; /** Cache for user groups. */ private Map> m_cacheUserGroups; /** Cache for user lists. */ private Map> m_cacheUserList; /** The vfs memory cache map. */ private Map m_cacheVfsObject; /** A permanent cache to avoid multiple readings of often used files from the VFS. */ private Map m_cacheXmlPermanentEntity; /** A temporary cache to avoid multiple readings of often used files from the VFS. */ private Map m_cacheXmlTemporaryEntity; /** The memory monitor configuration. */ private CmsMemoryMonitorConfiguration m_configuration; /** Map to keep track of disabled caches. */ private Map m_disabled = new HashMap(); /** Interval in which emails are send. */ private int m_intervalEmail; /** Interval in which the log is written. */ private int m_intervalLog; /** Interval between 2 warnings. */ private int m_intervalWarning; /** The time the caches were last cleared. */ private long m_lastClearCache; /** The time the last status email was send. */ private long m_lastEmailStatus; /** The time the last warning email was send. */ private long m_lastEmailWarning; /** The time the last status log was written. */ private long m_lastLogStatus; /** The time the last warning log was written. */ private long m_lastLogWarning; /** The number of times the log entry was written. */ private int m_logCount; /** Memory percentage to reach to go to warning level. */ private int m_maxUsagePercent; /** The average memory status. */ private CmsMemoryStatus m_memoryAverage; /** The current memory status. */ private CmsMemoryStatus m_memoryCurrent; /** Contains the object to be monitored. */ private Map m_monitoredObjects; /** Buffer for publish history. */ private Buffer m_publishHistory; /** Buffer for publish jobs. */ private Buffer m_publishQueue; /** Flag for memory warning mail send. */ private boolean m_warningLoggedSinceLastStatus; /** Flag for memory warning mail send. */ private boolean m_warningSendSinceLastStatus; /** * Empty constructor, required by OpenCms scheduler.

*/ public CmsMemoryMonitor() { m_monitoredObjects = new HashMap(); } /** * Creates a thread safe LRU cache map based on the guava cache builder.

* Use this instead of synchronized maps for better performance.

* * @param capacity the cache capacity * * @return the cache map */ @SuppressWarnings("unchecked") public static Map createLRUCacheMap(int capacity) { CacheBuilder builder = CacheBuilder.newBuilder().concurrencyLevel(CONCURRENCY_LEVEL).maximumSize( capacity); builder.build(); return (Map)(builder.build().asMap()); } /** * Returns the size of objects that are instances of * byte[], String, CmsFile,I_CmsLruCacheObject.

* For other objects, a size of 0 is returned. * * @param obj the object * @return the size of the object */ public static int getMemorySize(Object obj) { if (obj instanceof I_CmsMemoryMonitorable) { return ((I_CmsMemoryMonitorable)obj).getMemorySize(); } if (obj instanceof byte[]) { // will always be a total of 16 + 8 return 8 + (int)(Math.ceil(((byte[])obj).length / 16.0) * 16.0); } if (obj instanceof String) { // will always be a total of 16 + 24 return 24 + (int)(Math.ceil(((String)obj).length() / 8.0) * 16.0); } if (obj instanceof CmsFile) { CmsFile f = (CmsFile)obj; if (f.getContents() != null) { return f.getContents().length + 1024; } else { return 1024; } } if (obj instanceof CmsUUID) { return 184; // worst case if UUID String has been generated } if (obj instanceof CmsPermissionSet) { return 16; // two ints } if (obj instanceof CmsResource) { return 1024; // estimated size } if (obj instanceof CmsPublishedResource) { return 512; // estimated size } if (obj instanceof CmsUser) { return 2048; // estimated size } if (obj instanceof CmsGroup) { return 512; // estimated size } if (obj instanceof CmsProject) { return 512; // estimated size } if (obj instanceof Boolean) { return 8; // one boolean } if (obj instanceof CmsProperty) { int size = 8; CmsProperty property = (CmsProperty)obj; size += getMemorySize(property.getName()); if (property.getResourceValue() != null) { size += getMemorySize(property.getResourceValue()); } if (property.getStructureValue() != null) { size += getMemorySize(property.getStructureValue()); } if (property.getOrigin() != null) { size += getMemorySize(property.getOrigin()); } return size; } if (obj instanceof CmsPropertyDefinition) { int size = 8; CmsPropertyDefinition propDef = (CmsPropertyDefinition)obj; size += getMemorySize(propDef.getName()); size += getMemorySize(propDef.getId()); return size; } return 8; } /** * Returns the total value size of a list object.

* * @param listValue the list object * @param depth the max recursion depth for calculation the size * * @return the size of the list object */ public static long getValueSize(List listValue, int depth) { long totalSize = 0; try { Object[] values = listValue.toArray(); for (int i = 0, s = values.length; i < s; i++) { Object obj = values[i]; if (obj instanceof CmsAccessControlList) { obj = ((CmsAccessControlList)obj).getPermissionMap(); } if (obj instanceof CmsFlexCacheVariation) { obj = ((CmsFlexCacheVariation)obj).m_map; } if ((obj instanceof Map) && (depth < MAX_DEPTH)) { totalSize += getValueSize((Map)obj, depth + 1); continue; } if ((obj instanceof List) && (depth < MAX_DEPTH)) { totalSize += getValueSize((List)obj, depth + 1); continue; } totalSize += getMemorySize(obj); } } catch (ConcurrentModificationException e) { // this might happen since even the .toArray() method internally creates an iterator } catch (Throwable t) { // catch all other exceptions otherwise the whole monitor will stop working if (LOG.isDebugEnabled()) { LOG.debug(Messages.get().getBundle().key(Messages.LOG_CAUGHT_THROWABLE_1, t.getMessage())); } } return totalSize; } /** * Returns the total value size of a map object.

* * @param mapValue the map object * @param depth the max recursion depth for calculation the size * * @return the size of the map object */ public static long getValueSize(Map mapValue, int depth) { long totalSize = 0; try { Object[] values = mapValue.values().toArray(); for (int i = 0, s = values.length; i < s; i++) { Object obj = values[i]; if (obj instanceof CmsAccessControlList) { obj = ((CmsAccessControlList)obj).getPermissionMap(); } if (obj instanceof CmsFlexCacheVariation) { obj = ((CmsFlexCacheVariation)obj).m_map; } if ((obj instanceof Map) && (depth < MAX_DEPTH)) { totalSize += getValueSize((Map)obj, depth + 1); continue; } if ((obj instanceof List) && (depth < MAX_DEPTH)) { totalSize += getValueSize((List)obj, depth + 1); continue; } totalSize += getMemorySize(obj); } } catch (ConcurrentModificationException e) { // this might happen since even the .toArray() method internally creates an iterator } catch (Throwable t) { // catch all other exceptions otherwise the whole monitor will stop working if (LOG.isDebugEnabled()) { LOG.debug(Messages.get().getBundle().key(Messages.LOG_CAUGHT_THROWABLE_1, t.getMessage())); } } return totalSize; } /** * Returns the value sizes of value objects within the monitored object.

* * @param obj the object * * @return the value sizes of value objects or "-"-fields */ public static long getValueSize(Object obj) { if (obj instanceof CmsLruCache) { return ((CmsLruCache)obj).size(); } if (obj instanceof Map) { return getValueSize((Map)obj, 1); } if (obj instanceof List) { return getValueSize((List)obj, 1); } try { return getMemorySize(obj); } catch (Exception exc) { return 0; } } /** * Caches the given acl under the given cache key.

* * @param key the cache key * @param acl the acl to cache */ public void cacheACL(String key, CmsAccessControlList acl) { if (m_disabled.get(CacheType.ACL) != null) { return; } m_cacheAccessControlList.put(key, acl); } /** * Caches the given content definition under the given cache key.

* * @param key the cache key * @param contentDefinition the content definition to cache */ public void cacheContentDefinition(String key, CmsXmlContentDefinition contentDefinition) { if (m_disabled.get(CacheType.CONTENT_DEFINITION) != null) { return; } m_cacheContentDefinitions.put(key, contentDefinition); } /** * Caches the given group under its id AND fully qualified name.

* * @param group the group to cache */ public void cacheGroup(CmsGroup group) { if (m_disabled.get(CacheType.GROUP) != null) { return; } m_cacheGroup.put(group.getId().toString(), group); m_cacheGroup.put(group.getName(), group); } /** * Caches the given locale under the given cache key.

* * @param key the cache key * @param locale the locale to cache */ public void cacheLocale(String key, Locale locale) { if (m_cacheLocale != null) { if (m_disabled.get(CacheType.LOCALE) != null) { return; } // this may be accessed before initialization m_cacheLocale.put(key, locale); } } /** * Caches the given lock.

* * The lock is cached by it resource's root path.

* * @param lock the lock to cache */ public void cacheLock(CmsLock lock) { if (m_disabled.get(CacheType.LOCK) != null) { return; } m_cacheLock.put(lock.getResourceName(), lock); } /** * Caches the given object under the given cache key.

* * @param key the cache key * @param obj the object to cache */ public void cacheMemObject(String key, Object obj) { if (m_disabled.get(CacheType.MEMORY_OBJECT) != null) { return; } m_cacheMemObject.put(key, obj); } /** * Caches the given organizational under its id AND the fully qualified name.

* * @param orgUnit the organizational unit to cache */ public void cacheOrgUnit(CmsOrganizationalUnit orgUnit) { if (m_disabled.get(CacheType.ORG_UNIT) != null) { return; } m_cacheOrgUnit.put(orgUnit.getId().toString(), orgUnit); m_cacheOrgUnit.put(orgUnit.getName(), orgUnit); } /** * Caches the given permission check result under the given cache key.

* * @param key the cache key * @param permission the permission check result to cache */ public void cachePermission(String key, I_CmsPermissionHandler.CmsPermissionCheckResult permission) { if (m_disabled.get(CacheType.PERMISSION) != null) { return; } m_cachePermission.put(key, permission); } /** * Caches the given project under its id AND the fully qualified name.

* * @param project the project to cache */ public void cacheProject(CmsProject project) { if (m_disabled.get(CacheType.PROJECT) != null) { return; } m_cacheProject.put(project.getUuid().toString(), project); m_cacheProject.put(project.getName(), project); } /** * Caches the given project resource list under the given cache key.

* * @param key the cache key * @param projectResources the project resources to cache */ public void cacheProjectResources(String key, List projectResources) { if (m_disabled.get(CacheType.PROJECT_RESOURCES) != null) { return; } m_cacheProjectResources.put(key, projectResources); } /** * Caches the given property under the given cache key.

* * @param key the cache key * @param property the property to cache */ public void cacheProperty(String key, CmsProperty property) { if (m_disabled.get(CacheType.PROPERTY) != null) { return; } m_cacheProperty.put(key, property); } /** * Caches the given property list under the given cache key.

* * @param key the cache key * @param propertyList the property list to cache */ public void cachePropertyList(String key, List propertyList) { if (m_disabled.get(CacheType.PROPERTY_LIST) != null) { return; } m_cachePropertyList.put(key, propertyList); } /** * Caches the given published resources list under the given cache key.

* * @param cacheKey the cache key * @param publishedResources the published resources list to cache */ public void cachePublishedResources(String cacheKey, List publishedResources) { if (m_disabled.get(CacheType.PUBLISHED_RESOURCES) != null) { return; } m_cachePublishedResources.put(cacheKey, publishedResources); } /** * Caches the given publish job.

* * @param publishJob the publish job */ @SuppressWarnings("unchecked") public void cachePublishJob(CmsPublishJobInfoBean publishJob) { if (m_disabled.get(CacheType.PUBLISH_QUEUE) != null) { return; } m_publishQueue.add(publishJob); } /** * Caches the given publish job in the publish job history.

* * @param publishJob the publish job */ @SuppressWarnings("unchecked") public void cachePublishJobInHistory(CmsPublishJobInfoBean publishJob) { if (m_disabled.get(CacheType.PUBLISH_HISTORY) != null) { return; } m_publishHistory.add(publishJob); } /** * Caches the given resource under the given cache key.

* * @param key the cache key * @param resource the resource to cache */ public void cacheResource(String key, CmsResource resource) { if (m_disabled.get(CacheType.RESOURCE) != null) { return; } m_cacheResource.put(key, resource); } /** * Caches the given resource list under the given cache key.

* * @param key the cache key * @param resourceList the resource list to cache */ public void cacheResourceList(String key, List resourceList) { if (m_disabled.get(CacheType.RESOURCE_LIST) != null) { return; } m_cacheResourceList.put(key, resourceList); } /** * Caches the given value under the given cache key.

* * @param key the cache key * @param hasRole if the user has the given role */ public void cacheRole(String key, boolean hasRole) { if (m_disabled.get(CacheType.HAS_ROLE) != null) { return; } m_cacheHasRoles.put(key, Boolean.valueOf(hasRole)); } /** * Caches the given value under the given cache key.

* * @param key the cache key * @param roles the roles of the user */ public void cacheRoleList(String key, List roles) { if (m_disabled.get(CacheType.ROLE_LIST) != null) { return; } m_cacheRoleLists.put(key, roles); } /** * Caches the given user under its id AND the fully qualified name.

* * @param user the user to cache */ public void cacheUser(CmsUser user) { if (m_disabled.get(CacheType.USER) != null) { return; } m_cacheUser.put(user.getId().toString(), user); m_cacheUser.put(user.getName(), user); } /** * Caches the given list of user groups under the given cache key.

* * @param key the cache key * @param userGroups the list of user groups to cache */ public void cacheUserGroups(String key, List userGroups) { if (m_disabled.get(CacheType.USERGROUPS) != null) { return; } m_cacheUserGroups.put(key, userGroups); } /** * Caches the given list of users under the given cache key.

* * @param key the cache key * @param userList the list of users to cache */ public void cacheUserList(String key, List userList) { if (m_disabled.get(CacheType.USER_LIST) != null) { return; } m_cacheUserList.put(key, userList); } /** * Caches the given vfs object under the given cache key.

* * @param key the cache key * @param obj the vfs object to cache */ public void cacheVfsObject(String key, Object obj) { if (m_disabled.get(CacheType.VFS_OBJECT) != null) { return; } m_cacheVfsObject.put(key, obj); } /** * Caches the given xml entity under the given system id.

* * @param systemId the cache key * @param content the content to cache */ public void cacheXmlPermanentEntity(String systemId, byte[] content) { if (m_disabled.get(CacheType.XML_ENTITY_PERM) != null) { return; } m_cacheXmlPermanentEntity.put(systemId, content); } /** * Caches the given xml entity under the given cache key.

* * @param key the cache key * @param content the content to cache */ public void cacheXmlTemporaryEntity(String key, byte[] content) { if (m_disabled.get(CacheType.XML_ENTITY_TEMP) != null) { return; } m_cacheXmlTemporaryEntity.put(key, content); } /** * Clears the access control list cache when access control entries are changed.

*/ public void clearAccessControlListCache() { flushCache(CacheType.ACL); flushCache(CacheType.PERMISSION); clearResourceCache(); } /** * Clears almost all internal caches.

*/ public void clearCache() { clearPrincipalsCache(); flushCache(CacheType.PROJECT); flushCache(CacheType.RESOURCE); flushCache(CacheType.RESOURCE_LIST); flushCache(CacheType.PROPERTY); flushCache(CacheType.PROPERTY_LIST); flushCache(CacheType.PROJECT_RESOURCES); flushCache(CacheType.PUBLISHED_RESOURCES); } /** * Clears all internal principal-related caches.

*/ public void clearPrincipalsCache() { flushCache(CacheType.USER); flushCache(CacheType.GROUP); flushCache(CacheType.ORG_UNIT); flushCache(CacheType.ACL); flushCache(CacheType.PERMISSION); flushCache(CacheType.HAS_ROLE); flushCache(CacheType.ROLE_LIST); flushCache(CacheType.USERGROUPS); flushCache(CacheType.USER_LIST); } /** * Clears all the depending caches when a resource was changed.

*/ public void clearResourceCache() { flushCache(CacheType.RESOURCE); flushCache(CacheType.RESOURCE_LIST); flushCache(CacheType.HAS_ROLE); flushCache(CacheType.ROLE_LIST); } /** * Clears the user cache for the given user.

* * @param user the user */ public void clearUserCache(CmsUser user) { uncacheUser(user); flushCache(CacheType.RESOURCE_LIST); } /** * Disables the given cache.

* * @param types the cache type to disable */ public void disableCache(CacheType... types) { for (CacheType type : types) { m_disabled.put(type, Boolean.TRUE); } flushCache(types); } /** * Enables the given cache.

* * @param types the cache type to disable */ public void enableCache(CacheType... types) { for (CacheType type : types) { m_disabled.remove(type); } } /** * Returns if monitoring is enabled.

* * @return true if monitoring is enabled */ public boolean enabled() { return true; } /** * Flushes the ACL cache.

* * @deprecated use {@link #flushCache(CacheType[])} instead */ @Deprecated public void flushACLs() { flushCache(CacheType.ACL); } /** * Flushes the given cache.

* * @param types the cache types to flush */ public void flushCache(CacheType... types) { for (CacheType type : types) { switch (type) { case ACL: m_cacheAccessControlList.clear(); break; case CONTENT_DEFINITION: m_cacheContentDefinitions.clear(); break; case GROUP: m_cacheGroup.clear(); break; case HAS_ROLE: m_cacheHasRoles.clear(); break; case LOCALE: m_cacheLocale.clear(); break; case LOCK: m_cacheLock.clear(); break; case MEMORY_OBJECT: m_cacheMemObject.clear(); break; case ORG_UNIT: m_cacheOrgUnit.clear(); break; case PERMISSION: m_cachePermission.clear(); break; case PROJECT: m_cacheProject.clear(); break; case PROJECT_RESOURCES: m_cacheProjectResources.clear(); break; case PROPERTY: m_cacheProperty.clear(); break; case PROPERTY_LIST: m_cachePropertyList.clear(); break; case PUBLISHED_RESOURCES: m_cachePublishedResources.clear(); break; case PUBLISH_HISTORY: m_publishHistory.clear(); break; case PUBLISH_QUEUE: m_publishQueue.clear(); break; case RESOURCE: m_cacheResource.clear(); break; case RESOURCE_LIST: m_cacheResourceList.clear(); break; case ROLE_LIST: m_cacheRoleLists.clear(); break; case USER: m_cacheUser.clear(); break; case USERGROUPS: m_cacheUserGroups.clear(); break; case USER_LIST: m_cacheUserList.clear(); break; case VFS_OBJECT: m_cacheVfsObject.clear(); break; case XML_ENTITY_PERM: m_cacheXmlPermanentEntity.clear(); break; case XML_ENTITY_TEMP: m_cacheXmlTemporaryEntity.clear(); break; default: // can't happen } } } /** * Flushes the xml content definitions cache.

* * @deprecated use {@link #flushCache(CacheType[])} instead */ @Deprecated public void flushContentDefinitions() { flushCache(CacheType.CONTENT_DEFINITION); } /** * Flushes the group cache.

* * @deprecated use {@link #flushCache(CacheType[])} instead */ @Deprecated public void flushGroups() { flushCache(CacheType.GROUP); } /** * Flushes the locale cache.

* * @deprecated use {@link #flushCache(CacheType[])} instead */ @Deprecated public void flushLocales() { flushCache(CacheType.LOCALE); } /** * Flushes the locks cache.

* * @param newLocks if not null the lock cache is replaced by the given map */ public void flushLocks(Map newLocks) { if ((newLocks == null) || newLocks.isEmpty()) { flushCache(CacheType.LOCK); return; } // initialize new lock cache Map newLockCache = new ConcurrentHashMap(newLocks); // register it register(CmsLockManager.class.getName(), newLockCache); // save the old cache Map oldCache = m_cacheLock; // replace the old by the new cache m_cacheLock = newLockCache; // clean up the old cache oldCache.clear(); } /** * Flushes the memory object cache.

* * @deprecated use {@link #flushCache(CacheType[])} instead */ @Deprecated public void flushMemObjects() { flushCache(CacheType.MEMORY_OBJECT); } /** * Flushes the organizational unit cache.

* * @deprecated use {@link #flushCache(CacheType[])} instead */ @Deprecated public void flushOrgUnits() { flushCache(CacheType.ORG_UNIT); } /** * Flushes the permission check result cache.

* * @deprecated use {@link #flushCache(CacheType[])} instead */ @Deprecated public void flushPermissions() { flushCache(CacheType.PERMISSION); } /** * Flushes the project resources cache.

* * @deprecated use {@link #flushCache(CacheType[])} instead */ @Deprecated public void flushProjectResources() { flushCache(CacheType.PROJECT_RESOURCES); } /** * Flushes the project cache.

* * @deprecated use {@link #flushCache(CacheType[])} instead */ @Deprecated public void flushProjects() { flushCache(CacheType.PROJECT); } /** * Flushes the property cache.

* * @deprecated use {@link #flushCache(CacheType[])} instead */ @Deprecated public void flushProperties() { flushCache(CacheType.PROPERTY); } /** * Flushes the property list cache.

* * @deprecated use {@link #flushCache(CacheType[])} instead */ @Deprecated public void flushPropertyLists() { flushCache(CacheType.PROPERTY_LIST); } /** * Flushes the published resources cache.

* * @deprecated use {@link #flushCache(CacheType[])} instead */ @Deprecated public void flushPublishedResources() { flushCache(CacheType.PUBLISHED_RESOURCES); } /** * Flushes the publish history.

* * @deprecated use {@link #flushCache(CacheType[])} instead */ @Deprecated public void flushPublishJobHistory() { flushCache(CacheType.PUBLISH_HISTORY); } /** * Flushes the publish queue.

* * @deprecated use {@link #flushCache(CacheType[])} instead */ @Deprecated public void flushPublishJobs() { flushCache(CacheType.PUBLISH_QUEUE); } /** * Flushes the resource list cache.

* * @deprecated use {@link #flushCache(CacheType[])} instead */ @Deprecated public void flushResourceLists() { flushCache(CacheType.RESOURCE_LIST); } /** * Flushes the resource cache.

* * @deprecated use {@link #flushCache(CacheType[])} instead */ @Deprecated public void flushResources() { flushCache(CacheType.RESOURCE); } /** * Flushes the role lists cache.

* * @deprecated use {@link #flushCache(CacheType[])} instead */ @Deprecated public void flushRoleLists() { flushCache(CacheType.ROLE_LIST); } /** * Flushes the roles cache.

* * @deprecated use {@link #flushCache(CacheType[])} instead */ @Deprecated public void flushRoles() { flushCache(CacheType.HAS_ROLE); } /** * Flushes the user groups cache.

* * @deprecated use {@link #flushCache(CacheType[])} instead */ @Deprecated public void flushUserGroups() { flushCache(CacheType.USERGROUPS); flushCache(CacheType.USER_LIST); } /** * Flushes the users cache.

* * @deprecated use {@link #flushCache(CacheType[])} instead */ @Deprecated public void flushUsers() { flushCache(CacheType.USER); } /** * Flushes the vfs object cache.

* * @deprecated use {@link #flushCache(CacheType[])} instead */ @Deprecated public void flushVfsObjects() { flushCache(CacheType.VFS_OBJECT); } /** * Flushes the xml permanent entities cache.

* * @deprecated use {@link #flushCache(CacheType[])} instead */ @Deprecated public void flushXmlPermanentEntities() { flushCache(CacheType.XML_ENTITY_PERM); } /** * Flushes the xml temporary entities cache.

* * @deprecated use {@link #flushCache(CacheType[])} instead */ @Deprecated public void flushXmlTemporaryEntities() { flushCache(CacheType.XML_ENTITY_TEMP); } /** * Returns all cached lock root paths.

* * @return a list of {@link String} objects */ public List getAllCachedLockPaths() { return new ArrayList(m_cacheLock.keySet()); } /** * Returns all cached locks.

* * @return a list of {@link CmsLock} objects */ public List getAllCachedLocks() { return new ArrayList(m_cacheLock.values()); } /** * Returns all cached publish jobs in the queue as ordered list.

* * @return all cached publish jobs */ @SuppressWarnings("unchecked") public List getAllCachedPublishJobs() { return new ArrayList(m_publishQueue); } /** * Returns all cached publish jobs in the history as ordered list.

* * @return all cached publish jobs */ @SuppressWarnings("unchecked") public List getAllCachedPublishJobsInHistory() { return new ArrayList(m_publishHistory); } /** * Returns the ACL cached with the given cache key or null if not found.

* * @param key the cache key to look for * * @return the ACL cached with the given cache key */ public CmsAccessControlList getCachedACL(String key) { return m_cacheAccessControlList.get(key); } /** * Returns the xml content definition cached with the given cache key or null if not found.

* * @param key the cache key to look for * * @return the xml content definition cached with the given cache key */ public CmsXmlContentDefinition getCachedContentDefinition(String key) { return m_cacheContentDefinitions.get(key); } /** * Returns the group cached with the given cache key or null if not found.

* * @param key the cache key to look for, this may be the group's uuid or the fqn * * @return the group cached with the given cache key */ public CmsGroup getCachedGroup(String key) { return m_cacheGroup.get(key); } /** * Returns the locale cached with the given cache key or null if not found.

* * @param key the cache key to look for * * @return the locale cached with the given cache key */ public Locale getCachedLocale(String key) { if (m_cacheLocale == null) { // this may be accessed before initialization return null; } return m_cacheLocale.get(key); } /** * Returns the lock cached with the given root path or null if not found.

* * @param rootPath the root path to look for * * @return the lock cached with the given root path */ public CmsLock getCachedLock(String rootPath) { return m_cacheLock.get(rootPath); } /** * Returns the memory object cached with the given cache key or null if not found.

* * @param key the cache key to look for * * @return the memory object cached with the given cache key */ public Object getCachedMemObject(String key) { return m_cacheMemObject.get(key); } /** * Returns the organizational unit cached with the given cache key or null if not found.

* * @param key the cache key to look for, this may be the organizational unit's uuid or the fqn * * @return the organizational unit cached with the given cache key */ public CmsOrganizationalUnit getCachedOrgUnit(String key) { return m_cacheOrgUnit.get(key); } /** * Returns the permission check result cached with the given cache key or null if not found.

* * @param key the cache key to look for * * @return the permission check result cached with the given cache key */ public I_CmsPermissionHandler.CmsPermissionCheckResult getCachedPermission(String key) { return m_cachePermission.get(key); } /** * Returns the project cached with the given cache key or null if not found.

* * @param key the cache key to look for, this may be the project's uuid or the fqn * * @return the project cached with the given cache key */ public CmsProject getCachedProject(String key) { return m_cacheProject.get(key); } /** * Returns the project resources list cached with the given cache key or null if not found.

* * @param key the cache key to look for * * @return the project resources list cached with the given cache key */ public List getCachedProjectResources(String key) { return m_cacheProjectResources.get(key); } /** * Returns the property cached with the given cache key or null if not found.

* * @param key the cache key to look for * * @return the property cached with the given cache key */ public CmsProperty getCachedProperty(String key) { return m_cacheProperty.get(key); } /** * Returns the property list cached with the given cache key or null if not found.

* * @param key the cache key to look for * * @return the property list cached with the given cache key */ public List getCachedPropertyList(String key) { return m_cachePropertyList.get(key); } /** * Returns the published resources list cached with the given cache key or null if not found.

* * @param cacheKey the cache key to look for * * @return the published resources list cached with the given cache key */ public List getCachedPublishedResources(String cacheKey) { return m_cachePublishedResources.get(cacheKey); } /** * Returns the publish job with the given cache key or null if not found.

* * @param key the cache key to look for * * @return the publish job with the given cache key */ public CmsPublishJobInfoBean getCachedPublishJob(String key) { synchronized (m_publishQueue) { for (Object obj : m_publishQueue) { CmsPublishJobInfoBean publishJob = (CmsPublishJobInfoBean)obj; if (publishJob.getPublishHistoryId().toString().equals(key)) { return publishJob; } } } return null; } /** * Returns the publish job from the history with the given cache key or null if not found.

* * @param key the cache key to look for * * @return the publish job with the given cache key */ public CmsPublishJobInfoBean getCachedPublishJobInHistory(String key) { for (Object obj : m_publishHistory) { CmsPublishJobInfoBean publishJob = (CmsPublishJobInfoBean)obj; if (publishJob.getPublishHistoryId().toString().equals(key)) { return publishJob; } } return null; } /** * Returns the resource cached with the given cache key or null if not found.

* * @param key the cache key to look for * * @return the resource cached with the given cache key */ public CmsResource getCachedResource(String key) { return m_cacheResource.get(key); } /** * Returns the resource list cached with the given cache key or null if not found.

* * @param key the cache key to look for * * @return the resource list cached with the given cache key */ public List getCachedResourceList(String key) { return m_cacheResourceList.get(key); } /** * Returns the value cached with the given cache key or null if not found.

* * @param key the cache key to look for * * @return if the user has the given role */ public Boolean getCachedRole(String key) { return m_cacheHasRoles.get(key); } /** * Returns the value cached with the given cache key or null if not found.

* * @param key the cache key to look for * * @return list of roles */ public List getCachedRoleList(String key) { return m_cacheRoleLists.get(key); } /** * Returns the user cached with the given cache key or null if not found.

* * @param key the cache key to look for, this may be the user's uuid or the fqn * * @return the user cached with the given cache key */ public CmsUser getCachedUser(String key) { return m_cacheUser.get(key); } /** * Returns the user groups list cached with the given cache key or null if not found.

* * @param key the cache key to look for * * @return the user groups list cached with the given cache key */ public List getCachedUserGroups(String key) { return m_cacheUserGroups.get(key); } /** * Returns the user list cached with the given cache key or null if not found.

* * @param key the cache key to look for * * @return the user groups list cached with the given cache key */ public List getCachedUserList(String key) { return m_cacheUserList.get(key); } /** * Returns the vfs object cached with the given cache key or null if not found.

* * @param key the cache key to look for * * @return the vfs object cached with the given cache key */ public Object getCachedVfsObject(String key) { return m_cacheVfsObject.get(key); } /** * Returns the xml permanent entity content cached with the given systemId or null if not found.

* * @param systemId the cache key to look for * * @return the xml permanent entity content cached with the given cache key */ public byte[] getCachedXmlPermanentEntity(String systemId) { return m_cacheXmlPermanentEntity.get(systemId); } /** * Returns the xml temporary entity content cached with the given cache key or null if not found.

* * @param key the cache key to look for * * @return the xml temporary entity content cached with the given cache key */ public byte[] getCachedXmlTemporaryEntity(String key) { return m_cacheXmlTemporaryEntity.get(key); } /** * Returns the configuration.

* * @return the configuration */ public CmsMemoryMonitorConfiguration getConfiguration() { return m_configuration; } /** * Returns the next publish job from the publish job queue.

* * @return the next publish job */ public CmsPublishJobInfoBean getFirstCachedPublishJob() { synchronized (m_publishQueue) { if (!m_publishQueue.isEmpty()) { return (CmsPublishJobInfoBean)m_publishQueue.get(); } else { return null; } } } /** * Returns the log count.

* * @return the log count */ public int getLogCount() { return m_logCount; } /** * Returns the current memory status.

* * @return the memory status */ public CmsMemoryStatus getMemoryStatus() { m_memoryCurrent.update(); return m_memoryCurrent; } /** * Initializes the monitor with the provided configuration.

* * @param configuration the configuration to use */ public void initialize(CmsSystemConfiguration configuration) { CmsCacheSettings cacheSettings = configuration.getCacheSettings(); m_memoryAverage = new CmsMemoryStatus(); m_memoryCurrent = new CmsMemoryStatus(); m_warningSendSinceLastStatus = false; m_warningLoggedSinceLastStatus = false; m_lastEmailWarning = 0; m_lastEmailStatus = 0; m_lastLogStatus = 0; m_lastLogWarning = 0; m_lastClearCache = 0; m_configuration = configuration.getCmsMemoryMonitorConfiguration(); m_intervalWarning = 720 * 60000; m_maxUsagePercent = 90; m_intervalEmail = m_configuration.getEmailInterval() * 1000; m_intervalLog = m_configuration.getLogInterval() * 1000; if (m_configuration.getWarningInterval() > 0) { m_intervalWarning = m_configuration.getWarningInterval(); } m_intervalWarning *= 1000; if (m_configuration.getMaxUsagePercent() > 0) { m_maxUsagePercent = m_configuration.getMaxUsagePercent(); } if (CmsLog.INIT.isInfoEnabled()) { CmsLog.INIT.info( Messages.get().getBundle().key(Messages.LOG_MM_INTERVAL_LOG_1, new Integer(m_intervalLog / 1000))); CmsLog.INIT.info( Messages.get().getBundle().key(Messages.LOG_MM_INTERVAL_EMAIL_1, new Integer(m_intervalEmail / 1000))); CmsLog.INIT.info( Messages.get().getBundle().key( Messages.LOG_MM_INTERVAL_WARNING_1, new Integer(m_intervalWarning / 1000))); CmsLog.INIT.info( Messages.get().getBundle().key(Messages.LOG_MM_INTERVAL_MAX_USAGE_1, new Integer(m_maxUsagePercent))); if ((m_configuration.getEmailReceiver() == null) || (m_configuration.getEmailSender() == null)) { CmsLog.INIT.info(Messages.get().getBundle().key(Messages.LOG_MM_EMAIL_DISABLED_0)); } else { CmsLog.INIT.info( Messages.get().getBundle().key(Messages.LOG_MM_EMAIL_SENDER_1, m_configuration.getEmailSender())); Iterator i = m_configuration.getEmailReceiver().iterator(); int n = 0; while (i.hasNext()) { CmsLog.INIT.info( Messages.get().getBundle().key(Messages.LOG_MM_EMAIL_RECEIVER_2, new Integer(n + 1), i.next())); n++; } } } // create and register all system caches // temporary xml entities cache m_cacheXmlTemporaryEntity = createLRUCacheMap(128); register(CmsXmlEntityResolver.class.getName() + ".xmlEntityTemporaryCache", m_cacheXmlTemporaryEntity); // permanent xml entities cache m_cacheXmlPermanentEntity = new ConcurrentHashMap(32); register(CmsXmlEntityResolver.class.getName() + ".xmlEntityPermanentCache", m_cacheXmlPermanentEntity); // xml content definitions cache m_cacheContentDefinitions = createLRUCacheMap(64); register(CmsXmlEntityResolver.class.getName() + ".contentDefinitionsCache", m_cacheContentDefinitions); // lock cache m_cacheLock = new ConcurrentHashMap(); register(CmsLockManager.class.getName(), m_cacheLock); // locale cache m_cacheLocale = new ConcurrentHashMap(); register(CmsLocaleManager.class.getName(), m_cacheLocale); // permissions cache m_cachePermission = createLRUCacheMap(cacheSettings.getPermissionCacheSize()); register(CmsSecurityManager.class.getName(), m_cachePermission); // user cache m_cacheUser = createLRUCacheMap(cacheSettings.getUserCacheSize()); register(CmsDriverManager.class.getName() + ".userCache", m_cacheUser); // user list cache m_cacheUserList = createLRUCacheMap(cacheSettings.getUserCacheSize()); register(CmsDriverManager.class.getName() + ".userListCache", m_cacheUserList); // group cache m_cacheGroup = createLRUCacheMap(cacheSettings.getGroupCacheSize()); register(CmsDriverManager.class.getName() + ".groupCache", m_cacheGroup); // organizational unit cache m_cacheOrgUnit = createLRUCacheMap(cacheSettings.getOrgUnitCacheSize()); register(CmsDriverManager.class.getName() + ".orgUnitCache", m_cacheOrgUnit); // user groups list cache m_cacheUserGroups = createLRUCacheMap(cacheSettings.getUserGroupsCacheSize()); register(CmsDriverManager.class.getName() + ".userGroupsCache", m_cacheUserGroups); // project cache m_cacheProject = createLRUCacheMap(cacheSettings.getProjectCacheSize()); register(CmsDriverManager.class.getName() + ".projectCache", m_cacheProject); // project resources cache cache m_cacheProjectResources = createLRUCacheMap(cacheSettings.getProjectResourcesCacheSize()); register(CmsDriverManager.class.getName() + ".projectResourcesCache", m_cacheProjectResources); // publish history int size = configuration.getPublishManager().getPublishHistorySize(); Buffer buffer = CmsPublishHistory.getQueue(size); m_publishHistory = SynchronizedBuffer.decorate(buffer); register(CmsPublishHistory.class.getName() + ".publishHistory", buffer); // publish queue buffer = CmsPublishQueue.getQueue(); m_publishQueue = SynchronizedBuffer.decorate(buffer); register(CmsPublishQueue.class.getName() + ".publishQueue", buffer); // resource cache m_cacheResource = createLRUCacheMap(cacheSettings.getResourceCacheSize()); register(CmsDriverManager.class.getName() + ".resourceCache", m_cacheResource); // roles cache m_cacheHasRoles = createLRUCacheMap(cacheSettings.getRolesCacheSize()); register(CmsDriverManager.class.getName() + ".rolesCache", m_cacheHasRoles); // role lists cache m_cacheRoleLists = createLRUCacheMap(cacheSettings.getRolesCacheSize()); register(CmsDriverManager.class.getName() + ".roleListsCache", m_cacheRoleLists); // resource list cache m_cacheResourceList = createLRUCacheMap(cacheSettings.getResourcelistCacheSize()); register(CmsDriverManager.class.getName() + ".resourceListCache", m_cacheResourceList); // property cache m_cacheProperty = createLRUCacheMap(cacheSettings.getPropertyCacheSize()); register(CmsDriverManager.class.getName() + ".propertyCache", m_cacheProperty); // property list cache m_cachePropertyList = createLRUCacheMap(cacheSettings.getPropertyListsCacheSize()); register(CmsDriverManager.class.getName() + ".propertyListCache", m_cachePropertyList); // published resources list cache m_cachePublishedResources = createLRUCacheMap(5); register(CmsDriverManager.class.getName() + ".publishedResourcesCache", m_cachePublishedResources); // acl cache m_cacheAccessControlList = createLRUCacheMap(cacheSettings.getAclCacheSize()); register(CmsDriverManager.class.getName() + ".accessControlListCache", m_cacheAccessControlList); // vfs object cache m_cacheVfsObject = new ConcurrentHashMap(); register(CmsVfsMemoryObjectCache.class.getName(), m_cacheVfsObject); // memory object cache m_cacheMemObject = new ConcurrentHashMap(); register(CmsMemoryObjectCache.class.getName(), m_cacheMemObject); if (LOG.isDebugEnabled()) { // this will happen only once during system startup LOG.debug(Messages.get().getBundle().key(Messages.LOG_MM_CREATED_1, new Date(System.currentTimeMillis()))); } } /** * Checks if the property cache is enabled.

* * @return true if the property cache is enabled * * @deprecated use {@link #isEnabled(CacheType)} instead */ @Deprecated public boolean isCacheProperty() { return isEnabled(CacheType.PROPERTY); } /** * Checks if the property list cache is enabled.

* * @return true if the property list cache is enabled * * @deprecated use {@link #isEnabled(CacheType)} instead */ @Deprecated public boolean isCachePropertyList() { return isEnabled(CacheType.PROPERTY_LIST); } /** * Checks if the resource cache is enabled.

* * @return true if the resource cache is enabled * * @deprecated use {@link #isEnabled(CacheType)} instead */ @Deprecated public boolean isCacheResource() { return isEnabled(CacheType.RESOURCE); } /** * Checks if the resource list cache is enabled.

* * @return true if the resource list cache is enabled * * @deprecated use {@link #isEnabled(CacheType)} instead */ @Deprecated public boolean isCacheResourceList() { return isEnabled(CacheType.RESOURCE_LIST); } /** * Checks if the given cache is enabled.

* * @param type the cache type to check * * @return true if the given cache is enabled */ public boolean isEnabled(CacheType type) { return (m_disabled.get(type) == null); } /** * Checks if there is a registered monitored object with the given key.

* * @param key the key to look for * * @return true if there is a registered monitored object with the given key */ public boolean isMonitoring(String key) { return (m_monitoredObjects.get(key) != null); } /** * @see org.opencms.scheduler.I_CmsScheduledJob#launch(CmsObject, Map) */ public String launch(CmsObject cms, Map parameters) throws Exception { CmsMemoryMonitor monitor = OpenCms.getMemoryMonitor(); // make sure job is not launched twice if (m_currentlyRunning) { return null; } try { m_currentlyRunning = true; // update the memory status monitor.updateStatus(); // check if the system is in a low memory condition if (monitor.lowMemory()) { // log warning monitor.monitorWriteLog(true); // send warning email monitor.monitorSendEmail(true); // clean up caches monitor.clearCaches(); } // check if regular a log entry must be written if ((System.currentTimeMillis() - monitor.m_lastLogStatus) > monitor.m_intervalLog) { monitor.monitorWriteLog(false); } // check if the memory status email must be send if ((System.currentTimeMillis() - monitor.m_lastEmailStatus) > monitor.m_intervalEmail) { monitor.monitorSendEmail(false); } } finally { // make sure state is reset even if an error occurs, // otherwise MM will not be executed after an error m_currentlyRunning = false; } return null; } /** * Returns true if the system runs low on memory.

* * @return true if the system runs low on memory */ public boolean lowMemory() { return ((m_maxUsagePercent > 0) && (m_memoryCurrent.getUsage() > m_maxUsagePercent)); } /** * Adds a new object to the monitor.

* * @param objectName name of the object * @param object the object for monitoring */ public void register(String objectName, Object object) { if (enabled()) { m_monitoredObjects.put(objectName, object); } } /** * Checks if some kind of persistence is required.

* * This could be overwritten in a distributed environment.

* * @return true if some kind of persistence is required */ public boolean requiresPersistency() { return true; } /** * Sets if the property cache is enabled.

* * @param cacheProperty if the property cache is enabled * * @deprecated use {@link #enableCache(CacheType[])} or {@link #disableCache(CacheType[])} instead */ @Deprecated public void setCacheProperty(boolean cacheProperty) { if (cacheProperty) { enableCache(CacheType.PROPERTY); } else { disableCache(CacheType.PROPERTY); } } /** * Sets if the property list cache is enabled.

* * @param cachePropertyList if the property list cache is enabled * * @deprecated use {@link #enableCache(CacheType[])} or {@link #disableCache(CacheType[])} instead */ @Deprecated public void setCachePropertyList(boolean cachePropertyList) { if (cachePropertyList) { enableCache(CacheType.PROPERTY_LIST); } else { disableCache(CacheType.PROPERTY_LIST); } } /** * Sets if the resource cache is enabled.

* * @param cacheResource if the resource cache is enabled * * @deprecated use {@link #enableCache(CacheType[])} or {@link #disableCache(CacheType[])} instead */ @Deprecated public void setCacheResource(boolean cacheResource) { if (cacheResource) { enableCache(CacheType.RESOURCE); } else { disableCache(CacheType.RESOURCE); } } /** * Sets if the resource list cache is enabled.

* * @param cacheResourceList if the resource list cache is enabled * * @deprecated use {@link #enableCache(CacheType[])} or {@link #disableCache(CacheType[])} instead */ @Deprecated public void setCacheResourceList(boolean cacheResourceList) { if (cacheResourceList) { enableCache(CacheType.RESOURCE_LIST); } else { disableCache(CacheType.RESOURCE_LIST); } } /** * Flushes all cached objects.

* * @throws Exception if something goes wrong */ public void shutdown() throws Exception { for (CacheType type : CacheType.values()) { flushCache(type); } } /** * Removes the given xml content definition from the cache.

* * @param key the cache key to remove from cache */ public void uncacheContentDefinition(String key) { m_cacheContentDefinitions.remove(key); } /** * Removes the given group from the cache.

* * The group is removed by name AND also by uuid.

* * @param group the group to remove from cache */ public void uncacheGroup(CmsGroup group) { m_cacheGroup.remove(group.getId().toString()); m_cacheGroup.remove(group.getName()); } /** * Removes the cached lock for the given root path from the cache.

* * @param rootPath the root path of the lock to remove from cache */ public void uncacheLock(String rootPath) { m_cacheLock.remove(rootPath); } /** * Removes the given organizational unit from the cache.

* * The organizational unit is removed by name AND also by uuid.

* * @param orgUnit the organizational unit to remove from cache */ public void uncacheOrgUnit(CmsOrganizationalUnit orgUnit) { m_cacheOrgUnit.remove(orgUnit.getId().toString()); m_cacheOrgUnit.remove(orgUnit.getName()); } /** * Removes the given project from the cache.

* * The project is removed by name AND also by uuid.

* * @param project the project to remove from cache */ public void uncacheProject(CmsProject project) { m_cacheProject.remove(project.getUuid().toString()); m_cacheProject.remove(project.getName()); } /** * Removes the given publish job from the cache.

* * @param publishJob the publish job to remove */ public void uncachePublishJob(CmsPublishJobInfoBean publishJob) { m_publishQueue.remove(publishJob); } /** * Removes the given publish job from the history.

* * @param publishJob the publish job to remove */ public void uncachePublishJobInHistory(CmsPublishJobInfoBean publishJob) { m_publishHistory.remove(publishJob); } /** * Removes the given user from the cache.

* * The user is removed by name AND also by uuid.

* * @param user the user to remove from cache */ public void uncacheUser(CmsUser user) { m_cacheUser.remove(user.getId().toString()); m_cacheUser.remove(user.getName()); } /** * Removes the given vfs object from the cache.

* * @param key the cache key to remove from cache */ public void uncacheVfsObject(String key) { m_cacheVfsObject.remove(key); } /** * Removes the given xml temporary entity from the cache.

* * @param key the cache key to remove from cache */ public void uncacheXmlTemporaryEntity(String key) { m_cacheXmlTemporaryEntity.remove(key); } /** * Clears the OpenCms caches.

*/ protected void clearCaches() { if ((m_lastClearCache + INTERVAL_CLEAR) > System.currentTimeMillis()) { // if the cache has already been cleared less then 15 minutes ago we skip this because // clearing the caches to often will hurt system performance and the // setup seems to be in trouble anyway return; } m_lastClearCache = System.currentTimeMillis(); if (LOG.isWarnEnabled()) { LOG.warn(Messages.get().getBundle().key(Messages.LOG_CLEAR_CACHE_MEM_CONS_0)); } OpenCms.fireCmsEvent( new CmsEvent(I_CmsEventListener.EVENT_CLEAR_CACHES, Collections. emptyMap())); System.gc(); } /** * Returns the cache costs of a monitored object.

* * obj must be of type {@link CmsLruCache}.

* * @param obj the object * * @return the cache costs or "-" */ protected long getCosts(Object obj) { long costs = 0; if (obj instanceof CmsLruCache) { costs = ((CmsLruCache)obj).getObjectCosts(); if (costs < 0) { costs = 0; } } return costs; } /** * Returns the number of items within a monitored object.

* * obj must be of type {@link CmsLruCache} or {@link Map}.

* * @param obj the object * * @return the number of items or "-" */ protected String getItems(Object obj) { if (obj instanceof CmsLruCache) { return Integer.toString(((CmsLruCache)obj).size()); } if (obj instanceof Map) { return Integer.toString(((Map)obj).size()); } return "-"; } /** * Returns the total size of key strings within a monitored map.

* * The keys must be of type {@link String}.

* * @param map the map * @param depth the max recursion depth for calculation the size * * @return total size of key strings */ protected long getKeySize(Map map, int depth) { long keySize = 0; try { Object[] values = map.values().toArray(); for (int i = 0, s = values.length; i < s; i++) { Object obj = values[i]; if ((obj instanceof Map) && (depth < MAX_DEPTH)) { keySize += getKeySize((Map)obj, depth + 1); continue; } } values = null; Object[] keys = map.keySet().toArray(); for (int i = 0, s = keys.length; i < s; i++) { Object obj = keys[i]; if (obj instanceof String) { String st = (String)obj; keySize += (st.length() * 2); } } } catch (ConcurrentModificationException e) { // this might happen since even the .toArray() method internally creates an iterator } catch (Throwable t) { // catch all other exceptions otherwise the whole monitor will stop working if (LOG.isDebugEnabled()) { LOG.debug(Messages.get().getBundle().key(Messages.LOG_CAUGHT_THROWABLE_1, t.getMessage())); } } return keySize; } /** * Returns the total size of key strings within a monitored object.

* * obj must be of type {@link Map}, the keys must be of type {@link String}.

* * @param obj the object * * @return the total size of key strings */ protected long getKeySize(Object obj) { if (obj instanceof Map) { return getKeySize((Map)obj, 1); } return 0; } /** * Returns the max costs for all items within a monitored object.

* * obj must be of type {@link CmsLruCache} or {@link LRUMap}.

* * @param obj the object * * @return max cost limit or "-" */ protected String getLimit(Object obj) { if (obj instanceof CmsLruCache) { return Long.toString(((CmsLruCache)obj).getMaxCacheCosts()); } if (obj instanceof LRUMap) { return Integer.toString(((LRUMap)obj).maxSize()); } return "-"; } /** * Sends a warning or status email with OpenCms Memory information.

* * @param warning if true, send a memory warning email */ protected void monitorSendEmail(boolean warning) { if ((m_configuration.getEmailSender() == null) || (m_configuration.getEmailReceiver() == null)) { // send no mails if not fully configured return; } else if (warning && (m_warningSendSinceLastStatus && !((m_intervalEmail <= 0) && (System.currentTimeMillis() < (m_lastEmailWarning + m_intervalWarning))))) { // send no warning email if no status email has been send since the last warning // if status is disabled, send no warn email if warn interval has not passed return; } else if ((!warning) && (m_intervalEmail <= 0)) { // if email iterval is <= 0 status email is disabled return; } String date = CmsDateUtil.getDateTimeShort(System.currentTimeMillis()); String subject; String content = ""; if (warning) { m_warningSendSinceLastStatus = true; m_lastEmailWarning = System.currentTimeMillis(); subject = "OpenCms Memory W A R N I N G [" + OpenCms.getSystemInfo().getServerName().toUpperCase() + "/" + date + "]"; content += "W A R N I N G !\nOpenCms memory consumption on server " + OpenCms.getSystemInfo().getServerName().toUpperCase() + " has reached a critical level !\n\n" + "The configured limit is " + m_maxUsagePercent + "%\n\n"; } else { m_warningSendSinceLastStatus = false; m_lastEmailStatus = System.currentTimeMillis(); subject = "OpenCms Memory Status [" + OpenCms.getSystemInfo().getServerName().toUpperCase() + "/" + date + "]"; } content += "Memory usage report of OpenCms server " + OpenCms.getSystemInfo().getServerName().toUpperCase() + " at " + date + "\n\n" + "Memory maximum heap size: " + m_memoryCurrent.getMaxMemory() + " mb\n" + "Memory current heap size: " + m_memoryCurrent.getTotalMemory() + " mb\n\n" + "Memory currently used : " + m_memoryCurrent.getUsedMemory() + " mb (" + m_memoryCurrent.getUsage() + "%)\n" + "Memory currently unused : " + m_memoryCurrent.getFreeMemory() + " mb\n\n\n"; if (warning) { content += "*** Please take action NOW to ensure that no OutOfMemoryException occurs.\n\n\n"; } CmsSessionManager sm = OpenCms.getSessionManager(); if (sm != null) { content += "Current status of the sessions:\n\n"; content += "Logged in users : " + sm.getSessionCountAuthenticated() + "\n"; content += "Currently active sessions: " + sm.getSessionCountCurrent() + "\n"; content += "Total created sessions : " + sm.getSessionCountTotal() + "\n\n\n"; } sm = null; content += "Current status of the caches:\n\n"; List keyList = new ArrayList(m_monitoredObjects.keySet()); Collections.sort(keyList); long totalSize = 0; for (Iterator keys = keyList.iterator(); keys.hasNext();) { String key = keys.next(); String[] shortKeys = key.split("\\."); String shortKey = shortKeys[shortKeys.length - 2] + '.' + shortKeys[shortKeys.length - 1]; PrintfFormat form = new PrintfFormat("%9s"); Object obj = m_monitoredObjects.get(key); long size = getKeySize(obj) + getValueSize(obj) + getCosts(obj); totalSize += size; content += new PrintfFormat("%-42.42s").sprintf(shortKey) + " " + "Entries: " + form.sprintf(getItems(obj)) + " " + "Limit: " + form.sprintf(getLimit(obj)) + " " + "Size: " + form.sprintf(Long.toString(size)) + "\n"; } content += "\nTotal size of cache memory monitored: " + totalSize + " (" + (totalSize / 1048576) + ")\n\n"; String from = m_configuration.getEmailSender(); List receivers = new ArrayList(); List receiverEmails = m_configuration.getEmailReceiver(); try { if ((from != null) && (receiverEmails != null) && !receiverEmails.isEmpty()) { Iterator i = receiverEmails.iterator(); while (i.hasNext()) { receivers.add(new InternetAddress(i.next())); } CmsSimpleMail email = new CmsSimpleMail(); email.setFrom(from); email.setTo(receivers); email.setSubject(subject); email.setMsg(content); new CmsMailTransport(email).send(); } if (LOG.isInfoEnabled()) { if (warning) { LOG.info(Messages.get().getBundle().key(Messages.LOG_MM_WARNING_EMAIL_SENT_0)); } else { LOG.info(Messages.get().getBundle().key(Messages.LOG_MM_STATUS_EMAIL_SENT_0)); } } } catch (Exception e) { e.printStackTrace(); } } /** * Write a warning or status log entry with OpenCms Memory information.

* * @param warning if true, write a memory warning log entry */ protected void monitorWriteLog(boolean warning) { if (!LOG.isWarnEnabled()) { // we need at last warn level for this output return; } else if ((!warning) && (!LOG.isInfoEnabled())) { // if not warning we need info level return; } else if (warning && (m_warningLoggedSinceLastStatus && !(((m_intervalLog <= 0) && (System.currentTimeMillis() < (m_lastLogWarning + m_intervalWarning)))))) { // write no warning log if no status log has been written since the last warning // if status is disabled, log no warn entry if warn interval has not passed return; } else if ((!warning) && (m_intervalLog <= 0)) { // if log interval is <= 0 status log is disabled return; } if (warning) { m_lastLogWarning = System.currentTimeMillis(); m_warningLoggedSinceLastStatus = true; LOG.warn( Messages.get().getBundle().key( Messages.LOG_MM_WARNING_MEM_CONSUME_2, new Long(m_memoryCurrent.getUsage()), new Integer(m_maxUsagePercent))); } else { m_warningLoggedSinceLastStatus = false; m_lastLogStatus = System.currentTimeMillis(); } if (warning) { LOG.warn( Messages.get().getBundle().key( Messages.LOG_MM_WARNING_MEM_STATUS_6, new Object[] { new Long(m_memoryCurrent.getMaxMemory()), new Long(m_memoryCurrent.getTotalMemory()), new Long(m_memoryCurrent.getFreeMemory()), new Long(m_memoryCurrent.getUsedMemory()), new Long(m_memoryCurrent.getUsage()), new Integer(m_maxUsagePercent)})); } else { m_logCount++; LOG.info( Messages.get().getBundle().key( Messages.LOG_MM_LOG_INFO_2, OpenCms.getSystemInfo().getServerName().toUpperCase(), String.valueOf(m_logCount))); List keyList = new ArrayList(m_monitoredObjects.keySet()); Collections.sort(keyList); long totalSize = 0; for (Iterator keys = keyList.iterator(); keys.hasNext();) { String key = keys.next(); Object obj = m_monitoredObjects.get(key); long size = getKeySize(obj) + getValueSize(obj) + getCosts(obj); totalSize += size; PrintfFormat name1 = new PrintfFormat("%-80s"); PrintfFormat name2 = new PrintfFormat("%-50s"); PrintfFormat form = new PrintfFormat("%9s"); LOG.info( Messages.get().getBundle().key( Messages.LOG_MM_NOWARN_STATUS_5, new Object[] { name1.sprintf(key), name2.sprintf(obj.getClass().getName()), form.sprintf(getItems(obj)), form.sprintf(getLimit(obj)), form.sprintf(Long.toString(size))})); } LOG.info( Messages.get().getBundle().key( Messages.LOG_MM_WARNING_MEM_STATUS_6, new Object[] { new Long(m_memoryCurrent.getMaxMemory()), new Long(m_memoryCurrent.getTotalMemory()), new Long(m_memoryCurrent.getFreeMemory()), new Long(m_memoryCurrent.getUsedMemory()), new Long(m_memoryCurrent.getUsage()), new Integer(m_maxUsagePercent), new Long(totalSize), new Long(totalSize / 1048576)}) ); LOG.info( Messages.get().getBundle().key( Messages.LOG_MM_WARNING_MEM_STATUS_AVG_6, new Object[] { new Long(m_memoryAverage.getMaxMemory()), new Long(m_memoryAverage.getTotalMemory()), new Long(m_memoryAverage.getFreeMemory()), new Long(m_memoryAverage.getUsedMemory()), new Long(m_memoryAverage.getUsage()), new Integer(m_memoryAverage.getCount())})); CmsSessionManager sm = OpenCms.getSessionManager(); if (sm != null) { LOG.info( Messages.get().getBundle().key( Messages.LOG_MM_SESSION_STAT_3, String.valueOf(sm.getSessionCountAuthenticated()), String.valueOf(sm.getSessionCountCurrent()), String.valueOf(sm.getSessionCountTotal()))); } sm = null; for (Iterator i = OpenCms.getSqlManager().getDbPoolUrls().iterator(); i.hasNext();) { String poolname = i.next(); try { LOG.info( Messages.get().getBundle().key( Messages.LOG_MM_CONNECTIONS_3, poolname, Integer.toString(OpenCms.getSqlManager().getActiveConnections(poolname)), Integer.toString(OpenCms.getSqlManager().getIdleConnections(poolname)))); } catch (Exception exc) { LOG.info( Messages.get().getBundle().key( Messages.LOG_MM_CONNECTIONS_3, poolname, Integer.toString(-1), Integer.toString(-1))); } } LOG.info( Messages.get().getBundle().key( Messages.LOG_MM_STARTUP_TIME_2, CmsDateUtil.getDateTimeShort(OpenCms.getSystemInfo().getStartupTime()), CmsStringUtil.formatRuntime(OpenCms.getSystemInfo().getRuntime()))); } } /** * Updates the memory information of the memory monitor.

*/ protected void updateStatus() { m_memoryCurrent.update(); m_memoryAverage.calculateAverage(m_memoryCurrent); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy