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:
- containing
str1andstr2 - containing
str1but notstr2
then Logs Insights is the right tool.
Open CloudWatch Logs Insights
In the AWS Console:
- Open CloudWatch
- Go to Logs Insights
- Select the relevant log group or log groups
- Choose the time range carefully
- 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:
orderandtimeoutexceptionanduserIdpaymentandfailed
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.
5. Case-Insensitive Search
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:
- Open CloudWatch
- Go to Log groups
- Open the relevant log group
- Select all streams or choose Search log group
- 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:
filterandornot like- exact field matches
- sorting and limiting
For the basic search interface, think in terms of:
- space-separated terms for AND
-termfor 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 str2str1 -str2
Once you get comfortable with both modes, add or, exact phrases, case-insensitive matching, and structured-field filters to search much faster.