CSV Save Start Script

Tcat Server reached its End of Life in 2017. Contact your Customer Success Manager to determine options for managing, monitoring, or deploying your application.

Run the start script just once when you have it configured. You should see a success message in the admin shell, and your Tomcat’s catalina.out log file should show that it is now collecting metric data for the metrics you listed, on each of the servers in the Tcat server group matching the ID you configured.

As soon as you execute this script, it adds a group membership event listener that makes any servers added to the group also begin monitoring these metrics, and any server you remove from the group will have the metric monitors removed as well. You can run the start script as many times as you like – it only refreshes the listener and monitors on each subsequent re-run, whether or not any refresh is needed. You should schedule this start script to run on Tcat startup so that the event listener runs after Tcat console server JVM restarts.

import com.mulesoft.common.server.GroupMembershipEvent
import com.mulesoft.common.agent.jmx.JmxCollectorInfo
import com.mulesoft.common.remoting.RemoteContext
import com.mulesoft.common.agent.jmx.JmxService
import org.mule.galaxy.util.SecurityUtils
import org.mule.galaxy.ee.common.dto.ChartDefinition
import org.mule.galaxy.ee.common.charts.ChartDefinitionTypes
import org.mule.galaxy.DuplicateItemException
import org.mule.galaxy.ee.common.dto.ServerGroup
import org.mule.galaxy.event.EventManager
import org.mule.galaxy.event.annotation.Async
import org.mule.galaxy.event.annotation.BindToEvent
import org.mule.galaxy.event.annotation.OnEvent
import org.mule.galaxy.NotFoundException

import org.springframework.context.ApplicationContext

public class DevGroup10sMetricsMonitorListener {

    // The below variables are for the user to configure, to set what is to
    // be monitored on which server group.
    def groupId = "401e81bf-b792-49fd-9006-eff59cd29387"
    def objectNames = [ "Catalina:type=GlobalRequestProcessor,name=http-8080",
    def attributeNames = [ "requestCount", "currentThreadsBusy" ]
    def trackDeltas = [ false, false ]
    def period = 10

    // The below variables are more programmatic, and shouldn't need changing.
    def applicationContext
    def serverManager
    def eventManager
    def chartService

    public DevGroup10sMetricsMonitorListener(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext

    public void install() {
        serverManager = applicationContext.getBean("serverManager")
        eventManager = applicationContext.getBean("eventManager")
        chartService = applicationContext.getBean("chartService")

        // Get the group by ID so that if it gets renamed we can still track it.
        try {
            ServerGroup group = serverManager.getServerGroup(groupId)
        } catch (NotFoundException e) {
            println e

        // Remove the previous listener, if any.
        eventManager.listeners.each {
            if (it.class.simpleName == "DevGroup10sMetricsMonitorListener") {
        // Add this event listener.

        // Add monitors for all servers that are already in this group.
        def results = serverManager.getServersForGroup(groupId, 0, -1, null)
        def servers = results.getData()
        servers.each { server ->
            // Only talk to the server if it is reachable by the console..
            if (serverManager.isServerUp(server.id)) {
                def metricCount = -1;
                objectNames.each { objectName ->
                    def attributeName = attributeNames[metricCount]
                    def trackDelta = trackDeltas[metricCount]
                    addMonitor(server.id, objectName, attributeName, trackDelta)

    void onEvent(com.mulesoft.common.server.GroupMembershipEvent e) {
        if (e.groupId == this.groupId) {
            def metricCount = -1;
            objectNames.each { objectName ->
                def attributeName = attributeNames[metricCount]
                def trackDelta = trackDeltas[metricCount]
                if (e.added == true) {
                    addMonitor(e.serverId, objectName, attributeName, trackDelta)

    void addMonitor(String serverId, String objectName,
                    String attributeName, boolean trackDelta) {
        // Start monitoring the JMX attribute in this server's agent.
        def d = new ChartDefinition()
        def jmxCollectorInfoId = groupId + "|" + period + "|" + serverId + "|" + objectName + "|" + attributeName + "|" + trackDelta
        Map<String, String> config = d.getConfiguration()
        config.put(ChartDefinition.JMX_OBJECT_NAME, objectName)
        config.put(ChartDefinition.JMX_ATTRIBUTE, attributeName)
        config.put(ChartDefinition.JMX_PERIOD, period as String)
        config.put(ChartDefinition.JMX_TRACK_DELTA, trackDelta as String)

        try {
            println "Started monitoring ${jmxCollectorInfoId}"
        } catch (DuplicateItemException e) {
            // This metric is already being monitored.
            println "Already being monitored: ${jmxCollectorInfoId}"

new DevGroup10sMetricsMonitorListener(applicationContext).install()

Was this article helpful?

💙 Thanks for your feedback!

Edit on GitHub