When people say they want to “search in CloudWatch”, what they usually need is CloudWatch Logs Insights.

It is much more useful than manually opening individual log streams because you can search across log groups, combine conditions, sort by timestamp, and limit results quickly.

That said, AWS also has the basic log search interface inside a log group. If you select all streams and search there, the syntax is different. It uses filter patterns, not Logs Insights query language.

If your goal is to find log lines:

  1. containing str1 and str2
  2. containing str1 but not str2

then Logs Insights is the right tool.

Open CloudWatch Logs Insights

In the AWS Console:

  1. Open CloudWatch
  2. Go to Logs Insights
  3. Select the relevant log group or log groups
  4. Choose the time range carefully
  5. Run a query

The time range matters a lot. If you search a huge time window, the query becomes slower and scans more data.

Basic Query Shape

Most searches start with something like this:

fields @timestamp, @message
| sort @timestamp desc
| limit 100

This simply shows recent log lines.

From there, add a filter clause.

1. Search Log Lines Containing str1 and str2

Use:

fields @timestamp, @message
| filter @message like /str1/ and @message like /str2/
| sort @timestamp desc
| limit 100

This returns only log lines where both strings appear in the same log event.

Example:

fields @timestamp, @message
| filter @message like /payment/ and @message like /failed/
| sort @timestamp desc
| limit 100

This is useful for cases like:

  • order and timeout
  • exception and userId
  • payment and failed

2. Search Log Lines Containing str1 but Not str2

Use:

fields @timestamp, @message
| filter @message like /str1/ and @message not like /str2/
| sort @timestamp desc
| limit 100

Example:

fields @timestamp, @message
| filter @message like /error/ and @message not like /timeout/
| sort @timestamp desc
| limit 100

This is helpful when one keyword is too broad and you want to remove noisy results.

3. Search for Either str1 or str2

Sometimes you want either term instead of both:

fields @timestamp, @message
| filter @message like /str1/ or @message like /str2/
| sort @timestamp desc
| limit 100

Example:

fields @timestamp, @message
| filter @message like /error/ or @message like /exception/
| sort @timestamp desc
| limit 100

4. Search for an Exact Phrase

If the thing you want is a phrase, search that phrase directly:

fields @timestamp, @message
| filter @message like /connection refused/
| sort @timestamp desc
| limit 100

This is often better than searching individual words separately when the message format is stable.

If your logs may contain Error, ERROR, or error, use a case-insensitive regex:

fields @timestamp, @message
| filter @message like /(?i)error/
| sort @timestamp desc
| limit 100

This avoids missing matches because of letter casing.

6. Search Structured Fields Instead of Raw Message Text

If your logs are structured and fields are available, prefer filtering by fields instead of searching the whole @message.

Example:

fields @timestamp, level, service, requestId, @message
| filter level = "ERROR" and service = "payments"
| sort @timestamp desc
| limit 100

This is better than free-text search because:

  • it is more precise
  • it is easier to maintain
  • equality-based filters can be more efficient than like

7. Useful Additions While Debugging

Search by request ID

fields @timestamp, @message, requestId
| filter requestId = "abc-123"
| sort @timestamp desc
| limit 100

Find recent exceptions only

fields @timestamp, @message
| filter @message like /Exception/
| sort @timestamp desc
| limit 50

Exclude health checks or noisy endpoints

fields @timestamp, @message
| filter @message like /error/
| filter @message not like /health/
| filter @message not like /ready/
| sort @timestamp desc
| limit 100

8. Tips to Search CloudWatch Logs More Effectively

1. Always narrow the time range

This is the fastest way to reduce noise, query time, and scan volume.

2. Start with @message, then move to fields

If you do not yet know the structure of the logs, begin with:

fields @timestamp, @message
| sort @timestamp desc
| limit 20

Then identify useful fields like requestId, status, level, path, or service.

3. Use limit

When debugging, you usually do not need thousands of rows immediately.

| limit 50

is often enough.

4. Prefer exact field matches when possible

A query like:

| filter requestId = "abc-123"

is usually better than:

| filter @message like /abc-123/

because exact field filters are more targeted.

5. Use not like to remove noise

This is one of the most useful techniques in production debugging, especially when health checks, retries, or known warning messages flood the results.

If You Want to Use the Basic CloudWatch Log Search Interface

Sometimes you are already inside a log group and want to use the built-in search box after selecting all streams.

That works too, but the syntax is different from Logs Insights.

In the AWS Console:

  1. Open CloudWatch
  2. Go to Log groups
  3. Open the relevant log group
  4. Select all streams or choose Search log group
  5. Enter a filter pattern in the log events search box

Basic Interface Query Syntax

In the basic interface, unstructured text search uses filter patterns:

  • multiple terms separated by spaces mean AND
  • prefix a term with - to exclude it
  • wrap an exact phrase in double quotes
  • regex uses %...%

Do not paste Logs Insights queries like fields, filter, or sort into this box. They will not work there.

Basic Search: Contains str1 and str2

Use:

str1 str2

Example:

payment failed

This returns log events that contain both terms.

Basic Search: Contains str1 but Not str2

Use:

str1 -str2

Example:

error -timeout

This returns log events that contain error but exclude events that also contain timeout.

Basic Search: Exact Phrase

Use double quotes:

"connection refused"

This is useful when the phrase is stable and you do not want broad partial matches.

Basic Search: Regex

The basic interface also supports regex filter patterns using %:

%ERROR|Exception%

This can be useful for broader matching, but the regex support is more limited than what many developers expect, so keep patterns simple.

When to Use Basic Search vs Logs Insights

Use the basic interface when:

  • you are inspecting one log group quickly
  • you already know the time range
  • you want a fast text filter over selected streams

Use Logs Insights when:

  • you need richer queries
  • you want to combine conditions clearly
  • you want sorting, fields, parsing, or aggregations
  • you need to search across multiple log groups more effectively

Common Mistake

A common mistake is to mix the two CloudWatch search modes.

For Logs Insights, think in terms of:

  • filter
  • and
  • or
  • not like
  • exact field matches
  • sorting and limiting

For the basic search interface, think in terms of:

  • space-separated terms for AND
  • -term for exclusion
  • "exact phrase" for phrase search
  • %regex% for regex patterns

That is what makes CloudWatch log searches practical at scale.

Final Query Cheat Sheet

Contains str1 and str2

fields @timestamp, @message
| filter @message like /str1/ and @message like /str2/
| sort @timestamp desc
| limit 100

Contains str1 but not str2

fields @timestamp, @message
| filter @message like /str1/ and @message not like /str2/
| sort @timestamp desc
| limit 100

Basic interface: contains str1 and str2

str1 str2

Basic interface: contains str1 but not str2

str1 -str2

Contains str1 or str2

fields @timestamp, @message
| filter @message like /str1/ or @message like /str2/
| sort @timestamp desc
| limit 100

Conclusion

For most real-world debugging in AWS, the best way to search log lines is to use CloudWatch Logs Insights with filter conditions.

The two most useful patterns are:

  • like ... and like ...
  • like ... and not like ...

If you stay in the older log-group search interface after selecting all streams, use:

  • str1 str2
  • str1 -str2

Once you get comfortable with both modes, add or, exact phrases, case-insensitive matching, and structured-field filters to search much faster.