provisioning-core/nulib/primitives/io/logging.nu

103 lines
3.9 KiB
Text
Raw Permalink Normal View History

# Logging — env-var-only debug flags; no config reads (primitives contract)
# Parse PROVISIONING_DEBUG as a numeric level.
# Accepts: 0/1/2/3 (int or string), "true" → 1, "false"/"" → 0, bool.
# Level semantics: 0=off 1=operational 2=verbose 3=raw/trace
export def debug-level []: nothing -> int {
let raw = ($env.PROVISIONING_DEBUG? | default 0)
let t = ($raw | describe)
if ($t | str starts-with "bool") {
return (if $raw { 1 } else { 0 })
}
if ($t | str starts-with "int") {
return (if $raw > 0 { $raw } else { 0 })
}
# string path
let s = ($raw | into string | str trim)
match $s {
"true" => 1
"false" => 0
"" => 0
"0" => 0
_ => (try { $s | into int } catch { 0 })
}
}
# True when PROVISIONING_DEBUG >= 1 (any debug output enabled).
export def is-debug-enabled []: nothing -> bool { (debug-level) >= 1 }
# True when PROVISIONING_DEBUG >= level. Use to gate verbose/raw output.
export def is-debug-level [level: int]: nothing -> bool { (debug-level) >= $level }
# Check if debug-check mode is enabled (local task/service simulation).
export def is-debug-check-enabled [] {
$env.PROVISIONING_DEBUG_CHECK? | default false | into bool
}
# Check if metadata mode is enabled (detailed error spans).
export def is-metadata-enabled [] {
$env.PROVISIONING_METADATA? | default false | into bool
}
export def set-debug-enabled [value: bool] { $env.PROVISIONING_DEBUG = (if $value { 1 } else { 0 }) }
export def set-metadata-enabled [value: bool] { $env.PROVISIONING_METADATA = $value }
export def log-info [message: string, context?: string] {
let ts = (date now | format date '%Y-%m-%d %H:%M:%S')
let ctx = if ($context | is-not-empty) { $" [($context)]" } else { "" }
print $" ($ts)($ctx) ($message)"
}
export def log-success [message: string, context?: string] {
let ts = (date now | format date '%Y-%m-%d %H:%M:%S')
let ctx = if ($context | is-not-empty) { $" [($context)]" } else { "" }
print $"✅ ($ts)($ctx) ($message)"
}
export def log-warning [message: string, context?: string] {
let ts = (date now | format date '%Y-%m-%d %H:%M:%S')
let ctx = if ($context | is-not-empty) { $" [($context)]" } else { "" }
print $"⚠️ ($ts)($ctx) ($message)"
}
export def log-error [message: string, context?: string, details?: string] {
let ts = (date now | format date '%Y-%m-%d %H:%M:%S')
let ctx = if ($context | is-not-empty) { $" [($context)]" } else { "" }
let det = if ($details | is-not-empty) { $"\n Details: ($details)" } else { "" }
print $"🛑 ($ts)($ctx) ($message)($det)"
}
export def log-debug [
message: string
context?: string
--level: int = 1 # minimum debug level required to emit this line
] {
if (is-debug-level $level) {
let ts = (date now | format date '%Y-%m-%d %H:%M:%S')
let ctx = if ($context | is-not-empty) { $" [($context)]" } else { "" }
print $"🐛 ($ts)($ctx) ($message)"
}
}
export def log-step [step: string, total_steps: int, current_step: int, context?: string] {
let ctx = if ($context | is-not-empty) { $" [($context)]" } else { "" }
print $"🔄 ($current_step)/($total_steps)($ctx) ($step)"
}
export def log-progress [message: string, percent: int, context?: string] {
let ctx = if ($context | is-not-empty) { $" [($context)]" } else { "" }
print $"📊 ($ctx) ($message) ($percent)%"
}
export def log-section [title: string, context?: string] {
let ctx = if ($context | is-not-empty) { $" [($context)]" } else { "" }
print ""
print $"📋 ($ctx) ($title)"
print "─────────────────────────────────────────────────────────────"
}
export def log-subsection [title: string, context?: string] {
let ctx = if ($context | is-not-empty) { $" [($context)]" } else { "" }
print $" 📌 ($ctx) ($title)"
}