Skip to content

Commit

Permalink
Add JMX Metrics Test To Metric Agent Value Benchmark/
Browse files Browse the repository at this point in the history
Add opentelemetry-jmx-metrics.jar To MSI

Add Tomcat JMX Metrics Tests
  • Loading branch information
sethAmazon committed May 24, 2024
1 parent 4045108 commit d1fe328
Show file tree
Hide file tree
Showing 6 changed files with 197 additions and 2 deletions.
4 changes: 4 additions & 0 deletions msi/tools/amazon-cloudwatch-agent.wxs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
<ComponentRef Id='SchemaJSON' />
<ComponentRef Id='DownloaderEXE' />
<ComponentRef Id='TranslatorEXE' />
<ComponentRef Id='OtelJmxJar' />
<ComponentRef Id='CWAGENT_VERSION' />
<ComponentRef Id='LICENSE' />
<ComponentRef Id='NOTICE' />
Expand Down Expand Up @@ -119,6 +120,9 @@
<Component Id='TranslatorEXE' Guid='f4527006-edcb-4271-a971-039848bc8bb7' Win64='yes'>
<File Source='config-translator.exe' KeyPath='yes' Checksum='yes'/>
</Component>
<Component Id='OtelJmxJar' Guid='5af08c39-c483-4b08-8315-c99345684c4d' Win64='yes'>
<File Source='opentelemetry-jmx-metrics.jar' KeyPath='yes'/>
</Component>
<Component Id='CWAGENT_VERSION' Guid='f4ddf7bf-48fc-41f6-a914-4153a7cf0afc' Win64='yes'>
<File Source='CWAGENT_VERSION' KeyPath='yes'/>
</Component>
Expand Down
2 changes: 1 addition & 1 deletion test/metric/metric_value_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func (n *MetricValueFetcher) Fetch(namespace, metricName string, metricSpecificD
Period: &metricQueryPeriod,
Stat: aws.String(string(stat)),
},
Id: aws.String(strings.ToLower(metricName)),
Id: aws.String(strings.ToLower(strings.ReplaceAll(metricName, ".", "_"))),
},
}

Expand Down
27 changes: 27 additions & 0 deletions test/metric_value_benchmark/agent_configs/jmx_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"agent": {
"debug": true
},
"metrics": {
"namespace": "MetricValueBenchmarkJMXTest",
"force_flush_interval": 5,
"aggregation_dimensions": [
[
"InstanceId"
]
],
"append_dimensions": {
"InstanceId": "${aws:InstanceId}"
},
"metrics_collected": {
"jmx": [
{
"endpoint": "localhost:2020"
},
{
"endpoint": "localhost:2030"
}
]
}
}
}
Binary file not shown.
158 changes: 158 additions & 0 deletions test/metric_value_benchmark/jmx_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT

//go:build !windows

package metric_value_benchmark

import (
"log"
"time"

"github.com/aws/amazon-cloudwatch-agent-test/test/metric"
"github.com/aws/amazon-cloudwatch-agent-test/test/metric/dimension"
"github.com/aws/amazon-cloudwatch-agent-test/test/status"
"github.com/aws/amazon-cloudwatch-agent-test/test/test_runner"
"github.com/aws/amazon-cloudwatch-agent-test/util/common"
)

const jmxNamespace = "MetricValueBenchmarkJMXTest"

type JMXTestRunner struct {
test_runner.BaseTestRunner
}

var _ test_runner.ITestRunner = (*JMXTestRunner)(nil)

func (t *JMXTestRunner) Validate() status.TestGroupResult {
metricsToFetch := t.GetMeasuredMetrics()
testResults := make([]status.TestResult, len(metricsToFetch))
for i, metricName := range metricsToFetch {
testResults[i] = t.validateJMXMetric(metricName)
}

return status.TestGroupResult{
Name: t.GetTestName(),
TestResults: testResults,
}
}

func (t *JMXTestRunner) GetTestName() string {
return "JMX"
}

func (t *JMXTestRunner) GetAgentConfigFileName() string {
return "jmx_config.json"
}

func (t *JMXTestRunner) GetAgentRunDuration() time.Duration {
return 1 * time.Minute
}

func (t *JMXTestRunner) SetupBeforeAgentRun() error {
err := t.BaseTestRunner.SetupBeforeAgentRun()
if err != nil {
return err
}

log.Println("set up zookeeper and kafka")
startJMXCommands := []string{
"curl https://dlcdn.apache.org/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz -o apache-zookeeper-3.8.4-bin.tar.gz",
"tar -xzf apache-zookeeper-3.8.4-bin.tar.gz",
"mkdir apache-zookeeper-3.8.4-bin/data",
"touch apache-zookeeper-3.8.4-bin/conf/zoo.cfg",
"echo -e 'tickTime = 2000\ndataDir = ../data\nclientPort = 2181\ninitLimit = 5\nsyncLimit = 2\n' >> apache-zookeeper-3.8.4-bin/conf/zoo.cfg",
"apache-zookeeper-3.8.4-bin/bin/zkServer.sh start",
"curl https://dlcdn.apache.org/kafka/3.6.2/kafka_2.13-3.6.2.tgz -o kafka_2.13-3.6.2.tgz",
"tar -xzf kafka_2.13-3.6.2.tgz",
"echo 'KAFKA_JMX_OPTS=\"-Dcom.sun.management.jmxremote.port=2020 -Dcom.sun.management.jmxremote.rmi.port=2021 -Djava.rmi.server.hostname=localhost -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false\"'|cat - kafka_2.13-3.6.2/bin/kafka-run-class.sh > /tmp/kafka-jmx-config && mv /tmp/kafka-jmx-config kafka_2.13-3.6.2/bin/kafka-run-class.sh",
"sudo chmod +x kafka_2.13-3.6.2/bin/kafka-run-class.sh",
"kafka_2.13-3.6.2/bin/kafka-server-start.sh kafka_2.13-3.6.2/config/server.properties > /tmp/kafka-jar-logs.txt 2>&1 &",
"nohup java -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=2030 -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.rmi.port=2030 -Dcom.sun.management.jmxremote.host=0.0.0.0 -Djava.rmi.server.hostname=0.0.0.0 -Dserver.port=8090 -Dspring.application.admin.enabled=true -jar jars/spring-boot-web-starter-tomcat.jar > /tmp/spring-boot-web-starter-tomcat-jar.txt 2>&1 &",
}

err = common.RunCommands(startJMXCommands)
if err != nil {
return err
}
return nil
}

func (t *JMXTestRunner) GetMeasuredMetrics() []string {
return []string{
"jvm.threads.count",
"jvm.memory.pool.used",
"jvm.memory.pool.max",
"jvm.memory.pool.init",
"jvm.memory.pool.committed",
"jvm.memory.nonheap.used",
"jvm.memory.nonheap.max",
"jvm.memory.nonheap.init",
"jvm.memory.nonheap.committed",
"jvm.memory.heap.used",
"jvm.memory.heap.max",
"jvm.memory.heap.init",
"jvm.memory.heap.committed",
"jvm.gc.collections.elapsed",
"jvm.gc.collections.count",
"jvm.classes.loaded",
"kafka.unclean.election.rate",
"kafka.request.time.total",
"kafka.request.time.avg",
"kafka.request.time.99p",
"kafka.request.time.50p",
"kafka.request.queue",
"kafka.request.failed",
"kafka.request.count",
"kafka.purgatory.size",
"kafka.partition.under_replicated",
"kafka.partition.offline",
"kafka.partition.count",
"kafka.network.io",
"kafka.message.count",
"kafka.max.lag",
"kafka.leader.election.rate",
"kafka.isr.operation.count",
"kafka.controller.active.count",
"tomcat.traffic",
"tomcat.threads",
"tomcat.sessions",
"tomcat.request_count",
"tomcat.processing_time",
"tomcat.max_time",
"tomcat.errors",
}
}

func (t *JMXTestRunner) validateJMXMetric(metricName string) status.TestResult {
testResult := status.TestResult{
Name: metricName,
Status: status.FAILED,
}

dims, failed := t.DimensionFactory.GetDimensions([]dimension.Instruction{
{
Key: "InstanceId",
Value: dimension.UnknownDimensionValue(),
},
})

if len(failed) > 0 {
return testResult
}

fetcher := metric.MetricValueFetcher{}
values, err := fetcher.Fetch(jmxNamespace, metricName, dims, metric.AVERAGE, metric.HighResolutionStatPeriod)
log.Printf("metric values are %v", values)
if err != nil {
log.Printf("err: %v\n", err)
return testResult
}

if !metric.IsAllValuesGreaterThanOrEqualToExpectedValue(metricName, values, 0) {
return testResult
}

testResult.Status = status.SUCCESSFUL
return testResult
}
8 changes: 7 additions & 1 deletion test/metric_value_benchmark/metrics_value_benchmark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ func getEc2TestRunners(env *environment.MetaData) []*test_runner.TestRunner {
{TestRunner: &ProcessesTestRunner{test_runner.BaseTestRunner{DimensionFactory: factory}}},
{TestRunner: &CollectDTestRunner{test_runner.BaseTestRunner{DimensionFactory: factory}}},
{TestRunner: &RenameSSMTestRunner{test_runner.BaseTestRunner{DimensionFactory: factory}}},
{TestRunner: &JMXTestRunner{test_runner.BaseTestRunner{DimensionFactory: factory}}},
}
}
return ec2TestRunners
Expand Down Expand Up @@ -157,5 +158,10 @@ func shouldRunEC2Test(env *environment.MetaData, t *test_runner.TestRunner) bool
}
_, shouldRun := env.EC2PluginTests[strings.ToLower(t.TestRunner.GetTestName())]
_, shouldExclude := env.ExcludedTests[strings.ToLower(t.TestRunner.GetTestName())]
return shouldRun || !shouldExclude
if shouldRun {
return true
} else if len(env.ExcludedTests) != 0 {
return !shouldExclude
}
return false
}

0 comments on commit d1fe328

Please sign in to comment.