Course-এর সূচি

19.2

CloudWatch Logs, Agent আর Subscription

log group আর stream, unified agent, Logs Insights, export বনাম subscription, অনেক account-এর log এক জায়গায় আনা, আর Live Tail।

26 মিনিট পড়া + Animation

টিপস: ডটেড-আন্ডারলাইন করা যেকোনো শব্দে ট্যাপ বা Hover করলে তার অর্থ দেখবে।

এই লেসন শেষে তুমি পারবে

  • CloudWatch Logs কীভাবে log রাখে বুঝিয়ে বলতে: log event, log stream আর log group, আর কোন কোন setting group-এ থাকে (retention, KMS key, log class, access)।
  • কোন কোন source থেকে CloudWatch Logs-এ log আসে বলতে, আর কেন agent না পাঠানো পর্যন্ত EC2 instance থেকে কিছুই বের হয় না, ব্যাখ্যা করতে।
  • Metric filter দিয়ে log-এর লাইনকে metric-এ বদলাতে, আর পরীক্ষার চেনা শিকলটা বানাতে: log → metric filter → metric → alarm → SNS।
  • Logs Insights দিয়ে জমা log-এ query চালাতে (এর তিনটা query language আর দাম জানতে), আর Live Tail দিয়ে নতুন log আসার সাথে সাথে দেখতে।
  • S3-এ export task (batch, ১২ ঘণ্টা পর্যন্ত পিছিয়ে) আর subscription filter (real time; Kinesis Data Streams, Data Firehose, Lambda বা OpenSearch-এ)-এর মধ্যে ঠিকটা বাছতে।
  • Destination, access policy আর IAM role দিয়ে অনেক account আর Region-এর log একটা log-archive account-এ জড়ো করতে।
  • পুরোনো CloudWatch Logs agent-এর বদলে unified CloudWatch agent বেছে নিতে, আর EC2 ও on-premises দুই জায়গাতেই তাকে credential দিতে।

#CloudWatch Logs কেন: সব log এক জায়গায়

লেসন ১৯.১-এর বিষয় ছিল সংখ্যা: CPU, latency, request-এর হিসাব। সংখ্যা বলে দেয় যে কিছু একটা গোলমাল হয়েছে। কেন হয়েছে জানতে হলে log পড়তে হয়: stack trace, ব্যর্থ SQL statement, কোন IP বারবার login page-এ ধাক্কা দিচ্ছিল। এই লেসন সেই log AWS-এ কোথায় থাকে, তা নিয়ে।

#সমস্যাটা কী

ঢাকার একটা news portal EC2-তে বারোটা web server চালায়, ছবি ছোট করার জন্য কয়েকটা Lambda function আছে, mobile app-এর জন্য একটা API Gateway, আর তেজগাঁওয়ের একটা data centre-এর server-এ চলে পুরোনো printing system। প্রত্যেকেই log লেখে, যার যার নিজের disk-এ। নির্বাচনের রাতে home page ধীর হয়ে গেল। কারণ খুঁজতে একজন engineer-কে বারোটা server-এ login করে বারোটা file পড়তে হতো, আর যে server-গুলো Auto Scaling আগেই বন্ধ করে দিয়েছে, তাদের log তো তাদের সাথেই চলে গেছে।

Amazon CloudWatch Logs এই সমস্যার সমাধান: application, operating system আর AWS service-এর (VPC Flow Logs, Route 53, CloudTrail আর আরও অনেক) log একটা regional service-এ জড়ো করে, তুমি যতদিন চাও ততদিন রাখে, আর সেগুলো খুঁজতে, metric বানাতে, alert দিতে আর অন্য জায়গায় পাঠাতে দেয়।

#Event, stream আর group

CloudWatch Logs-এর গঠন তিন স্তরের:

স্তরকী জিনিসউদাহরণ
Log eventএকটা record: একটা message আর একটা timestamp। সাধারণত log file-এর একটা লাইন। সর্বোচ্চ 1 MB (1,024 KB)।2026-11-01T09:00:03Z /sports 200 41ms 198.51.100.23
Log streamএকটা source-এর event-এর ধারা, সময়ের ক্রমে।Instance i-0a1b2c3d-এর সব লাইন, একটা container, বা একটা Lambda execution environment
Log groupStream-গুলোর একটা পাত্র, যাদের setting একই: retention, encryption, access control, log class, filter। সাধারণত প্রতিটা application বা component-এর জন্য একটা।/news/app, /aws/lambda/resize-photo

একটা group-এ যত খুশি stream থাকতে পারে, আর stream সাধারণত যে লেখে সে নিজেই বানিয়ে নেয় (agent, Lambda, ECS)।

Log event, stream আর log group

ঢাকার একটা news portal দুটো web server চালায়। দেখো তাদের প্রতিটা লাইন কীভাবে log event হয়, প্রতিটা server কীভাবে নিজের stream পায়, আর group কীভাবে setting ধরে রাখে: retention, encryption key আর access।

পরিস্থিতি

Event = timestamp-সহ একটা লাইন। Stream = একটা source-এর event, সময়ের ক্রমে। Group = stream-গুলোর folder, setting থাকে এখানেই।

web-1agent সহ
web-2agent সহ
Log group/news/app
KMS keycustomer managed
Engineer
১টা event

Log event

timestamp

2026-11-01T09:00:03Z

message

/sports 200 41ms 198.51.100.23

ধাপ 1 / 7
1

একজন পাঠক খেলার পাতা খুলল। web-1-এর agent access log-এর নতুন লাইনটা পড়ে একটা log event হিসেবে পাঠায়: একটা message আর একটা timestamp। এই একটা লাইনই CloudWatch Logs-এর সবচেয়ে ছোট একক।

#Group-এর setting

