Das Wichtigste zuerst: Dies ist der Beginn eines von der Community betriebenen Open-Source-Projekts, das aktiv nach Beiträgen sucht, sei es Code, Dokumentation oder Ideen. Neben dem Beitrag zu SwiftLog
selbst gibt es derzeit noch eine weitere große Lücke: SwiftLog
ist ein API-Paket , das versucht, eine gemeinsame API zu etablieren, die das Ökosystem nutzen kann. Damit die Protokollierung für reale Arbeitslasten wirklich funktioniert, benötigen wir SwiftLog
-kompatible Protokollierungs-Backends , die die Protokollnachrichten dann entweder in Dateien speichern, sie auf dem Terminal in schöneren Farben rendern oder sie an Splunk oder ELK senden.
Was SwiftLog
heute bietet, finden Sie in den API-Dokumenten.
Wenn Sie über eine serverseitige Swift-Anwendung oder vielleicht eine plattformübergreifende (z. B. Linux und macOS) App/Bibliothek verfügen und protokollieren möchten, halten wir die Ausrichtung auf dieses Protokollierungs-API-Paket für eine gute Idee. Nachfolgend finden Sie alles, was Sie für den Einstieg wissen müssen.
SwiftLog
wurde für Swift 5.8 und höher entwickelt. Um vom Protokollierungs-API-Paket abhängig zu sein, müssen Sie Ihre Abhängigkeit in Ihrer Package.swift
deklarieren:
. package ( url : " https://github.com/apple/swift-log.git " , from : " 1.0.0 " ) ,
Fügen Sie zu Ihrem Anwendungs-/Bibliotheksziel "Logging"
zu Ihren dependencies
hinzu, z. B. so:
. target ( name : " BestExampleApp " , dependencies : [
. product ( name : " Logging " , package : " swift-log " )
] ,
// 1) let's import the logging API package
import Logging
// 2) we need to create a logger, the label works similarly to a DispatchQueue label
let logger = Logger ( label : " com.example.BestExampleApp.main " )
// 3) we're now ready to use it
logger . info ( " Hello World! " )
2019-03-13T15:46:38+0000 info: Hello World!
Logger
SwiftLog
bietet über StreamLogHandler
eine sehr einfache Konsolenprotokollierung, die sofort einsatzbereit ist. Es ist möglich, die Standardausgabe wie folgt auf stderr
umzustellen:
LoggingSystem . bootstrap ( StreamLogHandler . standardError )
StreamLogHandler
dient in erster Linie nur der Annehmlichkeit und bietet keine wesentlichen Anpassungsmöglichkeiten. Bibliotheksbetreuer, die ihre eigenen Protokollierungs-Backends für die Integration und Nutzung erstellen möchten, sollten das LogHandler
-Protokoll direkt implementieren, wie im Abschnitt „Über die Implementierung eines Protokollierungs-Backends“ beschrieben.
Weitere Informationen finden Sie in der API-Dokumentation.
Sie können eines der folgenden Backends auswählen, um Ihre Protokolle zu nutzen. Wenn Sie an der Implementierung interessiert sind, sehen Sie sich den Abschnitt „Überlegungen zur Implementierung“ weiter unten an, in dem erläutert wird, wie das geht. Liste der vorhandenen SwiftLog API-kompatiblen Bibliotheken:
Repository | Beschreibung des Handlers |
---|---|
Kitura/HeliumLogger | ein im Kitura-Ökosystem weit verbreitetes Protokollierungs-Backend |
ianpartridge/swift-log- syslog | ein Syslog-Backend |
Adorkable/swift-log- format-and-pipe | ein Backend, das die Anpassung des Ausgabeformats und des resultierenden Ziels ermöglicht |
chrisaljoudi/swift-log- oslog | ein OSLog Unified Logging-Backend zur Verwendung auf Apple-Plattformen. Wichtiger Hinweis: Wir empfehlen die direkte Verwendung von os_log wie hier beschrieben. Die Verwendung von os_log über Swift-Log mit diesem Backend ist weniger effizient und verhindert auch die Angabe der Vertraulichkeit der Nachricht. Das Backend verwendet immer %{public}@ als Formatzeichenfolge und wandelt alle Zeichenfolgeninterpolationen eifrig in Zeichenfolgen um. Dies hat zwei Nachteile: 1. Die statischen Komponenten der String-Interpolation würden vom einheitlichen Protokollierungssystem gerne kopiert, was zu Leistungsverlusten führen würde. 2. Dadurch werden alle Nachrichten öffentlich, wodurch sich die Standard-Datenschutzrichtlinie von os_log ändert und die Angabe eines fein abgestuften Datenschutzes für Abschnitte der Nachricht nicht möglich ist. In einer separaten laufenden Arbeit werden die Swift-APIs für os_log verbessert und an die Swift-Log-APIs angepasst. Referenzen: Protokollierungsebenen vereinheitlichen, os_log dazu bringen, String-Interpolationen mithilfe der Interpretation zur Kompilierungszeit zu akzeptieren. |
Brainfinance/StackdriverLogging | ein strukturiertes JSON-Protokollierungs-Backend zur Verwendung auf der Google Cloud Platform mit dem Stackdriver-Protokollierungsagenten |
DnV1eX/GoogleCloudLogging | eine clientseitige Bibliothek zum Protokollieren von Anwendungsereignissen in Google Cloud über REST API v2. |
Dampf-/Konsolen-Kit | einen Logger an das aktuelle Terminal oder stdout mit stilisierter (ANSI) Ausgabe. Der Standard-Logger für alle Vapor-Anwendungen |
neallester/swift-log-testing | Bietet Zugriff auf Protokollnachrichten zur Verwendung in Behauptungen (innerhalb von Testzielen). |
wlisac/swift-log-slack | ein Protokollierungs-Backend, das kritische Protokollnachrichten an Slack sendet |
NSHipster/swift-log-github-actions | ein Protokollierungs-Backend, das Protokollierungsnachrichten in Workflow-Befehle für GitHub-Aktionen übersetzt. |
stevapple/swift-log-telegram | ein Protokollierungs-Backend, das Protokollnachrichten an jeden Telegram-Chat sendet (inspiriert von und abgeleitet von wlisac/swift-log-slack) |
jagreenwood/swift-log-datadog | ein Protokollierungs-Backend, das Protokollnachrichten an den Datadog-Protokollverwaltungsdienst sendet |
google/SwiftLogFireCloud | ein Protokollierungs-Backend für die Zeitreihenprotokollierung, das Protokolle als Flatfiles an Firebase Cloud Storage überträgt. |
crspybits/swift-log-file | ein einfacher lokaler Dateilogger (mit Foundation FileManager ) |
Sushichop/Welpe | ein Protokollierungs-Backend, das mehrere Transporte (Konsole, Datei, Syslog usw.) unterstützt und über die Funktion zur Formatierung und Dateiprotokollrotation verfügt |
ShivaHuang/swift-log-SwiftyBeaver | ein Protokollierungs-Backend zum Drucken farbiger Protokollierung an die Xcode-Konsole/-Datei oder zum Senden verschlüsselter Protokollierung an die SwiftyBeaver-Plattform. |
Apodini/Swift-Log-Elch | ein Protokollierungs-Backend, das Protokolldaten formatiert, zwischenspeichert und an Elastic/Logstash sendet |
binärscraping/swift-log-supabase | ein Protokollierungs-Backend, das Protokolleinträge an Supabase sendet. |
kiliankoe/swift-log-matrix | ein Protokollierungs-Backend zum direkten Senden von Protokollen an einen Matrix-Raum |
DiscordBM/DiscordLogger | eine Discord-Protokollierungsimplementierung, um Ihre Protokolle auf ansprechende Weise und mit vielen Konfigurationsoptionen an einen Discord-Kanal zu senden, einschließlich der Möglichkeit, nur einige wichtige Protokollebenen wie warning / error / critical zu senden. |
KakaoHolzfäller | ein schnelles und einfaches, aber dennoch leistungsstarkes und flexibles Protokollierungsframework für macOS, iOS, tvOS und watchOS, das ein Protokollierungs-Backend für Swift-Log enthält. |
rwbutler/swift-log-ecs | ein Protokollierungs-Backend für die Protokollierung im ECS-Protokollformat. Kompatibel mit Vapor und ermöglicht die Verkettung mehrerer LogHandler. |
ShipBook/Swift-Log -Schiffsbuch | ein Protokollierungs-Backend, das Protokolleinträge an Shipbook sendet – Shipbook gibt Ihnen die Möglichkeit, Ihre Benutzerprotokolle und Ausnahmen in der Cloud aus der Ferne zu sammeln, zu durchsuchen und zu analysieren, und zwar pro Benutzer und Sitzung. |
Ihre Bibliothek? | Nehmen Sie Kontakt auf! |
Ich bin froh, dass du gefragt hast. Wir glauben, dass es für das Swift on Server-Ökosystem von entscheidender Bedeutung ist, über eine Protokollierungs-API zu verfügen, die von jedem übernommen werden kann, damit eine Vielzahl von Bibliotheken verschiedener Parteien alle an einem gemeinsamen Ziel protokollieren können. Konkreter bedeutet dies, dass wir davon ausgehen, dass alle Protokollnachrichten aus allen Bibliotheken in derselben Datei, Datenbank, derselben Elastic Stack-/Splunk-Instanz oder was auch immer Sie wählen, landen.
In der Praxis gibt es jedoch so viele Meinungen darüber, wie sich ein Protokollierungssystem genau verhalten sollte, wie eine Protokollnachricht formatiert sein sollte und wo/wie sie gespeichert werden sollte. Wir glauben, dass es nicht machbar ist, darauf zu warten, dass ein Protokollierungspaket alles unterstützt, was eine bestimmte Bereitstellung benötigt, und gleichzeitig einfach genug zu verwenden und leistungsfähig bleibt. Deshalb haben wir beschlossen, das Problem zu halbieren:
Dieses Paket stellt nur die Protokollierungs-API selbst bereit und daher ist SwiftLog
ein „Protokollierungs-API-Paket“. SwiftLog
(mit LoggingSystem.bootstrap
) kann so konfiguriert werden, dass eine beliebige kompatible Protokollierungs-Backend-Implementierung ausgewählt wird. Auf diese Weise können Pakete die API übernehmen und die Anwendung kann jede kompatible Protokollierungs-Backend-Implementierung auswählen, ohne dass Änderungen an einer der Bibliotheken erforderlich sind.
Nur der Vollständigkeit halber: Dieses API-Paket enthält tatsächlich eine übermäßig vereinfachte und nicht konfigurierbare Protokollierungs-Backend-Implementierung, die einfach alle Protokollnachrichten nach stdout
schreibt. Der Grund für die Einbeziehung dieser zu einfachen Protokollierungs-Backend-Implementierung besteht darin, das erstmalige Nutzungserlebnis zu verbessern. Nehmen wir an, Sie starten ein Projekt und probieren SwiftLog
zum ersten Mal aus. Es ist einfach viel besser, etwas, das Sie protokolliert haben, in einem vereinfachten Format auf stdout
angezeigt zu sehen, als dass überhaupt nichts passiert. Für jede reale Anwendung empfehlen wir die Konfiguration einer anderen Protokollierungs-Backend-Implementierung, die in dem von Ihnen gewünschten Stil protokolliert.
Logger
werden zum Ausgeben von Protokollnachrichten verwendet und sind daher der wichtigste Typ in SwiftLog
. Daher sollte ihre Verwendung so einfach wie möglich sein. Am häufigsten werden sie verwendet, um Protokollmeldungen in einer bestimmten Protokollebene auszugeben. Zum Beispiel:
// logging an informational message
logger . info ( " Hello World! " )
// ouch, something went wrong
logger . error ( " Houston, we have a problem: ( problem ) " )
Die folgenden Protokollebenen werden unterstützt:
trace
debug
info
notice
warning
error
critical
Die Protokollebene eines bestimmten Loggers kann geändert werden, die Änderung wirkt sich jedoch nur auf den spezifischen Logger aus, auf dem Sie sie geändert haben. Man könnte sagen, dass der Logger
ein Werttyp in Bezug auf die Protokollebene ist.
Protokollierungsmetadaten sind Metadaten, die an Logger angehängt werden können, um Informationen hinzuzufügen, die beim Debuggen eines Problems von entscheidender Bedeutung sind. Bei Servern ist das übliche Beispiel das Anhängen einer Anforderungs-UUID an einen Logger, die dann in allen mit diesem Logger protokollierten Protokollnachrichten vorhanden ist. Beispiel:
var logger = logger
logger [ metadataKey : " request-uuid " ] = " ( UUID ( ) ) "
logger . info ( " hello world " )
wird gedruckt
2019-03-13T18:30:02+0000 info: request-uuid=F8633013-3DD8-481C-9256-B296E43443ED hello world
mit der standardmäßigen Protokollierungs-Backend-Implementierung, die im Lieferumfang von SwiftLog
enthalten ist. Selbstverständlich wird das Format vollständig durch das von Ihnen gewählte Protokollierungs-Backend definiert.
LogHandler
)Hinweis: Wenn Sie kein benutzerdefiniertes Protokollierungs-Backend implementieren möchten, ist wahrscheinlich nicht alles in diesem Abschnitt sehr relevant. Sie können ihn also gerne überspringen.
Um ein kompatibles Protokollierungs-Backend zu werden, das alle SwiftLog
Konsumenten verwenden können, müssen Sie zwei Dinge tun: 1) Implementieren Sie einen Typ (normalerweise eine struct
), der LogHandler
implementiert, ein von SwiftLog
bereitgestelltes Protokoll, und 2) weisen Sie SwiftLog
an, Ihre Protokollierungs-Backend-Implementierung zu verwenden .
Ein LogHandler
oder eine Protokollierungs-Backend-Implementierung ist alles, was dem folgenden Protokoll entspricht
public protocol LogHandler {
func log ( level : Logger . Level , message : Logger . Message , metadata : Logger . Metadata ? , source : String , file : String , function : String , line : UInt )
subscript ( metadataKey _ : String ) -> Logger . Metadata . Value ? { get set }
var metadata : Logger . Metadata { get set }
var logLevel : Logger . Level { get set }
}
Es ist sehr einfach, SwiftLog
anzuweisen, Ihr Protokollierungs-Backend als dasjenige zu verwenden, das die gesamte Anwendung (einschließlich aller Bibliotheken) verwenden soll:
LoggingSystem . bootstrap ( MyLogHandler . init )
LogHandler
steuern die meisten Teile des Protokollierungssystems:
LogHandler
LogHandler
steuern die beiden entscheidenden Teile der Logger
-Konfiguration, nämlich:
logger.logLevel
)logger[metadataKey:]
und logger.metadata
) Damit das System funktioniert, ist es jedoch wichtig, dass LogHandler
die Konfiguration als Werttypen behandelt. Das bedeutet, dass LogHandler
s struct
sein sollten und eine Änderung der Protokollebene oder der Protokollierungsmetadaten sich nur auf genau den LogHandler
auswirken sollte, auf dem sie geändert wurde.
In besonderen Fällen ist es jedoch akzeptabel, dass ein LogHandler
eine globale Überschreibung der Protokollebene bereitstellt, die sich auf alle erstellten LogHandler
auswirken kann.
LogHandler
s LogHandler
s steuern nicht, ob eine Nachricht protokolliert werden soll oder nicht. Logger
ruft die log
eines LogHandler
nur dann auf, wenn Logger
feststellt, dass angesichts der konfigurierten Protokollebene eine Protokollmeldung ausgegeben werden soll.
Ein Logger
trägt eine (unveränderliche) label
und jede Protokollnachricht trägt einen source
(seit SwiftLog 1.3.0). Das Label des Logger
identifiziert den Ersteller des Logger
. Wenn Sie die strukturierte Protokollierung verwenden, indem Sie Metadaten über mehrere Module hinweg beibehalten, ist die label
des Logger
keine gute Möglichkeit, den Ursprung einer Protokollnachricht zu identifizieren, da sie den Ersteller eines Logger
identifiziert, der häufig zwischen Bibliotheken weitergegeben wird, um Metadaten zu bewahren und dergleichen.
Wenn Sie alle Protokollmeldungen filtern möchten, die von einem bestimmten Subsystem stammen, filtern Sie nach der source
, die standardmäßig das Modul ist, das die Protokollmeldung ausgibt.
Weitere Informationen zum Sicherheitsprozess von SwiftLog finden Sie unter SECURITY.md.
Diese Protokollierungs-API wurde mit den Mitwirkenden der Swift on Server-Community entwickelt und von der SSWG (Swift Server Work Group) auf der „Sandbox-Ebene“ des SSWG-Inkubationsprozesses genehmigt.