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("activeRequests", RequestCountListener.getCurrentRequestCount()); 116 } 117 catch (IllegalStateException e) 118 { 119 // empty : no value in activeSession means an error 120 } 121 122 123 ThreadMXBean tBean = ManagementFactory.getThreadMXBean(); 124 MemoryMXBean mBean = ManagementFactory.getMemoryMXBean(); 125 RuntimeMXBean rBean = ManagementFactory.getRuntimeMXBean(); 126 127 result.put("activeThreads", tBean.getThreadCount()); 128 long[] lockedThreads = ManagementFactory.getThreadMXBean().findMonitorDeadlockedThreads(); 129 130 result.put("deadlockThreads", lockedThreads != null ? String.valueOf(lockedThreads.length) : "0"); 131 132 result.put("heap-memory-max", mBean.getHeapMemoryUsage().getMax()); 133 result.put("heap-memory-used", mBean.getHeapMemoryUsage().getUsed()); 134 result.put("heap-memory-commited", mBean.getHeapMemoryUsage().getCommitted()); 135 136 137 result.put("startTime", DateUtils.dateToString(new Date(rBean.getStartTime()))); 138 139 return result; 140 } 141 142 /** 143 * Retrieves the monitoring data 144 * @return a map containing the monitoring data 145 */ 146 @Callable 147 public Map<String, Object> getMonitoringData() 148 { 149 Map<String, Object> result = new HashMap<> (); 150 151 Map<String, Object> samples = new HashMap<> (); 152 List<String> periods = new ArrayList<> (); 153 154 for (Period period : Period.values()) 155 { 156 periods.add(period.toString()); 157 } 158 159 samples.put("periods", periods); 160 161 List<Map<String, Object>> sampleList = new ArrayList<> (); 162 for (String extensionId : _monitoringExtensionPoint.getExtensionsIds()) 163 { 164 Map<String, Object> sample = new HashMap<> (); 165 SampleManager sampleManager = _monitoringExtensionPoint.getExtension(extensionId); 166 167 sample.put("id", sampleManager.getId()); 168 sample.put("label", _i18nUtils.translate(sampleManager.getLabel())); 169 sample.put("description", _i18nUtils.translate(sampleManager.getDescription())); 170 if (sampleManager instanceof AlertSampleManager) 171 { 172 Map<String, Object> thresholdValues = new HashMap<>(); 173 174 Map<String, Threshold> thresholds = ((AlertSampleManager) sampleManager).getThresholdValues(); 175 for (String datasourceName : thresholds.keySet()) 176 { 177 thresholdValues.put(datasourceName, thresholds.get(datasourceName).getValue()); 178 } 179 180 sample.put("thresholds", thresholdValues); 181 } 182 183 File rrdFile = new File(_rrdStoragePath, sampleManager.getId() + RRD_EXT); 184 if (getLogger().isDebugEnabled()) 185 { 186 getLogger().debug("Using RRD file: " + rrdFile); 187 } 188 189 try (RrdDb rrdDb = RrdDb.of(rrdFile.getPath())) 190 { 191 sample.put("ds", rrdDb.getDsNames()); 192 193 Set<String> consolidationFunction = new HashSet<>(); 194 for (int i = 0; i < rrdDb.getArcCount(); i++) 195 { 196 Archive archive = rrdDb.getArchive(i); 197 consolidationFunction.add(archive.getConsolFun().toString()); 198 } 199 sample.put("consolFun", consolidationFunction); 200 } 201 catch (Exception e) 202 { 203 getLogger().error("Unable to collect sample for: " + sampleManager.getId(), e); 204 } 205 206 sampleList.add(sample); 207 } 208 209 samples.put("sampleList", sampleList); 210 result.put("samples", samples); 211 return result; 212 } 213}