Retention। Default অবস্থায় log group তার event চিরকাল রাখে (Never Expire)। চাইলে নির্দিষ্ট কয়েকটা ধাপে ১ দিন থেকে ১০ বছর পর্যন্ত retention দেওয়া যায়: ১, ৩, ৫, ৭, ১৪, ৩০, ৬০, ৯০, ১২০, ১৫০, ১৮০, ৩৬৫, ৪০০, ৫৪৫, ৭৩১, ১,০৯৬, ১,৮২৭, ২,১৯২, ২,৫৫৭, ২,৯২২, ৩,২৮৮ বা ৩,৬৫৩ দিন। Retention-এর চেয়ে পুরোনো event মোছার জন্য চিহ্নিত হয় (সাথে সাথেই সেগুলোর bill বন্ধ হয়; আসলে মুছতে ৭২ ঘণ্টা পর্যন্ত লাগতে পারে), আর আর ফেরত আনা যায় না। চেনা একটা design: খোঁজার জন্য CloudWatch Logs-এ ছোট retention, আর দীর্ঘ সময়ের copy S3-এ lifecycle rule-সহ (লেসন ১০.৫)।

Encryption। Log data সবসময়ই at rest encrypt থাকে, default-এ service-এর নিজের সামলানো key দিয়ে 256-bit AES-এ। আরও নিয়ন্ত্রণ চাইলে log group-এর সাথে একটা customer managed KMS key (শুধু symmetric) জুড়ে দিতে পারো, group বানানোর সময় বা পরে associate-kms-key দিয়ে। Key policy-তে ওই Region-এর CloudWatch Logs service principal-কে অনুমতি দিতে হয়। তারপর নতুন event তোমার key দিয়ে encrypt হয়; key বন্ধ করলে log পড়া যায় না, আর key মুছে ফেললে সেগুলো চিরতরে হারায়। KMS নিজে পড়বে লেসন ২১.২-এ।

Access। কে একটা group পড়তে বা লিখতে পারবে, তা ঠিক করে IAM policy (group-এর ARN ধরে, বা tag দিয়ে)। Stream-এর নিজের কোনো permission নেই; access ঠিক হয় group-এর স্তরে। ভুল করে মুছে ফেলা ঠেকাতে deletion protection চালু করা যায়।

Log class। Group বানানোর সময়ই বাছতে হয়, পরে আর বদলানো যায় না:

StandardEssentials (আগের নাম Infrequent Access)
Ingestion-এর দামস্বাভাবিক (us-east-1-এ GB-প্রতি প্রায় ০.৫০ USD)প্রায় অর্ধেক
Storage আর Logs Insights-এর দামএকইএকই
Logs Insights query, S3-এ export, KMS, cross-account, data protectionআছেআছে
Metric filter, subscription filter, Live Tail, anomaly detection, embedded metricআছেনেই
কীসের জন্য ভালোযে log-এ alert দাও, stream করো বা live দেখোমাঝেমধ্যে query করা debug আর forensic log

#Log আসে কোথা থেকে

  • তোমার code: AWS SDK আর CLI (PutLogEvents), 1 MB পর্যন্ত batch-এ। ১৪ দিনের বেশি পুরোনো বা ২ ঘণ্টার বেশি ভবিষ্যতের event বাতিল হয়।
  • Server-এ agent: unified CloudWatch agent (আর deprecated CloudWatch Logs agent), EC2-তে বা on-premises-এ। নিচে বিস্তারিত।
  • Elastic Beanstalk: log streaming চালু থাকলে instance-এর application log পাঠায়।
  • ECS আর EKS: container stdout-এ লেখে, আর awslogs log driver (বা Fluent Bit) প্রতিটা container-এর output একটা stream হিসেবে পাঠায় (লেসন ১৪.২)।
  • Lambda: execution role অনুমতি দিলে প্রতিটা function নিজে থেকেই /aws/lambda/<function-name>-এ লেখে (লেসন ১৫.১)।
  • VPC Flow Logs: VPC, subnet বা network interface-এর গৃহীত আর প্রত্যাখ্যাত connection (লেসন ২২.৩)।
  • API Gateway: প্রতিটা stage-এর execution log আর access log।
  • CloudTrail: একটা trail তার API event একটা log group-এও পাঠাতে পারে, যাতে metric filter দিয়ে সেগুলোর ওপর alarm বসানো যায় (লেসন ১৯.৬)।
  • Route 53: DNS query log। Public hosted zone-এর query log যায় us-east-1-এর একটা log group-এ; Resolver query log রাখে তোমার VPC-র ভেতর থেকে করা DNS query।
  • আরও অনেক: RDS আর Aurora-র database log, AWS WAF, Step Functions, Systems Manager Run Command-এর output…

#Metric filter: log-এর লাইন থেকে সংখ্যা

Alarm দেখে metric, লেখা না। Log-এ কোনো নির্দিষ্ট লাইন এলেই জানতে চাইলে আগে মিলে যাওয়া লাইনগুলোকে একটা সংখ্যায় বদলাতে হয়। সেটাই metric filter:

  • এটা একটা log group-এর অংশ, আর এর একটা filter pattern থাকে: একটা শব্দ বা বাক্যাংশ (ERROR, "payment failed"), কয়েকটা শব্দ (?ERROR ?Timeout, যেকোনো একটা মিললেই), লাইনের field ধরে space দিয়ে ভাগ করা pattern ([ip, user, ts, request, status=5*, size]), বা JSON pattern ({ $.level = "error" }, { $.latency > 2000 })।
  • মিলে যাওয়া প্রতিটা নতুন event-এর জন্য এটা একটা মান publish করে (সাধারণত 1, বা latency-র মতো কোনো field) তোমার বাছা namespace আর নামের একটা custom metric-এ, চাইলে event-এর field থেকে নেওয়া dimension-সহ (সর্বোচ্চ ৩টা)।
  • যে period-এ কিছুই মেলেনি, তার জন্য একটা default value (সাধারণত 0) publish হয়; না দিলে শান্ত সময়গুলোতে কোনো data-ই থাকে না।
  • এটা খাটে শুধু তৈরি হওয়ার পরে ঢোকা event-এ: পুরোনো data কখনো scan করে না। একটা log group-এ ১০০টা পর্যন্ত metric filter, শুধু Standard class-এ।

