¿Qué es la Observabilidad y por qué la necesita un desarrollador Swift?
\n\n¿Alguna vez has intentado entender por qué tu aplicación Swift en iOS se ralentiza justo en la pantalla de perfil, o la parte del servidor en Vapor responde con un retraso de 3 segundos solo para usuarios de Europa? Si es así, ya te has enfrentado al problema que resuelve la observabilidad.
\n\nLa observabilidad no es solo "logging". Es la capacidad de hacer cualquier pregunta al sistema sobre su estado sin necesidad de escribir nuevo código. Los tres pilares de la observabilidad son: trazado (tracing), métricas y logs. Juntos brindan una imagen completa de lo que sucede: desde la solicitud del usuario hasta la ejecución en lo profundo de la base de datos.
\n\nEn este artículo, analizaremos cómo implementar la observabilidad en proyectos Swift, tanto en el cliente (iOS) como en el servidor (Vapor / Hummingbird). Aprenderás qué librerías usar, cómo escribir trazas y métricas efectivas, y cómo no ahogarte en los logs.
\n\n¿Por qué Swift es un candidato ideal para la Observabilidad?
\n\nSwift es un lenguaje con tipado fuerte, rendimiento a nivel de C y un ecosistema creciente para el desarrollo backend. Pero hay un detalle: la comunidad Swift apenas está comenzando a adoptar activamente la observabilidad. A diferencia de Java o Go, donde OpenTelemetry ya es un estándar, en Swift el mundo de la observabilidad es una tendencia reciente que brinda a los primeros adoptantes una gran ventaja.
\n\nPrincipales desafíos para el desarrollador Swift:
\n- \n
- Asincronía: async/await y Structured Concurrency cambian las reglas del juego para el trazado. \n
- Multiplataforma: el código Swift puede ejecutarse en iOS, macOS, servidores e incluso sistemas embebidos. \n
- Falta de un estándar unificado: aún no existe una "bala de plata" como en el mundo Java. \n
Pero la buena noticia es que Swift proporciona todas las herramientas para construir una observabilidad sólida; solo necesitas saber dónde mirar.
\n\nTrazado (Tracing) en Swift: de la solicitud a la respuesta
\n\n¿Qué es el trazado y para qué sirve?
\nEl trazado (o trazado distribuido) permite rastrear la ruta de una sola solicitud a través de todos los servicios y funciones de la aplicación. En el mundo de los microservicios, es indispensable. Pero incluso en una aplicación iOS monolítica, el trazado ayuda a entender qué parte específica del código se está ralentizando.
\n\nOpenTelemetry Swift: tu herramienta principal
\nOpenTelemetry es un estándar abierto para la observabilidad. Para Swift existe el paquete opentelemetry-swift. Soporta trazado, métricas y logs, así como la exportación de datos a cualquier backend (Jaeger, Prometheus, Grafana).
Instalación a través de Swift Package Manager:
\n// Package.swift\n.package(url: "https://github.com/open-telemetry/opentelemetry-swift.git", from: "1.10.0")\n\nEscribiendo nuestra primera traza en Swift
\nImagina que tienes una función para cargar el perfil de un usuario. Sin trazado, solo ves el tiempo total de ejecución. Con trazado, ves cada paso:
\n\nimport 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 // Paso 1: verificación de caché\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 // Paso 2: solicitud a la API\n let apiSpan = tracer.spanBuilder(spanName: "fetchFromAPI").startSpan()\n let profile = try await api.fetchPro