Java tutorial
/** This file is part of the Zeidon Java Object Engine (Zeidon JOE). Zeidon JOE 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 3 of the License, or (at your option) any later version. Zeidon JOE 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. You should have received a copy of the GNU Lesser General Public License along with Zeidon JOE. If not, see <http://www.gnu.org/licenses/>. Copyright 2009-2015 QuinSoft */ package com.quinsoft.zeidon.jmx; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Properties; import java.util.concurrent.ConcurrentMap; import org.apache.commons.lang3.StringUtils; import org.joda.time.DateTime; import com.google.common.collect.MapMaker; import com.quinsoft.zeidon.Application; import com.quinsoft.zeidon.ObjectEngine; import com.quinsoft.zeidon.ObjectEngineEventListener; import com.quinsoft.zeidon.Task; import com.quinsoft.zeidon.View; import com.quinsoft.zeidon.ZeidonLogger; import com.quinsoft.zeidon.objectdefinition.LodDef; import com.quinsoft.zeidon.standardoe.JavaOeConfiguration; import com.quinsoft.zeidon.utils.JoeUtils; /** * An instance of an ObjectEngineEventListener that creates a JMX bean that can * be queried through JMX (e.g. jconsole). The OE can then be partly managed through * the bean. * * @author dg * */ public class JmxObjectEngineMonitor implements JmxObjectEngineMonitorMBean, ObjectEngineEventListener { private ObjectEngine oe; private final ConcurrentMap<String, EventInfo> eventInfo = new MapMaker().concurrencyLevel(10).makeMap(); /** */ public JmxObjectEngineMonitor(JavaOeConfiguration config) { if (!StringUtils.isBlank(config.getJmxAppName())) JoeUtils.RegisterJmxBean(this, "com.quinsoft.zeidon:type=ObjectEngine", config.getJmxAppName()); } public JmxObjectEngineMonitor(String jmxName) { JoeUtils.RegisterJmxBean(this, jmxName, null); } /* (non-Javadoc) * @see com.quinsoft.zeidon.jmx.ObjectEngineMonitorMBean#getViewList() */ @Override public Collection<Map<String, String>> getViewList() { ArrayList<Map<String, String>> list = new ArrayList<Map<String, String>>(); if (oe == null) return list; for (Task task : oe.getTaskList()) { if (!task.isValid()) continue; for (View v : task.getViewList()) { for (String name : task.getViewNameList(v)) { HashMap<String, String> map = new HashMap<String, String>(); list.add(map); map.put("taskId", task.getTaskId()); map.put("application", v.getApplication().getName()); map.put("lodDef", v.getLodDef().getName()); map.put("name", name); map.put("oiId", Long.toString(v.getOiId())); } } } return list; } /* (non-Javadoc) * @see com.quinsoft.zeidon.jmx.ObjectEngineMonitorMBean#dropViewByName(java.lang.String, java.lang.String) */ @Override public String dropViewByName(String taskId, String viewName) { if (oe == null) return "ObjectEngine not specified"; Task task = oe.getTaskById(taskId); if (task == null) return "Unknown TaskId"; View v = task.getViewByName(viewName); if (v == null) return "Unknown viewname for task"; v.dropNameForView(viewName); return "View name dropped"; } /* (non-Javadoc) * @see com.quinsoft.zeidon.ObjectEngineEventListener#setObjectEngine(com.quinsoft.zeidon.ObjectEngine) */ @Override public void setObjectEngine(ObjectEngine oe) { this.oe = oe; } /* (non-Javadoc) * @see com.quinsoft.zeidon.jmx.ObjectEngineMonitorMBean#getRuntimeProperties() */ @Override public Properties getRuntimeProperties() { Properties properties = new Properties(); // Add activate information. for (String key : eventInfo.keySet()) { EventInfo info = eventInfo.get(key); synchronized (info) // To keep other threads from changing times and counts. { if (info.activates > 0) { properties.put(String.format("%s activates", key), info.activates); double average = info.totalActivateTime / 1000.0 / info.activates; properties.put(String.format("%s activate average", key), String.format("%1.4f", average)); if (info.activateErrors > 0) properties.put(String.format("%s activate errors", key), info.activateErrors); } if (info.commits > 0) { properties.put(String.format("%s commits\n", key), info.commits); double average = info.totalCommitTime / 1000.0 / info.commits; properties.put(String.format("%s commit average", key), String.format("%1.4f", average)); if (info.commitErrors > 0) properties.put(String.format("%s commit errors", key), info.commitErrors); } } } ZeidonLogger logger = oe.getSystemTask().log(); for (Object key : properties.keySet()) { Object value = properties.get(key); logger.info("%s %s", key, value); } return properties; } private EventInfo getEventInfo(String key) { EventInfo info = eventInfo.get(key); if (info == null) { info = new EventInfo(); eventInfo.putIfAbsent(key, info); info = eventInfo.get(key); } return info; } private EventInfo getEventInfo(View view) { LodDef lodDef = view.getLodDef(); EventInfo info = getEventInfo(lodDef.toString()); if (info.lodDef == null) info.lodDef = lodDef; return info; } private EventInfo getEventInfo(Application app) { EventInfo info = getEventInfo(app.toString()); return info; } /* (non-Javadoc) * @see com.quinsoft.zeidon.ObjectEngineEventListener#objectInstanceActivated(com.quinsoft.zeidon.View, long) */ @Override public void objectInstanceActivated(View view, View qualification, long millis, Exception exception) { try { EventInfo info = getEventInfo(view); info.incrementActivate(millis, exception); info = getEventInfo(view.getApplication()); info.incrementActivate(millis, exception); } catch (Exception e) { oe.getSystemTask().log().error(e); } } /* (non-Javadoc) * @see com.quinsoft.zeidon.ObjectEngineEventListener#objectInstanceCommitted(com.quinsoft.zeidon.View, long) */ @Override public void objectInstanceCommitted(Collection<View> viewList, long millis, Exception exception) { try { for (View view : viewList) { if (view == null) continue; EventInfo info = getEventInfo(view); info.incrementCommit(millis, exception); info = getEventInfo(view.getApplication()); info.incrementCommit(millis, exception); } } catch (Exception e) { oe.getSystemTask().log().error(e); } } private class EventInfo { LodDef lodDef; long totalActivateTime = 0; long activates = 0; long totalCommitTime = 0; long commits = 0; long activateErrors = 0; long commitErrors = 0; private synchronized void incrementActivate(long millis, Exception e) { totalActivateTime += millis; activates++; if (e != null) activateErrors++; } private synchronized void incrementCommit(long millis, Exception e) { totalCommitTime += millis; commits++; if (e != null) commitErrors++; } } @Override public Collection<String> getTaskList() { ArrayList<String> taskList = new ArrayList<String>(); for (Task task : oe.getTaskList()) taskList.add(task.getTaskId() + "," + task.getApplication().getName()); return taskList; } @Override public String logViews(String taskId) { if (oe == null) return "ObjectEngine not specified"; Task task = oe.getTaskById(taskId); if (task == null) return "Unknown TaskId"; task.log().info("Logging views for task %s (%s)", taskId, new DateTime()); for (View view : task.getViewList()) { Collection<String> nameList = view.getNameList(); task.log().info(" View %s (%s) Entity Count = %d Names = %s", view.getId(), view.getLodDef(), view.getEntityCount(true), nameList); } return "Views listed in log"; } @Override public String startObjectBrowser() { if (oe == null) return "ObjectEngine not specified"; try { if (oe.startBrowser()) return "Browser started"; else return "Error starting browser. See log for more info."; } catch (Exception e) { oe.getSystemTask().log().error(e); return "Error starting browser: " + e.getMessage(); } } @Override public String dropCachedViewByName(String viewName) { if (oe == null) return "ObjectEngine not specified"; Task task = oe.getSystemTask(); if (task == null) return "No System Task!"; View v = task.getViewByName(viewName); if (v == null) return "Unknown viewname for System task"; v.dropNameForView(viewName); return "Cached view name dropped"; } @Override public Collection<String> getViewList(String taskId) { ArrayList<String> list = new ArrayList<>(); if (oe == null) return list; Task task = oe.getTaskById(taskId); if (task == null || !task.isValid()) return list; for (View v : task.getViewList()) { String lodDef = v.getLodDef().getName(); String app = v.getLodDef().getApplication().getName(); Collection<String> nameList = v.getNameList(); if (nameList.size() == 0) { list.add(String.format("%d,%d,%s,%s", v.getId(), v.getOiId(), lodDef, app)); } else { for (String name : nameList) list.add(String.format("%d,%d,%s,%s,%s", v.getId(), v.getOiId(), lodDef, app, name)); } } return list; } @Override public String getSerializedView(String taskId, Long viewId) { if (oe == null) return "NO OE"; Task task = oe.getTaskById(taskId); if (task == null || !task.isValid()) return "NO TASK"; View view = task.getViewByKey(viewId); if (view == null) return "NO VIEW"; return view.serializeOi().asJson().withIncremental().compressed().toStringWriter().toString(); } @Override public String logTaskList() { for (Task task : oe.getTaskList()) task.log().info("Task ID %s for %s has ~ %d views", task.getTaskId(), task.getApplication().getName(), task.getViewCount()); return "Tasks logged"; } @Override public String logAllTasksAndViews() { for (Task task : oe.getTaskList()) { task.log().info("Task ID %s for %s", task.getTaskId(), task.getApplication().getName()); logViews(task.getTaskId()); } return "Tasks logged"; } }