You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ch...@apache.org on 2011/06/12 23:46:56 UTC

svn commit: r1134991 - in /activemq/activemq-apollo/trunk: apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/ apollo-cli/src/main/scala/org/apache/activemq/apollo/cli/commands/ apollo-dto/src/main/java/org/apache/activemq/apollo/dto/ apoll...

Author: chirino
Date: Sun Jun 12 21:46:55 2011
New Revision: 1134991

URL: http://svn.apache.org/viewvc?rev=1134991&view=rev
Log:
Fixes https://issues.apache.org/jira/browse/APLO-41 : Expose JVM Metrics via REST API

Added:
    activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/JvmMetricsDTO.java
    activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/MemoryMetricsDTO.java
      - copied, changed from r1134946, activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/BrokerStatusDTO.java
Modified:
    activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/Broker.scala
    activemq/activemq-apollo/trunk/apollo-cli/src/main/scala/org/apache/activemq/apollo/cli/commands/Run.scala
    activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/BrokerStatusDTO.java
    activemq/activemq-apollo/trunk/apollo-web/src/main/scala/org/apache/activemq/apollo/web/resources/BrokerResource.scala

Modified: activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/Broker.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/Broker.scala?rev=1134991&r1=1134990&r2=1134991&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/Broker.scala (original)
+++ activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/Broker.scala Sun Jun 12 21:46:55 2011
@@ -30,7 +30,9 @@ import org.apache.activemq.apollo.util._
 import org.fusesource.hawtbuf.AsciiBuffer._
 import CollectionsSupport._
 import FileSupport._
