-
Notifications
You must be signed in to change notification settings - Fork 198
/
Logger.fs
72 lines (62 loc) · 2.88 KB
/
Logger.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
namespace Suave.Logging
open System
/// The primary Logger abstraction that you can log data into
type Logger =
/// log - evaluate the function if the log level matches - by making it
/// a function we don't needlessly need to evaluate it
/// Calls to this method must be thread-safe and not change any state
abstract member Log : LogLevel -> (unit -> LogLine) -> unit
module Loggers =
/// A logger to use for combining a number of other loggers
type CombiningLogger(otherLoggers : Logger list) =
interface Logger with
member x.Log level fLine =
otherLoggers |> List.iter (fun l -> l.Log level fLine)
/// let the ISO8601 love flow
let internal defaultFormatter (line : LogLine) =
// [I] 2014-04-05T12:34:56Z: Hello World! [my.sample.app]
"[" + Char.ToUpperInvariant(line.level.ToString().[0]).ToString() + "] " +
(DateTime(line.tsUTCTicks, DateTimeKind.Utc).ToString("o")) + ": " +
line.message + " [" + line.path + "]" +
(match line.``exception`` with | Some e -> " exn:\n" + e.ToString() | None -> "")
/// Log a line with the given format, printing the current time in UTC ISO-8601 format
/// and then the string, like such:
/// '2013-10-13T13:03:50.2950037Z: today is the day'
type ConsoleWindowLogger(minLevel, ?formatter, ?colourise, ?originalColor, ?consoleSemaphore) =
let sem = defaultArg consoleSemaphore (obj())
let originalColor = defaultArg originalColor Console.ForegroundColor
let formatter = defaultArg formatter defaultFormatter
let colourise = defaultArg colourise true
let write = System.Console.WriteLine : string -> unit
let toColor = function
| LogLevel.Verbose -> ConsoleColor.DarkGreen
| LogLevel.Debug -> ConsoleColor.Green
| LogLevel.Info -> ConsoleColor.White
| LogLevel.Warn -> ConsoleColor.Yellow
| LogLevel.Error -> ConsoleColor.DarkRed
| LogLevel.Fatal -> ConsoleColor.Red
let log color line =
if colourise then
lock sem <| fun _ ->
Console.ForegroundColor <- color
(write << formatter) line
Console.ForegroundColor <- originalColor
else
// we don't need to take another lock, since Console.WriteLine does that for us
(write << formatter) line
interface Logger with
member x.Log level f =
if level >= minLevel then
log (toColor level) (f ())
type OutputWindowLogger(minLevel, ?formatter) =
let formatter = defaultArg formatter defaultFormatter
let log line = System.Diagnostics.Debug.WriteLine(formatter line)
interface Logger with
member x.Log level fLine = if level >= minLevel then log (fLine ())
let saneDefaultsFor level =
if level >= LogLevel.Warn then
ConsoleWindowLogger(level) :> Logger
else
CombiningLogger(
[ ConsoleWindowLogger(level)
OutputWindowLogger(level) ]) :> Logger