awslabs.cloudwatch-applicationsignals-mcp-server 0.1.21__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- awslabs/__init__.py +17 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/__init__.py +17 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/audit_presentation_utils.py +288 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/audit_utils.py +912 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/aws_clients.py +120 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/canary_utils.py +910 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/ec2/ec2-dotnet-enablement.md +435 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/ec2/ec2-java-enablement.md +321 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/ec2/ec2-nodejs-enablement.md +420 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/ec2/ec2-python-enablement.md +598 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/ecs/ecs-dotnet-enablement.md +264 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/ecs/ecs-java-enablement.md +193 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/ecs/ecs-nodejs-enablement.md +198 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/ecs/ecs-python-enablement.md +236 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/eks/eks-dotnet-enablement.md +166 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/eks/eks-java-enablement.md +166 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/eks/eks-nodejs-enablement.md +166 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/eks/eks-python-enablement.md +169 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/lambda/lambda-dotnet-enablement.md +336 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/lambda/lambda-java-enablement.md +336 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/lambda/lambda-nodejs-enablement.md +336 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/lambda/lambda-python-enablement.md +336 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_tools.py +147 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/server.py +1505 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/service_audit_utils.py +231 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/service_tools.py +659 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/sli_report_client.py +333 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/slo_tools.py +386 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/trace_tools.py +784 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/utils.py +172 -0
- awslabs_cloudwatch_applicationsignals_mcp_server-0.1.21.dist-info/METADATA +808 -0
- awslabs_cloudwatch_applicationsignals_mcp_server-0.1.21.dist-info/RECORD +36 -0
- awslabs_cloudwatch_applicationsignals_mcp_server-0.1.21.dist-info/WHEEL +4 -0
- awslabs_cloudwatch_applicationsignals_mcp_server-0.1.21.dist-info/entry_points.txt +2 -0
- awslabs_cloudwatch_applicationsignals_mcp_server-0.1.21.dist-info/licenses/LICENSE +174 -0
- awslabs_cloudwatch_applicationsignals_mcp_server-0.1.21.dist-info/licenses/NOTICE +2 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# Task: Enable AWS Application Signals for .NET on ECS
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
This guide provides complete steps to enable AWS Application Signals for ECS Fargate services, distributed tracing, performance monitoring, and service mapping.
|
|
5
|
+
|
|
6
|
+
## Prerequisites
|
|
7
|
+
- Services running on ECS both the ec2 and Fargate launch types.
|
|
8
|
+
- Applications using .NET language
|
|
9
|
+
|
|
10
|
+
## Implementation Steps
|
|
11
|
+
|
|
12
|
+
**Constraints:**
|
|
13
|
+
You must strictly follow the steps in the order below, do not skip or combine steps.
|
|
14
|
+
|
|
15
|
+
### Step 1: Setup CloudWatch Agent Task
|
|
16
|
+
When running in ECS, the CloudWatch Agent is deployed as a sidecar container next to the application container.
|
|
17
|
+
Proper permissions, a CWAgentConfig configuration file, and the target log group must be set up to enable logging and metrics collection.
|
|
18
|
+
|
|
19
|
+
#### 1.1 Add CloudWatch Agent Permissions to ECS Task Role
|
|
20
|
+
|
|
21
|
+
Update ECS task role to add CloudWatchAgentServerPolicy:
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
// Update existing taskRole or create new one
|
|
25
|
+
const taskRole = new iam.Role(this, 'EcsTaskRole', {
|
|
26
|
+
assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
|
|
27
|
+
managedPolicies: [
|
|
28
|
+
iam.ManagedPolicy.fromAwsManagedPolicyName('AWSXRayDaemonWriteAccess'),
|
|
29
|
+
iam.ManagedPolicy.fromAwsManagedPolicyName('CloudWatchAgentServerPolicy'),
|
|
30
|
+
],
|
|
31
|
+
inlinePolicies: {
|
|
32
|
+
// Your existing inline policies...
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
#### 1.2 Create CloudWatch Agent Log Group
|
|
38
|
+
```typescript
|
|
39
|
+
const cwAgentLogGroup = new logs.LogGroup(this, 'CwAgentLogGroup', {
|
|
40
|
+
logGroupName: '/ecs/ecs-cwagent',
|
|
41
|
+
removalPolicy: cdk.RemovalPolicy.DESTROY,
|
|
42
|
+
retention: logs.RetentionDays.ONE_WEEK,
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
#### 1.3 Add CloudWatch Agent Container to Each Task Definition
|
|
47
|
+
```typescript
|
|
48
|
+
// Add CloudWatch Agent sidecar to each task definition
|
|
49
|
+
const cwAgentContainer = taskDefinition.addContainer('ecs-cwagent-{SERVICE_NAME}', {
|
|
50
|
+
image: ecs.ContainerImage.fromRegistry('public.ecr.aws/cloudwatch-agent/cloudwatch-agent:latest'),
|
|
51
|
+
essential: false,
|
|
52
|
+
memoryReservationMiB: 128,
|
|
53
|
+
cpu: 64,
|
|
54
|
+
environment: {
|
|
55
|
+
CW_CONFIG_CONTENT: JSON.stringify({
|
|
56
|
+
"traces": {
|
|
57
|
+
"traces_collected": {
|
|
58
|
+
"application_signals": {}
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"logs": {
|
|
62
|
+
"metrics_collected": {
|
|
63
|
+
"application_signals": {}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}),
|
|
67
|
+
},
|
|
68
|
+
logging: ecs.LogDrivers.awsLogs({
|
|
69
|
+
streamPrefix: 'ecs',
|
|
70
|
+
logGroup: cwAgentLogGroup,
|
|
71
|
+
}),
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Step 2: Add AWS Distro for OpenTelemetry Zero-Code Instrumentation to Main Service
|
|
76
|
+
|
|
77
|
+
#### 2.1 Add Bind Mount Volumes to Task Definition
|
|
78
|
+
```typescript
|
|
79
|
+
const taskDefinition = new ecs.FargateTaskDefinition(this, '{SERVICE_NAME}TaskDefinition', {
|
|
80
|
+
// Existing configuration...
|
|
81
|
+
volumes: [
|
|
82
|
+
{
|
|
83
|
+
name: "opentelemetry-auto-instrumentation-dotnet"
|
|
84
|
+
}
|
|
85
|
+
],
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### 2.2 Add ADOT Auto-instrumentation Init Container
|
|
90
|
+
|
|
91
|
+
##### For Linux Containers:
|
|
92
|
+
```typescript
|
|
93
|
+
const initContainer = taskDefinition.addContainer('init', {
|
|
94
|
+
image: ecs.ContainerImage.fromRegistry('public.ecr.aws/aws-observability/adot-autoinstrumentation-dotnet:v1.9.2'),
|
|
95
|
+
essential: false,
|
|
96
|
+
memoryReservationMiB: 64,
|
|
97
|
+
cpu: 32,
|
|
98
|
+
command: ['cp', '-a', '/autoinstrumentation/.', '/otel-auto-instrumentation-dotnet'],
|
|
99
|
+
logging: ecs.LogDrivers.awsLogs({
|
|
100
|
+
streamPrefix: 'init-{SERVICE_NAME}',
|
|
101
|
+
logGroup: serviceLogGroup,
|
|
102
|
+
}),
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// Add mount point to init container
|
|
106
|
+
initContainer.addMountPoints({
|
|
107
|
+
sourceVolume: 'opentelemetry-auto-instrumentation-dotnet',
|
|
108
|
+
containerPath: '/otel-auto-instrumentation-dotnet',
|
|
109
|
+
readOnly: false,
|
|
110
|
+
});
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
##### For Windows Server Containers:
|
|
114
|
+
```typescript
|
|
115
|
+
const initContainer = taskDefinition.addContainer('init', {
|
|
116
|
+
image: ecs.ContainerImage.fromRegistry('public.ecr.aws/aws-observability/adot-autoinstrumentation-dotnet:v1.9.2'),
|
|
117
|
+
essential: false,
|
|
118
|
+
memoryReservationMiB: 64,
|
|
119
|
+
cpu: 32,
|
|
120
|
+
command: ['CMD', '/c', 'xcopy', '/e', 'C:\\autoinstrumentation\\*', 'C:\\otel-auto-instrumentation', '&&', 'icacls', 'C:\\otel-auto-instrumentation', '/grant', '*S-1-1-0:R', '/T'],
|
|
121
|
+
logging: ecs.LogDrivers.awsLogs({
|
|
122
|
+
streamPrefix: 'init-{SERVICE_NAME}',
|
|
123
|
+
logGroup: serviceLogGroup,
|
|
124
|
+
}),
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// Add mount point to init container
|
|
128
|
+
initContainer.addMountPoints({
|
|
129
|
+
sourceVolume: 'opentelemetry-auto-instrumentation-dotnet',
|
|
130
|
+
containerPath: 'C:\\otel-auto-instrumentation',
|
|
131
|
+
readOnly: false,
|
|
132
|
+
});
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
#### 2.3 Configure Main Application Container OpenTelemetry Environment Variables
|
|
136
|
+
|
|
137
|
+
##### For Linux Containers:
|
|
138
|
+
```typescript
|
|
139
|
+
const mainContainer = taskDefinition.addContainer('{SERVICE_NAME}-container', {
|
|
140
|
+
// Existing configuration...
|
|
141
|
+
environment: {
|
|
142
|
+
// Existing environment variables...
|
|
143
|
+
|
|
144
|
+
// ADOT Configuration for Application Signals - .NET Linux
|
|
145
|
+
OTEL_RESOURCE_ATTRIBUTES: 'service.name={SERVICE_NAME}', // SERVICE_NAME is defined by user. Check for service.serviceName for example
|
|
146
|
+
OTEL_METRICS_EXPORTER: 'none',
|
|
147
|
+
OTEL_LOGS_EXPORTER: 'none',
|
|
148
|
+
DOTNET_STARTUP_HOOKS: '/otel-auto-instrumentation-dotnet/net/OpenTelemetry.AutoInstrumentation.StartupHook.dll',
|
|
149
|
+
DOTNET_ADDITIONAL_DEPS: '/otel-auto-instrumentation-dotnet/AdditionalDeps',
|
|
150
|
+
DOTNET_SHARED_STORE: '/otel-auto-instrumentation-dotnet/store',
|
|
151
|
+
OTEL_DOTNET_AUTO_HOME: '/otel-auto-instrumentation-dotnet',
|
|
152
|
+
OTEL_TRACES_EXPORTER: 'otlp',
|
|
153
|
+
OTEL_EXPORTER_OTLP_PROTOCOL: 'http/protobuf',
|
|
154
|
+
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: 'http://localhost:4316/v1/traces',
|
|
155
|
+
OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT: 'http://localhost:4316/v1/metrics',
|
|
156
|
+
OTEL_AWS_APPLICATION_SIGNALS_ENABLED: 'true',
|
|
157
|
+
CORECLR_ENABLE_PROFILING: '1',
|
|
158
|
+
CORECLR_PROFILER: '{918728DD-259F-4A6A-AC2B-B85E1B658318}',
|
|
159
|
+
CORECLR_PROFILER_PATH: '/otel-auto-instrumentation-dotnet/linux-x64/OpenTelemetry.AutoInstrumentation.Native.so',
|
|
160
|
+
OTEL_DOTNET_AUTO_PLUGINS: 'AWS.Distro.OpenTelemetry.AutoInstrumentation.Plugin, AWS.Distro.OpenTelemetry.AutoInstrumentation',
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
##### For Windows Server Containers:
|
|
166
|
+
```typescript
|
|
167
|
+
const mainContainer = taskDefinition.addContainer('{SERVICE_NAME}-container', {
|
|
168
|
+
// Existing configuration...
|
|
169
|
+
environment: {
|
|
170
|
+
// Existing environment variables...
|
|
171
|
+
|
|
172
|
+
// ADOT Configuration for Application Signals - .NET Windows
|
|
173
|
+
OTEL_RESOURCE_ATTRIBUTES: 'service.name={SERVICE_NAME}', // SERVICE_NAME is defined by user. Check for service.serviceName for example
|
|
174
|
+
OTEL_METRICS_EXPORTER: 'none',
|
|
175
|
+
OTEL_LOGS_EXPORTER: 'none',
|
|
176
|
+
DOTNET_STARTUP_HOOKS: 'C:\\otel-auto-instrumentation\\net\\OpenTelemetry.AutoInstrumentation.StartupHook.dll',
|
|
177
|
+
DOTNET_ADDITIONAL_DEPS: 'C:\\otel-auto-instrumentation\\AdditionalDeps',
|
|
178
|
+
DOTNET_SHARED_STORE: 'C:\\otel-auto-instrumentation\\store',
|
|
179
|
+
OTEL_DOTNET_AUTO_HOME: 'C:\\otel-auto-instrumentation',
|
|
180
|
+
OTEL_TRACES_EXPORTER: 'otlp',
|
|
181
|
+
OTEL_EXPORTER_OTLP_PROTOCOL: 'http/protobuf',
|
|
182
|
+
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: 'http://localhost:4316/v1/traces',
|
|
183
|
+
OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT: 'http://localhost:4316/v1/metrics',
|
|
184
|
+
OTEL_AWS_APPLICATION_SIGNALS_ENABLED: 'true',
|
|
185
|
+
CORECLR_ENABLE_PROFILING: '1',
|
|
186
|
+
CORECLR_PROFILER: '{918728DD-259F-4A6A-AC2B-B85E1B658318}',
|
|
187
|
+
CORECLR_PROFILER_PATH: 'C:\\otel-auto-instrumentation\\win-x64\\OpenTelemetry.AutoInstrumentation.Native.dll',
|
|
188
|
+
OTEL_DOTNET_AUTO_PLUGINS: 'AWS.Distro.OpenTelemetry.AutoInstrumentation.Plugin, AWS.Distro.OpenTelemetry.AutoInstrumentation',
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
#### 2.4 Add Mount Point to Main Container
|
|
194
|
+
|
|
195
|
+
##### For Linux Containers:
|
|
196
|
+
```typescript
|
|
197
|
+
// Add mount point to main application container
|
|
198
|
+
mainContainer.addMountPoints({
|
|
199
|
+
sourceVolume: 'opentelemetry-auto-instrumentation-dotnet',
|
|
200
|
+
containerPath: '/otel-auto-instrumentation-dotnet',
|
|
201
|
+
readOnly: false,
|
|
202
|
+
});
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
##### For Windows Server Containers:
|
|
206
|
+
```typescript
|
|
207
|
+
// Add mount point to main application container
|
|
208
|
+
mainContainer.addMountPoints({
|
|
209
|
+
sourceVolume: 'opentelemetry-auto-instrumentation-dotnet',
|
|
210
|
+
containerPath: 'C:\\otel-auto-instrumentation',
|
|
211
|
+
readOnly: false,
|
|
212
|
+
});
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
#### 2.5 Configure Container Dependencies
|
|
216
|
+
```typescript
|
|
217
|
+
// Ensure containers start in correct order
|
|
218
|
+
mainContainer.addContainerDependencies({
|
|
219
|
+
container: initContainer,
|
|
220
|
+
condition: ecs.ContainerDependencyCondition.SUCCESS,
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
mainContainer.addContainerDependencies({
|
|
224
|
+
container: cwAgentContainer,
|
|
225
|
+
condition: ecs.ContainerDependencyCondition.START,
|
|
226
|
+
});
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Completion
|
|
230
|
+
|
|
231
|
+
**Tell the user:**
|
|
232
|
+
|
|
233
|
+
"I've completed the Application Signals enablement for your .NET application. Here's what I modified:
|
|
234
|
+
|
|
235
|
+
**Files Changed:**
|
|
236
|
+
- IAM role: Added CloudWatchAgentServerPolicy
|
|
237
|
+
- ECS container: Installed and configured CloudWatch Agent as sidecar
|
|
238
|
+
- ADOT SDK container: Mounted ADOT SDK dependencies into Application container
|
|
239
|
+
- Application container: Enabled zero-code instrumentation for .NET Application
|
|
240
|
+
|
|
241
|
+
**Next Steps:**
|
|
242
|
+
1. Ensure that [Application Signals is enabled in AWS account](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Application-Signals-Enable.html).
|
|
243
|
+
This is a one-time setup; if already enabled, you can skip this step.
|
|
244
|
+
2. Review the changes I made using `git diff`
|
|
245
|
+
3. Deploy your infrastructure:
|
|
246
|
+
- For CDK: `cdk deploy`
|
|
247
|
+
- For Terraform: `terraform apply`
|
|
248
|
+
- For CloudFormation: Deploy your stack
|
|
249
|
+
4. After deployment, wait 5-10 minutes for telemetry data to start flowing
|
|
250
|
+
|
|
251
|
+
**Verification:**
|
|
252
|
+
Once deployed, you can verify Application Signals is working by:
|
|
253
|
+
- Opening the AWS CloudWatch Console
|
|
254
|
+
- Navigating to Application Signals → Services
|
|
255
|
+
- Looking for your service (named: {{SERVICE_NAME}})
|
|
256
|
+
- Checking that traces and metrics are being collected
|
|
257
|
+
|
|
258
|
+
**Monitor Application Health:**
|
|
259
|
+
After enablement, you can monitor your application's operational health using Application Signals dashboards. For more information, see [Monitor the operational health of your applications with Application Signals](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Services.html).
|
|
260
|
+
|
|
261
|
+
**Troubleshooting**
|
|
262
|
+
If you encounter any other issues, refer to the [CloudWatch APM troubleshooting guide](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Application-Signals-Enable-Troubleshoot.html).
|
|
263
|
+
|
|
264
|
+
Let me know if you'd like me to make any adjustments before you deploy!"
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# Task: Enable AWS Application Signals for Java on ECS
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
This guide provides complete steps to enable AWS Application Signals for ECS Fargate services, distributed tracing, performance monitoring, and service mapping.
|
|
5
|
+
|
|
6
|
+
## Prerequisites
|
|
7
|
+
- Services running on ECS both the ec2 and Fargate launch types.
|
|
8
|
+
- Applications using Java language
|
|
9
|
+
|
|
10
|
+
## Implementation Steps
|
|
11
|
+
|
|
12
|
+
**Constraints:**
|
|
13
|
+
You must strictly follow the steps in the order below, do not skip or combine steps.
|
|
14
|
+
|
|
15
|
+
### Step 1: Setup CloudWatch Agent Task
|
|
16
|
+
When running in ECS, the CloudWatch Agent is deployed as a sidecar container next to the application container.
|
|
17
|
+
Proper permissions, a CWAgentConfig configuration file, and the target log group must be set up to enable logging and metrics collection.
|
|
18
|
+
|
|
19
|
+
#### 1.1 Add CloudWatch Agent Permissions to ECS Task Role
|
|
20
|
+
|
|
21
|
+
Update ECS task role to add CloudWatchAgentServerPolicy:
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
// Update existing taskRole or create new one
|
|
25
|
+
const taskRole = new iam.Role(this, 'EcsTaskRole', {
|
|
26
|
+
assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
|
|
27
|
+
managedPolicies: [
|
|
28
|
+
iam.ManagedPolicy.fromAwsManagedPolicyName('AWSXRayDaemonWriteAccess'),
|
|
29
|
+
iam.ManagedPolicy.fromAwsManagedPolicyName('CloudWatchAgentServerPolicy'),
|
|
30
|
+
],
|
|
31
|
+
inlinePolicies: {
|
|
32
|
+
// Your existing inline policies...
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
#### 1.2 Create CloudWatch Agent Log Group
|
|
38
|
+
```typescript
|
|
39
|
+
const cwAgentLogGroup = new logs.LogGroup(this, 'CwAgentLogGroup', {
|
|
40
|
+
logGroupName: '/ecs/ecs-cwagent',
|
|
41
|
+
removalPolicy: cdk.RemovalPolicy.DESTROY,
|
|
42
|
+
retention: logs.RetentionDays.ONE_WEEK,
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
#### 1.3 Add CloudWatch Agent Container to Each Task Definition
|
|
47
|
+
```typescript
|
|
48
|
+
// Add CloudWatch Agent sidecar to each task definition
|
|
49
|
+
const cwAgentContainer = taskDefinition.addContainer('ecs-cwagent-{SERVICE_NAME}', {
|
|
50
|
+
image: ecs.ContainerImage.fromRegistry('public.ecr.aws/cloudwatch-agent/cloudwatch-agent:latest'),
|
|
51
|
+
essential: false,
|
|
52
|
+
memoryReservationMiB: 128,
|
|
53
|
+
cpu: 64,
|
|
54
|
+
environment: {
|
|
55
|
+
CW_CONFIG_CONTENT: JSON.stringify({
|
|
56
|
+
"traces": {
|
|
57
|
+
"traces_collected": {
|
|
58
|
+
"application_signals": {}
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"logs": {
|
|
62
|
+
"metrics_collected": {
|
|
63
|
+
"application_signals": {}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}),
|
|
67
|
+
},
|
|
68
|
+
logging: ecs.LogDrivers.awsLogs({
|
|
69
|
+
streamPrefix: 'ecs',
|
|
70
|
+
logGroup: cwAgentLogGroup,
|
|
71
|
+
}),
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Step 2: Add AWS Distro of OpenTelemetry Zero-Code Instrumentation to Main Service
|
|
76
|
+
|
|
77
|
+
#### 2.1 Add Bind Mount Volumes to Task Definition
|
|
78
|
+
```typescript
|
|
79
|
+
const taskDefinition = new ecs.FargateTaskDefinition(this, '{SERVICE_NAME}TaskDefinition', {
|
|
80
|
+
// Existing configuration...
|
|
81
|
+
volumes: [
|
|
82
|
+
{
|
|
83
|
+
name: "opentelemetry-auto-instrumentation-java"
|
|
84
|
+
}
|
|
85
|
+
],
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### 2.2 Add ADOT Auto-instrumentation Init Container
|
|
90
|
+
```typescript
|
|
91
|
+
const initContainer = taskDefinition.addContainer('init', {
|
|
92
|
+
image: ecs.ContainerImage.fromRegistry('public.ecr.aws/aws-observability/adot-autoinstrumentation-java:v2.20.0'),
|
|
93
|
+
essential: false,
|
|
94
|
+
memoryReservationMiB: 64,
|
|
95
|
+
cpu: 32,
|
|
96
|
+
command: ['cp', '-a', '/javaagent.jar', '/otel-auto-instrumentation-java/javaagent.jar'],
|
|
97
|
+
logging: ecs.LogDrivers.awsLogs({
|
|
98
|
+
streamPrefix: 'init-{SERVICE_NAME}',
|
|
99
|
+
logGroup: serviceLogGroup,
|
|
100
|
+
}),
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Add mount point to init container
|
|
104
|
+
initContainer.addMountPoints({
|
|
105
|
+
sourceVolume: 'opentelemetry-auto-instrumentation-java',
|
|
106
|
+
containerPath: '/otel-auto-instrumentation-java',
|
|
107
|
+
readOnly: false,
|
|
108
|
+
});
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
#### 2.3 Configure Main Application Container OpenTelemetry Environment Variables
|
|
112
|
+
|
|
113
|
+
##### Java Application Configuration:
|
|
114
|
+
```typescript
|
|
115
|
+
const mainContainer = taskDefinition.addContainer('{SERVICE_NAME}-container', {
|
|
116
|
+
// Existing configuration...
|
|
117
|
+
environment: {
|
|
118
|
+
// Existing environment variables...
|
|
119
|
+
|
|
120
|
+
// ADOT Configuration for Application Signals
|
|
121
|
+
OTEL_RESOURCE_ATTRIBUTES: 'service.name={SERVICE_NAME}', // SERVICE_NAME is defined by user
|
|
122
|
+
OTEL_METRICS_EXPORTER: 'none',
|
|
123
|
+
OTEL_LOGS_EXPORTER: 'none',
|
|
124
|
+
JAVA_TOOL_OPTIONS: ' -javaagent:/otel-auto-instrumentation-java/javaagent.jar',
|
|
125
|
+
OTEL_TRACES_EXPORTER: 'otlp',
|
|
126
|
+
OTEL_EXPORTER_OTLP_PROTOCOL: 'http/protobuf',
|
|
127
|
+
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: 'http://localhost:4316/v1/traces',
|
|
128
|
+
OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT: 'http://localhost:4316/v1/metrics',
|
|
129
|
+
OTEL_AWS_APPLICATION_SIGNALS_ENABLED: 'true',
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
#### 2.4 Add Mount Point to Main Container
|
|
135
|
+
```typescript
|
|
136
|
+
// Add mount point to main application container
|
|
137
|
+
mainContainer.addMountPoints({
|
|
138
|
+
sourceVolume: 'opentelemetry-auto-instrumentation-java',
|
|
139
|
+
containerPath: '/otel-auto-instrumentation-java',
|
|
140
|
+
readOnly: false,
|
|
141
|
+
});
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
#### 2.5 Configure Container Dependencies
|
|
145
|
+
```typescript
|
|
146
|
+
// Ensure containers start in correct order
|
|
147
|
+
mainContainer.addContainerDependencies({
|
|
148
|
+
container: initContainer,
|
|
149
|
+
condition: ecs.ContainerDependencyCondition.SUCCESS,
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
mainContainer.addContainerDependencies({
|
|
153
|
+
container: cwAgentContainer,
|
|
154
|
+
condition: ecs.ContainerDependencyCondition.START,
|
|
155
|
+
});
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Completion
|
|
159
|
+
|
|
160
|
+
**Tell the user:**
|
|
161
|
+
|
|
162
|
+
"I've completed the Application Signals enablement for your application. Here's what I modified:
|
|
163
|
+
|
|
164
|
+
**Files Changed:**
|
|
165
|
+
- IAM role: Added CloudWatchAgentServerPolicy
|
|
166
|
+
- ECS container: Installed and configured CloudWatch Agent as sidecar
|
|
167
|
+
- ADOT SDK container: Mounted ADOT SDK dependencies into Application container
|
|
168
|
+
- Applicaiton container: Enabled zero-code instrumentation for Application
|
|
169
|
+
|
|
170
|
+
**Next Steps:**
|
|
171
|
+
1. Ensure that [Application Signals is enabled in AWS account](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Application-Signals-Enable.html).
|
|
172
|
+
This is a one-time setup; if already enabled, you can skip this step.
|
|
173
|
+
2. Review the changes I made using `git diff`
|
|
174
|
+
3. Deploy your infrastructure:
|
|
175
|
+
- For CDK: `cdk deploy`
|
|
176
|
+
- For Terraform: `terraform apply`
|
|
177
|
+
- For CloudFormation: Deploy your stack
|
|
178
|
+
4. After deployment, wait 5-10 minutes for telemetry data to start flowing
|
|
179
|
+
|
|
180
|
+
**Verification:**
|
|
181
|
+
Once deployed, you can verify Application Signals is working by:
|
|
182
|
+
- Opening the AWS CloudWatch Console
|
|
183
|
+
- Navigating to Application Signals → Services
|
|
184
|
+
- Looking for your service (named: {{SERVICE_NAME}})
|
|
185
|
+
- Checking that traces and metrics are being collected
|
|
186
|
+
|
|
187
|
+
**Monitor Application Health:**
|
|
188
|
+
After enablement, you can monitor your application's operational health using Application Signals dashboards. For more information, see [Monitor the operational health of your applications with Application Signals](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Services.html).
|
|
189
|
+
|
|
190
|
+
**Troubleshooting**
|
|
191
|
+
If you encounter any other issues, refer to the [CloudWatch APM troubleshooting guide](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Application-Signals-Enable-Troubleshoot.html).
|
|
192
|
+
|
|
193
|
+
Let me know if you'd like me to make any adjustments before you deploy!"
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# Task: Enable AWS Application Signals for Node.js on ECS
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
This guide provides complete steps to enable AWS Application Signals for ECS Fargate services, distributed tracing, performance monitoring, and service mapping.
|
|
5
|
+
|
|
6
|
+
## Prerequisites
|
|
7
|
+
- Services running on ECS both the ec2 and Fargate launch types.
|
|
8
|
+
- Applications using Node.js language
|
|
9
|
+
|
|
10
|
+
## Implementation Steps
|
|
11
|
+
|
|
12
|
+
**Constraints:**
|
|
13
|
+
You must strictly follow the steps in the order below, do not skip or combine steps.
|
|
14
|
+
|
|
15
|
+
### Step 1: Setup CloudWatch Agent Task
|
|
16
|
+
When running in ECS, the CloudWatch Agent is deployed as a sidecar container next to the application container.
|
|
17
|
+
Proper permissions, a CWAgentConfig configuration file, and the target log group must be set up to enable logging and metrics collection.
|
|
18
|
+
|
|
19
|
+
#### 1.1 Add CloudWatch Agent Permissions to ECS Task Role
|
|
20
|
+
|
|
21
|
+
Update ECS task role to add CloudWatchAgentServerPolicy:
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
// Update existing taskRole or create new one
|
|
25
|
+
const taskRole = new iam.Role(this, 'EcsTaskRole', {
|
|
26
|
+
assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
|
|
27
|
+
managedPolicies: [
|
|
28
|
+
iam.ManagedPolicy.fromAwsManagedPolicyName('AWSXRayDaemonWriteAccess'),
|
|
29
|
+
iam.ManagedPolicy.fromAwsManagedPolicyName('CloudWatchAgentServerPolicy'),
|
|
30
|
+
],
|
|
31
|
+
inlinePolicies: {
|
|
32
|
+
// Your existing inline policies...
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
#### 1.2 Create CloudWatch Agent Log Group
|
|
38
|
+
```typescript
|
|
39
|
+
const cwAgentLogGroup = new logs.LogGroup(this, 'CwAgentLogGroup', {
|
|
40
|
+
logGroupName: '/ecs/ecs-cwagent',
|
|
41
|
+
removalPolicy: cdk.RemovalPolicy.DESTROY,
|
|
42
|
+
retention: logs.RetentionDays.ONE_WEEK,
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
#### 1.3 Add CloudWatch Agent Container to Each Task Definition
|
|
47
|
+
```typescript
|
|
48
|
+
// Add CloudWatch Agent sidecar to each task definition
|
|
49
|
+
const cwAgentContainer = taskDefinition.addContainer('ecs-cwagent-{SERVICE_NAME}', {
|
|
50
|
+
image: ecs.ContainerImage.fromRegistry('public.ecr.aws/cloudwatch-agent/cloudwatch-agent:latest'),
|
|
51
|
+
essential: false,
|
|
52
|
+
memoryReservationMiB: 128,
|
|
53
|
+
cpu: 64,
|
|
54
|
+
environment: {
|
|
55
|
+
CW_CONFIG_CONTENT: JSON.stringify({
|
|
56
|
+
"traces": {
|
|
57
|
+
"traces_collected": {
|
|
58
|
+
"application_signals": {}
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"logs": {
|
|
62
|
+
"metrics_collected": {
|
|
63
|
+
"application_signals": {}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}),
|
|
67
|
+
},
|
|
68
|
+
logging: ecs.LogDrivers.awsLogs({
|
|
69
|
+
streamPrefix: 'ecs',
|
|
70
|
+
logGroup: cwAgentLogGroup,
|
|
71
|
+
}),
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Step 2: Add ADOT Zero-Code Instrumentation to Main Service
|
|
76
|
+
|
|
77
|
+
#### 2.1 Add Bind Mount Volumes to Task Definition
|
|
78
|
+
```typescript
|
|
79
|
+
const taskDefinition = new ecs.FargateTaskDefinition(this, '{SERVICE_NAME}TaskDefinition', {
|
|
80
|
+
// Existing configuration...
|
|
81
|
+
volumes: [
|
|
82
|
+
{
|
|
83
|
+
name: "opentelemetry-auto-instrumentation-node"
|
|
84
|
+
}
|
|
85
|
+
],
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### 2.2 Add AWS Distro of OpenTelemetry Auto-instrumentation Init Container
|
|
90
|
+
```typescript
|
|
91
|
+
const initContainer = taskDefinition.addContainer('init', {
|
|
92
|
+
image: ecs.ContainerImage.fromRegistry('public.ecr.aws/aws-observability/adot-autoinstrumentation-node:v0.8.0'),
|
|
93
|
+
essential: false,
|
|
94
|
+
memoryReservationMiB: 64,
|
|
95
|
+
cpu: 32,
|
|
96
|
+
command: ['cp', '-a', '/autoinstrumentation/.', '/otel-auto-instrumentation-node'],
|
|
97
|
+
logging: ecs.LogDrivers.awsLogs({
|
|
98
|
+
streamPrefix: 'init-{SERVICE_NAME}',
|
|
99
|
+
logGroup: serviceLogGroup,
|
|
100
|
+
}),
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Add mount point to init container
|
|
104
|
+
initContainer.addMountPoints({
|
|
105
|
+
sourceVolume: 'opentelemetry-auto-instrumentation-node',
|
|
106
|
+
containerPath: '/otel-auto-instrumentation-node',
|
|
107
|
+
readOnly: false,
|
|
108
|
+
});
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
#### 2.3 Configure Main Application Container OpenTelemetry Environment Variables
|
|
112
|
+
|
|
113
|
+
##### Node.js Application Configuration:
|
|
114
|
+
```typescript
|
|
115
|
+
const mainContainer = taskDefinition.addContainer('{SERVICE_NAME}-container', {
|
|
116
|
+
// Existing configuration...
|
|
117
|
+
environment: {
|
|
118
|
+
// Existing environment variables...
|
|
119
|
+
|
|
120
|
+
// ADOT Configuration for Application Signals - Node.js
|
|
121
|
+
OTEL_RESOURCE_ATTRIBUTES: 'service.name=${SERVICE_NAME}', // SERVICE_NAME is defined by user
|
|
122
|
+
OTEL_METRICS_EXPORTER: 'none',
|
|
123
|
+
OTEL_LOGS_EXPORTER: 'none',
|
|
124
|
+
NODE_OPTIONS: '--require /otel-auto-instrumentation-node/autoinstrumentation.js', // CJS
|
|
125
|
+
OTEL_TRACES_EXPORTER: 'otlp',
|
|
126
|
+
OTEL_EXPORTER_OTLP_PROTOCOL: 'http/protobuf',
|
|
127
|
+
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: 'http://localhost:4316/v1/traces',
|
|
128
|
+
OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT: 'http://localhost:4316/v1/metrics',
|
|
129
|
+
OTEL_AWS_APPLICATION_SIGNALS_ENABLED: 'true',
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
If the project uses CJS, then
|
|
134
|
+
NODE_OPTIONS: '--require /otel-auto-instrumentation-node/autoinstrumentation.js',
|
|
135
|
+
|
|
136
|
+
but if it uses ESM, then
|
|
137
|
+
NODE_OPTIONS: '--import /otel-auto-instrumentation-node/autoinstrumentation.js --experimental-loader=/otel-auto-instrumentation-node/node_modules/@opentelemetry/instrumentation/instrumentation/hook.mjs'
|
|
138
|
+
|
|
139
|
+
#### 2.4 Add Mount Point to Main Container
|
|
140
|
+
```typescript
|
|
141
|
+
// Add mount point to main application container
|
|
142
|
+
mainContainer.addMountPoints({
|
|
143
|
+
sourceVolume: 'opentelemetry-auto-instrumentation-node',
|
|
144
|
+
containerPath: '/otel-auto-instrumentation-node',
|
|
145
|
+
readOnly: false,
|
|
146
|
+
});
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
#### 2.5 Configure Container Dependencies
|
|
150
|
+
```typescript
|
|
151
|
+
// Ensure containers start in correct order
|
|
152
|
+
mainContainer.addContainerDependencies({
|
|
153
|
+
container: initContainer,
|
|
154
|
+
condition: ecs.ContainerDependencyCondition.SUCCESS,
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
mainContainer.addContainerDependencies({
|
|
158
|
+
container: cwAgentContainer,
|
|
159
|
+
condition: ecs.ContainerDependencyCondition.START,
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Completion
|
|
164
|
+
|
|
165
|
+
**Tell the user:**
|
|
166
|
+
|
|
167
|
+
"I've completed the Application Signals enablement for your application. Here's what I modified:
|
|
168
|
+
|
|
169
|
+
**Files Changed:**
|
|
170
|
+
- IAM role: Added CloudWatchAgentServerPolicy
|
|
171
|
+
- ECS container: Installed and configured CloudWatch Agent as sidecar
|
|
172
|
+
- ADOT SDK container: Mounted ADOT SDK dependencies into Application container
|
|
173
|
+
- Applicaiton container: Enabled zero-code instrumentation for Application
|
|
174
|
+
|
|
175
|
+
**Next Steps:**
|
|
176
|
+
1. Ensure that [Application Signals is enabled in AWS account](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Application-Signals-Enable.html).
|
|
177
|
+
This is a one-time setup; if already enabled, you can skip this step.
|
|
178
|
+
2. Review the changes I made using `git diff`
|
|
179
|
+
3. Deploy your infrastructure:
|
|
180
|
+
- For CDK: `cdk deploy`
|
|
181
|
+
- For Terraform: `terraform apply`
|
|
182
|
+
- For CloudFormation: Deploy your stack
|
|
183
|
+
4. After deployment, wait 5-10 minutes for telemetry data to start flowing
|
|
184
|
+
|
|
185
|
+
**Verification:**
|
|
186
|
+
Once deployed, you can verify Application Signals is working by:
|
|
187
|
+
- Opening the AWS CloudWatch Console
|
|
188
|
+
- Navigating to Application Signals → Services
|
|
189
|
+
- Looking for your service (named: {{SERVICE_NAME}})
|
|
190
|
+
- Checking that traces and metrics are being collected
|
|
191
|
+
|
|
192
|
+
**Monitor Application Health:**
|
|
193
|
+
After enablement, you can monitor your application's operational health using Application Signals dashboards. For more information, see [Monitor the operational health of your applications with Application Signals](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Services.html).
|
|
194
|
+
|
|
195
|
+
**Troubleshooting**
|
|
196
|
+
If you encounter any other issues, refer to the [CloudWatch APM troubleshooting guide](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Application-Signals-Enable-Troubleshoot.html).
|
|
197
|
+
|
|
198
|
+
Let me know if you'd like me to make any adjustments before you deploy!"
|