তারপর চেনা শিকলটাই গল্প শেষ করে: ওই metric-এর ওপর একটা alarm (লেসন ১৯.৩), যার action একটা SNS topic-এ publish করে (email, SMS, Lambda function, chat channel; লেসন ১৩.৪)।

Log-এর লাইন থেকে ফোনে alert

একটা mobile wallet-এর payment API JSON log লেখে। একটা metric filter ব্যর্থ payment গোনে, একটা alarm সেই সংখ্যার দিকে চোখ রাখে, আর SNS on-call engineer-কে জাগিয়ে তোলে। তারপর দেখো দুটো চেনা চমক।

পরিস্থিতি

Log → metric filter → metric → alarm → SNS: “log-এ নির্দিষ্ট error দেখা দিলেই জানাও” প্রশ্নের পরীক্ষার শিকল।

wallet-apipayment
Log group/wallet/api
Metricpayment error
Alarmমিনিটে ≥ ৫
SNSon-call topic
On-call
log লাইন

দুটো log event

09:14:02

{"level":"info","path":"/send-money","status":200}

09:14:03

{"level":"error","code":"payment_failed","status":502}

ধাপ 1 / 5
1

ঈদের বেতনের দিন, প্রচুর traffic। বেশিরভাগ লাইনে level info, কিন্তু কিছু payment ব্যর্থ হয়, আর app level error আর code payment_failed দিয়ে একটা লাইন লেখে। শুধু log দিয়ে alarm বাজানো যায় না; alarm দেখে metric।

#Logs Insights: জমা log-কে প্রশ্ন করো

CloudWatch Logs Insights হলো তোমার log group-এ আগে থেকে জমা event-এর ওপর একটা interactive query engine। তুমি একটা সময়ের পরিসর আর এক বা একাধিক log group বেছে নাও (CloudWatch cross-account observability দিয়ে অন্য account-এরও), তারপর query লেখো। সাধারণ প্রশ্ন: প্রতি ৫ মিনিটে কতগুলো ERROR লাইন, একটা IP-র সব request, সবচেয়ে ধীর দশটা endpoint, deployment-এর পরে সবচেয়ে বেশি আসা error message কোনগুলো।

  • তিনটা query language। নিজস্ব Logs Insights query language (pipe দিয়ে জোড়া command: fields, filter, stats, sort, limit, parse, dedup, pattern…), আর ২০২৪-এর শেষ থেকে OpenSearch PPL আর OpenSearch SQL-ও (SQL দিয়ে log group-এর মধ্যে join পর্যন্ত করা যায়)।
  • নিজে থেকে চেনা field। AWS service-এর log (Lambda, VPC Flow Logs, CloudTrail, Route 53) আর যেকোনো JSON log-এ field নিজেই চিনে নেয়, তাই status বা duration নাম ধরেই filter করা যায়; সাধারণ লেখা থেকে field বের করে parse।
  • Real time না। এটা query করে যা আগেই জমা হয়েছে, কয়েক সেকেন্ড আগের থেকে কয়েক বছর আগের পর্যন্ত। একটা query সর্বোচ্চ ৬০ মিনিট চলে, ফলাফল থাকে ৭ দিন। এক account-এ একসাথে ১০০টা পর্যন্ত query চলতে পারে।
  • দাম। টাকা লাগে যত GB data scan হলো তার জন্য (us-east-1-এ GB-প্রতি প্রায় ০.০০৫ USD), যত কম সারিই মিলুক। ছোট সময়ের পরিসর আর কম log group মানে কম খরচ; field index দিয়ে অনেক event এড়িয়ে যাওয়া যায়।
  • আবার ব্যবহার। Query save করো (parameter-সহ), CloudWatch dashboard-এ বসাও, সময় ধরে চালাও, বা সাধারণ ইংরেজিতে প্রশ্ন লিখে query বানিয়ে নাও।

Logs Insights খেলাঘর

/wallet/api log group-এর ০৯:০০ থেকে ০৯:১৫-এর ষোলোটা event। একটা query বেছে নাও, দেখো কোন লাইনগুলো ছোঁয় আর কী ফেরত দেয়। তারপর Live Tail-এ গিয়ে দেখো নতুন লাইন কীভাবে আসে।

একটা query বেছে নাও

Log event (মিলে যাওয়া লাইন রাঙানো)

  1. 09:00:12 {"level":"info","path":"/send-money","status":200,"duration":120,"ip":"198.51.100.23"}
  2. 09:01:40 {"level":"info","path":"/balance","status":200,"duration":35,"ip":"198.51.100.41"}
  3. 09:02:05 {"level":"info","path":"/cash-out","status":200,"duration":210,"ip":"203.0.113.7"}
  4. 09:03:18 {"level":"warn","path":"/send-money","status":429,"duration":8,"ip":"203.0.113.7"}
  5. 09:04:51 {"level":"info","path":"/balance","status":200,"duration":31,"ip":"198.51.100.23"}
  6. 09:05:30 {"level":"info","path":"/send-money","status":200,"duration":140,"ip":"198.51.100.62"}
  7. 09:06:02 {"level":"error","path":"/cash-out","status":502,"duration":3010,"ip":"198.51.100.41"}
  8. 09:07:44 {"level":"info","path":"/balance","status":200,"duration":29,"ip":"203.0.113.7"}
  9. 09:08:15 {"level":"error","path":"/send-money","status":502,"duration":3002,"ip":"198.51.100.23"}
  10. 09:09:59 {"level":"info","path":"/send-money","status":200,"duration":133,"ip":"198.51.100.62"}
  11. 09:10:20 {"level":"error","path":"/send-money","status":504,"duration":5000,"ip":"198.51.100.88"}
  12. 09:11:03 {"level":"error","path":"/cash-out","status":502,"duration":3005,"ip":"203.0.113.7"}
  13. 09:11:47 {"level":"info","path":"/balance","status":200,"duration":33,"ip":"198.51.100.41"}
  14. 09:12:30 {"level":"error","path":"/send-money","status":502,"duration":3011,"ip":"198.51.100.62"}
  15. 09:13:09 {"level":"info","path":"/cash-out","status":200,"duration":190,"ip":"198.51.100.88"}
  16. 09:14:26 {"level":"error","path":"/send-money","status":504,"duration":5000,"ip":"198.51.100.23"}

