[ 
https://issues.apache.org/jira/browse/KARAF-5799?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16607078#comment-16607078
 ] 

ASF GitHub Bot commented on KARAF-5799:
---------------------------------------

jbonofre closed pull request #52: [KARAF-5799] Add support of operation 
execution in the JMX Collector
URL: https://github.com/apache/karaf-decanter/pull/52
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git 
a/collector/jmx/src/main/cfg/org.apache.karaf.decanter.collector.jmx-activemq.cfg
 
b/collector/jmx/src/main/cfg/org.apache.karaf.decanter.collector.jmx-activemq.cfg
index cbfa44b..b034dff 100644
--- 
a/collector/jmx/src/main/cfg/org.apache.karaf.decanter.collector.jmx-activemq.cfg
+++ 
b/collector/jmx/src/main/cfg/org.apache.karaf.decanter.collector.jmx-activemq.cfg
@@ -45,6 +45,9 @@ object.name=org.apache.activemq:*
 #object.name.karaf=org.apache.karaf:type=http,name=*
 #object.name.3=org.apache.activemq:*
 
+# You can also execute operations on some MBeans, providing the object name, 
operation and arguments (separated by |)
+#result.name.rootLogger=org.apache.karaf:type=log,name=root|getLevel|rootLogger
+
 # You can add any custom field that the collector will "forward" to the 
dispatcher
 # For instance:
 #
diff --git 
a/collector/jmx/src/main/cfg/org.apache.karaf.decanter.collector.jmx-camel.cfg 
b/collector/jmx/src/main/cfg/org.apache.karaf.decanter.collector.jmx-camel.cfg
index b8491d7..8437822 100644
--- 
a/collector/jmx/src/main/cfg/org.apache.karaf.decanter.collector.jmx-camel.cfg
+++ 
b/collector/jmx/src/main/cfg/org.apache.karaf.decanter.collector.jmx-camel.cfg
@@ -45,6 +45,9 @@ object.name=org.apache.camel:context=*,type=routes,name=*
 #object.name.karaf=org.apache.karaf:type=http,name=*
 #object.name.3=org.apache.activemq:*
 
+# You can also execute operations on some MBeans, providing the object name, 
operation and arguments (separated by |)
+#result.name.rootLogger=org.apache.karaf:type=log,name=root|getLevel|rootLogger
+
 # You can add any custom field that the collector will "forward" to the 
dispatcher
 # For instance:
 #
diff --git 
a/collector/jmx/src/main/cfg/org.apache.karaf.decanter.collector.jmx-local.cfg 
b/collector/jmx/src/main/cfg/org.apache.karaf.decanter.collector.jmx-local.cfg
index 6096b5d..52d4d5d 100644
--- 
a/collector/jmx/src/main/cfg/org.apache.karaf.decanter.collector.jmx-local.cfg
+++ 
b/collector/jmx/src/main/cfg/org.apache.karaf.decanter.collector.jmx-local.cfg
@@ -45,6 +45,10 @@ url=local
 #object.name.karaf=org.apache.karaf:type=http,name=*
 #object.name.3=org.apache.activemq:*
 
+# You can also execute operations on some MBeans, providing the object name, 
operation, arguments (separated by ,)
+# and signatures (separated by ,) for the arguments (separated by |)
+#operation.name.rootLogger=org.apache.karaf:type=log,name=root|getLevel|rootLogger|java.lang.String
+
 # You can add any custom field that the collector will "forward" to the 
dispatcher
 # For instance:
 #
diff --git 
a/collector/jmx/src/main/java/org/apache/karaf/decanter/collector/jmx/BeanHarvester.java
 
b/collector/jmx/src/main/java/org/apache/karaf/decanter/collector/jmx/BeanHarvester.java
index 614d740..c7d1735 100644
--- 
a/collector/jmx/src/main/java/org/apache/karaf/decanter/collector/jmx/BeanHarvester.java
+++ 
b/collector/jmx/src/main/java/org/apache/karaf/decanter/collector/jmx/BeanHarvester.java
@@ -109,10 +109,22 @@
             } catch (SecurityException se) {
                 LOGGER.error("SecurityException: ", se);
             } catch (Exception e) {
-                LOGGER.debug("Could not read attribute " + name.toString() + " 
" + attribute.getName());
+                LOGGER.debug("Could not read attribute {} {}", 
name.toString(), attribute.getName());
             }
 
         }
         return data;
     }
+
+    public Map<String, Object> executeOperation(String resultName, ObjectName 
objectName, String operation, Object[] arguments, String[] signatures) throws 
Exception {
+        LOGGER.debug("Executing operation {} on {}", operation, objectName);
+        Map<String, Object> data = new HashMap<>();
+        data.put("type", type);
+        data.put("operation.name", operation);
+        data.put("operation.arguments", arguments);
+        data.put("operation.signatures", signatures);
+        Object result = connection.invoke(objectName, operation, arguments, 
signatures);
+        data.put(resultName, result);
+        return data;
+    }
 }
diff --git 
a/collector/jmx/src/main/java/org/apache/karaf/decanter/collector/jmx/JmxCollector.java
 
b/collector/jmx/src/main/java/org/apache/karaf/decanter/collector/jmx/JmxCollector.java
index 7930812..495cdad 100644
--- 
a/collector/jmx/src/main/java/org/apache/karaf/decanter/collector/jmx/JmxCollector.java
+++ 
b/collector/jmx/src/main/java/org/apache/karaf/decanter/collector/jmx/JmxCollector.java
@@ -66,6 +66,7 @@
     private String remoteProtocolPkgs;
 
     private Set<String> objectNames;
