Swift SDK

Swift Logo

The official Swift SDK for LogFlux. Send logs, metrics, traces, events, and audit entries directly to the LogFlux cloud with end-to-end encryption from iOS and macOS apps. The server never sees your plaintext data.

GitHub Repository ยท Release Notes

Key Features

  • End-to-end encryption – AES-256-GCM with RSA key exchange
  • 7 entry types – Log, Metric, Trace, Event, Audit, Telemetry, TelemetryManaged
  • Multipart binary transport – 33% less overhead than JSON + base64
  • Disk persistence – Entries survive app termination and network outages
  • Async by default – Non-blocking queue with background workers
  • Breadcrumbs – Automatic trail of recent events attached to error captures
  • Distributed tracing – Spans, child spans, context propagation
  • Scopes – Per-request context isolation
  • Keychain storage – AES keys stored securely in iOS/macOS Keychain
  • Failsafe – SDK errors never crash your application
  • Zero external dependencies – Apple frameworks only

Installation

Swift Package Manager

Add to your Package.swift:

1
2
3
dependencies: [
    .package(url: "https://github.com/logflux-io/logflux-swift-sdk.git", from: "3.0.0")
]

Or in Xcode: File > Add Package Dependencies > enter the repository URL.

Quick Start

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import LogFlux

try LogFlux.initialize(options: Options(apiKey: "eu-lf_your_api_key") {
    $0.source = "my-ios-app"
    $0.environment = "production"
    $0.release = "1.2.3"
})

LogFlux.info("app launched")
LogFlux.flush(timeout: 2.0)

Entry Types

Log (Type 1)

Standard application logs with 8 severity levels.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
LogFlux.debug("cache miss for key users:123")
LogFlux.info("request processed")
LogFlux.warn("deprecated API called")
LogFlux.error("network request failed")
LogFlux.critical("out of memory")

// With attributes
LogFlux.log(level: .error, "query timeout", attributes: [
    "db.host": "primary.db.internal",
    "duration_ms": "5023",
])

Metric (Type 2)

Counters, gauges, and distributions.

1
2
3
4
5
6
7
8
LogFlux.counter("http.requests.total", value: 1, attributes: [
    "method": "GET",
    "status": "200",
])

LogFlux.gauge("system.memory.used", value: 85.2, attributes: [
    "host": "iphone-14",
])

Event (Type 4)

Discrete application events.

1
2
3
4
LogFlux.event("user.signup", attributes: [
    "user_id": "usr_987",
    "plan": "starter",
])

Audit (Type 5)

Immutable audit trail with Object Lock storage (365-day retention).

1
2
3
LogFlux.audit("record.deleted", actor: "usr_456", resource: "invoice", resourceID: "inv_789", attributes: [
    "reason": "customer_request",
])

Trace (Type 3)

Distributed tracing with span helpers.

1
2
3
4
5
let span = LogFlux.startSpan("http.request", "GET /api/users")
defer { span.end() }

let dbSpan = span.startChild("db.query", "SELECT * FROM users")
dbSpan.end()

Telemetry (Types 6 and 7)

Device and sensor data. Type 6 is end-to-end encrypted, type 7 is server-side encrypted.

Error Capture

Capture Swift errors with automatic breadcrumb trail.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
do {
    try database.query(sql)
} catch {
    LogFlux.captureError(error)

    // With extra context
    LogFlux.captureError(error, attributes: [
        "sql": sql,
        "db.host": "primary",
    ])
}

Breadcrumbs record a trail of events leading up to an error. They are automatically added for log and event calls, and attached to captureError.

1
2
3
4
5
6
7
8
LogFlux.info("loading config")          // auto breadcrumb
LogFlux.event("user.login")             // auto breadcrumb

LogFlux.addBreadcrumb("http", "GET /api/users", data: [
    "status": "200",
])

LogFlux.captureError(error)  // includes breadcrumb trail

Scopes

Per-request context isolation. Attributes set on a scope are merged into every entry.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
LogFlux.withScope { scope in
    scope.setUser("usr_456")
    scope.setRequest("GET", path: "/api/users", requestID: "req_abc123")
    scope.setAttribute("tenant", value: "acme-corp")

    scope.info("processing request")

    if let error = error {
        scope.captureError(error)
    }
}

Trace Context Propagation

Propagate trace context across network requests.

1
2
3
4
5
6
7
8
// Inject into outgoing URLRequest
let span = LogFlux.startSpan("http.client", "GET /api")
var request = URLRequest(url: url)
request.setValue(span.traceHeader, forHTTPHeaderField: "X-LogFlux-Trace")

// Continue from incoming headers
let span = LogFlux.continueFromRequest(headers, operation: "http.server", description: "GET /api")
defer { span.end() }

Configuration

Options

OptionTypeDefaultDescription
apiKeyStringrequiredAPI key (<region>-lf_<key>)
sourceStringService/app name
environmentStringAttached to meta.environment
releaseStringAttached to meta.release
queueSizeInt1000In-memory buffer capacity
batchSizeInt100Entries per HTTP request
workerCountInt2Background threads
maxRetriesInt3Max retry attempts
sampleRateDouble1.00.0-1.0, send probability
maxBreadcrumbsInt100Ring buffer size
failsafeBooltrueNever crash host app
enableCompressionBooltrueGzip before encryption

Environment Variables

1
try LogFlux.initFromEnvironment(node: "iphone-14")

Reads LOGFLUX_API_KEY, LOGFLUX_ENVIRONMENT, LOGFLUX_NODE, etc.

BeforeSend Hooks

Filter or modify entries before they are sent. Return nil to drop.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
opts.beforeSendLog = { log in
    if log.level == LogLevel.debug.rawValue {
        return nil  // drop debug logs
    }
    return log
}

opts.beforeSendAudit = { audit in
    var a = audit
    a.attributes?.removeValue(forKey: "ip")  // scrub PII
    return a
}

Sampling

1
opts.sampleRate = 0.1  // send 10% of entries

Audit entries (type 5) are never sampled.

Disk Persistence

Unlike server-side SDKs, the Swift SDK persists entries to disk before sending. This ensures data survives:

  • App suspension/termination by iOS
  • Network connectivity loss
  • App crashes

Entries are stored in ~/Library/Caches/io.logflux.queue/ with FIFO ordering and automatic eviction.

Security

  • Zero-knowledge: All payloads encrypted client-side with AES-256-GCM
  • RSA key exchange: AES keys negotiated via RSA-2048 OAEP handshake
  • Keychain storage: AES keys stored in iOS/macOS Keychain (whenUnlockedThisDeviceOnly)
  • Key zeroing: AES keys cleared from memory on close()
  • Bounded reads: All HTTP responses size-limited (1MB)
  • Failsafe: SDK errors never crash the host application

Requirements

  • Swift 5.9 or later
  • macOS 13+ / iOS 16+
  • LogFlux account with API key

No External Dependencies

Uses only Apple frameworks: CryptoKit, Security, Foundation, Network, Compression, os.log.

License

Elastic License 2.0 (ELv2) – free for all use except offering as a hosted or managed service to third parties.

Support

Disclaimer

The Swift logo and trademarks are the property of Apple Inc. LogFlux is not affiliated with, endorsed by, or sponsored by Apple Inc. The Swift logo is used solely for identification purposes to indicate compatibility and integration capabilities.