LoggingELK 库为 Apple 的 apple/swift-log 包(它基本上只定义了一个日志 API)提供了一个日志后端。日志条目被正确格式化、缓存,然后通过 HTTP/HTTPS 上传到 elastic/logstash,以便在其管道中进行进一步处理。然后,日志可以存储在 elastic/elasticsearch 中,并在 elastic/kibana 中可视化。
LoggingELK 需要 Xcode 12 或带有 Swift Package Manager 的 Swift 5.4 工具链。
将 swift-log
和 swift-log-elk
包作为依赖项添加到您的 Package.swift
文件中。
dependencies: [
.package(url: "https://github.com/apple/swift-log.git", from: "1.0.0"),
.package(url: "https://github.com/Apodini/swift-log-elk.git", from: "0.1.0")
]
将 Logging
(来自 swift-log
)和 LoggingELK
(来自 swift-log-elk
)添加到您的目标的依赖项中。
targets: [
.target(
name: "ExampleWebService",
dependencies: [
.product(name: "Logging", package: "swift-log"),
.product(name: "LoggingELK", package: "swift-log-elk")
]
)
]
导入 Logging
和 LoggingELK
模块
import Logging
import LoggingELK
使用适当的配置设置 LogstashLogHandler
,并在应用程序的生命周期中一次性注册要使用的日志后端
// Setup of LogstashLogHandler
LogstashLogHandler.setup(hostname: "0.0.0.0", port: 31311)
// Register LogstashLogHandler in the LoggingSystem
LoggingSystem.bootstrap(LogstashLogHandler.init)
重要提示: 在 LoggingSystem
中注册 LogstashLogHandler
之前,请先设置它!
此外,可以注册多个日志后端。一种选择是将日志发送到 Logstash,同时将其打印到控制台
// Setup of LogstashLogHandler
LogstashLogHandler.setup(hostname: "0.0.0.0", port: 31311)
// Register LogHandlers in the LoggingSystem
LoggingSystem.bootstrap { label in
MultiplexLogHandler(
[
LogstashLogHandler(label: label),
StreamLogHandler.standardOutput(label: label)
]
)
}
LogstashLogHandler
还可以配置超出标准配置值。下面您可以看到最大可能配置选项的示例。开发者可以例如指定是否应使用 HTTPS(即 TLS 加密),用于处理 HTTP 请求的 EventLoopGroup
,记录 LogstashLogHandler
或网络连接的后台活动的 Logger
,以及某个 uploadInterval
,即日志数据应以什么时间间隔上传到 Logstash。此外,还可以配置缓存日志数据的缓冲区大小以及所有日志缓冲区的最大总大小(因为在上传期间会创建临时缓冲区)。
重要提示: maximumTotalLogStorageSize
必须至少是 logStorageSize
的两倍大(这也在 LogstashLogHandler
的实例化期间进行验证)。原因是上传日志数据期间分配的临时缓冲区,以便同时进行的日志记录调用不会阻塞(除了将日志复制到临时缓冲区所需的时间,这非常快)。
为什么至少是两倍大?如果在上传“旧”日志数据期间日志存储空间已满,则可能会重复分配临时缓冲区的过程。一种可能的情况是,网络连接到 Logstash 的环境非常慢,因此上传需要很长时间。此过程可能会一遍又一遍地重复,直到达到 maximumTotalLogStorageSize
。然后,新的日志记录调用会阻塞,直到有足够的内存空间再次可用,这是通过部分完成的日志数据上传来实现的,从而释放临时缓冲区。在实践中,接近 maximumTotalLogStorageSize
基本上永远不会发生,除非在资源非常受限的环境中。
// Setup of LogstashLogHandler
LogstashLogHandler.setup(
hostname: "0.0.0.0",
port: 31311,
useHTTPS: false,
eventLoopGroup: eventLoopGroup,
backgroundActivityLogger: logger,
uploadInterval: TimeAmount.seconds(5),
logStorageSize: 500_000,
maximumTotalLogStorageSize: 4_000_000
)
// Register LogstashLogHandler in the LoggingSystem
LoggingSystem.bootstrap(LogstashLogHandler.init)
现在 LogstashLogHandler
的设置已完成,您可以像往常一样使用 SwiftLog
(也包括元数据等)。
import Logging
let logger = Logger(label: "com.example.WebService")
logger.info("This is a test!")
要实际使用 LogstashLogHandler
,显然还剩下最后一步:设置一个 elastic/logstash 实例,日志将发送到该实例。本地 Logstash 实例可能最简单的设置是使用 docker/elk,它提供了由 Docker 和 Docker-compose 驱动的整个 Elastic 堆栈 (ELK)。ELK 堆栈允许我们收集、分析和呈现日志数据以及更多内容。请按照存储库的 README.me 中的说明正确设置和配置 ELK 堆栈。
然后,我们需要配置 Logstash 管道以接受特定主机和端口上的 HTTP 输入。这可以在 Logstash 管道配置文件 中完成。只需像这样调整文件的 input
部分,以允许在端口 31311 上本地上传日志
input {
http {
host => "0.0.0.0"
port => 31311
}
}
此外,要使用 LogstashLogHandler
创建的时间戳(而不是实际发送到 Logstash 的数据的时间戳),请像下面所示调整 Logstash 管道配置文件 的 filter
部分。第二个选项消除了来自 LogstashLogHandler
到 Logstash 的 HTTP 请求标头,因为这些标头也会被保存到日志条目中(这绝对与我们无关)。
filter {
date {
match => [ "timestamp", "ISO8601" ]
locale => "en_US" # POSIX
target => "@timestamp"
}
mutate {
remove_field => ["headers"]
}
}
现在整个设置过程已完成,创建一些日志数据,然后自动发送到 Logstash(例如,请参阅上面的 设置日志记录部分)。
由于我们使用了整个 ELK 堆栈,而不仅仅是 Logstash,我们可以使用 elastic/kibana 立即可视化上传的日志数据。访问 Kibana Web 界面(在相应的端口上)并导航到 Analytics/Discover
。您创建的日志消息(包括元数据)现在应该在此处显示
恭喜,您通过 swift-log 和 swift-log-elk 将您的第一个日志发送到 elastic/logstash,将它们保存在 elastic/elasticsearch 中,并使用 elastic/kibana 可视化它们!🎉
有关如何准确使用 apple/swift-log 的日志记录功能的详细信息,请查看 swift-log 的文档。
查看我们的 API 参考,获取包的完整文档。
欢迎对此项目做出贡献。请务必先阅读 贡献指南。
本项目根据 MIT 许可证获得许可。有关更多信息,请参阅 许可证。