Skip to content

Instantly share code, notes, and snippets.

@ern
Created April 6, 2016 14:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ern/cb939c9b92f5bb20baf0371c78a7ecfa to your computer and use it in GitHub Desktop.
Save ern/cb939c9b92f5bb20baf0371c78a7ecfa to your computer and use it in GitHub Desktop.
Estimates the size of attributes in the session
diff --git a/kernel/kernel-impl/pom.xml b/kernel/kernel-impl/pom.xml
index f5e5a64..b0b1d65 100644
--- a/kernel/kernel-impl/pom.xml
+++ b/kernel/kernel-impl/pom.xml
@@ -312,6 +312,11 @@
<scope>compile</scope>
</dependency>
-->
+ <dependency>
+ <groupId>com.carrotsearch</groupId>
+ <artifactId>java-sizeof</artifactId>
+ <version>0.0.5</version>
+ </dependency>
<!-- TESTING -->
<dependency>
<groupId>org.subethamail</groupId>
diff --git a/kernel/kernel-impl/src/main/java/org/sakaiproject/tool/impl/MyLittleSession.java b/kernel/kernel-impl/src/main/java/org/sakaiproject/tool/impl/MyLittleSession.java
index 786a771..f497d05 100644
--- a/kernel/kernel-impl/src/main/java/org/sakaiproject/tool/impl/MyLittleSession.java
+++ b/kernel/kernel-impl/src/main/java/org/sakaiproject/tool/impl/MyLittleSession.java
@@ -21,10 +21,17 @@
package org.sakaiproject.tool.impl;
import org.apache.commons.collections.iterators.IteratorChain;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.sakaiproject.component.cover.ServerConfigurationService;
import org.sakaiproject.thread_local.api.ThreadLocalManager;
import org.sakaiproject.tool.api.*;
import org.sakaiproject.util.IteratorEnumeration;
+import com.carrotsearch.sizeof.ObjectTree;
+import com.carrotsearch.sizeof.RamUsageEstimator;
+
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
@@ -33,6 +40,7 @@ import javax.servlet.http.HttpSessionContext;
import java.io.Serializable;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Pattern;
/**********************************************************************************************************************************************************************************************************************************************************
* Entity: ToolSession, ContextSession (and even HttpSession)
@@ -162,6 +170,8 @@ public class MyLittleSession implements ToolSession, ContextSession, HttpSession
TERRACOTTA_CLUSTER = "true".equals(clusterTerracotta);
}
+ private static Log LOG = LogFactory.getLog(MyLittleSession.class);
+
/**
* @inheritDoc
*/
@@ -295,6 +305,37 @@ public class MyLittleSession implements ToolSession, ContextSession, HttpSession
else
{
+ if (LOG.isTraceEnabled()) {
+ // DO NOT USE this in a production system as calculating object sizes is very
+ // CPU intensive and is for debugging only. YOU HAVE BEEN WARNED.
+ String regex = ServerConfigurationService.getString("sizeof.session.tool.attributes.regex");
+ if (StringUtils.isBlank(regex)) {
+ // set a default value of everything
+ regex = ".*";
+ }
+
+ if (Pattern.matches(regex, name)) {
+ try {
+ long size = RamUsageEstimator.sizeOf(value);
+ StringBuilder msg = new StringBuilder("sizeOf [toolSession=>attribute]:[");
+ msg.append(this.m_littleId + "=>" + name + "] size is " + RamUsageEstimator.humanReadableUnits(size));
+ if (Pattern.matches(".*\\|dumpObjectTree$", regex)) {
+ // to get a dump of the object tree append dumpObjectTree to your regex
+ // .*|dumpObjectTree, also don't dump anything over 1MB
+ if (size <= 1048576 ) {
+ msg.append(", dumping object tree:\n");
+ msg.append(ObjectTree.dump(value));
+ } else {
+ msg.append(", object is over 1MB skipping dump\n");
+ }
+ }
+ LOG.trace(msg);
+ } catch(Exception e) {
+ LOG.error("sizeOf could not calculate the size of [toolSession=>attribute: " + this.m_id + "=>" + name + "]", e);
+ }
+ }
+ }
+
Object old = null;
// If this is not a terracotta clustered environment then immediately
diff --git a/kernel/kernel-impl/src/main/java/org/sakaiproject/tool/impl/MySession.java b/kernel/kernel-impl/src/main/java/org/sakaiproject/tool/impl/MySession.java
index 3f33099..2db947d 100644
--- a/kernel/kernel-impl/src/main/java/org/sakaiproject/tool/impl/MySession.java
+++ b/kernel/kernel-impl/src/main/java/org/sakaiproject/tool/impl/MySession.java
@@ -22,7 +22,11 @@
package org.sakaiproject.tool.impl;
import org.apache.commons.collections.iterators.IteratorChain;
+import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.mutable.MutableLong;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.sakaiproject.component.cover.ServerConfigurationService;
import org.sakaiproject.event.api.UsageSession;
import org.sakaiproject.id.api.IdManager;
import org.sakaiproject.thread_local.api.ThreadLocalManager;
@@ -31,12 +35,16 @@ import org.sakaiproject.util.IteratorEnumeration;
import org.sakaiproject.util.RequestFilter;
import org.sakaiproject.util.ResourceLoader;
+import com.carrotsearch.sizeof.ObjectTree;
+import com.carrotsearch.sizeof.RamUsageEstimator;
+
import javax.servlet.ServletContext;
import javax.servlet.http.*;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Pattern;
/*************************************************************************************************************************************************
@@ -147,6 +155,7 @@ public class MySession implements Session, HttpSession, Serializable
TERRACOTTA_CLUSTER = "true".equals(clusterTerracotta);
}
+ private static Log LOG = LogFactory.getLog(MySession.class);
/**
* @inheritDoc
*/
@@ -511,6 +520,37 @@ public class MySession implements Session, HttpSession, Serializable
else
{
+ if (LOG.isTraceEnabled()) {
+ // DO NOT USE this in a production system as calculating object sizes is very
+ // CPU intensive and is for debugging only. YOU HAVE BEEN WARNED.
+ String regex = ServerConfigurationService.getString("sizeof.session.attributes.regex");
+ if (StringUtils.isBlank(regex)) {
+ // set a default value of everything
+ regex = ".*";
+ }
+
+ if (Pattern.matches(regex, name)) {
+ try {
+ long size = RamUsageEstimator.sizeOf(value);
+ StringBuilder msg = new StringBuilder("sizeOf [session=>attribute]:[");
+ msg.append(this.m_id + "=>" + name + "] size is " + RamUsageEstimator.humanReadableUnits(size));
+ if (Pattern.matches(".*\\|dumpObjectTree$", regex)) {
+ // to get a dump of the object tree append dumpObjectTree to your regex
+ // .*|dumpObjectTree, also don't dump anything over 1MB
+ if (size <= 1048576) {
+ msg.append(", dumping object tree:\n");
+ msg.append(ObjectTree.dump(value));
+ } else {
+ msg.append(", object is over 1MB skipping dump\n");
+ }
+ }
+ LOG.trace(msg);
+ } catch(Exception e) {
+ LOG.error("sizeOf could not calculate the size of [session=>attribute: " + this.m_id + "=>" + name + "]", e);
+ }
+ }
+ }
+
Object old = null;
// If this is not a terracotta clustered environment then immediately
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment