diff options
author | Andrew M. Finkbeiner | 2017-04-04 16:40:14 +0000 |
---|---|---|
committer | Michael P. Masterson | 2018-06-04 18:14:11 +0000 |
commit | f0822d2eb3119e7adfeb887df55546596f8d27c1 (patch) | |
tree | a472dba5f1e492cec22364e99b8f4ad47f8a1cca | |
parent | b25a50c41e8e2e924696649d60a741cdaba8c189 (diff) | |
download | org.eclipse.ote-f0822d2eb3119e7adfeb887df55546596f8d27c1.tar.gz org.eclipse.ote-f0822d2eb3119e7adfeb887df55546596f8d27c1.tar.xz org.eclipse.ote-f0822d2eb3119e7adfeb887df55546596f8d27c1.zip |
feature[ats_ATS331083]: Add a GC listener to the test serverOTE_06_21_2018sprint127ote_0.25_temp
Change-Id: I7fd7e93c2bcb3c89b884f1b71e4382759c7a669a
6 files changed, 291 insertions, 0 deletions
diff --git a/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/environment/interfaces/ITestLogger.java b/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/environment/interfaces/ITestLogger.java index 0aad8b0d0..0f0976005 100644 --- a/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/environment/interfaces/ITestLogger.java +++ b/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/environment/interfaces/ITestLogger.java @@ -32,6 +32,8 @@ public interface ITestLogger { public void log(TestRecord record); public void log(Level level, String message, Throwable th); + + public void log(ITestEnvironmentAccessor source, Level level, String message, Throwable th); public void methodCalled(ITestEnvironmentAccessor source); diff --git a/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/framework/testrun/BaseTestRunManager.java b/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/framework/testrun/BaseTestRunManager.java index c56762995..17af221cc 100644 --- a/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/framework/testrun/BaseTestRunManager.java +++ b/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/framework/testrun/BaseTestRunManager.java @@ -21,6 +21,7 @@ import org.eclipse.osee.ote.core.framework.IMethodResult; import org.eclipse.osee.ote.core.framework.MethodResultImpl; import org.eclipse.osee.ote.core.framework.ReturnCode; import org.eclipse.osee.ote.core.internal.Activator; +import org.eclipse.osee.ote.core.log.GCHelper; public class BaseTestRunManager implements ITestRunManager { @@ -61,6 +62,7 @@ public class BaseTestRunManager implements ITestRunManager { return result; } try { + GCHelper.enable(true); testRunThread = new TestRunThread(propertyStore, test, environment, listenerProvider, dataProvider); testRunThread.start(); testRunThread.join(); @@ -71,6 +73,7 @@ public class BaseTestRunManager implements ITestRunManager { result = methodresult; OseeLog.log(Activator.class, Level.SEVERE, ex); } finally { + GCHelper.enable(false); aborted = false; testRunThread = null; } diff --git a/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/internal/Activator.java b/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/internal/Activator.java index b9b19b357..7e98b4e1d 100644 --- a/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/internal/Activator.java +++ b/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/internal/Activator.java @@ -22,6 +22,7 @@ import org.eclipse.osee.ote.core.environment.TestEnvironment; import org.eclipse.osee.ote.core.environment.TestEnvironmentInterface; import org.eclipse.osee.ote.core.environment.console.ConsoleCommandManager; import org.eclipse.osee.ote.core.environment.console.ICommandManager; +import org.eclipse.osee.ote.core.log.GCHelper; import org.eclipse.osee.ote.message.internal.MessageIoManagementStarter; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; @@ -50,6 +51,7 @@ public class Activator implements BundleActivator { @Override public void start(BundleContext context) throws Exception { activator = this; + GCHelper.installGCMonitoring(); bundleContext = context; consoleCommandManager = new ConsoleCommandManager(); if (OteProperties.isOteCmdConsoleEnabled()) { diff --git a/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/log/GCHelper.java b/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/log/GCHelper.java new file mode 100644 index 000000000..701ef4e22 --- /dev/null +++ b/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/log/GCHelper.java @@ -0,0 +1,221 @@ +package org.eclipse.osee.ote.core.log; + +import java.lang.management.GarbageCollectorMXBean; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; + +import javax.management.Notification; +import javax.management.NotificationEmitter; +import javax.management.NotificationListener; +import javax.management.openmbean.CompositeDataSupport; +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.TabularDataSupport; +import javax.management.openmbean.TabularType; + +import org.eclipse.osee.framework.logging.OseeLog; +public class GCHelper { + + private static final String installGCMonitoring = System.getProperty("org.eclipse.osee.ote.gcmonitor", "true"); + + + private static volatile boolean enableLog = false; + + public static void enable(boolean enable){ + enableLog = enable; + } + + public static void installGCMonitoring(){ + if(Boolean.parseBoolean(installGCMonitoring)){ + List<GarbageCollectorMXBean> gcbeans = java.lang.management.ManagementFactory.getGarbageCollectorMXBeans(); + for (GarbageCollectorMXBean gcbean : gcbeans) { + NotificationEmitter emitter = (NotificationEmitter) gcbean; + NotificationListener listener = new GCListener(); + emitter.addNotificationListener(listener, null, null); + } + } + } + + private static class GCListener implements NotificationListener { + + private GCNotification gcData; + + public void printCompositeDataSupport(Object obj, int level){ + if(obj instanceof CompositeDataSupport){ + CompositeDataSupport dataSupport = (CompositeDataSupport)obj; + CompositeType type = dataSupport.getCompositeType(); + for(String key : type.keySet()){ + Object value = dataSupport.get(key); + if(value instanceof CompositeDataSupport || value instanceof TabularDataSupport){ + printCompositeDataSupport(value, level + 1); + } else { + if(!populateCompositeData(key, type, value)){ + for(int i = 0; i < level; i++){ + System.out.print(" "); + } + System.out.printf("key[%s] desc[%s] value[%s] class[%s]\n", key , type.getDescription(key), value, value.getClass().getName()); + } + } + } + } else if (obj instanceof TabularDataSupport){ + TabularDataSupport dataSupport = (TabularDataSupport)obj; + TabularType type = dataSupport.getTabularType(); + for(Object value : dataSupport.values()){ + if(value instanceof CompositeDataSupport || value instanceof TabularDataSupport){ + printCompositeDataSupport(value, level + 1); + } else { + System.out.println("nope"); + } + } + } + else { + if(!populateGenericValue(obj)){ + for(int i = 0; i < level; i++){ + System.out.print(" "); + } + System.out.printf("valud[%s] class[%s]\n", obj, obj.getClass().getName()); + } + } + } + + private boolean populateCompositeData(String key, CompositeType type, Object value) { + if(key.equals("GcThreadCount")){ + gcData.threadCount = (Integer)value; + return true; + } else if (key.equals("duration")){ + gcData.duration = (Long)value; + return true; + } else if (key.equals("endTime")){ + gcData.endtime = (Long)value; + return true; + } else if (key.equals("startTime")){ + gcData.startTime = (Long)value; + return true; + } else if (key.equals("id")){ + //ignore + return true; + } else if (key.equals("key")){ + gcData.currentGcMemory = new GCMemory(); + gcData.currentGcMemory.memType = GCMemory.getType(value); + if(gcData.currentGcMemory.memType == GCMemory.type.unknown){ + System.out.printf("unknown mem type [%s]\n", value); + } + gcData.memory.add(gcData.currentGcMemory); + return true; + } else if (key.equals("committed")){ + gcData.currentGcMemory.committed = (Long)value; + return true; + }else if (key.equals("init")){ + gcData.currentGcMemory.init = (Long)value; + return true; + }else if (key.equals("max")){ + gcData.currentGcMemory.max = (Long)value; + return true; + }else if (key.equals("used")){ + gcData.currentGcMemory.used = (Long)value; + return true; + } + return false; + } + + private boolean populateGenericValue(Object obj) { + if(obj.toString().equals("end of minor GC")){ + gcData.isMinor = true; + return true; + } else if(obj.toString().equals("end of major GC")){ + gcData.isMajor = true; + return true; + } else if (obj.toString().equals("System.gc()") || obj.toString().equals("Metadata GC Threshold") || obj.toString().equals("Allocation Failure") || + obj.toString().equals("PS Scavenge") || obj.toString().equals("PS MarkSweep") || obj.toString().equals("ParNew") || obj.toString().equals("GCLocker Initiated GC")){ + if(gcData.reason == null){ + gcData.reason = obj.toString(); + } else { + gcData.reason = gcData.reason +", " + obj.toString(); + } + return true; + } + return false; + } + + //implement the notifier callback handler + @Override + public void handleNotification(Notification notification, Object handback) { + if(enableLog){ + gcData = new GCNotification(); + Object userData = notification.getUserData(); + if(userData instanceof CompositeDataSupport){ + CompositeDataSupport dataSupport = (CompositeDataSupport)userData; + for(Object obj :dataSupport.values()){ + printCompositeDataSupport(obj, 0); + } + + } else { + System.out.printf("%s - %s\n", userData.getClass().getName(), userData); + } + OseeLog.log(GCHelper.class, Level.INFO, gcData.toString()); + } + } + } + + public static class GCNotification { + + public String reason; + public Long startTime; + public GCMemory currentGcMemory; + + enum gcType { psScavenge, psMarkSweep; } + + private gcType type; + private boolean isMajor = false; + private boolean isMinor = false; + private int threadCount; + private long duration; + private long endtime; + private long id; + + private List<GCMemory> memory; + + public GCNotification(){ + memory = new ArrayList<GCHelper.GCMemory>(); + currentGcMemory = new GCMemory(); + } + + public String toString(){ + return String.format("GC %s - %s - elapsedTime[%d]", (isMajor ? "major" : "minor"), reason, duration); + } + } + + public static class GCMemory { + enum type { compressedClassSpace, psSurvivorSpace, parSurvivorSpace, psOldGen, parOldGen, psEdenSpace, parEdenSpace, Metaspace, CodeCache, unknown; } + + private type memType; + private long committed; + private long init; + private long max; + private long used; + + public static org.eclipse.osee.ote.core.log.GCHelper.GCMemory.type getType(Object value) { + if(value.equals("Compressed Class Space")){ + return type.compressedClassSpace; + } else if (value.equals("PS Survivor Space")){ + return type.psSurvivorSpace; + } else if (value.equals("PS Old Gen")){ + return type.psOldGen; + } else if (value.equals("Metaspace")){ + return type.Metaspace; + } else if (value.equals("PS Eden Space")){ + return type.psEdenSpace; + } else if (value.equals("Code Cache")){ + return type.CodeCache; + } else if (value.equals("Par Survivor Space")){ + return type.parSurvivorSpace; + } else if (value.equals("CMS Old Gen")){ + return type.parOldGen; + } else if (value.equals("Par Eden Space")){ + return type.parEdenSpace; + } + return type.unknown; + } + } + +} diff --git a/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/log/TestLogger.java b/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/log/TestLogger.java index 6aa213148..2cf1f2d6f 100644 --- a/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/log/TestLogger.java +++ b/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/log/TestLogger.java @@ -13,6 +13,7 @@ package org.eclipse.osee.ote.core.log; import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; + import org.eclipse.osee.framework.jdk.core.persistence.Xmlizable; import org.eclipse.osee.framework.jdk.core.persistence.XmlizableStream; import org.eclipse.osee.ote.core.MethodFormatter; @@ -24,6 +25,7 @@ import org.eclipse.osee.ote.core.environment.interfaces.ITestLogger; import org.eclipse.osee.ote.core.environment.interfaces.ITestPoint; import org.eclipse.osee.ote.core.log.record.AttentionRecord; import org.eclipse.osee.ote.core.log.record.DebugRecord; +import org.eclipse.osee.ote.core.log.record.InfoRecord; import org.eclipse.osee.ote.core.log.record.RequirementRecord; import org.eclipse.osee.ote.core.log.record.SevereRecord; import org.eclipse.osee.ote.core.log.record.SupportRecord; @@ -297,4 +299,25 @@ public class TestLogger extends Logger implements ITestLogger { } log(record); } + + @Override + public void log(ITestEnvironmentAccessor source, Level level, String message, Throwable th) { + if(level.intValue() >= Level.SEVERE.intValue()){ + SevereRecord severe = new SevereRecord(source, message, true); + severe.setThrown(th); + this.log(severe); + } else if (level.intValue() >= Level.WARNING.intValue()){ + WarningRecord warn = new WarningRecord(source, message, true); + warn.setThrown(th); + this.log(warn); + } else if (level.intValue() >= Level.INFO.intValue()){ + InfoRecord info = new InfoRecord(source, message, true); + info.setThrown(th); + this.log(info); + } else { + this.log(level, message, th); + } + } + + }
\ No newline at end of file diff --git a/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/log/record/InfoRecord.java b/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/log/record/InfoRecord.java new file mode 100644 index 000000000..7c6ed0d9d --- /dev/null +++ b/org.eclipse.osee.ote.core/src/org/eclipse/osee/ote/core/log/record/InfoRecord.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2004, 2007 Boeing. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.ote.core.log.record; + +import java.util.logging.Level; +import org.eclipse.osee.ote.core.environment.interfaces.ITestEnvironmentAccessor; + +public class InfoRecord extends TestRecord { + + private static final long serialVersionUID = -3124953320400273382L; + + /** + * InfoRecord Constructor. Sets up a Warning log message. + * + * @param source The object requesting the logging. + * @param msg The log message. + * @param timeStamp <b>True </b> if a timestamp should be recorded, <b>False </b> if not. + */ + public InfoRecord(ITestEnvironmentAccessor source, String msg, boolean timeStamp) { + super(source, Level.INFO, msg, timeStamp); + } + + /** + * InfoRecord Constructor. Sets up a Warning log message. + * + * @param source The object requesting the logging. + * @param msg The log message. + */ + public InfoRecord(ITestEnvironmentAccessor source, String msg) { + this(source, msg, true); + } +}
\ No newline at end of file |