-
-
Notifications
You must be signed in to change notification settings - Fork 0
Writing Events
Every write names a level and a message template with its arguments: logger.information(template, arguments), and likewise verbose, debug, warning, error, and fatal. write takes the level as an argument; writeFailure attaches a Failure; tryWrite answers an audit sink's failure; emit writes a complete event.
| Hole | Meaning |
|---|---|
{Name} |
a named property; structures render to text |
{@Name} |
destructure: keep a structure's members |
{$Name} |
stringify: render any value to text |
{0}, {1}
|
positional holes, bound by number |
{Name,8}, {Name,-8}
|
right or left alignment to a width |
{Name:0.00}, {When:HH:mm}
|
a format for numbers, dates, and durations |
{{ and }}
|
literal braces |
Named holes bind left to right; a name used twice takes the later value. Arguments beyond the holes are kept as __0, __1, and so on; missing ones are reported to the self-log.
PuduLangLog.Value builds what a property holds: text, int, float, decimal, bool, nothing, moment, duration, bytes, list, structure (with a tag), object (without one), dictionary, and keyed. A type implementing Value.Capturable is captured with Value.of.
module Ex02Events
import Std.Io as Io
import Std.Option as Option
import PuduLangLog.Configuration as Configuration
import PuduLangLog.Event as Event
import PuduLangLog.Failure as Failure
import PuduLangLog as Log
import PuduLangLog.Logger as Logger
import PuduLangLog.Sinks.Memory as Memory
import PuduLangLog.Value as Value
type Point = { x: Int, y: Int }
impl Value.Capturable for Point {
fn capture(self: &Self) -> Log.Value { Value.structure("Point", [("X", Value.int(self.x)), ("Y", Value.int(self.y))]) }
}
export fn main() -> Int {
let memory = Memory.create()
let logger = Configuration.create().minimumLevel(Log.Debug).writeTo(Memory.sink(&memory)).createLogger()
logger.information("User \{User\} logged in from \{Address\}", [Value.text("ada"), Value.text("10.0.0.7")])
logger.information("\{1\} was added to \{0\}", [Value.text("cart"), Value.text("tea")])
logger.information("Moved from \{From\} to \{@To\}", [Value.of(Point{x: 1, y: 2}), Value.of(Point{x: 3, y: 4})])
logger.information("Stored \{$Items\}", [Value.list([Value.int(1), Value.int(2)])])
logger.information("[\{Left,-6\}] [\{Right,6\}] \{Ratio:0.00\} \{Share:P1\}", [Value.text("tea"), Value.text("cup"), Value.float(0.4567), Value.float(0.4567)])
logger.information("Escaped \{\{braces\}\} stay literal", [])
logger.writeFailure(Log.Error, Failure.causedBy(&Failure.of("PaymentError", "card declined"), Failure.of("Timeout", "gateway")), "Payment for \{OrderId\} failed", [Value.int(7)])
for event in Memory.events(&memory) {
let _line = Io.writeLine(Event.message(&event))
}
let failed = Memory.events(&memory)[6]
let _failure = Io.writeLine(Failure.describe(&Option.unwrapOr(failed.failure, Failure.of("", ""))))
let (template, properties) = logger.bindTemplate("\{A\} and \{B\}", [Value.int(1), Value.int(2)])
let _bound = Io.writeLine(template.text + " binds " + show(properties.length()) + " properties")
let _enabled = Io.writeLine("verbose enabled: " + show(logger.isEnabled(Log.Verbose)))
Logger.close(&logger)
0
}
Check it and run it:
pudu check src/Ex02Events.pudu
pudu run src/Ex02Events.puduOutput:
User "ada" logged in from "10.0.0.7"
"tea" was added to "cart"
Moved from "Point { X: 1, Y: 2 }" to Point { X: 3, Y: 4 }
Stored "[1, 2]"
["tea" ] [ "cup"] 0.46 45.7 %
Escaped {braces} stay literal
Payment for 7 failed
PaymentError: card declined
---> Timeout: gateway
{A} and {B} binds 2 properties
verbose enabled: false
Text renders quoted in messages; structures render as Tag { Name: value }. bindTemplate and bindProperty capture exactly as a write would, for code that builds events itself, and isEnabled tells whether a level would be written.