-import org.apache.activemq.apollo.dto.{ConnectorDTO, VirtualHostDTO, LogCategoryDTO, BrokerDTO}
+import management.ManagementFactory
+import org.apache.activemq.apollo.dto._
+import javax.management.ObjectName
 
 /**
  * <p>
@@ -146,6 +148,51 @@ object Broker extends Log {
     read_text(source).trim
   }
 
+  def capture(command:String*) = {
+    import ProcessSupport._
+    try {
+      system(command:_*) match {
+        case(0, out, _) => Some(new String(out).trim)
+        case _ => None
+      }
+    } catch {
+      case _ => None
+    }
+  }
+
+  val os = {
+    val os = System.getProperty("os.name")
+    val rc = os +" "+System.getProperty("os.version")
+
+    // Try to get a better version from the OS itself..
+    val los = os.toLowerCase()
+    if( los.startsWith("linux") ) {
+      capture("lsb_release", "-sd").map("%s (%s)".format(rc, _)).getOrElse(rc)
+    } else {
+      rc
+    }
+
+  }
+
+  val jvm = {
+    val vendor = System.getProperty("java.vendor")
+    val version =System.getProperty("java.version")
+    val vm =System.getProperty("java.vm.name")
+    "%s %s (%s)".format(vm, version, vendor)
+  }
+
+  val max_fd_limit = {
+    if( System.getProperty("os.name").toLowerCase().startsWith("windows") ) {
+      None
+    } else {
+      val mbean_server = ManagementFactory.getPlatformMBeanServer()
+      mbean_server.getAttribute(new ObjectName("java.lang:type=OperatingSystem"), "MaxFileDescriptorCount") match {
+        case x:java.lang.Long=> Some(x.longValue)
+        case _ => None
+      }
+    }
+  }
+
 }
 
 /**
@@ -195,10 +242,10 @@ class Broker() extends BaseService {
   var web_server:WebServer = _
 
   var config_log:Log = Log(new MemoryLogger(Broker.log))
-  var audit_log:Log = Broker.log
-  var security_log:Log  = Broker.log
-  var connection_log:Log = Broker.log
-  var console_log:Log = Broker.log
+  var audit_log:Log = Broker
+  var security_log:Log  = Broker
+  var connection_log:Log = Broker
+  var console_log:Log = Broker
   var services = List[Service]()
 
   override def toString() = "broker: "+id
@@ -442,40 +489,6 @@ class Broker() extends BaseService {
   }
 
   private def log_versions = {
-
-    def capture(command:String*) = {
-      import ProcessSupport._
-      try {
-        system(command:_*) match {
-          case(0, out, _) => Some(new String(out).trim)
-          case _ => None
-        }
-      } catch {
-        case _ => None
-      }
-    }
-
-    val os = {
-      val os = System.getProperty("os.name")
-      val rc = os +" "+System.getProperty("os.version")
-
-      // Try to get a better version from the OS itself..
-      val los = os.toLowerCase()
-      if( los.startsWith("linux") ) {
-        capture("lsb_release", "-sd").map("%s (%s)".format(rc, _)).getOrElse(rc)
-      } else {
-        rc
-      }
-
-    }
-
-    val jvm = {
-      val vendor = System.getProperty("java.vendor")
-      val version =System.getProperty("java.version")
-      val vm =System.getProperty("java.vm.name")
-      "%s %s (%s)".format(vm, version, vendor)
-    }
-
     val location_info = Option(System.getProperty("apollo.home")).map { home=>
       " (at: "+new File(home).getCanonicalPath+")"
     }.getOrElse("")
@@ -483,53 +496,22 @@ class Broker() extends BaseService {
     console_log.info("OS     : %s", os)
     console_log.info("JVM    : %s", jvm)
     console_log.info("Apollo : %s%s", Broker.version, location_info)
-
   }
-  private def check_file_limit:Unit = {
-    if( System.getProperty("os.name").toLowerCase().startsWith("windows") ) {
-      return
-    }
-
-    import ProcessSupport._
-    def process(out:Array[Byte]) = try {
-      val limit = new String(out).trim
-      console_log.info("OS is restricting the open file limit to: %s", limit)
-      if( limit!="unlimited" ) {
-        val l = limit.toInt
 
+  private def check_file_limit:Unit = {
+    max_fd_limit match {
+      case Some(limit) =>
+        console_log.info("OS is restricting the open file limit to: %s", limit)
         var min_limit = 500 // estimate.. perhaps could we do better?
         config.connectors.foreach { connector=>
           import OptionSupport._
           min_limit += connector.connection_limit.getOrElse(10000)
         }
-
-        if( l < min_limit ) {
+        if( limit < min_limit ) {
           console_log.warn("Please increase the process file limit using 'ulimit -n %d' or configure lower connection limits on the broker connectors.", min_limit)
         }
-      }
-    } catch {
-      case _ =>
-    }
-
-    try {
-      launch("ulimit","-n") { case (rc, out, err) =>
-        if( rc==0 ) {
-          process(out)
-        }
-      }
-    } catch {
-      case _ =>
-        try {
-          launch("sh", "-c", "ulimit -n") { case (rc, out, err) =>
-            if( rc==0 ) {
-              process(out)
-            }
-          }
-        } catch {
-          case _ =>
-        }
+      case None =>
     }
-
   }
 
   def get_virtual_host(name: AsciiBuffer) = dispatch_queue ! {

Modified: activemq/activemq-apollo/trunk/apollo-cli/src/main/scala/org/apache/activemq/apollo/cli/commands/Run.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-cli/src/main/scala/org/apache/activemq/apollo/cli/commands/Run.scala?rev=1134991&r1=1134990&r2=1134991&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-cli/src/main/scala/org/apache/activemq/apollo/cli/commands/Run.scala (original)
+++ activemq/activemq-apollo/trunk/apollo-cli/src/main/scala/org/apache/activemq/apollo/cli/commands/Run.scala Sun Jun 12 21:46:55 2011
@@ -49,7 +49,6 @@ class Run extends Action {
 
     try {
 
-      val home = system_dir("apollo.home")
       val base = system_dir("apollo.base")
       val etc: File = base / "etc"
 
@@ -94,7 +93,6 @@ class Run extends Action {
       var jul_config = etc / "jul.properties"
       val jul_config_monitor = if ( jul_config.exists()) {
         new FileMonitor(jul_config, {
-          broker.console_log.
           using(new FileInputStream(jul_config)) { is =>
             LogManager.getLogManager.readConfiguration(is)
           }

Modified: activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/BrokerStatusDTO.java
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/BrokerStatusDTO.java?rev=1134991&r1=1134990&r2=1134991&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/BrokerStatusDTO.java (original)
+++ activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/BrokerStatusDTO.java Sun Jun 12 21:46:55 2011
@@ -37,6 +37,12 @@ public class BrokerStatusDTO extends Ser
 	public String version;
 
     /**
+     * Metrics about the JVM
+     */
+	@XmlElement(name="jvm_metrics")
+    public JvmMetricsDTO jvm_metrics;
+
+    /**
      * The current time on the broker machine.  In milliseconds since the epoch.
      */
 	@XmlAttribute(name="current_time")

Added: activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/JvmMetricsDTO.java
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/JvmMetricsDTO.java?rev=1134991&view=auto
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/JvmMetricsDTO.java (added)
+++ activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/JvmMetricsDTO.java Sun Jun 12 21:46:55 2011
@@ -0,0 +1,94 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.apollo.dto;
+
+import javax.xml.bind.annotation.*;
+
+/**
+ * <p>
+ * </p>
+ *
+ * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
+ */
+@XmlRootElement(name="jvm_metrics")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class JvmMetricsDTO {
+
+    @XmlElement(name="heap_memory")
+    public MemoryMetricsDTO heap_memory;
+
+    @XmlElement(name="non_heap_memory")
+    public MemoryMetricsDTO non_heap_memory;
+
+    @XmlAttribute(name="classes_loaded")
+    public int classes_loaded;
+
+    @XmlAttribute(name="classes_unloaded")
+    public long classes_unloaded;
+
+    @XmlAttribute(name="threads_current")
+    public int threads_current;
+
+    @XmlAttribute(name="threads_peak")
+    public int threads_peak;
+
+    @XmlAttribute(name="os_arch")
+    public String os_arch;
+
+    @XmlAttribute(name="os_name")
+    public String os_name;
+
+    @XmlAttribute(name="os_memory_total")
+    public long os_memory_total;
+
+    @XmlAttribute(name="os_memory_free")
+    public long os_memory_free;
+
+    @XmlAttribute(name="os_swap_total")
+    public long os_swap_total;
+
+    @XmlAttribute(name="os_swap_free")
+    public long os_swap_free;
+
+    @XmlAttribute(name="os_fd_open")
+    public long os_fd_open;
+
+    @XmlAttribute(name="os_fd_max")
+    public long os_fd_max;
+
+    @XmlAttribute(name="os_load_average")
+    public double os_load_average;
+
+    @XmlAttribute(name="os_cpu_time")
+    public long os_cpu_time;
+
+    @XmlAttribute(name="os_processors")
+    public int os_processors;
+
+    @XmlAttribute(name="runtime_name")
+    public String runtime_name;
+
+    @XmlAttribute(name="jvm_name")
+    public String jvm_name;
+
+    @XmlAttribute(name="uptime")
+    public long uptime;
+
+    @XmlAttribute(name="start_time")
+    public long start_time;
+
+}
\ No newline at end of file

Copied: activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/MemoryMetricsDTO.java (from r1134946, activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/BrokerStatusDTO.java)
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/MemoryMetricsDTO.java?p2=activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/MemoryMetricsDTO.java&p1=activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/BrokerStatusDTO.java&r1=1134946&r2=1134991&rev=1134991&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/BrokerStatusDTO.java (original)
+++ activemq/activemq-apollo/trunk/apollo-dto/src/main/java/org/apache/activemq/apollo/dto/MemoryMetricsDTO.java Sun Jun 12 21:46:55 2011
@@ -16,9 +16,10 @@
  */
 package org.apache.activemq.apollo.dto;
 
-import javax.xml.bind.annotation.*;
-import java.util.ArrayList;
-import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlRootElement;
 
 /**
  * <p>
@@ -26,38 +27,16 @@ import java.util.List;
  *
  * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
  */
-@XmlRootElement(name="broker_status")
 @XmlAccessorType(XmlAccessType.FIELD)
-public class BrokerStatusDTO extends ServiceStatusDTO {
+public class MemoryMetricsDTO {
 
-    /**
-     * Version of the broker
-     */
-	@XmlAttribute
-	public String version;
-
-    /**
-     * The current time on the broker machine.  In milliseconds since the epoch.
-     */
-	@XmlAttribute(name="current_time")
-	public long current_time;
-
-    /**
-     * Ids of all the virtual hosts running on the broker
-     */
-    @XmlElement(name="virtual_host")
-    public List<String> virtual_hosts = new ArrayList<String>();
-
-    /**
-     * Ids of all the connectors running on the broker
-     */
-    @XmlElement(name="connector")
-    public List<String> connectors = new ArrayList<String>();
-
-    /**
-     * Ids of all the connections running on the broker
-     */
-    @XmlElement(name="connection")
-    public List<LongIdLabeledDTO> connections = new ArrayList<LongIdLabeledDTO>();
+    @XmlAttribute(name="used")
+    public long used;
 
-}
+    @XmlAttribute(name="alloc")
+    public long alloc;
+
+    @XmlAttribute(name="max")
+    public long max;
+
+}
\ No newline at end of file

Modified: activemq/activemq-apollo/trunk/apollo-web/src/main/scala/org/apache/activemq/apollo/web/resources/BrokerResource.scala
URL: http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-web/src/main/scala/org/apache/activemq/apollo/web/resources/BrokerResource.scala?rev=1134991&r1=1134990&r2=1134991&view=diff
==============================================================================
--- activemq/activemq-apollo/trunk/apollo-web/src/main/scala/org/apache/activemq/apollo/web/resources/BrokerResource.scala (original)
+++ activemq/activemq-apollo/trunk/apollo-web/src/main/scala/org/apache/activemq/apollo/web/resources/BrokerResource.scala Sun Jun 12 21:46:55 2011
@@ -33,6 +33,9 @@ import core.Response
 import Response.Status._
 import org.josql.expressions.SelectItemExpression
 import org.apache.activemq.apollo.util.BaseService._
