anchor.diff:              | _ -> System.Console.Error.WriteLine(le.ToString())
               System.Console.ResetColor()
           Logger("", print)
  -        
  +
       /// A logger that prints to std::out / std::err based on the context, with extra colourization, using a short form
       let ColorConsoleShort =
           let print (le:LogEntry) =
  
positive.code: open System.Globalization
  
  type LogLevel =
      | Trace = 0
      | Debug = 1
      | Info = 2
      | Notice = 3
      | Warn = 4
      | Error = 5
      | Fatal = 6
  
  /// Immutable struct holding information relating to a log entry.
  [<Struct>]
  type LogEntry(level : LogLevel, time : DateTime, path : string, message : string) = 
  
      static let separators = [| '\\'; '/' |]
      
      /// The log level of the message
      member __.Level = level
      
      /// The time at which the entry was logged
      member __.Time = time
      
      /// The source of the message
      member __.Path = path
      
      /// The actual log message
      member __.Message = message
      
      override __.ToString() = sprintf "[%A|%A]%s:%s" time level path message
  
      /// Retrieves a string representation of the long message using some default formatting. This is a more compact representation than ToString()
      member __.ShortString = 
          let sb = StringBuilder(path.Length)
          let idx = path.LastIndexOfAny(separators, path.Length - 1)
          let ts = DateTimeFormatInfo.CurrentInfo.LongTimePattern
  
negative.code:           .Append(message)
            .ToString()
  
  /// Immutable logger, which holds information about the logging context.
  [<Struct>]
  [<StructuredFormatDisplay("Logger: {path = path; consumer = consumer}")>]
  type Logger internal (path : string, consumer : LogEntry -> unit) =
  
      /// The current path of this logger
      member _.Path = path
  
      /// The current consumer for this logger
      member _.Consumer = consumer
  
      /// Logs an unformatted message at the specified level
      member _.Log level message =
          let logEntry = LogEntry(level, DateTime.Now, path, message)
          consumer logEntry
  
      member x.Logf level format = Printf.ksprintf (x.Log level) format
  
      // ---------------------
      // FORMAT METHODS
      // ---------------------
      
      /// Logs a format string at the trace level. This is the lowest log level.
      member x.Tf format = Printf.ksprintf (x.Log LogLevel.Trace) format
  
      /// Logs a format string at the debug level. This is higher than trace and lower than info.
      member x.Df format = Printf.ksprintf (x.Log LogLevel.Debug) format
  
      /// Logs a format string at the info level. This is higher than debug and lower than notice.
      member x.If format = Printf.ksprintf (x.Log LogLevel.Info) format
  
      /// Logs a format string at the notice level. This is higher than info and lower than warn.
      member x.Nf format = Printf.ksprintf (x.Log LogLevel.Notice) format
  
      /// Logs a format string at the warning level. This is higher than notice and lower than error.
      member x.Wf format = Printf.ksprintf (x.Log LogLevel.Warn) format
  
      /// Logs a format string at the error level. This is higher than warn and lower than fatal.
      member x.Ef format = Printf.ksprintf (x.Log LogLevel.Error) format
  
      /// Logs a format string at the fatal level. This is the highest log level.
      member x.Ff format = Printf.ksprintf (x.Log LogLevel.Fatal) format
          
      // ---------------------
      // INTERPOLATION METHODS
      // ---------------------
          
      /// Logs the message at the trace level. This is the lowest log level.
      member x.T msg = x.Log LogLevel.Trace msg
  
      /// Logs the message at the debug level. This is higher than trace and lower than info.
      member x.D msg = x.Log LogLevel.Debug msg
  
      /// Logs the message at the info level. This is higher than debug and lower than notice.
      member x.I msg = x.Log LogLevel.Info msg
  
      /// Logs the message at the notice level. This is higher than info and lower than warn.
      member x.N msg = x.Log LogLevel.Notice msg
  
      /// Logs the message at the warning level. This is higher than notice and lower than error.
      member x.W msg = x.Log LogLevel.Warn msg
  
      /// Logs the message at the error level. This is higher than warn and lower than fatal.
      member x.E msg = x.Log LogLevel.Error msg
  
      /// Logs the message at the fatal level. This is the highest log level.
      member x.F msg = x.Log LogLevel.Fatal msg
          
  
      override _.ToString() = $"Logger: {{path = '{path}'; consumer = {consumer}}}"
  
  module Logger =
      /// The default logger. Has no path and does nothing on consumption.
      let Default = Logger("", ignore)
      let mutable Platform = Default
  
      /// A logger that prints to std::out / std::err based on the context
      let Console =
          let print (le:LogEntry) =
              match le.Level with
              | LogLevel.Debug | LogLevel.Info -> Console.WriteLine (string le)
              | _ -> Console.Error.WriteLine(string le)
  
          Logger("", print)
  
      /// A logger that prints to std::out / std::err based on the context, using a short form
      let ConsoleShort =
          let print (le:LogEntry) =
              match le.Level with
              | LogLevel.Debug | LogLevel.Info -> System.Console.WriteLine(le)
              | _ -> System.Console.Error.WriteLine(le.ShortString)
  
          Logger("", print)
  
      let private levelToCol l =
          match l with
          | LogLevel.Trace -> ConsoleColor.DarkGray
          | LogLevel.Debug -> ConsoleColor.Gray
          | LogLevel.Info -> ConsoleColor.White
          | LogLevel.Notice -> ConsoleColor.Blue
          | LogLevel.Warn -> ConsoleColor.Yellow
          | LogLevel.Error -> ConsoleColor.Red
  