Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .chloggen/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ components:
- receiver/kubeletstats
- receiver/libhoney
- receiver/loki
- receiver/macosunifiedlogging
- receiver/memcached
- receiver/mongodb
- receiver/mongodbatlas
Expand Down
27 changes: 27 additions & 0 deletions .chloggen/feat_macosunifiedloggingreceiver.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Use this changelog template to create an entry for release notes.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: new_component

# The name of the component, or a single word describing the area of concern, (e.g. receiver/filelog)
component: receiver/macosunifiedlogging

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Add a new receiver for macOS Unified Logging.

# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
issues: [44089]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:

# If your change doesn't affect end users or the exported elements of any package,
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
# Optional: The change log or logs in which this entry should be included.
# e.g. '[user]' or '[user, api]'
# Include 'user' if the change is relevant to end users.
# Include 'api' if there is a change to a library API.
# Default: '[user]'
change_logs: []
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ receiver/kafkareceiver/ @open-telemetry
receiver/kubeletstatsreceiver/ @open-telemetry/collector-contrib-approvers @dmitryax @TylerHelmuth @ChrsMark
receiver/libhoneyreceiver/ @open-telemetry/collector-contrib-approvers @TylerHelmuth @mterhar
receiver/lokireceiver/ @open-telemetry/collector-contrib-approvers @mar4uk
receiver/macosunifiedloggingreceiver/ @open-telemetry/collector-contrib-approvers @Caleb-Hurshman
receiver/memcachedreceiver/ @open-telemetry/collector-contrib-approvers @jsirianni
receiver/mongodbatlasreceiver/ @open-telemetry/collector-contrib-approvers @justinianvoss22
receiver/mongodbreceiver/ @open-telemetry/collector-contrib-approvers @justinianvoss22
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/beta_stability.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ body:
- receiver/kubeletstats
- receiver/libhoney
- receiver/loki
- receiver/macosunifiedlogging
- receiver/memcached
- receiver/mongodb
- receiver/mongodbatlas
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ body:
- receiver/kubeletstats
- receiver/libhoney
- receiver/loki
- receiver/macosunifiedlogging
- receiver/memcached
- receiver/mongodb
- receiver/mongodbatlas
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ body:
- receiver/kubeletstats
- receiver/libhoney
- receiver/loki
- receiver/macosunifiedlogging
- receiver/memcached
- receiver/mongodb
- receiver/mongodbatlas
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/other.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ body:
- receiver/kubeletstats
- receiver/libhoney
- receiver/loki
- receiver/macosunifiedlogging
- receiver/memcached
- receiver/mongodb
- receiver/mongodbatlas
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/unmaintained.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ body:
- receiver/kubeletstats
- receiver/libhoney
- receiver/loki
- receiver/macosunifiedlogging
- receiver/memcached
- receiver/mongodb
- receiver/mongodbatlas
Expand Down
1 change: 1 addition & 0 deletions cmd/otelcontribcol/builder-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ receivers:
- gomod: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/kubeletstatsreceiver v0.139.0
- gomod: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/libhoneyreceiver v0.139.0
- gomod: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/lokireceiver v0.139.0
- gomod: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/macosunifiedloggingreceiver v0.139.0
- gomod: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/memcachedreceiver v0.139.0
- gomod: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/mongodbatlasreceiver v0.139.0
- gomod: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/mongodbreceiver v0.139.0
Expand Down
1 change: 1 addition & 0 deletions internal/tidylist/tidylist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ receiver/kafkareceiver
receiver/kubeletstatsreceiver
receiver/libhoneyreceiver
receiver/lokireceiver
receiver/macosunifiedloggingreceiver
receiver/memcachedreceiver
receiver/mongodbatlasreceiver
receiver/mongodbreceiver
Expand Down
1 change: 1 addition & 0 deletions receiver/macosunifiedloggingreceiver/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include ../../Makefile.Common
178 changes: 178 additions & 0 deletions receiver/macosunifiedloggingreceiver/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
# macOS Unified Logging Receiver

<!-- status autogenerated section -->
| Status | |
| ------------- |-----------|
| Stability | [development]: logs |
| Distributions | [] |
| Issues | [![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fmacosunifiedlogging%20&label=open&color=orange&logo=opentelemetry)](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues?q=is%3Aopen+is%3Aissue+label%3Areceiver%2Fmacosunifiedlogging) [![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fmacosunifiedlogging%20&label=closed&color=blue&logo=opentelemetry)](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues?q=is%3Aclosed+is%3Aissue+label%3Areceiver%2Fmacosunifiedlogging) |
| Code coverage | [![codecov](https://codecov.io/github/open-telemetry/opentelemetry-collector-contrib/graph/main/badge.svg?component=receiver_macosunifiedlogging)](https://app.codecov.io/gh/open-telemetry/opentelemetry-collector-contrib/tree/main/?components%5B0%5D=receiver_macosunifiedlogging&displayType=list) |
| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@Caleb-Hurshman](https://www.github.com/Caleb-Hurshman) |

[development]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/component-stability.md#development
<!-- end autogenerated section -->

The macOS Unified Logging Receiver collects logs from macOS systems using the native `log` command. This receiver supports both live system logs and archived log files (`.logarchive`).

## 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" |
| `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) |
| `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 logs are detected again, the interval resets to the minimum (100ms)

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

### Basic Configuration (Live Mode)

```yaml
receivers:
macosunifiedlogging:
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
receivers:
macosunifiedlogging:
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
receivers:
macosunifiedlogging:
archive_path: "/logs/**/*.logarchive" # Matches all .logarchive directories recursively
format: "ndjson"
```


### With Filtering

```yaml
receivers:
macosunifiedlogging:
archive_path: "./logs.logarchive"
predicate: "subsystem == 'com.apple.systempreferences'"
```

### With Custom Format

```yaml
receivers:
macosunifiedlogging:
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 IN {'Error', '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**: Set to observed time (when the log was received)
- **Severity**: Not set

## Example

Complete example configuration:

```yaml
receivers:
macosunifiedlogging:
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]
```

Loading
Loading