+import management.ManagementFactory
+import javax.management.ObjectName
+import javax.management.openmbean.CompositeData
 
 /**
  * <p>
@@ -61,6 +64,7 @@ case class BrokerResource() extends Reso
         val result = new BrokerStatusDTO
 
         result.id = broker.id
+        result.jvm_metrics = create_jvm_metrics
         result.current_time = System.currentTimeMillis
         result.state = broker.service_state.toString
         result.state_since = broker.service_state.since
@@ -85,6 +89,66 @@ case class BrokerResource() extends Reso
     }
   }
 
+
+  private def create_jvm_metrics = {
+    val rc = new JvmMetricsDTO
+    rc.jvm_name = Broker.jvm
+
+    implicit def to_object_name(value:String):ObjectName = new ObjectName(value)
+    implicit def to_long(value:AnyRef):Long = value.asInstanceOf[java.lang.Long].longValue()
+    implicit def to_int(value:AnyRef):Int = value.asInstanceOf[java.lang.Integer].intValue()
+    implicit def to_double(value:AnyRef):Double = value.asInstanceOf[java.lang.Double].doubleValue()
+
+    def attempt(func: => Unit) = {
+      try {
+        func
+      } catch {
+        case _ => // ignore
+      }
+    }
+
+    val mbean_server = ManagementFactory.getPlatformMBeanServer()
+
+    attempt( rc.uptime = mbean_server.getAttribute("java.lang:type=Runtime", "Uptime") )
+    attempt( rc.start_time = mbean_server.getAttribute("java.lang:type=Runtime", "StartTime") )
+    attempt( rc.runtime_name = mbean_server.getAttribute("java.lang:type=Runtime", "Name").toString )
+
+    rc.os_name = Broker.os
+    attempt( rc.os_arch = mbean_server.getAttribute("java.lang:type=OperatingSystem", "Arch").toString )
+
+    attempt( rc.os_fd_open = mbean_server.getAttribute("java.lang:type=OperatingSystem", "OpenFileDescriptorCount"))
+    rc.os_fd_max = Broker.max_fd_limit.getOrElse(0)
+
+    attempt( rc.os_memory_total = mbean_server.getAttribute("java.lang:type=OperatingSystem", "TotalPhysicalMemorySize") )
+    attempt( rc.os_memory_free = mbean_server.getAttribute("java.lang:type=OperatingSystem", "FreePhysicalMemorySize") )
+
+    attempt( rc.os_swap_free = mbean_server.getAttribute("java.lang:type=OperatingSystem", "FreeSwapSpaceSize") )
+    attempt( rc.os_swap_free = mbean_server.getAttribute("java.lang:type=OperatingSystem", "TotalSwapSpaceSize") )
+
+    attempt( rc.os_load_average = mbean_server.getAttribute("java.lang:type=OperatingSystem", "SystemLoadAverage") )
+    attempt( rc.os_cpu_time = mbean_server.getAttribute("java.lang:type=OperatingSystem", "ProcessCpuTime") )
+    attempt( rc.os_processors = mbean_server.getAttribute("java.lang:type=OperatingSystem", "AvailableProcessors") )
+
+    attempt( rc.classes_loaded = mbean_server.getAttribute("java.lang:type=ClassLoading", "LoadedClassCount") )
+    attempt( rc.classes_unloaded = mbean_server.getAttribute("java.lang:type=ClassLoading", "UnloadedClassCount") )
+
+    attempt( rc.threads_peak = mbean_server.getAttribute("java.lang:type=Threading", "PeakThreadCount") )
+    attempt( rc.threads_current = mbean_server.getAttribute("java.lang:type=Threading", "ThreadCount") )
+
+    def memory_metrics(data:CompositeData) = {
+      val rc = new MemoryMetricsDTO
+      rc.alloc =  data.get("committed").asInstanceOf[java.lang.Long].longValue()
+      rc.used =  data.get("used").asInstanceOf[java.lang.Long].longValue()
+      rc.max =  data.get("max").asInstanceOf[java.lang.Long].longValue()
+      rc
+    }
+
+    attempt( rc.heap_memory = memory_metrics(mbean_server.getAttribute("java.lang:type=Memory", "HeapMemoryUsage").asInstanceOf[CompositeData]) )
+    attempt( rc.non_heap_memory = memory_metrics(mbean_server.getAttribute("java.lang:type=Memory", "NonHeapMemoryUsage").asInstanceOf[CompositeData]) )
+
+    rc
+  }
+
   @GET
   @Path("queue-metrics")
   def get_queue_metrics(): AggregateQueueMetricsDTO = {