# FuseQL examples and use cases

## Sample log lines

The examples below are written against these five representative log lines. They cover the most common log shapes you encounter in practice — labeled key=value, structured JSON, free-form text, and delimited records.

**nginx access log**  
A typical web server access log written by nginx or similar reverse proxies. The fields `path`, `status`, and `duration_ms` are key=value **facets** embedded in the log body, distinct from the `source` **label** applied at ingestion.

```none
source="nginx" path=/api/orders status=503 duration_ms=842
```

**Java app log**  
A structured application log. `level` and `msg` are common label/facet names. `trace_id` links this log line to a distributed trace — useful for correlation across services.

```none
source="orders-service" level="ERROR" msg="Connection refused" trace_id=abc123
```

**Plain text key=value record**  
An unstructured log line where fields are embedded inline in `key=value` format. These fields are not indexed at ingestion — you must extract them with a `parse` operator at query time before you can aggregate or filter on them.

```none
source="payments" user_id=u123 amount=42.50 latency_ms=420
```

**JSON-structured log**  
A log line whose body is a pure JSON object. `source` is a **label** attached by the log shipper at ingestion — it is not part of the log body. `level`, `user.id`, and `http.status` are fields inside the JSON body. Use `| json "path"` with dot-notation to extract nested fields.

```none
{"level":"warn","user":{"id":"u123"},"http":{"status":500,"path":'/cart/checkout'}}
```

**Delimited record (used by `split` examples)**  
A comma-separated audit record with no field names. The raw log body is the CSV — `source` is a **label** attached at ingestion and is not included in `__kf_msg` (the raw message body). Columns are zero-indexed, so column 0 is the timestamp.

```none
2026-06-06T11:23Z,login,u123,success,10.0.0.7
```

## Filtering

Search filters appear **before** the first `|` in a FuseQL query. They narrow the set of log lines the pipeline operates on and are evaluated against the index — they do not scan raw log bodies. Filtering early is the single most effective way to keep queries fast.

Two types of fields are filterable before the pipe:

- **Labels** — metadata attached to each log line at ingestion time, such as `source`, `level`, `kube_namespace`. Use bare `name="value"` syntax.
- **Facets** — structured fields extracted from the log body at ingestion and indexed separately. Use `@name` syntax.

