Stay Updated

Get the latest OpenObserve insights delivered to your inbox

By subscribing, you agree to receive product and marketing related updates from OpenObserve.

Table of Contents
log-searching-and-filtering-hero-image.png

Logs are the heartbeat of modern applications. They help you debug issues, monitor system health, and understand user behavior. But with massive volumes of logs generated every second, finding relevant information quickly becomes challenging. That’s where log searching and filtering come in.

In this blog, we’ll cover:

  • The fundamentals of log searching and filtering
  • Common techniques used across platforms
  • How OpenObserve enhances log exploration

What Logs Look Like

Before diving into searching and filtering, it’s important to understand what logs look like. Broadly, logs fall into two categories:

1. Structured Logs (e.g., JSON or key-value pairs)

Structured logs are machine-readable and contain clearly defined fields. For example:

{
  "timestamp": "2025-10-15T10:23:45Z",
  "service": "login",
  "level": "ERROR",
  "user_id": "12345",
  "message": "Failed login attempt"
}

Advantages:

  • Fields can be directly queried and filtered.
  • Easier to aggregate and visualize.

There are several structured log formats : JSON, key-value pairs, CSV-style lines, and even semi-structured formats generated by frameworks or log libraries. For simplicity and consistency, we’ll focus on JSON logs, since they’re the most common.

2. Unstructured Logs (Plain Text)

Unstructured logs are freeform text, often written by developers or applications without a defined schema:

2025-10-15 10:23:45 ERROR [login] User 12345 failed to login due to invalid password

Challenges:

  • Requires parsing or pattern matching for meaningful queries.
  • Harder to filter or aggregate automatically.

Searching and Filtering Strategies

Whether structured or unstructured, the goal of log searching is the same: find relevant information quickly. Filtering helps narrow down results to meaningful subsets.

Here’s a structured approach:

Time Based Filtering

Time is usually the first filter you apply when exploring logs. Filtering logs within a specific time range, e.g., last hour, day, or week is essential for isolating incidents and analyzing trends.

OpenObserve lets you filter logs by time directly from the UI, without any queries. You can choose predefined relative ranges (last 5 minutes, hour, 24 hours, 7 days) for real-time monitoring, or select custom start and end times for detailed analysis or audits.

Relative time based log filtering

Absolute time based log filtering

Field Based Filtering

Filtering logs by specific fields helps you zoom in on relevant information. Fields are attributes associated with logs, such as service name, log level, host, user ID, or custom tags.

  • In most platforms, structured logs (like JSON) make it easy to filter by fields.
  • For unstructured logs, fields may need to be extracted or parsed before filtering.

OpenObserve Approach:

  • OpenObserve automatically extracts fields from logs and lets you filter directly from the UI.

OpenObserve automatically extracts fields from logs

  • You can select a field (e.g., service=login or level=ERROR) and instantly see matching logs.

    Matching and filtering logs

  • Multiple fields can be combined to focus on specific services, severity levels, hosts, or users, making investigations faser and more precise. You can make use of AND and OR to combine multiple conditions.

Multiple condition based log Filtering

Besides categorical fields, numeric fields like status codes or response times can also be filtered using comparison operators. For numeric field comparison you can use statements like status_code = 200 , status_code > 399, status_code is null to filter out relevant data.

You can enable SQL mode and look for relevant fields and corresponding values using SQL queries. Enable SQL mode for query based filtering

Keyword and Pattern Searching

Keyword search is the simplest way to find relevant logs: just look for specific words, phrases, or patterns.Pattern search (using regex or wildcards) allows finding more complex matches, especially in unstructured logs.

OpenObserve Approach:

  • To find field specific keyword or string matches you can make use of str_match() function

Filtering logs using str_match function

Similarly there are a bunch of functions you can use to search for relevant keywords, check out the detailed documentation here.