+    private Map<String, String> operations;
     private Dictionary<String, Object> properties;
 
     @SuppressWarnings("unchecked")
@@ -86,13 +87,17 @@ public void activate(ComponentContext context) {
         this.remoteProtocolPkgs = remoteProtocolPkgs;
 
         this.objectNames = new HashSet<> ();
-        for (Enumeration<String> e = this.properties.keys(); 
e.hasMoreElements(); ) {
+        this.operations = new HashMap<>();
+        for (Enumeration<String> e = properties.keys(); e.hasMoreElements(); ) 
{
                String key = e.nextElement();
                if( "object.name".equals( key ) || key.startsWith( 
"object.name." )) {
                        Object value = this.properties.get( key );
                        if (value != null)
                                this.objectNames.add( value.toString());
                }
+               if (key.startsWith("operation.name.")) {
+                   operations.put(key.substring("operation.name.".length()), 
(String) properties.get(key));
+            }
         }
     }
 
@@ -152,11 +157,29 @@ public void run() {
                     data.put("host", host);
                     Event event = new Event("decanter/collect/jmx/" + 
this.type + "/" + getTopic(name), data);
                     LOGGER.debug("Posting for {}", name);
-                    this.dispatcher.postEvent(event);
+                    dispatcher.postEvent(event);
                 } catch (Exception e) {
                     LOGGER.warn("Can't read MBean {} ({})", name, this.type, 
e);
                 }
             }
+
+            for (String operation : operations.keySet()) {
+                String raw = operations.get(operation);
+                String[] split = raw.split("\\|");
+                if (split.length == 4) {
+                    ObjectName objectName = new ObjectName(split[0]);
+                    String operationName = split[1];
+                    String[] arguments = split[2].split(",");
+                    String[] signatures = split[3].split(",");
+                    Map<String, Object> data = 
harvester.executeOperation(operation, objectName, operationName, arguments, 
signatures);
+                    PropertiesPreparator.prepare(data, properties);
+                    data.put("host", host);
+                    Event event = new Event("decanter/collect/jmx/" + 
this.type + "/" + getTopic(objectName), data);
+                    dispatcher.postEvent(event);
+                } else {
+                    LOGGER.warn("{} is not well configured ({})", operation, 
raw);
+                }
+            }
         } catch (Exception e) {
             LOGGER.warn("Can't query object name from {} ({}) {}", this.url, 
this.type, currentObjectName);
         }
diff --git a/manual/src/main/asciidoc/user-guide/collectors.adoc 
b/manual/src/main/asciidoc/user-guide/collectors.adoc
index 81304ba..9a22c3e 100644
--- a/manual/src/main/asciidoc/user-guide/collectors.adoc
+++ b/manual/src/main/asciidoc/user-guide/collectors.adoc
@@ -205,6 +205,8 @@ The Decanter JMX Collector is a polled collector, executed 
periodically by the D
 The JMX collector connects to a JMX MBeanServer (local or remote), and 
retrieves all attributes of each available MBeans.
 The JMX metrics (attribute values) are send to the appenders.
 
+In addition, the JMX collector also supports the execution of operations on 
dedicated ObjectName that you configure via `cfg` file.
+
 The `decanter-collector-jmx` feature installs the JMX collector, and a default 
configuration file:
 
 ----
@@ -241,6 +243,10 @@ url=local
 #object.name.system=java.lang:*
 #object.name.karaf=org.apache.karaf:type=http,name=*
 #object.name.3=org.apache.activemq:*
+
+# You can also execute operations on some MBeans, providing the object name, 
operation, arguments (separated by ,)
+# and signatures (separated by ,) for the arguments (separated by |)
+#operation.name.rootLogger=org.apache.karaf:type=log,name=root|getLevel|rootLogger|java.lang.String
 ----
 
 This file harvests the data of the local MBeanServer:
@@ -254,11 +260,12 @@ can also polled any remote MBean server (Karaf based or 
not) providing the servi
 is secured.
 * the `password` property contains the password to connect to the MBean 
server. It's only required if the MBean server
 is secured.
-* the `object.name` property is optional. If this property is not specified, 
the collector will retrieve the attributes
+* the `object.name` prefix is optional. If this property is not specified, the 
collector will retrieve the attributes
 of all MBeans. You can filter to consider only some MBeans. This property 
contains the ObjectName filter to retrieve
 the attributes only to some MBeans. Several object names can be listed, 
provided the property prefix is `object.name.`.
 * any other values will be part of the collected data. It means that you can 
add your own property if you want to add
 additional data, and create queries based on this data.
+* the `operation.name` prefix is also optional. You can use it to execute an 
operation. The value format is `objectName|operation|arguments|signatures`.
 
 You can retrieve multiple MBean servers. For that, you just create a new 
configuration file using the file name format
 `etc/org.apache.karaf.decanter.collector.jmx-[ANYNAME].cfg`.


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


> Be able to execute JMX operation in the collector
> -------------------------------------------------
>
>                 Key: KARAF-5799
>                 URL: https://issues.apache.org/jira/browse/KARAF-5799
>             Project: Karaf
>          Issue Type: Improvement
>          Components: decanter
>            Reporter: Jean-Baptiste Onofré
>            Assignee: Jean-Baptiste Onofré
>            Priority: Major
>             Fix For: decanter-2.1.0
>
>
> IN addition of harvesting the MBean attributes, it would be great to be able 
> to execute MBean operation and push the results on the dispatcher.
> The MBean, operations and arguments have to be described in the corresponding 
> cfg file. Something like:
> {code}
> result.name=mbean.operation.arg1.arg2
> {code}



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to