♻️ sync owner migration and facade thinning

This commit is contained in:
Nanaloveyuki
2026-07-07 20:03:22 +08:00
parent 5d9924026e
commit e3097ba4fc
79 changed files with 5255 additions and 3191 deletions
+19 -19
View File
@@ -1,46 +1,46 @@
///|
pub type ConfigError = @utils.ConfigError
pub type ConfigError = @config_model.ConfigError
///|
pub type SinkKind = @utils.SinkKind
pub type SinkKind = @config_model.SinkKind
///|
pub type TextFormatterConfig = @utils.TextFormatterConfig
pub type TextFormatterConfig = @config_model.TextFormatterConfig
///|
pub type QueueConfig = @utils.QueueConfig
pub type QueueConfig = @config_model.QueueConfig
///|
pub type SinkConfig = @utils.SinkConfig
pub type SinkConfig = @config_model.SinkConfig
///|
pub type LoggerConfig = @utils.LoggerConfig
pub type LoggerConfig = @config_model.LoggerConfig
///|
pub fn default_text_formatter_config() -> TextFormatterConfig {
@utils.default_text_formatter_config()
@config_model.default_text_formatter_config()
}
///|
pub fn default_sink_config() -> SinkConfig {
@utils.default_sink_config()
@config_model.default_sink_config()
}
///|
pub fn default_logger_config() -> LoggerConfig {
@utils.default_logger_config()
@config_model.default_logger_config()
}
///|
pub fn parse_logger_config_text(
input : String,
) -> LoggerConfig raise ConfigError {
@utils.parse_logger_config_text(input)
@config_model.parse_logger_config_text(input)
}
///|
pub fn queue_config_to_json(queue : QueueConfig) -> @json_parser.JsonValue {
@utils.queue_config_to_json(queue)
@config_model.queue_config_to_json(queue)
}
///|
@@ -48,14 +48,14 @@ pub fn stringify_queue_config(
queue : QueueConfig,
pretty? : Bool = false,
) -> String {
@utils.stringify_queue_config(queue, pretty~)
@config_model.stringify_queue_config(queue, pretty~)
}
///|
pub fn text_formatter_config_to_json(
config : TextFormatterConfig,
) -> @json_parser.JsonValue {
@utils.text_formatter_config_to_json(config)
@config_model.text_formatter_config_to_json(config)
}
///|
@@ -63,19 +63,19 @@ pub fn stringify_text_formatter_config(
config : TextFormatterConfig,
pretty? : Bool = false,
) -> String {
@utils.stringify_text_formatter_config(config, pretty~)
@config_model.stringify_text_formatter_config(config, pretty~)
}
///|
pub fn file_rotation_config_to_json(
config : FileRotation,
) -> @json_parser.JsonValue {
@utils.file_rotation_config_to_json(config)
@file_model.file_rotation_config_to_json(config)
}
///|
pub fn sink_config_to_json(config : SinkConfig) -> @json_parser.JsonValue {
@utils.sink_config_to_json(config)
@config_model.sink_config_to_json(config)
}
///|
@@ -83,12 +83,12 @@ pub fn stringify_sink_config(
config : SinkConfig,
pretty? : Bool = false,
) -> String {
@utils.stringify_sink_config(config, pretty~)
@config_model.stringify_sink_config(config, pretty~)
}
///|
pub fn logger_config_to_json(config : LoggerConfig) -> @json_parser.JsonValue {
@utils.logger_config_to_json(config)
@config_model.logger_config_to_json(config)
}
///|
@@ -96,5 +96,5 @@ pub fn stringify_logger_config(
config : LoggerConfig,
pretty? : Bool = false,
) -> String {
@utils.stringify_logger_config(config, pretty~)
@config_model.stringify_logger_config(config, pretty~)
}
@@ -20,12 +20,12 @@ pub struct TextFormatterConfig {
separator : String
field_separator : String
template : String
color_mode : ColorMode
color_support : ColorSupport
style_markup : StyleMarkupMode
target_style_markup : StyleMarkupMode
fields_style_markup : StyleMarkupMode
style_tags : Map[String, TextStyle]
color_mode : @formatting.ColorMode
color_support : @formatting.ColorSupport
style_markup : @formatting.StyleMarkupMode
target_style_markup : @formatting.StyleMarkupMode
fields_style_markup : @formatting.StyleMarkupMode
style_tags : Map[String, @formatting.TextStyle]
}
///|
@@ -37,12 +37,12 @@ pub fn TextFormatterConfig::new(
separator? : String = " ",
field_separator? : String = " ",
template? : String = "",
color_mode? : ColorMode = ColorMode::Never,
color_support? : ColorSupport = ColorSupport::TrueColor,
style_markup? : StyleMarkupMode = StyleMarkupMode::Full,
target_style_markup? : StyleMarkupMode = StyleMarkupMode::Disabled,
fields_style_markup? : StyleMarkupMode = StyleMarkupMode::Disabled,
style_tags? : Map[String, TextStyle] = {},
color_mode? : @formatting.ColorMode = @formatting.ColorMode::Never,
color_support? : @formatting.ColorSupport = @formatting.ColorSupport::TrueColor,
style_markup? : @formatting.StyleMarkupMode = @formatting.StyleMarkupMode::Full,
target_style_markup? : @formatting.StyleMarkupMode = @formatting.StyleMarkupMode::Disabled,
fields_style_markup? : @formatting.StyleMarkupMode = @formatting.StyleMarkupMode::Disabled,
style_tags? : Map[String, @formatting.TextStyle] = {},
) -> TextFormatterConfig {
{
show_timestamp,
@@ -63,9 +63,9 @@ pub fn TextFormatterConfig::new(
///|
fn style_tag_registry_from_config(
style_tags : Map[String, TextStyle],
) -> StyleTagRegistry {
let registry = style_tag_registry()
style_tags : Map[String, @formatting.TextStyle],
) -> @formatting.StyleTagRegistry {
let registry = @formatting.style_tag_registry()
for name, style in style_tags {
ignore(registry.set_tag(name, style~))
}
@@ -75,8 +75,8 @@ fn style_tag_registry_from_config(
///|
pub fn TextFormatterConfig::to_formatter(
self : TextFormatterConfig,
) -> TextFormatter {
text_formatter(
) -> @formatting.TextFormatter {
@formatting.text_formatter(
show_timestamp=self.show_timestamp,
show_level=self.show_level,
show_target=self.show_target,
@@ -100,13 +100,13 @@ pub fn TextFormatterConfig::to_formatter(
///|
pub struct QueueConfig {
max_pending : Int
overflow : QueueOverflowPolicy
overflow : @queue_model.QueueOverflowPolicy
}
///|
pub fn QueueConfig::new(
max_pending : Int,
overflow? : QueueOverflowPolicy = QueueOverflowPolicy::DropNewest,
overflow? : @queue_model.QueueOverflowPolicy = @queue_model.QueueOverflowPolicy::DropNewest,
) -> QueueConfig {
{ max_pending, overflow }
}
@@ -117,7 +117,7 @@ pub struct SinkConfig {
path : String
append : Bool
auto_flush : Bool
rotation : FileRotation?
rotation : @file_model.FileRotation?
text_formatter : TextFormatterConfig
}
@@ -127,7 +127,7 @@ pub fn SinkConfig::new(
path? : String = "",
append? : Bool = true,
auto_flush? : Bool = true,
rotation? : FileRotation? = None,
rotation? : @file_model.FileRotation? = None,
text_formatter? : TextFormatterConfig = default_text_formatter_config(),
) -> SinkConfig {
{ kind, path, append, auto_flush, rotation, text_formatter }
@@ -282,11 +282,13 @@ fn parse_level(name : String) -> @core.Level raise ConfigError {
}
///|
fn parse_overflow(name : String) -> QueueOverflowPolicy raise ConfigError {
fn parse_overflow(
name : String,
) -> @queue_model.QueueOverflowPolicy raise ConfigError {
match name.to_upper() {
"DROPNEWEST" => QueueOverflowPolicy::DropNewest
"DROPPOLDEST" => QueueOverflowPolicy::DropOldest
"DROPOLDEST" => QueueOverflowPolicy::DropOldest
"DROPNEWEST" => @queue_model.QueueOverflowPolicy::DropNewest
"DROPPOLDEST" => @queue_model.QueueOverflowPolicy::DropOldest
"DROPOLDEST" => @queue_model.QueueOverflowPolicy::DropOldest
_ =>
raise ConfigError::InvalidConfig(
"Unsupported queue overflow policy: " + name,
@@ -308,30 +310,34 @@ fn parse_sink_kind(name : String) -> SinkKind raise ConfigError {
}
///|
fn parse_color_mode(name : String) -> ColorMode raise ConfigError {
fn parse_color_mode(name : String) -> @formatting.ColorMode raise ConfigError {
match name.to_upper() {
"NEVER" => ColorMode::Never
"AUTO" => ColorMode::Auto
"ALWAYS" => ColorMode::Always
"NEVER" => @formatting.ColorMode::Never
"AUTO" => @formatting.ColorMode::Auto
"ALWAYS" => @formatting.ColorMode::Always
_ => raise ConfigError::InvalidConfig("Unsupported color mode: " + name)
}
}
///|
fn parse_color_support(name : String) -> ColorSupport raise ConfigError {
fn parse_color_support(
name : String,
) -> @formatting.ColorSupport raise ConfigError {
match name.to_upper() {
"BASIC" => ColorSupport::Basic
"TRUECOLOR" => ColorSupport::TrueColor
"BASIC" => @formatting.ColorSupport::Basic
"TRUECOLOR" => @formatting.ColorSupport::TrueColor
_ => raise ConfigError::InvalidConfig("Unsupported color support: " + name)
}
}
///|
fn parse_style_markup_mode(name : String) -> StyleMarkupMode raise ConfigError {
fn parse_style_markup_mode(
name : String,
) -> @formatting.StyleMarkupMode raise ConfigError {
match name.to_upper() {
"DISABLED" => StyleMarkupMode::Disabled
"BUILTIN" => StyleMarkupMode::Builtin
"FULL" => StyleMarkupMode::Full
"DISABLED" => @formatting.StyleMarkupMode::Disabled
"BUILTIN" => @formatting.StyleMarkupMode::Builtin
"FULL" => @formatting.StyleMarkupMode::Full
_ =>
raise ConfigError::InvalidConfig("Unsupported style markup mode: " + name)
}
@@ -384,9 +390,9 @@ fn parse_text_formatter_config(
fn parse_text_style_config(
value : @json_parser.JsonValue,
context : String,
) -> TextStyle raise ConfigError {
) -> @formatting.TextStyle raise ConfigError {
let obj = expect_object(value, context)
text_style(
@formatting.text_style(
fg=get_optional_string(obj, "fg"),
bg=get_optional_string(obj, "bg"),
bold=get_bool(obj, "bold", default=false),
@@ -399,9 +405,9 @@ fn parse_text_style_config(
///|
fn parse_style_tags_config(
value : @json_parser.JsonValue,
) -> Map[String, TextStyle] raise ConfigError {
) -> Map[String, @formatting.TextStyle] raise ConfigError {
let obj = expect_object(value, "text_formatter.style_tags")
let style_tags : Map[String, TextStyle] = {}
let style_tags : Map[String, @formatting.TextStyle] = {}
for name, item in obj {
style_tags[name] = parse_text_style_config(
item,
@@ -425,12 +431,17 @@ fn parse_queue_config(
///|
fn parse_file_rotation_config(
value : @json_parser.JsonValue,
) -> FileRotation raise ConfigError {
) -> @file_model.FileRotation raise ConfigError {
let obj = expect_object(value, "sink.rotation")
let max_backups = get_int(obj, "max_backups", default=1)
match get_optional_int64_string(obj, "max_bytes_i64") {
Some(max_bytes_i64) => file_rotation_i64(max_bytes_i64, max_backups~)
None => file_rotation(get_int(obj, "max_bytes", default=1), max_backups~)
Some(max_bytes_i64) =>
@file_model.file_rotation_i64(max_bytes_i64, max_backups~)
None =>
@file_model.file_rotation(
get_int(obj, "max_bytes", default=1),
max_backups~,
)
}
}
@@ -494,8 +505,8 @@ pub fn queue_config_to_json(queue : QueueConfig) -> @json_parser.JsonValue {
"max_pending": @json_parser.JsonValue::Number(queue.max_pending.to_double()),
"overflow": @json_parser.JsonValue::String(
match queue.overflow {
QueueOverflowPolicy::DropNewest => "DropNewest"
QueueOverflowPolicy::DropOldest => "DropOldest"
@queue_model.QueueOverflowPolicy::DropNewest => "DropNewest"
@queue_model.QueueOverflowPolicy::DropOldest => "DropOldest"
},
),
})
@@ -527,19 +538,19 @@ pub fn text_formatter_config_to_json(
"field_separator": @json_parser.JsonValue::String(config.field_separator),
"template": @json_parser.JsonValue::String(config.template),
"color_mode": @json_parser.JsonValue::String(
color_mode_label(config.color_mode),
@formatting.color_mode_label(config.color_mode),
),
"color_support": @json_parser.JsonValue::String(
color_support_label(config.color_support),
@formatting.color_support_label(config.color_support),
),
"style_markup": @json_parser.JsonValue::String(
style_markup_mode_label(config.style_markup),
@formatting.style_markup_mode_label(config.style_markup),
),
"target_style_markup": @json_parser.JsonValue::String(
style_markup_mode_label(config.target_style_markup),
@formatting.style_markup_mode_label(config.target_style_markup),
),
"fields_style_markup": @json_parser.JsonValue::String(
style_markup_mode_label(config.fields_style_markup),
@formatting.style_markup_mode_label(config.fields_style_markup),
),
}
if config.style_tags.length() != 0 {
@@ -549,7 +560,9 @@ pub fn text_formatter_config_to_json(
}
///|
fn text_style_config_to_json(style : TextStyle) -> @json_parser.JsonValue {
fn text_style_config_to_json(
style : @formatting.TextStyle,
) -> @json_parser.JsonValue {
let obj : Map[String, @json_parser.JsonValue] = {
"bold": @json_parser.JsonValue::Bool(style.bold),
"dim": @json_parser.JsonValue::Bool(style.dim),
@@ -569,7 +582,7 @@ fn text_style_config_to_json(style : TextStyle) -> @json_parser.JsonValue {
///|
fn style_tags_config_to_json(
style_tags : Map[String, TextStyle],
style_tags : Map[String, @formatting.TextStyle],
) -> @json_parser.JsonValue {
let obj : Map[String, @json_parser.JsonValue] = {}
for name, style in style_tags {
@@ -591,24 +604,6 @@ pub fn stringify_text_formatter_config(
}
}
///|
pub fn file_rotation_config_to_json(
config : FileRotation,
) -> @json_parser.JsonValue {
let obj : Map[String, @json_parser.JsonValue] = {
"max_bytes": @json_parser.JsonValue::Number(config.max_bytes.to_double()),
"max_backups": @json_parser.JsonValue::Number(
config.max_backups.to_double(),
),
}
match config.native_wide_max_bytes {
Some(value) =>
obj["max_bytes_i64"] = @json_parser.JsonValue::String(value.to_string())
None => ()
}
@json_parser.JsonValue::Object(obj)
}
///|
pub fn sink_config_to_json(config : SinkConfig) -> @json_parser.JsonValue {
let obj : Map[String, @json_parser.JsonValue] = {
@@ -620,7 +615,8 @@ pub fn sink_config_to_json(config : SinkConfig) -> @json_parser.JsonValue {
}
match config.rotation {
None => ()
Some(rotation) => obj["rotation"] = file_rotation_config_to_json(rotation)
Some(rotation) =>
obj["rotation"] = @file_model.file_rotation_config_to_json(rotation)
}
@json_parser.JsonValue::Object(obj)
}
+8
View File
@@ -0,0 +1,8 @@
import {
"Nanaloveyuki/BitLogger/src/core",
"Nanaloveyuki/BitLogger/src/file_model",
"Nanaloveyuki/BitLogger/src/formatting",
"Nanaloveyuki/BitLogger/src/queue_model",
"maria/json_parser",
"moonbitlang/core/string",
}
+96
View File
@@ -0,0 +1,96 @@
// Generated using `moon info`, DON'T EDIT IT
package "Nanaloveyuki/BitLogger/src/config_model"
import {
"Nanaloveyuki/BitLogger/src/core",
"Nanaloveyuki/BitLogger/src/file_model",
"Nanaloveyuki/BitLogger/src/formatting",
"Nanaloveyuki/BitLogger/src/queue_model",
"maria/json_parser",
}
// Values
pub fn default_logger_config() -> LoggerConfig
pub fn default_sink_config() -> SinkConfig
pub fn default_text_formatter_config() -> TextFormatterConfig
pub fn logger_config_to_json(LoggerConfig) -> @json_parser.JsonValue
pub fn parse_logger_config_text(String) -> LoggerConfig raise ConfigError
pub fn queue_config_to_json(QueueConfig) -> @json_parser.JsonValue
pub fn sink_config_to_json(SinkConfig) -> @json_parser.JsonValue
pub fn stringify_logger_config(LoggerConfig, pretty? : Bool) -> String
pub fn stringify_queue_config(QueueConfig, pretty? : Bool) -> String
pub fn stringify_sink_config(SinkConfig, pretty? : Bool) -> String
pub fn stringify_text_formatter_config(TextFormatterConfig, pretty? : Bool) -> String
pub fn text_formatter_config_to_json(TextFormatterConfig) -> @json_parser.JsonValue
// Errors
pub(all) suberror ConfigError {
InvalidConfig(String)
}
// Types and methods
pub struct LoggerConfig {
min_level : @core.Level
target : String
timestamp : Bool
sink : SinkConfig
queue : QueueConfig?
}
pub fn LoggerConfig::new(min_level? : @core.Level, target? : String, timestamp? : Bool, sink? : SinkConfig, queue? : QueueConfig?) -> Self
pub struct QueueConfig {
max_pending : Int
overflow : @queue_model.QueueOverflowPolicy
}
pub fn QueueConfig::new(Int, overflow? : @queue_model.QueueOverflowPolicy) -> Self
pub struct SinkConfig {
kind : SinkKind
path : String
append : Bool
auto_flush : Bool
rotation : @file_model.FileRotation?
text_formatter : TextFormatterConfig
}
pub fn SinkConfig::new(kind? : SinkKind, path? : String, append? : Bool, auto_flush? : Bool, rotation? : @file_model.FileRotation?, text_formatter? : TextFormatterConfig) -> Self
pub(all) enum SinkKind {
Console
JsonConsole
TextConsole
File
}
pub struct TextFormatterConfig {
show_timestamp : Bool
show_level : Bool
show_target : Bool
show_fields : Bool
separator : String
field_separator : String
template : String
color_mode : @formatting.ColorMode
color_support : @formatting.ColorSupport
style_markup : @formatting.StyleMarkupMode
target_style_markup : @formatting.StyleMarkupMode
fields_style_markup : @formatting.StyleMarkupMode
style_tags : Map[String, @formatting.TextStyle]
}
pub fn TextFormatterConfig::new(show_timestamp? : Bool, show_level? : Bool, show_target? : Bool, show_fields? : Bool, separator? : String, field_separator? : String, template? : String, color_mode? : @formatting.ColorMode, color_support? : @formatting.ColorSupport, style_markup? : @formatting.StyleMarkupMode, target_style_markup? : @formatting.StyleMarkupMode, fields_style_markup? : @formatting.StyleMarkupMode, style_tags? : Map[String, @formatting.TextStyle]) -> Self
pub fn TextFormatterConfig::to_formatter(Self) -> @formatting.TextFormatter
// Type aliases
// Traits
-47
View File
@@ -1,47 +0,0 @@
///|
type FileHandle = @utils.FileHandle
///|
fn open_file_handle_internal(path : String, append : Bool) -> FileHandle? {
@utils.open_file_handle_internal(path, append)
}
///|
fn write_file_handle_internal(handle : FileHandle, content : String) -> Bool {
@utils.write_file_handle_internal(handle, content)
}
///|
fn flush_file_handle_internal(handle : FileHandle) -> Bool {
@utils.flush_file_handle_internal(handle)
}
///|
fn close_file_handle_internal(handle : FileHandle) -> Bool {
@utils.close_file_handle_internal(handle)
}
///|
fn file_size_i64_internal(handle : FileHandle) -> Int64 {
@utils.file_size_i64_internal(handle)
}
///|
fn rename_file_internal(from_path : String, to_path : String) -> Bool {
@utils.rename_file_internal(from_path, to_path)
}
///|
fn remove_file_internal(path : String) -> Bool {
@utils.remove_file_internal(path)
}
///|
fn string_byte_length_internal(content : String) -> Int {
@utils.string_byte_length_internal(content)
}
///|
fn native_files_supported_internal() -> Bool {
@utils.native_files_supported_internal()
}
-47
View File
@@ -1,47 +0,0 @@
///|
type FileHandle = @utils.FileHandle
///|
fn open_file_handle_internal(path : String, append : Bool) -> FileHandle? {
@utils.open_file_handle_internal(path, append)
}
///|
fn write_file_handle_internal(handle : FileHandle, content : String) -> Bool {
@utils.write_file_handle_internal(handle, content)
}
///|
fn flush_file_handle_internal(handle : FileHandle) -> Bool {
@utils.flush_file_handle_internal(handle)
}
///|
fn close_file_handle_internal(handle : FileHandle) -> Bool {
@utils.close_file_handle_internal(handle)
}
///|
fn file_size_i64_internal(handle : FileHandle) -> Int64 {
@utils.file_size_i64_internal(handle)
}
///|
fn rename_file_internal(from_path : String, to_path : String) -> Bool {
@utils.rename_file_internal(from_path, to_path)
}
///|
fn remove_file_internal(path : String) -> Bool {
@utils.remove_file_internal(path)
}
///|
fn string_byte_length_internal(content : String) -> Int {
@utils.string_byte_length_internal(content)
}
///|
fn native_files_supported_internal() -> Bool {
@utils.native_files_supported_internal()
}
@@ -1,23 +1,23 @@
///|
pub struct RuntimeFileState {
file : FileSinkState
queued : Bool
pending_count : Int
dropped_count : Int
pub fn file_rotation_config_to_json(
config : FileRotation,
) -> @json_parser.JsonValue {
let obj : Map[String, @json_parser.JsonValue] = {
"max_bytes": @json_parser.JsonValue::Number(config.max_bytes.to_double()),
"max_backups": @json_parser.JsonValue::Number(
config.max_backups.to_double(),
),
}
match config.native_wide_max_bytes {
Some(value) =>
obj["max_bytes_i64"] = @json_parser.JsonValue::String(value.to_string())
None => ()
}
@json_parser.JsonValue::Object(obj)
}
///|
pub fn RuntimeFileState::new(
file : FileSinkState,
queued? : Bool = false,
pending_count? : Int = 0,
dropped_count? : Int = 0,
) -> RuntimeFileState {
{ file, queued, pending_count, dropped_count }
}
///|
fn file_sink_policy_to_json_value(
pub fn file_sink_policy_to_json(
policy : FileSinkPolicy,
) -> @json_parser.JsonValue {
let obj : Map[String, @json_parser.JsonValue] = {
@@ -31,19 +31,12 @@ fn file_sink_policy_to_json_value(
@json_parser.JsonValue::Object(obj)
}
///|
pub fn file_sink_policy_to_json(
policy : FileSinkPolicy,
) -> @json_parser.JsonValue {
file_sink_policy_to_json_value(policy)
}
///|
pub fn stringify_file_sink_policy(
policy : FileSinkPolicy,
pretty? : Bool = false,
) -> String {
let value = file_sink_policy_to_json_value(policy)
let value = file_sink_policy_to_json(policy)
if pretty {
@json_parser.stringify_pretty(value, 2)
} else {
@@ -52,9 +45,7 @@ pub fn stringify_file_sink_policy(
}
///|
fn file_sink_state_to_json_value(
state : FileSinkState,
) -> @json_parser.JsonValue {
pub fn file_sink_state_to_json(state : FileSinkState) -> @json_parser.JsonValue {
let obj : Map[String, @json_parser.JsonValue] = {
"path": @json_parser.JsonValue::String(state.path),
"available": @json_parser.JsonValue::Bool(state.available),
@@ -80,46 +71,12 @@ fn file_sink_state_to_json_value(
@json_parser.JsonValue::Object(obj)
}
///|
pub fn file_sink_state_to_json(state : FileSinkState) -> @json_parser.JsonValue {
file_sink_state_to_json_value(state)
}
///|
pub fn stringify_file_sink_state(
state : FileSinkState,
pretty? : Bool = false,
) -> String {
let value = file_sink_state_to_json_value(state)
if pretty {
@json_parser.stringify_pretty(value, 2)
} else {
@json_parser.stringify(value)
}
}
///|
pub fn runtime_file_state_to_json(
state : RuntimeFileState,
) -> @json_parser.JsonValue {
@json_parser.JsonValue::Object({
"file": file_sink_state_to_json_value(state.file),
"queued": @json_parser.JsonValue::Bool(state.queued),
"pending_count": @json_parser.JsonValue::Number(
state.pending_count.to_double(),
),
"dropped_count": @json_parser.JsonValue::Number(
state.dropped_count.to_double(),
),
})
}
///|
pub fn stringify_runtime_file_state(
state : RuntimeFileState,
pretty? : Bool = false,
) -> String {
let value = runtime_file_state_to_json(state)
let value = file_sink_state_to_json(state)
if pretty {
@json_parser.stringify_pretty(value, 2)
} else {
+99
View File
@@ -0,0 +1,99 @@
///|
pub struct FileRotation {
max_bytes : Int
max_backups : Int
native_wide_max_bytes : Int64?
}
///|
pub struct FileSinkState {
path : String
available : Bool
append : Bool
auto_flush : Bool
rotation : FileRotation?
open_failures : Int
write_failures : Int
flush_failures : Int
rotation_failures : Int
}
///|
pub struct FileSinkPolicy {
append : Bool
auto_flush : Bool
rotation : FileRotation?
}
///|
pub fn FileSinkPolicy::new(
append? : Bool = true,
auto_flush? : Bool = true,
rotation? : FileRotation? = None,
) -> FileSinkPolicy {
{ append, auto_flush, rotation }
}
///|
pub fn FileSinkState::new(
path : String,
available? : Bool = false,
append? : Bool = true,
auto_flush? : Bool = true,
rotation? : FileRotation? = None,
open_failures? : Int = 0,
write_failures? : Int = 0,
flush_failures? : Int = 0,
rotation_failures? : Int = 0,
) -> FileSinkState {
{
path,
available,
append,
auto_flush,
rotation,
open_failures,
write_failures,
flush_failures,
rotation_failures,
}
}
///|
pub fn file_rotation(max_bytes : Int, max_backups? : Int = 1) -> FileRotation {
{
max_bytes: if max_bytes <= 0 {
1
} else {
max_bytes
},
max_backups: if max_backups <= 0 {
1
} else {
max_backups
},
native_wide_max_bytes: None,
}
}
///|
pub fn file_rotation_i64(
max_bytes : Int64,
max_backups? : Int = 1,
) -> FileRotation {
let normalized = if max_bytes <= 0L { 1L } else { max_bytes }
let clamped_max_bytes = if normalized > 2147483647L {
2147483647
} else {
normalized.to_int()
}
{
max_bytes: clamped_max_bytes,
max_backups: if max_backups <= 0 {
1
} else {
max_backups
},
native_wide_max_bytes: Some(normalized),
}
}
+3
View File
@@ -0,0 +1,3 @@
import {
"maria/json_parser",
}
+67
View File
@@ -0,0 +1,67 @@
// Generated using `moon info`, DON'T EDIT IT
package "Nanaloveyuki/BitLogger/src/file_model"
import {
"maria/json_parser",
}
// Values
pub fn file_rotation(Int, max_backups? : Int) -> FileRotation
pub fn file_rotation_config_to_json(FileRotation) -> @json_parser.JsonValue
pub fn file_rotation_i64(Int64, max_backups? : Int) -> FileRotation
pub fn file_sink_policy_to_json(FileSinkPolicy) -> @json_parser.JsonValue
pub fn file_sink_state_to_json(FileSinkState) -> @json_parser.JsonValue
pub fn runtime_file_state_to_json(RuntimeFileState) -> @json_parser.JsonValue
pub fn stringify_file_sink_policy(FileSinkPolicy, pretty? : Bool) -> String
pub fn stringify_file_sink_state(FileSinkState, pretty? : Bool) -> String
pub fn stringify_runtime_file_state(RuntimeFileState, pretty? : Bool) -> String
// Errors
// Types and methods
pub struct FileRotation {
max_bytes : Int
max_backups : Int
native_wide_max_bytes : Int64?
}
pub struct FileSinkPolicy {
append : Bool
auto_flush : Bool
rotation : FileRotation?
}
pub fn FileSinkPolicy::new(append? : Bool, auto_flush? : Bool, rotation? : FileRotation?) -> Self
pub struct FileSinkState {
path : String
available : Bool
append : Bool
auto_flush : Bool
rotation : FileRotation?
open_failures : Int
write_failures : Int
flush_failures : Int
rotation_failures : Int
}
pub fn FileSinkState::new(String, available? : Bool, append? : Bool, auto_flush? : Bool, rotation? : FileRotation?, open_failures? : Int, write_failures? : Int, flush_failures? : Int, rotation_failures? : Int) -> Self
pub struct RuntimeFileState {
file : FileSinkState
queued : Bool
pending_count : Int
dropped_count : Int
}
pub fn RuntimeFileState::new(FileSinkState, queued? : Bool, pending_count? : Int, dropped_count? : Int) -> Self
// Type aliases
// Traits
+46
View File
@@ -0,0 +1,46 @@
///|
pub struct RuntimeFileState {
file : FileSinkState
queued : Bool
pending_count : Int
dropped_count : Int
}
///|
pub fn RuntimeFileState::new(
file : FileSinkState,
queued? : Bool = false,
pending_count? : Int = 0,
dropped_count? : Int = 0,
) -> RuntimeFileState {
{ file, queued, pending_count, dropped_count }
}
///|
pub fn runtime_file_state_to_json(
state : RuntimeFileState,
) -> @json_parser.JsonValue {
@json_parser.JsonValue::Object({
"file": file_sink_state_to_json(state.file),
"queued": @json_parser.JsonValue::Bool(state.queued),
"pending_count": @json_parser.JsonValue::Number(
state.pending_count.to_double(),
),
"dropped_count": @json_parser.JsonValue::Number(
state.dropped_count.to_double(),
),
})
}
///|
pub fn stringify_runtime_file_state(
state : RuntimeFileState,
pretty? : Bool = false,
) -> String {
let value = runtime_file_state_to_json(state)
if pretty {
@json_parser.stringify_pretty(value, 2)
} else {
@json_parser.stringify(value)
}
}
+385
View File
@@ -0,0 +1,385 @@
///|
type FileHandle = @utils.FileHandle
///|
type FileRotation = @file_model.FileRotation
///|
type FileSinkState = @file_model.FileSinkState
///|
type FileSinkPolicy = @file_model.FileSinkPolicy
///|
type Record = @core.Record
///|
type RecordFormatter = @formatting.RecordFormatter
///|
pub struct FileSink {
priv path : String
priv append : Ref[Bool]
priv default_append : Bool
priv handle : Ref[FileHandle?]
priv formatter : RecordFormatter
priv auto_flush : Ref[Bool]
priv default_auto_flush : Bool
priv rotation : Ref[FileRotation?]
priv default_rotation : FileRotation?
priv open_failures : Ref[Int]
priv write_failures : Ref[Int]
priv flush_failures : Ref[Int]
priv rotation_failures : Ref[Int]
}
///|
pub fn native_files_supported() -> Bool {
@utils.native_files_supported_internal()
}
///|
pub fn file_sink(
path : String,
append? : Bool = true,
auto_flush? : Bool = true,
rotation? : FileRotation? = None,
formatter? : RecordFormatter = fn(rec) { @formatting.format_text(rec) },
) -> FileSink {
let handle = @utils.open_file_handle_internal(path, append)
{
path,
append: Ref(append),
default_append: append,
handle: Ref(handle),
formatter,
auto_flush: Ref(auto_flush),
default_auto_flush: auto_flush,
rotation: Ref(rotation),
default_rotation: rotation,
open_failures: Ref(if handle is Some(_) { 0 } else { 1 }),
write_failures: Ref(0),
flush_failures: Ref(0),
rotation_failures: Ref(0),
}
}
///|
pub fn FileSink::is_available(self : FileSink) -> Bool {
self.handle.val is Some(_)
}
///|
pub fn FileSink::flush(self : FileSink) -> Bool {
match self.handle.val {
None => false
Some(handle) => {
let ok = @utils.flush_file_handle_internal(handle)
if !ok {
self.flush_failures.val += 1
}
ok
}
}
}
///|
pub fn FileSink::append_mode(self : FileSink) -> Bool {
self.append.val
}
///|
pub fn FileSink::set_append_mode(self : FileSink, append : Bool) -> Unit {
self.append.val = append
}
///|
pub fn FileSink::path(self : FileSink) -> String {
self.path
}
///|
pub fn FileSink::auto_flush_enabled(self : FileSink) -> Bool {
self.auto_flush.val
}
///|
pub fn FileSink::rotation_enabled(self : FileSink) -> Bool {
self.rotation.val is Some(_)
}
///|
pub fn FileSink::rotation_config(self : FileSink) -> FileRotation? {
self.rotation.val
}
///|
pub fn FileSink::set_auto_flush(self : FileSink, enabled : Bool) -> Unit {
self.auto_flush.val = enabled
}
///|
pub fn FileSink::set_policy(self : FileSink, policy : FileSinkPolicy) -> Unit {
self.append.val = policy.append
self.auto_flush.val = policy.auto_flush
self.rotation.val = policy.rotation
}
///|
pub fn FileSink::set_rotation(
self : FileSink,
rotation : FileRotation?,
) -> Unit {
self.rotation.val = rotation
}
///|
pub fn FileSink::clear_rotation(self : FileSink) -> Unit {
self.rotation.val = None
}
///|
pub fn FileSink::close(self : FileSink) -> Bool {
match self.handle.val {
None => false
Some(handle) => {
let ok = @utils.close_file_handle_internal(handle)
self.handle.val = None
ok
}
}
}
///|
pub fn FileSink::rotation_failures(self : FileSink) -> Int {
self.rotation_failures.val
}
///|
pub fn FileSink::open_failures(self : FileSink) -> Int {
self.open_failures.val
}
///|
pub fn FileSink::write_failures(self : FileSink) -> Int {
self.write_failures.val
}
///|
pub fn FileSink::flush_failures(self : FileSink) -> Int {
self.flush_failures.val
}
///|
pub fn FileSink::reset_failure_counters(self : FileSink) -> Unit {
self.open_failures.val = 0
self.write_failures.val = 0
self.flush_failures.val = 0
self.rotation_failures.val = 0
}
///|
pub fn FileSink::reset_policy(self : FileSink) -> Unit {
self.append.val = self.default_append
self.auto_flush.val = self.default_auto_flush
self.rotation.val = self.default_rotation
}
///|
pub fn FileSink::policy(self : FileSink) -> FileSinkPolicy {
FileSinkPolicy::new(
append=self.append.val,
auto_flush=self.auto_flush.val,
rotation=self.rotation.val,
)
}
///|
pub fn FileSink::default_policy(self : FileSink) -> FileSinkPolicy {
FileSinkPolicy::new(
append=self.default_append,
auto_flush=self.default_auto_flush,
rotation=self.default_rotation,
)
}
///|
pub fn FileSink::policy_matches_default(self : FileSink) -> Bool {
let current = self.policy()
let default = self.default_policy()
current.append == default.append &&
current.auto_flush == default.auto_flush &&
policy_rotation_equals_internal(current.rotation, default.rotation)
}
///|
fn policy_rotation_equals_internal(
left : FileRotation?,
right : FileRotation?,
) -> Bool {
match (left, right) {
(None, None) => true
(Some(a), Some(b)) =>
a.max_bytes == b.max_bytes &&
a.max_backups == b.max_backups &&
a.native_wide_max_bytes == b.native_wide_max_bytes
_ => false
}
}
///|
fn rotation_max_bytes_internal(rotation : FileRotation) -> Int64 {
match rotation.native_wide_max_bytes {
Some(value) => value
None => rotation.max_bytes.to_int64()
}
}
///|
pub fn FileSink::state(self : FileSink) -> FileSinkState {
FileSinkState::new(
self.path,
available=self.is_available(),
append=self.append.val,
auto_flush=self.auto_flush.val,
rotation=self.rotation.val,
open_failures=self.open_failures.val,
write_failures=self.write_failures.val,
flush_failures=self.flush_failures.val,
rotation_failures=self.rotation_failures.val,
)
}
///|
pub fn FileSink::reopen(self : FileSink, append? : Bool? = None) -> Bool {
let append_mode = append.unwrap_or(self.append.val)
self.append.val = append_mode
match self.handle.val {
None => ()
Some(handle) => {
ignore(@utils.close_file_handle_internal(handle))
self.handle.val = None
}
}
let reopened = @utils.open_file_handle_internal(self.path, append_mode)
self.handle.val = reopened
if reopened is Some(_) {
true
} else {
self.open_failures.val += 1
false
}
}
///|
pub fn FileSink::reopen_with_current_policy(self : FileSink) -> Bool {
self.reopen()
}
///|
pub fn FileSink::reopen_append(self : FileSink) -> Bool {
self.reopen(append=Some(true))
}
///|
pub fn FileSink::reopen_truncate(self : FileSink) -> Bool {
self.reopen(append=Some(false))
}
///|
fn rotated_file_path(path : String, index : Int) -> String {
"\{path}.\{index}"
}
///|
fn rotate_file_sink_internal(sink : FileSink, rotation : FileRotation) -> Bool {
let closed = match sink.handle.val {
None => true
Some(handle) => {
let ok = @utils.close_file_handle_internal(handle)
sink.handle.val = None
ok
}
}
if !closed {
return false
}
if rotation.max_backups > 0 {
ignore(
@utils.remove_file_internal(
rotated_file_path(sink.path, rotation.max_backups),
),
)
for index = rotation.max_backups - 1; index >= 1; {
let from_path = rotated_file_path(sink.path, index)
let to_path = rotated_file_path(sink.path, index + 1)
ignore(@utils.rename_file_internal(from_path, to_path))
continue index - 1
}
ignore(
@utils.rename_file_internal(sink.path, rotated_file_path(sink.path, 1)),
)
} else {
ignore(@utils.remove_file_internal(sink.path))
}
sink.handle.val = @utils.open_file_handle_internal(sink.path, false)
sink.handle.val is Some(_)
}
///|
fn rotate_if_needed_internal(sink : FileSink, next_line_bytes : Int) -> Bool {
match sink.rotation.val {
None => true
Some(rotation) =>
match sink.handle.val {
None => false
Some(handle) => {
let size = @utils.file_size_i64_internal(handle)
let next_line = next_line_bytes.to_int64()
if size + next_line <= rotation_max_bytes_internal(rotation) {
true
} else {
let rotated = rotate_file_sink_internal(sink, rotation)
if !rotated {
sink.rotation_failures.val += 1
}
rotated
}
}
}
}
}
///|
pub impl @sink_graph.Sink for FileSink with fn write(self, rec : Record) {
match self.handle.val {
None => self.write_failures.val += 1
Some(_) => {
let line = "\{(self.formatter)(rec)}\n"
let can_write = rotate_if_needed_internal(
self,
@utils.string_byte_length_internal(line),
)
if can_write {
match self.handle.val {
None => self.write_failures.val += 1
Some(active) => {
let wrote = @utils.write_file_handle_internal(active, line)
if wrote {
if self.auto_flush.val {
let flushed = @utils.flush_file_handle_internal(active)
if !flushed {
self.flush_failures.val += 1
}
}
} else {
self.write_failures.val += 1
}
}
}
} else {
self.write_failures.val += 1
}
}
}
}
+8
View File
@@ -0,0 +1,8 @@
import {
"Nanaloveyuki/BitLogger/src/core",
"Nanaloveyuki/BitLogger/src/file_model",
"Nanaloveyuki/BitLogger/src/formatting",
"Nanaloveyuki/BitLogger/src/sink_graph",
"Nanaloveyuki/BitLogger/src/utils",
"moonbitlang/core/ref",
}
+53
View File
@@ -0,0 +1,53 @@
// Generated using `moon info`, DON'T EDIT IT
package "Nanaloveyuki/BitLogger/src/file_runtime"
import {
"Nanaloveyuki/BitLogger/src/core",
"Nanaloveyuki/BitLogger/src/file_model",
"Nanaloveyuki/BitLogger/src/sink_graph",
}
// Values
pub fn file_sink(String, append? : Bool, auto_flush? : Bool, rotation? : @file_model.FileRotation?, formatter? : (@core.Record) -> String) -> FileSink
pub fn native_files_supported() -> Bool
// Errors
// Types and methods
pub struct FileSink {
// private fields
}
pub fn FileSink::append_mode(Self) -> Bool
pub fn FileSink::auto_flush_enabled(Self) -> Bool
pub fn FileSink::clear_rotation(Self) -> Unit
pub fn FileSink::close(Self) -> Bool
pub fn FileSink::default_policy(Self) -> @file_model.FileSinkPolicy
pub fn FileSink::flush(Self) -> Bool
pub fn FileSink::flush_failures(Self) -> Int
pub fn FileSink::is_available(Self) -> Bool
pub fn FileSink::open_failures(Self) -> Int
pub fn FileSink::path(Self) -> String
pub fn FileSink::policy(Self) -> @file_model.FileSinkPolicy
pub fn FileSink::policy_matches_default(Self) -> Bool
pub fn FileSink::reopen(Self, append? : Bool?) -> Bool
pub fn FileSink::reopen_append(Self) -> Bool
pub fn FileSink::reopen_truncate(Self) -> Bool
pub fn FileSink::reopen_with_current_policy(Self) -> Bool
pub fn FileSink::reset_failure_counters(Self) -> Unit
pub fn FileSink::reset_policy(Self) -> Unit
pub fn FileSink::rotation_config(Self) -> @file_model.FileRotation?
pub fn FileSink::rotation_enabled(Self) -> Bool
pub fn FileSink::rotation_failures(Self) -> Int
pub fn FileSink::set_append_mode(Self, Bool) -> Unit
pub fn FileSink::set_auto_flush(Self, Bool) -> Unit
pub fn FileSink::set_policy(Self, @file_model.FileSinkPolicy) -> Unit
pub fn FileSink::set_rotation(Self, @file_model.FileRotation?) -> Unit
pub fn FileSink::state(Self) -> @file_model.FileSinkState
pub fn FileSink::write_failures(Self) -> Int
pub impl @sink_graph.Sink for FileSink
// Type aliases
// Traits
+10 -10
View File
@@ -1,47 +1,47 @@
///|
pub type RecordPredicate = @utils.RecordPredicate
pub type RecordPredicate = @record_ops.RecordPredicate
///|
pub fn level_at_least(min_level : Level) -> RecordPredicate {
@utils.level_at_least(min_level)
@record_ops.level_at_least(min_level)
}
///|
pub fn target_is(target : String) -> RecordPredicate {
@utils.target_is(target)
@record_ops.target_is(target)
}
///|
pub fn target_has_prefix(prefix : String) -> RecordPredicate {
@utils.target_has_prefix(prefix)
@record_ops.target_has_prefix(prefix)
}
///|
pub fn message_contains(fragment : String) -> RecordPredicate {
@utils.message_contains(fragment)
@record_ops.message_contains(fragment)
}
///|
pub fn has_field(key : String) -> RecordPredicate {
@utils.has_field(key)
@record_ops.has_field(key)
}
///|
pub fn field_equals(key : String, value : String) -> RecordPredicate {
@utils.field_equals(key, value)
@record_ops.field_equals(key, value)
}
///|
pub fn not_(predicate : RecordPredicate) -> RecordPredicate {
@utils.not_(predicate)
@record_ops.not_(predicate)
}
///|
pub fn all_of(predicates : Array[RecordPredicate]) -> RecordPredicate {
@utils.all_of(predicates)
@record_ops.all_of(predicates)
}
///|
pub fn any_of(predicates : Array[RecordPredicate]) -> RecordPredicate {
@utils.any_of(predicates)
@record_ops.any_of(predicates)
}
+19 -19
View File
@@ -1,17 +1,17 @@
///|
pub type RecordFormatter = @utils.RecordFormatter
pub type RecordFormatter = @formatting.RecordFormatter
///|
pub type ColorMode = @utils.ColorMode
pub type ColorMode = @formatting.ColorMode
///|
pub type ColorSupport = @utils.ColorSupport
pub type ColorSupport = @formatting.ColorSupport
///|
pub type StyleMarkupMode = @utils.StyleMarkupMode
pub type StyleMarkupMode = @formatting.StyleMarkupMode
///|
pub type TextStyle = @utils.TextStyle
pub type TextStyle = @formatting.TextStyle
///|
pub fn text_style(
@@ -22,39 +22,39 @@ pub fn text_style(
italic? : Bool = false,
underline? : Bool = false,
) -> TextStyle {
@utils.text_style(fg~, bg~, bold~, dim~, italic~, underline~)
@formatting.text_style(fg~, bg~, bold~, dim~, italic~, underline~)
}
///|
pub type StyleTagRegistry = @utils.StyleTagRegistry
pub type StyleTagRegistry = @formatting.StyleTagRegistry
///|
pub fn style_tag_registry() -> StyleTagRegistry {
@utils.style_tag_registry()
@formatting.style_tag_registry()
}
///|
pub fn default_style_tag_registry() -> StyleTagRegistry {
@utils.default_style_tag_registry()
@formatting.default_style_tag_registry()
}
///|
pub fn global_style_tag_registry() -> StyleTagRegistry {
@utils.global_style_tag_registry()
@formatting.global_style_tag_registry()
}
///|
pub fn set_global_style_tag_registry(registry : StyleTagRegistry) -> Unit {
@utils.set_global_style_tag_registry(registry)
@formatting.set_global_style_tag_registry(registry)
}
///|
pub fn reset_global_style_tag_registry() -> Unit {
@utils.reset_global_style_tag_registry()
@formatting.reset_global_style_tag_registry()
}
///|
pub type TextFormatter = @utils.TextFormatter
pub type TextFormatter = @formatting.TextFormatter
///|
pub fn text_formatter(
@@ -72,7 +72,7 @@ pub fn text_formatter(
fields_style_markup? : StyleMarkupMode = StyleMarkupMode::Disabled,
style_tags? : StyleTagRegistry? = None,
) -> TextFormatter {
@utils.text_formatter(
@formatting.text_formatter(
show_timestamp~,
show_level~,
show_target~,
@@ -91,17 +91,17 @@ pub fn text_formatter(
///|
pub fn color_support_label(support : ColorSupport) -> String {
@utils.color_support_label(support)
@formatting.color_support_label(support)
}
///|
pub fn style_markup_mode_label(mode : StyleMarkupMode) -> String {
@utils.style_markup_mode_label(mode)
@formatting.style_markup_mode_label(mode)
}
///|
pub fn color_mode_label(mode : ColorMode) -> String {
@utils.color_mode_label(mode)
@formatting.color_mode_label(mode)
}
///|
@@ -109,10 +109,10 @@ pub fn format_text(
rec : Record,
formatter? : TextFormatter = text_formatter(),
) -> String {
@utils.format_text(rec, formatter~)
@formatting.format_text(rec, formatter~)
}
///|
pub fn format_json(rec : Record) -> String {
@utils.format_json(rec)
@formatting.format_json(rec)
}
File diff suppressed because it is too large Load Diff
+7
View File
@@ -0,0 +1,7 @@
import {
"Nanaloveyuki/BitLogger/src/core",
"moonbitlang/core/env",
"moonbitlang/core/json",
"moonbitlang/core/ref",
"moonbitlang/core/string",
}
+96
View File
@@ -0,0 +1,96 @@
// Generated using `moon info`, DON'T EDIT IT
package "Nanaloveyuki/BitLogger/src/formatting"
import {
"Nanaloveyuki/BitLogger/src/core",
}
// Values
pub fn color_mode_label(ColorMode) -> String
pub fn color_support_label(ColorSupport) -> String
pub fn default_style_tag_registry() -> StyleTagRegistry
pub fn format_json(@core.Record) -> String
pub fn format_text(@core.Record, formatter? : TextFormatter) -> String
pub fn global_style_tag_registry() -> StyleTagRegistry
pub fn reset_global_style_tag_registry() -> Unit
pub fn set_global_style_tag_registry(StyleTagRegistry) -> Unit
pub fn style_markup_mode_label(StyleMarkupMode) -> String
pub fn style_tag_registry() -> StyleTagRegistry
pub fn text_formatter(show_timestamp? : Bool, show_level? : Bool, show_target? : Bool, show_fields? : Bool, separator? : String, field_separator? : String, template? : String, color_mode? : ColorMode, color_support? : ColorSupport, style_markup? : StyleMarkupMode, target_style_markup? : StyleMarkupMode, fields_style_markup? : StyleMarkupMode, style_tags? : StyleTagRegistry?) -> TextFormatter
pub fn text_style(fg? : String?, bg? : String?, bold? : Bool, dim? : Bool, italic? : Bool, underline? : Bool) -> TextStyle
// Errors
// Types and methods
pub(all) enum ColorMode {
Never
Auto
Always
}
pub(all) enum ColorSupport {
Basic
TrueColor
}
pub(all) enum StyleMarkupMode {
Disabled
Builtin
Full
}
pub struct StyleTagRegistry {
entries : Map[String, TextStyle]
}
pub fn StyleTagRegistry::contains(Self, String) -> Bool
pub fn StyleTagRegistry::define_alias(Self, String, String) -> Self
pub fn StyleTagRegistry::get(Self, String) -> TextStyle?
pub fn StyleTagRegistry::set_tag(Self, String, style? : TextStyle, fg? : String?, bg? : String?, bold? : Bool, dim? : Bool, italic? : Bool, underline? : Bool) -> Self
pub struct TextFormatter {
show_timestamp : Bool
show_level : Bool
show_target : Bool
show_fields : Bool
separator : String
field_separator : String
template : String
color_mode : ColorMode
color_support : ColorSupport
style_markup : StyleMarkupMode
target_style_markup : StyleMarkupMode
fields_style_markup : StyleMarkupMode
style_tags : StyleTagRegistry?
}
pub fn TextFormatter::with_color_support(Self, ColorSupport) -> Self
pub fn TextFormatter::with_fields_style_markup(Self, StyleMarkupMode) -> Self
pub fn TextFormatter::with_style_markup(Self, StyleMarkupMode) -> Self
pub fn TextFormatter::with_style_tags(Self, StyleTagRegistry) -> Self
pub fn TextFormatter::with_target_style_markup(Self, StyleMarkupMode) -> Self
pub fn TextFormatter::without_style_markup(Self) -> Self
pub struct TextStyle {
fg : String?
bg : String?
bold : Bool
dim : Bool
italic : Bool
underline : Bool
}
// Type aliases
pub type RecordFormatter = (@core.Record) -> String
// Traits
+1 -1
View File
@@ -43,7 +43,7 @@ pub fn[S] Logger::with_context_fields(
) -> Logger[ContextSink[S]] {
{
min_level: self.min_level,
sink: ContextSink::{ sink: self.sink, context_fields: fields },
sink: context_sink(self.sink, fields),
target: self.target,
timestamp: self.timestamp,
}
+12 -9
View File
@@ -1,6 +1,14 @@
import {
"Nanaloveyuki/BitLogger/src/record_ops",
"Nanaloveyuki/BitLogger/src/config_model",
"Nanaloveyuki/BitLogger/src/core",
"Nanaloveyuki/BitLogger/src/utils",
"Nanaloveyuki/BitLogger/src/file_model",
"Nanaloveyuki/BitLogger/src/file_runtime",
"Nanaloveyuki/BitLogger/src/formatting",
"Nanaloveyuki/BitLogger/src/presets_pkg",
"Nanaloveyuki/BitLogger/src/queue_model",
"Nanaloveyuki/BitLogger/src/runtime",
"Nanaloveyuki/BitLogger/src/sink_graph",
"maria/json_parser",
"moonbitlang/core/array",
"moonbitlang/core/builtin",
@@ -10,11 +18,6 @@ import {
"moonbitlang/core/ref",
}
options(
targets: {
"sinks_file.mbt": [ "native", "llvm", "js", "wasm", "wasm-gc" ],
"runtime_file_controls.mbt": [ "native", "llvm", "js", "wasm", "wasm-gc" ],
"file_backend_native.mbt": [ "native", "llvm" ],
"file_backend_stub.mbt": [ "js", "wasm", "wasm-gc" ],
},
)
import {
"Nanaloveyuki/BitLogger/src/utils",
} for "wbtest"
+8 -8
View File
@@ -1,29 +1,29 @@
///|
pub type RecordPatch = @utils.RecordPatch
pub type RecordPatch = @record_ops.RecordPatch
///|
pub fn identity_patch() -> RecordPatch {
@utils.identity_patch()
@record_ops.identity_patch()
}
///|
pub fn set_target(target : String) -> RecordPatch {
@utils.set_target(target)
@record_ops.set_target(target)
}
///|
pub fn prefix_message(prefix : String) -> RecordPatch {
@utils.prefix_message(prefix)
@record_ops.prefix_message(prefix)
}
///|
pub fn append_fields(extra_fields : Array[Field]) -> RecordPatch {
@utils.append_fields(extra_fields)
@record_ops.append_fields(extra_fields)
}
///|
pub fn redact_field(key : String, placeholder? : String = "***") -> RecordPatch {
@utils.redact_field(key, placeholder~)
@record_ops.redact_field(key, placeholder~)
}
///|
@@ -31,10 +31,10 @@ pub fn redact_fields(
keys : Array[String],
placeholder? : String = "***",
) -> RecordPatch {
@utils.redact_fields(keys, placeholder~)
@record_ops.redact_fields(keys, placeholder~)
}
///|
pub fn compose_patches(patches : Array[RecordPatch]) -> RecordPatch {
@utils.compose_patches(patches)
@record_ops.compose_patches(patches)
}
+365
View File
@@ -0,0 +1,365 @@
// Generated using `moon info`, DON'T EDIT IT
package "Nanaloveyuki/BitLogger/src"
import {
"Nanaloveyuki/BitLogger/src/config_model",
"Nanaloveyuki/BitLogger/src/core",
"Nanaloveyuki/BitLogger/src/file_model",
"Nanaloveyuki/BitLogger/src/file_runtime",
"Nanaloveyuki/BitLogger/src/formatting",
"Nanaloveyuki/BitLogger/src/queue_model",
"Nanaloveyuki/BitLogger/src/runtime",
"Nanaloveyuki/BitLogger/src/sink_graph",
"maria/json_parser",
}
// Values
pub fn all_of(Array[(@core.Record) -> Bool]) -> (@core.Record) -> Bool
pub fn any_of(Array[(@core.Record) -> Bool]) -> (@core.Record) -> Bool
pub fn append_fields(Array[@core.Field]) -> (@core.Record) -> @core.Record
pub fn[S] buffered_sink(S, flush_limit? : Int) -> @sink_graph.BufferedSink[S]
pub fn build_application_logger(@config_model.LoggerConfig) -> Logger[@runtime.RuntimeSink]
pub fn build_library_logger(@config_model.LoggerConfig) -> LibraryLogger[@runtime.RuntimeSink]
pub fn build_logger(@config_model.LoggerConfig) -> Logger[@runtime.RuntimeSink]
pub fn callback_sink((@core.Record) -> Unit) -> @sink_graph.CallbackSink
pub fn color_mode_label(@formatting.ColorMode) -> String
pub fn color_support_label(@formatting.ColorSupport) -> String
pub fn compose_patches(Array[(@core.Record) -> @core.Record]) -> (@core.Record) -> @core.Record
pub fn console(min_level? : @core.Level, target? : String, timestamp? : Bool) -> @config_model.LoggerConfig
pub fn console_sink() -> @sink_graph.ConsoleSink
pub fn[S] context_sink(S, Array[@core.Field]) -> @sink_graph.ContextSink[S]
pub fn debug(String, fields? : Array[@core.Field]) -> Unit
pub fn default_library_logger() -> LibraryLogger[@sink_graph.ConsoleSink]
pub fn default_logger() -> Logger[@sink_graph.ConsoleSink]
pub fn default_logger_config() -> @config_model.LoggerConfig
pub fn default_sink_config() -> @config_model.SinkConfig
pub fn default_style_tag_registry() -> @formatting.StyleTagRegistry
pub fn default_text_formatter_config() -> @config_model.TextFormatterConfig
pub fn error(String, fields? : Array[@core.Field]) -> Unit
pub fn[A, B] fanout_sink(A, B) -> @sink_graph.FanoutSink[A, B]
pub fn field(String, String) -> @core.Field
pub fn field_equals(String, String) -> (@core.Record) -> Bool
pub fn fields(Array[(String, String)]) -> Array[@core.Field]
pub fn file(String, min_level? : @core.Level, target? : String, timestamp? : Bool, append? : Bool, auto_flush? : Bool, rotation? : @file_model.FileRotation?, text_formatter? : @config_model.TextFormatterConfig) -> @config_model.LoggerConfig raise @config_model.ConfigError
pub fn file_rotation(Int, max_backups? : Int) -> @file_model.FileRotation
pub fn file_rotation_config_to_json(@file_model.FileRotation) -> @json_parser.JsonValue
pub fn file_rotation_i64(Int64, max_backups? : Int) -> @file_model.FileRotation
pub fn file_sink(String, append? : Bool, auto_flush? : Bool, rotation? : @file_model.FileRotation?, formatter? : (@core.Record) -> String) -> @file_runtime.FileSink
pub fn file_sink_policy_to_json(@file_model.FileSinkPolicy) -> @json_parser.JsonValue
pub fn file_sink_state_to_json(@file_model.FileSinkState) -> @json_parser.JsonValue
pub fn[S] filter_sink(S, (@core.Record) -> Bool) -> @sink_graph.FilterSink[S]
pub fn format_json(@core.Record) -> String
pub fn format_text(@core.Record, formatter? : @formatting.TextFormatter) -> String
pub fn formatted_callback_sink((@core.Record) -> String, (String) -> Unit) -> @sink_graph.FormattedCallbackSink
pub fn formatted_console_sink((@core.Record) -> String) -> @sink_graph.FormattedConsoleSink
pub fn global_style_tag_registry() -> @formatting.StyleTagRegistry
pub fn has_field(String) -> (@core.Record) -> Bool
pub fn identity_patch() -> (@core.Record) -> @core.Record
pub fn info(String, fields? : Array[@core.Field]) -> Unit
pub fn json_console(min_level? : @core.Level, target? : String, timestamp? : Bool) -> @config_model.LoggerConfig
pub fn json_console_sink() -> @sink_graph.JsonConsoleSink
pub fn level_at_least(@core.Level) -> (@core.Record) -> Bool
pub fn log(@core.Level, String, fields? : Array[@core.Field]) -> Unit
pub fn logger_config_to_json(@config_model.LoggerConfig) -> @json_parser.JsonValue
pub fn message_contains(String) -> (@core.Record) -> Bool
pub fn native_files_supported() -> Bool
pub fn not_((@core.Record) -> Bool) -> (@core.Record) -> Bool
pub fn parse_and_build_application_logger(String) -> Logger[@runtime.RuntimeSink] raise @config_model.ConfigError
pub fn parse_and_build_library_logger(String) -> LibraryLogger[@runtime.RuntimeSink] raise @config_model.ConfigError
pub fn parse_and_build_logger(String) -> Logger[@runtime.RuntimeSink] raise @config_model.ConfigError
pub fn parse_logger_config_text(String) -> @config_model.LoggerConfig raise @config_model.ConfigError
pub fn[S] patch_sink(S, (@core.Record) -> @core.Record) -> @sink_graph.PatchSink[S]
pub fn prefix_message(String) -> (@core.Record) -> @core.Record
pub fn queue_config_to_json(@config_model.QueueConfig) -> @json_parser.JsonValue
pub fn[S] queued_sink(S, max_pending? : Int, overflow? : @queue_model.QueueOverflowPolicy) -> @sink_graph.QueuedSink[S]
pub fn redact_field(String, placeholder? : String) -> (@core.Record) -> @core.Record
pub fn redact_fields(Array[String], placeholder? : String) -> (@core.Record) -> @core.Record
pub fn reset_global_style_tag_registry() -> Unit
pub fn runtime_file_state_to_json(@file_model.RuntimeFileState) -> @json_parser.JsonValue
pub fn set_default_min_level(@core.Level) -> Unit
pub fn set_default_target(String) -> Unit
pub fn set_global_style_tag_registry(@formatting.StyleTagRegistry) -> Unit
pub fn set_target(String) -> (@core.Record) -> @core.Record
pub fn sink_config_to_json(@config_model.SinkConfig) -> @json_parser.JsonValue
pub fn[A, B] split_by_level(A, B, min_level? : @core.Level) -> @sink_graph.SplitSink[A, B]
pub fn[A, B] split_sink(A, B, (@core.Record) -> Bool) -> @sink_graph.SplitSink[A, B]
pub fn stringify_file_sink_policy(@file_model.FileSinkPolicy, pretty? : Bool) -> String
pub fn stringify_file_sink_state(@file_model.FileSinkState, pretty? : Bool) -> String
pub fn stringify_logger_config(@config_model.LoggerConfig, pretty? : Bool) -> String
pub fn stringify_queue_config(@config_model.QueueConfig, pretty? : Bool) -> String
pub fn stringify_runtime_file_state(@file_model.RuntimeFileState, pretty? : Bool) -> String
pub fn stringify_sink_config(@config_model.SinkConfig, pretty? : Bool) -> String
pub fn stringify_text_formatter_config(@config_model.TextFormatterConfig, pretty? : Bool) -> String
pub fn style_markup_mode_label(@formatting.StyleMarkupMode) -> String
pub fn style_tag_registry() -> @formatting.StyleTagRegistry
pub fn target_has_prefix(String) -> (@core.Record) -> Bool
pub fn target_is(String) -> (@core.Record) -> Bool
pub fn text_callback_sink(@formatting.TextFormatter, (String) -> Unit) -> @sink_graph.FormattedCallbackSink
pub fn text_console(min_level? : @core.Level, target? : String, timestamp? : Bool, text_formatter? : @config_model.TextFormatterConfig) -> @config_model.LoggerConfig
pub fn text_console_sink(@formatting.TextFormatter) -> @sink_graph.FormattedConsoleSink
pub fn text_formatter(show_timestamp? : Bool, show_level? : Bool, show_target? : Bool, show_fields? : Bool, separator? : String, field_separator? : String, template? : String, color_mode? : @formatting.ColorMode, color_support? : @formatting.ColorSupport, style_markup? : @formatting.StyleMarkupMode, target_style_markup? : @formatting.StyleMarkupMode, fields_style_markup? : @formatting.StyleMarkupMode, style_tags? : @formatting.StyleTagRegistry?) -> @formatting.TextFormatter
pub fn text_formatter_config_to_json(@config_model.TextFormatterConfig) -> @json_parser.JsonValue
pub fn text_style(fg? : String?, bg? : String?, bold? : Bool, dim? : Bool, italic? : Bool, underline? : Bool) -> @formatting.TextStyle
pub fn trace(String, fields? : Array[@core.Field]) -> Unit
pub fn warn(String, fields? : Array[@core.Field]) -> Unit
pub fn with_file_rotation(@config_model.LoggerConfig, Int, max_backups? : Int) -> @config_model.LoggerConfig
pub fn with_file_rotation_i64(@config_model.LoggerConfig, Int64, max_backups? : Int) -> @config_model.LoggerConfig
pub fn with_queue(@config_model.LoggerConfig, max_pending? : Int, overflow? : @queue_model.QueueOverflowPolicy) -> @config_model.LoggerConfig
// Errors
// Types and methods
pub struct LibraryLogger[S] {
inner : Logger[S]
}
pub fn[S] LibraryLogger::bind(Self[S], Array[@core.Field]) -> Self[@sink_graph.ContextSink[S]]
pub fn[S] LibraryLogger::child(Self[S], String) -> Self[S]
pub fn[S : @sink_graph.Sink] LibraryLogger::error(Self[S], String, fields? : Array[@core.Field]) -> Unit
pub fn[S : @sink_graph.Sink] LibraryLogger::info(Self[S], String, fields? : Array[@core.Field]) -> Unit
pub fn[S] LibraryLogger::is_enabled(Self[S], @core.Level) -> Bool
pub fn[S : @sink_graph.Sink] LibraryLogger::log(Self[S], @core.Level, String, fields? : Array[@core.Field], target? : String) -> Unit
pub fn[S] LibraryLogger::new(S, min_level? : @core.Level, target? : String) -> Self[S]
pub fn[S] LibraryLogger::to_logger(Self[S]) -> Logger[S]
pub fn[S : @sink_graph.Sink] LibraryLogger::warn(Self[S], String, fields? : Array[@core.Field]) -> Unit
pub fn[S] LibraryLogger::with_context_fields(Self[S], Array[@core.Field]) -> Self[@sink_graph.ContextSink[S]]
pub fn[S] LibraryLogger::with_target(Self[S], String) -> Self[S]
pub struct Logger[S] {
min_level : @core.Level
sink : S
target : String
timestamp : Bool
}
pub fn[S] Logger::bind(Self[S], Array[@core.Field]) -> Self[@sink_graph.ContextSink[S]]
pub fn[S] Logger::child(Self[S], String) -> Self[S]
pub fn Logger::close(Self[@runtime.RuntimeSink]) -> Bool
pub fn[S : @sink_graph.Sink] Logger::debug(Self[S], String, fields? : Array[@core.Field]) -> Unit
pub fn Logger::drain(Self[@runtime.RuntimeSink], max_items? : Int) -> Int
pub fn Logger::drain_progress(Self[@runtime.RuntimeSink], max_items? : Int) -> @runtime.RuntimeSinkProgress
pub fn Logger::dropped_count(Self[@runtime.RuntimeSink]) -> Int
pub fn[S : @sink_graph.Sink] Logger::error(Self[S], String, fields? : Array[@core.Field]) -> Unit
pub fn Logger::file_append_mode(Self[@runtime.RuntimeSink]) -> Bool
pub fn Logger::file_auto_flush(Self[@runtime.RuntimeSink]) -> Bool
pub fn Logger::file_available(Self[@runtime.RuntimeSink]) -> Bool
pub fn Logger::file_clear_rotation(Self[@runtime.RuntimeSink]) -> Bool
pub fn Logger::file_close(Self[@runtime.RuntimeSink]) -> Bool
pub fn Logger::file_default_policy(Self[@runtime.RuntimeSink]) -> @file_model.FileSinkPolicy
pub fn Logger::file_default_policy_or_none(Self[@runtime.RuntimeSink]) -> @file_model.FileSinkPolicy?
pub fn Logger::file_flush(Self[@runtime.RuntimeSink]) -> Bool
pub fn Logger::file_flush_failures(Self[@runtime.RuntimeSink]) -> Int
pub fn Logger::file_open_failures(Self[@runtime.RuntimeSink]) -> Int
pub fn Logger::file_path(Self[@runtime.RuntimeSink]) -> String
pub fn Logger::file_path_or_none(Self[@runtime.RuntimeSink]) -> String?
pub fn Logger::file_policy(Self[@runtime.RuntimeSink]) -> @file_model.FileSinkPolicy
pub fn Logger::file_policy_matches_default(Self[@runtime.RuntimeSink]) -> Bool
pub fn Logger::file_policy_or_none(Self[@runtime.RuntimeSink]) -> @file_model.FileSinkPolicy?
pub fn Logger::file_reopen(Self[@runtime.RuntimeSink], append? : Bool?) -> Bool
pub fn Logger::file_reopen_append(Self[@runtime.RuntimeSink]) -> Bool
pub fn Logger::file_reopen_truncate(Self[@runtime.RuntimeSink]) -> Bool
pub fn Logger::file_reopen_with_current_policy(Self[@runtime.RuntimeSink]) -> Bool
pub fn Logger::file_reset_failure_counters(Self[@runtime.RuntimeSink]) -> Bool
pub fn Logger::file_reset_policy(Self[@runtime.RuntimeSink]) -> Bool
pub fn Logger::file_rotation_config(Self[@runtime.RuntimeSink]) -> @file_model.FileRotation?
pub fn Logger::file_rotation_enabled(Self[@runtime.RuntimeSink]) -> Bool
pub fn Logger::file_rotation_failures(Self[@runtime.RuntimeSink]) -> Int
pub fn Logger::file_runtime_state(Self[@runtime.RuntimeSink]) -> @file_model.RuntimeFileState?
pub fn Logger::file_set_append_mode(Self[@runtime.RuntimeSink], Bool) -> Bool
pub fn Logger::file_set_auto_flush(Self[@runtime.RuntimeSink], Bool) -> Bool
pub fn Logger::file_set_policy(Self[@runtime.RuntimeSink], @file_model.FileSinkPolicy) -> Bool
pub fn Logger::file_set_rotation(Self[@runtime.RuntimeSink], @file_model.FileRotation?) -> Bool
pub fn Logger::file_state(Self[@runtime.RuntimeSink]) -> @file_model.FileSinkState
pub fn Logger::file_state_or_none(Self[@runtime.RuntimeSink]) -> @file_model.FileSinkState?
pub fn Logger::file_write_failures(Self[@runtime.RuntimeSink]) -> Int
pub fn Logger::flush(Self[@runtime.RuntimeSink]) -> Int
pub fn Logger::flush_progress(Self[@runtime.RuntimeSink]) -> @runtime.RuntimeSinkProgress
pub fn[S : @sink_graph.Sink] Logger::info(Self[S], String, fields? : Array[@core.Field]) -> Unit
pub fn[S] Logger::is_enabled(Self[S], @core.Level) -> Bool
pub fn[S : @sink_graph.Sink] Logger::log(Self[S], @core.Level, String, fields? : Array[@core.Field], target? : String) -> Unit
pub fn[S] Logger::new(S, min_level? : @core.Level, target? : String) -> Self[S]
pub fn Logger::pending_count(Self[@runtime.RuntimeSink]) -> Int
pub fn[S] Logger::to_library_logger(Self[S]) -> LibraryLogger[S]
pub fn[S : @sink_graph.Sink] Logger::trace(Self[S], String, fields? : Array[@core.Field]) -> Unit
pub fn[S : @sink_graph.Sink] Logger::warn(Self[S], String, fields? : Array[@core.Field]) -> Unit
pub fn[S] Logger::with_context_fields(Self[S], Array[@core.Field]) -> Self[@sink_graph.ContextSink[S]]
pub fn[S] Logger::with_filter(Self[S], (@core.Record) -> Bool) -> Self[@sink_graph.FilterSink[S]]
pub fn[S] Logger::with_min_level(Self[S], @core.Level) -> Self[S]
pub fn[S] Logger::with_patch(Self[S], (@core.Record) -> @core.Record) -> Self[@sink_graph.PatchSink[S]]
pub fn[S] Logger::with_queue(Self[S], max_pending? : Int, overflow? : @queue_model.QueueOverflowPolicy) -> Self[@sink_graph.QueuedSink[S]]
pub fn[S] Logger::with_target(Self[S], String) -> Self[S]
pub fn[S] Logger::with_timestamp(Self[S], enabled? : Bool) -> Self[S]
// Type aliases
pub type ApplicationLogger = Logger[@runtime.RuntimeSink]
pub using @sink_graph {type BufferedSink}
pub using @sink_graph {type CallbackSink}
pub using @formatting {type ColorMode}
pub using @formatting {type ColorSupport}
pub using @config_model {type ConfigError}
pub type ConfiguredLogger = Logger[@runtime.RuntimeSink]
pub using @sink_graph {type ConsoleSink}
pub using @sink_graph {type ContextSink}
pub using @sink_graph {type FanoutSink}
pub using @core {type Field}
pub using @file_model {type FileRotation}
pub using @file_runtime {type FileSink}
pub using @file_model {type FileSinkPolicy}
pub using @file_model {type FileSinkState}
pub using @sink_graph {type FilterSink}
pub using @sink_graph {type FormattedCallbackSink}
pub using @sink_graph {type FormattedConsoleSink}
pub using @sink_graph {type JsonConsoleSink}
pub using @core {type Level}
pub using @config_model {type LoggerConfig}
pub using @sink_graph {type PatchSink}
pub using @config_model {type QueueConfig}
pub using @queue_model {type QueueOverflowPolicy}
pub using @sink_graph {type QueuedSink}
pub using @core {type Record}
pub type RecordFormatter = (@core.Record) -> String
pub type RecordPatch = (@core.Record) -> @core.Record
pub type RecordPredicate = (@core.Record) -> Bool
pub using @file_model {type RuntimeFileState}
pub using @runtime {type RuntimeSink}
pub using @runtime {type RuntimeSinkProgress}
pub using @config_model {type SinkConfig}
pub using @config_model {type SinkKind}
pub using @sink_graph {type SplitSink}
pub using @formatting {type StyleMarkupMode}
pub using @formatting {type StyleTagRegistry}
pub using @formatting {type TextFormatter}
pub using @config_model {type TextFormatterConfig}
pub using @formatting {type TextStyle}
pub using @sink_graph {trait Sink}
// Traits
+12 -73
View File
@@ -4,12 +4,7 @@ pub fn console(
target? : String = "",
timestamp? : Bool = false,
) -> LoggerConfig {
LoggerConfig::new(
min_level~,
target~,
timestamp~,
sink=SinkConfig::new(kind=SinkKind::Console),
)
@presets_pkg.console(min_level~, target~, timestamp~)
}
///|
@@ -18,12 +13,7 @@ pub fn json_console(
target? : String = "",
timestamp? : Bool = false,
) -> LoggerConfig {
LoggerConfig::new(
min_level~,
target~,
timestamp~,
sink=SinkConfig::new(kind=SinkKind::JsonConsole),
)
@presets_pkg.json_console(min_level~, target~, timestamp~)
}
///|
@@ -33,12 +23,7 @@ pub fn text_console(
timestamp? : Bool = false,
text_formatter? : TextFormatterConfig = default_text_formatter_config(),
) -> LoggerConfig {
LoggerConfig::new(
min_level~,
target~,
timestamp~,
sink=SinkConfig::new(kind=SinkKind::TextConsole, text_formatter~),
)
@presets_pkg.text_console(min_level~, target~, timestamp~, text_formatter~)
}
///|
@@ -52,21 +37,15 @@ pub fn file(
rotation? : FileRotation? = None,
text_formatter? : TextFormatterConfig = default_text_formatter_config(),
) -> LoggerConfig raise ConfigError {
if path == "" {
raise ConfigError::InvalidConfig("File sink requires non-empty path")
}
LoggerConfig::new(
@presets_pkg.file(
path,
min_level~,
target~,
timestamp~,
sink=SinkConfig::new(
kind=SinkKind::File,
path~,
append~,
auto_flush~,
rotation~,
text_formatter~,
),
append~,
auto_flush~,
rotation~,
text_formatter~,
)
}
@@ -76,13 +55,7 @@ pub fn with_queue(
max_pending? : Int = 0,
overflow? : QueueOverflowPolicy = QueueOverflowPolicy::DropNewest,
) -> LoggerConfig {
LoggerConfig::new(
min_level=config.min_level,
target=config.target,
timestamp=config.timestamp,
sink=config.sink,
queue=Some(QueueConfig::new(max_pending, overflow~)),
)
@presets_pkg.with_queue(config, max_pending~, overflow~)
}
///|
@@ -91,24 +64,7 @@ pub fn with_file_rotation(
max_bytes : Int,
max_backups? : Int = 1,
) -> LoggerConfig {
match config.sink.kind {
SinkKind::File =>
LoggerConfig::new(
min_level=config.min_level,
target=config.target,
timestamp=config.timestamp,
sink=SinkConfig::new(
kind=config.sink.kind,
path=config.sink.path,
append=config.sink.append,
auto_flush=config.sink.auto_flush,
rotation=Some(file_rotation(max_bytes, max_backups~)),
text_formatter=config.sink.text_formatter,
),
queue=config.queue,
)
_ => config
}
@presets_pkg.with_file_rotation(config, max_bytes, max_backups~)
}
///|
@@ -117,22 +73,5 @@ pub fn with_file_rotation_i64(
max_bytes : Int64,
max_backups? : Int = 1,
) -> LoggerConfig {
match config.sink.kind {
SinkKind::File =>
LoggerConfig::new(
min_level=config.min_level,
target=config.target,
timestamp=config.timestamp,
sink=SinkConfig::new(
kind=config.sink.kind,
path=config.sink.path,
append=config.sink.append,
auto_flush=config.sink.auto_flush,
rotation=Some(file_rotation_i64(max_bytes, max_backups~)),
text_formatter=config.sink.text_formatter,
),
queue=config.queue,
)
_ => config
}
@presets_pkg.with_file_rotation_i64(config, max_bytes, max_backups~)
}
+6
View File
@@ -0,0 +1,6 @@
import {
"Nanaloveyuki/BitLogger/src/config_model",
"Nanaloveyuki/BitLogger/src/core",
"Nanaloveyuki/BitLogger/src/file_model",
"Nanaloveyuki/BitLogger/src/queue_model",
}
+33
View File
@@ -0,0 +1,33 @@
// Generated using `moon info`, DON'T EDIT IT
package "Nanaloveyuki/BitLogger/src/presets_pkg"
import {
"Nanaloveyuki/BitLogger/src/config_model",
"Nanaloveyuki/BitLogger/src/core",
"Nanaloveyuki/BitLogger/src/file_model",
"Nanaloveyuki/BitLogger/src/queue_model",
}
// Values
pub fn console(min_level? : @core.Level, target? : String, timestamp? : Bool) -> @config_model.LoggerConfig
pub fn file(String, min_level? : @core.Level, target? : String, timestamp? : Bool, append? : Bool, auto_flush? : Bool, rotation? : @file_model.FileRotation?, text_formatter? : @config_model.TextFormatterConfig) -> @config_model.LoggerConfig raise @config_model.ConfigError
pub fn json_console(min_level? : @core.Level, target? : String, timestamp? : Bool) -> @config_model.LoggerConfig
pub fn text_console(min_level? : @core.Level, target? : String, timestamp? : Bool, text_formatter? : @config_model.TextFormatterConfig) -> @config_model.LoggerConfig
pub fn with_file_rotation(@config_model.LoggerConfig, Int, max_backups? : Int) -> @config_model.LoggerConfig
pub fn with_file_rotation_i64(@config_model.LoggerConfig, Int64, max_backups? : Int) -> @config_model.LoggerConfig
pub fn with_queue(@config_model.LoggerConfig, max_pending? : Int, overflow? : @queue_model.QueueOverflowPolicy) -> @config_model.LoggerConfig
// Errors
// Types and methods
// Type aliases
// Traits
+143
View File
@@ -0,0 +1,143 @@
///|
pub fn console(
min_level? : @core.Level = @core.Level::Info,
target? : String = "",
timestamp? : Bool = false,
) -> @config_model.LoggerConfig {
@config_model.LoggerConfig::new(
min_level~,
target~,
timestamp~,
sink=@config_model.SinkConfig::new(kind=@config_model.SinkKind::Console),
)
}
///|
pub fn json_console(
min_level? : @core.Level = @core.Level::Info,
target? : String = "",
timestamp? : Bool = false,
) -> @config_model.LoggerConfig {
@config_model.LoggerConfig::new(
min_level~,
target~,
timestamp~,
sink=@config_model.SinkConfig::new(kind=@config_model.SinkKind::JsonConsole),
)
}
///|
pub fn text_console(
min_level? : @core.Level = @core.Level::Info,
target? : String = "",
timestamp? : Bool = false,
text_formatter? : @config_model.TextFormatterConfig = @config_model.default_text_formatter_config(),
) -> @config_model.LoggerConfig {
@config_model.LoggerConfig::new(
min_level~,
target~,
timestamp~,
sink=@config_model.SinkConfig::new(
kind=@config_model.SinkKind::TextConsole,
text_formatter~,
),
)
}
///|
pub fn file(
path : String,
min_level? : @core.Level = @core.Level::Info,
target? : String = "",
timestamp? : Bool = false,
append? : Bool = true,
auto_flush? : Bool = true,
rotation? : @file_model.FileRotation? = None,
text_formatter? : @config_model.TextFormatterConfig = @config_model.default_text_formatter_config(),
) -> @config_model.LoggerConfig raise @config_model.ConfigError {
if path == "" {
raise @config_model.ConfigError::InvalidConfig(
"File sink requires non-empty path",
)
}
@config_model.LoggerConfig::new(
min_level~,
target~,
timestamp~,
sink=@config_model.SinkConfig::new(
kind=@config_model.SinkKind::File,
path~,
append~,
auto_flush~,
rotation~,
text_formatter~,
),
)
}
///|
pub fn with_queue(
config : @config_model.LoggerConfig,
max_pending? : Int = 0,
overflow? : @queue_model.QueueOverflowPolicy = @queue_model.QueueOverflowPolicy::DropNewest,
) -> @config_model.LoggerConfig {
@config_model.LoggerConfig::new(
min_level=config.min_level,
target=config.target,
timestamp=config.timestamp,
sink=config.sink,
queue=Some(@config_model.QueueConfig::new(max_pending, overflow~)),
)
}
///|
pub fn with_file_rotation(
config : @config_model.LoggerConfig,
max_bytes : Int,
max_backups? : Int = 1,
) -> @config_model.LoggerConfig {
match config.sink.kind {
@config_model.SinkKind::File =>
@config_model.LoggerConfig::new(
min_level=config.min_level,
target=config.target,
timestamp=config.timestamp,
sink=@config_model.SinkConfig::new(
kind=config.sink.kind,
path=config.sink.path,
append=config.sink.append,
auto_flush=config.sink.auto_flush,
rotation=Some(@file_model.file_rotation(max_bytes, max_backups~)),
text_formatter=config.sink.text_formatter,
),
queue=config.queue,
)
_ => config
}
}
///|
pub fn with_file_rotation_i64(
config : @config_model.LoggerConfig,
max_bytes : Int64,
max_backups? : Int = 1,
) -> @config_model.LoggerConfig {
match config.sink.kind {
@config_model.SinkKind::File =>
@config_model.LoggerConfig::new(
min_level=config.min_level,
target=config.target,
timestamp=config.timestamp,
sink=@config_model.SinkConfig::new(
kind=config.sink.kind,
path=config.sink.path,
append=config.sink.append,
auto_flush=config.sink.auto_flush,
rotation=Some(@file_model.file_rotation_i64(max_bytes, max_backups~)),
text_formatter=config.sink.text_formatter,
),
queue=config.queue,
)
_ => config
}
}
+1
View File
@@ -0,0 +1 @@
///|
+17
View File
@@ -0,0 +1,17 @@
// Generated using `moon info`, DON'T EDIT IT
package "Nanaloveyuki/BitLogger/src/queue_model"
// Values
// Errors
// Types and methods
pub(all) enum QueueOverflowPolicy {
DropNewest
DropOldest
}
// Type aliases
// Traits
+5
View File
@@ -0,0 +1,5 @@
///|
pub(all) enum QueueOverflowPolicy {
DropNewest
DropOldest
}
+75
View File
@@ -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
}
}
+4
View File
@@ -0,0 +1,4 @@
import {
"Nanaloveyuki/BitLogger/src/core",
"moonbitlang/core/string",
}
+74
View File
@@ -0,0 +1,74 @@
///|
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
}
}
+51
View File
@@ -0,0 +1,51 @@
// Generated using `moon info`, DON'T EDIT IT
package "Nanaloveyuki/BitLogger/src/record_ops"
import {
"Nanaloveyuki/BitLogger/src/core",
}
// Values
pub fn all_of(Array[(@core.Record) -> Bool]) -> (@core.Record) -> Bool
pub fn any_of(Array[(@core.Record) -> Bool]) -> (@core.Record) -> Bool
pub fn append_fields(Array[@core.Field]) -> (@core.Record) -> @core.Record
pub fn compose_patches(Array[(@core.Record) -> @core.Record]) -> (@core.Record) -> @core.Record
pub fn field_equals(String, String) -> (@core.Record) -> Bool
pub fn has_field(String) -> (@core.Record) -> Bool
pub fn identity_patch() -> (@core.Record) -> @core.Record
pub fn level_at_least(@core.Level) -> (@core.Record) -> Bool
pub fn message_contains(String) -> (@core.Record) -> Bool
pub fn not_((@core.Record) -> Bool) -> (@core.Record) -> Bool
pub fn prefix_message(String) -> (@core.Record) -> @core.Record
pub fn redact_field(String, placeholder? : String) -> (@core.Record) -> @core.Record
pub fn redact_fields(Array[String], placeholder? : String) -> (@core.Record) -> @core.Record
pub fn set_target(String) -> (@core.Record) -> @core.Record
pub fn target_has_prefix(String) -> (@core.Record) -> Bool
pub fn target_is(String) -> (@core.Record) -> Bool
// Errors
// Types and methods
// Type aliases
pub type RecordPatch = (@core.Record) -> @core.Record
pub type RecordPredicate = (@core.Record) -> Bool
// Traits
+8
View File
@@ -0,0 +1,8 @@
import {
"Nanaloveyuki/BitLogger/src/config_model",
"Nanaloveyuki/BitLogger/src/file_runtime",
"Nanaloveyuki/BitLogger/src/file_model",
"Nanaloveyuki/BitLogger/src/formatting",
"Nanaloveyuki/BitLogger/src/sink_graph",
"maria/json_parser",
}
+87
View File
@@ -0,0 +1,87 @@
// Generated using `moon info`, DON'T EDIT IT
package "Nanaloveyuki/BitLogger/src/runtime"
import {
"Nanaloveyuki/BitLogger/src/config_model",
"Nanaloveyuki/BitLogger/src/core",
"Nanaloveyuki/BitLogger/src/file_model",
"Nanaloveyuki/BitLogger/src/file_runtime",
"Nanaloveyuki/BitLogger/src/sink_graph",
"maria/json_parser",
}
// Values
pub fn apply_queue_config(RuntimeSink, @config_model.QueueConfig) -> RuntimeSink
pub fn build_runtime_sink(@config_model.SinkConfig) -> RuntimeSink
pub fn runtime_file_state_to_json(@file_model.RuntimeFileState) -> @json_parser.JsonValue
pub fn stringify_runtime_file_state(@file_model.RuntimeFileState, pretty? : Bool) -> String
// Errors
// Types and methods
pub(all) enum RuntimeSink {
Console(@sink_graph.ConsoleSink)
JsonConsole(@sink_graph.JsonConsoleSink)
TextConsole(@sink_graph.FormattedConsoleSink)
File(@file_runtime.FileSink)
QueuedConsole(@sink_graph.QueuedSink[@sink_graph.ConsoleSink])
QueuedJsonConsole(@sink_graph.QueuedSink[@sink_graph.JsonConsoleSink])
QueuedTextConsole(@sink_graph.QueuedSink[@sink_graph.FormattedConsoleSink])
QueuedFile(@sink_graph.QueuedSink[@file_runtime.FileSink])
}
pub fn RuntimeSink::close(Self) -> Bool
pub fn RuntimeSink::drain(Self, max_items? : Int) -> Int
pub fn RuntimeSink::drain_progress(Self, max_items? : Int) -> RuntimeSinkProgress
pub fn RuntimeSink::dropped_count(Self) -> Int
pub fn RuntimeSink::file_append_mode(Self) -> Bool
pub fn RuntimeSink::file_auto_flush(Self) -> Bool
pub fn RuntimeSink::file_available(Self) -> Bool
pub fn RuntimeSink::file_clear_rotation(Self) -> Bool
pub fn RuntimeSink::file_close(Self) -> Bool
pub fn RuntimeSink::file_default_policy(Self) -> @file_model.FileSinkPolicy
pub fn RuntimeSink::file_default_policy_or_none(Self) -> @file_model.FileSinkPolicy?
pub fn RuntimeSink::file_flush(Self) -> Bool
pub fn RuntimeSink::file_flush_failures(Self) -> Int
pub fn RuntimeSink::file_open_failures(Self) -> Int
pub fn RuntimeSink::file_path(Self) -> String
pub fn RuntimeSink::file_path_or_none(Self) -> String?
pub fn RuntimeSink::file_policy(Self) -> @file_model.FileSinkPolicy
pub fn RuntimeSink::file_policy_matches_default(Self) -> Bool
pub fn RuntimeSink::file_policy_or_none(Self) -> @file_model.FileSinkPolicy?
pub fn RuntimeSink::file_reopen(Self, append? : Bool?) -> Bool
pub fn RuntimeSink::file_reopen_append(Self) -> Bool
pub fn RuntimeSink::file_reopen_truncate(Self) -> Bool
pub fn RuntimeSink::file_reopen_with_current_policy(Self) -> Bool
pub fn RuntimeSink::file_reset_failure_counters(Self) -> Bool
pub fn RuntimeSink::file_reset_policy(Self) -> Bool
pub fn RuntimeSink::file_rotation_config(Self) -> @file_model.FileRotation?
pub fn RuntimeSink::file_rotation_enabled(Self) -> Bool
pub fn RuntimeSink::file_rotation_failures(Self) -> Int
pub fn RuntimeSink::file_runtime_state(Self) -> @file_model.RuntimeFileState?
pub fn RuntimeSink::file_set_append_mode(Self, Bool) -> Bool
pub fn RuntimeSink::file_set_auto_flush(Self, Bool) -> Bool
pub fn RuntimeSink::file_set_policy(Self, @file_model.FileSinkPolicy) -> Bool
pub fn RuntimeSink::file_set_rotation(Self, @file_model.FileRotation?) -> Bool
pub fn RuntimeSink::file_state(Self) -> @file_model.FileSinkState
pub fn RuntimeSink::file_state_or_none(Self) -> @file_model.FileSinkState?
pub fn RuntimeSink::file_write_failures(Self) -> Int
pub fn RuntimeSink::flush(Self) -> Int
pub fn RuntimeSink::flush_progress(Self) -> RuntimeSinkProgress
pub fn RuntimeSink::pending_count(Self) -> Int
pub impl @sink_graph.Sink for RuntimeSink
pub struct RuntimeSinkProgress {
queue_advanced_count : Int
file_flush_step_count : Int
queue_backed : Bool
file_backed : Bool
}
// Type aliases
pub using @file_model {type RuntimeFileState}
// Traits
+746
View File
@@ -0,0 +1,746 @@
///|
type SinkConfig = @config_model.SinkConfig
///|
type SinkKind = @config_model.SinkKind
///|
type QueueConfig = @config_model.QueueConfig
///|
type FileSink = @file_runtime.FileSink
///|
type FileRotation = @file_model.FileRotation
///|
type FileSinkState = @file_model.FileSinkState
///|
type FileSinkPolicy = @file_model.FileSinkPolicy
///|
type ConsoleSink = @sink_graph.ConsoleSink
///|
type JsonConsoleSink = @sink_graph.JsonConsoleSink
///|
type FormattedConsoleSink = @sink_graph.FormattedConsoleSink
///|
type QueuedSink[S] = @sink_graph.QueuedSink[S]
///|
pub(all) enum RuntimeSink {
Console(ConsoleSink)
JsonConsole(JsonConsoleSink)
TextConsole(FormattedConsoleSink)
File(FileSink)
QueuedConsole(QueuedSink[ConsoleSink])
QueuedJsonConsole(QueuedSink[JsonConsoleSink])
QueuedTextConsole(QueuedSink[FormattedConsoleSink])
QueuedFile(QueuedSink[FileSink])
}
///|
pub type RuntimeFileState = @file_model.RuntimeFileState
///|
pub struct RuntimeSinkProgress {
queue_advanced_count : Int
file_flush_step_count : Int
queue_backed : Bool
file_backed : Bool
}
///|
pub fn runtime_file_state_to_json(
state : RuntimeFileState,
) -> @json_parser.JsonValue {
@file_model.runtime_file_state_to_json(state)
}
///|
pub fn stringify_runtime_file_state(
state : RuntimeFileState,
pretty? : Bool = false,
) -> String {
@file_model.stringify_runtime_file_state(state, pretty~)
}
///|
pub impl @sink_graph.Sink for RuntimeSink with fn write(self, rec) {
match self {
Console(sink) => sink.write(rec)
JsonConsole(sink) => sink.write(rec)
TextConsole(sink) => sink.write(rec)
File(sink) => sink.write(rec)
QueuedConsole(sink) => sink.write(rec)
QueuedJsonConsole(sink) => sink.write(rec)
QueuedTextConsole(sink) => sink.write(rec)
QueuedFile(sink) => sink.write(rec)
}
}
///|
fn[S : @sink_graph.Sink] queued_sink_close_internal(
sink : QueuedSink[S],
) -> Bool {
ignore(sink.flush())
sink.pending_count() == 0
}
///|
fn runtime_file_sink_internal(sink : RuntimeSink) -> FileSink? {
match sink {
File(sink) => Some(sink)
QueuedFile(sink) => Some(sink.sink)
_ => None
}
}
///|
fn queued_file_policy_mutation_allowed_internal(
sink : QueuedSink[FileSink],
) -> Bool {
sink.pending_count() == 0
}
///|
fn queued_file_flush_internal(sink : QueuedSink[FileSink]) -> Bool {
let before_write_failures = sink.sink.write_failures()
let before_flush_failures = sink.sink.flush_failures()
let before_rotation_failures = sink.sink.rotation_failures()
ignore(sink.flush())
let flushed = sink.sink.flush()
sink.pending_count() == 0 &&
flushed &&
sink.sink.write_failures() == before_write_failures &&
sink.sink.flush_failures() == before_flush_failures &&
sink.sink.rotation_failures() == before_rotation_failures
}
///|
fn queued_file_close_internal(sink : QueuedSink[FileSink]) -> Bool {
let flushed = queued_file_flush_internal(sink)
let closed = sink.sink.close()
flushed && closed
}
///|
fn runtime_sink_progress_compat_count(progress : RuntimeSinkProgress) -> Int {
progress.queue_advanced_count + progress.file_flush_step_count
}
///|
pub fn RuntimeSink::flush_progress(self : RuntimeSink) -> RuntimeSinkProgress {
match self {
Console(_) =>
{
queue_advanced_count: 0,
file_flush_step_count: 0,
queue_backed: false,
file_backed: false,
}
JsonConsole(_) =>
{
queue_advanced_count: 0,
file_flush_step_count: 0,
queue_backed: false,
file_backed: false,
}
TextConsole(_) =>
{
queue_advanced_count: 0,
file_flush_step_count: 0,
queue_backed: false,
file_backed: false,
}
File(sink) =>
{
queue_advanced_count: 0,
file_flush_step_count: if sink.flush() {
1
} else {
0
},
queue_backed: false,
file_backed: true,
}
QueuedConsole(sink) =>
{
queue_advanced_count: sink.flush(),
file_flush_step_count: 0,
queue_backed: true,
file_backed: false,
}
QueuedJsonConsole(sink) =>
{
queue_advanced_count: sink.flush(),
file_flush_step_count: 0,
queue_backed: true,
file_backed: false,
}
QueuedTextConsole(sink) =>
{
queue_advanced_count: sink.flush(),
file_flush_step_count: 0,
queue_backed: true,
file_backed: false,
}
QueuedFile(sink) =>
{
queue_advanced_count: sink.flush(),
file_flush_step_count: 0,
queue_backed: true,
file_backed: true,
}
}
}
///|
pub fn RuntimeSink::flush(self : RuntimeSink) -> Int {
runtime_sink_progress_compat_count(self.flush_progress())
}
///|
pub fn RuntimeSink::drain_progress(
self : RuntimeSink,
max_items? : Int = -1,
) -> RuntimeSinkProgress {
match self {
Console(_) =>
{
queue_advanced_count: 0,
file_flush_step_count: 0,
queue_backed: false,
file_backed: false,
}
JsonConsole(_) =>
{
queue_advanced_count: 0,
file_flush_step_count: 0,
queue_backed: false,
file_backed: false,
}
TextConsole(_) =>
{
queue_advanced_count: 0,
file_flush_step_count: 0,
queue_backed: false,
file_backed: false,
}
File(sink) =>
{
queue_advanced_count: 0,
file_flush_step_count: if sink.flush() {
1
} else {
0
},
queue_backed: false,
file_backed: true,
}
QueuedConsole(sink) =>
{
queue_advanced_count: sink.drain(max_items~),
file_flush_step_count: 0,
queue_backed: true,
file_backed: false,
}
QueuedJsonConsole(sink) =>
{
queue_advanced_count: sink.drain(max_items~),
file_flush_step_count: 0,
queue_backed: true,
file_backed: false,
}
QueuedTextConsole(sink) =>
{
queue_advanced_count: sink.drain(max_items~),
file_flush_step_count: 0,
queue_backed: true,
file_backed: false,
}
QueuedFile(sink) =>
{
queue_advanced_count: sink.drain(max_items~),
file_flush_step_count: 0,
queue_backed: true,
file_backed: true,
}
}
}
///|
pub fn RuntimeSink::drain(self : RuntimeSink, max_items? : Int = -1) -> Int {
runtime_sink_progress_compat_count(self.drain_progress(max_items~))
}
///|
pub fn RuntimeSink::close(self : RuntimeSink) -> Bool {
match self {
Console(_) => true
JsonConsole(_) => true
TextConsole(_) => true
File(sink) => sink.close()
QueuedConsole(sink) => queued_sink_close_internal(sink)
QueuedJsonConsole(sink) => queued_sink_close_internal(sink)
QueuedTextConsole(sink) => queued_sink_close_internal(sink)
QueuedFile(sink) => queued_file_close_internal(sink)
}
}
///|
pub fn RuntimeSink::pending_count(self : RuntimeSink) -> Int {
match self {
Console(_) => 0
JsonConsole(_) => 0
TextConsole(_) => 0
File(_) => 0
QueuedConsole(sink) => sink.pending_count()
QueuedJsonConsole(sink) => sink.pending_count()
QueuedTextConsole(sink) => sink.pending_count()
QueuedFile(sink) => sink.pending_count()
}
}
///|
pub fn RuntimeSink::dropped_count(self : RuntimeSink) -> Int {
match self {
Console(_) => 0
JsonConsole(_) => 0
TextConsole(_) => 0
File(_) => 0
QueuedConsole(sink) => sink.dropped_count()
QueuedJsonConsole(sink) => sink.dropped_count()
QueuedTextConsole(sink) => sink.dropped_count()
QueuedFile(sink) => sink.dropped_count()
}
}
///|
pub fn RuntimeSink::file_available(self : RuntimeSink) -> Bool {
match self {
File(sink) => sink.is_available()
QueuedFile(sink) => sink.sink.is_available()
_ => false
}
}
///|
pub fn RuntimeSink::file_reopen(
self : RuntimeSink,
append? : Bool? = None,
) -> Bool {
match self {
File(sink) => sink.reopen(append~)
QueuedFile(sink) =>
if queued_file_policy_mutation_allowed_internal(sink) {
sink.sink.reopen(append~)
} else {
false
}
_ => false
}
}
///|
pub fn RuntimeSink::file_reopen_with_current_policy(self : RuntimeSink) -> Bool {
self.file_reopen()
}
///|
pub fn RuntimeSink::file_reopen_append(self : RuntimeSink) -> Bool {
self.file_reopen(append=Some(true))
}
///|
pub fn RuntimeSink::file_reopen_truncate(self : RuntimeSink) -> Bool {
self.file_reopen(append=Some(false))
}
///|
pub fn RuntimeSink::file_append_mode(self : RuntimeSink) -> Bool {
match self {
File(sink) => sink.append_mode()
QueuedFile(sink) => sink.sink.append_mode()
_ => false
}
}
///|
pub fn RuntimeSink::file_set_append_mode(
self : RuntimeSink,
append : Bool,
) -> Bool {
match self {
File(sink) => {
sink.set_append_mode(append)
true
}
QueuedFile(sink) =>
if queued_file_policy_mutation_allowed_internal(sink) {
sink.sink.set_append_mode(append)
true
} else {
false
}
_ => false
}
}
///|
pub fn RuntimeSink::file_path_or_none(self : RuntimeSink) -> String? {
runtime_file_sink_internal(self).map(fn(sink) { sink.path() })
}
///|
pub fn RuntimeSink::file_path(self : RuntimeSink) -> String {
self.file_path_or_none().unwrap_or("")
}
///|
pub fn RuntimeSink::file_auto_flush(self : RuntimeSink) -> Bool {
match self {
File(sink) => sink.auto_flush_enabled()
QueuedFile(sink) => sink.sink.auto_flush_enabled()
_ => false
}
}
///|
pub fn RuntimeSink::file_rotation_enabled(self : RuntimeSink) -> Bool {
match self {
File(sink) => sink.rotation_enabled()
QueuedFile(sink) => sink.sink.rotation_enabled()
_ => false
}
}
///|
pub fn RuntimeSink::file_rotation_config(self : RuntimeSink) -> FileRotation? {
match self {
File(sink) => sink.rotation_config()
QueuedFile(sink) => sink.sink.rotation_config()
_ => None
}
}
///|
pub fn RuntimeSink::file_set_auto_flush(
self : RuntimeSink,
enabled : Bool,
) -> Bool {
match self {
File(sink) => {
sink.set_auto_flush(enabled)
true
}
QueuedFile(sink) =>
if queued_file_policy_mutation_allowed_internal(sink) {
sink.sink.set_auto_flush(enabled)
true
} else {
false
}
_ => false
}
}
///|
pub fn RuntimeSink::file_set_policy(
self : RuntimeSink,
policy : FileSinkPolicy,
) -> Bool {
match self {
File(sink) => {
sink.set_policy(policy)
true
}
QueuedFile(sink) =>
if queued_file_policy_mutation_allowed_internal(sink) {
sink.sink.set_policy(policy)
true
} else {
false
}
_ => false
}
}
///|
pub fn RuntimeSink::file_set_rotation(
self : RuntimeSink,
rotation : FileRotation?,
) -> Bool {
match self {
File(sink) => {
sink.set_rotation(rotation)
true
}
QueuedFile(sink) =>
if queued_file_policy_mutation_allowed_internal(sink) {
sink.sink.set_rotation(rotation)
true
} else {
false
}
_ => false
}
}
///|
pub fn RuntimeSink::file_clear_rotation(self : RuntimeSink) -> Bool {
match self {
File(sink) => {
sink.clear_rotation()
true
}
QueuedFile(sink) =>
if queued_file_policy_mutation_allowed_internal(sink) {
sink.sink.clear_rotation()
true
} else {
false
}
_ => false
}
}
///|
pub fn RuntimeSink::file_flush(self : RuntimeSink) -> Bool {
match self {
File(sink) => sink.flush()
QueuedFile(sink) => queued_file_flush_internal(sink)
_ => false
}
}
///|
pub fn RuntimeSink::file_close(self : RuntimeSink) -> Bool {
match self {
File(sink) => sink.close()
QueuedFile(sink) => queued_file_close_internal(sink)
_ => false
}
}
///|
pub fn RuntimeSink::file_open_failures(self : RuntimeSink) -> Int {
match self {
File(sink) => sink.open_failures()
QueuedFile(sink) => sink.sink.open_failures()
_ => 0
}
}
///|
pub fn RuntimeSink::file_write_failures(self : RuntimeSink) -> Int {
match self {
File(sink) => sink.write_failures()
QueuedFile(sink) => sink.sink.write_failures()
_ => 0
}
}
///|
pub fn RuntimeSink::file_flush_failures(self : RuntimeSink) -> Int {
match self {
File(sink) => sink.flush_failures()
QueuedFile(sink) => sink.sink.flush_failures()
_ => 0
}
}
///|
pub fn RuntimeSink::file_rotation_failures(self : RuntimeSink) -> Int {
match self {
File(sink) => sink.rotation_failures()
QueuedFile(sink) => sink.sink.rotation_failures()
_ => 0
}
}
///|
pub fn RuntimeSink::file_reset_failure_counters(self : RuntimeSink) -> Bool {
match self {
File(sink) => {
sink.reset_failure_counters()
true
}
QueuedFile(sink) => {
sink.sink.reset_failure_counters()
true
}
_ => false
}
}
///|
pub fn RuntimeSink::file_reset_policy(self : RuntimeSink) -> Bool {
match self {
File(sink) => {
sink.reset_policy()
true
}
QueuedFile(sink) =>
if queued_file_policy_mutation_allowed_internal(sink) {
sink.sink.reset_policy()
true
} else {
false
}
_ => false
}
}
///|
pub fn RuntimeSink::file_policy_or_none(self : RuntimeSink) -> FileSinkPolicy? {
runtime_file_sink_internal(self).map(fn(sink) { sink.policy() })
}
///|
pub fn RuntimeSink::file_policy(self : RuntimeSink) -> FileSinkPolicy {
self
.file_policy_or_none()
.unwrap_or(FileSinkPolicy::new(append=false, auto_flush=false, rotation=None))
}
///|
pub fn RuntimeSink::file_default_policy_or_none(
self : RuntimeSink,
) -> FileSinkPolicy? {
runtime_file_sink_internal(self).map(fn(sink) { sink.default_policy() })
}
///|
pub fn RuntimeSink::file_default_policy(self : RuntimeSink) -> FileSinkPolicy {
self
.file_default_policy_or_none()
.unwrap_or(FileSinkPolicy::new(append=false, auto_flush=false, rotation=None))
}
///|
pub fn RuntimeSink::file_policy_matches_default(self : RuntimeSink) -> Bool {
match self {
File(sink) => sink.policy_matches_default()
QueuedFile(sink) => sink.sink.policy_matches_default()
_ => false
}
}
///|
pub fn RuntimeSink::file_state_or_none(self : RuntimeSink) -> FileSinkState? {
runtime_file_sink_internal(self).map(fn(sink) { sink.state() })
}
///|
pub fn RuntimeSink::file_state(self : RuntimeSink) -> FileSinkState {
self
.file_state_or_none()
.unwrap_or(
FileSinkState::new(
"",
available=false,
append=false,
auto_flush=false,
rotation=None,
open_failures=0,
write_failures=0,
flush_failures=0,
rotation_failures=0,
),
)
}
///|
pub fn RuntimeSink::file_runtime_state(self : RuntimeSink) -> RuntimeFileState? {
match self {
File(sink) => Some(RuntimeFileState::new(sink.state()))
QueuedFile(sink) =>
Some(
RuntimeFileState::new(
sink.sink.state(),
queued=true,
pending_count=sink.pending_count(),
dropped_count=sink.dropped_count(),
),
)
_ => None
}
}
///|
pub fn build_runtime_sink(config : SinkConfig) -> RuntimeSink {
match config.kind {
SinkKind::Console => RuntimeSink::Console(@sink_graph.console_sink())
SinkKind::JsonConsole =>
RuntimeSink::JsonConsole(@sink_graph.json_console_sink())
SinkKind::TextConsole =>
RuntimeSink::TextConsole(
@sink_graph.text_console_sink(config.text_formatter.to_formatter()),
)
SinkKind::File =>
RuntimeSink::File(
@file_runtime.file_sink(
config.path,
append=config.append,
auto_flush=config.auto_flush,
rotation=config.rotation,
formatter=fn(rec) {
@formatting.format_text(
rec,
formatter=config.text_formatter.to_formatter(),
)
},
),
)
}
}
///|
pub fn apply_queue_config(
sink : RuntimeSink,
queue : QueueConfig,
) -> RuntimeSink {
match sink {
Console(inner) =>
RuntimeSink::QueuedConsole(
@sink_graph.queued_sink(
inner,
max_pending=queue.max_pending,
overflow=queue.overflow,
),
)
JsonConsole(inner) =>
RuntimeSink::QueuedJsonConsole(
@sink_graph.queued_sink(
inner,
max_pending=queue.max_pending,
overflow=queue.overflow,
),
)
TextConsole(inner) =>
RuntimeSink::QueuedTextConsole(
@sink_graph.queued_sink(
inner,
max_pending=queue.max_pending,
overflow=queue.overflow,
),
)
File(inner) =>
RuntimeSink::QueuedFile(
@sink_graph.queued_sink(
inner,
max_pending=queue.max_pending,
overflow=queue.overflow,
),
)
QueuedConsole(_) => sink
QueuedJsonConsole(_) => sink
QueuedTextConsole(_) => sink
QueuedFile(_) => sink
}
}
+79 -472
View File
@@ -1,585 +1,192 @@
///|
fn runtime_file_sink_internal(sink : RuntimeSink) -> FileSink? {
match sink {
File(sink) => Some(sink)
QueuedFile(sink) => Some(sink.sink)
_ => None
}
pub fn Logger::file_available(self : Logger[RuntimeSink]) -> Bool {
@runtime.RuntimeSink::file_available(self.sink)
}
///|
fn queued_file_policy_mutation_allowed_internal(
sink : QueuedSink[FileSink],
) -> Bool {
sink.pending_count() == 0
}
///|
fn queued_file_flush_internal(sink : QueuedSink[FileSink]) -> Bool {
let before_write_failures = sink.sink.write_failures()
let before_flush_failures = sink.sink.flush_failures()
let before_rotation_failures = sink.sink.rotation_failures()
ignore(sink.flush())
let flushed = sink.sink.flush()
sink.pending_count() == 0 &&
flushed &&
sink.sink.write_failures() == before_write_failures &&
sink.sink.flush_failures() == before_flush_failures &&
sink.sink.rotation_failures() == before_rotation_failures
}
///|
fn queued_file_close_internal(sink : QueuedSink[FileSink]) -> Bool {
let flushed = queued_file_flush_internal(sink)
let closed = sink.sink.close()
flushed && closed
}
///|
pub fn RuntimeSink::file_available(self : RuntimeSink) -> Bool {
match self {
File(sink) => sink.is_available()
QueuedFile(sink) => sink.sink.is_available()
_ => false
}
}
///|
pub fn RuntimeSink::file_reopen(
self : RuntimeSink,
pub fn Logger::file_reopen(
self : Logger[RuntimeSink],
append? : Bool? = None,
) -> Bool {
match self {
File(sink) => sink.reopen(append~)
QueuedFile(sink) =>
if queued_file_policy_mutation_allowed_internal(sink) {
sink.sink.reopen(append~)
} else {
false
}
_ => false
}
@runtime.RuntimeSink::file_reopen(self.sink, append~)
}
///|
pub fn RuntimeSink::file_reopen_with_current_policy(self : RuntimeSink) -> Bool {
self.file_reopen()
pub fn Logger::file_reopen_with_current_policy(
self : Logger[RuntimeSink],
) -> Bool {
@runtime.RuntimeSink::file_reopen_with_current_policy(self.sink)
}
///|
pub fn RuntimeSink::file_reopen_append(self : RuntimeSink) -> Bool {
self.file_reopen(append=Some(true))
pub fn Logger::file_reopen_append(self : Logger[RuntimeSink]) -> Bool {
@runtime.RuntimeSink::file_reopen_append(self.sink)
}
///|
pub fn RuntimeSink::file_reopen_truncate(self : RuntimeSink) -> Bool {
self.file_reopen(append=Some(false))
pub fn Logger::file_reopen_truncate(self : Logger[RuntimeSink]) -> Bool {
@runtime.RuntimeSink::file_reopen_truncate(self.sink)
}
///|
pub fn RuntimeSink::file_append_mode(self : RuntimeSink) -> Bool {
match self {
File(sink) => sink.append_mode()
QueuedFile(sink) => sink.sink.append_mode()
_ => false
}
pub fn Logger::file_append_mode(self : Logger[RuntimeSink]) -> Bool {
@runtime.RuntimeSink::file_append_mode(self.sink)
}
///|
pub fn RuntimeSink::file_set_append_mode(
self : RuntimeSink,
pub fn Logger::file_set_append_mode(
self : Logger[RuntimeSink],
append : Bool,
) -> Bool {
match self {
File(sink) => {
sink.set_append_mode(append)
true
}
QueuedFile(sink) => {
if queued_file_policy_mutation_allowed_internal(sink) {
sink.sink.set_append_mode(append)
true
} else {
false
}
}
_ => false
}
@runtime.RuntimeSink::file_set_append_mode(self.sink, append)
}
///|
pub fn RuntimeSink::file_path_or_none(self : RuntimeSink) -> String? {
runtime_file_sink_internal(self).map(fn(sink) { sink.path() })
pub fn Logger::file_path_or_none(self : Logger[RuntimeSink]) -> String? {
@runtime.RuntimeSink::file_path_or_none(self.sink)
}
///|
pub fn RuntimeSink::file_path(self : RuntimeSink) -> String {
self.file_path_or_none().unwrap_or("")
pub fn Logger::file_path(self : Logger[RuntimeSink]) -> String {
@runtime.RuntimeSink::file_path(self.sink)
}
///|
pub fn RuntimeSink::file_auto_flush(self : RuntimeSink) -> Bool {
match self {
File(sink) => sink.auto_flush_enabled()
QueuedFile(sink) => sink.sink.auto_flush_enabled()
_ => false
}
pub fn Logger::file_auto_flush(self : Logger[RuntimeSink]) -> Bool {
@runtime.RuntimeSink::file_auto_flush(self.sink)
}
///|
pub fn RuntimeSink::file_rotation_enabled(self : RuntimeSink) -> Bool {
match self {
File(sink) => sink.rotation_enabled()
QueuedFile(sink) => sink.sink.rotation_enabled()
_ => false
}
pub fn Logger::file_rotation_enabled(self : Logger[RuntimeSink]) -> Bool {
@runtime.RuntimeSink::file_rotation_enabled(self.sink)
}
///|
pub fn RuntimeSink::file_rotation_config(self : RuntimeSink) -> FileRotation? {
match self {
File(sink) => sink.rotation_config()
QueuedFile(sink) => sink.sink.rotation_config()
_ => None
}
}
///|
pub fn RuntimeSink::file_set_auto_flush(
self : RuntimeSink,
enabled : Bool,
) -> Bool {
match self {
File(sink) => {
sink.set_auto_flush(enabled)
true
}
QueuedFile(sink) => {
if queued_file_policy_mutation_allowed_internal(sink) {
sink.sink.set_auto_flush(enabled)
true
} else {
false
}
}
_ => false
}
}
///|
pub fn RuntimeSink::file_set_policy(
self : RuntimeSink,
policy : FileSinkPolicy,
) -> Bool {
match self {
File(sink) => {
sink.set_policy(policy)
true
}
QueuedFile(sink) => {
if queued_file_policy_mutation_allowed_internal(sink) {
sink.sink.set_policy(policy)
true
} else {
false
}
}
_ => false
}
}
///|
pub fn RuntimeSink::file_set_rotation(
self : RuntimeSink,
rotation : FileRotation?,
) -> Bool {
match self {
File(sink) => {
sink.set_rotation(rotation)
true
}
QueuedFile(sink) => {
if queued_file_policy_mutation_allowed_internal(sink) {
sink.sink.set_rotation(rotation)
true
} else {
false
}
}
_ => false
}
}
///|
pub fn RuntimeSink::file_clear_rotation(self : RuntimeSink) -> Bool {
match self {
File(sink) => {
sink.clear_rotation()
true
}
QueuedFile(sink) => {
if queued_file_policy_mutation_allowed_internal(sink) {
sink.sink.clear_rotation()
true
} else {
false
}
}
_ => false
}
}
///|
pub fn RuntimeSink::file_flush(self : RuntimeSink) -> Bool {
match self {
File(sink) => sink.flush()
QueuedFile(sink) => queued_file_flush_internal(sink)
_ => false
}
}
///|
pub fn RuntimeSink::file_close(self : RuntimeSink) -> Bool {
match self {
File(sink) => sink.close()
QueuedFile(sink) => queued_file_close_internal(sink)
_ => false
}
}
///|
pub fn RuntimeSink::file_open_failures(self : RuntimeSink) -> Int {
match self {
File(sink) => sink.open_failures()
QueuedFile(sink) => sink.sink.open_failures()
_ => 0
}
}
///|
pub fn RuntimeSink::file_write_failures(self : RuntimeSink) -> Int {
match self {
File(sink) => sink.write_failures()
QueuedFile(sink) => sink.sink.write_failures()
_ => 0
}
}
///|
pub fn RuntimeSink::file_flush_failures(self : RuntimeSink) -> Int {
match self {
File(sink) => sink.flush_failures()
QueuedFile(sink) => sink.sink.flush_failures()
_ => 0
}
}
///|
pub fn RuntimeSink::file_rotation_failures(self : RuntimeSink) -> Int {
match self {
File(sink) => sink.rotation_failures()
QueuedFile(sink) => sink.sink.rotation_failures()
_ => 0
}
}
///|
pub fn RuntimeSink::file_reset_failure_counters(self : RuntimeSink) -> Bool {
match self {
File(sink) => {
sink.reset_failure_counters()
true
}
QueuedFile(sink) => {
sink.sink.reset_failure_counters()
true
}
_ => false
}
}
///|
pub fn RuntimeSink::file_reset_policy(self : RuntimeSink) -> Bool {
match self {
File(sink) => {
sink.reset_policy()
true
}
QueuedFile(sink) => {
if queued_file_policy_mutation_allowed_internal(sink) {
sink.sink.reset_policy()
true
} else {
false
}
}
_ => false
}
}
///|
pub fn RuntimeSink::file_policy_or_none(self : RuntimeSink) -> FileSinkPolicy? {
runtime_file_sink_internal(self).map(fn(sink) { sink.policy() })
}
///|
pub fn RuntimeSink::file_policy(self : RuntimeSink) -> FileSinkPolicy {
self.file_policy_or_none().unwrap_or(
FileSinkPolicy::new(append=false, auto_flush=false, rotation=None),
)
}
///|
pub fn RuntimeSink::file_default_policy_or_none(
self : RuntimeSink,
) -> FileSinkPolicy? {
runtime_file_sink_internal(self).map(fn(sink) { sink.default_policy() })
}
///|
pub fn RuntimeSink::file_default_policy(self : RuntimeSink) -> FileSinkPolicy {
self.file_default_policy_or_none().unwrap_or(
FileSinkPolicy::new(append=false, auto_flush=false, rotation=None),
)
}
///|
pub fn RuntimeSink::file_policy_matches_default(self : RuntimeSink) -> Bool {
match self {
File(sink) => sink.policy_matches_default()
QueuedFile(sink) => sink.sink.policy_matches_default()
_ => false
}
}
///|
pub fn RuntimeSink::file_state_or_none(self : RuntimeSink) -> FileSinkState? {
runtime_file_sink_internal(self).map(fn(sink) { sink.state() })
}
///|
pub fn RuntimeSink::file_state(self : RuntimeSink) -> FileSinkState {
self.file_state_or_none().unwrap_or(
FileSinkState::new(
"",
available=false,
append=false,
auto_flush=false,
rotation=None,
open_failures=0,
write_failures=0,
flush_failures=0,
rotation_failures=0,
),
)
}
///|
pub fn RuntimeSink::file_runtime_state(self : RuntimeSink) -> RuntimeFileState? {
match self {
File(sink) => Some(RuntimeFileState::new(sink.state()))
QueuedFile(sink) =>
Some(
RuntimeFileState::new(
sink.sink.state(),
queued=true,
pending_count=sink.pending_count(),
dropped_count=sink.dropped_count(),
),
)
_ => None
}
}
///|
pub fn ConfiguredLogger::file_available(self : ConfiguredLogger) -> Bool {
self.sink.file_available()
}
///|
pub fn ConfiguredLogger::file_reopen(
self : ConfiguredLogger,
append? : Bool? = None,
) -> Bool {
self.sink.file_reopen(append~)
}
///|
pub fn ConfiguredLogger::file_reopen_with_current_policy(
self : ConfiguredLogger,
) -> Bool {
self.sink.file_reopen_with_current_policy()
}
///|
pub fn ConfiguredLogger::file_reopen_append(self : ConfiguredLogger) -> Bool {
self.sink.file_reopen_append()
}
///|
pub fn ConfiguredLogger::file_reopen_truncate(self : ConfiguredLogger) -> Bool {
self.sink.file_reopen_truncate()
}
///|
pub fn ConfiguredLogger::file_append_mode(self : ConfiguredLogger) -> Bool {
self.sink.file_append_mode()
}
///|
pub fn ConfiguredLogger::file_set_append_mode(
self : ConfiguredLogger,
append : Bool,
) -> Bool {
self.sink.file_set_append_mode(append)
}
///|
pub fn ConfiguredLogger::file_path_or_none(self : ConfiguredLogger) -> String? {
self.sink.file_path_or_none()
}
///|
pub fn ConfiguredLogger::file_path(self : ConfiguredLogger) -> String {
self.sink.file_path()
}
///|
pub fn ConfiguredLogger::file_auto_flush(self : ConfiguredLogger) -> Bool {
self.sink.file_auto_flush()
}
///|
pub fn ConfiguredLogger::file_rotation_enabled(self : ConfiguredLogger) -> Bool {
self.sink.file_rotation_enabled()
}
///|
pub fn ConfiguredLogger::file_rotation_config(
self : ConfiguredLogger,
pub fn Logger::file_rotation_config(
self : Logger[RuntimeSink],
) -> FileRotation? {
self.sink.file_rotation_config()
@runtime.RuntimeSink::file_rotation_config(self.sink)
}
///|
pub fn ConfiguredLogger::file_set_auto_flush(
self : ConfiguredLogger,
pub fn Logger::file_set_auto_flush(
self : Logger[RuntimeSink],
enabled : Bool,
) -> Bool {
self.sink.file_set_auto_flush(enabled)
@runtime.RuntimeSink::file_set_auto_flush(self.sink, enabled)
}
///|
pub fn ConfiguredLogger::file_set_policy(
self : ConfiguredLogger,
pub fn Logger::file_set_policy(
self : Logger[RuntimeSink],
policy : FileSinkPolicy,
) -> Bool {
self.sink.file_set_policy(policy)
@runtime.RuntimeSink::file_set_policy(self.sink, policy)
}
///|
pub fn ConfiguredLogger::file_set_rotation(
self : ConfiguredLogger,
pub fn Logger::file_set_rotation(
self : Logger[RuntimeSink],
rotation : FileRotation?,
) -> Bool {
self.sink.file_set_rotation(rotation)
@runtime.RuntimeSink::file_set_rotation(self.sink, rotation)
}
///|
pub fn ConfiguredLogger::file_clear_rotation(self : ConfiguredLogger) -> Bool {
self.sink.file_clear_rotation()
pub fn Logger::file_clear_rotation(self : Logger[RuntimeSink]) -> Bool {
@runtime.RuntimeSink::file_clear_rotation(self.sink)
}
///|
pub fn ConfiguredLogger::file_flush(self : ConfiguredLogger) -> Bool {
self.sink.file_flush()
pub fn Logger::file_flush(self : Logger[RuntimeSink]) -> Bool {
@runtime.RuntimeSink::file_flush(self.sink)
}
///|
pub fn ConfiguredLogger::file_close(self : ConfiguredLogger) -> Bool {
self.sink.file_close()
pub fn Logger::file_close(self : Logger[RuntimeSink]) -> Bool {
@runtime.RuntimeSink::file_close(self.sink)
}
///|
pub fn ConfiguredLogger::file_open_failures(self : ConfiguredLogger) -> Int {
self.sink.file_open_failures()
pub fn Logger::file_open_failures(self : Logger[RuntimeSink]) -> Int {
@runtime.RuntimeSink::file_open_failures(self.sink)
}
///|
pub fn ConfiguredLogger::file_write_failures(self : ConfiguredLogger) -> Int {
self.sink.file_write_failures()
pub fn Logger::file_write_failures(self : Logger[RuntimeSink]) -> Int {
@runtime.RuntimeSink::file_write_failures(self.sink)
}
///|
pub fn ConfiguredLogger::file_flush_failures(self : ConfiguredLogger) -> Int {
self.sink.file_flush_failures()
pub fn Logger::file_flush_failures(self : Logger[RuntimeSink]) -> Int {
@runtime.RuntimeSink::file_flush_failures(self.sink)
}
///|
pub fn ConfiguredLogger::file_rotation_failures(self : ConfiguredLogger) -> Int {
self.sink.file_rotation_failures()
pub fn Logger::file_rotation_failures(self : Logger[RuntimeSink]) -> Int {
@runtime.RuntimeSink::file_rotation_failures(self.sink)
}
///|
pub fn ConfiguredLogger::file_reset_failure_counters(
self : ConfiguredLogger,
pub fn Logger::file_reset_failure_counters(
self : Logger[RuntimeSink],
) -> Bool {
self.sink.file_reset_failure_counters()
@runtime.RuntimeSink::file_reset_failure_counters(self.sink)
}
///|
pub fn ConfiguredLogger::file_reset_policy(self : ConfiguredLogger) -> Bool {
self.sink.file_reset_policy()
pub fn Logger::file_reset_policy(self : Logger[RuntimeSink]) -> Bool {
@runtime.RuntimeSink::file_reset_policy(self.sink)
}
///|
pub fn ConfiguredLogger::file_policy_or_none(
self : ConfiguredLogger,
pub fn Logger::file_policy_or_none(
self : Logger[RuntimeSink],
) -> FileSinkPolicy? {
self.sink.file_policy_or_none()
@runtime.RuntimeSink::file_policy_or_none(self.sink)
}
///|
pub fn ConfiguredLogger::file_policy(self : ConfiguredLogger) -> FileSinkPolicy {
self.sink.file_policy()
pub fn Logger::file_policy(self : Logger[RuntimeSink]) -> FileSinkPolicy {
@runtime.RuntimeSink::file_policy(self.sink)
}
///|
pub fn ConfiguredLogger::file_default_policy_or_none(
self : ConfiguredLogger,
pub fn Logger::file_default_policy_or_none(
self : Logger[RuntimeSink],
) -> FileSinkPolicy? {
self.sink.file_default_policy_or_none()
@runtime.RuntimeSink::file_default_policy_or_none(self.sink)
}
///|
pub fn ConfiguredLogger::file_default_policy(
self : ConfiguredLogger,
pub fn Logger::file_default_policy(
self : Logger[RuntimeSink],
) -> FileSinkPolicy {
self.sink.file_default_policy()
@runtime.RuntimeSink::file_default_policy(self.sink)
}
///|
pub fn ConfiguredLogger::file_policy_matches_default(
self : ConfiguredLogger,
pub fn Logger::file_policy_matches_default(
self : Logger[RuntimeSink],
) -> Bool {
self.sink.file_policy_matches_default()
@runtime.RuntimeSink::file_policy_matches_default(self.sink)
}
///|
pub fn ConfiguredLogger::file_state_or_none(
self : ConfiguredLogger,
pub fn Logger::file_state_or_none(
self : Logger[RuntimeSink],
) -> FileSinkState? {
self.sink.file_state_or_none()
@runtime.RuntimeSink::file_state_or_none(self.sink)
}
///|
pub fn ConfiguredLogger::file_state(self : ConfiguredLogger) -> FileSinkState {
self.sink.file_state()
pub fn Logger::file_state(self : Logger[RuntimeSink]) -> FileSinkState {
@runtime.RuntimeSink::file_state(self.sink)
}
///|
pub fn ConfiguredLogger::file_runtime_state(
self : ConfiguredLogger,
pub fn Logger::file_runtime_state(
self : Logger[RuntimeSink],
) -> RuntimeFileState? {
self.sink.file_runtime_state()
@runtime.RuntimeSink::file_runtime_state(self.sink)
}
+26 -322
View File
@@ -1,59 +1,17 @@
///|
pub(all) enum RuntimeSink {
Console(ConsoleSink)
JsonConsole(JsonConsoleSink)
TextConsole(FormattedConsoleSink)
File(FileSink)
QueuedConsole(QueuedSink[ConsoleSink])
QueuedJsonConsole(QueuedSink[JsonConsoleSink])
QueuedTextConsole(QueuedSink[FormattedConsoleSink])
QueuedFile(QueuedSink[FileSink])
}
pub type RuntimeSink = @runtime.RuntimeSink
///|
pub type RuntimeFileState = @utils.RuntimeFileState
pub type RuntimeFileState = @file_model.RuntimeFileState
///|
pub struct RuntimeSinkProgress {
queue_advanced_count : Int
file_flush_step_count : Int
queue_backed : Bool
file_backed : Bool
}
///|
pub fn file_sink_policy_to_json(
policy : FileSinkPolicy,
) -> @json_parser.JsonValue {
@utils.file_sink_policy_to_json(policy)
}
///|
pub fn stringify_file_sink_policy(
policy : FileSinkPolicy,
pretty? : Bool = false,
) -> String {
@utils.stringify_file_sink_policy(policy, pretty~)
}
///|
pub fn file_sink_state_to_json(state : FileSinkState) -> @json_parser.JsonValue {
@utils.file_sink_state_to_json(state)
}
///|
pub fn stringify_file_sink_state(
state : FileSinkState,
pretty? : Bool = false,
) -> String {
@utils.stringify_file_sink_state(state, pretty~)
}
pub type RuntimeSinkProgress = @runtime.RuntimeSinkProgress
///|
pub fn runtime_file_state_to_json(
state : RuntimeFileState,
) -> @json_parser.JsonValue {
@utils.runtime_file_state_to_json(state)
@file_model.runtime_file_state_to_json(state)
}
///|
@@ -61,315 +19,61 @@ pub fn stringify_runtime_file_state(
state : RuntimeFileState,
pretty? : Bool = false,
) -> String {
@utils.stringify_runtime_file_state(state, pretty~)
}
///|
pub impl Sink for RuntimeSink with fn write(self, rec) {
match self {
Console(sink) => sink.write(rec)
JsonConsole(sink) => sink.write(rec)
TextConsole(sink) => sink.write(rec)
File(sink) => sink.write(rec)
QueuedConsole(sink) => sink.write(rec)
QueuedJsonConsole(sink) => sink.write(rec)
QueuedTextConsole(sink) => sink.write(rec)
QueuedFile(sink) => sink.write(rec)
}
}
///|
fn[S : Sink] queued_sink_close_internal(sink : QueuedSink[S]) -> Bool {
ignore(sink.flush())
sink.pending_count() == 0
}
///|
fn runtime_sink_progress_compat_count(progress : RuntimeSinkProgress) -> Int {
progress.queue_advanced_count + progress.file_flush_step_count
}
///|
pub fn RuntimeSink::flush_progress(self : RuntimeSink) -> RuntimeSinkProgress {
match self {
Console(_) => {
queue_advanced_count: 0,
file_flush_step_count: 0,
queue_backed: false,
file_backed: false,
}
JsonConsole(_) => {
queue_advanced_count: 0,
file_flush_step_count: 0,
queue_backed: false,
file_backed: false,
}
TextConsole(_) => {
queue_advanced_count: 0,
file_flush_step_count: 0,
queue_backed: false,
file_backed: false,
}
File(sink) => {
queue_advanced_count: 0,
file_flush_step_count: if sink.flush() { 1 } else { 0 },
queue_backed: false,
file_backed: true,
}
QueuedConsole(sink) => {
queue_advanced_count: sink.flush(),
file_flush_step_count: 0,
queue_backed: true,
file_backed: false,
}
QueuedJsonConsole(sink) => {
queue_advanced_count: sink.flush(),
file_flush_step_count: 0,
queue_backed: true,
file_backed: false,
}
QueuedTextConsole(sink) => {
queue_advanced_count: sink.flush(),
file_flush_step_count: 0,
queue_backed: true,
file_backed: false,
}
QueuedFile(sink) => {
queue_advanced_count: sink.flush(),
file_flush_step_count: 0,
queue_backed: true,
file_backed: true,
}
}
}
///|
pub fn RuntimeSink::flush(self : RuntimeSink) -> Int {
runtime_sink_progress_compat_count(self.flush_progress())
}
///|
pub fn RuntimeSink::drain_progress(
self : RuntimeSink,
max_items? : Int = -1,
) -> RuntimeSinkProgress {
match self {
Console(_) => {
queue_advanced_count: 0,
file_flush_step_count: 0,
queue_backed: false,
file_backed: false,
}
JsonConsole(_) => {
queue_advanced_count: 0,
file_flush_step_count: 0,
queue_backed: false,
file_backed: false,
}
TextConsole(_) => {
queue_advanced_count: 0,
file_flush_step_count: 0,
queue_backed: false,
file_backed: false,
}
File(sink) => {
queue_advanced_count: 0,
file_flush_step_count: if sink.flush() { 1 } else { 0 },
queue_backed: false,
file_backed: true,
}
QueuedConsole(sink) => {
queue_advanced_count: sink.drain(max_items~),
file_flush_step_count: 0,
queue_backed: true,
file_backed: false,
}
QueuedJsonConsole(sink) => {
queue_advanced_count: sink.drain(max_items~),
file_flush_step_count: 0,
queue_backed: true,
file_backed: false,
}
QueuedTextConsole(sink) => {
queue_advanced_count: sink.drain(max_items~),
file_flush_step_count: 0,
queue_backed: true,
file_backed: false,
}
QueuedFile(sink) => {
queue_advanced_count: sink.drain(max_items~),
file_flush_step_count: 0,
queue_backed: true,
file_backed: true,
}
}
}
///|
pub fn RuntimeSink::drain(self : RuntimeSink, max_items? : Int = -1) -> Int {
runtime_sink_progress_compat_count(self.drain_progress(max_items~))
}
///|
pub fn RuntimeSink::close(self : RuntimeSink) -> Bool {
match self {
Console(_) => true
JsonConsole(_) => true
TextConsole(_) => true
File(sink) => sink.close()
QueuedConsole(sink) => queued_sink_close_internal(sink)
QueuedJsonConsole(sink) => queued_sink_close_internal(sink)
QueuedTextConsole(sink) => queued_sink_close_internal(sink)
QueuedFile(sink) => queued_file_close_internal(sink)
}
}
///|
pub fn RuntimeSink::pending_count(self : RuntimeSink) -> Int {
match self {
Console(_) => 0
JsonConsole(_) => 0
TextConsole(_) => 0
File(_) => 0
QueuedConsole(sink) => sink.pending_count()
QueuedJsonConsole(sink) => sink.pending_count()
QueuedTextConsole(sink) => sink.pending_count()
QueuedFile(sink) => sink.pending_count()
}
}
///|
pub fn RuntimeSink::dropped_count(self : RuntimeSink) -> Int {
match self {
Console(_) => 0
JsonConsole(_) => 0
TextConsole(_) => 0
File(_) => 0
QueuedConsole(sink) => sink.dropped_count()
QueuedJsonConsole(sink) => sink.dropped_count()
QueuedTextConsole(sink) => sink.dropped_count()
QueuedFile(sink) => sink.dropped_count()
}
@file_model.stringify_runtime_file_state(state, pretty~)
}
///|
pub type ConfiguredLogger = Logger[RuntimeSink]
///|
pub fn ConfiguredLogger::flush_progress(
self : ConfiguredLogger,
pub fn Logger::flush_progress(
self : Logger[RuntimeSink],
) -> RuntimeSinkProgress {
self.sink.flush_progress()
@runtime.RuntimeSink::flush_progress(self.sink)
}
///|
pub fn ConfiguredLogger::flush(self : ConfiguredLogger) -> Int {
self.sink.flush()
pub fn Logger::flush(self : Logger[RuntimeSink]) -> Int {
@runtime.RuntimeSink::flush(self.sink)
}
///|
pub fn ConfiguredLogger::drain_progress(
self : ConfiguredLogger,
pub fn Logger::drain_progress(
self : Logger[RuntimeSink],
max_items? : Int = -1,
) -> RuntimeSinkProgress {
self.sink.drain_progress(max_items~)
@runtime.RuntimeSink::drain_progress(self.sink, max_items~)
}
///|
pub fn ConfiguredLogger::drain(
self : ConfiguredLogger,
pub fn Logger::drain(
self : Logger[RuntimeSink],
max_items? : Int = -1,
) -> Int {
self.sink.drain(max_items~)
@runtime.RuntimeSink::drain(self.sink, max_items~)
}
///|
pub fn ConfiguredLogger::close(self : ConfiguredLogger) -> Bool {
self.sink.close()
pub fn Logger::close(self : Logger[RuntimeSink]) -> Bool {
@runtime.RuntimeSink::close(self.sink)
}
///|
pub fn ConfiguredLogger::pending_count(self : ConfiguredLogger) -> Int {
self.sink.pending_count()
pub fn Logger::pending_count(self : Logger[RuntimeSink]) -> Int {
@runtime.RuntimeSink::pending_count(self.sink)
}
///|
pub fn ConfiguredLogger::dropped_count(self : ConfiguredLogger) -> Int {
self.sink.dropped_count()
pub fn Logger::dropped_count(self : Logger[RuntimeSink]) -> Int {
@runtime.RuntimeSink::dropped_count(self.sink)
}
///|
fn build_runtime_sink(config : SinkConfig) -> RuntimeSink {
match config.kind {
SinkKind::Console => RuntimeSink::Console(console_sink())
SinkKind::JsonConsole => RuntimeSink::JsonConsole(json_console_sink())
SinkKind::TextConsole =>
RuntimeSink::TextConsole(
text_console_sink(config.text_formatter.to_formatter()),
)
SinkKind::File =>
RuntimeSink::File(
file_sink(
config.path,
append=config.append,
auto_flush=config.auto_flush,
rotation=config.rotation,
formatter=fn(rec) {
format_text(rec, formatter=config.text_formatter.to_formatter())
},
),
)
}
}
///|
fn apply_queue_config(sink : RuntimeSink, queue : QueueConfig) -> RuntimeSink {
match sink {
Console(inner) =>
RuntimeSink::QueuedConsole(
queued_sink(
inner,
max_pending=queue.max_pending,
overflow=queue.overflow,
),
)
JsonConsole(inner) =>
RuntimeSink::QueuedJsonConsole(
queued_sink(
inner,
max_pending=queue.max_pending,
overflow=queue.overflow,
),
)
TextConsole(inner) =>
RuntimeSink::QueuedTextConsole(
queued_sink(
inner,
max_pending=queue.max_pending,
overflow=queue.overflow,
),
)
File(inner) =>
RuntimeSink::QueuedFile(
queued_sink(
inner,
max_pending=queue.max_pending,
overflow=queue.overflow,
),
)
QueuedConsole(_) => sink
QueuedJsonConsole(_) => sink
QueuedTextConsole(_) => sink
QueuedFile(_) => sink
}
}
///|
pub fn build_logger(config : LoggerConfig) -> ConfiguredLogger {
let sink = build_runtime_sink(config.sink)
pub fn build_logger(config : LoggerConfig) -> Logger[RuntimeSink] {
let sink = @runtime.build_runtime_sink(config.sink)
let actual_sink = match config.queue {
None => sink
Some(queue) => apply_queue_config(sink, queue)
Some(queue) => @runtime.apply_queue_config(sink, queue)
}
Logger::new(actual_sink, min_level=config.min_level, target=config.target).with_timestamp(
enabled=config.timestamp,
@@ -379,6 +83,6 @@ pub fn build_logger(config : LoggerConfig) -> ConfiguredLogger {
///|
pub fn parse_and_build_logger(
input : String,
) -> ConfiguredLogger raise ConfigError {
) -> Logger[RuntimeSink] raise ConfigError {
build_logger(parse_logger_config_text(input))
}
+8
View File
@@ -0,0 +1,8 @@
import {
"Nanaloveyuki/BitLogger/src/core",
"Nanaloveyuki/BitLogger/src/formatting",
"Nanaloveyuki/BitLogger/src/queue_model",
"Nanaloveyuki/BitLogger/src/record_ops",
"moonbitlang/core/queue",
"moonbitlang/core/ref",
}
+132
View File
@@ -0,0 +1,132 @@
// Generated using `moon info`, DON'T EDIT IT
package "Nanaloveyuki/BitLogger/src/sink_graph"
import {
"Nanaloveyuki/BitLogger/src/core",
"Nanaloveyuki/BitLogger/src/formatting",
"Nanaloveyuki/BitLogger/src/queue_model",
"moonbitlang/core/queue",
"moonbitlang/core/ref",
}
// Values
pub fn[S] buffered_sink(S, flush_limit? : Int) -> BufferedSink[S]
pub fn callback_sink((@core.Record) -> Unit) -> CallbackSink
pub fn console_sink() -> ConsoleSink
pub fn[S] context_sink(S, Array[@core.Field]) -> ContextSink[S]
pub fn[A, B] fanout_sink(A, B) -> FanoutSink[A, B]
pub fn[S] filter_sink(S, (@core.Record) -> Bool) -> FilterSink[S]
pub fn formatted_callback_sink((@core.Record) -> String, (String) -> Unit) -> FormattedCallbackSink
pub fn formatted_console_sink((@core.Record) -> String) -> FormattedConsoleSink
pub fn json_console_sink() -> JsonConsoleSink
pub fn[S] patch_sink(S, (@core.Record) -> @core.Record) -> PatchSink[S]
pub fn[S] queued_sink(S, max_pending? : Int, overflow? : @queue_model.QueueOverflowPolicy) -> QueuedSink[S]
pub fn[A, B] split_by_level(A, B, min_level? : @core.Level) -> SplitSink[A, B]
pub fn[A, B] split_sink(A, B, (@core.Record) -> Bool) -> SplitSink[A, B]
pub fn text_callback_sink(@formatting.TextFormatter, (String) -> Unit) -> FormattedCallbackSink
pub fn text_console_sink(@formatting.TextFormatter) -> FormattedConsoleSink
// Errors
// Types and methods
pub struct BufferedSink[S] {
sink : S
buffer : @ref.Ref[Array[@core.Record]]
flush_limit : Int
}
pub fn[S : Sink] BufferedSink::flush(Self[S]) -> Unit
pub fn[S] BufferedSink::pending_count(Self[S]) -> Int
pub impl[S : Sink] Sink for BufferedSink[S]
pub struct CallbackSink {
callback : (@core.Record) -> Unit
}
pub impl Sink for CallbackSink
pub struct ConsoleSink {
_dummy : Unit
}
pub impl Sink for ConsoleSink
pub struct ContextSink[S] {
sink : S
context_fields : Array[@core.Field]
}
pub impl[S : Sink] Sink for ContextSink[S]
pub struct FanoutSink[A, B] {
left : A
right : B
}
pub impl[A : Sink, B : Sink] Sink for FanoutSink[A, B]
pub struct FilterSink[S] {
sink : S
predicate : (@core.Record) -> Bool
}
pub impl[S : Sink] Sink for FilterSink[S]
pub struct FormattedCallbackSink {
formatter : (@core.Record) -> String
callback : (String) -> Unit
}
pub impl Sink for FormattedCallbackSink
pub struct FormattedConsoleSink {
formatter : (@core.Record) -> String
}
pub impl Sink for FormattedConsoleSink
pub struct JsonConsoleSink {
_dummy : Unit
}
pub impl Sink for JsonConsoleSink
pub struct PatchSink[S] {
sink : S
patch : (@core.Record) -> @core.Record
}
pub impl[S : Sink] Sink for PatchSink[S]
pub struct QueuedSink[S] {
sink : S
queue : @queue.Queue[@core.Record]
max_pending : Int
overflow : @queue_model.QueueOverflowPolicy
dropped_count : @ref.Ref[Int]
}
pub fn[S : Sink] QueuedSink::drain(Self[S], max_items? : Int) -> Int
pub fn[S] QueuedSink::dropped_count(Self[S]) -> Int
pub fn[S : Sink] QueuedSink::flush(Self[S]) -> Int
pub fn[S] QueuedSink::pending_count(Self[S]) -> Int
pub impl[S] Sink for QueuedSink[S]
pub struct SplitSink[A, B] {
left : A
right : B
predicate : (@core.Record) -> Bool
}
pub impl[A : Sink, B : Sink] Sink for SplitSink[A, B]
// Type aliases
pub using @queue_model {type QueueOverflowPolicy}
// Traits
pub(open) trait Sink {
fn write(Self, @core.Record) -> Unit
}
+352
View File
@@ -0,0 +1,352 @@
///|
type Record = @core.Record
///|
type Field = @core.Field
///|
type Level = @core.Level
///|
type RecordFormatter = @formatting.RecordFormatter
///|
type TextFormatter = @formatting.TextFormatter
///|
type RecordPatch = @record_ops.RecordPatch
///|
pub(open) trait Sink {
fn write(Self, Record) -> Unit
}
///|
pub struct ConsoleSink {
_dummy : Unit
}
///|
pub fn console_sink() -> ConsoleSink {
{ _dummy: () }
}
///|
pub impl Sink for ConsoleSink with fn write(self, rec) {
ignore(self)
println(@formatting.format_text(rec))
}
///|
pub struct ContextSink[S] {
sink : S
context_fields : Array[Field]
}
///|
pub fn[S] context_sink(
sink : S,
context_fields : Array[Field],
) -> ContextSink[S] {
{ sink, context_fields }
}
///|
pub impl[S : Sink] Sink for ContextSink[S] with fn write(self, rec) {
let merged = if self.context_fields.length() == 0 {
rec.fields
} else if rec.fields.length() == 0 {
self.context_fields
} else {
self.context_fields + rec.fields
}
self.sink.write(rec.with_fields(merged))
}
///|
pub struct JsonConsoleSink {
_dummy : Unit
}
///|
pub fn json_console_sink() -> JsonConsoleSink {
{ _dummy: () }
}
///|
pub impl Sink for JsonConsoleSink with fn write(self, rec) {
ignore(self)
println(@formatting.format_json(rec))
}
///|
pub struct FormattedConsoleSink {
formatter : RecordFormatter
}
///|
pub fn formatted_console_sink(
formatter : RecordFormatter,
) -> FormattedConsoleSink {
{ formatter, }
}
///|
pub fn text_console_sink(formatter : TextFormatter) -> FormattedConsoleSink {
formatted_console_sink(fn(rec) { @formatting.format_text(rec, formatter~) })
}
///|
pub impl Sink for FormattedConsoleSink with fn write(self, rec) {
println((self.formatter)(rec))
}
///|
pub struct FormattedCallbackSink {
formatter : RecordFormatter
callback : (String) -> Unit
}
///|
pub fn formatted_callback_sink(
formatter : RecordFormatter,
callback : (String) -> Unit,
) -> FormattedCallbackSink {
{ formatter, callback }
}
///|
pub fn text_callback_sink(
formatter : TextFormatter,
callback : (String) -> Unit,
) -> FormattedCallbackSink {
formatted_callback_sink(
fn(rec) { @formatting.format_text(rec, formatter~) },
callback,
)
}
///|
pub impl Sink for FormattedCallbackSink with fn write(self, rec) {
(self.callback)((self.formatter)(rec))
}
///|
pub struct FanoutSink[A, B] {
left : A
right : B
}
///|
pub fn[A, B] fanout_sink(left : A, right : B) -> FanoutSink[A, B] {
{ left, right }
}
///|
pub impl[A : Sink, B : Sink] Sink for FanoutSink[A, B] with fn write(self, rec) {
self.left.write(rec)
self.right.write(rec.copy())
}
///|
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 fn write(self, rec) {
if (self.predicate)(rec) {
self.left.write(rec)
} else {
self.right.write(rec)
}
}
///|
pub struct CallbackSink {
callback : (Record) -> Unit
}
///|
pub fn callback_sink(callback : (Record) -> Unit) -> CallbackSink {
{ callback, }
}
///|
pub impl Sink for CallbackSink with fn write(self, rec) {
(self.callback)(rec)
}
///|
pub struct BufferedSink[S] {
sink : S
buffer : Ref[Array[Record]]
flush_limit : Int
}
///|
pub fn[S] buffered_sink(sink : S, flush_limit? : Int = 1) -> BufferedSink[S] {
let actual_limit = if flush_limit <= 0 { 1 } else { flush_limit }
{ sink, buffer: Ref([]), flush_limit: actual_limit }
}
///|
pub fn[S] BufferedSink::pending_count(self : BufferedSink[S]) -> Int {
self.buffer.val.length()
}
///|
pub fn[S : Sink] BufferedSink::flush(self : BufferedSink[S]) -> Unit {
if self.buffer.val.length() == 0 {
()
} else {
let pending = self.buffer.val
self.buffer.val = []
for rec in pending {
self.sink.write(rec)
}
}
}
///|
pub impl[S : Sink] Sink for BufferedSink[S] with fn write(self, rec) {
self.buffer.val.push(rec)
if self.buffer.val.length() >= self.flush_limit {
self.flush()
}
}
///|
pub type QueueOverflowPolicy = @queue_model.QueueOverflowPolicy
///|
pub struct QueuedSink[S] {
sink : S
queue : @queue.Queue[Record]
max_pending : Int
overflow : QueueOverflowPolicy
dropped_count : Ref[Int]
}
///|
pub fn[S] queued_sink(
sink : S,
max_pending? : Int = 0,
overflow? : QueueOverflowPolicy = QueueOverflowPolicy::DropNewest,
) -> QueuedSink[S] {
{
sink,
queue: @queue.Queue([]),
max_pending,
overflow,
dropped_count: Ref(0),
}
}
///|
pub fn[S] QueuedSink::pending_count(self : QueuedSink[S]) -> Int {
self.queue.length()
}
///|
pub fn[S] QueuedSink::dropped_count(self : QueuedSink[S]) -> Int {
self.dropped_count.val
}
///|
pub fn[S : Sink] QueuedSink::drain(
self : QueuedSink[S],
max_items? : Int = -1,
) -> Int {
if max_items == 0 {
return 0
}
let limit = if max_items < 0 { self.pending_count() } else { max_items }
for drained = 0; drained < limit; {
match self.queue.pop() {
None => break drained
Some(rec) => {
self.sink.write(rec)
continue drained + 1
}
}
} nobreak {
limit
}
}
///|
pub fn[S : Sink] QueuedSink::flush(self : QueuedSink[S]) -> Int {
self.drain()
}
///|
pub impl[S] Sink for QueuedSink[S] with fn write(self, rec) {
let full = self.max_pending > 0 && self.pending_count() >= self.max_pending
if !full {
self.queue.push(rec)
} else {
self.dropped_count.val += 1
match self.overflow {
QueueOverflowPolicy::DropNewest => ()
QueueOverflowPolicy::DropOldest => {
ignore(self.queue.pop())
self.queue.push(rec)
}
}
}
}
///|
pub struct FilterSink[S] {
sink : S
predicate : (Record) -> Bool
}
///|
pub fn[S] filter_sink(sink : S, predicate : (Record) -> Bool) -> FilterSink[S] {
{ sink, predicate }
}
///|
pub impl[S : Sink] Sink for FilterSink[S] with fn write(self, rec) {
if (self.predicate)(rec) {
self.sink.write(rec)
}
}
///|
pub struct PatchSink[S] {
sink : S
patch : RecordPatch
}
///|
pub fn[S] patch_sink(sink : S, patch : RecordPatch) -> PatchSink[S] {
{ sink, patch }
}
///|
pub impl[S : Sink] Sink for PatchSink[S] with fn write(self, rec) {
self.sink.write((self.patch)(rec))
}
+35 -219
View File
@@ -1,92 +1,57 @@
///|
pub trait Sink {
fn write(Self, Record) -> Unit
}
pub using @sink_graph {trait Sink}
///|
pub struct ConsoleSink {
_dummy : Unit
}
pub type ConsoleSink = @sink_graph.ConsoleSink
///|
pub fn console_sink() -> ConsoleSink {
{ _dummy: () }
@sink_graph.console_sink()
}
///|
pub impl Sink for ConsoleSink with fn write(self, rec) {
ignore(self)
println(format_text(rec))
pub type ContextSink[S] = @sink_graph.ContextSink[S]
///|
pub fn[S] context_sink(
sink : S,
context_fields : Array[Field],
) -> ContextSink[S] {
@sink_graph.context_sink(sink, context_fields)
}
///|
pub struct ContextSink[S] {
sink : S
context_fields : Array[Field]
}
///|
pub impl[S : Sink] Sink for ContextSink[S] with fn write(self, rec) {
let merged = if self.context_fields.length() == 0 {
rec.fields
} else if rec.fields.length() == 0 {
self.context_fields
} else {
self.context_fields + rec.fields
}
self.sink.write(rec.with_fields(merged))
}
///|
pub struct JsonConsoleSink {
_dummy : Unit
}
pub type JsonConsoleSink = @sink_graph.JsonConsoleSink
///|
pub fn json_console_sink() -> JsonConsoleSink {
{ _dummy: () }
@sink_graph.json_console_sink()
}
///|
pub impl Sink for JsonConsoleSink with fn write(self, rec) {
ignore(self)
println(format_json(rec))
}
///|
pub struct FormattedConsoleSink {
formatter : RecordFormatter
}
pub type FormattedConsoleSink = @sink_graph.FormattedConsoleSink
///|
pub fn formatted_console_sink(
formatter : RecordFormatter,
) -> FormattedConsoleSink {
{ formatter, }
@sink_graph.formatted_console_sink(formatter)
}
///|
pub fn text_console_sink(formatter : TextFormatter) -> FormattedConsoleSink {
formatted_console_sink(fn(rec) { format_text(rec, formatter~) })
@sink_graph.text_console_sink(formatter)
}
///|
pub impl Sink for FormattedConsoleSink with fn write(self, rec) {
println((self.formatter)(rec))
}
///|
pub struct FormattedCallbackSink {
formatter : RecordFormatter
callback : (String) -> Unit
}
pub type FormattedCallbackSink = @sink_graph.FormattedCallbackSink
///|
pub fn formatted_callback_sink(
formatter : RecordFormatter,
callback : (String) -> Unit,
) -> FormattedCallbackSink {
{ formatter, callback }
@sink_graph.formatted_callback_sink(formatter, callback)
}
///|
@@ -94,37 +59,19 @@ pub fn text_callback_sink(
formatter : TextFormatter,
callback : (String) -> Unit,
) -> FormattedCallbackSink {
formatted_callback_sink(fn(rec) { format_text(rec, formatter~) }, callback)
@sink_graph.text_callback_sink(formatter, callback)
}
///|
pub impl Sink for FormattedCallbackSink with fn write(self, rec) {
(self.callback)((self.formatter)(rec))
}
///|
pub struct FanoutSink[A, B] {
left : A
right : B
}
pub type FanoutSink[A, B] = @sink_graph.FanoutSink[A, B]
///|
pub fn[A, B] fanout_sink(left : A, right : B) -> FanoutSink[A, B] {
{ left, right }
@sink_graph.fanout_sink(left, right)
}
///|
pub impl[A : Sink, B : Sink] Sink for FanoutSink[A, B] with fn write(self, rec) {
self.left.write(rec)
self.right.write(rec.copy())
}
///|
pub struct SplitSink[A, B] {
left : A
right : B
predicate : (Record) -> Bool
}
pub type SplitSink[A, B] = @sink_graph.SplitSink[A, B]
///|
pub fn[A, B] split_sink(
@@ -132,7 +79,7 @@ pub fn[A, B] split_sink(
right : B,
predicate : (Record) -> Bool,
) -> SplitSink[A, B] {
{ left, right, predicate }
@sink_graph.split_sink(left, right, predicate)
}
///|
@@ -141,83 +88,30 @@ pub fn[A, B] split_by_level(
right : B,
min_level? : Level = Level::Warn,
) -> SplitSink[A, B] {
split_sink(left, right, fn(rec) { rec.level.enabled(min_level) })
@sink_graph.split_by_level(left, right, min_level~)
}
///|
pub impl[A : Sink, B : Sink] Sink for SplitSink[A, B] with fn write(self, rec) {
if (self.predicate)(rec) {
self.left.write(rec)
} else {
self.right.write(rec)
}
}
///|
pub struct CallbackSink {
callback : (Record) -> Unit
}
pub type CallbackSink = @sink_graph.CallbackSink
///|
pub fn callback_sink(callback : (Record) -> Unit) -> CallbackSink {
{ callback, }
@sink_graph.callback_sink(callback)
}
///|
pub impl Sink for CallbackSink with fn write(self, rec) {
(self.callback)(rec)
}
///|
pub struct BufferedSink[S] {
sink : S
buffer : Ref[Array[Record]]
flush_limit : Int
}
pub type BufferedSink[S] = @sink_graph.BufferedSink[S]
///|
pub fn[S] buffered_sink(sink : S, flush_limit? : Int = 1) -> BufferedSink[S] {
let actual_limit = if flush_limit <= 0 { 1 } else { flush_limit }
{ sink, buffer: Ref([]), flush_limit: actual_limit }
@sink_graph.buffered_sink(sink, flush_limit~)
}
///|
pub fn[S] BufferedSink::pending_count(self : BufferedSink[S]) -> Int {
self.buffer.val.length()
}
pub type QueueOverflowPolicy = @queue_model.QueueOverflowPolicy
///|
pub fn[S : Sink] BufferedSink::flush(self : BufferedSink[S]) -> Unit {
if self.buffer.val.length() == 0 {
()
} else {
let pending = self.buffer.val
self.buffer.val = []
for rec in pending {
self.sink.write(rec)
}
}
}
///|
pub impl[S : Sink] Sink for BufferedSink[S] with fn write(self, rec) {
self.buffer.val.push(rec)
if self.buffer.val.length() >= self.flush_limit {
self.flush()
}
}
///|
pub type QueueOverflowPolicy = @utils.QueueOverflowPolicy
///|
pub struct QueuedSink[S] {
sink : S
queue : @queue.Queue[Record]
max_pending : Int
overflow : QueueOverflowPolicy
dropped_count : Ref[Int]
}
pub type QueuedSink[S] = @sink_graph.QueuedSink[S]
///|
pub fn[S] queued_sink(
@@ -225,99 +119,21 @@ pub fn[S] queued_sink(
max_pending? : Int = 0,
overflow? : QueueOverflowPolicy = QueueOverflowPolicy::DropNewest,
) -> QueuedSink[S] {
{
sink,
queue: @queue.Queue([]),
max_pending,
overflow,
dropped_count: Ref(0),
}
@sink_graph.queued_sink(sink, max_pending~, overflow~)
}
///|
pub fn[S] QueuedSink::pending_count(self : QueuedSink[S]) -> Int {
self.queue.length()
}
///|
pub fn[S] QueuedSink::dropped_count(self : QueuedSink[S]) -> Int {
self.dropped_count.val
}
///|
pub fn[S : Sink] QueuedSink::drain(
self : QueuedSink[S],
max_items? : Int = -1,
) -> Int {
if max_items == 0 {
return 0
}
let limit = if max_items < 0 { self.pending_count() } else { max_items }
for drained = 0; drained < limit; {
match self.queue.pop() {
None => break drained
Some(rec) => {
self.sink.write(rec)
continue drained + 1
}
}
} nobreak {
limit
}
}
///|
pub fn[S : Sink] QueuedSink::flush(self : QueuedSink[S]) -> Int {
self.drain()
}
///|
pub impl[S] Sink for QueuedSink[S] with fn write(self, rec) {
let full = self.max_pending > 0 && self.pending_count() >= self.max_pending
if !full {
self.queue.push(rec)
} else {
self.dropped_count.val += 1
match self.overflow {
QueueOverflowPolicy::DropNewest => ()
QueueOverflowPolicy::DropOldest => {
ignore(self.queue.pop())
self.queue.push(rec)
}
}
}
}
///|
pub struct FilterSink[S] {
sink : S
predicate : (Record) -> Bool
}
pub type FilterSink[S] = @sink_graph.FilterSink[S]
///|
pub fn[S] filter_sink(sink : S, predicate : (Record) -> Bool) -> FilterSink[S] {
{ sink, predicate }
@sink_graph.filter_sink(sink, predicate)
}
///|
pub impl[S : Sink] Sink for FilterSink[S] with fn write(self, rec) {
if (self.predicate)(rec) {
self.sink.write(rec)
}
}
///|
pub struct PatchSink[S] {
sink : S
patch : RecordPatch
}
pub type PatchSink[S] = @sink_graph.PatchSink[S]
///|
pub fn[S] patch_sink(sink : S, patch : RecordPatch) -> PatchSink[S] {
{ sink, patch }
}
///|
pub impl[S : Sink] Sink for PatchSink[S] with fn write(self, rec) {
self.sink.write((self.patch)(rec))
@sink_graph.patch_sink(sink, patch)
}
+36 -353
View File
@@ -1,32 +1,18 @@
///|
pub struct FileSink {
path : String
append : Ref[Bool]
default_append : Bool
handle : Ref[FileHandle?]
formatter : RecordFormatter
auto_flush : Ref[Bool]
default_auto_flush : Bool
rotation : Ref[FileRotation?]
default_rotation : FileRotation?
open_failures : Ref[Int]
write_failures : Ref[Int]
flush_failures : Ref[Int]
rotation_failures : Ref[Int]
}
pub type FileSink = @file_runtime.FileSink
///|
pub type FileRotation = @utils.FileRotation
pub type FileRotation = @file_model.FileRotation
///|
pub type FileSinkState = @utils.FileSinkState
pub type FileSinkState = @file_model.FileSinkState
///|
pub type FileSinkPolicy = @utils.FileSinkPolicy
pub type FileSinkPolicy = @file_model.FileSinkPolicy
///|
pub fn file_rotation(max_bytes : Int, max_backups? : Int = 1) -> FileRotation {
@utils.file_rotation(max_bytes, max_backups~)
@file_model.file_rotation(max_bytes, max_backups~)
}
///|
@@ -34,12 +20,40 @@ pub fn file_rotation_i64(
max_bytes : Int64,
max_backups? : Int = 1,
) -> FileRotation {
@utils.file_rotation_i64(max_bytes, max_backups~)
@file_model.file_rotation_i64(max_bytes, max_backups~)
}
///|
pub fn native_files_supported() -> Bool {
native_files_supported_internal()
@file_runtime.native_files_supported()
}
///|
pub fn file_sink_policy_to_json(
policy : FileSinkPolicy,
) -> @json_parser.JsonValue {
@file_model.file_sink_policy_to_json(policy)
}
///|
pub fn stringify_file_sink_policy(
policy : FileSinkPolicy,
pretty? : Bool = false,
) -> String {
@file_model.stringify_file_sink_policy(policy, pretty~)
}
///|
pub fn file_sink_state_to_json(state : FileSinkState) -> @json_parser.JsonValue {
@file_model.file_sink_state_to_json(state)
}
///|
pub fn stringify_file_sink_state(
state : FileSinkState,
pretty? : Bool = false,
) -> String {
@file_model.stringify_file_sink_state(state, pretty~)
}
///|
@@ -50,336 +64,5 @@ pub fn file_sink(
rotation? : FileRotation? = None,
formatter? : RecordFormatter = fn(rec) { format_text(rec) },
) -> FileSink {
let handle = open_file_handle_internal(path, append)
{
path,
append: Ref(append),
default_append: append,
handle: Ref(handle),
formatter,
auto_flush: Ref(auto_flush),
default_auto_flush: auto_flush,
rotation: Ref(rotation),
default_rotation: rotation,
open_failures: Ref(if handle is Some(_) { 0 } else { 1 }),
write_failures: Ref(0),
flush_failures: Ref(0),
rotation_failures: Ref(0),
}
}
///|
pub fn FileSink::is_available(self : FileSink) -> Bool {
self.handle.val is Some(_)
}
///|
pub fn FileSink::flush(self : FileSink) -> Bool {
match self.handle.val {
None => false
Some(handle) => {
let ok = flush_file_handle_internal(handle)
if !ok {
self.flush_failures.val += 1
}
ok
}
}
}
///|
pub fn FileSink::append_mode(self : FileSink) -> Bool {
self.append.val
}
///|
pub fn FileSink::set_append_mode(self : FileSink, append : Bool) -> Unit {
self.append.val = append
}
///|
pub fn FileSink::path(self : FileSink) -> String {
self.path
}
///|
pub fn FileSink::auto_flush_enabled(self : FileSink) -> Bool {
self.auto_flush.val
}
///|
pub fn FileSink::rotation_enabled(self : FileSink) -> Bool {
self.rotation.val is Some(_)
}
///|
pub fn FileSink::rotation_config(self : FileSink) -> FileRotation? {
self.rotation.val
}
///|
pub fn FileSink::set_auto_flush(self : FileSink, enabled : Bool) -> Unit {
self.auto_flush.val = enabled
}
///|
pub fn FileSink::set_policy(self : FileSink, policy : FileSinkPolicy) -> Unit {
self.append.val = policy.append
self.auto_flush.val = policy.auto_flush
self.rotation.val = policy.rotation
}
///|
pub fn FileSink::set_rotation(
self : FileSink,
rotation : FileRotation?,
) -> Unit {
self.rotation.val = rotation
}
///|
pub fn FileSink::clear_rotation(self : FileSink) -> Unit {
self.rotation.val = None
}
///|
pub fn FileSink::close(self : FileSink) -> Bool {
match self.handle.val {
None => false
Some(handle) => {
let ok = close_file_handle_internal(handle)
self.handle.val = None
ok
}
}
}
///|
pub fn FileSink::rotation_failures(self : FileSink) -> Int {
self.rotation_failures.val
}
///|
pub fn FileSink::open_failures(self : FileSink) -> Int {
self.open_failures.val
}
///|
pub fn FileSink::write_failures(self : FileSink) -> Int {
self.write_failures.val
}
///|
pub fn FileSink::flush_failures(self : FileSink) -> Int {
self.flush_failures.val
}
///|
pub fn FileSink::reset_failure_counters(self : FileSink) -> Unit {
self.open_failures.val = 0
self.write_failures.val = 0
self.flush_failures.val = 0
self.rotation_failures.val = 0
}
///|
pub fn FileSink::reset_policy(self : FileSink) -> Unit {
self.append.val = self.default_append
self.auto_flush.val = self.default_auto_flush
self.rotation.val = self.default_rotation
}
///|
pub fn FileSink::policy(self : FileSink) -> FileSinkPolicy {
FileSinkPolicy::new(
append=self.append.val,
auto_flush=self.auto_flush.val,
rotation=self.rotation.val,
)
}
///|
pub fn FileSink::default_policy(self : FileSink) -> FileSinkPolicy {
FileSinkPolicy::new(
append=self.default_append,
auto_flush=self.default_auto_flush,
rotation=self.default_rotation,
)
}
///|
pub fn FileSink::policy_matches_default(self : FileSink) -> Bool {
let current = self.policy()
let default = self.default_policy()
current.append == default.append &&
current.auto_flush == default.auto_flush &&
policy_rotation_equals_internal(current.rotation, default.rotation)
}
///|
fn policy_rotation_equals_internal(
left : FileRotation?,
right : FileRotation?,
) -> Bool {
match (left, right) {
(None, None) => true
(Some(a), Some(b)) =>
a.max_bytes == b.max_bytes &&
a.max_backups == b.max_backups &&
a.native_wide_max_bytes == b.native_wide_max_bytes
_ => false
}
}
///|
fn rotation_max_bytes_internal(rotation : FileRotation) -> Int64 {
match rotation.native_wide_max_bytes {
Some(value) => value
None => rotation.max_bytes.to_int64()
}
}
///|
pub fn FileSink::state(self : FileSink) -> FileSinkState {
FileSinkState::new(
self.path,
available=self.is_available(),
append=self.append.val,
auto_flush=self.auto_flush.val,
rotation=self.rotation.val,
open_failures=self.open_failures.val,
write_failures=self.write_failures.val,
flush_failures=self.flush_failures.val,
rotation_failures=self.rotation_failures.val,
)
}
///|
pub fn FileSink::reopen(self : FileSink, append? : Bool? = None) -> Bool {
let append_mode = append.unwrap_or(self.append.val)
self.append.val = append_mode
match self.handle.val {
None => ()
Some(handle) => {
ignore(close_file_handle_internal(handle))
self.handle.val = None
}
}
let reopened = open_file_handle_internal(self.path, append_mode)
self.handle.val = reopened
if reopened is Some(_) {
true
} else {
self.open_failures.val += 1
false
}
}
///|
pub fn FileSink::reopen_with_current_policy(self : FileSink) -> Bool {
self.reopen()
}
///|
pub fn FileSink::reopen_append(self : FileSink) -> Bool {
self.reopen(append=Some(true))
}
///|
pub fn FileSink::reopen_truncate(self : FileSink) -> Bool {
self.reopen(append=Some(false))
}
///|
fn rotated_file_path(path : String, index : Int) -> String {
"\{path}.\{index}"
}
///|
fn rotate_file_sink_internal(sink : FileSink, rotation : FileRotation) -> Bool {
let closed = match sink.handle.val {
None => true
Some(handle) => {
let ok = close_file_handle_internal(handle)
sink.handle.val = None
ok
}
}
if !closed {
return false
}
if rotation.max_backups > 0 {
ignore(
remove_file_internal(rotated_file_path(sink.path, rotation.max_backups)),
)
for index = rotation.max_backups - 1; index >= 1; {
let from_path = rotated_file_path(sink.path, index)
let to_path = rotated_file_path(sink.path, index + 1)
ignore(rename_file_internal(from_path, to_path))
continue index - 1
}
ignore(rename_file_internal(sink.path, rotated_file_path(sink.path, 1)))
} else {
ignore(remove_file_internal(sink.path))
}
sink.handle.val = open_file_handle_internal(sink.path, false)
sink.handle.val is Some(_)
}
///|
fn rotate_if_needed_internal(sink : FileSink, next_line_bytes : Int) -> Bool {
match sink.rotation.val {
None => true
Some(rotation) =>
match sink.handle.val {
None => false
Some(handle) => {
let size = file_size_i64_internal(handle)
let next_line = next_line_bytes.to_int64()
if size + next_line <= rotation_max_bytes_internal(rotation) {
true
} else {
let rotated = rotate_file_sink_internal(sink, rotation)
if !rotated {
sink.rotation_failures.val += 1
}
rotated
}
}
}
}
}
///|
pub impl Sink for FileSink with fn write(self, rec) {
match self.handle.val {
None => self.write_failures.val += 1
Some(_) => {
let line = "\{(self.formatter)(rec)}\n"
let can_write = rotate_if_needed_internal(
self,
string_byte_length_internal(line),
)
if can_write {
match self.handle.val {
None => self.write_failures.val += 1
Some(active) => {
let wrote = write_file_handle_internal(active, line)
if wrote {
if self.auto_flush.val {
let flushed = flush_file_handle_internal(active)
if !flushed {
self.flush_failures.val += 1
}
}
} else {
self.write_failures.val += 1
}
}
}
} else {
self.write_failures.val += 1
}
}
}
@file_runtime.file_sink(path, append~, auto_flush~, rotation~, formatter~)
}
+11
View File
@@ -93,6 +93,17 @@ pub fn open_file_handle_internal(path : String, append : Bool) -> FileHandle? {
}
}
///|
pub fn file_exists_internal(path : String) -> Bool {
let raw = file_open_ffi(string_to_c_bytes(path), string_to_c_bytes("rb"))
if file_is_null_ffi(raw) {
false
} else {
ignore(file_close_ffi(raw))
true
}
}
///|
pub fn write_file_handle_internal(
handle : FileHandle,
+10 -38
View File
@@ -1,75 +1,47 @@
///|
pub type RecordPredicate = (@core.Record) -> Bool
pub type RecordPredicate = @record_ops.RecordPredicate
///|
pub fn level_at_least(min_level : @core.Level) -> RecordPredicate {
fn(rec) { rec.level.priority() >= min_level.priority() }
@record_ops.level_at_least(min_level)
}
///|
pub fn target_is(target : String) -> RecordPredicate {
fn(rec) { rec.target == target }
@record_ops.target_is(target)
}
///|
pub fn target_has_prefix(prefix : String) -> RecordPredicate {
fn(rec) { rec.target.has_prefix(prefix) }
@record_ops.target_has_prefix(prefix)
}
///|
pub fn message_contains(fragment : String) -> RecordPredicate {
fn(rec) { rec.message.contains(fragment) }
@record_ops.message_contains(fragment)
}
///|
pub fn has_field(key : String) -> RecordPredicate {
fn(rec) {
for field in rec.fields {
if field.key == key {
return true
}
}
false
}
@record_ops.has_field(key)
}
///|
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
}
@record_ops.field_equals(key, value)
}
///|
pub fn not_(predicate : RecordPredicate) -> RecordPredicate {
fn(rec) { !predicate(rec) }
@record_ops.not_(predicate)
}
///|
pub fn all_of(predicates : Array[RecordPredicate]) -> RecordPredicate {
fn(rec) {
for predicate in predicates {
if !predicate(rec) {
return false
}
}
true
}
@record_ops.all_of(predicates)
}
///|
pub fn any_of(predicates : Array[RecordPredicate]) -> RecordPredicate {
fn(rec) {
for predicate in predicates {
if predicate(rec) {
return true
}
}
false
}
@record_ops.any_of(predicates)
}
+33 -1062
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -1,6 +1,7 @@
import {
"Nanaloveyuki/BitLogger/src/core",
"maria/json_parser",
"Nanaloveyuki/BitLogger/src/formatting",
"Nanaloveyuki/BitLogger/src/record_ops",
"moonbitlang/core/env",
"moonbitlang/core/json",
"moonbitlang/core/ref",
+8 -42
View File
@@ -1,47 +1,29 @@
///|
pub type RecordPatch = (@core.Record) -> @core.Record
pub type RecordPatch = @record_ops.RecordPatch
///|
pub fn identity_patch() -> RecordPatch {
fn(rec) { rec }
@record_ops.identity_patch()
}
///|
pub fn set_target(target : String) -> RecordPatch {
fn(rec) { rec.with_target(target) }
@record_ops.set_target(target)
}
///|
pub fn prefix_message(prefix : String) -> RecordPatch {
fn(rec) { rec.with_message("\{prefix}\{rec.message}") }
@record_ops.prefix_message(prefix)
}
///|
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)
}
}
@record_ops.append_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
}
}),
)
}
@record_ops.redact_field(key, placeholder~)
}
///|
@@ -49,26 +31,10 @@ 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
}
}),
)
}
@record_ops.redact_fields(keys, placeholder~)
}
///|
pub fn compose_patches(patches : Array[RecordPatch]) -> RecordPatch {
fn(rec) {
let mut current = rec
for patch in patches {
current = patch(current)
}
current
}
@record_ops.compose_patches(patches)
}
-104
View File
@@ -1,105 +1 @@
///|
pub struct FileRotation {
max_bytes : Int
max_backups : Int
native_wide_max_bytes : Int64?
}
///|
pub struct FileSinkState {
path : String
available : Bool
append : Bool
auto_flush : Bool
rotation : FileRotation?
open_failures : Int
write_failures : Int
flush_failures : Int
rotation_failures : Int
}
///|
pub struct FileSinkPolicy {
append : Bool
auto_flush : Bool
rotation : FileRotation?
}
///|
pub fn FileSinkPolicy::new(
append? : Bool = true,
auto_flush? : Bool = true,
rotation? : FileRotation? = None,
) -> FileSinkPolicy {
{ append, auto_flush, rotation }
}
///|
pub fn FileSinkState::new(
path : String,
available? : Bool = false,
append? : Bool = true,
auto_flush? : Bool = true,
rotation? : FileRotation? = None,
open_failures? : Int = 0,
write_failures? : Int = 0,
flush_failures? : Int = 0,
rotation_failures? : Int = 0,
) -> FileSinkState {
{
path,
available,
append,
auto_flush,
rotation,
open_failures,
write_failures,
flush_failures,
rotation_failures,
}
}
///|
pub fn file_rotation(max_bytes : Int, max_backups? : Int = 1) -> FileRotation {
{
max_bytes: if max_bytes <= 0 {
1
} else {
max_bytes
},
max_backups: if max_backups <= 0 {
1
} else {
max_backups
},
native_wide_max_bytes: None,
}
}
///|
pub fn file_rotation_i64(
max_bytes : Int64,
max_backups? : Int = 1,
) -> FileRotation {
let normalized = if max_bytes <= 0L { 1L } else { max_bytes }
let clamped_max_bytes = if normalized > 2147483647L {
2147483647
} else {
normalized.to_int()
}
{
max_bytes: clamped_max_bytes,
max_backups: if max_backups <= 0 {
1
} else {
max_backups
},
native_wide_max_bytes: Some(normalized),
}
}
///|
pub(all) enum QueueOverflowPolicy {
DropNewest
DropOldest
}