Filtering logs using regex match function

  • Keyword and pattern searches can be combined with field and time filters to quickly locate logs relevant to a specific incident.

The type of log you’re dealing with influences how you search and filter. Structured logs allow direct field-based queries, while unstructured logs often require keyword or pattern searches. Regardless of the type, you can always apply time filters to narrow down your results.

OpenObserve Query Syntax Guide

Once you understand filtering basics, here’s how to express them in OpenObserve.

Note: These functions are for additional help; you can always use SQL queries directly to filter, match, or search logs as needed.

Basic Searches

Function Syntax Description Example
str_match str_match(field, 'value') Alias: match_field(field, 'value') Filters logs where the specified field contains the exact string (case-sensitive). SELECT * FROM "default" WHERE str_match(k8s_pod_name, 'main-openobserve-ingester-1')
str_match_ignore_case str_match_ignore_case(field, 'value') Alias: match_field_ignore_case(field, 'value') Filters logs where the field contains the string (case-insensitive). SELECT * FROM "default" WHERE str_match_ignore_case(k8s_pod_name, 'MAIN-OPENOBSERVE-INGESTER-1')
match_all match_all('value') Searches across all full-text indexed fields (case-insensitive). SELECT * FROM "default" WHERE match_all('openobserve-querier')
re_match re_match(field, 'pattern') Case-insensitive: re_match(field, '(?i)pattern') Filters logs by regex pattern. Useful for complex matches or multiple keywords. SELECT * FROM "default" WHERE re_match(k8s_container_name, 'openobserve-querier')
re_not_match re_not_match(field, 'pattern') Returns logs where the field does not match the regex pattern. SELECT * FROM "default" WHERE re_not_match(k8s_container_name, 'openobserve-querier')

Practical Debugging Examples

  • Find all 5xx errors in the payments service. Quickly identifies server-side failures affecting your payment API.
service='payments' AND code >= 500
  • Locate failed login attempts.Helps investigate authentication issues and potential security incidents.
service='login' AND message LIKE '%failed%'
  • Identify slow API responses (>2000ms). Highlights performance bottlenecks in your services.
service='api' AND response_time > 2000
  • Analyze payment service in staging environment:
match_all('staging') AND str_match(service, 'payments')
  • Exclude system containers from error analysis:
re_not_match(k8s_container_name, 'openobserve-querier|controller')

Search Around in Logs

When debugging, a single log line rarely tells the full story. You often need to see what happened before and after an error or warning to understand the root cause. That’s exactly what the Search Around feature in OpenObserve helps you do.

The Search Around feature retrieves log entries that were stored immediately before and after a selected record. Unlike filters or queries, it does not apply your original search conditions, this ensures you get the complete surrounding context as it appears in the backend storage.

Essentially, it helps you answer questions like:

  • “What happened right before this error?”
  • “Did any warnings appear just after this failure?”

How to Use Search Around

  1. Based on your search query, you can filter the records and expand on the target record. Locate the search around button at the bottom of the page: Search around logs feature in OpenObserve.png
  2. In the Number of events selector, choose how many records you want to retrieve in total, including the selected record and Click Search Around. Event selector for logs in search around feature For example, when you select 10, the result set contains 10 records in total, including the selected record. The split is 5 records before the selected record and 4 records after.

Log Aggregation

Once you’ve searched and filtered logs, the next step is aggregation, summarizing log data to uncover trends, patterns, and insights that individual log lines alone cannot reveal.

Why Aggregation Matters

  • Makes sense of large volumes of logs.
  • Helps identify spikes, anomalies, or repetitive issues.
  • Powers dashboards, alerts, and reports for operational visibility.

