mirror of
https://github.com/Nanaloveyuki/BitLogger.git
synced 2026-05-30 15:42:25 +00:00
✨ Add split sink routing helpers
This commit is contained in:
@@ -182,6 +182,58 @@ test "callback sink receives record" {
|
||||
inspect(captured_message.val, content="hello")
|
||||
}
|
||||
|
||||
test "split sink routes records by predicate" {
|
||||
let left_messages : Ref[Array[String]] = Ref::new([])
|
||||
let right_messages : Ref[Array[String]] = Ref::new([])
|
||||
let logger = Logger::new(
|
||||
split_sink(
|
||||
callback_sink(fn(rec) {
|
||||
left_messages.val.push(rec.message)
|
||||
}),
|
||||
callback_sink(fn(rec) {
|
||||
right_messages.val.push(rec.message)
|
||||
}),
|
||||
fn(rec) {
|
||||
rec.target == "audit"
|
||||
},
|
||||
),
|
||||
min_level=Level::Info,
|
||||
target="main",
|
||||
)
|
||||
logger.info("drop to right")
|
||||
logger.log(Level::Info, "keep on left", target="audit")
|
||||
inspect(left_messages.val.length(), content="1")
|
||||
inspect(left_messages.val[0], content="keep on left")
|
||||
inspect(right_messages.val.length(), content="1")
|
||||
inspect(right_messages.val[0], content="drop to right")
|
||||
}
|
||||
|
||||
test "split_by_level routes warn and error separately" {
|
||||
let high_messages : Ref[Array[String]] = Ref::new([])
|
||||
let low_messages : Ref[Array[String]] = Ref::new([])
|
||||
let logger = Logger::new(
|
||||
split_by_level(
|
||||
callback_sink(fn(rec) {
|
||||
high_messages.val.push(rec.level.label() + ":" + rec.message)
|
||||
}),
|
||||
callback_sink(fn(rec) {
|
||||
low_messages.val.push(rec.level.label() + ":" + rec.message)
|
||||
}),
|
||||
min_level=Level::Warn,
|
||||
),
|
||||
min_level=Level::Trace,
|
||||
target="split",
|
||||
)
|
||||
logger.info("info")
|
||||
logger.warn("warn")
|
||||
logger.error("error")
|
||||
inspect(high_messages.val.length(), content="2")
|
||||
inspect(high_messages.val[0], content="WARN:warn")
|
||||
inspect(high_messages.val[1], content="ERROR:error")
|
||||
inspect(low_messages.val.length(), content="1")
|
||||
inspect(low_messages.val[0], content="INFO:info")
|
||||
}
|
||||
|
||||
test "callback sink sees child target and context logger shape" {
|
||||
let captured_target : Ref[String] = Ref::new("")
|
||||
let captured_message : Ref[String] = Ref::new("")
|
||||
|
||||
@@ -24,6 +24,8 @@ BitLogger 是一个基于 MoonBit 的结构化日志库。
|
||||
- `json_console_sink()` 提供 JSON 控制台输出
|
||||
- sink composition via `fanout_sink(...)`
|
||||
- `fanout_sink(...)` 支持多 sink 组合
|
||||
- sink routing via `split_sink(...)` and `split_by_level(...)`
|
||||
- `split_sink(...)`、`split_by_level(...)` 支持按谓词或 level 将日志路由到不同 sink
|
||||
- custom callback sink via `callback_sink(...)`
|
||||
- `callback_sink(...)` 支持自定义外部集成
|
||||
- buffered sink via `buffered_sink(...)`
|
||||
@@ -142,6 +144,24 @@ test {
|
||||
}
|
||||
```
|
||||
|
||||
```mbt check
|
||||
test {
|
||||
let logger = Logger::new(
|
||||
split_by_level(
|
||||
callback_sink(fn(rec) {
|
||||
println("high priority: \{rec.level.label()} \{rec.message}")
|
||||
}),
|
||||
console_sink(),
|
||||
min_level=Level::Warn,
|
||||
),
|
||||
min_level=Level::Trace,
|
||||
target="split",
|
||||
)
|
||||
logger.info("normal output")
|
||||
logger.warn("warning output")
|
||||
}
|
||||
```
|
||||
|
||||
```mbt check
|
||||
test {
|
||||
let formatter = text_formatter(
|
||||
|
||||
@@ -247,6 +247,34 @@ pub impl[A : Sink, B : Sink] Sink for FanoutSink[A, B] with write(self, rec) {
|
||||
self.right.write({ ..rec })
|
||||
}
|
||||
|
||||
pub struct SplitSink[A, B] {
|
||||
left : A
|
||||
right : B
|
||||
predicate : (Record) -> Bool
|
||||
}
|
||||
|
||||
pub fn[A, B] split_sink(left : A, right : B, predicate : (Record) -> Bool) -> SplitSink[A, B] {
|
||||
{ left, right, predicate }
|
||||
}
|
||||
|
||||
pub fn[A, B] split_by_level(
|
||||
left : A,
|
||||
right : B,
|
||||
min_level~ : Level = Level::Warn,
|
||||
) -> SplitSink[A, B] {
|
||||
split_sink(left, right, fn(rec) {
|
||||
rec.level.enabled(min_level)
|
||||
})
|
||||
}
|
||||
|
||||
pub impl[A : Sink, B : Sink] Sink for SplitSink[A, B] with write(self, rec) {
|
||||
if (self.predicate)(rec) {
|
||||
self.left.write(rec)
|
||||
} else {
|
||||
self.right.write(rec)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CallbackSink {
|
||||
callback : (Record) -> Unit
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user