From 51098f99448f945f60fe9314bfec52a8df4d019e Mon Sep 17 00:00:00 2001 From: Jeffrey Chien Date: Thu, 10 Oct 2024 18:51:11 -0400 Subject: [PATCH] Add configuration files for JMX support. (#817) *Description of changes:* ### 1. rules/*.yaml The [JMX Metric Insight](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/instrumentation/jmx-metrics/javaagent/README.md) and the [JMX Metric Gatherer](https://github.com/open-telemetry/opentelemetry-java-contrib/tree/main/jmx-metrics) have different pre-defined target systems (activemq, tomcat, etc.) and even different metrics within each shared target system (https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/9765). This is an effort to unify the metrics being generated by deferring to the Gatherer's definition files. By placing it in the same path as the JMX Metric Insight resources, the rule files can be overwritten and referred to [directly](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/instrumentation/jmx-metrics/javaagent/src/main/java/io/opentelemetry/instrumentation/javaagent/jmx/JmxMetricInsightInstaller.java#L55). ``` > gradlew build > jar tf otelagent/build/libs/aws-opentelemetry-agent-1.33.0-SNAPSHOT.jar | grep jmx inst/META-INF/io/opentelemetry/instrumentation/io.opentelemetry.jmx-metrics.properties inst/io/opentelemetry/javaagent/shaded/instrumentation/javaagent/jmx/ inst/io/opentelemetry/javaagent/shaded/instrumentation/javaagent/jmx/JmxMetricInsightInstaller.classdata inst/io/opentelemetry/javaagent/shaded/instrumentation/jmx/ inst/io/opentelemetry/javaagent/shaded/instrumentation/jmx/engine/ inst/io/opentelemetry/javaagent/shaded/instrumentation/jmx/engine/AttributeInfo.classdata inst/io/opentelemetry/javaagent/shaded/instrumentation/jmx/engine/BeanAttributeExtractor.classdata inst/io/opentelemetry/javaagent/shaded/instrumentation/jmx/engine/BeanFinder$1.classdata inst/io/opentelemetry/javaagent/shaded/instrumentation/jmx/engine/BeanFinder.classdata inst/io/opentelemetry/javaagent/shaded/instrumentation/jmx/engine/BeanGroup.classdata inst/io/opentelemetry/javaagent/shaded/instrumentation/jmx/engine/DetectionStatus.classdata inst/io/opentelemetry/javaagent/shaded/instrumentation/jmx/engine/JmxMetricInsight.classdata inst/io/opentelemetry/javaagent/shaded/instrumentation/jmx/engine/MetricAttribute.classdata inst/io/opentelemetry/javaagent/shaded/instrumentation/jmx/engine/MetricAttributeExtractor.classdata inst/io/opentelemetry/javaagent/shaded/instrumentation/jmx/engine/MetricConfiguration.classdata inst/io/opentelemetry/javaagent/shaded/instrumentation/jmx/engine/MetricDef.classdata inst/io/opentelemetry/javaagent/shaded/instrumentation/jmx/engine/MetricExtractor.classdata inst/io/opentelemetry/javaagent/shaded/instrumentation/jmx/engine/MetricInfo$Type.classdata inst/io/opentelemetry/javaagent/shaded/instrumentation/jmx/engine/MetricInfo.classdata inst/io/opentelemetry/javaagent/shaded/instrumentation/jmx/engine/MetricRegistrar$1.classdata inst/io/opentelemetry/javaagent/shaded/instrumentation/jmx/engine/MetricRegistrar.classdata inst/io/opentelemetry/javaagent/shaded/instrumentation/jmx/yaml/ inst/io/opentelemetry/javaagent/shaded/instrumentation/jmx/yaml/JmxConfig.classdata inst/io/opentelemetry/javaagent/shaded/instrumentation/jmx/yaml/JmxRule.classdata inst/io/opentelemetry/javaagent/shaded/instrumentation/jmx/yaml/Metric.classdata inst/io/opentelemetry/javaagent/shaded/instrumentation/jmx/yaml/MetricStructure.classdata inst/io/opentelemetry/javaagent/shaded/instrumentation/jmx/yaml/RuleParser.classdata inst/jmx/ inst/jmx/rules/ inst/jmx/rules/activemq.yaml inst/jmx/rules/hadoop.yaml inst/jmx/rules/jetty.yaml inst/jmx/rules/kafka-broker.yaml inst/jmx/rules/tomcat.yaml inst/jmx/rules/wildfly.yaml inst/jmx/ inst/jmx/rules/ inst/jmx/rules/jvm.yaml inst/jmx/rules/kafka-consumer.yaml inst/jmx/rules/kafka-producer.yaml inst/jmx/rules/kafka.yaml inst/jmx/rules/tomcat.yaml inst/jmx/view.yaml ``` This makes it easier for users to specify the target systems via environment variables. ``` OTEL_JMX_TARGET_SYSTEM: jvm, tomcat ``` This results in ``` petclinic [otel.javaagent 2024-06-14 20:27:36:575 +0000] [main] INFO io.opentelemetry.javaagent.shaded.instrumentation.jmx.yaml.RuleParser - jvm: found 5 metric rules petclinic [otel.javaagent 2024-06-14 20:27:36:607 +0000] [main] INFO io.opentelemetry.javaagent.shaded.instrumentation.jmx.yaml.RuleParser - tomcat: found 6 metric rules petclinic [otel.javaagent 2024-06-14 20:27:37:731 +0000] [pool-8-thread-1] INFO io.opentelemetry.javaagent.shaded.instrumentation.jmx.engine.MetricRegistrar - Created Gauge for jvm.classes.loaded petclinic [otel.javaagent 2024-06-14 20:27:37:738 +0000] [pool-8-thread-1] INFO io.opentelemetry.javaagent.shaded.instrumentation.jmx.engine.MetricRegistrar - Created Counter for jvm.gc.collections.count petclinic [otel.javaagent 2024-06-14 20:27:37:739 +0000] [pool-8-thread-1] INFO io.opentelemetry.javaagent.shaded.instrumentation.jmx.engine.MetricRegistrar - Created Counter for jvm.gc.collections.elapsed petclinic [otel.javaagent 2024-06-14 20:27:37:740 +0000] [pool-8-thread-1] INFO io.opentelemetry.javaagent.shaded.instrumentation.jmx.engine.MetricRegistrar - Created Gauge for jvm.memory.heap petclinic [otel.javaagent 2024-06-14 20:27:37:740 +0000] [pool-8-thread-1] INFO io.opentelemetry.javaagent.shaded.instrumentation.jmx.engine.MetricRegistrar - Created Gauge for jvm.memory.nonheap petclinic [otel.javaagent 2024-06-14 20:27:37:745 +0000] [pool-8-thread-1] INFO io.opentelemetry.javaagent.shaded.instrumentation.jmx.engine.MetricRegistrar - Created Gauge for jvm.memory.pool.usage petclinic [otel.javaagent 2024-06-14 20:27:37:745 +0000] [pool-8-thread-1] INFO io.opentelemetry.javaagent.shaded.instrumentation.jmx.engine.MetricRegistrar - Created Gauge for jvm.threads.count ``` By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. --- .../src/main/resources/jmx/rules/jvm.yaml | 37 ++- .../resources/jmx/rules/kafka-consumer.yaml | 51 ++++ .../resources/jmx/rules/kafka-producer.yaml | 61 +++++ .../src/main/resources/jmx/rules/kafka.yaml | 234 ++++++++++++++++++ .../src/main/resources/jmx/rules/tomcat.yaml | 132 ++++++++++ 5 files changed, 510 insertions(+), 5 deletions(-) create mode 100644 instrumentation/jmx-metrics/src/main/resources/jmx/rules/kafka-consumer.yaml create mode 100644 instrumentation/jmx-metrics/src/main/resources/jmx/rules/kafka-producer.yaml create mode 100644 instrumentation/jmx-metrics/src/main/resources/jmx/rules/kafka.yaml create mode 100644 instrumentation/jmx-metrics/src/main/resources/jmx/rules/tomcat.yaml diff --git a/instrumentation/jmx-metrics/src/main/resources/jmx/rules/jvm.yaml b/instrumentation/jmx-metrics/src/main/resources/jmx/rules/jvm.yaml index b2c29cfbc2..6f3606e5a8 100644 --- a/instrumentation/jmx-metrics/src/main/resources/jmx/rules/jvm.yaml +++ b/instrumentation/jmx-metrics/src/main/resources/jmx/rules/jvm.yaml @@ -8,7 +8,7 @@ rules: LoadedClassCount: metric: loaded desc: Number of loaded classes - - bean: java.lang:type=GarbageCollector,* + - bean: java.lang:type=GarbageCollector,name=* prefix: jvm.gc.collections. type: counter metricAttribute: @@ -27,13 +27,31 @@ rules: prefix: jvm.memory. type: gauge mapping: + HeapMemoryUsage.init: + metric: heap.init + desc: The initial amount of memory that the JVM requests from the operating system for the heap HeapMemoryUsage.used: metric: heap.used desc: The current heap usage + HeapMemoryUsage.committed: + metric: heap.committed + desc: The amount of memory that is guaranteed to be available for the heap + HeapMemoryUsage.max: + metric: heap.max + desc: The maximum amount of memory can be used for the heap + NonHeapMemoryUsage.init: + metric: nonheap.init + desc: The initial amount of memory that the JVM requests from the operating system for non-heap purposes NonHeapMemoryUsage.used: metric: nonheap.used - desc: The current non-heap usage - - bean: java.lang:type=MemoryPool,* + desc: The current non-heap memory usage + NonHeapMemoryUsage.committed: + metric: nonheap.committed + desc: The amount of memory that is guaranteed to be available for non-heap purposes + NonHeapMemoryUsage.max: + metric: nonheap.max + desc: The maximum amount of memory can be used for non-heap purposes + - bean: java.lang:type=MemoryPool,name=* unit: by prefix: jvm.memory.pool. type: gauge @@ -43,9 +61,18 @@ rules: CollectionUsage.used: metric: used_after_last_gc desc: Memory used after the most recent gc event + Usage.init: + metric: init + desc: The initial amount of memory that the JVM requests from the operating system for the memory pool Usage.used: metric: used - desc: Current memory pool used + desc: The current memory pool memory usage + Usage.committed: + metric: committed + desc: The amount of memory that is guaranteed to be available for the memory pool + Usage.max: + metric: max + desc: The maximum amount of memory can be used for the memory pool - bean: java.lang:type=Threading unit: "1" prefix: jvm.threads. @@ -54,7 +81,7 @@ rules: ThreadCount: metric: count desc: Number of threads - - bean: java.lang:type=OperatingSystem,* + - bean: java.lang:type=OperatingSystem prefix: jvm.cpu. type: gauge mapping: diff --git a/instrumentation/jmx-metrics/src/main/resources/jmx/rules/kafka-consumer.yaml b/instrumentation/jmx-metrics/src/main/resources/jmx/rules/kafka-consumer.yaml new file mode 100644 index 0000000000..c3d2860b90 --- /dev/null +++ b/instrumentation/jmx-metrics/src/main/resources/jmx/rules/kafka-consumer.yaml @@ -0,0 +1,51 @@ +--- +rules: + - bean: kafka.consumer:type=consumer-fetch-manager-metrics,client-id=* + metricAttribute: + client-id: param(client-id) + mapping: + fetch-rate: + metric: kafka.consumer.fetch-rate + type: gauge + desc: The number of fetch requests for all topics per second + unit: "1" + records-lag-max: + metric: kafka.consumer.records-lag-max + type: gauge + desc: Number of messages the consumer lags behind the producer + unit: "1" + bytes-consumed-rate: + metric: kafka.consumer.total.bytes-consumed-rate + type: gauge + desc: The average number of bytes consumed for all topics per second + unit: by + fetch-size-avg: + metric: kafka.consumer.total.fetch-size-avg + type: gauge + desc: The average number of bytes fetched per request for all topics + unit: by + records-consumed-rate: + metric: kafka.consumer.total.records-consumed-rate + type: gauge + desc: The average number of records consumed for all topics per second + unit: "1" + - bean: kafka.consumer:type=consumer-fetch-manager-metrics,client-id=*,topic=* + metricAttribute: + client-id: param(client-id) + topic: param(topic) + mapping: + bytes-consumed-rate: + metric: kafka.consumer.bytes-consumed-rate + type: gauge + desc: The average number of bytes consumed per second + unit: by + fetch-size-avg: + metric: kafka.consumer.fetch-size-avg + type: gauge + desc: The average number of bytes fetched per request + unit: by + records-consumed-rate: + metric: kafka.consumer.records-consumed-rate + type: gauge + desc: The average number of records consumed per second + unit: "1" diff --git a/instrumentation/jmx-metrics/src/main/resources/jmx/rules/kafka-producer.yaml b/instrumentation/jmx-metrics/src/main/resources/jmx/rules/kafka-producer.yaml new file mode 100644 index 0000000000..dbbd95f7ae --- /dev/null +++ b/instrumentation/jmx-metrics/src/main/resources/jmx/rules/kafka-producer.yaml @@ -0,0 +1,61 @@ +--- +rules: + - bean: kafka.producer:type=producer-metrics,client-id=* + metricAttribute: + client-id: param(client-id) + mapping: + io-wait-time-ns-avg: + metric: kafka.producer.io-wait-time-ns-avg + type: gauge + desc: The average length of time the I/O thread spent waiting for a socket ready for reads or writes + unit: ns + outgoing-byte-rate: + metric: kafka.producer.outgoing-byte-rate + type: gauge + desc: The average number of outgoing bytes sent per second to all servers + unit: by + request-latency-avg: + metric: kafka.producer.request-latency-avg + type: gauge + desc: The average request latency + unit: ms + request-rate: + metric: kafka-producer.request-rate + type: gauge + desc: The average number of requests sent per second + unit: "1" + response-rate: + metric: kafka.producer.response-rate + type: gauge + desc: Responses received per second + unit: "1" + - bean: kafka.producer:type=producer-topic-metrics,client-id=*,topic=* + metricAttribute: + client-id: param(client-id) + topic: param(topic) + mapping: + byte-rate: + metric: kafka.producer.byte-rate + type: gauge + desc: The average number of bytes sent per second for a topic + unit: by + compression-rate: + metric: kafka.producer.compression-rate + type: gauge + desc: The average compression rate of record batches for a topic + unit: "1" + record-error-rate: + metric: kafka.producer.record-error-rate + type: gauge + desc: The average per-second number of record sends that resulted in errors for a topic + unit: "1" + record-retry-rate: + metric: kafka.producer.record-retry-rate + type: gauge + desc: The average per-second number of retried record sends for a topic + unit: "1" + record-send-rate: + metric: kafka.producer.record-send-rate + type: gauge + desc: The average number of records sent per second for a topic + unit: "1" diff --git a/instrumentation/jmx-metrics/src/main/resources/jmx/rules/kafka.yaml b/instrumentation/jmx-metrics/src/main/resources/jmx/rules/kafka.yaml new file mode 100644 index 0000000000..5da5d93d11 --- /dev/null +++ b/instrumentation/jmx-metrics/src/main/resources/jmx/rules/kafka.yaml @@ -0,0 +1,234 @@ +--- +rules: + - bean: kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec + mapping: + Count: + metric: kafka.message.count + type: counter + desc: The number of messages received by the broker + unit: "{messages}" + - bean: kafka.server:type=BrokerTopicMetrics,name=TotalProduceRequestsPerSec + metricAttribute: + type: const(produce) + mapping: + Count: + metric: kafka.request.count + type: counter + desc: The number of requests received by the broker + unit: "{requests}" + - bean: kafka.server:type=BrokerTopicMetrics,name=TotalFetchRequestsPerSec + metricAttribute: + type: const(fetch) + mapping: + Count: + metric: kafka.request.count + type: counter + desc: The number of requests received by the broker + unit: "{requests}" + - bean: kafka.server:type=BrokerTopicMetrics,name=FailedProduceRequestsPerSec + metricAttribute: + type: const(produce) + mapping: + Count: + metric: kafka.request.failed + type: counter + desc: The number of requests to the broker resulting in a failure + unit: "{requests}" + - bean: kafka.server:type=BrokerTopicMetrics,name=FailedFetchRequestsPerSec + metricAttribute: + type: const(fetch) + mapping: + Count: + metric: kafka.request.failed + type: counter + desc: The number of requests to the broker resulting in a failure + unit: "{requests}" + - bean: kafka.network:type=RequestMetrics,name=TotalTimeMs,request=Produce + metricAttribute: + type: const(produce) + unit: ms + mapping: + Count: + metric: kafka.request.time.total + type: counter + desc: The total time the broker has taken to service requests + 50thPercentile: + metric: kafka.request.time.50p + type: gauge + desc: The 50th percentile time the broker has taken to service requests + 99thPercentile: + metric: kafka.request.time.99p + type: gauge + desc: The 99th percentile time the broker has taken to service requests + Mean: + metric: kafka.request.time.avg + type: gauge + desc: The average time the broker has taken to service requests + - bean: kafka.network:type=RequestMetrics,name=TotalTimeMs,request=FetchConsumer + metricAttribute: + type: const(fetchconsumer) + unit: ms + mapping: + Count: + metric: kafka.request.time.total + type: counter + desc: The total time the broker has taken to service requests + 50thPercentile: + metric: kafka.request.time.50p + type: gauge + desc: The 50th percentile time the broker has taken to service requests + 99thPercentile: + metric: kafka.request.time.99p + type: gauge + desc: The 99th percentile time the broker has taken to service requests + Mean: + metric: kafka.request.time.avg + type: gauge + desc: The average time the broker has taken to service requests + - bean: kafka.network:type=RequestMetrics,name=TotalTimeMs,request=FetchFollower + metricAttribute: + type: const(fetchfollower) + unit: ms + mapping: + Count: + metric: kafka.request.time.total + type: counter + desc: The total time the broker has taken to service requests + 50thPercentile: + metric: kafka.request.time.50p + type: gauge + desc: The 50th percentile time the broker has taken to service requests + 99thPercentile: + metric: kafka.request.time.99p + type: gauge + desc: The 99th percentile time the broker has taken to service requests + Mean: + metric: kafka.request.time.avg + type: gauge + desc: The average time the broker has taken to service requests + - bean: kafka.server:type=BrokerTopicMetrics,name=BytesInPerSec + metricAttribute: + direction: const(in) + mapping: + Count: + metric: kafka.network.io + type: counter + desc: The bytes received or sent by the broker + unit: by + - bean: kafka.server:type=BrokerTopicMetrics,name=BytesOutPerSec + metricAttribute: + direction: const(out) + mapping: + Count: + metric: kafka.network.io + type: counter + desc: The bytes received or sent by the broker + unit: by + - bean: kafka.server:type=DelayedOperationPurgatory,name=PurgatorySize,delayedOperation=Produce + metricAttribute: + type: const(produce) + mapping: + Value: + metric: kafka.purgatory.size + type: gauge + desc: The number of requests waiting in purgatory + unit: "{requests}" + - bean: kafka.server:type=DelayedOperationPurgatory,name=PurgatorySize,delayedOperation=Fetch + metricAttribute: + type: const(fetch) + mapping: + Value: + metric: kafka.purgatory.size + type: gauge + desc: The number of requests waiting in purgatory + unit: "{requests}" + - bean: kafka.server:type=ReplicaManager,name=PartitionCount + mapping: + Value: + metric: kafka.partition.count + type: gauge + desc: The number of partitions on the broker + unit: "{partitions}" + - bean: kafka.controller:type=KafkaController,name=OfflinePartitionsCount + mapping: + Value: + metric: kafka.partition.offline + type: gauge + desc: The number of partitions offline + unit: "{partitions}" + - bean: kafka.server:type=ReplicaManager,name=UnderReplicatedPartitions + mapping: + Value: + metric: kafka.partition.under_replicated + type: gauge + desc: The number of under replicated partitions + unit: "{partitions}" + - bean: kafka.server:type=ReplicaManager,name=IsrShrinksPerSec + metricAttribute: + operation: const(shrink) + mapping: + Count: + metric: kafka.isr.operation.count + type: counter + desc: The number of in-sync replica shrink and expand operations + unit: "{operations}" + - bean: kafka.server:type=ReplicaManager,name=IsrExpandsPerSec + metricAttribute: + operation: const(expand) + mapping: + Count: + metric: kafka.isr.operation.count + type: counter + desc: The number of in-sync replica shrink and expand operations + unit: "{operations}" + - bean: kafka.server:type=ReplicaFetcherManager,name=MaxLag,clientId=Replica + mapping: + Value: + metric: kafka.max.lag + type: gauge + desc: max lag in messages between follower and leader replicas + unit: "{messages}" + - bean: kafka.controller:type=KafkaController,name=ActiveControllerCount + mapping: + Value: + metric: kafka.controller.active.count + type: gauge + desc: controller is active on broker + unit: "{controllers}" + - bean: kafka.controller:type=ControllerStats,name=LeaderElectionRateAndTimeMs + mapping: + Count: + metric: kafka.leader.election.rate + type: counter + desc: leader election rate - increasing indicates broker failures + unit: "{elections}" + - bean: kafka.controller:type=ControllerStats,name=UncleanLeaderElectionsPerSec + mapping: + Count: + metric: kafka.unclean.election.rate + type: counter + desc: unclean leader election rate - increasing indicates broker failures + unit: "{elections}" + - bean: kafka.network:type=RequestChannel,name=RequestQueueSize + mapping: + Value: + metric: kafka.request.queue + type: gauge + desc: size of the request queue + unit: "{requests}" + - bean: kafka.log:type=LogFlushStats,name=LogFlushRateAndTimeMs + unit: ms + prefix: kafka.logs.flush.time. + mapping: + Count: + metric: count + type: counter + desc: log flush count + 50thPercentile: + metric: median + type: gauge + desc: log flush time - 50th percentile + 99thPercentile: + metric: 99p + type: gauge + desc: log flush time - 99th percentile diff --git a/instrumentation/jmx-metrics/src/main/resources/jmx/rules/tomcat.yaml b/instrumentation/jmx-metrics/src/main/resources/jmx/rules/tomcat.yaml new file mode 100644 index 0000000000..0d7fa1602f --- /dev/null +++ b/instrumentation/jmx-metrics/src/main/resources/jmx/rules/tomcat.yaml @@ -0,0 +1,132 @@ +--- +rules: + - bean: Catalina:type=Manager,host=localhost,context=* + metricAttribute: + context: param(context) + mapping: + activeSessions: + metric: tomcat.sessions + type: gauge + unit: sessions + desc: The number of active sessions. + - bean: Catalina:type=GlobalRequestProcessor,name=* + metricAttribute: + name: param(name) + mapping: + errorCount: + metric: tomcat.errors + type: counter + unit: errors + desc: The number of errors encountered. + requestCount: + metric: tomcat.request_count + type: counter + unit: requests + desc: The total requests. + maxTime: + metric: tomcat.max_time + type: gauge + unit: ms + desc: Maximum time to process a request + processingTime: + metric: tomcat.processing_time + type: counter + unit: ms + desc: The total processing time. + bytesReceived: + metric: tomcat.traffic + metricAttribute: + direction: const(received) + type: counter + unit: by + desc: The number of bytes transmitted and received. + bytesSent: + metric: tomcat.traffic + metricAttribute: + direction: const(sent) + type: counter + unit: by + desc: The number of bytes transmitted and received. + - bean: Catalina:type=ThreadPool,name=* + metricAttribute: + name: param(name) + mapping: + currentThreadCount: + metric: tomcat.threads + metricAttribute: + state: const(idle) + type: gauge + unit: threads + desc: The number of threads + currentThreadsBusy: + metric: tomcat.threads + metricAttribute: + state: const(busy) + type: gauge + unit: threads + desc: The number of threads + - bean: Tomcat:type=Manager,host=localhost,context=* + metricAttribute: + context: param(context) + mapping: + activeSessions: + metric: tomcat.sessions + type: gauge + unit: sessions + desc: The number of active sessions. + - bean: Tomcat:type=GlobalRequestProcessor,name=* + metricAttribute: + name: param(name) + mapping: + errorCount: + metric: tomcat.errors + type: counter + unit: errors + desc: The number of errors encountered. + requestCount: + metric: tomcat.request_count + type: counter + unit: requests + desc: The total requests. + maxTime: + metric: tomcat.max_time + type: gauge + unit: ms + desc: Maximum time to process a request + processingTime: + metric: tomcat.processing_time + type: counter + unit: ms + desc: The total processing time. + bytesReceived: + metric: tomcat.traffic + metricAttribute: + direction: const(received) + type: counter + unit: by + desc: The number of bytes transmitted and received. + bytesSent: + metric: tomcat.traffic + metricAttribute: + direction: const(sent) + type: counter + unit: by + desc: The number of bytes transmitted and received. + - bean: Tomcat:type=ThreadPool,name=* + metricAttribute: + name: param(name) + mapping: + currentThreadCount: + metric: tomcat.threads + metricAttribute: + state: const(idle) + type: gauge + unit: threads + desc: The number of threads + currentThreadsBusy: + metric: tomcat.threads + metricAttribute: + state: const(busy) + type: gauge + unit: threads + desc: The number of threads