2

Is https://github.com/clojure/java.jmx equivalent to using JVM starting options(like -Dcom.sun.management.jmxremote...)?

Can we expose a JMX port in production for other (non-clojure) monitoring tools?

Or is is only clojure-to-clojure?

The goal is to do this in Clojure instead of relying on system startup scripts to do this, which makes it easier to configure/test in my case.

Community
  • 1
  • 1
nha
  • 17,623
  • 13
  • 87
  • 133

1 Answers1

2

It all depends what you want and why you're asking, a little more context might be applicable: Do you want to monitor from a Clojure process, or do you want to monitor a Clojure process ? Which of these two processes do you have author control over ?

JMX client

clojure.java.jmx is a client library to call Java JMX functions from Clojure, either locally or over the wire (JMX over RMI). It's basically the programming alternative to GUI's like JVisualVM / JMC.

JMX server

Over RMI

While you can always use JMX calls from within a Java process itself, to be able to monitor a Java / Clojure process remotely, you'd still need to include the -Dcom.sun.management.jmxremote parameters. This makes the process act as a server for JMX requests over an RMI connection.

Over HTTP

An alternative to RMI is serving JMX through a REST interface via jolokia. RMI is notoriously hard to manage over network infrastructure borders like firewalls, and to secure through authentication and authorization.

JMX over REST is much easier to manage (reverse proxy exclusions for JMX URLs). Authentication and authorization can also be done in your current web stack.

There's no Clojure client for these REST calls though, but it should be easy to mirror the clojure.java.jmx API and have it generate HTTP requests.

Exposing JMX beans

If you have a Clojure app that needs to expose application specific metrics that can be read through JMX, you need turn it into an JMX MBean. You can wrap any clojure map ref in a bean, and any updates to that ref can be seen through a JMX request.

clojure.java.jmx can help here as well.

(def my-statistics
  (ref {:current-sessions 0}))

(jmx/register-mbean
  (jmx/create-bean my-statistics)
  "my.namespace:name=Sessions")

(defn login
  [user]
  ;(do-login user)
  (dosync (alter my-statistics update :current-sessions inc)))

(login "foo")

;just as an example to show you can read the bean through JMX 
(jmx/attribute-names "my.namespace:name=Sessions")
 => (:current-sessions)

(jmx/read "my.namespace:name=Sessions" :current-sessions)   
=> 1

Make sure the ref map has string/symbol keys and Java 'primitive' values, or you might get a read exception on the client side.

The data from this bean can then be requested through JMX, provided you have set up a way to connect to the process.

NielsK
  • 6,886
  • 1
  • 24
  • 46
  • Thanks, I will have a look at jolokia. My use case is a datadog integration, so it would have to behave exactly like `jmxremote`. (Not familiar at all with MBeans, RMI to be honest). Do you think this would feasible from Clojure? – nha Nov 30 '16 at 15:26
  • Their integration steps include a JMX connector: http://docs.datadoghq.com/integrations/java/#installation Yes, they have an agent for basic metrics (memory, disk, cpu). And yes the idea is to set up an agent monitoring the app log files (not a problem I recon) and at the same time having JMX metrics (my question right now). – nha Nov 30 '16 at 15:51
  • Although now that I think about it, I could maybe just periodically log the jmx metrics using Clojure? – nha Nov 30 '16 at 15:52
  • Thanks for the update - it is helpful. So what you are saying is that I should try to combine `jmx/with-connection` and `mx/register-mbean`? – nha Nov 30 '16 at 16:08
  • Oh I see so in my case I have to do both `-Dcom.sun.management.jmxremote` and `mx/register-mbean`. I will try that tomorrow and let you know, but thanks for all the help :) – nha Nov 30 '16 at 16:47
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/129512/discussion-between-nielsk-and-nha). – NielsK Dec 01 '16 at 09:43