<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Anjali Damani</title>
    <description>The latest articles on DEV Community by Anjali Damani (@anjali_07).</description>
    <link>https://dev.to/anjali_07</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3907438%2Fbb2852d2-81a1-4108-b0f7-bebfa8a919a6.png</url>
      <title>DEV Community: Anjali Damani</title>
      <link>https://dev.to/anjali_07</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/anjali_07"/>
    <language>en</language>
    <item>
      <title>Spring Boot App Is Running, but CloudWatch Shows No Custom Metrics. Here's How to Debug It.</title>
      <dc:creator>Anjali Damani</dc:creator>
      <pubDate>Sun, 01 Nov 2026 10:25:56 +0000</pubDate>
      <link>https://dev.to/anjali_07/spring-boot-app-is-running-but-cloudwatch-shows-no-custom-metrics-heres-how-to-debug-it-22ji</link>
      <guid>https://dev.to/anjali_07/spring-boot-app-is-running-but-cloudwatch-shows-no-custom-metrics-heres-how-to-debug-it-22ji</guid>
      <description>&lt;p&gt;Your Spring Boot application is running on Amazon ECS. API requests are succeeding, business operations are executing, and the application logs look normal.&lt;/p&gt;

&lt;p&gt;But when you open Amazon CloudWatch, the custom metrics you expected to see are missing.&lt;/p&gt;

&lt;p&gt;You check the dashboard. No data.&lt;/p&gt;

&lt;p&gt;You check the metric namespace. Nothing appears.&lt;/p&gt;

&lt;p&gt;You wait a few minutes and refresh. Still nothing.&lt;/p&gt;

&lt;p&gt;Where should you start debugging?&lt;/p&gt;

&lt;p&gt;The problem could be in the application, Micrometer configuration, metric publishing, AWS permissions, network connectivity, or the way you are querying CloudWatch.&lt;/p&gt;

&lt;p&gt;In this article, we'll build a small example and follow the complete path from recording a metric in Spring Boot to verifying it in CloudWatch.&lt;/p&gt;

&lt;p&gt;By the end, you'll have a systematic troubleshooting process you can reuse in your own applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Understand the complete metrics flow
&lt;/h2&gt;

&lt;p&gt;Before changing any configuration, understand how a custom application metric reaches CloudWatch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Spring Boot Application
        |
        v
Business Operation
        |
        v
Micrometer Counter / Timer
        |
        v
MeterRegistry
        |
        v
CloudWatch Registry
        |
        v
CloudWatch PutMetricData API
        |
        v
Amazon CloudWatch Metrics
        |
        +------&amp;gt; Dashboard
        |
        +------&amp;gt; Alarm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each component has a different responsibility.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Business operation:&lt;/strong&gt; The event you want to measure, such as a successfully created order.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Micrometer:&lt;/strong&gt; Provides a consistent API for recording application metrics.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MeterRegistry:&lt;/strong&gt; Holds and manages the meters registered by your application.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CloudWatch registry:&lt;/strong&gt; Exports supported Micrometer measurements to AWS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CloudWatch:&lt;/strong&gt; Stores the published metric data and makes it available for querying, visualization, and alarms.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A metric being recorded in Java does not automatically mean it has been published to CloudWatch.&lt;/p&gt;

&lt;p&gt;Similarly, a metric existing in CloudWatch does not automatically mean your dashboard is configured to display it.&lt;/p&gt;

&lt;p&gt;This distinction is the foundation of the debugging process.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Understand SimpleMeterRegistry versus CloudWatchMeterRegistry
&lt;/h2&gt;

&lt;p&gt;One of the first things to investigate is the &lt;code&gt;MeterRegistry&lt;/code&gt; used by your application.&lt;/p&gt;

&lt;p&gt;Micrometer provides different registry implementations for different purposes.&lt;/p&gt;

&lt;h3&gt;
  
  
  SimpleMeterRegistry
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;SimpleMeterRegistry&lt;/code&gt; stores the latest values of meters in memory. It does not export those measurements to an external monitoring system.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;SimpleMeterRegistry&lt;/span&gt; &lt;span class="n"&gt;registry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SimpleMeterRegistry&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="nc"&gt;Counter&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Counter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"orders.created"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;register&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;increment&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The counter value increases locally, but this code does not send the metric to CloudWatch.&lt;/p&gt;