ফলাফল

একটা query বেছে নাও

#Live Tail: log আসার সাথে সাথে দেখো

Live Tail হলো Logs Insights-এর উল্টো: অতীত না খুঁজে এটা ১০টা পর্যন্ত log group থেকে নতুন event ঢোকার মোটামুটি এক সেকেন্ডের মধ্যে তোমার console বা CLI-তে দেখায়, filter আর highlight-সহ। Developer-রা deployment বা incident-এর সময় এটা খুলে রাখেন, যাতে নতুন version এই মুহূর্তে কী লিখছে তা চোখের সামনে দেখা যায়।

Logs InsightsLive Tail
কী দেখেএকটা সময়ের পরিসরে জমা, অতীতের eventএখন থেকে আসা নতুন event
কাজতদন্ত, পরিসংখ্যান, report, dashboardচলতি deployment বা incident live দেখা
BillScan করা GB ধরেSession-এর মিনিট ধরে (মিনিটে প্রায় ০.০১ USD)
Log classStandard আর Essentialsশুধু Standard

Session interactive: এক account-এ একসাথে ১৫টা পর্যন্ত, আর API session চলে সর্বোচ্চ ৩ ঘণ্টা।

#Log বাইরে নেওয়া: export নাকি subscription

সাম্প্রতিক log খোঁজার জন্য CloudWatch Logs ভালো জায়গা, কিন্তু বছরের পর বছর রেখে দেওয়ার জন্য সবসময় না, আর security team যে tool আগে থেকে ব্যবহার করে সেটাও না। বাইরে নেওয়ার পথ দুটো।

#S3-এ export: batch

একটা export task (CreateExportTask) একটা log group-এর একটা সময়ের অংশ-এর event gzip file হিসেবে একটা S3 bucket-এ, তোমার দেওয়া prefix-এর নিচে copy করে।

  • এটা real time না: log data export করার মতো হতে ১২ ঘণ্টা পর্যন্ত লাগতে পারে।
  • প্রতি account আর Region-এ একসাথে একটাই export task সক্রিয় থাকতে পারে; ২৪ ঘণ্টার বেশি চললে task timeout হয়।
  • Bucket policy-তে CloudWatch Logs service-কে লেখার অনুমতি দিতে হয়। SSE-S3 বা SSE-KMS দিয়ে encrypt করা bucket আর Object Lock-সহ bucket চলে (DSSE-KMS চলে না)। Bucket অন্য account-এরও হতে পারে।
  • নিরবচ্ছিন্ন archive-এর জন্য নিয়মিত export চালাতে AWS নিষেধ করে; তার জন্য subscription।

কাজে লাগে: auditor-এর জন্য গত মাসের একবারের copy, বা migration।

#Subscription filter: real time

একটা subscription filter log group-এর যেসব event একটা pattern-এর সাথে মেলে (ফাঁকা pattern মানে সব), সেগুলো ঢোকার সাথে সাথেই পাঠায়:

  • Kinesis Data Streams-এ: নিজস্ব real-time consumer আর replay-এর জন্য (লেসন ১৩.৫)।
  • Amazon Data Firehose-এ (আগের নাম Kinesis Data Firehose): কোনো code ছাড়াই প্রায় real time-এ S3, Redshift, OpenSearch বা Splunk, Datadog-এর মতো partner-এর কাছে (লেসন ১৩.৬)।
  • Lambda-য়: event-এর প্রতিটা batch-এ নিজস্ব processing।
  • OpenSearch Service-এ: console নিজে একটা Lambda function বানিয়ে এটা জুড়ে দেয়, full-text search আর dashboard-এর জন্য (লেসন ১৭.৩)।

যে খুঁটিনাটিগুলো জরুরি:

  • Event পৌঁছায় base64 encode আর gzip compress করা অবস্থায়, সাধারণত তিন মিনিটের অনেক কমে, অন্তত একবার (কালেভদ্রে একটা duplicate হতে পারে)।
  • একটা log group-এ ৫টা পর্যন্ত subscription filter, প্রতিটার নিজের pattern আর গন্তব্য।
  • গন্তব্যে লেখার অনুমতি CloudWatch Logs-এর লাগে: Kinesis আর Firehose-এর জন্য একটা IAM role, Lambda function-এ একটা resource-based permission।
  • গন্তব্য throttle করলে বা আবার-চেষ্টাযোগ্য error দিলে ২৪ ঘণ্টা পর্যন্ত আবার পাঠানোর চেষ্টা চলে; তারপর event-গুলো subscription থেকে বাদ পড়ে। Delivery throttling metric-এ চোখ রাখো।
  • Account-level subscription filter (২০২৪ থেকে): প্রতি account আর Region-এ একটা, যেটা সব log group (বা তুমি বাদ দিলে বাকিগুলো) ঢেকে Kinesis Data Streams, Firehose বা Lambda-য় পাঠায়। Delivery pipeline-এর নিজের log group বাদ দাও, না হলে subscription নিজেকেই খাওয়াতে থাকবে, একটা অন্তহীন আর দামি চক্রে।
  • শুধু Standard class-এ।
