Groovy - JMX

JMX è lo standard di fatto utilizzato per monitorare tutte le applicazioni che hanno qualcosa a che fare con l'ambiente virtuale Java. Dato che Groovy si trova direttamente sopra Java, Groovy può sfruttare l'enorme quantità di lavoro già svolto per JMX con Java.

Monitoraggio della JVM

Si possono utilizzare le classi standard disponibili in java.lang.management per effettuare il monitoraggio della JVM. Il seguente esempio di codice mostra come eseguire questa operazione.

import java.lang.management.*

def os = ManagementFactory.operatingSystemMXBean 
println """OPERATING SYSTEM: 
\tOS architecture = $os.arch 
\tOS name = $os.name 
\tOS version = $os.version 
\tOS processors = $os.availableProcessors 
""" 
 
def rt = ManagementFactory.runtimeMXBean 
println """RUNTIME: 
   \tRuntime name = $rt.name 
   \tRuntime spec name = $rt.specName 
   \tRuntime vendor = $rt.specVendor 
   \tRuntime spec version = $rt.specVersion 
   \tRuntime management spec version = $rt.managementSpecVersion 
   """ 

def mem = ManagementFactory.memoryMXBean 
def heapUsage = mem.heapMemoryUsage 
def nonHeapUsage = mem.nonHeapMemoryUsage 

println """MEMORY: 
   HEAP STORAGE: 
      \tMemory committed = $heapUsage.committed 
      \tMemory init = $heapUsage.init 
      \tMemory max = $heapUsage.max 
      \tMemory used = $heapUsage.used NON-HEAP STORAGE: 
      \tNon-heap memory committed = $nonHeapUsage.committed 
      \tNon-heap memory init = $nonHeapUsage.init 
      \tNon-heap memory max = $nonHeapUsage.max 
      \tNon-heap memory used = $nonHeapUsage.used 
   """
  
println "GARBAGE COLLECTION:" 
ManagementFactory.garbageCollectorMXBeans.each { gc ->
   println "\tname = $gc.name"
   println "\t\tcollection count = $gc.collectionCount"
   println "\t\tcollection time = $gc.collectionTime"
   String[] mpoolNames =   gc.memoryPoolNames
	
   mpoolNames.each { 
      mpoolName -> println "\t\tmpool name = $mpoolName"
   } 
}

Quando il codice viene eseguito, l'output varierà a seconda del sistema su cui viene eseguito il codice. Di seguito viene fornito un esempio dell'output.

OPERATING SYSTEM: 
   OS architecture = x86 
   OS name = Windows 7 
   OS version = 6.1 
   OS processors = 4
   
RUNTIME: 
   Runtime name = [email protected] 
   Runtime spec name = Java Virtual Machine Specification 
   Runtime vendor = Oracle Corporation 
   Runtime spec version = 1.7 
   Runtime management spec version = 1.2
   
MEMORY: 
   HEAP STORAGE: 
      Memory committed = 16252928 
      Memory init = 16777216 
      Memory max = 259522560 
      Memory used = 7355840
   
NON-HEAP STORAGE: 
   Non-heap memory committed = 37715968 
   Non-heap memory init = 35815424 
   Non-heap memory max = 123731968 
   Non-heap memory used = 18532232 
   
GARBAGE COLLECTION: 
   name = Copy 
   collection count = 15 
   collection time = 47 
   mpool name = Eden Space 
   mpool name = Survivor Space
		
   name = MarkSweepCompact 
      collection count = 0 
      collection time = 0 
		
      mpool name = Eden Space 
      mpool name = Survivor Space 
      mpool name = Tenured Gen 
      mpool name = Perm Gen 
      mpool name = Perm Gen [shared-ro] 
      mpool name = Perm Gen [shared-rw]

Monitoraggio di Tomcat

Per monitorare Tomcat, è necessario impostare il seguente parametro all'avvio di Tomcat:

set JAVA_OPTS = -Dcom.sun.management.jmxremote 
Dcom.sun.management.jmxremote.port = 9004\
 
-Dcom.sun.management.jmxremote.authenticate=false 
Dcom.sun.management.jmxremote.ssl = false

Il codice seguente utilizza JMX per rilevare gli MBean disponibili nel Tomcat in esecuzione, determinare quali sono i moduli Web ed estrarre il tempo di elaborazione per ciascun modulo Web.

import groovy.swing.SwingBuilder
  
import javax.management.ObjectName 
import javax.management.remote.JMXConnectorFactory as JmxFactory 
import javax.management.remote.JMXServiceURL as JmxUrl 
import javax.swing.WindowConstants as WC 
 
import org.jfree.chart.ChartFactory 
import org.jfree.data.category.DefaultCategoryDataset as Dataset 
import org.jfree.chart.plot.PlotOrientation as Orientation 
 
def serverUrl = 'service:jmx:rmi:///jndi/rmi://localhost:9004/jmxrmi' 
def server = JmxFactory.connect(new JmxUrl(serverUrl)).MBeanServerConnection 
def serverInfo = new GroovyMBean(server, 'Catalina:type = Server').serverInfo 
println "Connected to: $serverInfo" 
 
def query = new ObjectName('Catalina:*') 
String[] allNames = server.queryNames(query, null) 

def modules = allNames.findAll { name -> 
   name.contains('j2eeType=WebModule') 
}.collect{ new GroovyMBean(server, it) }
  
println "Found ${modules.size()} web modules. Processing ..." 
def dataset = new Dataset() 
 
modules.each { m ->
   println m.name()
   dataset.addValue m.processingTime, 0, m.path 
}