&lt;p&gt;This registry is useful for simple tests and local experimentation.&lt;/p&gt;

&lt;h3&gt;
  
  
  CloudWatchMeterRegistry
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;CloudWatchMeterRegistry&lt;/code&gt; is the Micrometer registry implementation for publishing supported metrics to Amazon CloudWatch.&lt;/p&gt;

&lt;p&gt;However, adding a dependency alone is not sufficient in every Spring application. You also need the appropriate registry configuration and AWS client credentials, permissions, and Region.&lt;/p&gt;

&lt;h3&gt;
  
  
  What happens in Spring Boot?
&lt;/h3&gt;

&lt;p&gt;Spring Boot Actuator integrates with Micrometer and can configure a composite registry containing the available registry implementations.&lt;/p&gt;

&lt;p&gt;When a CloudWatch-compatible registry is properly configured, metrics recorded through the injected &lt;code&gt;MeterRegistry&lt;/code&gt; can be exported through that registry.&lt;/p&gt;

&lt;p&gt;If your application is only recording to an in-memory registry, there is no CloudWatch publishing path.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Documentation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.micrometer.io/micrometer/reference/concepts/registry.html" rel="noopener noreferrer"&gt;Micrometer registry concepts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.spring.io/spring-boot/reference/actuator/metrics.html" rel="noopener noreferrer"&gt;Spring Boot Actuator metrics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.micrometer.io/micrometer/reference/implementations/cloudwatch.html" rel="noopener noreferrer"&gt;Micrometer CloudWatch integration&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Create a simple Spring Boot example
&lt;/h2&gt;

&lt;p&gt;Let's create a small example that records a custom metric whenever a demo order operation succeeds.&lt;/p&gt;

&lt;p&gt;The example deliberately avoids a database so that we can isolate metric recording and publishing from business logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Record the metric
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.micrometer.core.instrument.Counter&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.micrometer.core.instrument.MeterRegistry&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.stereotype.Service&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Service&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Counter&lt;/span&gt; &lt;span class="n"&gt;ordersCreated&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;OrderService&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MeterRegistry&lt;/span&gt; &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ordersCreated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Counter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"orders.created"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Number of successful demo order operations"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;register&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;createOrder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="c1"&gt;// Replace this with the actual business operation.&lt;/span&gt;

        &lt;span class="n"&gt;ordersCreated&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;increment&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we register a counter named &lt;code&gt;orders.created&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Every time &lt;code&gt;createOrder()&lt;/code&gt; completes its intended operation, the counter increments.&lt;/p&gt;

&lt;p&gt;In a real application, the metric should reflect a clearly defined business event. If the operation involves a database transaction, be careful not to count an order as successfully committed before the transaction actually commits.&lt;/p&gt;

&lt;h3&gt;
  
  
  Expose a demo endpoint
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.bind.annotation.PostMapping&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.bind.annotation.RestController&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@RestController&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;OrderService&lt;/span&gt; &lt;span class="n"&gt;orderService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;OrderController&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;OrderService&lt;/span&gt; &lt;span class="n"&gt;orderService&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orderService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;orderService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@PostMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/orders/demo"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;createOrder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;orderService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createOrder&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Demo order operation completed"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After starting the application, send a POST request to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /orders/demo
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, using curl:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:8080/orders/demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each successful request invokes the service and increments the counter.&lt;/p&gt;

&lt;p&gt;At this point, we have demonstrated metric recording. We have not yet proved that the metric reaches CloudWatch.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Configure CloudWatch publishing
&lt;/h2&gt;

&lt;p&gt;For this example, assume you're using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Java and Spring Boot 3.x.&lt;/li&gt;
&lt;li&gt;A compatible Spring Cloud AWS 3.x release.&lt;/li&gt;
&lt;li&gt;Micrometer's CloudWatch registry.&lt;/li&gt;
&lt;li&gt;AWS SDK for Java 2.x through the supported integration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use compatible dependency versions and the Spring Cloud AWS Bill of Materials (BOM). Do not mix incompatible major versions just to make the dependencies resolve.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add the dependencies
&lt;/h3&gt;

