Observability in Swift: Tracing, Metriken und Logs für Profis

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Was ist Observability und warum braucht ein Swift-Entwickler sie?

\n\n

Haben Sie jemals versucht zu verstehen, warum Ihre Swift-iOS-App genau auf dem Profilbildschirm ruckelt und der Serverteil mit Vapor nur für Benutzer aus Europa mit einer Verzögerung von 3 Sekunden antwortet? Wenn ja, sind Sie bereits auf das Problem gestoßen, das Observability (Beobachtbarkeit) löst.

\n\n

Observability ist nicht einfach nur „Logging“. Es ist die Fähigkeit, dem System beliebige Fragen über seinen Zustand zu stellen, ohne neuen Code schreiben zu müssen. Die drei Säulen der Observability sind: Tracing (Ablaufverfolgung), Metriken und Logs. Zusammen ergeben sie ein vollständiges Bild des Geschehens – von der Benutzeranfrage bis zur Ausführung in der Datenbanktiefe.

\n\n

In diesem Artikel werden wir besprechen, wie man Observability in Swift-Projekten implementiert – sowohl auf dem Client (iOS) als auch auf dem Server (Vapor / Hummingbird). Sie erfahren, welche Bibliotheken Sie verwenden, wie Sie effektive Traces und Metriken schreiben und wie Sie nicht in Logs ertrinken.

\n\n

Warum ist Swift ein idealer Kandidat für Observability?

\n\n

Swift ist eine stark typisierte Sprache mit C-ähnlicher Leistung und einem wachsenden Ökosystem für die Serverentwicklung. Es gibt jedoch eine Nuance: Die Swift-Community beginnt erst aktiv, Observability zu implementieren. Im Gegensatz zu Java oder Go, wo OpenTelemetry bereits zum Standard geworden ist, ist die Observability-Welt in Swift ein frischer Trend, der frühen Anwendern einen enormen Vorteil verschafft.

\n\n

Die größten Herausforderungen für Swift-Entwickler:

\n
    \n
  • Asynchronität: async/await und Structured Concurrency verändern die Regeln für Tracing.
  • \n
  • Multiplattform: Swift-Code kann auf iOS, macOS, dem Server und sogar eingebetteten Systemen laufen.
  • \n
  • Fehlender einheitlicher Standard: Es gibt noch keine „eierlegende Wollmilchsau“ wie in der Java-Welt.
  • \n
\n\n

Die gute Nachricht ist jedoch, dass Swift alle Werkzeuge für den Aufbau einer zuverlässigen Observability bietet – man muss nur wissen, wo man hinschauen muss.

\n\n

Tracing in Swift: Von der Anfrage bis zur Antwort

\n\n

Was ist Tracing und warum wird es benötigt?

\n

Tracing (oder verteilte Ablaufverfolgung) ermöglicht es, den Weg einer einzelnen Anfrage durch alle Dienste und Funktionen einer Anwendung zu verfolgen. In der Welt der Microservices ist dies unverzichtbar. Aber selbst in einer monolithischen iOS-App hilft Tracing zu verstehen, welcher Teil des Codes genau ruckelt.

\n\n

OpenTelemetry Swift: Ihr wichtigstes Werkzeug

\n

OpenTelemetry ist ein offener Standard für Observability. Für Swift gibt es das Paket opentelemetry-swift. Es unterstützt Tracing, Metriken und Logs sowie den Export von Daten in jedes Backend (Jaeger, Prometheus, Grafana).

\n\n

Installation über den Swift Package Manager:

\n
// Package.swift\n.package(url: "https://github.com/open-telemetry/opentelemetry-swift.git", from: "1.10.0")
\n\n

Unser ersten Trace in Swift schreiben

\n

Stellen Sie sich vor, Sie haben eine Funktion zum Laden eines Benutzerprofils. Ohne Tracing sehen Sie nur die Gesamtausführungszeit. Mit Tracing sehen Sie jeden Schritt:

\n\n
import OpenTelemetryApi\nimport OpenTelemetrySdk\n\nlet tracer = OpenTelemetry.instance.tracerProvider.get(\n    instrumentationName: "ProfileModule",\n    instrumentationVersion: "1.0.0"\n)\n\nfunc loadUserProfile(userId: String) async throws -> UserProfile {\n    let span = tracer.spanBuilder(spanName: "loadUserProfile")\n        .setAttribute(key: "user.id", value: userId)\n        .startSpan()\n    \n    defer {\n        span.end()\n    }\n    \n    // Schritt 1: Cache-Prüfung\n    let cacheSpan = tracer.spanBuilder(spanName: "checkCache").startSpan()\n    let cached = checkCache(for: userId)\n    cacheSpan.end()\n    \n    if let cachedProfile = cached {\n        span.setAttribute(key: "cache.hit", value: true)\n        return cachedProfile\n    }\n    \n    // Schritt 2: API-Anfrage\n    let apiSpan = tracer.spanBuilder(spanName: "fetchFromAPI").startSpan()\n    let profile = try await api.fetchPro                

Blogs

Buchempfehlungen