Export taskSubscription filter
সময়Batch; data export করার মতো হতে ১২ ঘণ্টা পর্যন্তReal time, event ঢোকার সাথে সাথে
কী ঢাকেএকটা log group, অতীতের একটা সময়ের অংশশুধু নতুন event, তৈরি হওয়ার পর থেকে
গন্তব্যS3 (একই বা অন্য account)Kinesis Data Streams, Firehose, Lambda, OpenSearch
সীমাপ্রতি account আর Region-এ একটা সক্রিয় taskLog group-প্রতি ৫টা, সাথে একটা account-level
কীসের জন্যএকবারের copy, auditনিরবচ্ছিন্ন archive, SIEM, real-time processing

Log বাইরে নেওয়া: subscription নাকি export

News portal-কে বছরের পর বছর S3-এ log রাখতে হবে। Subscription filter কয়েক সেকেন্ড বা মিনিটে log বাইরে পাঠায়; export task একটা সময়ের অংশ batch হিসেবে copy করে, যেটা কয়েক ঘণ্টা পিছিয়ে থাকতে পারে।

পরিস্থিতি

Subscription filter মিলে যাওয়া event ঢোকার সাথে সাথেই Kinesis Data Streams, Firehose, Lambda বা OpenSearch-এ পাঠায়। একটা log group-এ সর্বোচ্চ ৫টা।

Log group/news/appsubscription filter
Firehosebuffer, gzip
Lambdaনিজস্ব processing
Archive bucketnews-logs-example
ধাপ 1 / 4
1

Team একটা Firehose stream বানায় যেটা archive bucket-এ লেখে, আর একটা IAM role, যেটা CloudWatch Logs-কে Firehose-এ record ঢোকানোর অনুমতি দেয়। তারপর log group-এ একটা subscription filter যোগ করে, ফাঁকা pattern দিয়ে, মানে সব event।

#অনেক account আর Region থেকে log জড়ো করা

বড় প্রতিষ্ঠান প্রতিটা application আলাদা AWS account-এ রাখে (লেসন ২০.১)। তখন security team চায় সবগুলোর log আলাদা একটা log-archive account-এ যাক: খোঁজার জন্য এক জায়গা, আর এমন জায়গা যেখানে application team হাত দিতে পারবে না।

চেনা পথটা হলো cross-account subscription:

  1. Archive account-এ গ্রহণের দিক বানাও

    একটা Kinesis data stream (বা Firehose stream) বানাও, আর একটা IAM role, যেটা CloudWatch Logs নিতে পারে আর যাতে stream-এ record ঢোকানোর অনুমতি আছে।

  2. একটা destination বানাও

    একটা CloudWatch Logs destination (PutDestination) হলো নাম দেওয়া একটা প্রবেশপথ, যেটা stream আর role-কে মুড়ে রাখে। এর সাথে একটা destination access policy জোড়ো, যেটা বলে কোন কোন source account subscribe করতে পারবে, বা organization ID-র condition দিয়ে পুরো organization-কে অনুমতি দেয়।

  3. প্রতিটা source account থেকে subscribe করো

    প্রতিটা source account-এ log group-এর ওপর একটা subscription filter বানাও, যার লক্ষ্য destination-এর ARN। Source account কখনো stream-এ সরাসরি ঢুকতে পারে না।

  4. পৌঁছে দাও আর জমা রাখো

    Archive account-এ Kinesis Data Streams → Firehose → S3 (আর stream-এর ওপর যেকোনো real-time consumer)। Bucket-কে Object Lock আর কড়া bucket policy দিয়ে রক্ষা করো (লেসন ১০.৯)।

দুটো নিয়ম: log group আর destination-কে একই Region-এ থাকতে হয়, তাই প্রতিটা source Region-এ একটা করে destination বানাতে হয়; তবে destination-এর পেছনের resource (stream) অন্য Region-এ থাকতে পারে। Destination সরাসরি একটা Firehose stream-কেও মুড়ে রাখতে পারে, আর Lambda-ও cross-account লক্ষ্য হতে পারে।

সব account-এর log এক archive account-এ

একটা bank প্রতিটা application আলাদা AWS account-এ রাখে। Security team চায় সবগুলোর log, ঘটার সাথে সাথে, আলাদা একটা log-archive account-এ যাক, যেটা application team-রা ছুঁতেও পারবে না।

পরিস্থিতি

Subscription filter (source) → access policy-সহ destination (archive) → Kinesis Data Streams → Firehose → S3।

Source account
Log archive444455556666
Payments log111122223333
Cards log777788889999
Destination+ access policy
Kinesis Data Streams
Firehose
Central bucketObject Lock
ধাপ 1 / 6
1

Log-archive account-এ team গ্রহণ করার দিকটা বানায়: একটা Kinesis data stream, একটা IAM role যেটা CloudWatch Logs নিয়ে stream-এ record ঢোকাতে পারে, আর একটা CloudWatch Logs destination, যেটা stream আর role-কে একসাথে মুড়ে রাখে।

#Agent: unified CloudWatch agent

EC2 instance আর on-premises server-এ log file পাঠাতে, আর শুধু operating system যা জানে তা জানাতে, OS-এর ভেতরে একটা software লাগে। এমন agent দুটো ছিল:

CloudWatch Logs agent (পুরোনো)Unified CloudWatch agent
অবস্থাDeprecated, আর সুপারিশ করা হয় না; IMDSv2 সমর্থন করে না; Amazon Linux 2023 থেকে বাদচালু, সুপারিশ করা
কী পাঠায়শুধু logLog আর metric দুটোই
System metricনেইMemory, ব্যবহৃত disk-এর জায়গা, swap, CPU-র খুঁটিনাটি, disk I/O, netstat (TCP/UDP connection), process
Operating systemশুধু LinuxLinux, Windows Server আর macOS
কোথায় চলেEC2 আর on-premises Linux serverEC2 আর on-premises server (hybrid)
Configurationপ্রতিটা server-এ একটা local config fileJSON config, কেন্দ্রীয়ভাবে SSM Parameter Store-এ রাখা, প্রতিটা server সেখান থেকে আনে
বাড়তিকিছু নাStatsD আর collectd-এর custom metric, procstat দিয়ে process-প্রতি metric, X-Ray-তে trace