&lt;p&gt;For Maven, the relevant dependencies include the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-actuator&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.awspring.cloud&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-cloud-aws-starter&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.micrometer&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;micrometer-registry-cloudwatch2&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Import the compatible Spring Cloud AWS BOM in &lt;code&gt;dependencyManagement&lt;/code&gt; and use Spring Boot's dependency management for the versions they manage.&lt;/p&gt;

&lt;p&gt;For example, the Spring Cloud AWS BOM has this structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependencyManagement&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.awspring.cloud&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-cloud-aws-dependencies&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;${spring-cloud-aws.version}&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;type&amp;gt;&lt;/span&gt;pom&lt;span class="nt"&gt;&amp;lt;/type&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;import&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependencyManagement&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Define &lt;code&gt;spring-cloud-aws.version&lt;/code&gt; as a release compatible with your Spring Boot version. The placeholder above is intentional; select the version using the official compatibility guidance.&lt;/p&gt;

&lt;p&gt;Spring Cloud AWS provides the Spring Boot auto-configuration for the Micrometer CloudWatch integration.&lt;/p&gt;

&lt;p&gt;References:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.awspring.io/spring-cloud-aws/docs/current/reference/html/index.html" rel="noopener noreferrer"&gt;Spring Cloud AWS documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.micrometer.io/micrometer/reference/implementations/cloudwatch.html" rel="noopener noreferrer"&gt;Micrometer CloudWatch dependency and configuration&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configure application.yml
&lt;/h3&gt;

&lt;p&gt;For Spring Cloud AWS 3.x, a configuration example is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;spring&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;cloud&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;aws&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;cloudwatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
        &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;us-east-1&lt;/span&gt;

&lt;span class="na"&gt;management&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;cloudwatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metrics&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;export&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Demo/OrderService&lt;/span&gt;
        &lt;span class="na"&gt;step&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1m&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;us-east-1&lt;/code&gt; with your AWS Region.&lt;/p&gt;

&lt;p&gt;The namespace &lt;code&gt;Demo/OrderService&lt;/code&gt; is an example. Choose a namespace that identifies your application or service.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;step: 1m&lt;/code&gt; setting configures the publishing interval to one minute. Allow additional time for the data to become available after publishing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; Spring Cloud AWS 3.x uses &lt;code&gt;management.cloudwatch.metrics.export.*&lt;/code&gt; properties. Older Spring Cloud AWS versions use different property names. If you're using a different release family, consult the documentation for that exact version instead of copying this configuration unchanged.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Verify that the application records the metric
&lt;/h2&gt;

&lt;p&gt;Before investigating AWS, verify that the application actually records the metric.&lt;/p&gt;

&lt;p&gt;Spring Boot Actuator provides a metrics endpoint that can help with this check.&lt;/p&gt;

&lt;p&gt;For local debugging, you can expose the health and metrics endpoints in &lt;code&gt;application.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;management&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;endpoints&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;web&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;exposure&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;health,metrics&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your configuration already contains a &lt;code&gt;management&lt;/code&gt; section, merge the settings rather than replacing unrelated properties.&lt;/p&gt;

&lt;p&gt;Restart the application and invoke the demo endpoint several times.&lt;/p&gt;

&lt;p&gt;Then query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:8080/actuator/metrics/orders.created
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response should contain information about the registered meter and its measurements. After invoking the endpoint multiple times, check the counter's current value.&lt;/p&gt;

&lt;p&gt;If the metric is missing from Actuator, investigate the application first:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the relevant service method actually being called?&lt;/li&gt;
&lt;li&gt;Is the counter registered under the name you expect?&lt;/li&gt;
&lt;li&gt;Is the application using the &lt;code&gt;MeterRegistry&lt;/code&gt; injected by Spring?&lt;/li&gt;
&lt;li&gt;Is a different registry or metric filter involved?&lt;/li&gt;
&lt;li&gt;Did the application start with the expected configuration?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the metric is visible through Actuator, you've established that the application can record it locally. You still need to verify external publishing separately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security note:&lt;/strong&gt; Do not expose Actuator metrics publicly without appropriate access controls. Keep diagnostic endpoints internal or restrict them to authorized users.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Check AWS credentials and IAM permissions
&lt;/h2&gt;

