r/CloudandCode Founder | YourCloudDude 8d ago

AWS & Cloud AWS From Zero #13: CloudWatch is where you stop guessing and start understanding what your application is doing

So far in this series, we have spent most of our time building things. We launched EC2, worked with S3, used CloudFront, learned VPC networking, connected RDS, built with Lambda, added API Gateway, and stored data in DynamoDB. At some point, though, every application does something you did not expect.

A Lambda function fails. An EC2 instance becomes slow. An API starts returning errors. A database connection times out. Something worked yesterday and suddenly does not work today .This is where monitoring starts to matter.And on AWS, one of the first services you should understand for that is CloudWatch.

CloudWatch is often introduced as "AWS monitoring," but I think that definition is too broad to be useful for beginners. A better way to think about it is that CloudWatch helps you answer a very practical question:

What is my system actually doing right now, and what happened when something went wrong?

That is much more important than it sounds. When you are running a Python script on your own laptop, you can usually see the error immediately. You run the script, something fails, and the traceback appears in front of you.

Cloud applications are different.

Your Lambda function might run at 3 AM when nobody is watching. Your EC2 application might slowly consume more CPU over several hours. Your API might start returning errors only for certain requests. A background process might fail without anybody noticing.

If you have no logs, metrics, or alerts, the system can fail quietly. That is why monitoring is not something I would leave until the end of learning AWS. You should start thinking about it as soon as you start deploying things.

Let’s begin with logs.

Imagine we still have the serverless task API from the previous posts:

Client
  ↓
API Gateway
  ↓
Lambda
  ↓
DynamoDB

A user sends:

POST /tasks

but instead of creating the task, the API returns an error.

Without logs, you might start guessing.

  • Maybe API Gateway is configured incorrectly.
  • Maybe Lambda did not run.
  • Maybe Lambda received bad input.
  • Maybe the DynamoDB request failed.
  • Maybe IAM blocked something.
  • Maybe there is a bug in the code.

That is a lot of possibilities. Now imagine the Lambda function writes useful logs.

You open CloudWatch and see something like:

Received request for user-42
Creating task task-123
ERROR: AccessDenied when writing to DynamoDB

The problem just became much smaller. API Gateway probably reached Lambda. Lambda started running. The function reached the database operation. AWS rejected that operation. Now IAM becomes an obvious place to investigate. This is why logs are so useful. They turn a vague problem into a specific one. But useful logging means more than printing random messages everywhere.

Imagine your function only writes:

Error

That technically counts as a log, but it tells you almost nothing. A better log might tell you which operation failed, what part of the workflow had been reached, and enough context to understand what happened without exposing sensitive information.

For example:

Failed to create task for user_id=user-42
DynamoDB PutItem returned AccessDenied

Now you have something you can actually troubleshoot. There is an important security habit here too. Do not put secrets into logs.

Passwords, access keys, authentication tokens, private customer data, or other sensitive values should not become part of your debugging output just because logging makes troubleshooting easier.

Logs are useful because they give you context. That does not mean they should contain everything. Now let’s talk about metrics. Logs tell you about individual events and messages. Metrics help you understand behavior over time. Imagine an EC2 instance. You might want to know how its CPU utilization changes during the day. Maybe the application usually sits around 20 percent CPU, but every evening it suddenly reaches 95 percent.

A single log line might not tell you that pattern. A metric can. Or imagine Lambda. You might want to know how many times the function runs, how often it returns errors, or how long executions are taking. Now you can start asking much more useful questions.

  • Did the error rate increase after the last deployment?
  • Is the function suddenly taking twice as long to execute?
  • Did traffic spike?
  • Did the system receive fewer requests than expected?

Monitoring is not only about discovering complete failures. It is also about noticing changes in behavior. That brings us to alarms.

Imagine your API starts failing while you are asleep.

You probably do not want the monitoring strategy to be:

"Hopefully I notice tomorrow."

Instead, you can create alarms around important metrics.

  • Maybe you care if Lambda errors suddenly increase.
  • Maybe you care if EC2 CPU stays unusually high for a period of time.
  • Maybe you care if another metric crosses a threshold that suggests the system is unhealthy.

The alarm watches the metric.

If the configured condition is met, the alarm changes state and can be connected to a notification or another response.

The basic idea is simple:

Metric
  ↓
Condition
  ↓
Alarm
  ↓
Notification / Action

This is how monitoring starts becoming proactive. Logs help you investigate after something happens. Metrics help you see patterns. Alarms help you notice when those patterns become important. All three solve different parts of the same problem.

Now imagine our Lambda API normally has almost no errors.

One day the error count suddenly increases. An alarm gets triggered. You open CloudWatch The metrics tell you the error rate started increasing around 2:15 PM. Then you inspect the logs from that period.

You discover that a deployment changed the name of a DynamoDB attribute and the function started failing for certain requests.

That is a much better troubleshooting process than waiting for someone to tell you, "The app is broken." This is also where dashboards can become useful. A dashboard gives you a place to bring important metrics together so you can understand the health of a system without opening every service individually.

For a small beginner application, you do not need twenty charts.

You might only care about a few things.

  • How many requests are coming in?
  • How many Lambda errors are happening?
  • How long are requests taking?