Unified agent যে metric যোগ করে (default-এ CWAgent namespace-এ):

  • CPU: active, idle, guest, system, user, steal… অবস্থায় কাটানো সময়।
  • Disk: খালি, ব্যবহৃত, ব্যবহৃত শতাংশ, মোট; আর disk I/O: read, write, byte, IOPS।
  • Memory (RAM): খালি, ব্যবহৃত, ব্যবহৃত শতাংশ, cached, inactive, মোট।
  • Netstat: অবস্থা ধরে TCP connection আর UDP socket-এর সংখ্যা; network packet আর byte।
  • Process: মোট, running, sleeping, blocked, idle, dead (আর procstat দিয়ে প্রতিটা process-এর CPU আর memory)।
  • Swap: খালি, ব্যবহৃত, ব্যবহৃত শতাংশ।

তুলনা করো EC2-এর নিজের metric-এর সাথে, যেগুলো আসে hypervisor থেকে, guest operating system-এর বাইরে থেকে: CPU utilisation, network-এ ঢোকা আর বের হওয়া, instance store-এর disk operation, আর status check। Memory আর ব্যবহৃত disk-এর জায়গা এর মধ্যে নেই (লেসন ১৯.১)।

অনুমতি।

  • EC2-তে: AWS managed policy CloudWatchAgentServerPolicy-সহ একটা instance role লাগাও (এটা metric আর log লিখতে আর AmazonCloudWatch-* parameter পড়তে দেয়)। Disk-এ কোনো key রাখতে হয় না। Role পড়েছ লেসন ২.৪-এ।
  • On-premises-এ কোনো instance role নেই। Agent একটা shared credentials file-এর নির্দিষ্ট profile (default নাম AmazonCloudWatchAgent) থেকে credential পড়ে: একই policy-সহ একটা IAM user-এর access key, বা আরও ভালো, IAM Roles Anywhere দিয়ে নিয়মিত নতুন হওয়া স্বল্পমেয়াদি credential। Server-এর AWS পর্যন্ত একটা network পথও লাগে (internet, VPN বা Direct Connect)।

কেন্দ্রীয় configuration। Config একবার বানাও (agent-এর wizard লিখে দেয়), Parameter Store-এ AmazonCloudWatch-linux নামে রাখো, আর প্রতিটা server চালায় amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c ssm:AmazonCloudWatch-linux -s (on-premises-এ -m onPremise)। Systems Manager পুরো বহরে agent বসিয়ে configure করে দিতে পারে (লেসন ২৫.৩)। দরকারি log group আর stream agent নিজেই বানায়।

EC2 আর on-premises-এ unified CloudWatch agent

News portal-এর web server চলে EC2-তে, আর পুরোনো printing system চলে তেজগাঁওয়ের একটা data centre-এর server-এ। একটাই agent, Parameter Store-এ একটাই shared config, দুই জায়গা থেকেই log আর memory metric।

পরিস্থিতি

Agent server policy-সহ instance role → Parameter Store থেকে config আনা → log আর system metric পাঠানো।

Data centre
VPC
Print serveragent + key
Web serveragent + rolerole লাগানো
Parameter Storeagent config
CloudWatchlog + metric
ধাপ 1 / 4
1

Web server-এ amazon-cloudwatch-agent package বসানো (প্রায়ই Systems Manager দিয়ে), আর আছে একটা instance role, যাতে agent server-এর AWS managed policy লাগানো; সেটা log আর metric লিখতে আর config parameter পড়তে দেয়।

#আরও কয়েকটা জানার মতো feature

#কোন দরকারে কোন feature?

এই log কোথায় যাবে?

একটা পরিস্থিতি বেছে নাও, কোন CloudWatch Logs feature ব্যবহার করবে বেছে নাও, তারপর কারণটা পড়ো। Keyword-গুলো খেয়াল করো: alert, একবারের, নিরবচ্ছিন্ন, প্রতিটা event, search, অন্য account, অতীত, এই মুহূর্ত, সংবেদনশীল, memory।

১. একটা পরিস্থিতি বেছে নাও(প্রথমবারেই ঠিক: 0/10)

একটা wallet কোম্পানি চায়, API log-এ এক মিনিটে পাঁচটার বেশি payment_failed লাইন দেখা দিলেই এক মিনিটের মধ্যে on-call engineer-এর ফোন বেজে উঠুক।

২. তোমার উত্তর

প্রশ্নে বলা আছেউত্তর
Log-এ keyword বা error এলেই alertMetric filter → metric → alarm → SNS
জমা log গোনা বা বিশ্লেষণ, top N, হঠাৎ দরকারLogs Insights
Deployment-এর সময় log live দেখাLive Tail
Real time-এ S3, OpenSearch, Splunk, Lambda, Kinesis-এSubscription filter (S3 আর partner-এর জন্য Firehose-সহ)
পুরোনো log একবার S3-এ export, real time নাExport task (CreateExportTask)
অনেক account আর Region-এর log এক জায়গায়Cross-account destination + Kinesis Data Streams + Firehose + S3
EC2-এর memory বা disk-এর জায়গা; on-premises-এর log আর metricUnified CloudWatch agent
কালেভদ্রে query-র জন্য সস্তায় log রাখাInfrequent Access (Essentials) class, বা S3-এ archive
Log-এ সংবেদনশীল data লুকানোData protection policy

