Перво-наперво: это начало управляемого сообществом проекта с открытым исходным кодом, активно ищущего вклад, будь то код, документация или идеи. Помимо вклада в сам SwiftLog
, на данный момент есть еще один огромный пробел: SwiftLog
— это пакет API , который пытается создать общий API, который может использовать экосистема. Чтобы ведение журналов действительно работало для реальных рабочих нагрузок, нам нужны SwiftLog
-совместимые серверы журналирования , которые затем либо сохраняют сообщения журнала в файлах, отображают их в более приятных цветах на терминале, либо отправляют их в Splunk или ELK.
То, что SwiftLog
предоставляет сегодня, можно найти в документации API.
Если у вас есть серверное приложение Swift или, возможно, кроссплатформенное (например, Linux и macOS) приложение/библиотека, и вы хотите вести журналы, мы считаем, что выбор этого пакета API журналирования — отличная идея. Ниже вы найдете все, что вам нужно знать, чтобы начать работу.
SwiftLog
предназначен для Swift 5.8 и более поздних версий. Чтобы зависеть от пакета API журналирования, вам необходимо объявить свою зависимость в Package.swift
:
. package ( url : " https://github.com/apple/swift-log.git " , from : " 1.0.0 " ) ,
и к цели вашего приложения/библиотеки добавьте "Logging"
к вашим dependencies
, например так:
. 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
обеспечивает базовое ведение журнала консоли «из коробки» с помощью StreamLogHandler
. Можно переключить вывод по умолчанию на stderr
следующим образом:
LoggingSystem . bootstrap ( StreamLogHandler . standardError )
StreamLogHandler
предназначен в первую очередь только для удобства и не обеспечивает каких-либо существенных настроек. Сопровождающие библиотеки, которые стремятся создать свои собственные серверные части журналирования для интеграции и использования, должны реализовать протокол LogHandler
напрямую, как описано в разделе «О реализации серверной части журналирования».
Для получения дополнительной информации ознакомьтесь с документацией API.
Вы можете выбрать один из следующих серверов для использования ваших журналов. Если вы заинтересованы в его реализации, см. раздел «Вопросы реализации» ниже, где объясняется, как это сделать. Список существующих библиотек, совместимых с SwiftLog API:
Репозиторий | Описание обработчика |
---|---|
Китура/HeliumLogger | серверная часть журналирования, широко используемая в экосистеме Kitura |
ianpartridge/swift-log- системный журнал | серверная часть системного журнала |
Очаровательный/быстрый формат журнала и канал | серверная часть, которая позволяет настраивать формат вывода и конечный пункт назначения |
chrisaljoudi/swift-log- oslog | серверная часть унифицированного ведения журнала OSLog для использования на платформах Apple. Важное примечание: мы рекомендуем использовать os_log напрямую, как описано здесь. Использование os_log через Swift-log с использованием этого бэкэнда будет менее эффективным, а также не позволит указать конфиденциальность сообщения. Серверная часть всегда использует %{public}@ в качестве строки формата и быстро преобразует все интерполяции строк в строки. У этого есть два недостатка: 1. статические компоненты интерполяции строк будут охотно копироваться единой системой журналирования, что приведет к потере производительности. 2. Он делает все сообщения общедоступными, что меняет политику конфиденциальности os_log по умолчанию и не позволяет указать детальную конфиденциальность разделов сообщения. В рамках отдельной текущей работы API-интерфейсы Swift для os_log улучшаются и приводятся в соответствие с API-интерфейсами Swift-log. Ссылки: Унификация уровней ведения журнала, Заставление os_log принимать интерполяцию строк с использованием интерпретации во время компиляции. |
Brainfinance/StackdriverLogging | структурированный сервер ведения журнала JSON для использования на Google Cloud Platform с агентом ведения журналов Stackdriver. |
DnV1eX/GoogleCloudLogging | клиентская библиотека для регистрации событий приложений в Google Cloud через REST API v2. |
комплект Vapor/консоли | логгер для текущего терминала или стандартного вывода со стилизованным (ANSI) выводом. Регистратор по умолчанию для всех приложений Vapor. |
Neallester/Swift-log-тестирование | обеспечивает доступ к сообщениям журнала для использования в утверждениях (в пределах тестовых целей) |
wlisac/swift-log-slack | серверная часть журналирования, которая отправляет критические сообщения журнала в Slack |
NSHipster/swift-log-github-действия | серверная часть ведения журнала, которая преобразует сообщения журнала в команды рабочего процесса для действий GitHub. |
stevaple/swift-log-telegram | серверная часть журнала, которая отправляет сообщения журнала в любой чат Telegram (вдохновлено и разветвлено на wlisac/swift-log-slack) |
jagreenwood/swift-log-datadog | серверная часть ведения журнала, которая отправляет сообщения журнала в службу управления журналами Datadog |
Google/SwiftLogFireCloud | серверная часть для ведения журнала временных рядов, которая передает журналы в виде плоских файлов в облачное хранилище Firebase. |
crspybits/swift-log-файл | простой локальный регистратор файлов (с использованием Foundation FileManager ) |
сушичоп/Щенок | серверная часть журнала, которая поддерживает несколько транспортов (консоль, файл, системный журнал и т. д.) и имеет функцию форматирования и ротации журнала файлов. |
ШиваХуанг/swift-log-SwiftyBeaver | серверная часть журнала для печати цветных журналов в консоль/файл Xcode или отправки зашифрованных журналов на платформу SwiftyBeaver. |
Аподини / лось-стриж | серверная часть журнала, которая форматирует, кэширует и отправляет данные журнала в elastic/logstash |
двоичный очистка/быстрый журнал-супабаза | серверная часть журналирования, которая отправляет записи журнала в Supabase. |
килианкое/swift-log-matrix | серверная часть журналов для отправки журналов непосредственно в комнату Matrix |
DiscordBM/DiscordLogger | реализация ведения журнала Discord для удобной отправки ваших журналов на канал Discord и с множеством параметров конфигурации, включая возможность отправлять только несколько важных уровней журнала, таких как warning / error / critical . |
КакаоДровосек | быстрая и простая, но мощная и гибкая платформа ведения журналов для macOS, iOS, tvOS и watchOS, которая включает в себя серверную часть ведения журналов для Swift-log. |
rwbutler/swift-log-ecs | серверная часть для ведения журналов в формате журнала ECS. Совместим с Vapor и позволяет объединять несколько LogHandlers в цепочку. |
ShipBook/swift-log- судовая книга | серверная часть журнала, которая отправляет записи журнала в Shipbook. Shipbook дает вам возможность удаленно собирать, искать и анализировать ваши пользовательские журналы и исключения в облаке для каждого пользователя и сеанса. |
Ваша библиотека? | Свяжитесь с нами! |
Рад, что вы спросили. Мы считаем, что для экосистемы Swift on Server крайне важно иметь API ведения журналов, который может быть принят кем угодно, чтобы множество библиотек от разных сторон могли регистрироваться в общем месте назначения. Более конкретно, это означает, что мы считаем, что все сообщения журнала из всех библиотек попадают в один и тот же файл, базу данных, экземпляр Elastic Stack/Splunk или что-то еще по вашему выбору.
Однако в реальном мире существует очень много мнений о том, как именно должна вести себя система журналирования, как следует форматировать сообщения журнала и где/как их следует сохранять. Мы считаем, что нецелесообразно ждать, пока один пакет журналирования будет поддерживать все, что требуется для конкретного развертывания, но при этом будет достаточно простым в использовании и останется производительным. Поэтому мы решили сократить проблему вдвое:
Этот пакет предоставляет только сам API ведения журналов, поэтому SwiftLog
является «пакетом API ведения журналов». SwiftLog
(с использованием LoggingSystem.bootstrap
) можно настроить на выбор любой совместимой реализации бэкэнда ведения журналов. Таким образом, пакеты могут использовать API, а приложение может выбрать любую совместимую реализацию серверной части журналирования, не требуя каких-либо изменений в какой-либо из библиотек.
Просто для полноты картины: этот пакет API на самом деле включает в себя слишком упрощенную и ненастраиваемую реализацию серверной части журналирования, которая просто записывает все сообщения журнала в stdout
. Причина включения этой слишком упрощенной реализации серверной части журналирования состоит в том, чтобы улучшить удобство использования при первом использовании. Предположим, вы запускаете проект и впервые пробуете SwiftLog
. Гораздо лучше видеть, что записанные вами данные отображаются на stdout
в упрощенном формате, чем вообще ничего не происходит. Для любого реального приложения мы советуем настроить другую реализацию серверной части журналирования, которая будет вести журнал в том стиле, который вам нравится.
Logger
используются для отправки сообщений журнала и, следовательно, являются наиболее важным типом в SwiftLog
, поэтому их использование должно быть максимально простым. Чаще всего они используются для отправки сообщений журнала на определенном уровне журнала. Например:
// logging an informational message
logger . info ( " Hello World! " )
// ouch, something went wrong
logger . error ( " Houston, we have a problem: ( problem ) " )
Поддерживаются следующие уровни журнала:
trace
debug
info
notice
warning
error
critical
Уровень журнала данного регистратора можно изменить, но это изменение повлияет только на тот конкретный регистратор, на котором вы его изменили. Можно сказать, Logger
— это тип значения , относящийся к уровню журнала.
Метаданные журналирования — это метаданные, которые можно прикрепить к средствам журналирования для добавления информации, которая имеет решающее значение при отладке проблемы. На серверах обычным примером является прикрепление UUID запроса к средству ведения журнала, который затем будет присутствовать во всех сообщениях журнала, зарегистрированных с помощью этого средства ведения журнала. Пример:
var logger = logger
logger [ metadataKey : " request-uuid " ] = " ( UUID ( ) ) "
logger . info ( " hello world " )
напечатаю
2019-03-13T18:30:02+0000 info: request-uuid=F8633013-3DD8-481C-9256-B296E43443ED hello world
с реализацией бэкэнда ведения журналов по умолчанию, которая поставляется вместе со SwiftLog
. Излишне говорить, что формат полностью определяется выбранным вами сервером ведения журнала.
LogHandler
)Примечание. Если вы не хотите реализовывать собственный сервер ведения журналов, все в этом разделе, вероятно, не очень актуально, поэтому смело пропускайте его.
Чтобы стать совместимым сервером ведения журналов, который смогут использовать все потребители SwiftLog
, вам нужно сделать две вещи: 1) реализовать тип (обычно struct
), который реализует LogHandler
, протокол, предоставляемый SwiftLog
, и 2) дать SwiftLog
указание использовать реализацию вашего бэкэнда ведения журналов. .
Реализация LogHandler
или серверной части журналирования — это все, что соответствует следующему протоколу.
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 }
}
Указание SwiftLog
использовать ваш бэкэнд журналирования как тот, который должно использовать все приложение (включая все библиотеки), очень просто:
LoggingSystem . bootstrap ( MyLogHandler . init )
LogHandler
контролирует большую часть системы журналирования:
LogHandler
LogHandler
контролирует две важные части конфигурации Logger
, а именно:
logger.logLevel
)logger[metadataKey:]
и logger.metadata
) Однако для работы системы важно, чтобы LogHandler
рассматривал конфигурацию как типы значений . Это означает, что LogHandler
должны быть struct
, а изменение уровня журнала или метаданных журналирования должно влиять только на тот самый LogHandler
на котором оно было изменено.
Однако в особых случаях допустимо, чтобы LogHandler
предоставлял некоторое переопределение глобального уровня журнала, которое может повлиять на все созданные LogHandler
.
LogHandler
s LogHandler
не контролирует, должно ли сообщение регистрироваться или нет. Logger
будет вызывать функцию log
LogHandler
только в том случае, если Logger
определит, что сообщение журнала должно быть создано с учетом настроенного уровня журнала.
Logger
имеет (неизменяемую) label
, а каждое сообщение журнала содержит параметр source
(начиная с SwiftLog 1.3.0). Ярлык Logger
идентифицирует создателя Logger
. Если вы используете структурированное ведение журнала, сохраняя метаданные в нескольких модулях, label
Logger
не является хорошим способом определить, откуда пришло сообщение журнала, поскольку оно идентифицирует создателя Logger
, который часто передается между библиотеками для сохранения метаданных и подобное.
Если вы хотите отфильтровать все сообщения журнала, исходящие из определенной подсистемы, отфильтруйте по source
, который по умолчанию соответствует модулю, отправляющему сообщение журнала.
Пожалуйста, посетите SECURITY.md, чтобы узнать о процессе обеспечения безопасности SwiftLog.
Этот API ведения журнала был разработан совместно с участниками сообщества Swift on Server и одобрен SSWG (Рабочая группа Swift Server) для «уровня песочницы» инкубационного процесса SSWG.