Add logging module

This commit is contained in:
Alexander Heldt
2025-11-29 15:06:15 +01:00
parent 0877344a94
commit 610967b7be
4 changed files with 68 additions and 0 deletions

View File

@@ -0,0 +1,7 @@
import gleam/erlang/process.{type Subject}
pub type Control {
Write(String)
Exit(reply_to: Subject(Nil))
}

View File

@@ -0,0 +1,58 @@
import gleam/erlang/process.{type Subject}
import gleam/otp/actor
import gleam/result
import gleam/string
import gleam/time/calendar
import gleam/time/timestamp
import simplifile
import musicplayer/logging/control.{type Control}
type State {
State(filepath: String)
}
pub fn new(filepath: String) -> Result(Subject(Control), String) {
use _ <- result.try(
case simplifile.is_file(filepath) {
Ok(True) -> Ok(Nil)
_ -> simplifile.create_file(filepath)
}
|> result.map_error(fn(e) {
"Could not access or create log file: " <> string.inspect(e)
}),
)
actor.new(State(filepath:))
|> actor.on_message(handle_message)
|> actor.start
|> result.map_error(fn(start_error) {
"Could not start logger: " <> string.inspect(start_error)
})
|> result.map(fn(started) { started.data })
}
fn handle_message(state: State, control: Control) -> actor.Next(State, Control) {
case control {
control.Write(content) -> {
let log_line =
timestamp.system_time()
|> timestamp.to_rfc3339(calendar.utc_offset)
<> ": "
<> content
<> "\n"
// Ignore any logging errors
let _ = simplifile.append(state.filepath, log_line)
actor.continue(state)
}
control.Exit(reply_to) -> {
process.send(reply_to, Nil)
actor.stop()
}
}
}
pub fn log(logger: Subject(Control), content: String) -> Nil {
process.send(logger, control.Write(content))
}