Fields that are only present in the raw log body text (like `user_id` in the [key=value](https://docs.kloudfuse.com/platform/latest/query-languages/fuseql/examples/#sample-kv) line) cannot be filtered before the pipe — extract them with `parse` first, then use `| where` to filter.

### Label equality and inequality

Labels are the most efficient filter. They are indexed at ingestion, so equality checks against them incur near-zero scan cost regardless of volume. Always start with a label filter (`source=`, `level=`, `kube_namespace=`) to scope the query before adding any pipe stages.

Match a source exactly — restricts all downstream pipe stages to nginx lines only:

```fuseql
source="nginx"
```

Exclude a label value. Returns every line in the query window **except** those from the orders-service:

```fuseql
source!="orders-service"
```

Combine multiple label filters on the same line — both conditions must be true (implicit `and`):

```fuseql
source="nginx" level="ERROR"
```

### Facet equality, range, and regex

Facets are structured fields extracted from the log body at ingestion. They support equality, numeric comparison, and regex. Use `@` prefix to reference a facet.

Exact match on a string facet — find all activity for a specific user:

```fuseql
@user_id="u123"
```

Numeric comparison — find slow requests or error responses. Useful for SLO burn-rate queries where you want only the lines that breach a threshold:

```fuseql
@status>=500
```

### Substring, prefix, and suffix

These operators match against field values using positional string checks. They are most useful when you know part of a value but not the full string — for example, filtering API paths by prefix or identifying error classes by suffix.

Substring contains (`**`) — matches any log line where the label `kube_deployment` contains the substring:

```fuseql
kube_deployment**"ingress-nginx"
```

Starts-with (`*~`) — restricts to paths under `/api`:

```fuseql
@path*~"/api"
```

Ends-with (`~*`) — matches any path ending with `/checkout`:

```fuseql
@path~*"/checkout"
```

### Free-text terms and grep

FuseQL has two free-text search operators that both scan the full log line — labels and raw message body — but work differently:

**Term search** (single quotes `'…'`) looks up complete tokens in an inverted index. It is fast and case-insensitive.

Term existence — matches any log line where `error` appears as a complete token:

```fuseql
'error'
```

Negated term — excludes any line containing the word `healthcheck`:

```fuseql
!'healthcheck'
```

### Boolean combinators

Use `and`, `or`, and parentheses to express compound conditions.

Scope to nginx lines AND (high-status OR slow response):

```fuseql
source="nginx" and (@status>=500 or @duration_ms>=1000)
```

### Facet existence

Test whether a facet is present. In a log-search query (no aggregation), use the bare `@facet` form — it matches any line where the facet key exists, regardless of value:

```fuseql
@trace_id
```

## Aggregations

Aggregation operators collapse many log lines into a summary table. They always follow a pipe (`|`) and are typically the last stage in a query. The `by` clause breaks results into groups.

### Count and distinct count

`count` answers "how many log lines matched?" — it counts rows, not unique values.

Total log volume bucketed by minute:

```fuseql
* | timeslice 1m | count by _timeslice
```

`count_unique` answers "how many distinct values?" — equivalent to `COUNT(DISTINCT field)` in SQL.: navigate nested objects and bracket notation for arrays.

## Scenarios

These scenarios include the query, what to look for in the output, and specific situations where the analysis is useful.

Count all logs  
Count the total number of log lines over time, bucketed into 30-second intervals.

```fuseql
source="my-service" | timeslice 30s | count by (_timeslice)
```

When to use this query:
- Baselining normal traffic patterns
- Capacity planning and scaling decisions
- Post-deployment validation

Count all fingerprints  
Kloudfuse clusters log lines into **fingerprints** — templates that capture the structural pattern of a log line with values replaced by placeholders.

```fuseql
* | timeslice 30s | count_unique(fingerprint) by (_timeslice)
```

When to use this query:
- Detecting new code paths
- Early anomaly detection without alerting rules

Count all logs grouped by level  
Splitting log count by severity level turns a single total into a stack of signals.

```fuseql
* | timeslice 30s | count by (_timeslice, level)
```

When to use this query:
- Identifying the severity of an incident
- Catching warning storms before they become errors

Count all fingerprints grouped by source  
This query adds a service dimension to fingerprint diversity.

```fuseql
* | timeslice 30s | count_unique(fingerprint) by (_timeslice, source)
```

When to use this query:
- Root-cause localization
- Identifying verbosity outliers

Average of a duration or number facet  
Averaging a numeric facet over time produces a performance trend line.

```fuseql
* | timeslice 30s | avg(@duration:duration_seconds) by (_timeslice)
```

When to use this query:
- Tracking gradual latency degradation
- Correlating latency with traffic volume

### Anomaly on count of error logs  
Threshold-based alerts require you to know in advance what "too many errors" looks like.

```fuseql
core:level="error" | timeslice 120s | count by (_timeslice) | anomaly (_count) by 120s, model=agileRobust, seasonality=hourly, bounds=1, band=3
```

### Outlier detection  
Where anomaly detection asks "is this service behaving differently than usual?", outlier detection asks "is this service behaving differently than its peers?".

```fuseql
level="error" | timeslice 120s | count by (_timeslice, kube_namespace) | outlier (_count) by 120s, model=dbscan, eps=3
```

### Log math operator to scale down the Y-axis  
When log count varies by orders of magnitude across different services or time periods.

```fuseql
* | timeslice 1m | count as c by (_timeslice, source) | log(c) as log_count
```
