> For the complete documentation index, see [llms.txt](https://docs.bindplane.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.bindplane.com/integrations/sources/macos-unified-logging.md).

# macOS Unified Logging

Collects logs from the macOS unified logging system by invoking the native `log` command on the host. In stream mode it reads logs as they are written; in archive mode it reads from one or more `.logarchive` directories. A predicate expression filters which log messages are collected, and the log format controls how each record is parsed.

### Supported Telemetry

| Platform | Metrics | Logs | Traces |
| -------- | ------- | ---- | ------ |
| macOS    |         | ✓    |        |

### Prerequisites

* The collector must run on a macOS host. This source is macOS-only.
* The native `log` command (`/usr/bin/log`) must be available on the host. It ships with macOS.
* For stream mode, the collector process needs permission to read the system logs via `log stream`.
* For archive mode, the collector process needs read access to each `.logarchive` directory it targets.

Predicate syntax follows Apple's predicate format used by the `log` command. See the [Apple Predicate Programming Guide](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Predicates/AdditionalChapters/Introduction.html) and the [`log` command reference](https://ss64.com/mac/log.html). You can also run `log help predicates` on the host to list the valid predicate fields.

### Configuration

<figure><img src="/files/084Cff1UoyKD6VHpobW7" alt="Bindplane docs - macOS Unified Logging - image 1"><figcaption></figcaption></figure>

**General**

| Parameter       | Type                                         | Required | Default   | Description                                                                                                                                      |
| --------------- | -------------------------------------------- | -------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| Collection Mode | Enum: `archive`, `stream`                    | No       | `stream`  | The collection mode to run the source in. Archive mode reads logs from a `.logarchive` directory. Stream mode collects logs as they are written. |
| Log Format      | Enum: `default`, `syslog`, `json`, `compact` | No       | `json`    | The format of the logs to collect. JSON format produces parsed time and severity fields; all other formats are collected as raw strings.         |
| Predicate       | Predicate                                    | No       | *(empty)* | The expression used to filter which logs to collect. Uses Apple's predicate syntax.                                                              |
| Archive Path    | String                                       | No       | *(empty)* | The path or glob pattern to the `.logarchive` directory or directories to collect logs from. Shown when Collection Mode is `archive`.            |
| Start Time      | Date/Time                                    | No       | *(empty)* | The time to start collecting logs from. Applies in both stream and archive mode.                                                                 |
| End Time        | Date/Time                                    | No       | *(empty)* | The time to stop collecting logs at. Shown when Collection Mode is `archive`.                                                                    |

**Advanced**

| Parameter         | Type              | Required | Default | Description                                                                                                                                      |
| ----------------- | ----------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| Max Poll Interval | Integer (seconds) | No       | `30`    | The maximum interval between polls for new logs, in seconds. Uses exponential backoff starting at 100ms. Shown when Collection Mode is `stream`. |
| Max Log Age       | Integer (hours)   | No       | `24`    | The maximum age of a log to collect, in hours. Shown when Collection Mode is `stream`.                                                           |

### Examples

#### Stream errors and faults from a single subsystem

Collect only error- and fault-level messages from one subsystem as they are written. The predicate uses Apple's predicate syntax, the same form accepted by `log stream --predicate '...'` on the host.

```yaml
apiVersion: bindplane.observiq.com/v1
kind: Source
metadata:
  name: macos-unified-logging
spec:
  type: macos_unified_logging
  parameters:
    - name: mode
      value: stream
    - name: format
      value: json
    - name: predicate
      value: 'subsystem == "com.apple.network" && messageType == error'
```

The equivalent invocation a host operator would run by hand is:

```
log stream --predicate 'subsystem == "com.apple.network" && messageType == error' --style ndjson
```

#### Read a date range from a log archive

Collect logs from a captured `.logarchive` between two timestamps.

```yaml
apiVersion: bindplane.observiq.com/v1
kind: Source
metadata:
  name: macos-unified-logging
spec:
  type: macos_unified_logging
  parameters:
    - name: mode
      value: archive
    - name: format
      value: json
    - name: archive_path
      value: /var/log/system.logarchive
    - name: predicate
      value: 'eventMessage contains "Failure"'
    - name: start_time
      value: '2026-06-01T00:00:00'
    - name: end_time
      value: '2026-06-02T00:00:00'
```

### Configuration Tips

* For structured records with parsed timestamp and severity, use the `json` format. The other formats place the raw log line in the record body with no parsed severity.
* Keep predicates narrow. Streaming the full unified log without a predicate produces very high volume.
* The predicate is passed to the host `log` command, so certain shell metacharacters are rejected for safety. Use `&&`/`||` for logical operators and `==`, `<`, `>` for comparisons. Do not use pipes, command separators, variable expansion, or redirects (see Troubleshooting).

### Troubleshooting

#### No logs are collected in stream mode

Symptoms: the source is healthy but no log records arrive.

Solutions:

1. Confirm the predicate matches real traffic. Test it on the host with `log stream --predicate '<your predicate>'` and verify messages appear.
2. Confirm the collector process has permission to read system logs.
3. Check that Max Log Age is not excluding the logs you expect. Records older than the configured age are skipped.

#### Predicate is rejected or sanitized

Symptoms: the source reports an invalid predicate, or part of the predicate appears to be stripped.

Solutions:

1. Remove disallowed characters. The predicate may not contain command separators (`;`), pipes (`|`), variable expansion (`$`), backticks, redirects (`>>`, `<<`), or control characters such as newlines and carriage returns.
2. Use the normalized logical operators. `&&` is converted to `AND` and `||` is converted to `OR` to prevent command chaining. The `>` operator is allowed for comparisons such as `processID > 100` but is blocked when followed by a file path.
3. Run `log help predicates` on the host to confirm the field names you are using are valid.

#### Archive mode collects nothing

Symptoms: archive mode runs but returns no records.

Solutions:

1. Verify Archive Path points at a valid `.logarchive` directory and that the collector has read access to it.
2. Verify the Start Time / End Time window overlaps the data in the archive.
3. Confirm the predicate is not filtering out every record.

### Standalone Source

```yaml
apiVersion: bindplane.observiq.com/v1
kind: Source
metadata:
  name: macos-unified-logging
spec:
  type: macos_unified_logging
  parameters:
    - name: mode
      value: stream
    - name: format
      value: json
    - name: predicate
      value: 'subsystem == "com.apple.network" && messageType == error'
    - name: poll_interval
      value: 30
    - name: max_log_age
      value: 24
```

### Related Resources

* [macOS Unified Logging receiver (OpenTelemetry Collector Contrib)](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/macosunifiedloggingreceiver)
* [Apple Predicate Programming Guide](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Predicates/AdditionalChapters/Introduction.html)
* [`log` command reference](https://ss64.com/mac/log.html)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.bindplane.com/integrations/sources/macos-unified-logging.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
