Sunday, December 11, 2011

JMX grep scala script

A simple script to search for mbeans/attributes-names/attribute-values matching regular expressions given as script parameters. This script is using janalyse-jmx scala API; jajmx.jar java executable is used to startup the script.
This jmx grep script can be used against itself, with its own embedded jmx platform. This feature is enabled through java options (JAVA_OPTS) specified within script startup header.
$ ./jmxgrep localhost 9999  operating
java.lang:type=OperatingSystem - MaxFileDescriptorCount = 4096
java.lang:type=OperatingSystem - OpenFileDescriptorCount = 18
java.lang:type=OperatingSystem - CommittedVirtualMemorySize = 4520407040
java.lang:type=OperatingSystem - FreePhysicalMemorySize = 7900864512
java.lang:type=OperatingSystem - FreeSwapSpaceSize = 10742177792
java.lang:type=OperatingSystem - ProcessCpuTime = 1490000000
java.lang:type=OperatingSystem - TotalPhysicalMemorySize = 16848113664
java.lang:type=OperatingSystem - TotalSwapSpaceSize = 10742177792
java.lang:type=OperatingSystem - Name = Linux
java.lang:type=OperatingSystem - AvailableProcessors = 6
java.lang:type=OperatingSystem - Arch = amd64
java.lang:type=OperatingSystem - SystemLoadAverage = 0.0
java.lang:type=OperatingSystem - Version = 3.0.6-gentoo

$ ./jmxgrep localhost 9999 threadcount
java.lang:type=GarbageCollector,name=PS MarkSweep - LastGcInfo = javax.management.openmbean.CompositeDataSupport(compositeTyp...
java.lang:type=Runtime - SystemProperties = javax.management.openmbean.TabularDataSupport(tabularType=ja...
java.lang:type=Threading - DaemonThreadCount = 12
java.lang:type=Threading - PeakThreadCount = 13
java.lang:type=Threading - ThreadCount = 13
java.lang:type=Threading - TotalStartedThreadCount = 13
java.lang:type=GarbageCollector,name=PS Scavenge - LastGcInfo = javax.management.openmbean.CompositeDataSupport(compositeTyp...
jmxgrep code (just copy paste this code into a file named jmxgrep, and make it executable using chmod a+x jmxgrep) :
#!/bin/sh
JAVA_OPTS=""
JAVA_OPTS=$JAVA_OPTS" -Dcom.sun.management.jmxremote"
JAVA_OPTS=$JAVA_OPTS" -Dcom.sun.management.jmxremote.port=9999"
JAVA_OPTS=$JAVA_OPTS" -Dcom.sun.management.jmxremote.authenticate=false"
JAVA_OPTS=$JAVA_OPTS" -Dcom.sun.management.jmxremote.ssl=false"
SCA_OPTS="-nocompdaemon -usejavacp -savecompiled"
exec java $JAVA_OPTS -jar jajmx.jar $SCA_OPTS "$0" "$@"
!#

import fr.janalyse.jmx._
import JMXImplicits._

if (args.size < 2) {
  println("Usage   : jmxgrep host port searchMask1 ... searchMaskN")
  println("Example : jmxgrep localhost 1099  vendor")
  println("   will self connect to jmx server, and looks for vendor keyword")
  System.exit(1)
}
val host  = args(0)
val port  = args(1).toInt
val masks = args.toList.drop(2) map {s=>("(?i)"+s).r}

def truncate(str:String, n:Int=60) = if (str.size>n) str.take(n)+"..." else str

JMX.connect(host, port) { implicit jmx =>
  for(on <- jmx.browse ; attr <- on.browse) {
    val value = try { on.get[Any](attr).toString} catch { case _ => "**error**"}
    val found = List(on.toString, attr, value) exists { item =>
      masks exists {re => (re findFirstIn item).isDefined} 
    }
    if (found || masks.isEmpty) println("%s - %s = %s".format(on, attr, truncate(value)))
  }
}
Notice the "-savecompiled" scala option which enable the script compilation result to be stored in a file named "jmxgrep.jar". When started, already compiled code will be reuse if the script hasn't been modified since last compilation time. This allow very fast script startup.

No comments:

Post a Comment