&lt;p&gt;A CloudWatch registry needs AWS credentials with permission to publish metric data.&lt;/p&gt;

&lt;p&gt;When the application runs on Amazon ECS, distinguish between the two IAM roles.&lt;/p&gt;

&lt;h3&gt;
  
  
  ECS task role
&lt;/h3&gt;

&lt;p&gt;The task role supplies AWS permissions to application code running inside the task.&lt;/p&gt;

&lt;p&gt;For direct CloudWatch metric publishing by the application, this is generally the role that needs the &lt;code&gt;cloudwatch:PutMetricData&lt;/code&gt; permission.&lt;/p&gt;

&lt;h3&gt;
  
  
  ECS task execution role
&lt;/h3&gt;

&lt;p&gt;The execution role is used by the ECS agent for tasks such as pulling container images from Amazon ECR and sending container logs through configured logging integrations.&lt;/p&gt;

&lt;p&gt;It is not automatically the identity used by your application for CloudWatch metric publishing.&lt;/p&gt;

&lt;p&gt;Granting a permission to the execution role will not fix missing application metrics if the application is using the task role instead.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example IAM policy
&lt;/h3&gt;

&lt;p&gt;For a dedicated custom namespace, a policy can be restricted using CloudWatch's namespace condition key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cloudwatch:PutMetricData"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Condition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"StringEquals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"cloudwatch:namespace"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Demo/OrderService"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is an example policy for the namespace used in this tutorial. Adjust it to your requirements and verify any additional organizational policies.&lt;/p&gt;

&lt;p&gt;CloudWatch metric publishing does not support resource-level restriction in the usual way, so &lt;code&gt;Resource: "*"&lt;/code&gt; is used here with a namespace condition.&lt;/p&gt;

&lt;p&gt;Avoid hardcoding AWS access keys in source code, container images, or configuration files. Use the ECS task role and the AWS SDK's supported credential provider chain.&lt;/p&gt;

&lt;p&gt;If you receive an authorization error, check:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Which IAM role the task is actually using.&lt;/li&gt;
&lt;li&gt;Whether that role has &lt;code&gt;cloudwatch:PutMetricData&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Whether a namespace condition matches the configured namespace.&lt;/li&gt;
&lt;li&gt;Whether an AWS Organizations service control policy, permissions boundary, or other policy denies the request.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Reference: &lt;a href="https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html" rel="noopener noreferrer"&gt;IAM roles for Amazon ECS tasks&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Check network connectivity from ECS
&lt;/h2&gt;

&lt;p&gt;Correct IAM permissions are not enough if the application cannot reach the CloudWatch API.&lt;/p&gt;

&lt;p&gt;This matters especially when an ECS task runs in a private subnet.&lt;/p&gt;

&lt;p&gt;Check whether the task has a supported network path to the CloudWatch monitoring API. Depending on your architecture, this might be through a NAT gateway or an appropriate VPC interface endpoint.&lt;/p&gt;

&lt;p&gt;Also verify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DNS resolution.&lt;/li&gt;
&lt;li&gt;Security group egress rules.&lt;/li&gt;
&lt;li&gt;Network ACL rules.&lt;/li&gt;
&lt;li&gt;VPC endpoint configuration and policies, if applicable.&lt;/li&gt;
&lt;li&gt;Application logs for connection timeouts or endpoint errors.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do not assume that access to CloudWatch Logs proves that access to the CloudWatch metrics API is working. They are different API endpoints and may have different network paths and permissions.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Check the CloudWatch Region and namespace
&lt;/h2&gt;

&lt;p&gt;Suppose your application publishes to &lt;code&gt;us-east-1&lt;/code&gt;, but you're viewing CloudWatch in &lt;code&gt;eu-west-1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The metric will not appear in the Region you're viewing.&lt;/p&gt;

