Created
May 5, 2020 05:54
-
-
Save gubser/4853b209764be07704fc3d28a5a3afd2 to your computer and use it in GitHub Desktop.
Simple console logging in F# (incomplete)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Turns.Log | |
open System | |
open System.Threading.Tasks | |
open NodaTime | |
module Logging = | |
type LogLevel = | |
| Debug | |
| Info | |
| Warning | |
| Error | |
| Critical | |
type LogRecord = { | |
Level: LogLevel | |
Instant: Instant | |
Subsystem: string | |
Message: string | |
Extra: obj option | |
Completion: TaskCompletionSource<unit> option | |
} | |
let timeFormatter = | |
NodaTime.Text.InstantPattern.CreateWithInvariantCulture("uuuu'-'MM'-'dd'T'HH':'mm':'ss;FFF'Z'") | |
let logjson record = | |
let level = | |
match record.Level with | |
| LogLevel.Debug -> "debug" | |
| LogLevel.Info -> " info" | |
| LogLevel.Warning -> " warn" | |
| LogLevel.Error -> "error" | |
| LogLevel.Critical -> "critical" | |
let time = timeFormatter.Format(record.Instant) | |
printf "{ \"t\": \"%s\", \"l\": \"%s\", \"s\": %s, \"m\": %s }\n" | |
time | |
level | |
(Turns.Json.toJson record.Subsystem) | |
(Turns.Json.toJson record.Message) | |
let logconsole record = | |
let level = | |
match record.Level with | |
| LogLevel.Debug -> "DEBUG" | |
| LogLevel.Info -> " INFO" | |
| LogLevel.Warning -> Crayon.Output.BrightYellow " WARN" | |
| LogLevel.Error -> Crayon.Output.BrightRed "ERROR" | |
| LogLevel.Critical -> Crayon.Output.Red "CRITICAL" | |
let time = timeFormatter.Format(record.Instant) | |
let extra = | |
record.Extra | |
|> Option.map Turns.Json.toJson | |
|> Option.defaultValue "" | |
let printfunc = | |
match record.Level with | |
| LogLevel.Debug | |
| LogLevel.Info | |
| LogLevel.Warning -> printf | |
| LogLevel.Error | |
| LogLevel.Critical -> eprintf | |
printfunc "%s %s [%s] %s %s\n" | |
time | |
level | |
record.Subsystem | |
record.Message | |
extra | |
let logprinter = | |
MailboxProcessor.Start(fun inbox -> | |
let rec loop () = async { | |
let! record = inbox.Receive() | |
logconsole record | |
// logjson record | |
// in case completion is requested, we flush standard output | |
match record.Completion with | |
| Some tcs -> | |
Console.Out.Flush() | |
tcs.SetResult() | |
| None -> () | |
return! loop () | |
} | |
loop () | |
) | |
let logfunc level subsystem extra completion message = | |
Logging.logprinter.Post({ | |
Level = level | |
Instant = SystemClock.Instance.GetCurrentInstant() | |
Subsystem = subsystem | |
Message = message | |
Extra = extra | |
Completion = completion | |
}) | |
let debug subsystem = | |
Printf.ksprintf (logfunc Logging.LogLevel.Debug subsystem None None) | |
let info subsystem = | |
Printf.ksprintf (logfunc Logging.LogLevel.Info subsystem None None) | |
let warning subsystem = | |
Printf.ksprintf (logfunc Logging.LogLevel.Warning subsystem None None) | |
let error subsystem = | |
Printf.ksprintf (logfunc Logging.LogLevel.Error subsystem None None) | |
let critical subsystem = | |
Printf.ksprintf (logfunc Logging.LogLevel.Critical subsystem None None) | |
let debugX subsystem extra = | |
Printf.ksprintf (logfunc Logging.LogLevel.Debug subsystem (Some extra) None) | |
let infoX subsystem extra = | |
Printf.ksprintf (logfunc Logging.LogLevel.Info subsystem (Some extra) None) | |
let warningX subsystem extra = | |
Printf.ksprintf (logfunc Logging.LogLevel.Warning subsystem (Some extra) None) | |
let errorX subsystem extra = | |
Printf.ksprintf (logfunc Logging.LogLevel.Error subsystem (Some extra) None) | |
let logCriticalX subsystem extra = | |
Printf.ksprintf (logfunc Logging.LogLevel.Critical subsystem (Some extra) None) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment