SwiftBox 是一个基于 SwiftNIO 的包,它有助于构建基于 Swift/NIO 的微服务。
使用 Swift 运行微服务需要:
即将推出:与 https://github.com/apple/swift-log 集成。
SwiftBox 配置允许通过声明一个简单的结构体来传递类型安全的配置,例如命令行、环境变量和外部提供程序(例如 Vault)。配置可以同时从多个来源继承。
通过以下方式提供配置:
./yourapp --config:simple=test --config:nested.number=1 --config:array.0=string
SIMPLE=test NESTED_NUMBER=1 ARRAY_0=string ./yourapp
SwiftBox 配置支持:
导入模块
import SwiftBoxConfig
创建配置时,请记住,为了正确解码,它必须符合 Configuration
协议。
struct Conf: Configuration {
let simple: String
let int: Int
let double: Double
let nested: NestedConf // nested configuration
let array: [String?] // array of optionals
let arraynested: [NestedConf] // nested array
struct NestedConf: Configuration {
let value: String? // optional
}
}
配置在使用前必须进行引导。 为此,您需要首先符合 ConfigManager
协议
extension Conf: ConfigManager {
public static var configuration: Conf? = nil
}
接下来,在您的 ConfigManager
上调用 bootstrap
方法,并传递您想要使用的来源
try Conf.bootstrap(from: [EnvSource()])
请记住,引导必须在使用配置之前调用,并且不能多次调用。 否则,将抛出 fatalError
。
完成所有之前的步骤后,您最终可以在您的应用程序中使用配置。您可以通过 global
属性访问配置实例
Conf.global.simple
Conf.global.int
Conf.global.double
Conf.global.array[0] // Optional[String]
Conf.global.nested.value // Optional[String]
Conf.global.arraynested[0].value // Optional[String]
配置可以从多个来源提供。来源被传递到引导函数中。
如果您使用多个来源,输出将被合并(结构体被递归合并,其他值被覆盖)
try Conf.bootstrap(from: [
DictionarySource(dataSource: [
"int": 1,
"string": "some",
"array": [1, 2],
"nested": ["value1": 1]
]),
DictionarySource(dataSource: [
"string": "test",
"array": [2, 3],
"nested": ["value2": 2]
]),
])
// Output config:
[
"int": 1,
"string": "test",
"array": [2, 3],
"nested": [
"value1": 1,
"value2": 2
]
]
允许从字典读取配置,可用于指定配置的内联代码默认值。
try Conf.bootstrap(from: [
DictionarySource(dataSource: [
"int": 1,
"string": "some",
"array": [1, 2],
"nested": ["value1": 1]
])
])
允许从 JSON 数据读取配置。
try Conf.bootstrap(from: [
JSONSource(dataSource: "{\"test\": \"sample\"}")
])
允许从环境变量读取配置数据。
try Conf.bootstrap(from: [
EnvSource(prefix: "SAMPLE")
])
可以为 EnvSource
设置前缀,因此它只读取键以给定值开头的变量。
struct Conf: Configuration {
let simple: String
let int: Int
let double: Double
let nested: NestedConf
let array: [String?]
let arraynested: [NestedConf]
struct NestedConf: Configuration {
let value: String?
}
}
可以使用以下环境变量填充以上示例
SIMPLE="test"
INT="1"
DOUBLE="1.0"
NULL="null"
NESTED_VALUE="test"
ARRAY_0="test0"
ARRAY_1="test1"
ARRAY_2="null"
ARRAYNESTED_0_VALUE="test0"
ARRAYNESTED_1_VALUE="test1"
ARRAYNESTED_2_VALUE="null"
值 "null" 被强制转换为内部 nil 值
允许从环境变量读取配置数据。
Conf.bootstrap(from: [
CommandLineSource(prefix: "--config:my-prefix-")
])
如果设置了前缀,则只会读取以给定值开头的参数。 默认为 --config:
struct Conf: Configuration {
let simple: String
let int: Int
let double: Double
let null: String?
let nested: NestedConf
let array: [String?]
let arraynested: [NestedConf]
struct NestedConf: Configuration {
let value: String?
}
}
可以使用以下命令行参数填充以上示例
--config:simple=test
--config:int=1
--config:double=1.0
--config:null=null
--config:nested.value=test
--config:array.0=test0
--config:array.1=test1
--config:array.2=null
--config:arraynested.0.value=test0
--config:arraynested.1.value=test1
--config:arraynested.2.value=null
值 "null" 被强制转换为内部 nil 值
要创建自定义来源,您需要创建一个符合 ConfigSource
的类。 DictionarySource
是最简单的工作来源,可以用作示例
public typealias Storage = [String: Any?]
public class DictionarySource: ConfigSource {
let dataSource: Storage
public init(dataSource: Storage) {
self.dataSource = dataSource
}
public func getConfig() throws -> Storage {
return self.dataSource
}
}
Swift 的日志记录系统。
import SwiftBoxLogging
日志记录应在使用前进行引导(默认为 PrintLogger
)。 引导需要一个参数,即日志记录器工厂。
日志记录器工厂必须从 swift-log 包返回 LogHandler
。
Logging.bootstrap { label in ElasticsearchLogHandler(label: name) }
创建一个日志记录器实例
fileprivate var logger = Logging.make(#file)
使用可用的协议方法之一记录消息
func trace(_ message: String)
func info(_ message: String)
func debug(_ message: String)
func notice(_ message: String)
func warning(_ message: String)
func error(_ message: String)
func critical(_ message: String)
要创建自定义日志记录器,您的类必须符合 LoggerProtocol
。
您可以通过覆盖 Vapor 的默认日志处理程序来使用相同的日志记录
import Logging
LoggingSystem.bootstrap { label in
ElasticsearchLogHandler(label: label)
}
官方 swift-metrics API 的 StatsD 和 Logger 处理程序。
支持的指标类型
import Metrics
import SwiftBoxMetrics
指标必须使用符合 MetricsHandler
协议的 Handler 进行引导
// StatsD Handler initialization
MetricsSystem.bootstrap(
try! StatsDMetricsHandler(
baseMetricPath: AppConfig.global.statsd.basePath!,
client: UDPStatsDClient(
config: UDPConnectionConfig(
host: AppConfig.global.statsd.host!,
port: AppConfig.global.statsd.port!
)
)
)
)
// Logger Handler initialization
MetricsSystem.bootstrap(LoggerMetricsHandler())
用法详情可以在官方 swift-metrics GitHub 存储库中找到。
默认指标处理程序,将收集的指标发送到其日志记录器。
StatsD 指标处理程序负责将收集的日志发送到 StatsD 服务器。 支持 TCP 和 UDP 协议。 指标在单独的线程中发送,因此操作对于应用程序是非阻塞的。
try StatsDMetricsHandler(
baseMetricPath: AppConfig.global.statsd.basePath!,
client: UDPStatsDClient(
config: UDPConnectionConfig(
host: AppConfig.global.statsd.host!,
port: AppConfig.global.statsd.port!
)
)
)
baseMetricPath
是一个路径,它将附加到通过处理程序发送的每个指标。 client
是一个 TCPStatsDClient
或 UDPStatsDClient
实例。
要创建自定义处理程序,请符合 MetricsHandler
类。