&lt;p&gt;Verify the following values:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;What to verify&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;AWS Region&lt;/td&gt;
&lt;td&gt;The Region configured for the CloudWatch client&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Console Region&lt;/td&gt;
&lt;td&gt;The Region selected in the CloudWatch console&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Namespace&lt;/td&gt;
&lt;td&gt;The configured custom namespace&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Metric name&lt;/td&gt;
&lt;td&gt;The name registered and exported by the application&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dimensions&lt;/td&gt;
&lt;td&gt;The dimension names and values associated with the published series&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Custom metrics are identified by their namespace, metric name, and dimensions.&lt;/p&gt;

&lt;p&gt;For example, a metric with &lt;code&gt;Environment=dev&lt;/code&gt; is a different time series from one with &lt;code&gt;Environment=prod&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you add dimensions through registry configuration, filters, or instrumentation, use the correct dimension combination when querying the metric.&lt;/p&gt;

&lt;p&gt;Avoid high-cardinality dimensions such as user IDs, order IDs, request IDs, or arbitrary URLs. Every unique combination can create additional metric series and increase monitoring costs.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Verify that CloudWatch has received the metric
&lt;/h2&gt;

&lt;p&gt;Once the application has recorded the metric and the registry has had time to publish it, query CloudWatch directly.&lt;/p&gt;

&lt;p&gt;You can use the AWS CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws cloudwatch list-metrics &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--namespace&lt;/span&gt; &lt;span class="s2"&gt;"Demo/OrderService"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--metric-name&lt;/span&gt; &lt;span class="s2"&gt;"orders.created"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the namespace, metric name, and Region with your actual values.&lt;/p&gt;

&lt;p&gt;This command helps determine whether CloudWatch lists the metric.&lt;/p&gt;

&lt;h3&gt;
  
  
  What if the command returns no results?
&lt;/h3&gt;

&lt;p&gt;Do not immediately conclude that publishing failed.&lt;/p&gt;

&lt;p&gt;AWS documents that a newly created metric can take up to 15 minutes to appear through &lt;code&gt;ListMetrics&lt;/code&gt;. Statistics may be queryable sooner using &lt;code&gt;GetMetricData&lt;/code&gt; or &lt;code&gt;GetMetricStatistics&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Also note that &lt;code&gt;ListMetrics&lt;/code&gt; does not return metrics that have not reported data in the past two weeks.&lt;/p&gt;

&lt;p&gt;Therefore, check the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Did the publishing interval elapse?&lt;/li&gt;
&lt;li&gt;Did the application log any publishing errors?&lt;/li&gt;
&lt;li&gt;Are the namespace and Region correct?&lt;/li&gt;
&lt;li&gt;Is the metric name correct?&lt;/li&gt;
&lt;li&gt;Are you querying from the correct AWS account?&lt;/li&gt;
&lt;li&gt;Does the metric have dimensions that you haven't accounted for?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also inspect metric statistics with a command such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws cloudwatch get-metric-statistics &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--namespace&lt;/span&gt; &lt;span class="s2"&gt;"Demo/OrderService"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--metric-name&lt;/span&gt; &lt;span class="s2"&gt;"orders.created"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--start-time&lt;/span&gt; 2026-11-01T00:00:00Z &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--end-time&lt;/span&gt; 2026-11-01T01:00:00Z &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--period&lt;/span&gt; 60 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--statistics&lt;/span&gt; Sum &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; The dates above are illustrative. Replace them with a UTC time window that covers your actual test. If your metric has dimensions, include the exact dimension combination in the query.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Sum&lt;/code&gt; statistic is appropriate only when it matches the meaning of the published datapoints. For counters exported by a registry, inspect the registry's publishing semantics and actual CloudWatch datapoints rather than assuming that summing cumulative values always gives the number of events.&lt;/p&gt;

&lt;p&gt;References:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_ListMetrics.html" rel="noopener noreferrer"&gt;CloudWatch ListMetrics API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_GetMetricStatistics.html" rel="noopener noreferrer"&gt;CloudWatch GetMetricStatistics API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  10. The metric exists, but the dashboard still shows no data
&lt;/h2&gt;

