# Logging Mechanisms Used in Palmier Pro: Unified Logging, Crash Handling, and Sentry Telemetry

> Discover Palmier Pro's logging: unified logging with os.Logger, crash handling, and Sentry telemetry for complete observability from debug to fatal errors.

- Repository: [Palmier/palmier-pro](https://github.com/palmier-io/palmier-pro)
- Tags: deep-dive
- Published: 2026-06-21

---

**Palmier Pro combines Apple's native `os.Logger` framework, POSIX-style crash handlers, and Sentry SDK telemetry to create a comprehensive observability stack that captures everything from debug messages to fatal crashes.**

Palmier Pro implements a multi-layered logging architecture designed for macOS applications that require both local diagnostics and remote monitoring. The logging mechanisms used in Palmier Pro center around a custom `Log` enum in [`Sources/PalmierPro/Utilities/Log.swift`](https://github.com/palmier-io/palmier-pro/blob/main/Sources/PalmierPro/Utilities/Log.swift) that wraps Apple's Unified Logging system while integrating with Sentry through [`Telemetry.swift`](https://github.com/palmier-io/palmier-pro/blob/main/Telemetry.swift). This design allows the video editing application to maintain structured, category-scoped logs that appear in Console.app while simultaneously forwarding critical events to aggregated monitoring backends.

## Core Logging Architecture

### Local Structured Logging with os.Logger

At the foundation of Palmier Pro's observability stack sits **Apple's Unified Logging System** (`os.Logger`). The [`Log.swift`](https://github.com/palmier-io/palmier-pro/blob/main/Log.swift) file defines a `CategoryLog` struct that initializes loggers with a specific subsystem (`io.palmier.pro`) and category identifiers.

According to the source code in [`Log.swift`](https://github.com/palmier-io/palmier-pro/blob/main/Log.swift) (lines 49-56), each subsystem category—such as `app`, `editor`, `export`, and `transcription`—receives its own `os.Logger` instance. This enables precise filtering within Console.app using the subsystem identifier and category metadata. The system supports six severity levels: `debug`, `info`, `notice`, `warning`, `error`, and `fault`.

```swift
// Log a normal informational message for the app subsystem
Log.app.info("User opened project \"\(project.name)\"")

```

This call writes to the local log store with the `io.palmier.pro` subsystem and `app` category, making it queryable through the `log` command-line tool or Console.app.

### Crash Handling and Signal Management

Palmier Pro implements a robust crash persistence layer that captures fatal signals even when the application terminates abruptly. The `CrashHandler.install` method (lines 94-104 in [`Log.swift`](https://github.com/palmier-io/palmier-pro/blob/main/Log.swift)) registers POSIX-style signal handlers alongside `NSSetUncaughtExceptionHandler` to intercept SIGSEGV, SIGABRT, and uncaught Objective-C exceptions.

When a fatal error occurs, the handler writes a complete backtrace to `~/Library/Logs/PalmierPro/crash.log` and logs a `fault` entry via `os.Logger`. This dual approach ensures that crash data survives process termination while remaining visible in the unified logging system. The `Log.bootstrap()` method activates this handler during application launch, requiring no additional code from feature developers.

### Remote Telemetry via Sentry SDK

For aggregated monitoring and crash analytics, Palmier Pro integrates the **Sentry SDK** through [`Sources/PalmierPro/Telemetry/Telemetry.swift`](https://github.com/palmier-io/palmier-pro/blob/main/Sources/PalmierPro/Telemetry/Telemetry.swift). The `Telemetry.start()` method (lines 25-48) initializes the Sentry client, while the `Log` enum provides convenience methods that forward events to both the local logger and remote telemetry simultaneously.

The architecture uses **breadcrumbs** to maintain context across user sessions. When calling log methods with a `telemetry` argument, Palmier Pro sends structured context to Sentry, enabling reconstruction of user actions leading to errors.

## Implementation Details and Code Examples

### Basic Category-Scoped Logging

Each functional area of Palmier Pro has a dedicated logger accessible via static properties on the `Log` enum:

```swift
Log.editor.notice("Started editing clip \(clip.id.prefix(8))")
Log.transcription.debug("Audio buffer received: \(buffer.size) bytes")
Log.export.info("Begin export of project \(projectId)")

```

These calls route through `CategoryLog` instances configured with appropriate subsystem categories, ensuring logs remain organized by domain.

### Logging with Telemetry Breadcrumbs

To correlate local logs with remote telemetry, use the `telemetry` parameter. This pattern appears throughout [`ExportService.swift`](https://github.com/palmier-io/palmier-pro/blob/main/ExportService.swift) and [`GenerationService.swift`](https://github.com/palmier-io/palmier-pro/blob/main/GenerationService.swift):

```swift
Log.editor.notice(
    "Started editing clip \(clip.id.prefix(8))",
    telemetry: "Editor clip edit start",
    data: ["clipId": clip.id, "duration": clip.duration]
)

```

This single call performs two operations:
- Writes a `notice` line to the local unified log
- Sends a Sentry breadcrumb via `Telemetry.breadcrumb` so that subsequent error reports include the editing context

### Error Handling and Detail Capture

For comprehensive error reporting, the `Log.detail()` method aggregates full `NSError` chains, including underlying failure codes:

```swift
do {
    try someThrowingOperation()
} catch {
    let detail = Log.detail(error)          // Full NSError chain
    Log.error("Operation failed: \(detail)", telemetry: "OperationError")
}

```

`Log.error` forwards the message to `Telemetry.logError`, ensuring remote visibility of serious issues, while `Log.fault` triggers both local fault logging and `Telemetry.logFault` for critical system failures.

### Performance Tracing with Telemetry

For operation timing and performance monitoring, `Telemetry.trace` creates Sentry transactions:

```swift
Telemetry.trace(name: "ExportJob", operation: "export") {
    // Work performed here will be wrapped in a Sentry transaction
    try exportService.run()
}

```

The method automatically finishes the transaction on success or marks it as an internal error on exception, providing distributed tracing data for performance analysis.

## Key Source Files and Patterns

The following files demonstrate the consistent logging patterns used throughout Palmier Pro:

- **[`Sources/PalmierPro/Utilities/Log.swift`](https://github.com/palmier-io/palmier-pro/blob/main/Sources/PalmierPro/Utilities/Log.swift)** – Central logger implementation, `CategoryLog` definitions, crash handler installation, and helper methods including `bootstrap()` and `detail()`

- **[`Sources/PalmierPro/Telemetry/Telemetry.swift`](https://github.com/palmier-io/palmier-pro/blob/main/Sources/PalmierPro/Telemetry/Telemetry.swift)** – Sentry SDK wrapper managing initialization, breadcrumb emission, and error/fault forwarding

- **[`Sources/PalmierPro/Transcription/Transcription.swift`](https://github.com/palmier-io/palmier-pro/blob/main/Sources/PalmierPro/Transcription/Transcription.swift)** – Domain-specific logging examples using `Log.transcription.notice()`

- **[`Sources/PalmierPro/Export/ExportService.swift`](https://github.com/palmier-io/palmier-pro/blob/main/Sources/PalmierPro/Export/ExportService.swift)** – Integration of log-and-telemetry patterns for asynchronous export workflows

- **[`Sources/PalmierPro/Generation/GenerationService.swift`](https://github.com/palmier-io/palmier-pro/blob/main/Sources/PalmierPro/Generation/GenerationService.swift)** – Extensive logging across the AI generation pipeline, demonstrating fault handling and breadcrumb trails

Each subsystem follows the same pattern: instantiate a `CategoryLog` via the `Log` enum properties, then call severity-appropriate methods with optional telemetry context.

## Summary

- **Palmier Pro** uses a three-tier logging system: local `os.Logger` structured logs, POSIX-based crash handlers, and Sentry remote telemetry.
- The **`Log` enum** in [`Log.swift`](https://github.com/palmier-io/palmier-pro/blob/main/Log.swift) centralizes all logging through category-scoped instances, supporting six severity levels from `debug` to `fault`.
- **Crash handling** writes stack traces to `~/Library/Logs/PalmierPro/crash.log` and logs faults via `os.Logger` without requiring explicit developer intervention after `Log.bootstrap()`.
- **Telemetry integration** allows single-call logging that emits both local logs and Sentry breadcrumbs, maintaining context across user sessions.
- **Performance tracing** via `Telemetry.trace` provides automatic transaction tracking for critical operations like video export and AI generation.

## Frequently Asked Questions

### How does Palmier Pro handle application crashes?

Palmier Pro installs POSIX-style signal handlers and uncaught exception handlers during `Log.bootstrap()` that capture fatal signals (SIGSEGV, SIGABRT) and uncaught Objective-C exceptions. When a crash occurs, the handler writes a complete backtrace to `~/Library/Logs/PalmierPro/crash.log` and emits a `fault` level log entry through `os.Logger`, ensuring the crash data persists after process termination.

### What is the difference between `Log.error` and `Log.fault` in Palmier Pro?

`Log.error` logs an error-level message to the local unified logging system and forwards the event to Sentry via `Telemetry.logError`, suitable for recoverable failures. `Log.fault` indicates a non-recoverable system failure that requires immediate attention; it logs at the fault level and triggers `Telemetry.logFault`, signaling critical issues that may require application termination or restart.

### Where are local log files stored in Palmier Pro?

While standard `os.Logger` messages appear in the unified logging system (visible in Console.app), fatal crash logs are specifically written to `~/Library/Logs/PalmierPro/crash.log`. This file contains backtraces generated by the `CrashHandler` when signal handlers catch fatal errors, providing a persistent record even if the unified log buffer rotates.

### How do I add telemetry breadcrumbs to my logging calls?

Include the `telemetry` parameter when calling any log method on a `CategoryLog` instance. For example: `Log.editor.notice("Action occurred", telemetry: "breadcrumb_message", data: ["key": value])`. This sends a breadcrumb to Sentry containing the message and dictionary data, which appears in subsequent error reports to provide context about user actions preceding failures.