Common Aggregation Techniques

  1. Count & Group By

    • Count logs grouped by fields like service, level, or host.
    • Example: Find which service generated the most errors in the last 24 hours. Count and Group By function for Log Aggregation
  2. Time-Based Histograms

    • Bin logs over time intervals (minutes, hours, days) to visualize trends.
    • Example: Number of login errors per hour for the last week. Time based Histograms for log filtering
  3. Top-N Analysis

    • Identify top IP addresses, users, or endpoints causing errors.
    • Example: Top 10 endpoints returning HTTP 500 errors. Top N log Analysis in OpenObserve

OpenObserve Approach

  • SQL Mode: Aggregation queries are easy to write. Read detailed documentation here.
  • UI-Based Aggregation:
    • OpenObserve dashboards allow drag-and-drop aggregation on fields.
    • Time histograms, top values, and counts can be visualized without writing queries.
    • Combine with filters (time, field, keyword) to create focused analytics.

UI Based Log Aggregation and Dashboard Creation

Best Practices

  • Always apply filters before aggregation to avoid noisy or irrelevant results.
  • Use time bins appropriate for the volume of logs (e.g., hourly for high-volume services).
  • Combine field, keyword, and numeric filters to make aggregations actionable.

Saved Views

When you repeatedly search for similar patterns like login failures, 5xx errors, or latency spikes, Saved Views help you store and reuse those filters and queries.

With Saved Views, you can:

  • Save a search query or combination of filters for future use.
  • Reopen it anytime from the Saved Views section without rebuilding queries.
  • Share views across your team to ensure consistent troubleshooting.

Example: Save the query: service='payments' AND code>=500 as Payment Errors.

Next time you need to debug API issues, you can simply open this Saved View without recreating the query.

Creating saved views for Filtered logs

VRL Transformations: Enrich, Redact, and Customize Logs

Raw logs often need refinement before they can be effectively searched, filtered, or visualized. OpenObserve leverages VRL (Vector Remap Language), a flexible and powerful language designed to transform, enrich, and clean log data in real time during ingestion.

What is VRL?

VRL is a lightweight scripting language specifically for observability pipelines. It allows you to manipulate logs: extracting fields, modifying values, redacting sensitive information, and adding contextual metadata without changing the original log source.

Key Use Cases

  1. Enrichment : Add contextual information to logs to make them more actionable. For example:

    • Add service names, environment labels (staging, production), or host details.
    .environment = "staging"
    

    Using VRL for log updating

    • Generate derived fields like error categories, user regions, or request latency buckets.
  2. Redaction: Mask sensitive information like passwords, tokens, or PII before storing logs. This ensures compliance with privacy regulations. Sensetive Data Redaction in Logs Learn more about How to redact sensitive / PII data in your logs in detail.

  3. Field Transformation: Convert or normalize log fields for consistency across services: \

    • Change timestamps to a standard format.
    • Normalize status codes or log levels.
    • Concatenate fields to create a single, searchable identifier.

    Read about VRL Functions and Expressions.

4. Conditional Routing: You can also use VRL to tag or route logs based on certain conditions, making downstream analysis easier:

if .level == "ERROR" {
    .priority = "high"
} else if .level == "WARN" {
    .priority = "medium"
} else {
    .priority = "low"
}

Conclusion

Logs are the heartbeat of your applications, but finding what matters in a flood of data can be tricky. Understanding the difference between structured and unstructured logs helps you pick the right search and filter approach.

Time, field, and keyword-based filters let you zoom in on relevant events, and aggregation turns raw logs into insights you can act on. OpenObserve makes this easier by automatically extracting fields, supporting flexible searches, and letting you visualize trends all in one place.

By combining these techniques with good practices, you can investigate issues faster, reduce noise, and get a clearer picture of what’s happening in your systems.

Further Reads

Get Started with OpenObserve Today!

Sign up for a 14 day cloud trial. Check out our GitHub repository for self-hosting and contribution opportunities.

About the Author

Simran Kumari

Simran Kumari

LinkedIn

Passionate about observability, AI systems, and cloud-native tools. All in on DevOps and improving the developer experience.

Latest From Our Blogs

View all posts