&lt;p&gt;A CloudWatch dashboard visualizes the metric series selected in its widget. It does not create the metric itself.&lt;/p&gt;

&lt;p&gt;If the metric can be queried but the dashboard is blank, inspect the dashboard configuration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check the selected metric
&lt;/h3&gt;

&lt;p&gt;Verify that the widget points to the correct:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Namespace.&lt;/li&gt;
&lt;li&gt;Metric name.&lt;/li&gt;
&lt;li&gt;Dimension combination.&lt;/li&gt;
&lt;li&gt;Region.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Check the time range
&lt;/h3&gt;

&lt;p&gt;The dashboard might be displaying a time range that does not contain your test requests.&lt;/p&gt;

&lt;p&gt;Choose a range that includes the time when you invoked the demo endpoint and when the registry published its data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check the period and statistic
&lt;/h3&gt;

&lt;p&gt;The metric's publishing interval and the widget's aggregation period are related but are not necessarily the same setting.&lt;/p&gt;

&lt;p&gt;Select a period that makes sense for the metric's publishing frequency and the time range being displayed.&lt;/p&gt;

&lt;p&gt;For event counters, use a statistic that correctly represents the published values. For latency measurements, choose a statistic appropriate for the question you're trying to answer, such as average or a supported percentile.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check dimensions
&lt;/h3&gt;

&lt;p&gt;If the metric has dimensions, the dashboard must query the correct series. A mismatch in dimension values can make a valid metric appear to be missing.&lt;/p&gt;

&lt;p&gt;The quickest diagnostic sequence is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Confirm that the metric is visible through Actuator.&lt;/li&gt;
&lt;li&gt;Confirm that CloudWatch has received it.&lt;/li&gt;
&lt;li&gt;Query the metric's data.&lt;/li&gt;
&lt;li&gt;Only then troubleshoot the dashboard widget.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This separates metric collection problems from visualization problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. What about CloudWatch alarms?
&lt;/h2&gt;

&lt;p&gt;After confirming that a metric is published correctly, you can create an alarm to monitor it.&lt;/p&gt;

&lt;p&gt;However, a valid metric does not guarantee that an alarm will transition to &lt;code&gt;ALARM&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Check the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The alarm references the correct namespace, metric name, and dimensions.&lt;/li&gt;
&lt;li&gt;The statistic matches the meaning of the published measurements.&lt;/li&gt;
&lt;li&gt;The threshold and comparison operator are correct.&lt;/li&gt;
&lt;li&gt;The period and evaluation periods match the intended detection behavior.&lt;/li&gt;
&lt;li&gt;Missing-data treatment is appropriate for the metric.&lt;/li&gt;
&lt;li&gt;The alarm has enough data to evaluate its condition.&lt;/li&gt;
&lt;li&gt;Any notification action is configured and enabled.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, a counter that records failed business operations can be useful for monitoring errors. But the alarm threshold should reflect the expected volume and the way the metric is aggregated.&lt;/p&gt;

&lt;p&gt;An alarm in &lt;code&gt;INSUFFICIENT_DATA&lt;/code&gt; may not have enough datapoints to evaluate its condition. Missing data should not automatically be interpreted as evidence that the application is healthy.&lt;/p&gt;

&lt;p&gt;For a low-traffic application, the absence of events can be normal. For a continuously running service, the absence of expected telemetry may itself warrant investigation.&lt;/p&gt;

&lt;h2&gt;
  
  
  12. Common symptoms and their likely causes
&lt;/h2&gt;

