mirror of
https://github.com/Nanaloveyuki/BitLogger.git
synced 2026-05-30 15:42:25 +00:00
♻️ Extract core and utils subpackages
This commit is contained in:
@@ -0,0 +1,31 @@
|
|||||||
|
pub(all) enum Level {
|
||||||
|
Trace
|
||||||
|
Debug
|
||||||
|
Info
|
||||||
|
Warn
|
||||||
|
Error
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn Level::priority(self : Level) -> Int {
|
||||||
|
match self {
|
||||||
|
Level::Trace => 10
|
||||||
|
Level::Debug => 20
|
||||||
|
Level::Info => 30
|
||||||
|
Level::Warn => 40
|
||||||
|
Level::Error => 50
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn Level::label(self : Level) -> String {
|
||||||
|
match self {
|
||||||
|
Level::Trace => "TRACE"
|
||||||
|
Level::Debug => "DEBUG"
|
||||||
|
Level::Info => "INFO"
|
||||||
|
Level::Warn => "WARN"
|
||||||
|
Level::Error => "ERROR"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn Level::enabled(self : Level, min_level : Level) -> Bool {
|
||||||
|
self.priority() >= min_level.priority()
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
import {
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
pub struct Field {
|
||||||
|
key : String
|
||||||
|
value : String
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn field(key : String, value : String) -> Field {
|
||||||
|
{ key, value }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fields(entries : Array[(String, String)]) -> Array[Field] {
|
||||||
|
entries.map(fn(entry) {
|
||||||
|
field(entry.0, entry.1)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Record {
|
||||||
|
level : Level
|
||||||
|
timestamp_ms : UInt64
|
||||||
|
target : String
|
||||||
|
message : String
|
||||||
|
fields : Array[Field]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn Record::new(
|
||||||
|
level : Level,
|
||||||
|
message : String,
|
||||||
|
timestamp_ms~ : UInt64 = 0UL,
|
||||||
|
target~ : String = "",
|
||||||
|
fields~ : Array[Field] = [],
|
||||||
|
) -> Record {
|
||||||
|
{ level, timestamp_ms, target, message, fields }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn Field::with_value(self : Field, value : String) -> Field {
|
||||||
|
field(self.key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn Record::with_target(self : Record, target : String) -> Record {
|
||||||
|
Record::new(
|
||||||
|
self.level,
|
||||||
|
self.message,
|
||||||
|
timestamp_ms=self.timestamp_ms,
|
||||||
|
target=target,
|
||||||
|
fields=self.fields,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn Record::with_message(self : Record, message : String) -> Record {
|
||||||
|
Record::new(
|
||||||
|
self.level,
|
||||||
|
message,
|
||||||
|
timestamp_ms=self.timestamp_ms,
|
||||||
|
target=self.target,
|
||||||
|
fields=self.fields,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn Record::with_fields(self : Record, fields : Array[Field]) -> Record {
|
||||||
|
Record::new(
|
||||||
|
self.level,
|
||||||
|
self.message,
|
||||||
|
timestamp_ms=self.timestamp_ms,
|
||||||
|
target=self.target,
|
||||||
|
fields=fields,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn Record::copy(self : Record) -> Record {
|
||||||
|
Record::new(
|
||||||
|
self.level,
|
||||||
|
self.message,
|
||||||
|
timestamp_ms=self.timestamp_ms,
|
||||||
|
target=self.target,
|
||||||
|
fields=self.fields,
|
||||||
|
)
|
||||||
|
}
|
||||||
+10
-48
@@ -1,75 +1,37 @@
|
|||||||
pub type RecordPredicate = (Record) -> Bool
|
pub type RecordPredicate = @utils.RecordPredicate
|
||||||
|
|
||||||
pub fn level_at_least(min_level : Level) -> RecordPredicate {
|
pub fn level_at_least(min_level : Level) -> RecordPredicate {
|
||||||
fn(rec) {
|
@utils.level_at_least(min_level)
|
||||||
rec.level.priority() >= min_level.priority()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn target_is(target : String) -> RecordPredicate {
|
pub fn target_is(target : String) -> RecordPredicate {
|
||||||
fn(rec) {
|
@utils.target_is(target)
|
||||||
rec.target == target
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn target_has_prefix(prefix : String) -> RecordPredicate {
|
pub fn target_has_prefix(prefix : String) -> RecordPredicate {
|
||||||
fn(rec) {
|
@utils.target_has_prefix(prefix)
|
||||||
rec.target.has_prefix(prefix)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn message_contains(fragment : String) -> RecordPredicate {
|
pub fn message_contains(fragment : String) -> RecordPredicate {
|
||||||
fn(rec) {
|
@utils.message_contains(fragment)
|
||||||
rec.message.contains(fragment)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_field(key : String) -> RecordPredicate {
|
pub fn has_field(key : String) -> RecordPredicate {
|
||||||
fn(rec) {
|
@utils.has_field(key)
|
||||||
for field in rec.fields {
|
|
||||||
if field.key == key {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn field_equals(key : String, value : String) -> RecordPredicate {
|
pub fn field_equals(key : String, value : String) -> RecordPredicate {
|
||||||
fn(rec) {
|
@utils.field_equals(key, value)
|
||||||
for field in rec.fields {
|
|
||||||
if field.key == key && field.value == value {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn not_(predicate : RecordPredicate) -> RecordPredicate {
|
pub fn not_(predicate : RecordPredicate) -> RecordPredicate {
|
||||||
fn(rec) {
|
@utils.not_(predicate)
|
||||||
!(predicate(rec))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn all_of(predicates : Array[RecordPredicate]) -> RecordPredicate {
|
pub fn all_of(predicates : Array[RecordPredicate]) -> RecordPredicate {
|
||||||
fn(rec) {
|
@utils.all_of(predicates)
|
||||||
for predicate in predicates {
|
|
||||||
if !(predicate(rec)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn any_of(predicates : Array[RecordPredicate]) -> RecordPredicate {
|
pub fn any_of(predicates : Array[RecordPredicate]) -> RecordPredicate {
|
||||||
fn(rec) {
|
@utils.any_of(predicates)
|
||||||
for predicate in predicates {
|
|
||||||
if predicate(rec) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-31
@@ -1,31 +1 @@
|
|||||||
pub(all) enum Level {
|
pub type Level = @core.Level
|
||||||
Trace
|
|
||||||
Debug
|
|
||||||
Info
|
|
||||||
Warn
|
|
||||||
Error
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn Level::priority(self : Level) -> Int {
|
|
||||||
match self {
|
|
||||||
Level::Trace => 10
|
|
||||||
Level::Debug => 20
|
|
||||||
Level::Info => 30
|
|
||||||
Level::Warn => 40
|
|
||||||
Level::Error => 50
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn Level::label(self : Level) -> String {
|
|
||||||
match self {
|
|
||||||
Level::Trace => "TRACE"
|
|
||||||
Level::Debug => "DEBUG"
|
|
||||||
Level::Info => "INFO"
|
|
||||||
Level::Warn => "WARN"
|
|
||||||
Level::Error => "ERROR"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn Level::enabled(self : Level, min_level : Level) -> Bool {
|
|
||||||
self.priority() >= min_level.priority()
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
|
"Nanaloveyuki/BitLogger/src/core" @core,
|
||||||
|
"Nanaloveyuki/BitLogger/src/utils" @utils,
|
||||||
"maria/json_parser" @json_parser,
|
"maria/json_parser" @json_parser,
|
||||||
"moonbitlang/core/array",
|
"moonbitlang/core/array",
|
||||||
"moonbitlang/core/builtin",
|
"moonbitlang/core/builtin",
|
||||||
|
|||||||
+8
-48
@@ -1,69 +1,29 @@
|
|||||||
pub type RecordPatch = (Record) -> Record
|
pub type RecordPatch = @utils.RecordPatch
|
||||||
|
|
||||||
pub fn identity_patch() -> RecordPatch {
|
pub fn identity_patch() -> RecordPatch {
|
||||||
fn(rec) { rec }
|
@utils.identity_patch()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_target(target : String) -> RecordPatch {
|
pub fn set_target(target : String) -> RecordPatch {
|
||||||
fn(rec) {
|
@utils.set_target(target)
|
||||||
{ ..rec, target }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prefix_message(prefix : String) -> RecordPatch {
|
pub fn prefix_message(prefix : String) -> RecordPatch {
|
||||||
fn(rec) {
|
@utils.prefix_message(prefix)
|
||||||
{ ..rec, message: "\{prefix}\{rec.message}" }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn append_fields(extra_fields : Array[Field]) -> RecordPatch {
|
pub fn append_fields(extra_fields : Array[Field]) -> RecordPatch {
|
||||||
fn(rec) {
|
@utils.append_fields(extra_fields)
|
||||||
if extra_fields.length() == 0 {
|
|
||||||
rec
|
|
||||||
} else if rec.fields.length() == 0 {
|
|
||||||
{ ..rec, fields: extra_fields }
|
|
||||||
} else {
|
|
||||||
{ ..rec, fields: rec.fields + extra_fields }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn redact_field(key : String, placeholder~ : String = "***") -> RecordPatch {
|
pub fn redact_field(key : String, placeholder~ : String = "***") -> RecordPatch {
|
||||||
fn(rec) {
|
@utils.redact_field(key, placeholder=placeholder)
|
||||||
{
|
|
||||||
..rec,
|
|
||||||
fields: rec.fields.map(fn(field) {
|
|
||||||
if field.key == key {
|
|
||||||
{ ..field, value: placeholder }
|
|
||||||
} else {
|
|
||||||
field
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn redact_fields(keys : Array[String], placeholder~ : String = "***") -> RecordPatch {
|
pub fn redact_fields(keys : Array[String], placeholder~ : String = "***") -> RecordPatch {
|
||||||
fn(rec) {
|
@utils.redact_fields(keys, placeholder=placeholder)
|
||||||
{
|
|
||||||
..rec,
|
|
||||||
fields: rec.fields.map(fn(field) {
|
|
||||||
if keys.contains(field.key) {
|
|
||||||
{ ..field, value: placeholder }
|
|
||||||
} else {
|
|
||||||
field
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compose_patches(patches : Array[RecordPatch]) -> RecordPatch {
|
pub fn compose_patches(patches : Array[RecordPatch]) -> RecordPatch {
|
||||||
fn(rec) {
|
@utils.compose_patches(patches)
|
||||||
let mut current = rec
|
|
||||||
for patch in patches {
|
|
||||||
current = patch(current)
|
|
||||||
}
|
|
||||||
current
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-26
@@ -1,35 +1,14 @@
|
|||||||
pub struct Field {
|
pub type Field = @core.Field
|
||||||
key : String
|
|
||||||
value : String
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn field(key : String, value : String) -> Field {
|
pub fn field(key : String, value : String) -> Field {
|
||||||
{ key, value }
|
@core.field(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fields(entries : Array[(String, String)]) -> Array[Field] {
|
pub fn fields(entries : Array[(String, String)]) -> Array[Field] {
|
||||||
entries.map(fn(entry) {
|
@core.fields(entries)
|
||||||
field(entry.0, entry.1)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Record {
|
pub type Record = @core.Record
|
||||||
level : Level
|
|
||||||
timestamp_ms : UInt64
|
|
||||||
target : String
|
|
||||||
message : String
|
|
||||||
fields : Array[Field]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn Record::new(
|
|
||||||
level : Level,
|
|
||||||
message : String,
|
|
||||||
timestamp_ms~ : UInt64 = 0UL,
|
|
||||||
target~ : String = "",
|
|
||||||
fields~ : Array[Field] = [],
|
|
||||||
) -> Record {
|
|
||||||
{ level, timestamp_ms, target, message, fields }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn record(
|
fn record(
|
||||||
level : Level,
|
level : Level,
|
||||||
@@ -38,5 +17,5 @@ fn record(
|
|||||||
target~ : String = "",
|
target~ : String = "",
|
||||||
fields~ : Array[Field] = [],
|
fields~ : Array[Field] = [],
|
||||||
) -> Record {
|
) -> Record {
|
||||||
Record::new(level, message, timestamp_ms=timestamp_ms, target=target, fields=fields)
|
@core.Record::new(level, message, timestamp_ms=timestamp_ms, target=target, fields=fields)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -28,7 +28,7 @@ pub impl[S : Sink] Sink for ContextSink[S] with write(self, rec) {
|
|||||||
} else {
|
} else {
|
||||||
self.context_fields + rec.fields
|
self.context_fields + rec.fields
|
||||||
}
|
}
|
||||||
self.sink.write({ ..rec, fields: merged })
|
self.sink.write(rec.with_fields(merged))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct JsonConsoleSink {
|
pub struct JsonConsoleSink {
|
||||||
@@ -471,7 +471,7 @@ pub fn[A, B] fanout_sink(left : A, right : B) -> FanoutSink[A, B] {
|
|||||||
|
|
||||||
pub impl[A : Sink, B : Sink] Sink for FanoutSink[A, B] with write(self, rec) {
|
pub impl[A : Sink, B : Sink] Sink for FanoutSink[A, B] with write(self, rec) {
|
||||||
self.left.write(rec)
|
self.left.write(rec)
|
||||||
self.right.write({ ..rec })
|
self.right.write(rec.copy())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SplitSink[A, B] {
|
pub struct SplitSink[A, B] {
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
pub type RecordPredicate = (@core.Record) -> Bool
|
||||||
|
|
||||||
|
pub fn level_at_least(min_level : @core.Level) -> RecordPredicate {
|
||||||
|
fn(rec) {
|
||||||
|
rec.level.priority() >= min_level.priority()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn target_is(target : String) -> RecordPredicate {
|
||||||
|
fn(rec) {
|
||||||
|
rec.target == target
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn target_has_prefix(prefix : String) -> RecordPredicate {
|
||||||
|
fn(rec) {
|
||||||
|
rec.target.has_prefix(prefix)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn message_contains(fragment : String) -> RecordPredicate {
|
||||||
|
fn(rec) {
|
||||||
|
rec.message.contains(fragment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn has_field(key : String) -> RecordPredicate {
|
||||||
|
fn(rec) {
|
||||||
|
for field in rec.fields {
|
||||||
|
if field.key == key {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn field_equals(key : String, value : String) -> RecordPredicate {
|
||||||
|
fn(rec) {
|
||||||
|
for field in rec.fields {
|
||||||
|
if field.key == key && field.value == value {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn not_(predicate : RecordPredicate) -> RecordPredicate {
|
||||||
|
fn(rec) {
|
||||||
|
!(predicate(rec))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn all_of(predicates : Array[RecordPredicate]) -> RecordPredicate {
|
||||||
|
fn(rec) {
|
||||||
|
for predicate in predicates {
|
||||||
|
if !(predicate(rec)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn any_of(predicates : Array[RecordPredicate]) -> RecordPredicate {
|
||||||
|
fn(rec) {
|
||||||
|
for predicate in predicates {
|
||||||
|
if predicate(rec) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
import {
|
||||||
|
"Nanaloveyuki/BitLogger/src/core" @core,
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
pub type RecordPatch = (@core.Record) -> @core.Record
|
||||||
|
|
||||||
|
pub fn identity_patch() -> RecordPatch {
|
||||||
|
fn(rec) { rec }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_target(target : String) -> RecordPatch {
|
||||||
|
fn(rec) {
|
||||||
|
rec.with_target(target)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prefix_message(prefix : String) -> RecordPatch {
|
||||||
|
fn(rec) {
|
||||||
|
rec.with_message("\{prefix}\{rec.message}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn append_fields(extra_fields : Array[@core.Field]) -> RecordPatch {
|
||||||
|
fn(rec) {
|
||||||
|
if extra_fields.length() == 0 {
|
||||||
|
rec
|
||||||
|
} else if rec.fields.length() == 0 {
|
||||||
|
rec.with_fields(extra_fields)
|
||||||
|
} else {
|
||||||
|
rec.with_fields(rec.fields + extra_fields)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn redact_field(key : String, placeholder~ : String = "***") -> RecordPatch {
|
||||||
|
fn(rec) {
|
||||||
|
rec.with_fields(rec.fields.map(fn(field) {
|
||||||
|
if field.key == key {
|
||||||
|
field.with_value(placeholder)
|
||||||
|
} else {
|
||||||
|
field
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn redact_fields(keys : Array[String], placeholder~ : String = "***") -> RecordPatch {
|
||||||
|
fn(rec) {
|
||||||
|
rec.with_fields(rec.fields.map(fn(field) {
|
||||||
|
if keys.contains(field.key) {
|
||||||
|
field.with_value(placeholder)
|
||||||
|
} else {
|
||||||
|
field
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn compose_patches(patches : Array[RecordPatch]) -> RecordPatch {
|
||||||
|
fn(rec) {
|
||||||
|
let mut current = rec
|
||||||
|
for patch in patches {
|
||||||
|
current = patch(current)
|
||||||
|
}
|
||||||
|
current
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user