> ## Documentation Index
> Fetch the complete documentation index at: https://otel.fyi/llms.txt
> Use this file to discover all available pages before exploring further.

# Macosunifiedlogging

> OpenTelemetry receiver for Macosunifiedlogging

# Macosunifiedlogging Receiver

![Status](https://img.shields.io/badge/status-alpha-red)

**Available in:** `contrib`

**Maintainers:** [@Caleb-Hurshman](https://github.com/Caleb-Hurshman), [@atoulme](https://github.com/atoulme)

**Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/macosunifiedloggingreceiver)

## Supported Telemetry

![Logs](https://img.shields.io/badge/logs-alpha-blue)

## Overview

## Requirements

* macOS 10.12 (Sierra) or later
* The `log` command must be available in PATH
* For archive mode: Read access to the `.logarchive` directory
* For live mode: Appropriate permissions to read system logs

## Configuration

### Configuration Options

| Option | Type | Default | Description |
| - | - | - | - |
| `archive_path` | string | "" | Path or glob pattern to `.logarchive` directory(ies). If empty, reads live system logs. Supports glob patterns (e.g., `*.logarchive`, `**/logs/*.logarchive`) which will match multiple archives |
| `predicate` | string | "" | Filter predicate (e.g., `"subsystem == 'com.apple.example'"`) |
| `start_time` | string | "" | Start time in format "2006-01-02 15:04:05". In live mode it only applies to the first poll |
| `end_time` | string | "" | End time in format "2006-01-02 15:04:05" (archive mode only) |
| `max_poll_interval` | duration | 30s | Maximum interval between polling for new logs (live mode only). Uses exponential backoff starting at 100ms |
| `max_log_age` | duration | 24h | Maximum age of logs to read on startup (live mode only). Later polls resume from the last emitted record |
| `format` | string | "default" | Output format: `default`, `ndjson`, `json`, `syslog`, or `compact` |

### Exponential Backoff Behavior

In live mode, the receiver uses exponential backoff to optimize polling based on log activity:

* **Active Logging**: When logs are actively being written, the receiver polls frequently (starting at 100ms) to minimize latency and catch logs written immediately after the previous poll
* **Idle Period**: When no logs are found, the polling interval increases exponentially (doubling each time) up to `max_poll_interval`
* **Automatic Reset**: As soon as new logs are detected again, the interval resets to the minimum (100ms)

Each poll resumes from the timestamp of the newest record emitted by the previous poll, so with the `ndjson`,
`default`, `syslog` and `compact` formats a record is only emitted once. The `json` format prints each record
across several lines, so no per-line timestamp is available and those records are still emitted on every poll
that returns them; the same applies to any line without a parseable timestamp.

This approach minimizes both latency during active logging and resource usage during idle periods.

### Basic Configuration (Live Mode)

```yaml theme={null}
receivers:
  macos_unified_logging:
    max_poll_interval: 30s  # Maximum interval between polls (uses exponential backoff)
    max_log_age: 24h        # How far back to read on startup
```

### Archive Mode (Single Archive)

```yaml theme={null}
receivers:
  macos_unified_logging:
    archive_path: "/path/to/system_logs.logarchive"
    start_time: "2024-01-01 00:00:00"
    end_time: "2024-01-02 00:00:00"
```

### Archive Mode (Glob Pattern - Multiple Archives)

```yaml theme={null}
receivers:
  macos_unified_logging:
    archive_path: "/logs/**/*.logarchive"  # Matches all .logarchive directories recursively
    format: "ndjson"
```

### With Filtering

```yaml theme={null}
receivers:
  macos_unified_logging:
    archive_path: "./logs.logarchive"
    predicate: "subsystem == 'com.apple.systempreferences'"
```

### With Custom Format

```yaml theme={null}
receivers:
  macos_unified_logging:
    format: ndjson             # Use structured JSON output
    max_poll_interval: 30s
    max_log_age: 24h
```

## Predicate Examples

Filter by subsystem:

```
subsystem == 'com.apple.systempreferences'
```

Filter by process:

```
process == 'kernel'
```

Filter by message type:

```
messageType == 'Error'
```

Combine filters:

```
subsystem == 'com.apple.example' AND (messageType == 'Error' OR messageType == 'Fault')
```

For a full description of predicate expressions, run `log help predicates`.

### Security Note

Predicate values are validated to ensure only valid predicate syntax is used. The following are not allowed:

* Command separators: `;`
* Pipes: `|` (`||` are normalized to `OR`)
* Variable expansion: `$`
* Backticks: `` ` ``
* Redirects: `>>`, `<<`
* Control characters: newlines, carriage returns

Valid predicate operators like `&&` (logical AND), `<`, `>` (comparison) are allowed. The `>` operator is allowed for comparisons (e.g., `processID > 100`) but blocked when followed by file paths. Note that `&&` is automatically normalized to `AND` for consistency. Use standard predicate syntax as documented by Apple's `log` command.

## Output Format

The receiver converts macOS logs to OpenTelemetry log records:

* **Body**: Contains the entire log line as a string
* **Attributes**: Not set

### Format Options

#### `ndjson` and `json` Formats

When using JSON formats, each log line is captured as a complete JSON string in the body, with timestamp and severity extracted:

* **Timestamp**: Parsed from the `timestamp` field in the JSON
* **Severity**: Mapped from `messageType` (Error, Fault, Default, Info, Debug)

#### `default`, `syslog`, and `compact` Formats

When using plain text formats, each log line is captured as plain text in the body:

* **Timestamp**: Parsed from the leading timestamp column of the line
* **Severity**: Not set

## Example

Complete example configuration:

```yaml theme={null}
receivers:
  macos_unified_logging:
    archive_path: "./system_logs.logarchive"
    predicate: "subsystem BEGINSWITH 'com.apple'"
    start_time: "2024-01-01 00:00:00"

exporters:
  file:
    path: "./output/logs.json"
    format: json

service:
  pipelines:
    logs:
      receivers: [macosunifiedlogging]
      exporters: [file]
```

***

*Last generated: 2026-10-05*