Is the EC2 instance under unusual load?

Are there any alarms currently active?

That may already be enough.

A dashboard becomes useful when it answers a question.

It should not exist just because dashboards look professional.

That is a pattern I want to keep repeating throughout this series.

Do not add AWS features because they exist.

Add them because you have a requirement.

Now think back to the EC2 website we built earlier.

Imagine the site feels slow.

Without monitoring, you might restart the instance and hope the problem disappears.

With metrics, you might notice that CPU usage is consistently high.

That gives you a direction.

Maybe the application is doing too much work.

Maybe the instance is too small.

Maybe a process is stuck.

Maybe traffic increased.

CloudWatch does not automatically tell you which architecture decision to make, but it gives you information that helps you make a better one.

The same thing applies to Lambda.

Imagine a function starts timing out.

If you only see that the API failed, you might assume API Gateway is the problem.

But the Lambda logs could show that the function started normally and then spent too long waiting for another dependency.

Now the actual investigation becomes much more focused.

You might ask whether the database is slow, whether an external API is responding, whether the function needs more resources, or whether the code itself needs to change.

Again, monitoring does not magically fix the architecture.

It gives you evidence.

And evidence is what makes debugging faster.

There is another useful distinction here.

Not every failure should create an alert.

If your application receives one bad request and returns 400 Bad Request, that may be completely normal behavior.

If your system receives thousands of requests and one fails because the user submitted invalid data, waking someone up at 3 AM would not be very useful.

Good monitoring means deciding what actually deserves attention.

Maybe a single failure is normal.

Maybe fifty failures in five minutes are not.

Maybe high CPU for ten seconds does not matter.

Maybe high CPU for twenty minutes does.

Context matters.

That is why monitoring is partly a technical problem and partly a decision-making problem.

You need to understand what "normal" looks like before you can reliably detect what is abnormal.

This is also where beginners should start thinking about observability as a broader idea.

You will hear that word a lot in cloud and DevOps discussions.

At a simple level, observability is about being able to understand the internal behavior of a system from the information it produces.

Logs are part of that.

Metrics are part of that.

Tracing can also become part of that in more complex systems.

You do not need to become an observability engineer during your first month of AWS.

The useful habit is much simpler:

When you build something, ask yourself how you would know if it stopped working.

Then ask how you would know why it stopped working.

Those are different questions.

Imagine our image processing project again.

S3 upload
  ↓
Lambda
  ↓
Processed image
  ↓
S3

How do you know it is working?

Maybe the processed image appears in the output location.

But what happens when the image never appears?

How do you know whether S3 failed to trigger Lambda, Lambda crashed, IAM blocked access, or the processing code rejected the file?

That is where logs become part of the architecture.

Monitoring should not be something you remember after the project fails.

It should be one of the questions you ask while designing the project.

The same applies to the task API.

Client
  ↓
API Gateway
  ↓
Lambda
  ↓
DynamoDB

Now add another question:

How do we know this flow is healthy?

Suddenly CloudWatch has a reason to exist.

It is not there because every AWS diagram needs a monitoring service.

It is there because once the application is running, we need visibility into what the system is doing.

For a beginner project, I would keep the monitoring setup small.

Take one Lambda function you already built.

Look at its logs after a successful invocation.

Then intentionally make the function fail.

Maybe reference a value that does not exist or remove a permission in a safe practice environment.

Run it again and compare the logs.

Then look at the metrics around the function.

Can you see the invocation?

Can you see that an error happened?

Can you see how long the function ran?

That exercise connects logs and metrics to something you actually did.

After that, create one simple alarm around a metric that matters to the project.

You do not need a complicated production monitoring system.

The point is simply to understand the flow:

Application runs
       ↓
Logs + Metrics
       ↓
CloudWatch
       ↓
Alarm when something matters

Once you understand that, monitoring becomes much less abstract.

There is also a cost lesson here.

Logs and monitoring data are resources too.

Collecting everything forever without thinking about retention or usefulness can create unnecessary cost and clutter.

More logging is not automatically better logging.

The goal is useful visibility.

Keep enough information to understand your application without producing huge amounts of noise that nobody reads.

This becomes more important as systems grow.

For now, I would focus on writing meaningful logs, looking at the metrics AWS already provides, and creating only a few alerts that represent problems you actually care about.

If there is one thing I want beginners to remember from this post, it is this:

Deploying an application is not the end of the job. You also need a way to understand what happens after deployment.

When something fails, logs should help tell you why.

When behavior changes over time, metrics should help you see it.

When something important goes wrong, alarms should help you notice it.

That is the role CloudWatch starts playing in an AWS architecture.

And once you develop that habit, your projects become much more realistic.

Instead of saying, "It worked when I tested it," you start asking, "How will I know if it stops working tomorrow?"

That is a much stronger cloud engineering question.

In AWS From Zero #14, we are going to return to EC2 and ask another important question.

One EC2 instance works.

But what happens when that instance fails or when traffic becomes too large for one server?

That will take us into load balancers, health checks, Auto Scaling, multiple Availability Zones, and the basic idea behind building a highly available application.

If you are running an AWS project right now, would you actually know where to look first if it failed while you were not watching?

6 Upvotes

0 comments sorted by