telemetry-facade-patternlisted
Install: claude install-skill wei18/apple-dev-skills
# Telemetry Facade Pattern
## When to invoke
- Starting a new project and designing the logger / tracker / metrics interface.
- About to introduce OSLog and any tracking / analytics at the same time.
- Wanting to preserve flexibility for "swap the tracking provider later".
- User asks "should Logger and Tracking be separate", "how should the event interface look".
## Default decisions
### A single `Telemetry` target
- Create one `Telemetry` target inside the SwiftPM Package.
- It contains:
- `TelemetryEvent` value type (enum / struct, `Sendable`)
- `TelemetrySink` protocol:
```swift
public protocol TelemetrySink: Sendable {
func receive(_ event: TelemetryEvent) async
}
```
- The main facade — choose the type per the table below. The facade fans out to multiple sinks.
| Facade type | Use when | Cost |
|---|---|---|
| `actor Telemetry` (default) | any sink holds subscription identity (e.g. `MXMetricManagerSubscriber`) or does async I/O | `observe` is `async` |
| `struct Telemetry: Sendable` | every sink is fully synchronous and stateless | no lifecycle owner for stateful sinks |
- Default sinks (see below)
### Call sites describe only "what happened"
```swift
telemetry.observe(.sessionCompleted(id: sessionId, durationMs: 12_345))
```
- The call site **doesn't know** who will consume the event.
- Swapping providers / adding sinks only requires replacing a sink; call sites change nothing.
### Default sink set
| Sink | Rec