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.plugins.admin.jvmstatus.monitoring.MonitoringConstants; 046import org.ametys.runtime.plugins.admin.jvmstatus.monitoring.MonitoringExtensionPoint; 047import org.ametys.runtime.plugins.admin.jvmstatus.monitoring.SampleManager; 048import org.ametys.runtime.plugins.admin.jvmstatus.monitoring.alerts.AlertSampleManager; 049import org.ametys.runtime.plugins.admin.jvmstatus.monitoring.alerts.AlertSampleManager.Threshold; 050import org.ametys.runtime.servlet.RuntimeConfig; 051 052/** 053 * This helper allow to get information or runs some operations on JVM system 054 */ 055public class JVMStatusHelper extends AbstractLogEnabled implements Component, Serviceable, Initializable, MonitoringConstants 056{ 057 /** The monitoring extension point */ 058 private MonitoringExtensionPoint _monitoringExtensionPoint; 059 060 /** Component containing i18n utilitary methods */ 061 private I18nUtils _i18nUtils; 062 063 private String _rrdStoragePath; 064 065 @Override 066 public void service(ServiceManager manager) throws ServiceException 067 { 068 _monitoringExtensionPoint = (MonitoringExtensionPoint) manager.lookup(MonitoringExtensionPoint.ROLE); 069 _i18nUtils = (I18nUtils) manager.lookup(I18nUtils.ROLE); 070 } 071 072 public void initialize() throws Exception 073 { 074 _rrdStoragePath = FileUtils.getFile(RuntimeConfig.getInstance().getAmetysHome(), RRD_STORAGE_DIRECTORY).getPath(); 075 } 076 077 /** 078 * Runs a garbage collector. 079 * @return an empty map 080 */ 081 @Callable 082 public Map<String, Object> garbageCollect () 083 { 084 if (getLogger().isInfoEnabled()) 085 { 086 getLogger().info("Administrator is garbage collecting"); 087 } 088 089 System.gc(); 090 091 return Collections.EMPTY_MAP; 092 } 093 094 /** 095 * Retrieves information about the general status of the system 096 * @return a map containing the general status information 097 */ 098 @Callable 099 public Map<String, Object> getGeneralStatus() 100 { 101 Map<String, Object> result = new HashMap<>(); 102 103 result.put("osTime", DateUtils.dateToString(new Date())); 104 try 105 { 106 result.put("activeSessions", SessionCountListener.getSessionCount()); 107 } 108 catch (IllegalStateException e) 109 { 110 // empty : no value in activeSession means an error 111 } 112 113 try 114 { 115 result.put("activeSessionsDetail", ActiveSessionListener.getActiveSessions()); 116 } 117 catch (IllegalStateException e) 118 { 119 // empty : no value in activeSession means an error 120 } 121 122 try 123 { 124 result.put("activeRequests", RequestCountListener.getCurrentRequestCount()); 125 } 126 catch (IllegalStateException e) 127 { 128 // empty : no value in activeSession means an error 129 } 130 131 132 ThreadMXBean tBean = ManagementFactory.getThreadMXBean(); 133 MemoryMXBean mBean = ManagementFactory.getMemoryMXBean(); 134 RuntimeMXBean rBean = ManagementFactory.getRuntimeMXBean(); 135 136 result.put("activeThreads", tBean.getThreadCount()); 137 long[] lockedThreads = ManagementFactory.getThreadMXBean().findMonitorDeadlockedThreads(); 138 139 result.put("deadlockThreads", lockedThreads != null ? String.valueOf(lockedThreads.length) : "0"); 140 141 result.put("heap-memory-max", mBean.getHeapMemoryUsage().getMax()); 142 result.put("heap-memory-used", mBean.getHeapMemoryUsage().getUsed()); 143 result.put("heap-memory-commited", mBean.getHeapMemoryUsage().getCommitted()); 144 145 146 result.put("startTime", DateUtils.dateToString(new Date(rBean.getStartTime()))); 147 148 return result; 149 } 150 151 /** 152 * Retrieves the monitoring data 153 * @return a map containing the monitoring data 154 */ 155 @Callable 156 public Map<String, Object> getMonitoringData() 157 { 158 Map<String, Object> result = new HashMap<> (); 159 160 Map<String, Object> samples = new HashMap<> (); 161 List<String> periods = new ArrayList<> (); 162 163 for (Period period : Period.values()) 164 { 165 periods.add(period.toString()); 166 } 167 168 samples.put("periods", periods); 169 170 List<Map<String, Object>> sampleList = new ArrayList<> (); 171 for (String extensionId : _monitoringExtensionPoint.getExtensionsIds()) 172 { 173 Map<String, Object> sample = new HashMap<> (); 174 SampleManager sampleManager = _monitoringExtensionPoint.getExtension(extensionId); 175 176 sample.put("id", sampleManager.getId()); 177 sample.put("label", _i18nUtils.translate(sampleManager.getLabel())); 178 sample.put("description", _i18nUtils.translate(sampleManager.getDescription())); 179 if (sampleManager instanceof AlertSampleManager) 180 { 181 Map<String, Object> thresholdValues = new HashMap<>(); 182 183 Map<String, Threshold> thresholds = ((AlertSampleManager) sampleManager).getThresholdValues(); 184 for (String datasourceName : thresholds.keySet()) 185 { 186 thresholdValues.put(datasourceName, thresholds.get(datasourceName).getValue()); 187 } 188 189 sample.put("thresholds", thresholdValues); 190 } 191 192 File rrdFile = new File(_rrdStoragePath, sampleManager.getId() + RRD_EXT); 193 if (getLogger().isDebugEnabled()) 194 { 195 getLogger().debug("Using RRD file: " + rrdFile); 196 } 197 198 try (RrdDb rrdDb = RrdDb.of(rrdFile.getPath())) 199 { 200 sample.put("ds", rrdDb.getDsNames()); 201 202 Set<String> consolidationFunction = new HashSet<>(); 203 for (int i = 0; i < rrdDb.getArcCount(); i++) 204 { 205 Archive archive = rrdDb.getArchive(i); 206 consolidationFunction.add(archive.getConsolFun().toString()); 207 } 208 sample.put("consolFun", consolidationFunction); 209 } 210 catch (Exception e) 211 { 212 getLogger().error("Unable to collect sample for: " + sampleManager.getId(), e); 213 } 214 215 sampleList.add(sample); 216 } 217 218 samples.put("sampleList", sampleList); 219 result.put("samples", samples); 220 return result; 221 } 222}