The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
Build.PL 12
CHANGES 139
MANIFEST 110
META.json 27
META.yml 26
SIGNATURE 1700
config/glassfish.cfg 11
config/jboss7.cfg 0220
config/memory.cfg 927
config/weblogic.cfg 11
config/websphere/appstate.cfg 013
config/websphere/http.cfg 0129
config/websphere/jca.cfg 043
config/websphere/jdbc.cfg 088
config/websphere/jms.cfg 044
config/websphere/threads.cfg 045
config/websphere.cfg 030
it/check_jmx4perl/base.cfg 11
it/check_jmx4perl/base.pl 66
it/check_jmx4perl/checks.cfg 212
it/check_jmx4perl/multi_check.cfg 011
it/it.pl 12
it/t/01_version.t 13
it/t/52_check_operation.t 08
it/t/55_check_incremental.t 1318
it/t/57_check_config.t 35
it/t/58_check_multi_config.t 019
it/t/80_read.t 213
it/t/95_cors.t 08
it/t/99_discovery.t 035
lib/JMX/Jmx4Perl/Agent/Jolokia/Verifier/OpenPGPVerifier.pm 711
lib/JMX/Jmx4Perl/Agent/Jolokia/Verifier.pm 47
lib/JMX/Jmx4Perl/Agent/UserAgent.pm 014
lib/JMX/Jmx4Perl/Agent.pm 62
lib/JMX/Jmx4Perl/J4psh/Command/MBean.pm 316
lib/JMX/Jmx4Perl/J4psh.pm 013
lib/JMX/Jmx4Perl/Nagios/CheckJmx4Perl.pm 50124
lib/JMX/Jmx4Perl/Nagios/MessageHandler.pm 060
lib/JMX/Jmx4Perl/Nagios/SingleCheck.pm 3248
lib/JMX/Jmx4Perl/Util.pm 11
lib/JMX/Jmx4Perl.pm 171
scripts/check_jmx4perl 890
scripts/jmx4perl 11
t/30_request.t 123
t/40_check_jmx4perl.t 40
45 files changed (This is a version diff) 3351327
@@ -28,6 +28,7 @@ my %REQS = (
             "Scalar::Util" => 0,
             "base" => 0,
             "Sys::SigAction" => 0,
+            "IO::Socket::Multicast" => 0 # opt
            );
 
 my %SCRIPTS = ();
@@ -232,7 +233,7 @@ my $build = Module::Build->new
    dist_version_from => "lib/JMX/Jmx4Perl.pm",
    dist_author => 'Roland Huss (roland@cpan.org)',
    dist_abstract => 'Easy JMX access to Java EE applications',
-   sign => 1,
+   #sign => 1,
    installdirs => 'site',
    license => 'gpl',
    
