From 0eda6c9117e7831d62b3f42e2ddd2c2761bddde5 Mon Sep 17 00:00:00 2001 From: Nick Bailey Date: Thu, 23 Feb 2012 19:19:41 -0600 Subject: [PATCH] Add ability to read multiple attributes at once. Patch by Tyler Hobbs. --- src/main/clojure/clojure/java/jmx.clj | 47 ++++++++++++++++++---------- src/test/clojure/clojure/java/test_jmx.clj | 18 ++++++++++- 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/src/main/clojure/clojure/java/jmx.clj b/src/main/clojure/clojure/java/jmx.clj index 9aa2427..128e516 100644 --- a/src/main/clojure/clojure/java/jmx.clj +++ b/src/main/clojure/clojure/java/jmx.clj @@ -16,19 +16,25 @@ What beans do I have? (jmx/mbean-names \"*:*\") - -> # # (:Verbose :ObjectPendingFinalizationCount + -> (:Verbose :ObjectPendingFinalizationCount :HeapMemoryUsage :NonHeapMemoryUsage) - What is the value of an attribute? + What is the value of an attribute? (jmx/read \"java.lang:type=Memory\" :ObjectPendingFinalizationCount) -> 0 + (jmx/read \"java.lang:type=Memory\" [:HeapMemoryUsage :NonHeapMemoryUsage]) + -> + {:NonHeapMemoryUsage + {:used 16674024, :max 138412032, :init 24317952, :committed 24317952}, + :HeapMemoryUsage + {:used 18619064, :max 85393408, :init 0, :committed 83230720}} Can't I just have *all* the attributes in a Clojure map? @@ -43,16 +49,16 @@ Can I find and invoke an operation? (jmx/operation-names \"java.lang:type=Memory\") - -> (:gc) + -> (:gc) (jmx/invoke \"java.lang:type=Memory\" :gc) -> nil - + What about some other process? Just run *any* of the above code inside a with-connection: - (jmx/with-connection {:host \"localhost\", :port 3000} + (jmx/with-connection {:host \"localhost\", :port 3000} (jmx/mbean \"java.lang:type=Memory\")) - -> {:ObjectPendingFinalizationCount 0, + -> {:ObjectPendingFinalizationCount 0, :HeapMemoryUsage ... etc.} Can I serve my own beans? Sure, just drop a Clojure ref @@ -125,7 +131,7 @@ (into {} (map (fn [attr] [(keyword attr) (objects->data (.get cd attr))]) (.. cd getCompositeType keySet)))) - + javax.management.openmbean.TabularData (objects->data [td] @@ -137,7 +143,7 @@ (objects->data [m] (into {} (zipmap (keys m) (map objects->data (vals m))))) - + Object (objects->data [obj] obj)) @@ -185,12 +191,19 @@ (.getMBeanInfo *connection* (as-object-name n))) (defn raw-read - "Read an mbean property. Returns low-level Java object model for - composites, tabulars, etc. Most callers should use read." - [n attr] - (.getAttribute *connection* (as-object-name n) (name attr))) - -(def ^{:doc "Read an mbean property."} + "Read a list of mbean properties. Returns low-level Java object + models for composites, tabulars, etc. Most callers should use + read." + [n attrs] + (if (sequential? attrs) + (into {} + (map (fn [attr] [(keyword (.getName attr)) (.getValue attr)]) + (.getAttributes *connection* + (as-object-name n) + (into-array (map name attrs))))) + (.getAttribute *connection* (as-object-name n) (name attrs)))) + +(def ^{:doc "Read one or more mbean properties."} read (comp objects->data raw-read)) @@ -234,7 +247,7 @@ [n op] (first (filter #(= (-> % .getName keyword) op) (operations n)))) -(defn- op-param-types +(defn- op-param-types "The parameter types (as class name strings) for operation op on n. Used for invoke." [n op] @@ -250,7 +263,7 @@ [n] (.queryNames *connection* (as-object-name n) nil)) -(defn attribute-names +(defn attribute-names "All attribute names available on an MBean." [n] (doall (map #(-> % .getName keyword) diff --git a/src/test/clojure/clojure/java/test_jmx.clj b/src/test/clojure/clojure/java/test_jmx.clj index 7e154a8..70143fc 100644 --- a/src/test/clojure/clojure/java/test_jmx.clj +++ b/src/test/clojure/clojure/java/test_jmx.clj @@ -60,7 +60,12 @@ (are [a b] (= a b) false (jmx/raw-read mem :Verbose)) (are [type attr] (instance? type attr) - Number (jmx/raw-read mem :ObjectPendingFinalizationCount))))) + Number (jmx/raw-read mem :ObjectPendingFinalizationCount))) + (testing "reading multiple attributes" + (are [a b] (= a b) + false ((jmx/raw-read mem [:Verbose]) :Verbose)) + (are [type attr] (instance? type attr) + Number ((jmx/raw-read mem [:ObjectPendingFinalizationCount]) :ObjectPendingFinalizationCount))))) (deftest reading-attributes (testing "simple scalar attributes" @@ -72,6 +77,17 @@ (testing "tabular attributes" (is (map? (jmx/read "java.lang:type=Runtime" :SystemProperties))))) +(deftest reading-multiple-attributes + (testing "simple scalar attributes" + (are [type attr] (instance? type attr) + Number ((jmx/read "java.lang:type=Memory" [:ObjectPendingFinalizationCount]) :ObjectPendingFinalizationCount))) + (testing "composite attributes" + (are [ks attr] (=set ks (keys attr)) + [:used :max :init :committed] + ((jmx/read "java.lang:type=Memory" [:HeapMemoryUsage :NonHeapMemoryUsage]) :HeapMemoryUsage))) + (testing "tabular attributes" + (is (map? ((jmx/read "java.lang:type=Runtime" [:SystemProperties]) :SystemProperties))))) + (deftest writing-attributes (let [mem "java.lang:type=Memory"] (jmx/write! mem :Verbose true) -- 1.7.5.4