&lt;p&gt;Use this table as a quick reference when debugging a real service.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;What to investigate first&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Application starts, but no custom metrics appear&lt;/td&gt;
&lt;td&gt;Registry dependency, initialization, and publishing configuration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Actuator shows the metric, but CloudWatch does not&lt;/td&gt;
&lt;td&gt;CloudWatch registry, publishing errors, IAM, Region, and network connectivity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Publishing fails with an authorization error&lt;/td&gt;
&lt;td&gt;ECS task role, &lt;code&gt;cloudwatch:PutMetricData&lt;/code&gt;, and applicable policy conditions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Publishing times out&lt;/td&gt;
&lt;td&gt;Network path, DNS, VPC endpoint, or egress configuration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Metrics appear in another Region&lt;/td&gt;
&lt;td&gt;Registry Region versus console Region&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Some metric series appear, but others do not&lt;/td&gt;
&lt;td&gt;Registration, metric filters, dimensions, and publishing errors&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CloudWatch has data, but the dashboard is blank&lt;/td&gt;
&lt;td&gt;Widget configuration, time range, Region, dimensions, and statistic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alarm remains in &lt;code&gt;INSUFFICIENT_DATA&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Evaluation period, missing data, and available datapoints&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Metric is missing from &lt;code&gt;ListMetrics&lt;/code&gt; immediately after publishing&lt;/td&gt;
&lt;td&gt;Allow for metric discovery delay and query statistics separately&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  13. A repeatable debugging checklist
&lt;/h2&gt;

&lt;p&gt;When custom metrics are missing from CloudWatch, follow this order instead of changing several configurations at once.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Reproduce the problem:&lt;/strong&gt; Invoke the operation that should generate the metric.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify application recording:&lt;/strong&gt; Use Actuator or a test to confirm that the meter exists and changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify registry configuration:&lt;/strong&gt; Confirm that a CloudWatch-compatible registry is configured and active.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inspect publishing errors:&lt;/strong&gt; Check the application logs for AWS API, credentials, or configuration errors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify the ECS task role:&lt;/strong&gt; Confirm the identity and permissions used by the application.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check network connectivity:&lt;/strong&gt; Ensure the task can reach the CloudWatch monitoring API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify Region and namespace:&lt;/strong&gt; Compare the application configuration with the CloudWatch console.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wait for publishing and ingestion:&lt;/strong&gt; Account for the registry step and CloudWatch visibility delay.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Query the metric directly:&lt;/strong&gt; Use the console or AWS CLI to verify that data exists.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Troubleshoot the dashboard:&lt;/strong&gt; Check dimensions, time range, period, and statistic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validate the alarm:&lt;/strong&gt; Confirm the threshold, evaluation periods, missing-data behavior, and notification actions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This sequence helps isolate the failure at the correct layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;A Spring Boot application can run successfully while its custom metrics remain unavailable in CloudWatch.&lt;/p&gt;

&lt;p&gt;The important thing is to distinguish between recording a metric, publishing it to AWS, querying the resulting data, and displaying it on a dashboard.&lt;/p&gt;

&lt;p&gt;Once you understand these stages, troubleshooting becomes a systematic process rather than trial and error.&lt;/p&gt;

&lt;p&gt;Start with the application and its active registry. Then verify the publishing configuration, AWS permissions, and network path. Confirm the metric exists in CloudWatch before investigating dashboards and alarms.&lt;/p&gt;

&lt;p&gt;That approach is useful not only for Spring Boot applications running on ECS, but also for other Java services that publish custom metrics to CloudWatch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Official references
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.micrometer.io/micrometer/reference/concepts/registry.html" rel="noopener noreferrer"&gt;Micrometer registry concepts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.spring.io/spring-boot/reference/actuator/metrics.html" rel="noopener noreferrer"&gt;Spring Boot Actuator metrics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.micrometer.io/micrometer/reference/implementations/cloudwatch.html" rel="noopener noreferrer"&gt;Micrometer CloudWatch integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.awspring.io/spring-cloud-aws/docs/current/reference/html/index.html" rel="noopener noreferrer"&gt;Spring Cloud AWS documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html" rel="noopener noreferrer"&gt;ECS task IAM roles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_ListMetrics.html" rel="noopener noreferrer"&gt;CloudWatch ListMetrics API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_GetMetricStatistics.html" rel="noopener noreferrer"&gt;CloudWatch GetMetricStatistics API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Have you encountered a situation where your Spring Boot application was healthy but its CloudWatch metrics were missing? What was the root cause? Share your experience in the comments.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>springboot</category>
      <category>aws</category>
      <category>cloudwatch</category>
    </item>
  </channel>
</rss>