#কোথায় কোথায় ভুল হয়

  • Instance থেকে log আসে না: agent নেই, agent বন্ধ, instance role নেই বা policy ভুল, config-এ ভুল Region, ভুল file path। কোনটা, তা বলে দেয় instance-এর ভেতরে agent-এর নিজের log।
  • Log উধাও: retention মুছে দিয়েছে; বা log group-টাই মুছে ফেলা হয়েছে। পরে লাগতে পারে এমন সবকিছুর archive S3-এ রাখো, আর deletion protection চালু রাখো।
  • বিশাল bill: retention Never Expire-এ পড়ে আছে, debug log পুরো দামে ঢুকছে, বা কয়েক মাসের data জুড়ে Logs Insights query। Retention দাও, কম log লেখো, কালেভদ্রে পড়া log-এর জন্য সস্তা class নাও, query-র পরিসর ছোট করো।
  • অতীতের error-এর জন্য metric ফাঁকা: metric filter শুধু নতুন event গোনে। অতীত খোঁজো Logs Insights দিয়ে।
  • রাতে alarm insufficient data-য়: metric filter-এর default value নেই; কিছু না মিললে 0 publish করাও।
  • Log পড়া যায় না: customer managed KMS key বন্ধ করা হয়েছে, তার policy বদলেছে, বা মোছার জন্য schedule করা হয়েছে।
  • Subscription পাঠানো বন্ধ করেছে: গন্তব্য throttle করছে (Lambda concurrency, Kinesis shard কম), আর ২৪ ঘণ্টা চেষ্টার পরে event বাদ পড়ছে; বা role তার অনুমতি হারিয়েছে। Delivery metric-এ চোখ রাখো।
  • অন্তহীন চক্র আর bill: account-level subscription নিজের Lambda বা Firehose-এর log group-কেও subscribe করেছে। ওই log group-গুলো বাদ দাও।
  • Cross-account subscription প্রত্যাখ্যাত: source account destination access policy-তে নেই, বা destination অন্য Region-এ।
  • Export-এ শেষের কয়েক ঘণ্টা নেই: data export করার মতো হতে ১২ ঘণ্টা পর্যন্ত লাগে; আর দ্বিতীয় export প্রথমটার পেছনে অপেক্ষা করে।
  • Subscription বা metric filter যোগ করা যায় না: group Infrequent Access (Essentials) class-এ, যেটা বদলানো যায় না।
  • Log-এ গোপন তথ্য: debug code password বা card নম্বর ছাপছে। Code ঠিক করো, একটা data protection policy দাও, আর কে group পড়তে পারবে তা সীমিত করো।

#System design-এ CloudWatch Logs

  • Observability-র ভিত্তি: প্রতিটা service component-প্রতি একটা log group-এ structured JSON log লেখে, retention ঠিক হয় infrastructure code দিয়ে, জরুরি error-এর জন্য metric filter, আর SNS-এ alarm। Dashboard সেই metric-এর সাথে Logs Insights widget মিলিয়ে দেখায়।
  • Security আর compliance archive: subscription filter (বা centralization rule) প্রতিটা account-এর log একটা log-archive account-এ পাঠায়; Firehose lifecycle rule-সহ একটা Object Lock bucket-এ লেখে; তদন্তে কয়েক বছরের data লাগলে Athena archive-এ query চালায় (লেসন ১৭.১)।
  • Real-time ধরা: Kinesis Data Streams-এ subscription, যেটা একটা SIEM বা Lambda detector-কে খাওয়ায়; CloudWatch Logs-এ VPC Flow Logs আর CloudTrail, প্রত্যাখ্যাত traffic বা root login-এর জন্য metric filter-সহ (লেসন ১৯.৬ আর ২১.৭)।
  • Hybrid ব্যবস্থা: EC2 আর on-premises server-এ unified agent, Parameter Store-এ একটাই config, দুইয়ের জন্য একই dashboard।
  • খরচ নিয়ন্ত্রণ: debug log-এর জন্য সস্তা class, ছোট retention আর সাথে S3 archive, খুব বেশি কথা বলা service-এর log-এর নমুনা (sampling)।

আর কোথায় খুঁজবে: performance graph হলো metric (১৯.১), container আর Lambda-র গভীর ছবি Insights পরিবারে (লেসন ১৯.৪), কে কোন API call করেছে সেটা CloudTrail (১৯.৬), আর CloudWatch, CloudTrail আর Config-এর পুরো তুলনা লেসন ১৯.৭-এ।

#নিজে করে দেখো

এই command-গুলো ap-southeast-1-এ AWS CLI v2 দিয়ে চলে। Ingestion, storage, query আর Live Tail-এ সামান্য খরচ হয়; শেষে সব মুছে ফেলো।

# 1. A log group with 30-day retention, and a test event
aws logs create-log-group --log-group-name /wallet/api
aws logs put-retention-policy --log-group-name /wallet/api --retention-in-days 30
aws logs create-log-stream --log-group-name /wallet/api --log-stream-name test-1
aws logs put-log-events --log-group-name /wallet/api --log-stream-name test-1 \
  --log-events "timestamp=$(date +%s000),message={\"level\":\"error\",\"path\":\"/send-money\",\"status\":502}"
# { "nextSequenceToken": "49654...", "rejectedLogEventsInfo": null }

# 2. A metric filter that counts error lines, with 0 when nothing matches
aws logs put-metric-filter --log-group-name /wallet/api --filter-name payment-errors \
  --filter-pattern '{ $.level = "error" }' \
  --metric-transformations metricName=PaymentErrors,metricNamespace=Wallet,metricValue=1,defaultValue=0
aws logs test-metric-filter --filter-pattern '{ $.level = "error" }' \
  --log-event-messages '{"level":"error","status":502}' '{"level":"info","status":200}'
# { "matches": [ { "eventNumber": 1, "eventMessage": "{\"level\":\"error\",\"status\":502}", ... } ] }

