Skip to main content

CloudWatch Logging Guide

  • This guide covers CloudWatch-specific implementation details for viewing and querying DynamoAI logs
  • Applicable to: SaaS deployments (where logs are automatically exported to CloudWatch) or PaaS deployments using CloudWatch as the logging backend

CloudWatch Terminologies​

Before exploring logs in CloudWatch, it's helpful to understand these key concepts:

TerminologyDescription
CloudWatch Log GroupLog groups define groups of log streams that share the same retention and monitoring settings. All DynamoAI application logs are stored in a single log group per cluster.
CloudWatch Log StreamA log stream represents the sequence of events coming from a specific application instance or resource (e.g., a Kubernetes pod). Each pod gets its own log stream.

Log Group and Stream Mapping​

DynamoAI logs are organized in CloudWatch using the following structure:

Log Group Naming Convention​

All application logs are stored in a single log group per cluster:

/aws/containerinsights/${CLUSTER_NAME}/application

Where:

  • ${CLUSTER_NAME} is your Kubernetes cluster name (e.g., dfl-prod-default-eks)

Example: /aws/containerinsights/dfl-prod-default-eks/application

Note: All components (API, MongoDB, DynamoEval jobs, etc.) share the same log group regardless of namespace.

Log Stream Naming Convention​

Log streams follow this pattern:

${POD_NAME}.${CONTAINER_NAME}

Where:

  • ${POD_NAME} is the Kubernetes pod identifier (e.g., dynamoai-api-56fcf74495-rf2pj)
  • ${CONTAINER_NAME} is the container name (e.g., dynamoai-api, mongodb, db-migrations-job)

Component Log Stream Examples​

ComponentLog Stream Example
APIdynamoai-api-56fcf74495-rf2pj.dynamoai-api
DB Migrations Jobdb-migrations-job-vz564.db-migrations-job
Moderation Serverdynamoai-moderation-5bdc4cb97d-45wgd.dynamoai-moderation
MongoDBdynamoai-mongodb-1.mongodb
DynamoEval Attackscaled-job-cpu-1-2-t86sv-scszp.redis-client
Test Report Generationtestreportgeneration-cpu-1-rf8vz-xcsd4.redis-client
Mini Fine Tune Jobmini-finetune-l4-1-kr6wc-xnc5p.redis-client

Note: A new log stream is created whenever a new pod is created. When a pod is terminated, its log stream remains in CloudWatch (subject to retention policies).

Viewing Logs: Two Approaches​

Approach 1: CloudWatch Log Streams (Direct Viewing)​

Best for: Quickly viewing logs from a specific pod/component, general log browsing

Steps:

  1. Go to AWS CloudWatch Console - Log Groups
  2. Select the log group: /aws/containerinsights/${CLUSTER_NAME}/application (replace ${CLUSTER_NAME} with your cluster name, e.g., dfl-prod-default-eks)
  3. Click on the log stream you want to view (e.g., dynamoai-api-56fcf74495-rf2pj.dynamoai-api)

Log Group View

Log Stream View

Approach 2: CloudWatch Insights (Query-Based)​

Best for: Filtering logs by structured attributes, searching across multiple streams, complex queries

CloudWatch Insights allows you to query logs using a SQL-like syntax, making it ideal for filtering by structured logging attributes.

Access: AWS CloudWatch Insights

CloudWatch Insights Queries​

DynamoEval: Attack Logs​

View all logs for a specific DynamoEval attack. This query filters to log streams that follow the attack naming convention (starting with scaled-job).

Query:

filter @logStream like /scaled-job*/ 
| filter log_processed.attack_id="691bc0098fec174bf9ca81ad"
| fields @timestamp, log_processed.logger, log_processed.level, log_processed.event
| sort @timestamp asc
| limit 1000

Steps:

  1. Select the log group: /aws/containerinsights/${CLUSTER_NAME}/application (replace ${CLUSTER_NAME} with your cluster name, e.g., dfl-prod-default-eks)
  2. Select the time range for when the attack was executed
  3. Replace 691bc0098fec174bf9ca81ad with your actual attack ID
  4. Run the query

AWS Cloudwatch Insights

DynamoEval: Test Report Generation Logs​

View all logs for a specific test report generation job. This query filters to log streams that follow the test report generation naming convention (starting with testreportgeneration).

Query:

filter @logStream like 'testreportgeneration%' 
| filter log_processed.product="dynamoeval"
| filter log_processed.component="test-report-generation"
| filter log_processed.test_id="584d3a37a75f463c4a4c0397"
| fields @timestamp, @logStream, log_processed.logger, log_processed.event
| sort @timestamp asc

Steps:

  1. Select the log group: /aws/containerinsights/${CLUSTER_NAME}/application (replace ${CLUSTER_NAME} with your cluster name, e.g., dfl-prod-default-eks)
  2. Select the time range for when the test report generation was executed
  3. Replace 584d3a37a75f463c4a4c0397 with your actual test ID
  4. Run the query

