001/* 002 * Copyright 2015 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.runtime.plugins.admin.jvmstatus; 017 018import java.io.File; 019import java.lang.management.ManagementFactory; 020import java.lang.management.MemoryMXBean; 021import java.lang.management.RuntimeMXBean; 022import java.lang.management.ThreadMXBean; 023import java.util.ArrayList; 024import java.util.Collections; 025import java.util.Date; 026import java.util.HashMap; 027import java.util.HashSet; 028import java.util.List; 029import java.util.Map; 030import java.util.Set; 031 032import org.apache.avalon.framework.activity.Initializable; 033import org.apache.avalon.framework.component.Component; 034import org.apache.avalon.framework.logger.AbstractLogEnabled; 035import org.apache.avalon.framework.service.ServiceException; 036import org.apache.avalon.framework.service.ServiceManager; 037import org.apache.avalon.framework.service.Serviceable; 038import org.apache.commons.io.FileUtils; 039import org.rrd4j.core.Archive; 040import org.rrd4j.core.RrdDb; 041 042import org.ametys.core.ui.Callable; 043import org.ametys.core.util.DateUtils; 044import org.ametys.core.util.I18nUtils; 045import org.ametys.runtime.config.Config; 046import org.ametys.runtime.plugins.admin.jvmstatus.monitoring.MonitoringConstants; 047import org.ametys.runtime.plugins.admin.jvmstatus.monitoring.MonitoringExtensionPoint; 048import org.ametys.runtime.plugins.admin.jvmstatus.monitoring.SampleManager; 049import org.ametys.runtime.plugins.admin.jvmstatus.monitoring.alerts.AlertSampleManager; 050import org.ametys.runtime.plugins.admin.jvmstatus.monitoring.alerts.AlertSampleManager.Threshold; 051import org.ametys.runtime.servlet.RuntimeConfig; 052 053/** 054 * This helper allow to get information or runs some operations on JVM system 055 */ 056public class JVMStatusHelper extends AbstractLogEnabled implements Component, Serviceable, Initializable, MonitoringConstants 057{ 058 /** The monitoring extension point */ 059 private MonitoringExtensionPoint _monitoringExtensionPoint; 060 061 /** Component containing i18n utilitary methods */ 062 private I18nUtils _i18nUtils; 063 064 private String _rrdStoragePath; 065 066 @Override 067 public void service(ServiceManager manager) throws ServiceException 068 { 069 _monitoringExtensionPoint = (MonitoringExtensionPoint) manager.lookup(MonitoringExtensionPoint.ROLE); 070 _i18nUtils = (I18nUtils) manager.lookup(I18nUtils.ROLE); 071 } 072 073 public void initialize() throws Exception 074 { 075 _rrdStoragePath = FileUtils.getFile(RuntimeConfig.getInstance().getAmetysHome(), RRD_STORAGE_DIRECTORY).getPath(); 076 } 077 078 /** 079 * Runs a garbage collector. 080 * @return an empty map 081 */ 082 @Callable (rights = "Runtime_Rights_Admin_Access", context = "/admin") 083 public Map<String, Object> garbageCollect () 084 { 085 if (getLogger().isInfoEnabled()) 086 { 087 getLogger().info("Administrator is garbage collecting"); 088 } 089 090 System.gc(); 091 092 return Collections.EMPTY_MAP; 093 } 094 095 /** 096 * Retrieves information about the general status of the system 097 * @return a map containing the general status information 098 */ 099 @Callable (rights = "Runtime_Rights_Admin_Access", context = "/admin") 100 public Map<String, Object> getGeneralStatus() 101 { 102 Map<String, Object> result = new HashMap<>(); 103 104 result.put("osTime", DateUtils.dateToString(new Date())); 105 try 106 { 107 result.put("activeSessions", SessionCountListener.getSessionCount()); 108 } 109 catch (IllegalStateException e) 110 { 111 // empty : no value in activeSession means an error 112 } 113 114 try 115 { 116 result.put("activeSessionsDetail", ActiveSessionListener.getActiveSessions()); 117 } 118 catch (IllegalStateException e) 119 { 120 // empty : no value in activeSession means an error 121 } 122 123 try 124 { 125 result.put("activeRequests", RequestCountListener.getCurrentRequestCount()); 126 } 127 catch (IllegalStateException e) 128 { 129 // empty : no value in activeSession means an error 130 } 131 132 133 ThreadMXBean tBean = ManagementFactory.getThreadMXBean(); 134 MemoryMXBean mBean = ManagementFactory.getMemoryMXBean(); 135 RuntimeMXBean rBean = ManagementFactory.getRuntimeMXBean(); 136 137 result.put("activeThreads", tBean.getThreadCount()); 138 long[] lockedThreads = ManagementFactory.getThreadMXBean().findMonitorDeadlockedThreads(); 139 140 result.put("deadlockThreads", lockedThreads != null ? String.valueOf(lockedThreads.length) : "0"); 141 142 result.put("heap-memory-max", mBean.getHeapMemoryUsage().getMax()); 143 result.put("heap-memory-used", mBean.getHeapMemoryUsage().getUsed()); 144 result.put("heap-memory-commited", mBean.getHeapMemoryUsage().getCommitted()); 145 146 147 result.put("startTime", DateUtils.dateToString(new Date(rBean.getStartTime()))); 148 149 return result; 150 } 151 152 /** 153 * Retrieves the monitoring data 154 * @return a map containing the monitoring data 155 */ 156 @Callable (rights = "Runtime_Rights_Admin_Access", context = "/admin") 157 public Map<String, Object> getMonitoringData() 158 { 159 Map<String, Object> result = new HashMap<> (); 160 161 Map<String, Object> samples = new HashMap<> (); 162 List<String> periods = new ArrayList<> (); 163 164 for (Period period : Period.values()) 165 { 166 periods.add(period.toString()); 167 } 168 169 samples.put("periods", periods); 170 171 List<Map<String, Object>> sampleList = new ArrayList<> (); 172 for (String extensionId : _monitoringExtensionPoint.getExtensionsIds()) 173 { 174 Map<String, Object> sample = new HashMap<> (); 175 SampleManager sampleManager = _monitoringExtensionPoint.getExtension(extensionId); 176 177 sample.put("id", sampleManager.getId()); 178 sample.put("label", _i18nUtils.translate(sampleManager.getLabel())); 179 sample.put("description", _i18nUtils.translate(sampleManager.getDescription())); 180 if (sampleManager instanceof AlertSampleManager && Config.getInstance().getValue("runtime.system.alerts.enable") == Boolean.TRUE) 181 { 182 Map<String, Object> thresholdValues = new HashMap<>(); 183 184 Map<String, Threshold> thresholds = ((AlertSampleManager) sampleManager).getThresholdValues(); 185 for (String datasourceName : thresholds.keySet()) 186 { 187 thresholdValues.put(datasourceName, thresholds.get(datasourceName).getValue()); 188 } 189 190 sample.put("thresholds", thresholdValues); 191 } 192 193 File rrdFile = new File(_rrdStoragePath, sampleManager.getId() + RRD_EXT); 194 if (getLogger().isDebugEnabled()) 195 { 196 getLogger().debug("Using RRD file: " + rrdFile); 197 } 198 199 try (RrdDb rrdDb = RrdDb.of(rrdFile.getPath())) 200 { 201 sample.put("ds", rrdDb.getDsNames()); 202 203 Set<String> consolidationFunction = new HashSet<>(); 204 for (int i = 0; i < rrdDb.getArcCount(); i++) 205 { 206 Archive archive = rrdDb.getArchive(i); 207 consolidationFunction.add(archive.getConsolFun().toString()); 208 } 209 sample.put("consolFun", consolidationFunction); 210 } 211 catch (Exception e) 212 { 213 getLogger().error("Unable to collect sample for: " + sampleManager.getId(), e); 214 } 215 216 sampleList.add(sample); 217 } 218 219 samples.put("sampleList", sampleList); 220 result.put("samples", samples); 221 return result; 222 } 223}