@@ -1,4 +1,42 @@
-1.07 
+1.11 ()
+
+  - When within a MultiCheck a single check causes an exception, the
+    other checks are now still present in the output of check_jmx4perl
+    and the overall check has the status UNKNWON (#40)
+  - Minor fixes on the WebSphere Checks
+  - Fixed issue when calling check_jmx4perl for an operation without argument (RT##98166)
+
+1.10 (2014-06-30)
+
+  - Added WebSphere checks
+
+1.08 (2014-06-30)
+  - Fixed warning when using MBeanName (#31)
+  - Fixed BaseMBean and formatting
+  - Fixed relative checks when using MBean patterns
+  - Added formatter '%q' to include a ratio of value to base without
+    multiplying by 100 like for '%r'
+  - Disabled OpenPGPVerifier since it doesn't support the new digest
+    algorithms used for signing the Jolokia artefacts (#32)
+  - Don't set ssl_opts if on LWP < 6 (#28)
+  - Fixed BaseMBean and BaseAttribute config directives (#25)
+  - Fixed regexp for squeezing trailing slashes (RT#89108)
+  - Fixed check definition for 'wls_channel_connections (RT#89107)
+  - Changed check 'memory_gc_time' to be a relative check to measure the 
+    relative amount taken for the GC. If you use this check (or a sub-check of this)
+    YOU NEED TO UPDATE YOUR THRESHOLDS (and regenerate the pn4p graphics) if you use this 
+    check directly
+  - Fixed bug when using 0 thresholds in checks using parent checks (#38)
+  - Added support for '*' wildcard when navigation with cd for j4psh 
+  - Fixed bug with check inheritance and check parameters which contain parantheses
+  - Added an option "MultiCheckPrefix" for "Checks" in order to specify the prefix 
+    for multi checks 
+  - Added config options "SummaryOk" and "SummaryFailure" for allowing to fine tune 
+    multi check output (#24)
+  - "Argument" can be used in "Operation" config checks for providing arguments to 
+    Nagios checks which are based on operations (#27)
+
+1.07 (2013-04-16) 
   - Added more robust timeout for the Jmx4Perl Agent (requires Sys::SigAction)
   - SSL Host key verification switched off when connecting via SSL
   - Fixed issue with quoting in j4psh (#14)
@@ -2,6 +2,7 @@ Build.PL
 CHANGES
 config/common.cfg
 config/jboss.cfg
+config/jboss7.cfg
 config/jetty.cfg
 config/memory.cfg
 config/threads.cfg
@@ -9,6 +10,13 @@ config/tomcat.cfg
 config/weblogic.cfg
 config/glassfish.cfg
 config/metrics.cfg
+config/websphere.cfg
+config/websphere/appstate.cfg
+config/websphere/http.cfg
+config/websphere/jca.cfg
+config/websphere/jdbc.cfg
+config/websphere/jms.cfg
+config/websphere/threads.cfg
 examples/jsr77.pl
 examples/memory.pl
 examples/memory.sh
@@ -103,6 +111,7 @@ lib/JMX/Jmx4Perl/Manual.pod
 lib/JMX/Jmx4Perl/Nagios/CactiJmx4Perl.pm
 lib/JMX/Jmx4Perl/Nagios/CheckJmx4Perl.pm
 lib/JMX/Jmx4Perl/Nagios/SingleCheck.pm
+lib/JMX/Jmx4Perl/Nagios/MessageHandler.pm
 lib/JMX/Jmx4Perl/Product/ActiveMQ.pm
 lib/JMX/Jmx4Perl/Product/BaseHandler.pm
 lib/JMX/Jmx4Perl/Product/Geronimo.pm
@@ -138,8 +147,8 @@ t/40_check_jmx4perl.t
 t/50_config.t
 t/60_parse_name.t
 t/70_pod_syntax.t
+it/t/99_discovery.t
 t/j4p_test.cfg
 t/lib/It.pm
 t/lib/ProductTest/Test1Handler.pm
 t/lib/ProductTest/Test2Handler.pm
-SIGNATURE    Added here by Module::Build
@@ -37,6 +37,7 @@
             "File::SearchPath" : "0",
             "File::Temp" : "0",
             "Getopt::Long" : "0",
+            "IO::Socket::Multicast" : "0",
             "JSON" : "2.12",
             "LWP::UserAgent" : "0",
             "Module::Find" : "0",
@@ -60,7 +61,7 @@
    "provides" : {
       "JMX::Jmx4Perl" : {
          "file" : "lib/JMX/Jmx4Perl.pm",
-         "version" : "1.07"
+         "version" : "1.11"
       },
       "JMX::Jmx4Perl::Agent" : {
          "file" : "lib/JMX/Jmx4Perl/Agent.pm",
@@ -178,6 +179,10 @@
          "file" : "lib/JMX/Jmx4Perl/Nagios/CheckJmx4Perl.pm",
          "version" : 0
       },
+      "JMX::Jmx4Perl::Nagios::MessageHandler" : {
+         "file" : "lib/JMX/Jmx4Perl/Nagios/MessageHandler.pm",
+         "version" : 0
+      },
       "JMX::Jmx4Perl::Nagios::SingleCheck" : {
          "file" : "lib/JMX/Jmx4Perl/Nagios/SingleCheck.pm",
          "version" : 0
@@ -261,5 +266,5 @@
          "http://opensource.org/licenses/gpl-license.php"
       ]
    },
-   "version" : "1.07"
+   "version" : "1.11"
 }
@@ -17,7 +17,7 @@ name: jmx4perl
 provides:
   JMX::Jmx4Perl:
     file: lib/JMX/Jmx4Perl.pm
-    version: 1.07
+    version: 1.11
   JMX::Jmx4Perl::Agent:
     file: lib/JMX/Jmx4Perl/Agent.pm
     version: 0
@@ -105,6 +105,9 @@ provides:
   JMX::Jmx4Perl::Nagios::CheckJmx4Perl:
     file: lib/JMX/Jmx4Perl/Nagios/CheckJmx4Perl.pm
     version: 0
+  JMX::Jmx4Perl::Nagios::MessageHandler:
+    file: lib/JMX/Jmx4Perl/Nagios/MessageHandler.pm
+    version: 0
   JMX::Jmx4Perl::Nagios::SingleCheck:
     file: lib/JMX/Jmx4Perl/Nagios/SingleCheck.pm
     version: 0
@@ -173,6 +176,7 @@ requires:
   File::SearchPath: 0
   File::Temp: 0
   Getopt::Long: 0
+  IO::Socket::Multicast: 0
   JSON: 2.12
   LWP::UserAgent: 0
   Module::Find: 0
@@ -192,4 +196,4 @@ requires:
   base: 0
 resources:
   license: http://opensource.org/licenses/gpl-license.php
-version: 1.07
+version: 1.11
@@ -1,170 +0,0 @@
-This file contains message digests of all files listed in MANIFEST,
-signed via the Module::Signature module, version 0.70.
-
-To verify the content in this distribution, first make sure you have
-Module::Signature installed, then type:
-
-    % cpansign -v
-
-It will check each file's integrity, as well as the signature's
-validity.  If "==> Signature verified OK! <==" is not displayed,
-the distribution may already have been compromised, and you should
-not run its Makefile.PL or Build.PL.
-
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-SHA1 efb6ef8124d45ba3bc71937e49e8c1f3126b7167 Build.PL
-SHA1 bf11c279098f180c44dac105b87d45d346b1354c CHANGES
-SHA1 c8687c95995b52c206d5926b4cd4abfdd3200887 LICENSE
-SHA1 8d6c568ef3aca62f486fd13ff9d3cb9351645169 MANIFEST
-SHA1 5bb1b8d05f4dada19abadb96b41628e6220d0bb6 META.json
-SHA1 803d97edf7322339e8a9a9191b7986c47dcf6656 META.yml
-SHA1 73937eae74e3b5872afcc9a9311a63e925a9114f README
-SHA1 1293d955fab938aabfa3a08804e019425fcd84a7 config/common.cfg
-SHA1 c2648e1e3b4c52f77052d30713021685a5f8f464 config/glassfish.cfg
-SHA1 24b844a75ae7bb644da248614d98cbf3a41c36cc config/jboss.cfg
-SHA1 03a45a425166dc7b5cee93cc9b59d0532332ecc3 config/jetty.cfg
-SHA1 b783ba8830bc903a7ac467278eddb0e97baf5ddb config/memory.cfg
-SHA1 f326de8041bd9f4c288dc4759c59f4ee79958f5d config/metrics.cfg
-SHA1 7cc9d0df18278ee8668fe102b6fbe4b2adf1e621 config/threads.cfg
-SHA1 1658ab270d018d08282825609dd661643f21bd15 config/tomcat.cfg
-SHA1 803d9834d72d355521a1b22e268533df7a57a0d3 config/weblogic.cfg
-SHA1 b06c34e2d6ad6ef7743c0d1cfc9e9a6aaeb3e88c examples/jsr77.pl
-SHA1 4fe1fd0235330078a190e1be17664585b5be0456 examples/memory.pl
-SHA1 a5835abdd82b454935cbbd3e0b378e9ee945317c examples/memory.sh
-SHA1 18a34bb9adc6484173b1768038132a6a2a9fc158 examples/remote.pl
-SHA1 4c156ecb0625bbd63fd825fb4e3b52a3154e8df8 examples/threadDump.pl
-SHA1 fc2305300058b27e50b00fe0de093ab4229e02e5 inc/Module-Build/Module/Build.pm
-SHA1 00536c62636168bbcd4e6aea4787b71f01f8ff9f inc/Module-Build/Module/Build/API.pod
-SHA1 8b12ecc740383d16a7b79e4f265e4f7f3da9ff86 inc/Module-Build/Module/Build/Authoring.pod
-SHA1 0c3f019e4d08042118e9eaf66ac4b7cd26a0916c inc/Module-Build/Module/Build/Base.pm
-SHA1 9463f093cb3aad6caa966f91b0b92bc7579b2e0b inc/Module-Build/Module/Build/Compat.pm
-SHA1 8f008846ad5ace77499f89b7c1f31ae6330f0701 inc/Module-Build/Module/Build/Config.pm
-SHA1 cd6402b7a0fa06099ddb567a2b10e8e2465f6df6 inc/Module-Build/Module/Build/ConfigData.pm
-SHA1 7483c1468a8185fcdd95b069f6815b973ce9e5fa inc/Module-Build/Module/Build/Cookbook.pm
-SHA1 51fce7456b68a69f75dbb54b86a08e0dd9bee6b9 inc/Module-Build/Module/Build/Dumper.pm
-SHA1 2e9d91359d47480dfe3733d0db436eddb50a564b inc/Module-Build/Module/Build/ModuleInfo.pm
-SHA1 685577be41661ead51956a1e49a1f6a814efd352 inc/Module-Build/Module/Build/Notes.pm
-SHA1 6484f396f6fe2fea4d9d8af71fe9a59a42e52d2a inc/Module-Build/Module/Build/PPMMaker.pm
-SHA1 1acff92616db75e6e3d53afb949906b051e4088b inc/Module-Build/Module/Build/Platform/Amiga.pm
-SHA1 bcf82cd3e2214dc232434e05acad5f7d2158d0d4 inc/Module-Build/Module/Build/Platform/Default.pm
-SHA1 14a3072c96f0b0c0c03f6437e62bbeaa01f482f6 inc/Module-Build/Module/Build/Platform/EBCDIC.pm
-SHA1 ed79a501eab4f0ee602dc4aad36d7b03903ff5e2 inc/Module-Build/Module/Build/Platform/MPEiX.pm
-SHA1 0cdd0ab261ffb809e2827ccd481ddc948c1d0362 inc/Module-Build/Module/Build/Platform/MacOS.pm
-SHA1 baab8065c9105d21a522e2447ab60738f256ee66 inc/Module-Build/Module/Build/Platform/RiscOS.pm
-SHA1 77c9d5f9b4e34d685b55cf8af99863ecc78da5ee inc/Module-Build/Module/Build/Platform/Unix.pm
-SHA1 f9f56717f920cd4df7476e87da09626a96f5388e inc/Module-Build/Module/Build/Platform/VMS.pm
-SHA1 85274f36fc013bc01375496dc1ee05ff35021310 inc/Module-Build/Module/Build/Platform/VOS.pm
-SHA1 b4b3311bb07c60833afcff9279156e594b3b34f4 inc/Module-Build/Module/Build/Platform/Windows.pm
-SHA1 638785ffbc2244ae3ab3e75de6a4f4ee2dab3311 inc/Module-Build/Module/Build/Platform/aix.pm
-SHA1 94858f15146b626ff2d3335dfc7bf192edd3d9fd inc/Module-Build/Module/Build/Platform/cygwin.pm
-SHA1 e8548fb7413515f1511b2b519c42853f22b8d9ba inc/Module-Build/Module/Build/Platform/darwin.pm
-SHA1 b89bcf92179aebc62c4cd8f3db33771bd284bfed inc/Module-Build/Module/Build/Platform/os2.pm
-SHA1 311bf361f73a198b660022ed466d5693e9cf526a inc/Module-Build/Module/Build/PodParser.pm
-SHA1 f738334a6ad01d25cd472c0f1525284e7c4edd80 inc/Module-Build/Module/Build/Version.pm
-SHA1 ec3f32d9acbcf05285a37b722c258694621a377a inc/Module-Build/Module/Build/YAML.pm
-SHA1 39c740559f2d95ac3dcd2af0d91d5458e16ef141 it/check_jmx4perl/base.cfg
-SHA1 d61e4c888b4b40e77009caf72c39dd7d682bb2ba it/check_jmx4perl/base.pl
-SHA1 7024cf6a82db5156249a2dea40f9ba229b725f10 it/check_jmx4perl/checks.cfg
-SHA1 483430f8e91e3fb589be52350df5be9396b3aaf2 it/check_jmx4perl/multi_check.cfg
-SHA1 99cb8c3f483b56fe8e13539772020588b597261b it/it.pl
-SHA1 eb63064ad781938533005dbde057f9009b1705a1 it/t/01_version.t
-SHA1 bd602793b32d553ba388cc6cda49a782243ec1d5 it/t/02_http_header.t
-SHA1 6d401e4209006ac11a44c7b2ed00662db67f322f it/t/10_base.t
-SHA1 a206cbf7619da740414c7cc4b3ad06790900bfac it/t/30_naming.t
-SHA1 488a9828bb3cb03f853ab5c2ee3de81053b629b9 it/t/40_alias.t
-SHA1 6cf6a68a4be6cf1a62d715946481e4f4e317efb8 it/t/50_check_base.t
-SHA1 e17c51dde65390238905b1960ac563862ce25171 it/t/51_check_relative.t
-SHA1 e9da30cac58fd8dd2f3d8c4befde659fbbcf4b44 it/t/52_check_operation.t
-SHA1 057b594ca0349b3c6ce9f9c8b89ae2acf4bf341c it/t/53_check_non_numeric.t
-SHA1 fee5b94c93bdf7e13c7fa24eb63dc08ef905e00a it/t/54_check_unit.t
-SHA1 3b8746e709dddd7d65ca4ae063236e2e6db994d5 it/t/55_check_incremental.t
-SHA1 260403ee0fa8805c2c8d2ba540980dadbd7e2c9f it/t/56_check_value.t
-SHA1 e9303f6e1dd271a0a23c61850ce4abc015a26bb5 it/t/57_check_config.t
-SHA1 6a372195773ed9b00079d4d1f54c732f229f34b1 it/t/58_check_multi_config.t
-SHA1 1498d7fca477839314bc8a0b0398be087d31adfb it/t/59_check_timeout.t
-SHA1 98388b48061af9b55a26a765a6b22e26489fbbbd it/t/60_bulk_request.t
-SHA1 086d28bb65330f4728c216f2fe44244c9108c226 it/t/64_check_perfdata.t
-SHA1 defd7b61e42c70d1dbce6ddb2cff77a98c163324 it/t/70_overloaded_method.t
-SHA1 cc67e178cfcc79b5338674198fd4f59d7c9e1162 it/t/80_read.t
-SHA1 ae42a3b432bf764c2cf4973afc86489248eae19a it/t/83_write.t
-SHA1 559f1968eece6581c8ed18cc02fad340d758e7ff it/t/84_exec.t
-SHA1 71158019509ce5cd9cf1255cd5f146f65b087cea it/t/85_path_escaping.t
-SHA1 2da7577b853fd46e72a1e8e38e3c2061e6908b07 it/t/90_search.t
-SHA1 3fa673c6f0f1e43fbd63f4e518efe96ba02413f1 it/t/95_cors.t
-SHA1 529acabc1f064d748e8e7e217a61bad7310ebfbd lib/JMX/Jmx4Perl.pm
-SHA1 d5677142b376ca9b1bba861daa0bb7ae2c84ed52 lib/JMX/Jmx4Perl/Agent.pm
-SHA1 3090e3dbdccd697cedc4ded87e43986c3276f9bd lib/JMX/Jmx4Perl/Agent/Jolokia/ArtifactHandler.pm
-SHA1 54601c8245411eec3ab7378cfbd7b249ade6a7b1 lib/JMX/Jmx4Perl/Agent/Jolokia/DownloadAgent.pm
-SHA1 b9f9ed36dcbcf9e626a589d84c9ccacc8230ea93 lib/JMX/Jmx4Perl/Agent/Jolokia/Logger.pm
-SHA1 3701e66ede3886b621f0bc490752ee14cdd80e6f lib/JMX/Jmx4Perl/Agent/Jolokia/Meta.pm
-SHA1 54549b050081653d5f305073e9c448bb0a946afd lib/JMX/Jmx4Perl/Agent/Jolokia/Verifier.pm
-SHA1 28a1bc90664694e99e5d8e4ce7dfd4dbac499197 lib/JMX/Jmx4Perl/Agent/Jolokia/Verifier/ChecksumVerifier.pm
-SHA1 232352aa610063519ec8e5904509abd75ba0d4cd lib/JMX/Jmx4Perl/Agent/Jolokia/Verifier/GnuPGVerifier.pm
-SHA1 baea522b6d930ef9300c815e4e4d4872a9c8b3f5 lib/JMX/Jmx4Perl/Agent/Jolokia/Verifier/MD5Verifier.pm
-SHA1 bc7e04bb7676e197949d7860cf4720bf66b500b1 lib/JMX/Jmx4Perl/Agent/Jolokia/Verifier/OpenPGPVerifier.pm
-SHA1 6bf7f6fe4dec43126a5b4a15ad88d024effa2a22 lib/JMX/Jmx4Perl/Agent/Jolokia/Verifier/PGPKey.pm
-SHA1 16395880013ae48af3f19e3026317fc997590ae3 lib/JMX/Jmx4Perl/Agent/Jolokia/Verifier/SHA1Verifier.pm
-SHA1 06ff6de6e05fc8a3523500966a57e593416ff600 lib/JMX/Jmx4Perl/Agent/Jolokia/WebXmlHandler.pm
-SHA1 da1a9c8e8a982196b49140d3b2c6660c286c99f3 lib/JMX/Jmx4Perl/Agent/UserAgent.pm
-SHA1 388974f6aa0f266b98e6d051ff6a27509d9ea12a lib/JMX/Jmx4Perl/Alias.pm
-SHA1 1aecc0a8dabd6ca1cb6753b72994a9618a16b6a6 lib/JMX/Jmx4Perl/Alias/Object.pm
-SHA1 1c5f22e5190c56cc8e2a53633c33b19b55234064 lib/JMX/Jmx4Perl/Config.pm
-SHA1 5d9d56969351a838ac78678460fe63f8dd8e26d1 lib/JMX/Jmx4Perl/J4psh.pm
-SHA1 77516bb9599118c9635f572e0c26a9aa5bda5b68 lib/JMX/Jmx4Perl/J4psh/Command.pm
-SHA1 32110e3506932f86b0aea6c46eb7f3d23b29ae76 lib/JMX/Jmx4Perl/J4psh/Command/Global.pm
-SHA1 64d4cdaff62c7672c6b5850fe51d1e250e942fef lib/JMX/Jmx4Perl/J4psh/Command/MBean.pm
-SHA1 61b5260e8d6e9a5217fafa77836cc8baa105dde3 lib/JMX/Jmx4Perl/J4psh/Command/Server.pm
-SHA1 ed995a3c170ea9424b4ba7c51a93f408ec520e54 lib/JMX/Jmx4Perl/J4psh/CommandHandler.pm
-SHA1 51d3c92875104e3639a899b6876ecaa0e4efab49 lib/JMX/Jmx4Perl/J4psh/CompletionHandler.pm
-SHA1 f2ce282cd489f0222028354d79df65b9503f7ca8 lib/JMX/Jmx4Perl/J4psh/ServerHandler.pm
-SHA1 eba997374af96ce77f14686ce6b37ae7e28e095a lib/JMX/Jmx4Perl/J4psh/Shell.pm
-SHA1 2a8bc61e0d275f84ad55cdd92d0580cba71c53d6 lib/JMX/Jmx4Perl/Manual.pod
-SHA1 9543a64106a851f172df8bd121aecef56553b9dd lib/JMX/Jmx4Perl/Nagios/CactiJmx4Perl.pm
-SHA1 86e01804a382cc5d679ed0a75c388896d3488a68 lib/JMX/Jmx4Perl/Nagios/CheckJmx4Perl.pm
-SHA1 af58422a656200784f8176414f150608b5e3ca77 lib/JMX/Jmx4Perl/Nagios/SingleCheck.pm
-SHA1 999e651ec2674df085829d3f61a1bba2b3fecd58 lib/JMX/Jmx4Perl/Product/ActiveMQ.pm
-SHA1 f87f1d2e7ed105b34ef386d2cb4645367465bb55 lib/JMX/Jmx4Perl/Product/BaseHandler.pm
-SHA1 af4733aec45378e74f443ad31cd1fad6f208fa78 lib/JMX/Jmx4Perl/Product/Geronimo.pm
-SHA1 eabe3062b23a86606c4d5ea038024103edc1d4fe lib/JMX/Jmx4Perl/Product/Glassfish.pm
-SHA1 9982bd54e9157c068799058ea3afda15f5f2401f lib/JMX/Jmx4Perl/Product/Hadoop.pm
-SHA1 bf9586c33214d61f5147f915ee2c2e6ed7d34023 lib/JMX/Jmx4Perl/Product/JBoss.pm
-SHA1 598ed87add30b4d19af7aa3efbc211231578f418 lib/JMX/Jmx4Perl/Product/Jetty.pm
-SHA1 bc8e61124799c13ed04875b6dc0519e7ef0c0c4f lib/JMX/Jmx4Perl/Product/Jonas.pm
-SHA1 cc710775b96268acc988dd256f08c4c5d143f752 lib/JMX/Jmx4Perl/Product/Resin.pm
-SHA1 9bbe499d2c8817144eae146cee25cca3157398fb lib/JMX/Jmx4Perl/Product/SpringDM.pm
-SHA1 61badaf5d95359765ea59aff0c4850fe8ce84d38 lib/JMX/Jmx4Perl/Product/Terracotta.pm
-SHA1 4efd2cd5d826897d3064e9959c2d4218d57e941c lib/JMX/Jmx4Perl/Product/Tomcat.pm
-SHA1 b2c22c3c2fc228828df8c463ca25f48b8c9161b3 lib/JMX/Jmx4Perl/Product/Unknown.pm
-SHA1 38ec734500546e7490e1610bf79c9ab9efb41959 lib/JMX/Jmx4Perl/Product/Weblogic.pm
-SHA1 d24b0c995ac8c6ab15f515d96c37c198259d9575 lib/JMX/Jmx4Perl/Product/Websphere.pm
-SHA1 b51e9ca04a2ddff050bd52312606a4d52a9e334a lib/JMX/Jmx4Perl/Request.pm
-SHA1 0170fa2a769fb63619649e8bde22395159b1bb6e lib/JMX/Jmx4Perl/Response.pm
-SHA1 70cf9c6987563ab7b5ce64c5097d22bc63ad6a62 lib/JMX/Jmx4Perl/Util.pm
-SHA1 e3571527358bebebcaa7f29c05f0995f20a9855c scripts/cacti_jmx4perl
-SHA1 a340a800601cef4b15f709d6205d5d0017a06b79 scripts/check_jmx4perl
-SHA1 05686acab8a128630d4fe00a3ca7ea14e530ae8c scripts/j4psh
-SHA1 0dbbcbc4da7bff85b1de1ca884dd07d80b7edfd4 scripts/jmx4perl
-SHA1 a2bc806ebe327af844bae280264b903019297673 scripts/jolokia
-SHA1 147660596fdc69820e59147fadb857de38545b56 t/10_handler.t
-SHA1 4a8bb19315ab3f09b894d0d3e3833526b2ba747b t/20_alias.t
-SHA1 56eec9d8b9b6e2aee11180102f8145ff74a63c3e t/30_request.t
-SHA1 6cd7af64966fe98c3911c6f378674fcb5b360db3 t/40_check_jmx4perl.t
-SHA1 34c4b74957501c3bcaa75d36c0976b4d745d401b t/50_config.t
-SHA1 2d21e941e2c2fe6285ed464c904df9b7fb649759 t/60_parse_name.t
-SHA1 80827d16a010059986e159dbe6e4c29e313cb524 t/70_pod_syntax.t
-SHA1 58f29a2ce116a173081bcce2402a4ecd93593c00 t/j4p_test.cfg
-SHA1 d2f311f90fea446d87dc87664a9ae020e7f4c1af t/lib/It.pm
-SHA1 8f44123785800a2f16d2c4868bd50280fc7b0ca7 t/lib/ProductTest/Test1Handler.pm
-SHA1 7dfbae1265b70a3c56ef1e1af64ef7549aa7b976 t/lib/ProductTest/Test2Handler.pm
------BEGIN PGP SIGNATURE-----
-Version: GnuPG/MacGPG2 v2.0.19 (Darwin)
-Comment: GPGTools - http://gpgtools.org
-
-iQCVAwUBUW0edEKyJpPvEBFlAQJ9uQQAoZX7/u2pUXsBUOVLUVkI5m143qaB0/Ai
-i5ygXifS3umkA3Voet7LyVpmGVQfgUOTHH+t7x4KRc+o1fMRpkhV3jOK/zEKQHuU
-12waXGDMcZlzUrrg1Zg5rrabwWnj61PCMI42+4XUx1osjlOczMJBNd46hWFZFJ/5
-BEleZCvQuOs=
-=DLnz
------END PGP SIGNATURE-----
@@ -10,7 +10,7 @@
 # $0: Name of queue
 # $1: Critical (default: 1000)
 # $2: Warning (default: 800)
-Check gf_omq_queue_count>
+<Check gf_omq_queue_count>
   MBean = com.sun.messaging.jms.server:name="$0",subtype=Monitor,type=Destination,desttype=q
   Attribute = NumMsgs
   Name = JMS Queue $0 Count
@@ -0,0 +1,220 @@
+# JBoss 7 specific checks
+# ========================================================
+
+include "common.cfg"
+
+# Please note that JBoss 7 changed (/wrt JBoss 6) completely with relation to the 
+# internal MBean structure
+
+
+# Number of bytes received per minute for a connector
+# $0: Name of connector (e.g. 'http-8080')
+# $1: Critical (optional)
+# $2: Warning (optional)
+# $3: Name (optional)
+<Check jboss7_connector_received_rate>
+  Use = count_per_minute("bytes received")
+  Label = Connector $0 : $BASE
+  Name = ${3:bytes_received}
+  Value = jboss.as.expr:connector=$0,*/bytesReceived
+  Critical = ${1:104857600}
+  Warning = ${2:83886080}
+</Check>
+
+# Number of bytes sent per minute for a connector
+# $0: Name of connector (e.g. 'http-8080')
+# $1: Critical (optional)
+# $2: Warning (optional)
+# $3: Name (optional)
+<Check jboss7_connector_sent_rate>
+  Use = count_per_minute("bytes sent")
+  Label = Connector $0 : $BASE
+  Name = ${3:bytes_sent}
+  Value = jboss.as.expr:connector=$0,*/bytesSent
+  Critical = ${1:104857600}
+  Warning = ${2:83886080}
+</Check>
+
+# Increase of overall processing time per minute for a connector
+# This checks calculates the processing time for a certain
+# interval and scale it to a minute
+# $0: Connector name
+# $1: Critical (optional)
+# $2: Warning (optional)
+# $3: Name (optional)
+<Check jboss7_connector_processing_time>
+  Delta = 60
+  Label = Connector $0 : %2.0f ms request processing time / minute
+  Name = ${3:proc_time}
+  Value = jboss.as.expr:connector=$0,*/processingTime
+  Critical = ${1:50000}
+  Warning = ${2:40000}
+</Check>
+
+# Requests per minute for a connector
+# $0: Connector name
+# $1: Critical (optional)
+# $2: Warning (optional)
+# $3: Name (optional)
+<Check jboss7_connector_requests>
+  Use = count_per_minute("requests")
+  Label = Connector $0 : $BASE
+  Name = ${3:nr_requests}
+  Value = jboss.as.expr:connector=$0,*/requestCount
+  Critical = ${1:1000}
+  Warning = ${2:900}  
+</Check>
+
+# Number of errors for a connector per minute. 
+# $0: Connector name
+# $1: Critical (optional)
+# $2: Warning (optional)
+# $3: Name (optional)
+<Check jboss7_connector_error_count>
+  Value = jboss.as.expr:connector=$0,*/errorCount
+  Label = Connector $0:  %d errors
+  Name = ${3:errors}
+  Critical = ${1:100}
+  Warning = ${2:90}  
+  Delta = 60
+</Check>
+
+#################################################################
+
+# ==================================================================
+# Relative DB Pool check (active connection vs. maximal available connections)
+# $0: Name of datasource (e.g. "ExampleDS")
+# $1: Critical value (optional)
+# $2: Warning value (optional)
+# $3: Name (optional)
+<Check tc_datasource_connections>
+  Value = *:data-source=${0},statistics=pool,subsystem=datasources/ActiveCount
+  Base  = *:data-source=${0},subsystem=datasources/maxPoolSize
+  Name  = ${3:dbpool_used}
+  Label = %.2r% DB connections used (%v %u active / %b %w max)
+  Critical = ${1:90}
+  Warning = ${2:80}
+</Check>
+
+#######################################################################
+
+# Requests per minute for a servlet
+# $0: Web-Module name
+# $1: Servlet name
+# $2: Critical (optional)
+# $3: Warning (optional)
+# $4: Name (optional)
+<Check jboss7_servlet_requests>
+  MBean = jboss.as.expr:deployment=$0,servlet=$1,subdeployment=*,subsystem=web
+  Use = count_per_minute("requests")
+  Attribute = requestCount
+  Name = ${4:request}
+  Critical = ${2:6000}
+  Warning = ${3:5000}  
+</Check>
+
+# Increase of overall processing time per minute for a servlet module
+# This is calculate the processing time for a certain
+# interval and extrapolate to a minute
+# $0: Webmodule name
+# $1: Servlet name
+# $2: Critical (optional)
+# $3: Warning (optional)
+# $4: Name (optional)
+<Check jboss7_servlet_processing>
+  MBean = jboss.as.expr:deployment=$0,servlet=$1,subdeployment=*,subsystem=web
+  Attribute = processingTime
+  Delta = 60
+  Label = %2.0f ms request processing time / minute
+  Name = ${3:proc_time}
+  Critical = ${2:50000}
+  Warning = ${3:40000}
+</Check>
+
+# ========================================================
+# Session related checks
+
+# Number of active sessions at this moment
+# $0: Name of web-module
+# $1: Critical (optional)
+# $2: Warning (optional)
+<Check jboss7_session_active>
+  MBean = *:deployment=$0,subsystem=web
+  Attribute = activeSessions
+  Name = ${3:sessions_active}
+  Label = $0: Active Sessions = %v
+  Critical = ${1:1000}
+  Warning = ${2:800}
+</Check>
+
+# Maximum number of active sessions so far
+# $0: Name of web-module
+# $1: Critical (optional)
+# $2: Warning (optional)
+# $3: Name (optional)
+<Check jboss7_session_active_max>
+  MBean = *:deployment=$0,subsystem=web
+  Attribute = maxActive
+  Name = ${3:sessions_max}
+  Label = $0: Max-Active Sessions = %v
+  Critical = ${1:1000}
+  Warning = ${2:800}
+</Check>
+
+# Number of sessions we rejected due to maxActive beeing reached
+# $0: Name of web-module
+# $1: Critical (optional)
+# $2: Warning (optional)
+# $3: Name (optional)
+<Check jboss7_session_rejected>
+  MBean = *:deployment=$0,subsystem=web
+  Attribute = rejectedSessions
+  Name = ${3:sessions_rejected}
+  Label = $0: Rejected Sessions = %v
+  Critical = ${1:500}
+  Warning = ${2:200}
+</Check>
+
+# Average time an expired session had been alive
+# in seconds
+# $0: Name of web-module
+# $1: Critical (7200)
+# $2: Warning (7200)
+# $3: Name (optional)
+<Check jboss7_session_average_lifetime>
+  MBean = *:deployment=$0,subsystem=web
+  Attribute = sessionAverageAliveTime
+  Name = ${3:sessions_avg_life}
+  Label = $0: Average session lifetime = %v
+  Critical = ${1:7200}
+  Warning = ${2:6400}
+</Check>
+
+# Longest time an expired session had been alive
+# in seconds
+# $0: Name of web-module
+# $1: Critical (7200)
+# $2: Warning (6400)
+# $3: Name (optional)
+<Check jboss7_session_max_lifetime>
+  MBean = *:deployment=$0,subsystem=web
+  Attribute = sessionMaxAliveTime
+  Name = ${3:sessions_max_life}
+  Label = $0: Maximum session lifetime = %v
+  Critical = ${1:7200}
+  Warning = ${2:6400}
+</Check>
+
+# Increase rate of sessions per minute
+# $0: Name of web-module
+# $1: Critical (optional)
+# $2: Warning (optional)
+# $3: Name (optional)
+<Check jboss7_session_inc>
+  Use = count_per_minute("sessions")
+  MBean = *:deployment=$0,subsystem=web
+  Attribute = sessionCounter
+  Name = ${3:sessions_inc}
+  Critical = ${1:1000}
+  Warning = ${2:900}
+</Check>
@@ -9,6 +9,7 @@ include common.cfg
 <Check memory_relative_base>
    Use = relative_base($0,$1)
    Unit = B
+   BaseUnit = B
 </Check>
 
 # Relative Heap Memory used by the application. This
@@ -22,6 +23,7 @@ include common.cfg
    Base = java.lang:type=Memory/HeapMemoryUsage/max
    Label = Heap-Memory: $BASE
    Name = Heap
+   MultiCheckPrefix
 </Check>
 
 # Relative non-heap memory.  The JVM has memory other than the heap,
@@ -37,6 +39,7 @@ include common.cfg
    Base = java.lang:type=Memory/NonHeapMemoryUsage/max
    Label = Non-Heap-Memory: $BASE
    Name = Non-Heap
+   MultiCheckPrefix
 </Check>
 
 # =============================================================
@@ -63,25 +66,38 @@ include common.cfg
 <Check memory_gc_count_base>
    Use = count_per_minute("GC count")
    Value = java.lang:type=GarbageCollector,name=$0/CollectionCount
+
    Label = $0 : $BASE
    Name = $0 count
+
    Critical = 30
    Warning = 20
 </Check>
 
 # Base definition for garbage time measurements
-# This checks measure the time (in ms) garbage collections take per
-# minute
+# This checks measure the ratio the garbage collection takes from a minute
+# (e.g. how many percent of a minute is used for garbage collecting)
+
 # $0: Name of garbage collector (used as Label as well)
-# $1: Critical value (default: 200000)
-# $2: Warning value (default: 10000)
+# $1: Critical value in percent (default: 20)
+# $2: Warning value in percent (default: 10)
+
+# WARNING: THIS CHECK HAS CHANGED IN 1.08. Remove the 'Base' and adapt the label 
+# to obtain the old behaviour.
 <Check memory_gc_time_base>
-   Use = count_per_minute("GC ms")
    Value = java.lang:type=GarbageCollector,name=$0/CollectionTime
-   Label = $0 : $BASE
+
+   Label = %2.2r% GC Overhead
    Name = $0 time
-   Critical = ${1:20000}
-   Warning = ${2:10000}
+   
+   Delta 60
+
+   # Next line switches on relative checking to get the percentual overhead   
+   # for a garbage collection
+   Base = 60000
+
+   Critical = ${1:20}
+   Warning = ${2:10}
 </Check>
 
 # The paralled garbage collectors and memory 
@@ -99,6 +115,7 @@ include common.cfg
   Check = memory_gc_count_base("PS MarkSweep")
 </MultiCheck>
 
+# Since 1.08: Relative time instead of absolute values. 
 <MultiCheck memory_gc_time_parallel>
   Check = memory_gc_time_base("PS Scavenge")
   Check = memory_gc_time_base("PS MarkSweep")
@@ -119,6 +136,7 @@ include common.cfg
   Check = memory_gc_count_base("ConcurrentMarkSweep")
 </MultiCheck>
 
+# Since 1.08: Relative time instead of absolute values. 
 <MultiCheck memory_gc_time_concurrent>
   Check = memory_gc_time_base("ParNew")
   Check = memory_gc_time_base("ConcurrentMarkSweep")
@@ -140,12 +158,12 @@ include common.cfg
   Check = memory_gc_count_base("MarkSweepCompact")
 </MultiCheck>
 
+# Since 1.08: Relative time instead of absolute values. 
 <MultiCheck memory_gc_time_serial>
   Check = memory_gc_time_base("Copy")
   Check = memory_gc_time_base("MarkSweepCompact")
 </MultiCheck>
 
-
 <Check memory_code_cache>
    Use = memory_pool_base("Code Cache")
 </Check>
@@ -22,7 +22,7 @@ include common.cfg
 </Check>
 
 <Check wls_channel_connections>
-  Label = Channel $0 : %4.4d active connections
+  Label = Channel $0 : %4.4v active connections
   Name = connections
   Value = *:Name=$0,Type=ServerChannelRuntime,*/ConnectionsCount
   Critical = ${1:1000}
@@ -0,0 +1,13 @@
+# ---------------------------------------
+# Check of the application state 
+#
+# $0: application name
+<Check was_application_state>
+  MBean WebSphere:j2eeType=J2EEApplication,J2EEName=${0},*
+  Attribute state
+
+  Critical = ${1:1}
+  Label = $0 : status = %v
+  Name = $0-state
+</Check>
+
@@ -0,0 +1,129 @@
+# ============================================
+# HTTP Checks
+
+include threads.cfg
+
+# HTTP Thread Pool Utilization
+# Check of relative pool size, i.e. the ratio between actual created threads 
+# to the number of maximal available threads.
+<Check was_http_pool_size>
+  Use was_thread_pool_size('WebContainer',$0,$1)
+</Check>
+
+# Relative check of all active threads out of the threadpool for the web container
+<Check was_http_pool_active>
+  Use was_thread_pool_active('WebContainer',$0,$1)
+</Check>
+
+# Web-Sessions
+
+# Check for the number of session uses. The maximal number of sessions is not available 
+# and should be provided as argument to this check (default is 200).
+#
+# A unique part of the name contained in the 'mbeanIdentifier' key of the MBean 
+# must be used for the name (e.g. 'jolokia' for the Jolokia agent). 
+#
+# $0: Unique part of the name of the web app (see above)
+# $1: Maximum number of session (default: 200)
+# $2: Critical (default: 90%)
+# $3: Warning (default: 80%)
+<Check was_http_session_count>
+  MBean WebSphere:type=SessionManager,mbeanIdentifier=*${0}*,*
+  Attribute stats
+  Path */*/statistics/LiveCount/current
+  
+  # Base value as the number of maximal possible sessions
+  # (or if a proper MBean attribute is found, this could be inserted here) 
+  Base ${1:200}
+  
+  Critical ${2:90}
+  Warning ${3:80}
+
+  Label $0 : %.2r% sessions in use (%v / %b)
+  Name ${0}-http-sessions
+</Check>
+
+# HTTP Request Count
+# Check for the number of requests per minute for a specific servlet.
+#
+# $0: Part of the servlet name (see above)
+# $1: Critical as requests / minute (no default)
+# $2: Warning as requests / minute (no default)
+<Check was_http_request_count>
+  Use was_request_count($0,$1,$2)
+  MBean WebSphere:type=Servlet,mbeanIdentifier=*${0}*,*
+</Check>
+
+# Check for the number of requests per minute for a specific JSP
+#
+# $0: Part of the JSP name (see above)
+# $1: Critical as requests / minute (1000)
+# $2: Warning as requests / minute (800)
+<Check was_jsp_request_count>
+   Use was_request_count($0,$1,$2)
+   MBean WebSphere:type=JSP,mbeanIdentifier=*${0}*,*
+</Check>
+
+# Base Check for requests counts (servlet or JSPs)
+# $0: Part of the servlet name (see above)
+# $1: Critical as requests / minute (1000)
+# $2: Warning as requests / minute (800)
+<Check was_request_count>
+  Attribute stats
+  Path */*/statistics/RequestCount/count
+  Delta 60
+
+  Critical ${1:1000}
+  Warning ${2:800}
+
+  Label $0 : %2.2q requests / minute
+  Name ${0}-request-count
+</Check>
+
+# HTTP Service Time
+#
+# Check of average processing time per request for a servlet.
+#
+# $0: Part of the servlet name (see above)
+# $1: Critical (default: 10000ms)
+# $2: Warning (default: 5000ms)
+<Check was_http_service_time>
+  Use was_service_time($0,$1,$2)
+  MBean         WebSphere:type=Servlet,mbeanIdentifier=*${0}*,*
+  BaseMBean     WebSphere:type=Servlet,mbeanIdentifier=*${0}*,*
+</Check>
+
+# Check of average processing time per request for a JSP
+#
+# $0: Part of JSP name (see above)
+# $1: Critical (default: 10000ms)
+# $2: Warning (default: 5000ms)
+<Check was_jsp_service_time>
+  Use was_service_time($0,$1,$2)
+  MBean         WebSphere:type=JSP,mbeanIdentifier=*${0}*,*
+  BaseMBean     WebSphere:type=JSP,mbeanIdentifier=*${0}*,*
+</Check>
+
+# Base check for total service time checks (suggestion for
+# improvements: Currently the overall average is measured. It would be
+# much better to use only the average till the last
+# measurement. Therefore a "Delta" should be used (without
+# normalization), but unfortunately the base value is not used as 'delta' 
+# yet.
+<Check was_service_time>
+  Attribute stats
+  Path */*/statistics/ServiceTime/totalTime
+  
+  BaseAttribute stats
+  BasePath      */*/statistics/ServiceTime/count
+
+  Delta
+
+  # * 100 because the value is a 'relative' check typical used for percentages
+  Critical{1:1000000}   
+  Warning ${2:500000}
+
+  Label %2.2q ms ∅ processing time per request (%v ms total for %b requests)
+  Name $0-request-processing-time
+</Check>
+
@@ -0,0 +1,43 @@
+# ===============================================================
+# JCA
+
+# JCA connector pool usage
+# 
+# ${0} : part of the JCA connector name
+# ${1} : Managed Connection Factory Name (JCA)
+# ${2} : Critical (default: 90 percent)
+# ${3} : Warning (default: 80 percent)
+<Check was_jca_percent_used>
+  MBean     WebSphere:j2eeType=JCAResource,mbeanIdentifier=*${0}*,*
+  Attribute stats 
+  Path      */*/connectionPools/${1}/statistics/PercentUsed/current
+
+  Critical ${2:90}
+  Warning ${3:80}
+
+  Label $1 : %2.0f% connections used
+  Name jca-${1}-${0}-pool
+</Check>
+
+# Average waiting time until a JCA connector is available
+#
+# ${0} : part of the JCA resource name as it appears in the mbeanIdentifier
+# ${1} : Managed Connection Factory Name (JCA)
+# ${2} : Critical (default: 10s)
+# ${3} : Warning (default: 5s)
+<Check was_jca_wait_time>
+  MBean     WebSphere:j2eeType=JCAResource,mbeanIdentifier=*${0}*,*
+  Attribute stats 
+  Path      */*/connectionPools/${1}/statistics/WaitTime/totalTime
+
+  BaseMBean     WebSphere:j2eeType=JCAResource,mbeanIdentifier=${0},*
+  BaseAttribute stats
+  BasePath      */*/connectionPools/${1}/statistics/WaitTime/count
+
+  Critical ${2:10000}   
+  Warning ${3:5000}
+
+  Label $1: %2.2q ms ∅ wait time  (%v ms total for %b requests)
+  Name jca-${1}-${0}-wait-time
+</Check>
+
@@ -0,0 +1,88 @@
+# ==============================================================================
+# JDBC Datasources
+
+# JDBC Poolsize Check. This check requires two parameters at least: 
+# The name of th JDBC Provider and the data source name. It must be ensured that 
+# the pattern used in this check must result in a single data source only.
+# 
+# In order to specify this even further, a fourth parameter can be used to 
+# match on part of the mbeanIdentifier.
+#
+# ${0} : Name of the JDBC Provider
+# ${1} : DataSource Name
+# ${2} : Critical (default: 90%)
+# ${3} : Warning (default: 80%)
+# ${4} : Part of mbeanIdentifier (default: *)
+
+<Check was_jdbc_percent_used>
+  MBean     WebSphere:j2eeType=JDBCResource,name=${0},mbeanIdentifier=${4:*},*
+  Attribute stats 
+  Path      */*/connectionPools/${1}/statistics/PercentUsed/current
+
+  Critical ${2:90}
+  Warning ${3:80}
+
+  Label $1 : %2.0f % DB Connections used
+  Name jdbc-$0-connections
+</Check>
+
+# Average wait time until a connection is obtained
+
+# ${0} : Name of the JDBC Provider
+# ${1} : Datasource name
+# ${2} : Critical (default: 10s)
+# ${3} : Warning (default: 5s)
+# ${4} : Part of mbeanIdentifier (default: *)
+<Check was_jdbc_wait_time>
+  MBean     WebSphere:j2eeType=JDBCResource,name=${0},mbeanIdentifier=${4:*},*
+  Attribute stats 
+  Path      */*/connectionPools/${1}/statistics/WaitTime/totalTime
+
+  BaseMBean     WebSphere:j2eeType=JDBCResource,name=${0},mbeanIdentifier=${4:*},*
+  BaseAttribute stats
+  BasePath      */*/connectionPools/${1}/statistics/WaitTime/count
+
+  Critical ${2:10000}   
+  Warning ${3:5000}
+
+  Label $1: %2.2q ms ∅ waiting time (%v ms total for %b requests)
+  Name jdbc-$0-average-wait-time
+</Check>
+
+# Check for the number of rolled back transactions
+#
+# $0: Part of the MBean identifier 
+# $1: Critical as rollback count / minute
+# $2: Warning as rollback count / minute
+<Check was_transaction_rollback_count>
+  Use was_transaction_count($0,"RolledbackCount",$1,$2)
+</Check>
+
+# Check for the number of active transactions
+#
+# $0: Part of the MBean identifier 
+# $1: Critical as rollback count / minute
+# $2: Warning as rollback count / minute
+<Check was_transaction_active_count>
+  Use was_transaction_count($0,"ActiveCount",$1,$2)
+</Check>
+
+# Base-Check for the number of transactions
+#
+# $0: Part of the MBean identifier 
+# $1: Attribute name
+# $2: Critical as rollback count / minute
+# $3: Warning as rollback count / minute
+<Check was_transaction_count>
+  MBean WebSphere:type=TransactionService,mbeanIdentifier=*${0}*,*
+  Attribute stats
+  Path */*/statistics/${1}/count
+  Delta 60
+
+  Critical ${2:10}
+  Warning ${3:5}
+
+  Label $0 : %2.2q ${1} / minute
+  Name $1-$0-transaction
+</Check>
+
@@ -0,0 +1,44 @@
+# =======================================================
+# WebSphere JMS checks
+
+# Check the number of message in a queue
+#
+# $0: Queue Name
+# $1: Critical Threshold (default: 10)
+# $2: Warning Threshold (default: 5)
+<Check was_jms_depth>
+   MBean WebSphere:type=SIBQueuePoint,name=${0},*
+   Attribute depth
+
+   # Messages Thresshold 
+   Critical ${1:10}
+   Warning ${2:5}
+
+   Label %v messages in queue ${0}
+   Name jms-{0}-queue
+</Check>
+
+# PMI metrics available over UI but not still via JMX ? --> 
+
+# Queues.QueueStats.LocalProducerAttachesCount
+# Queues.QueueStats.LocalProducerCount
+# Queues.QueueStats.LocalConsumerAttachesCount
+# Queues.QueueStats.LocalConsumerCount
+# Queues.QueueStats.TotalMessagesProducedCount
+# Queues.QueueStats.BestEffortNonPersistentMessagesProducedCount
+# Queues.QueueStats.ExpressNonPersistentMessagesProducedCount
+# Queues.QueueStats.ReliableNonPersistentMessagesProducedCount
+# Queues.QueueStats.ReliablePersistentMessagesProducedCount
+# Queues.QueueStats.AssuredPersistentMessagesProducedCount
+# Queues.QueueStats.TotalMessagesConsumedCount
+# Queues.QueueStats.BestEffortNonPersistentMessagesConsumedCount
+# Queues.QueueStats.ExpressNonPersistentMessagesConsumedCount
+# Queues.QueueStats.ReliableNonPersistentMessagesConsumedCount
+# Queues.QueueStats.ReliablePersistentMessagesConsumedCount
+# Queues.QueueStats.AssuredPersistentMessagesConsumedCount
+# Queues.QueueStats.ReportEnabledMessagesExpiredCount
+# Queues.QueueStats.AggregateMessageWaitTime
+# Queues.QueueStats.LocalMessageWaitTime
+# Queues.QueueStats.LocalOldestMessageAge
+# Queues.QueueStats.AvailableMessageCount
+# Queues.QueueStats.UnavailableMessageCount
\ No newline at end of file
@@ -0,0 +1,45 @@
+# ============================================
+# Thread Pool Checks
+
+# Generic Thread-Pool Check for the size of a Thread-Pool
+#
+# $0: Name of ThreadPool (z.B. "WebContainer")
+# $1: Critical (default: 90%)
+# $2: Warning (default: 80%)
+<Check was_thread_pool_size>
+  Use was_thread_pool($0,'PoolSize',$1,$2)
+  Label $0: %2.2r% threads used (%v / %b)
+</Check>
+
+# Generic Thread-Pool Check for the number of active threads
+# within the thread pool
+#
+# $0: Name of ThreadPool (z.B. "WebContainer")
+# $1: Critical (default: 90%)
+# $2: Warning (default: 80%)
+<Check was_thread_pool_active>
+  Use was_thread_pool($0,'ActiveCount',$1,$2,)
+  Label $0: %2.2r% active threads (%v / %b)
+</Check>
+
+# Base Check for thread-pools checks
+# $0: Name of ThreadPool (z.B. "WebContainer")
+# $1: Attribute (PoolSize or ActiveCount)
+# $2: Critical (default: 90%)
+# $3: Warning (default: 80%)
+<Check was_thread_pool>
+  MBean         WebSphere:name=${0},type=ThreadPool,*
+  Attribute     stats
+  Path          */*/statistics/${1}/current
+
+  BaseMBean     WebSphere:name=${0},type=ThreadPool,*
+  BaseAttribute stats
+  BasePath      */*/statistics/${1}/upperBound
+   
+  Critical      ${2:90}
+  Warning       ${3:80}
+  
+  Label = ${0}: %.2r% Threads [${1}] (%v / %b)
+  Name = ${0}-${1}-threadpool
+</Check>
+
@@ -0,0 +1,30 @@
+# Websphere Checks
+# ----------------
+
+# These checks are for WebSphere and has been tested for WebSphere >= 8.0
+# (but should workd with older WebSphere servers as well).
+
+# For most of the test it is required that a customzied Jolokia agent is used 
+# which provides simplified access to JSR-77 metrics.
+#
+# These agents can be obtained from the 'jolokia-extra' project: https://github.com/rhuss/jolokia-extra
+# or downloaded from Maven central: http://central.maven.org/maven2/org/jolokia/extra/
+# They all have an classifier "-jsr77" and the first three parts of the version specify 
+# the Jolokia core version included. 
+# E.g. "jolokia-extra-war-1.2.2.2-jsr77.war" contains Jolokia 1.2.2 (and is the second variant with 
+# the JSR-77 specifier)
+
+# Most of these tests utilize the PMI subsystem of WebSphere.
+
+# ===============================================================
+# Including various checks. These config files are self contained, 
+# and for performance optimizations could be included separately if only 
+# some checks are needed.
+
+include websphere/threads.cfg
+include websphere/http.cfg
+include websphere/jdbc.cfg
+include websphere/jms.cfg
+include websphere/jca.cfg
+include websphere/appstate.cfg
+
@@ -15,5 +15,5 @@
 </Check>
 
 <Check base_relative_label>
-    Label = (grandpa) %.2r% used (%.2v %u / %.2b %u)
+    Label = (grandpa) %.2r% used (%.2v %u / %.2b %w)
 </Check>
\ No newline at end of file
@@ -19,12 +19,12 @@ sub exec_check_perl4jmx {
     push @args,("--url",$url);
     push @args,("--target",$target) if $target;
     push @args,("--target-user",$target_user,"--target-password",$target_password) if $target_user;
-#    push @args,"--legacy-escape";
-#    push @args,("--verbose");
+    #push @args,"--legacy-escape";
+    #push @args,("--verbose");
    
     my $cmd = "perl $FindBin::Bin/../../scripts/check_jmx4perl "
-          .join(" ",map { '"' . $_ . '"' } @args); 
-#    print $cmd,"\n";
+          .join(" ",map { '"' . $_ . '"' } @args);  
+    #print $cmd,"\n";
     open (F,"$cmd 2>&1 |") 
       || die "Cannot open check_jmx4perl: $!";
     my $content = join "",<F>;
@@ -42,9 +42,9 @@ sub exec_check_perl4jmx {
 
 sub reset_history {
     my $jmx = shift;
-    my ($mbean,$operation) = $jmx->resolve_alias(JMX4PERL_HISTORY_RESET);
+    my ($mbean,$operation) = $jmx->resolve_alias(JMX4PERL_HISTORY_RESET);   
     my $req = new JMX::Jmx4Perl::Request(EXEC,$mbean,$operation,{target => undef});
-    $jmx->request($req);
+    my $resp = $jmx->request($req);
 }
 
 1;
@@ -55,6 +55,7 @@ include base.cfg
 <Check thread_count>
    Value = java.lang:type=Threading/ThreadCount
    Name = ${0} $1 $2
+   Label = "thread_count: $0 $1 $2 : Value %f in range"
    Critical = ${0}
    Warning = $1  
    Method = POST
@@ -87,6 +88,7 @@ include base.cfg
 <Check overloaded_operation>
    MBean = jolokia.it:type=operation
    Operation = overloadedMethod(java.lang.String)
+   Argument = ${0}
    Critical = 5
    Warning = :1
 </Check>
@@ -116,14 +118,14 @@ for my $pool (@$pools) {
 }
 return $j4p->get_attribute($matched_pools[0],"Usage","used");
 EOT
-  Name script_check - $0
+  Name script_check $0
   Critical ${1:10}
   Unit B
 </Check>
 
 <MultiCheck script_multi_check>
   Check memory_heap(90,80)
-  Check script_check(Eden,1000000000)
+  Check script_check('Eden|Java',1000000000)
   Check memory_non_heap(90,80)
   Check script_check($0,1000000000)
   Check thread_count(1000,2000,3000)
@@ -169,6 +171,14 @@ EOT
     Critical = !no deadlock
 </Check>
 
+<Check counter_operation>
+    MBean jolokia.it:type=operation
+    Operation fetchNumber
+    Argument ${0:inc}
+    Critical 3
+    Warning  2
+</Check>
+
 # 75062
 
 <Check memory_without_perfdata>
@@ -29,9 +29,20 @@ include checks.cfg
    HtmlOutput
    Check memory_non_heap(1,2)
    Check memory_non_heap(30,20)
+   Check memory_heap(1,2)
+</MultiCheck>
+
+<MultiCheck error_multi_check>
    Check memory_heap
+   Check kaputt
+   Check memory_heap(1,2)
 </MultiCheck>
 
+<Check kaputt>
+   MBean bla:type=blub
+   Attribute foobar
+</Check>
+
 <MultiCheck nested_with_args>
    MultiCheck with_outer_args("NestedWithArgs")
 </MultiCheck>
@@ -7,6 +7,7 @@ use strict;
 use TAP::Harness;
 use Data::Dumper;
 
+
 my $dir = $FindBin::Bin . "/t";
 my ($gateway_url,$user,$password,$product,$target_url,$target_user,$target_password);
 GetOptions("dir=s" => \$dir,
@@ -36,7 +37,7 @@ my $harness = new TAP::Harness
     color => 1,
     merge => 1,
     jobs => 1,
-    lib => [ "$FindBin::Bin/../lib", "$FindBin::Bin/../t/lib" ]
+    lib => [ "$FindBin::Bin/../lib", "$FindBin::Bin/../t/lib", "$FindBin::Bin" ]
    });
 
 $ENV{JMX4PERL_GATEWAY} = $gateway_url;
@@ -24,4 +24,6 @@ print "Agent-Version:\n";
 print Dumper($value);
 ok($value->{protocol} > 0,"Protocol version " . $value->{protocol});
 #print Dumper(\@resps);
-
+my $resp = $jmx->request(new JMX::Jmx4Perl::Request(READ,"java.lang:type=Runtime","SystemProperties"));
+$value = $resp->{value};
+print "Java: ",$value->{'java.version'}," (",$value->{'java.vendor'},")\n";
@@ -3,6 +3,7 @@ use warnings;
 use Test::More qw(no_plan);
 use Data::Dumper;
 use It;
+use FindBin;
 
 require "check_jmx4perl/base.pl";
 
@@ -29,6 +30,13 @@ ok($content =~ /counter=(\d+)/ && $1 eq "1","Second operation returns 1");
 is($ret,2,"Third operation");
 ok($content =~ /counter=(\d+)/ && $1 eq "2","Third operation returns 2");
 
+my $config_file = $FindBin::Bin . "/../check_jmx4perl/checks.cfg";
+($ret,$content) = exec_check_perl4jmx("--config $config_file --check counter_operation");
+ok($content =~ /value (\d+)/ && $1 eq "3","Fourth operation return 3");
+is($ret,1,"Fourth operation");
+
+#print Dumper($ret,$content);
+
 ($ret,$content) = exec_check_perl4jmx("--mbean jolokia.it:type=operation --operation emptyStringArgumentCheck",
                                        "-c 1 /");
 is($ret,0,"Single slash argument (return code)");
@@ -7,7 +7,7 @@ use It;
 
 require "check_jmx4perl/base.pl";
 
-my $jmx = It->new(verbose => 0)->jmx4perl;
+my $jmx = It->new(verbose => 1)->jmx4perl;
 my ($ret,$content);
 
 # ====================================================
@@ -15,26 +15,31 @@ my ($ret,$content);
 
 reset_history($jmx);
 
-($ret,$content) = exec_check_perl4jmx("--alias MEMORY_HEAP_USED --delta -c 10 --name mem");
+my $membean = "--mbean java.lang:type=Memory --attribute HeapMemoryUsage";
+my $cparams = $membean . " --path used --unit B --delta --name mem";
+
+
+($ret,$content) = exec_check_perl4jmx($cparams);
 is($ret,0,"Initial history fetch returns OK");
+#print $content;
 ok($content =~ /mem=(\d+)/ && $1 eq "0","Initial history fetch returns 0 mem delta");
 
-$jmx->get_attribute(MEMORY_HEAP_USED);
-my $mem = $jmx->get_attribute(MEMORY_HEAP_MAX);
-my $c = abs(0.50 * $mem);
-#print "Mem: $mem\n";
+my $max_mem = $jmx->get_attribute("java.lang:type=Memory", "HeapMemoryUsage","max");
+my $c = abs(0.50 * $max_mem);
+#print "Mem Max: $mem\n";
+my $mem = $jmx->get_attribute("java.lang:type=Memory", "HeapMemoryUsage","used");
+#print "Used Memory: $mem\n";
 
 # Trigger Garbage collection
-#$jmx->execute("java.lang:type=Memory","gc");
+$jmx->execute("java.lang:type=Memory","gc");
 
-for (0 .. 2) {
+for my $i (0 .. 2) {
     $jmx->execute("java.lang:type=Memory","gc");
-    ($ret,$content) = exec_check_perl4jmx("--alias MEMORY_HEAP_USED --unit B --delta -c -$c:$c --name mem");
-    print Dumper($ret,$content);
+    ($ret,$content) = exec_check_perl4jmx($cparams . " -c -$c:$c");
+    is($ret,0,($i+1) . ". history fetch returns OK for -c $c");
+    ok($content =~ /mem=([\-\d]+)/ && $1 ne "0",($i+1) . ". history fetch return non null Mem-Delta ($1)");
+    #print Dumper($ret,$content);
     print "Heap: ",$jmx->get_attribute("java.lang:type=Memory","HeapMemoryUsage","used"),"\n";
-
-    is($ret,0,"Second history fetch returns OK for -c $c");
-    ok($content =~ /mem=([\-\d]+)/ && $1 ne "0","Second History fetch return non null Mem-Delta ($1)");
 }
 #print "$c: $content\n";
 
@@ -76,19 +76,21 @@ is($ret,3,"UNKNOWN");
 ok($content =~ /Unknown.*method/,"Unknown request method");
 
 ($ret,$content) = exec_check_perl4jmx("--config $config_file --method get --check thread_count 300 400"); 
+#print Dumper($ret,$content);
 is($ret,0,"OK");
 ok($content =~ /in range/,"In range");
 
 # =============================================================================
 # With scripting
 
-($ret,$content) = exec_check_perl4jmx("--config $config_file --check script_check Eden");
+($ret,$content) = exec_check_perl4jmx("--config $config_file --check script_check Eden|Java");
+#print Dumper($ret,$content);
 is($ret,2);
 ok($content =~ /threshold/i,"Script-Check: Threshold contained");
 
 
-($ret,$content) = exec_check_perl4jmx("--config $config_file --check script_multi_check Perm");
-is($ret,0);
+($ret,$content) = exec_check_perl4jmx("--config $config_file --check script_multi_check Perm|non-heap");
+ok($ret != 3);
 #print Dumper($ret,$content);
 ok($content =~ /Perm/,"Multi-Script-Check: Perm contained");
 ok($content =~ /Eden/,"Multi-Script-Check: Eden contained");
@@ -58,6 +58,7 @@ ok($content =~ /HelloLabel/,"First param");
 ok($content =~ /NestedWithOuterArgs/,"NestedWithOuterArgs");
 
 ($ret,$content) = exec_check_perl4jmx("--config $config_file --check overloaded_multi_check"); 
+#print Dumper($ret,$content);
 is($ret,0,"Multicheck with argument for operation");
 ok($content =~ /Value 1 in range/,"OperationWithArgument");
 
@@ -68,12 +69,30 @@ ok($content =~ /memory_non_heap/,"Failed check name is contained in summary");
 
 # Check labeling of failed tests
 ($ret,$content) = exec_check_perl4jmx("--config $config_file --check label_test"); 
+#print "==========================================\n";
+#print Dumper($ret,$content);
 is($ret,2,"Should fail as critical");
 my @lines = split /\n/,$content;
 is($#lines,2,"3 lines has been returned");
 ok($lines[0] =~ /bla/ && $lines[0] =~ /blub/,"Name of checks should be returned as critical values");
 #print Dumper($ret,$content);
 
+($ret,$content) = exec_check_perl4jmx("--config $config_file --check error_multi_check"); 
+is($ret,3,"Should fail as UNKNOWN");
+@lines = split /\n/,$content;
+is($#lines,3,"4 lines has been returned");
+ok($lines[1] =~ /kaputt/ && $lines[1] =~ /UNKNOWN/,"First line is UNKNOWN Check");
+#print Dumper($ret,$content);
+
+($ret,$content) = exec_check_perl4jmx("--unknown-is-critical --config $config_file --check error_multi_check"); 
+is($ret,2,"Should fail as CRITICAL");
+@lines = split /\n/,$content;
+is($#lines,3,"4 lines has been returned");
+ok($lines[0] =~ /kaputt/ && $lines[0] =~ /CRITICAL/,"First line is UNKNOWN Check");
+
+#print Dumper($ret,$content);
+
+
 # TODO:
 
 # Unknown multicheck name
@@ -79,6 +79,17 @@ is($resp->status,200);
 $value = $jmx->get_attribute("jolokia.it:type=tabularData","Table2","Value0.0/Value0.1");
 is($value->{Column1},"Value0.0","First column");
 is($value->{Column2},"Value0.1","Second column");
-$value = $jmx->get_attribute("jolokia.it:type=tabularData","Table2","Value0.1/Value0.0");
-is($value,undef,"Path with no value");
+
+
+$req = new JMX::Jmx4Perl::Request(READ,"jolokia.it:type=tabularData","Table2","Value0.1/Value0.0");
+$resp = $jmx->request($req);
 #print Dumper($resp);
+$value = $resp->{value};
+is($value,undef,"Path with no value");
+
+$value = $jmx->get_attribute("jolokia.it:type=mxbean","MapWithComplexKey");
+is(scalar(keys %$value),2,"2 elements");
+ok($value->{indexNames}->[0],"key");
+is(@{$value->{values}},2,"2 values");
+ok($value->{values}->[0]->{key}->{number} =~ /^(1|2)$/,"key match");
+#print Dumper($value);
@@ -11,6 +11,13 @@ my $url = $ENV{JMX4PERL_GATEWAY} || $ARGV[0];
 $url .= "/" unless $url =~ /\/$/;
 my $origin = "http://localhost:8080";
 my $ua = new LWP::UserAgent();
+
+if ($ENV{JMX4PERL_USER}) {
+    my $netloc = $url;
+    $netloc =~ s|^.*/([^:]+:\d+).*$|$1|;
+    $ua->credentials($netloc,"jolokia",$ENV{JMX4PERL_USER},$ENV{JMX4PERL_PASSWORD});
+}
+
 $ua->default_headers()->header("Origin" => $origin);
 
 # Test for CORS functionality. This is done without Jmx4Perl client library but
@@ -20,6 +27,7 @@ $ua->default_headers()->header("Origin" => $origin);
 my $req = new HTTP::Request("OPTIONS",$url);
 
 my $resp = $ua->request($req);
+#print Dumper($resp);
 is($resp->header('Access-Control-Allow-Origin'),$origin,"Access-Control-Allow Origin properly set");
 ok($resp->header('Access-Control-Allow-Max-Age') > 0,"Max Age set");
 ok(!$resp->header('Access-Control-Allow-Request-Header'),"No Request headers set");
@@ -0,0 +1,35 @@
+#!/usr/bin/perl
+
+use It;
+use Test::More qw(no_plan);
+use JMX::Jmx4Perl;
+use Data::Dumper;
+use strict;
+
+my $jmx = new It(verbose => 0)->jmx4perl;
+
+# Might find nothing, dependening on where it is run.
+my $disc_class = urls(JMX::Jmx4Perl->discover_agents());
+ok(defined($disc_class));
+my $disc_obj = urls($jmx->discover_agents());
+ok(defined($disc_obj));
+
+my $agents_found = $jmx->execute("jolokia:type=Discovery","lookupAgents");
+print Dumper($agents_found);
+print Dumper($disc_class);
+my $agent_urls = urls($agents_found);
+
+for my $disc_p ($disc_class,$disc_obj) {
+    for my $k (keys %$disc_p) {
+        ok(defined($agent_urls->{$k}),"Agent URL " . $k . " detected");
+    }
+}
+
+sub urls {
+    my $agents = shift;
+    my $ret = {};
+    for my $agent (@$agents) {
+        $ret->{$agent->{url}}++;
+    }
+    return $ret;
+}
@@ -20,11 +20,15 @@ signature with L<Crypt::OpenPGP>
 
 This verifier uses L<Crypt::OpenPGP> for validating a PGP signature obtained
 from the download site. Ie. each URL used for download should have (and does
-have) and associated signature ending with F<.asc>. This contains a signature
-which is verified with the public key contained in the __DATA__ section of this
-module (i.e. my personal key with ID EF101165). This verifier is the most
-robust one, however installing L<Crypt::OpenPGP> is a bit clumsy, so you might
-omit this one.
+have) and associated signature ending with F<.asc>. This verifier typically
+quite robust, however installing L<Crypt::OpenPGP> is a bit clumsy, so you
+might omit this one.
+
+=head1 IMPORTANT
+
+It is not used currently since the new agents has been signed with 'digest
+algortihm 10' which is not supported by OpenPGP. Use a native GnuPG instead
+(i.e. a 'gpg' which is in the path)
 
 =cut 
 
@@ -73,8 +77,8 @@ sub verify {
                    ($validate != 1 ? (", signed by ",$validate) : ""),
                    ($key ? " ($key)" :""));
         return 1;
-    } elsif ($validate == 0) {
-        $log->error("Invalid signature",$path ? " for $path" : "");
+    } elsif ($validate == 0) {        
+        $log->error("Invalid signature",$path ? " for $path" : "",": " . $pgp->errstr);
         die "\n";
     } else {
         $log->error("Error occured while verifying signature: ",$pgp->errstr);
@@ -61,14 +61,17 @@ BEGIN {
     };
 
     my $prefix = "JMX::Jmx4Perl::Agent::Jolokia::Verifier::";
-    if (eval "require Crypt::OpenPGP; 1") {
-        push @VERIFIERS,$create->($prefix . "OpenPGPVerifier");                    
-    } elsif (`gpg --version` =~ /GnuPG/m) {
+    if (`gpg --version` =~ /GnuPG/m) {
         push @VERIFIERS,$create->($prefix . "GnuPGVerifier");        
     } else {
-        push @WARNINGS,"No signature verification available. Please install GnupPG or Crypt::OpenPGP.";
+        push @WARNINGS,"No signature verification available. Please install GnupPG.";
     }
 
+    # Disabled support for OpenPGP since it doesn't support the digest
+    # algorithm used for signging the jolokia artefacts 
+    # } elsif (eval "requireCrypt::OpenPGP; 1") { 
+    #    push @VERIFIERS,$create->($prefix . "OpenPGPVerifier");
+
     push @VERIFIERS,$create->($prefix . "SHA1Verifier") if eval "require Digest::SHA1; 1";
     push @VERIFIERS,$create->($prefix . "MD5Verifier") if eval "require Digest::MD5; 1";
 }
@@ -32,6 +32,20 @@ L<JMX::Jmx4Perl::Agent>.
 =cut 
 
 
+# Constructor setting the proper SSL options (if possible)
+sub new {
+    my $class = shift;
+    my @opts = @_ || ();
+    if (LWP::UserAgent->VERSION >= 6.00) {
+        # We don't verify Hostnames by default, since the information we are
+        # sending is typically not critical. Also, we don't have yet a way to 
+        # configure a keystore, so this is the only chance for now. Ask me to add
+        # host certificate verification if wanted. It disabled only for LWP >= 6.00        
+        push @opts,(ssl_opts => { verify_hostname => 0 });
+    };
+    return $class->SUPER::new(@opts);
+}
+
 # Request using a more robust timeout See
 # http://stackoverflow.com/questions/73308/true-timeout-on-lwpuseragent-request-method 
 # for details.
@@ -122,11 +122,7 @@ sub init {
     my $self = shift;
         
     croak "No URL provided" unless $self->cfg('url');
-    # We don't verify Hostnames by default, since the information we are
-    # sending is typically not critical. Also, we don't have yet a way to 
-    # configure a keystore, so this is the only chance for now. Ask me to add
-    # host certificate verification if wanted.
-    my $ua = JMX::Jmx4Perl::Agent::UserAgent->new(ssl_opts => { verify_hostname => 0 });
+    my $ua = JMX::Jmx4Perl::Agent::UserAgent->new();
     $ua->jjagent_config($self->{cfg});
     #push @{ $ua->requests_redirectable }, 'POST';
     $ua->timeout($self->cfg('timeout')) if $self->cfg('timeout');
@@ -360,7 +356,7 @@ sub request_url {
         # Nothing further to append.
     }
     # Squeeze multiple slashes
-    $req =~ s|(!/)?/+|$1/|g;
+    $req =~ s|((?:!/)?/)/*|$1|g;
     #print "R: $req\n";
 
     if ($req =~ $INVALID_PATH_CHARS || $request->{use_query}) {
@@ -627,7 +627,6 @@ sub _cd_mbean {
     my $domain = shift;
     my $mbean = shift;
     
-    $self->_check_mbean($domain,$mbean);
     my $mbean_props = $self->_check_mbean($domain,$mbean);
     my $mbean_cmds = $self->mbean_commands($mbean_props);
     &{$self->push_on_stack($mbean_props->{prompt},$mbean_cmds)};    
@@ -644,9 +643,23 @@ sub _check_domain {
 sub _get_mbean {
     my $self = shift;
     my $domain = shift;
-    my $mbean = shift;
+    my $props = shift;
     my $context = $self->context;
-    return $context->mbeans_by_name->{$domain . ":" . $mbean};
+    if ($props =~ /\*/) {
+        my $mbeans = $context->search_mbeans($domain . ":" . $props);
+        # TODO: If more than one, present a menu to select from. Now simply die
+        return undef unless @{$mbeans};
+        if (scalar(@$mbeans) > 1) {
+            my $toomany = "";
+            for my $m (@$mbeans) {
+                my ($s,$r) = $self->color("mbean_name","reset");                          
+                $toomany .=" >>> " . $s . $m->{full} . $r . "\n";
+            }
+            die "More than one MBean found:\n" . $toomany;
+        } 
+        return $mbeans->[0];
+    }
+    return $context->mbeans_by_name->{$domain . ":" . $props};
 }
 
 # Handle navigational commands
@@ -153,6 +153,19 @@ sub mbeans_by_name {
     return shift->{mbeans_by_name};
 }
 
+sub search_mbeans {
+    my $self = shift;
+    my $pattern = shift;
+    $pattern = quotemeta($pattern);
+    $pattern =~ s/\\?\*/.*/g;
+    my @ret = ();
+    my $mbeans_by_name = $self->mbeans_by_name();
+    for my $name (sort keys %$mbeans_by_name) {
+        push @ret,$mbeans_by_name->{$name} if $name =~ /$pattern/        
+    }
+    return \@ret;
+}
+
 sub request { 
     my $self = shift;
     my $request = shift;
@@ -3,12 +3,13 @@ package JMX::Jmx4Perl::Nagios::CheckJmx4Perl;
 use strict;
 use warnings;
 use JMX::Jmx4Perl::Nagios::SingleCheck;
+use JMX::Jmx4Perl::Nagios::MessageHandler;
 use JMX::Jmx4Perl;
 use JMX::Jmx4Perl::Request;
 use JMX::Jmx4Perl::Response;
 use Data::Dumper;
 use Nagios::Plugin;
-use Nagios::Plugin::Functions qw(:codes %STATUS_TEXT);
+use Nagios::Plugin::Functions qw(:codes %ERRORS %STATUS_TEXT);
 use Time::HiRes qw(gettimeofday tv_interval);
 use Carp;
 use Text::ParseWords;
@@ -90,22 +91,38 @@ sub execute {
             push @requests,@{$check->get_requests($jmx,\@ARGV)};            
         }
         my $responses = $self->_send_requests($jmx,@requests);
+        #print Dumper($responses);
         my @extra_requests = ();
         my $nr_checks = scalar(@{$self->{checks}});
         if ($nr_checks == 1) {
-            my @r = $self->{checks}->[0]->extract_responses($responses,\@requests,{ target => $target_config });
-            push @extra_requests,@r if @r;
+            eval {
+                my @r = $self->{checks}->[0]->extract_responses($responses,\@requests,{ target => $target_config });
+                push @extra_requests,@r if @r;
+            };
+            $self->nagios_die($@) if $@;
         } else {
             my $i = 1;
             for my $check (@{$self->{checks}}) {
                 # A check can consume more than one response
-                my @r = $check->extract_responses($responses,\@requests,
-                                                    { 
-                                                     target => $target_config, 
-                                                     prefix => $self->_multi_check_prefix($check,$i++,$nr_checks),
-                                                     error_stat => $error_stat
-                                                    });
-                push @extra_requests,@r if @r;
+                my $prefix = $self->_multi_check_prefix($check,$i++,$nr_checks);
+                eval {
+                    my @r = $check->extract_responses($responses,\@requests,
+                                                        { 
+                                                         target => $target_config, 
+                                                         prefix => $prefix,
+                                                         error_stat => $error_stat
+                                                        });
+                    push @extra_requests,@r if @r;
+                };
+                if ($@) {
+                    my $txt = $@;
+                    $txt =~ s/^(.*?)\n.*$/$1/s;
+                    my $code = $np->opts->{'unknown-is-critical'} ? CRITICAL : UNKNOWN;
+                    $check->update_error_stats($error_stat,$code);
+                    $prefix =~ s/\%c/$STATUS_TEXT{$code}/g;
+                    my $msg_handler = $np->{msg_handler} || $np; 
+                    $msg_handler->add_message($code,$prefix . $txt);
+                }
             }
         }
         # Send extra requests, e.g. for switching on the history
@@ -135,12 +152,13 @@ output, which can be extracted from NagiosPlugin object.
 
 =cut 
 
-sub do_exit {
+sub do_exit {    
     my $self = shift;
     my $error_stat = shift;
     my $np = $self->{np};
 
-    my ($code,$message) = $np->check_messages(join => "\n", join_all => "\n");
+    my $msg_handler = $np->{msg_handler} || $np; 
+    my ($code,$message) = $msg_handler->check_messages(join => "\n", join_all => "\n");
     ($code,$message) = $self->_prepare_multicheck_message($np,$code,$message,$error_stat) if scalar(@{$self->{checks}}) > 1;
     
     $np->nagios_exit($code, $message);
@@ -154,43 +172,85 @@ sub _prepare_multicheck_message {
     my $error_stat = shift;
 
     my $summary;
+    my $labels = $self->{multi_check_labels} || {};
     my $nr_checks = scalar(@{$self->{checks}});
+    $code = $self->_check_for_UNKNOWN($error_stat,$code);
     if ($code eq OK) {
-        $summary = "All " . $nr_checks . " checks OK";
+        $summary = $self->_format_multicheck_ok_summary($labels->{summary_ok} ||
+                                                        "All %n checks OK",$nr_checks);
     } else {
-        my $nr_warnings = scalar(@{$np->messages->{warning} || []});
-        my $nr_errors = scalar(@{$np->messages->{critical} || []});
-        my @parts;
-        my $extra = "";
-        my $nr = 0;
-        for my $code (CRITICAL,WARNING,UNKNOWN) {
-            if (my $errs = $error_stat->{$code}) {
-                $extra .= scalar(@$errs) . " " . $STATUS_TEXT{$code} . " (" . join (",",@$errs) . "), ";
-                $nr += scalar(@$errs);
-            }
-        }
-        if ($nr > 0) {
-            # Cut off extra chars at the end
-            $extra = substr($extra,0,-2);
-        }
-        $summary = $nr . " of " . $nr_checks . " failed: " . $extra;
+        $summary = $self->_format_multicheck_failure_summary($labels->{summary_failure} ||
+                                                             "%e of %n checks failed [%d]",
+                                                             $nr_checks,
+                                                             $error_stat);
     }
     return ($code,$summary . "\n" . $message);
 }
 
+# UNKNOWN shadows everything else
+sub _check_for_UNKNOWN {
+    my $self = shift;
+    my $error_stat = shift;
+    my $code = shift;
+    return $error_stat->{UNKNOWN} && scalar(@$error_stat->{UNKNOWN}) ? UNKNOWN : $code;
+}
+
+sub _format_multicheck_ok_summary {
+    my $self = shift;
+    my $format = shift;
+    my $nr_checks = shift;
+    my $ret = $format;
+    $ret =~ s/\%n/$nr_checks/g;
+    return $ret;
+}
+
+sub _format_multicheck_failure_summary {
+    my $self = shift;
+    my $format = shift;
+    my $nr_checks = shift;
+    my $error_stat = shift;
+
+    my $ret = $format;
+
+    my $details = "";
+    my $total_errors = 0;
+    for my $code (UNKNOWN,CRITICAL,WARNING) {
+        if (my $errs = $error_stat->{$code}) {
+            $details .= scalar(@$errs) . " " . $STATUS_TEXT{$code} . " (" . join (",",@$errs) . "), ";
+            $total_errors += scalar(@$errs);
+        }
+    }
+    if ($total_errors > 0) {
+        # Cut off extra chars at the end
+        $details = substr($details,0,-2);
+    }
+    
+    $ret =~ s/\%d/$details/g;
+    $ret =~ s/\%e/$total_errors/g;
+    $ret =~ s/\%n/$nr_checks/g;
+    return $ret;
+}
+
 # Create a formatted prefix for multicheck output
 sub _multi_check_prefix {
     my $self = shift;
     my $check = shift;
     my $idx = shift;
     my $max = shift;
-    my $label = $check->{config}->{key} || $check->{config}->{name} || "";
+    
+    my $c = $check->{config};
+
     my $l = length($max);
+    
+    return sprintf("[%$l.${l}s] %%c ",$idx)
+      if (defined($c->{multicheckprefix}) && !length($c->{multicheckprefix}));
+    
+    my $label =  $c->{multicheckprefix} || $c->{name} || $c->{key} || "";
     return sprintf("[%$l.${l}s] %%c %s: ",$idx,$label);
 }
 
 
-# Sendp the requests via the build up agent
+# Send the requests via the build up agent
 sub _send_requests {
     my ($self,$jmx,@requests) = @_;
     my $o = $self->{opts};
@@ -305,10 +365,11 @@ sub _verify_and_initialize {
 
     # Fetch configuration
     my $config = $self->_get_config($o->config);
-    
     # Now, if a specific check is given, extract it, too.
     my $check_configs;
+    #print Dumper($config);
     $check_configs = $self->_extract_checks($config,$o->check);
+    #print Dumper($check_configs);
     if ($check_configs) {
         for my $c (@$check_configs) {
             my $s_c = new JMX::Jmx4Perl::Nagios::SingleCheck($np,$c);
@@ -330,17 +391,9 @@ sub _verify_and_initialize {
         my $name = $check->name ? " [Check: " . $check->name . "]" : "";
         $self->nagios_die("An MBean name and a attribute/operation must be provided " . $name)
           if ((!$check->mbean || (!$check->attribute && !$check->operation)) && !$check->alias && !$check->value && !$check->script);
-        $self->verify_check($check,$name);
     }
 }
 
-sub verify_check {
-    my $self = shift;
-    my $check = shift;
-    my $name = shift;
-    my $np = $self->{np};
-}
-
 # Extract one or more check configurations which can be 
 # simple <Check>s or <MultiCheck>s
 sub _extract_checks {
@@ -352,10 +405,11 @@ sub _extract_checks {
     if ($check) {
         $self->nagios_die("No configuration given") unless $config;
         $self->nagios_die("No checks defined in configuration") unless $config->{check};
-        
+
         my $check_configs;
         unless ($config->{check}->{$check}) {
             $check_configs = $self->_resolve_multicheck($config,$check,$self->{cmd_args});
+            $self->_retrieve_mc_summary_label($config,$check);
         } else {
             my $check_config = $config->{check}->{$check};
             $check_configs = ref($check_config) eq "ARRAY" ? $check_config : [ $check_config ];
@@ -363,17 +417,19 @@ sub _extract_checks {
         }
         $self->nagios_die("No check configuration with name " . $check . " found") unless (@{$check_configs});
 
+        #print Dumper($check_configs);
+
         # Resolve parent values
         for my $c (@{$check_configs}) {
-            # print "[A] ",Dumper($c);
+            #print "[A] ",Dumper($c);
             $self->_resolve_check_config($c,$config,$self->{cmd_args});
             
-            # print "[B] ",Dumper($c);
+            #print "[B] ",Dumper($c);
             # Finally, resolve any left over place holders
             for my $k (keys(%$c)) {
                 $c->{$k} = $self->_replace_placeholder($c->{$k},undef) unless ref($c->{$k});
             }
-            # print "[C] ",Dumper($c);
+            #print "[C] ",Dumper($c);
         }
         return $check_configs;
     } else {
@@ -422,6 +478,24 @@ sub _resolve_multicheck {
     return $check_config;
 }
 
+sub _retrieve_mc_summary_label { 
+    my $self = shift;
+    my $config = shift;
+    my $check = shift;
+
+    my $multi_checks = $config->{multicheck};    
+    if ($multi_checks) { 
+        my $m_check = $multi_checks->{$check};
+        if ($m_check && ($m_check->{summaryok} || $m_check->{summaryfailure})) {
+            my $mc_labels = 
+            $self->{multi_check_labels} = {
+                                           summary_ok => $m_check->{summaryok},
+                                           summary_failure => $m_check->{summaryfailure}
+                                          };
+        }
+    }
+}
+
 sub _merge_multicheck_args {
     my $self = shift;
     my $check_params = shift;
@@ -450,7 +524,7 @@ sub _resolve_check_config {
     my $check = shift;
     my $config = shift;
     # Args can come from the outside, but also as part of a multicheck (stored
-    # in $self->{args})
+    # in $check->{args})
     my $args = $check->{args} && @{$check->{args}} ? $check->{args} : shift;
     my $np = $self->{np};
     if ($check->{use}) {
@@ -465,7 +539,7 @@ sub _resolve_check_config {
             # Clone it to avoid side effects when replacing checks inline
             my $p_check = { %{$config->{check}->{$p_name}} };
             $p_check->{key} = $p_name;
-#            print "::::: ",Dumper($p_check,$p_args);
+            #print "::::: ",Dumper($p_check,$p_args);
 
             $self->_resolve_check_config($p_check,$config,$p_args);
 
@@ -474,7 +548,7 @@ sub _resolve_check_config {
         }
         # Replace inherited values
         for my $k (keys %$parent_merged) {
-            my $parent_val = $parent_merged->{$k} || "";
+            my $parent_val = defined($parent_merged->{$k}) ?  $parent_merged->{$k} :  "";
             if (defined($check->{$k})) {
                 $check->{$k} =~ s/\$BASE/$parent_val/g;
             } else {
@@ -483,7 +557,6 @@ sub _resolve_check_config {
         }
     }
     $self->_replace_args($check,$config,$args);
-    #print Dumper($check);
     return $check;
 }
 
@@ -534,8 +607,8 @@ EOP
         my $orig_val = '$' . $2;
         my $i = defined($3) ? $3 : $4;
         my $default = $5;
-        $default =~ s/^\s*(.*)+?\s*$/$1/ if $default; # Trim whitespace
         my $end = defined($6) ? $6 : "";
+        $default =~ s/^\s*(.*)+?\s*$/$1/ if $default; # Trim whitespace
         #print Dumper({start => $start, orig => $orig_val,end => $end, default=> $default, rest => $rest, i => $i}); 
         if (defined($args)) {
             my $repl = $args->[$i];            
@@ -580,7 +653,7 @@ EOP
 sub _parse_check_ref {
     my $self = shift;
     my $check_ref = shift;
-    if ($check_ref =~/^\s*([^(]+)\(([^)]*)\)\s*$/) {
+    if ($check_ref =~/^\s*(.+?)\((.*)\)\s*$/) {
         my $name = $1;
         my $args_s = $2;
         my $args = [ parse_line('\s*,\s*',0,$args_s) ];
@@ -630,6 +703,7 @@ sub create_nagios_plugin {
     $np->shortname(undef);
     $self->add_common_np_args($np);
     $self->add_nagios_np_args($np);
+    $np->{msg_handler} = new JMX::Jmx4Perl::Nagios::MessageHandler();
     $np->getopts();
     return $np;
 }
@@ -0,0 +1,60 @@
+package JMX::Jmx4Perl::Nagios::MessageHandler;
+
+use Nagios::Plugin::Functions qw(:codes %ERRORS %STATUS_TEXT);
+use strict;
+
+=head1 NAME
+
+JMX::Jmx4Perl::Nagios::MessageHandler - Handling Nagios exit message (one or
+many) 
+
+=cut
+
+sub new {
+    my $class = shift;
+    my $self = {
+                messages => {}
+               };
+    bless $self,(ref($class) || $class);
+    return $self;
+}
+
+sub add_message { 
+    my $self = shift;
+    my ($code,@messages) = @_;
+    
+    die "Invalid error code '$code'\n"
+        unless defined($ERRORS{uc $code}) || defined($STATUS_TEXT{$code});
+
+    # Store messages using strings rather than numeric codes
+    $code = $STATUS_TEXT{$code} if $STATUS_TEXT{$code};
+    $code = lc $code;
+    
+    $self->{messages}->{$code} = [] unless $self->{messages}->{$code};
+    push @{$self->{messages}->{$code}}, @messages;
+}
+
+sub check_messages {
+    my $self = shift;
+    my %arg = @_;
+
+    for my $code (qw(critical warning ok unknown)) {
+        $arg{$code} = $self->{messages}->{$code} || [];
+    }
+
+    my $code = OK;
+    $code ||= UNKNOWN   if @{$arg{unknown}};
+    $code ||= CRITICAL  if @{$arg{critical}};
+    $code ||= WARNING   if @{$arg{warning}};
+    
+    my $message = join( "\n",
+                        map { @$_ ? join( "\n", @$_) : () }
+                        $arg{unknown},
+                        $arg{critical},
+                        $arg{warning},
+                        $arg{ok} ? (ref $arg{ok} ? $arg{ok} : [ $arg{ok} ]) : []
+                      );
+    return ($code, $message);
+}
+
+1;
@@ -96,7 +96,11 @@ sub get_requests {
     if ($self->base || $self->base_mbean) {
         if (!looks_like_number($self->base)) {
             # It looks like a number, so we will use the base literally
-            my $alias = JMX::Jmx4Perl::Alias->by_name($self->base);
+            my $alias;
+            
+            if ($self->base) {
+                $alias = JMX::Jmx4Perl::Alias->by_name($self->base);
+            }
             if ($alias) {
                 push @requests,new JMX::Jmx4Perl::Request(READ,$jmx->resolve_alias($self->base));
             } else {
@@ -158,6 +162,7 @@ sub extract_responses {
     my $requests = shift;
     my $opts = shift || {};
     my $np = $self->{np};
+    my $msg_handler = $np->{msg_handler} || $np; 
 
     # Get response/request pair
     my $resp = shift @{$responses};
@@ -209,10 +214,10 @@ sub extract_responses {
         # Do the real check.
         my ($code,$mode) = $self->_check_threshold($rel_value);
         # For Multichecks, we remember the label of a currently failed check
-        $self->_update_error_stats($opts->{error_stat},$code) unless $code == OK;
+        $self->update_error_stats($opts->{error_stat},$code) unless $code == OK;
         my ($base_conv,$base_unit) = $self->_normalize_value($base_value);
-        $np->add_message($code,$self->_exit_message(code => $code,mode => $mode,rel_value => $rel_value, 
-                                                    value => $value_conv, unit => $unit,base => $base_conv, 
+        $msg_handler->add_message($code,$self->_exit_message(code => $code,mode => $mode,rel_value => $rel_value, 
+                                                    value => $value_conv, unit => $unit, base => $base_conv, 
                                                     base_unit => $base_unit, prefix => $opts->{prefix}));            
     } else {
         # Performance data
@@ -225,9 +230,9 @@ sub extract_responses {
         
         # Do the real check.
         my ($code,$mode) = $self->_check_threshold($value);
-        $self->_update_error_stats($opts->{error_stat},$code) unless $code == OK;
-        $np->add_message($code,$self->_exit_message(code => $code,mode => $mode,value => $value_conv, unit => $unit,
-                                                    prefix => $opts->{prefix}));                    
+        $self->update_error_stats($opts->{error_stat},$code) unless $code == OK;
+        $msg_handler->add_message($code,$self->_exit_message(code => $code,mode => $mode,value => $value_conv, unit => $unit,
+                                                             prefix => $opts->{prefix}));                    
     }
     return @extra_requests;
 }
@@ -242,7 +247,7 @@ sub _include_perf_data {
     return $self->perfdata !~ /^\s*(false|off|no|0)\s*$/i;
 }
 
-sub _update_error_stats {
+sub update_error_stats {
     my $self = shift;
     my $error_stat = shift || return;
     my $code = shift;
@@ -294,12 +299,12 @@ sub _extract_value_from_pattern_request {
     my $self = shift;
     my $val = shift;
     my $np = $self->{np};
-    $self->nagios_die("Pattern request does not result in a proper return format: " . Dumper($val))
+    $self->_die("Pattern request does not result in a proper return format: " . Dumper($val))
       if (ref($val) ne "HASH");
-    $self->nagios_die("More than one MBean found for a pattern request: " . Dumper([keys %$val])) if keys %$val != 1;
+    $self->_die("More than one MBean found for a pattern request: " . Dumper([keys %$val])) if keys %$val != 1;
     my $attr_val = (values(%$val))[0];
-    $self->nagios_die("Invalid response for pattern match: " . Dumper($attr_val)) unless ref($attr_val) eq "HASH";
-    $self->nagios_die("Only a single attribute can be used. Given: " . Dumper([keys %$attr_val])) if keys %$attr_val != 1;
+    $self->_die("Invalid response for pattern match: " . Dumper($attr_val)) unless ref($attr_val) eq "HASH";
+    $self->_die("Only a single attribute can be used. Given: " . Dumper([keys %$attr_val])) if keys %$attr_val != 1;
     return $self->_null_safe_value((values(%$attr_val))[0]);
 }
 
@@ -359,7 +364,8 @@ sub _base_value {
     }
     my $resp = shift @{$responses};
     my $req = shift @{$requests};
-    $self->nagios_die($resp->{error}) if $resp->{error};
+    $self->_die($resp->{error}) if $resp->{error};
+    #print Dumper($req,$resp);
     return $self->_extract_value($req,$resp);
 }
 
@@ -436,14 +442,16 @@ sub _verify_response {
     my ($self,$req,$resp) = @_;
     my $np = $self->{np};
     if ($resp->is_error) {
-        my $stacktrace = $resp->stacktrace;
         my $extra = "";
-        $extra = ref($stacktrace) eq "ARRAY" ? join "\n",@$stacktrace : $stacktrace if $stacktrace;
-        $self->nagios_die("Error: ".$resp->status." ".$resp->error_text.$extra);
+        if ($np->opts->{verbose}) {
+            my $stacktrace = $resp->stacktrace;
+            $extra = ref($stacktrace) eq "ARRAY" ? join "\n",@$stacktrace : $stacktrace if $stacktrace;
+        }
+        $self->_die("Error: ".$resp->status." ".$resp->error_text.$extra);
     }
     
     if (!$req->is_mbean_pattern && (ref($resp->value) && !$self->string) && !JSON::is_bool($resp->value)) { 
-        $self->nagios_die("Response value is a " . ref($resp->value) .
+        $self->_die("Response value is a " . ref($resp->value) .
                         ", not a plain value. Did you forget a --path parameter ?". " Value: " . 
                         Dumper($resp->value));
     }
@@ -463,7 +471,7 @@ sub _get_name {
             } else {
                 my $val = $self->value;
                 if ($val) {
-                    $name = "[" . $self->value . "]";
+                    $name = "[" . $val . "]";
                 } else {
                     my $a_or_o = $self->attribute || $self->operation || "";
                     my $p = $self->path ? "," . $self->path : "";
@@ -490,7 +498,7 @@ sub _prepare_read_args {
 
     if ($self->alias) {
         my @req_args = $jmx->resolve_alias($self->alias);
-        $self->nagios_die("Cannot resolve attribute alias ",$self->alias()) unless @req_args > 0;
+        $self->_die("Cannot resolve attribute alias ",$self->alias()) unless @req_args > 0;
         if ($self->path) {
             @req_args == 2 ? $req_args[2] = $self->path : $req_args[2] .= "/" . $self->path;
         }
@@ -507,10 +515,13 @@ sub _prepare_exec_args {
     my $np = $self->{np};
     my $jmx = shift;
 
+    #print Dumper($self->{config});
     # Merge CLI arguments and arguments from the configuration,
     # with CLI arguments taking precedence
     my @cli_args = @_;
-    my $config_args = $self->{config}->{args};
+    my $config_args = $self->{config}->{argument};
+    
+    $config_args = [ $config_args ] if defined($config_args) && ref($config_args) ne "ARRAY";
     my @args = ();
     if ($config_args) {
         my @c_args = (@$config_args);
@@ -524,7 +535,7 @@ sub _prepare_exec_args {
     }
     if ($self->alias) {
         my @req_args = $jmx->resolve_alias($self->alias);
-        $self->nagios_die("Cannot resolve operation alias ",$self->alias()) unless @req_args >= 2;
+        $self->_die("Cannot resolve operation alias ",$self->alias()) unless @req_args >= 2;
         return (@req_args,@args);
     } else {
         return ($self->mbean,$self->operation,@args);
@@ -544,7 +555,7 @@ sub _split_attr_spec {
         $p =~ s|\\(.)|$1|sg;
         push @ret,$p;
     }    
-    return @ret;
+    return (shift(@ret),shift(@ret),@ret ? join("/",@ret) : undef);
 }
 
 sub _check_threshold {
@@ -563,7 +574,8 @@ sub _check_threshold {
           (
            defined($self->critical) ? (critical => $self->critical) : (),
            defined($self->warning) ? (warning => $self->warning) : ()
-          );            
+          );  
+        #print Dumper({check => $value,@ths});
         return (@ths ? $np->check_threshold(check => $value,@ths) : OK,"numeric");    
     } else {
         return
@@ -610,7 +622,7 @@ sub _exit_message {
     my $code = $args->{code};
     my $mode = $args->{mode};
     if ($code == CRITICAL || $code == WARNING) {
-        if ($self->base) {
+        if ($self->base || $self->base_mbean) {
             return $self->_format_label
               ('%n : Threshold \'%t\' failed for value %.2r% ('. &_placeholder($args,"v") .' %u / '.
                &_placeholder($args,"b") . ' %u)',$args);
@@ -623,7 +635,7 @@ sub _exit_message {
             }
         }
     } else {
-        if ($self->base) {
+        if ($self->base || $self->base_mbean) {
             return $self->_format_label('%n : In range %.2r% ('. &_placeholder($args,"v") .' %u / '.
                                         &_placeholder($args,"b") . ' %w)',$args);
         } else {
@@ -652,10 +664,13 @@ sub _format_label {
     my $self = shift;
     my $label = shift;
     my $args = shift;
-    # %r : relative value
+    # %r : relative value (as percent)
+    # %q : relative value (as floating point)
     # %v : value
+    # %f : value as floating point
     # %u : unit
     # %b : base value
+    # %w : base unit
     # %t : threshold failed ("" for OK or UNKNOWN)
     # %c : code ("OK", "WARNING", "CRITICAL", "UNKNOWN")
     # %d : delta
@@ -665,8 +680,10 @@ sub _format_label {
     foreach my $p (@parts) {
         if ($p =~ /^(\%[\w\.\-]*)(\w)$/) {
             my ($format,$what) = ($1,$2);
-            if ($what eq "r") {
-                $ret .= sprintf $format . "f",($args->{rel_value} || 0);
+            if ($what eq "r" || $what eq "q") {
+                my $val = $args->{rel_value} || 0;
+                $val = $what eq "r" ? $val : $val / 100; 
+                $ret .= sprintf $format . "f",$val;
             } elsif ($what eq "b") {
                 $ret .= sprintf $format . &_format_char($args->{base}),($args->{base} || 0);
             } elsif ($what eq "u" || $what eq "w") {
@@ -719,11 +736,10 @@ sub _format_char {
     $val =~ /\./ ? "f" : "d";
 }
 
-sub nagios_die {
+sub _die {
     my $self = shift;
     my $msg = join("",@_);
-    my $np = $self->{np};
-    $np->nagios_die($msg,$np->opts->{'unknown-is-critical'} ? CRITICAL : UNKNOWN);
+    die $msg,"\n";
 }
 
 my $CHECK_CONFIG_KEYS = {
@@ -768,7 +784,7 @@ sub AUTOLOAD {
             return undef;
         }
     } else {
-        $self->nagios_die("No config attribute \"" . $name . "\" known");
+        $self->_die("No config attribute \"" . $name . "\" known");
     }
 }
 
@@ -93,7 +93,7 @@ sub dump_scalar {
 
     if (JSON::is_bool($value)) {
         my ($true,$false) = split /\//,$format;
-        if ($value eq "true") {
+        if ($value eq JSON::true) {
             return $true; 
         } else {
             return $false;
@@ -100,8 +100,9 @@ use strict;
 use vars qw($VERSION $HANDLER_BASE_PACKAGE @PRODUCT_HANDLER_ORDERING);
 use Data::Dumper;
 use Module::Find;
+use JSON;
 
-$VERSION = "1.07";
+$VERSION = "1.11";
 
 my $REGISTRY = {
                 # Agent based
@@ -596,6 +597,75 @@ sub request {
     croak "Internal: Must be overwritten by a subclass";    
 }
 
+=item $agents = JMX::Jmx4Perl->discover_agents($timeout) 
+
+Discover agents by sending a multicast request on which Jolokia agents are
+listening. The optional C<$timeout> can be used to tune how long to wait for
+discovery answers (in seconds). By default 1 seconds is waited. This functionality
+requires L<IO::Socket::Multicast> to be installed.
+
+This methods returns an array ref, which looks like
+
+   [
+     {
+       'version' => '1.2.0-SNAPSHOT',
+       'server_version' => '7.0.50',
+       'server_product' => 'tomcat',
+       'secured' => 0,
+       'url' => 'http://10.9.11.2:8778/jolokia/',
+       'server_vendor' => 'Apache',
+       'confidence' => 100,
+       'type' => 'response'
+     }
+   ]
+
+Please refer to Jolokia's reference documentation for the meaning of the keys. 
+The most important part it C<url> which points to the agent's URL which can 
+be used to construct a new L<JMX::Jmx4Perl> object. 
+
+=cut
+
+
+sub discover_agents {
+    my $self = shift;
+    my $timeout = shift | 1;
+
+    my $s;
+    eval {
+        $s = IO::Socket::Multicast->new();
+    };
+    if ($@) {
+        eval {
+            require "IO/Socket/Multicast.pm";
+            $s = IO::Socket::Multicast->new();
+        };
+        if ($@) {
+            die "No IO::Socket::Multicast installed\n";
+        }
+    }
+
+    $s->mcast_send('{"type" : "query"}',"239.192.48.84:24884");
+    
+    my @result = ();
+    my $data;
+  LOOP:
+    while (1) {
+        eval {
+            local $SIG{ALRM} = sub { die "timeout\n" }; # NB: \n required
+            alarm $timeout;
+            $s->recv($data,8192);
+            push @result,from_json($data, {utf8 => 1} );
+            alarm 0;
+        };
+        if ($@) {
+            die unless $@ eq "timeout\n";   # propagate unexpected errors
+            # timed out
+            last LOOP;
+        }
+    }    
+    return \@result;
+}
+
 # ===========================================================================
 # Alias handling
 
@@ -72,8 +72,8 @@ check_jmx4perl - Nagios plugin using jmx4perl for accessing JMX data remotely
                 --mbean java.lang:type=Threading \
                 --operation findDeadlockedThreads \
                 --null no-deadlock \
-                --string 1 \
-                --critical !no-deadlock \
+                --string \
+                --critical '!no-deadlock' \
                 --critical 10
 
  # Use check_jmx4perl in proxy mode
@@ -492,9 +492,9 @@ only, so for complex attributes a path is I<required>.
 
 The return values of operations can be used for threshold checking, too. Since
 a JMX exposed operation can take arguments, these has to be provided as extra
-arguments on the command line or in the configuration. Due to the agent's
-nature and the protocol used (JSON), only simple typed arguments like strings,
-numbers or booleans ("true"/"false") can be used.
+arguments on the command line or in the configuration via the C<Args> configuration 
+directive. Due to the agent's nature and the protocol used (JSON), only simple typed 
+arguments like strings, numbers or booleans ("true"/"false") can be used.
 
 Example:
 
@@ -512,7 +512,7 @@ agent. For this purpose an JMX operation C<getNrQueriesFor> is exposed which
 takes three arguments: The type ("operation"/"attribute"), the MBean's
 ObjectName and the operation/attribute name which was called.
 
-If the opertion to be called is an I<overloaded operation> (i.e. an operation
+If the operation to be called is an I<overloaded operation> (i.e. an operation
 whose name exists multiple times on the same MBean but with different parameter
 types), the argument types must be given within parentheses:
 
@@ -666,7 +666,8 @@ placeholders:
 
  %v   the absolute value 
  %f   the absolute value as floating point number
- %r   the relative value for relative calculations (--base)
+ %r   the relative value as percentage (--base)
+ %q   the relative value as ratio of value to base (--base)
  %u   the value's unit for the output when --unit is used (after shortening)
  %w   the base value's unit for the output when --unit is used (after shortening)
  %b   the absolut base value as it is used with --base 
@@ -1459,6 +1460,20 @@ parameter types), the argument types can be given within parentheses:
      ...
   </Check>
 
+=item Argument
+
+Used for specifying arguments to operation. This directive can be given multiple 
+times for multiple arguments. The order of the directive determine the order of the 
+arguments.
+
+  <Check>
+     ....
+     Operation checkUserCount(java.lang.String,java.lang.String)
+     Argument  Max
+     Argument  Morlock    
+  </Check>
+   
+
 =item Alias
 
 Alias, which must be known to C<check_jmx4perl>. Use C<jmx4perl aliases> to get
@@ -1538,6 +1553,13 @@ non-numeric thresholds. See L</"String checks"> for more details.
 The name to be used in the performance data. By default, a name is calculated
 based on the MBean and attribute/operation name.
 
+=item MultiCheckPrefix
+
+If this check is used within a multi check, this prefix is used to identify
+this particular check in the output of a multicheck. It can be set to an empty
+string if no prefix is required. By default the name as configured with C<Name>
+is used. 
+
 =item Label
 
 Format for setting the plugin output (not the performance data, use C<Name> for
@@ -1606,6 +1628,34 @@ and L</"Parameterized checks"> for more information about check inheritance.
 
 Multiple parents can be given by providing them in a comma separated list. 
 
+=item Script
+
+For complex checks which can not be realized with the configurations described
+until yet, it is possible to use a Perl script snippet to perfrom arbitrary
+logic. The content of this script is typically provided as an HERE-document
+(see example below). It comes with a predefined variable C<$j4p> which is an
+instance of L<JMX::Jmx4Perl> so that it can be used for a flexible access to
+the server. Note that this scriptlet is executed separately and doesn't not
+benefit from the optimization done for bulk or relative checks. Check
+parameters can be accessed as ${0}, ${1}, .. but since these are also valid
+Perl variables (and hence can be overwritten accidentially), it is recommended
+to assign them to local variable before using them. In summary, script based
+checks are powerful but might be expensive.
+
+Example:
+
+  Script <<EOT
+  
+  my $pools = $j4p->search("java.lang:type=MemoryPool,*");
+  my @matched_pools;
+  my $pattern = "${0}";
+  for my $pool (@$pools) {   
+     push @matched_pools,$pool if $pool =~ /$pattern/;   
+  }
+  return $j4p->get_attribute($matched_pools[0],"Usage","used");
+  
+  EOT
+
 =back
 
 =head2 Includes
@@ -1733,7 +1783,14 @@ multi check is, that multiple values can be retrieved from the server side with
 a single HTTP request. The output is conformant to Nagios 3 multiline
 format. It will lead to a C<CRITICAL> value as soon as one check is critical,
 same for C<WARNING>. If both, C<CRITICAL> and C<WARNING> is triggered by two or
-more checks, then a C<CRITICAL> is taken.
+more checks, then C<CRITICAL> take precedence.
+
+If a single check within a multi check fails with an exception (e.g. because an
+MBean is missing), its state becomes C<UNKNOWN>. C<UNKNOWN> is the highest
+state in so far that it shadows even C<CRITICAL> (i.e. if a single check is
+C<UNKNOWN> the whole multi check is C<UNKNOWN>, too). This can be changed by
+providing the command line option C<--unknown-is-critical> in which case all
+C<UNKNOWN> errors are mapped to C<CRITICAL>.
 
 A multi-check can be defined with the directive C<E<lt>MultiCheckE<gt>>, which
 contain various references to other C<E<lt>CheckE<gt>> definitions or other
@@ -1768,6 +1825,22 @@ A multi-check is referenced from the command line like any other check:
 
 (90 is the argument which replaces C<$0> in the definition above). 
 
+The summary label in a multi check can be configured, too. 
+
+Example:
+
+  <MultiCheck memory>
+    SummaryOk All %n checks are OK
+    SummaryFailure %e of %n checks failed [%d]
+    ...
+  </MultiCheck>
+
+These format specifiers can be used:
+
+  %n        Number of all checks executed 
+  %e        Number of failed checks
+  %d        Details which checks failed
+
 =head2 Predefined checks
 
 C<check_jmx4perl> comes with a collection of predefined configuration for
@@ -1803,6 +1876,15 @@ the app server, sessions (number and lifing time) or requests per minute.
 
 Mostly the same checks as for jetty, but for tomcat as application server. 
 
+=head3 websphere.cfg
+
+WebSphere specific checks, which uses the configuration files below the
+`websphere/` directory. For this checks to work, a customized Jolokia agent
+with JSR-77 extensions is required. The GitHub project for this enhanced agents
+can be found at L<https://github.com/rhuss/jolokia-extra> and downloaded at
+Maven Central
+(L<http://central.maven.org/maven2/org/jolokia/extra/jolokia-extra-war/>) 
+
 =head1 LICENSE
 
 This file is part of jmx4perl.
@@ -422,7 +422,7 @@ sub command_aliases {
 =head2 search
 
 Search for a certain MBean. As argument you should provide a pattern like
-C<*:*,j2eeType=Servlet,*>. I.e you can use the wildcard C<*> for the domain
+C<*:j2eeType=Servlet,*>. I.e you can use the wildcard C<*> for the domain
 name part, and properties as a whole (but not within a key=property tuple). See
 L<http://java.sun.com/j2se/1.5.0/docs/api/javax/management/ObjectName.html> for
 a complete explanation of how a pattern can look like. As a result of this
@@ -5,7 +5,7 @@ use warnings;
 use FindBin qw($Bin);
 use lib qq($Bin/lib);
 
-use Test::More tests => 22;
+use Test::More tests => 30;
 
 BEGIN { use_ok("JMX::Jmx4Perl::Request"); }
 
@@ -50,4 +50,26 @@ eval {
 };
 ok($@,"No attributes with GET");
 
+# Regexp for squeezing trailing slashes (RT#89108)
+my $regexps = {
+               new => 's|((?:!/)?/)/*|$1|g',
+               old => 's|(!/)?/+|$1/|g'
+              };
+my $data = {
+            '!////' => '!//',
+            '////'  => '/',
+            '/' => '/',
+            '!/' => '!/'            
+           };
+for my $d (keys %$data) {
+    no warnings;
+    for my $re (keys %$regexps) {
+        my $test = $d;
+        my $expected = $data->{$d};
+        eval '$^W = 0; $test =~ ' . $regexps->{$re};        
+        is($test,$expected,"Squeezing regexp '" . $re ."' : ".$d." --> ".$test);
+    }
+}
+
+
 
@@ -67,10 +67,6 @@ is($unit,"ns");
 is($value,1.01);
 is($unit,"us");
 
-
 my $label = $scheck->_exit_message(code => &Nagios::Plugin::OK,mode => "numeric",value => "2.1", unit => "MB");
 is($label,"Memory : Value 2.10 MB in range");
 
-
-
-