# 3. A Logs Insights query over the last hour
QID=$(aws logs start-query --log-group-name /wallet/api \
  --start-time $(date -d '-1 hour' +%s) --end-time $(date +%s) \
  --query-string 'filter level = "error" | stats count(*) as errors by bin(5m)' \
  --query queryId --output text)
aws logs get-query-results --query-id "$QID"
# { "status": "Complete", "statistics": { "recordsMatched": 1.0, "recordsScanned": 1.0, "bytesScanned": 78.0 },
#   "results": [ [ { "field": "bin(5m)", "value": "2026-11-01 09:15:00.000" }, { "field": "errors", "value": "1" } ] ] }

# 4. Live Tail for 5 minutes, highlighting errors (Ctrl+C to stop)
aws logs start-live-tail \
  --log-group-identifiers arn:aws:logs:ap-southeast-1:111122223333:log-group:/wallet/api \
  --log-event-filter-pattern '{ $.level = "error" }'

# 5. Export yesterday to S3 (bucket policy must allow logs.ap-southeast-1.amazonaws.com)
aws logs create-export-task --task-name wallet-2026-10-31 --log-group-name /wallet/api \
  --from 1761868800000 --to 1761955200000 \
  --destination wallet-logs-archive-example --destination-prefix exports/2026-10-31
# { "taskId": "c2a1f6d8-5b9e-4e1a-9a4f-0e7d2b3c4f51" }
aws logs describe-export-tasks --task-id c2a1f6d8-5b9e-4e1a-9a4f-0e7d2b3c4f51 --query 'exportTasks[0].status'
# { "code": "COMPLETED", "message": "Completed successfully" }

# 6. Real-time subscription to an existing Firehose stream (role lets logs put records)
aws logs put-subscription-filter --log-group-name /wallet/api --filter-name to-firehose \
  --filter-pattern '' \
  --destination-arn arn:aws:firehose:ap-southeast-1:111122223333:deliverystream/wallet-logs \
  --role-arn arn:aws:iam::111122223333:role/CWLtoFirehoseRole

# 7. Cross-account: in the archive account 444455556666, a destination and its access policy
aws logs put-destination --destination-name org-logs \
  --target-arn arn:aws:kinesis:ap-southeast-1:444455556666:stream/org-logs \
  --role-arn arn:aws:iam::444455556666:role/CWLtoKinesisRole
aws logs put-destination-policy --destination-name org-logs --access-policy '{
  "Version": "2012-10-17",
  "Statement": [{ "Effect": "Allow", "Principal": { "AWS": ["111122223333", "777788889999"] },
    "Action": "logs:PutSubscriptionFilter",
    "Resource": "arn:aws:logs:ap-southeast-1:444455556666:destination:org-logs" }] }'
#    ... and in each source account:
aws logs put-subscription-filter --log-group-name /wallet/api --filter-name to-archive --filter-pattern '' \
  --destination-arn arn:aws:logs:ap-southeast-1:444455556666:destination:org-logs

# 8. Unified agent on EC2 (instance role with CloudWatchAgentServerPolicy), config from Parameter Store
sudo dnf install -y amazon-cloudwatch-agent
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
  -a fetch-config -m ec2 -c ssm:AmazonCloudWatch-linux -s
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a status
# { "status": "running", "starttime": "2026-11-01T09:20:11+00:00", "configstatus": "configured", "version": "1.300..." }

# 9. Clean up
aws logs delete-subscription-filter --log-group-name /wallet/api --filter-name to-firehose
aws logs delete-log-group --log-group-name /wallet/api

Console-এও চেষ্টা করো: Logs Insights খোলো, একটা Lambda log group বেছে সবচেয়ে দামি invocation খোঁজার নমুনা query-টা চালাও; তারপর একই group-এ Live Tail খুলে function-টা invoke করো।

#সারসংক্ষেপ

মূল কথা

  • Log event (message + timestamp) → log stream (একটা source, ক্রমে) → log group (setting: retention, KMS key, access, log class)। Retention ১ দিন থেকে ১০ বছর, default Never Expire।
  • Log সবসময় at rest encrypt থাকে; চাইলে group-এর সাথে একটা customer managed KMS key জুড়ে দাও (key হারালে log-ও হারাবে)।
  • Source: SDK, agent, Beanstalk, ECS, Lambda, VPC Flow Logs, API Gateway, CloudTrail, Route 53 আর আরও। Agent আর IAM permission ছাড়া EC2 instance থেকে কিছুই বের হয় না।
  • Metric filter মিলে যাওয়া লাইনকে metric বানায়, শুধু নতুন event-এর জন্য; পরীক্ষার শিকল: log → metric filter → metric → alarm → SNS।
  • Logs Insights: জমা log-এ query (নিজস্ব ভাষা, OpenSearch PPL, OpenSearch SQL), scan করা GB ধরে দাম, real time না। Live Tail: এই মুহূর্তের নতুন log দেখা।
  • Export task (CreateExportTask) → S3, batch, ১২ ঘণ্টা পর্যন্ত পিছিয়ে, একটা সক্রিয় task। Subscription filter → Kinesis Data Streams, Data Firehose, Lambda, OpenSearch, real time, log group-প্রতি ৫টা, সাথে account-level filter।
  • অনেক account / অনেক Region: subscription filter → access policy-সহ destination (একই Region) → Kinesis Data Streams → Firehose → log-archive account-এর S3। নতুন: centralization rule, cross-account observability।
  • Unified CloudWatch agent (log + memory, disk, swap, netstat, process; Linux, Windows, macOS; EC2 আর on-premises; config SSM Parameter Store-এ) deprecated CloudWatch Logs agent-এর জায়গা নিয়েছে। EC2-তে CloudWatchAgentServerPolicy-সহ role লাগে; on-premises-এ লাগে credential।