API: View Logs for a Specific Request​

Trace all logs related to a specific API request using the request ID. This query searches across all API pods.

Query:

filter @logStream like /dynamoai-api-.*/ 
| filter log_processed.metadata.reqId = '19e555d0-b349-11f0-9ee0-09606a1108f9'
| fields @timestamp, log_processed.message
| sort @timestamp asc
| limit 1000

Steps:

  1. Select the log group: /aws/containerinsights/${CLUSTER_NAME}/application (replace ${CLUSTER_NAME} with your cluster name)
  2. Replace 19e555d0-b349-11f0-9ee0-09606a1108f9 with your request ID (found in the X-Request-Id response header)
  3. Run the query

Screenshot

API: View Error Logs​

Find all error-level logs from all API pods.

Query:

filter @logStream like /dynamoai-api-.*/ 
| filter log_processed.level = 'error'
| fields @timestamp, log_processed.message
| sort @timestamp asc
| limit 1000

Steps:

  1. Select the log group: /aws/containerinsights/${CLUSTER_NAME}/application (replace ${CLUSTER_NAME} with your cluster name)
  2. Adjust the time range as needed
  3. Run the query

API: View Request Entry Points for a Specific Route​

View the history of requests made to a specific API route across all API pods, including request IDs for further investigation.

Query:

filter @logStream like /dynamoai-api-.*/ 
| filter log_processed.metadata.url = '/v1/ml-model'
| fields @timestamp, log_processed.metadata.method, log_processed.metadata.url, log_processed.metadata.reqId
| sort @timestamp asc
| limit 1000

Steps:

  1. Select the log group: /aws/containerinsights/${CLUSTER_NAME}/application (replace ${CLUSTER_NAME} with your cluster name)
  2. Replace /v1/ml-model with the API route you want to investigate
  3. Run the query

Screenshot

DynamoGuard: Trace Analyze Request Across Components​

Trace all logs for a single DynamoGuard analyze request from API through Moderation Server to Models.

Step 1: Get the API Request ID

  • The API request ID is returned in the response header as X-Request-Id
  • Or find it in API logs using the API request query above

Step 2: View API Logs for the Analyze Request

filter @logStream like /dynamoai-api-.*/ 
| filter log_processed.metadata.reqId = '19e555d0-b349-11f0-9ee0-09606a1108f9'
| fields @timestamp, log_processed.message
| sort @timestamp asc
| limit 1000

Step 3: View Moderation Server Logs for the Same Request

filter @logStream like /dynamoai-moderation-.*/ 
| filter trace_id = '19e555d0-b349-11f0-9ee0-09606a1108f9'
| fields @timestamp, trace_id, request_id, log_processed.message
| sort @timestamp asc
| limit 1000

Step 4: View Model Logs for the Same Request

filter @logStream like /model-.*/ 
| filter request_id = '19e555d0-b349-11f0-9ee0-09606a1108f9'
| fields @timestamp, request_id, log_processed.message
| sort @timestamp asc
| limit 1000

Steps:

  1. Select the log group: /aws/containerinsights/${CLUSTER_NAME}/application (replace ${CLUSTER_NAME} with your cluster name)
  2. Replace 19e555d0-b349-11f0-9ee0-09606a1108f9 with your API request ID (from X-Request-Id header)
  3. Run all three queries to see the complete flow from API → Moderation Server → Models
  4. Note: A single API analyze request may result in multiple Moderation Server calls, each with a different request_id (worker_request_id) but the same trace_id
  5. The same request ID value (log_processed.metadata.reqId in API = trace_id in Moderation Server = request_id in Models) allows you to trace the entire request flow

Tips for CloudWatch Log Exploration​

  1. Finding the Right Log Stream: Use the component identification patterns from the Generic Component Logs guide to identify which log stream to query. Log streams follow the pattern ${POD_NAME}.${CONTAINER_NAME}
  2. Time Ranges: CloudWatch Insights queries are more efficient with narrower time ranges. Start with a specific time window and expand if needed
  3. Request ID Tracing: The API request ID (X-Request-Id header) is your best friend for tracing a request through all related logs. For DynamoGuard analyze requests, use the API request ID as trace_id in Moderation Server logs to trace the complete flow
  4. Multiple Streams: The API queries in this guide use @logStream like /dynamoai-api-.*/ to search across all API pods. You can use similar regex patterns for other components (e.g., @logStream like /mongodb-.*/ for MongoDB)
  5. Single Log Group: All application logs are in one log group (/aws/containerinsights/${CLUSTER_NAME}/application), making it easy to search across all components
  6. Saving Queries: CloudWatch Insights allows you to save frequently used queries for quick access