Last active
February 16, 2024 15:23
-
-
Save Thorium/fa7bb89fd9b165c5e57820eeec9bd6d0 to your computer and use it in GitHub Desktop.
Use (or replace) existing Logary via Microsoft.Extensions.Logging.Abstractions. This can be used to abstract Logary behind Microsoft.Extensions.Logging so it's easier to remove from existing infra (or migrate to, whatever).
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
// This expects you have 2 projects, this first one has dependendency only to Microsoft.Extensions.Logging.Abstractions | |
// (and temporarily usage of Microsoft.Extensions.Logging.Console ). | |
module AbstractProject | |
let loggerFactory = | |
Microsoft.Extensions.Logging.LoggerFactory.Create(fun builder -> | |
let _ = Microsoft.Extensions.Logging.ConsoleLoggerExtensions.AddSimpleConsole builder | |
()) | |
/// This is ILogger. | |
let mutable logger = lazy(loggerFactory.CreateLogger("Temp-logger")) // Initially some temp-logger, replaced below. | |
/// Module to repalce Logary with Microsoft.Extensions.Logging | |
/// Usage: Replace Logary.Message.eventDebug "hi {a}" |> Logary.Message "a" "world" |> writeLogSimple | |
/// With: Logari.Message.eventDebug "hi {a}" |> Logari.Message "a" "world" |> writeLogSimple | |
module Logari = | |
type CustomMessage = | |
{ Level: Microsoft.Extensions.Logging.LogLevel | |
Message: string | |
Fields: System.Collections.Generic.Dictionary<string, obj> | |
} with override this.ToString() = | |
if this = Unchecked.defaultof<CustomMessage> then "" else | |
let mutable sb = System.Text.StringBuilder this.Message | |
if this.Fields = null then sb.ToString() | |
for i in this.Fields do | |
if i.Value <> null then | |
sb <- sb.Replace("{" + i.Key + "}", i.Value.ToString()) | |
sb.ToString() | |
module Message = | |
let eventDebug (msg:string) = {Level = Microsoft.Extensions.Logging.LogLevel.Debug; Message = msg; Fields = new System.Collections.Generic.Dictionary<_,_>()} | |
let eventInfo (msg:string) = {Level = Microsoft.Extensions.Logging.LogLevel.Information; Message = msg; Fields = new System.Collections.Generic.Dictionary<_,_>()} | |
let eventWarn (msg:string) = {Level = Microsoft.Extensions.Logging.LogLevel.Warning; Message = msg; Fields = new System.Collections.Generic.Dictionary<_,_>()} | |
let eventError (msg:string) = {Level = Microsoft.Extensions.Logging.LogLevel.Error; Message = msg; Fields = new System.Collections.Generic.Dictionary<_,_>()} | |
let eventFatal (msg:string) = {Level = Microsoft.Extensions.Logging.LogLevel.Critical; Message = msg; Fields = new System.Collections.Generic.Dictionary<_,_>()} | |
let setField (name:string) (value:obj) (msg:CustomMessage)= | |
if not (msg.Fields.ContainsKey name) then | |
msg.Fields.Add(name, value) | |
msg | |
let setFieldFromObject (name:string) (value:obj) (msg:CustomMessage)= | |
if not (msg.Fields.ContainsKey name) then | |
msg.Fields.Add(name, value) | |
msg | |
module Logger = | |
let logSimple (l:Microsoft.Extensions.Logging.ILogger) (msg:CustomMessage) = | |
l.Log(msg.Level, 0, msg, null, fun msg _ -> msg.ToString()) | |
let writeLogSimple = Logari.Logger.logSimple |
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
// This second one has Logary dependency that is registering the Logary as Microsoft.Extensions.Logging.Abstraction | |
[<AutoOpen>] | |
module Logging | |
open Microsoft.Extensions.Logging | |
open Logary | |
/// Old Logary direct calls: | |
let logger = lazy(Logary.Logging.getCurrentLogger()) | |
/// General Logary logger | |
let writeLog x = | |
let l = logger.Force() | |
Logary.Logger.logSimple l x | |
type LogaryLogger(name) = | |
new() = LogaryLogger "default" | |
interface ILogger with | |
member __.IsEnabled(_) = true | |
member __.BeginScope(_) = { new System.IDisposable with | |
member this.Dispose() = ()} | |
member __.Log(level, evetId:EventId, state, ex, formatter) = | |
let msg = unbox<AbstractProject.Logari.CustomMessage>(state) | |
let mutable lmsg = | |
match level with | |
| Microsoft.Extensions.Logging.LogLevel.Debug -> | |
Logary.Message.eventDebug msg.Message | |
| Microsoft.Extensions.Logging.LogLevel.Information -> | |
Logary.Message.eventInfo msg.Message | |
| Microsoft.Extensions.Logging.LogLevel.Warning -> | |
Logary.Message.eventWarn msg.Message | |
| Microsoft.Extensions.Logging.LogLevel.Error -> | |
Logary.Message.eventError msg.Message | |
| Microsoft.Extensions.Logging.LogLevel.Critical -> | |
Logary.Message.eventFatal msg.Message | |
| Microsoft.Extensions.Logging.LogLevel.Trace | |
| Microsoft.Extensions.Logging.LogLevel.None | |
| _ -> Logary.Message.eventVerbose msg.Message | |
for i in msg.Fields do | |
lmsg <- lmsg |> Message.setFieldFromObject i.Key i.Value | |
() | |
writeLog lmsg | |
[<ProviderAlias("LogaryLogger")>] | |
type LogaryLoggerProvider() = | |
let loggers = System.Collections.Concurrent.ConcurrentDictionary<string, LogaryLogger>() | |
interface ILoggerProvider with | |
member _.CreateLogger categoryName = | |
loggers.GetOrAdd(categoryName, fun name -> new LogaryLogger(name)); | |
member _.Dispose() = loggers.Clear() | |
let mutable loggingSetup = false | |
let setupLogging() = | |
if not loggingSetup then | |
AbstractProject.logger <- lazy(LogaryLogger() :> ILogger) | |
loggingSetup <- true | |
setupLogging() |
Author
Thorium
commented
Dec 14, 2023
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment