Reduce a bit the thickness of selected RBC
[master-thesis.git] / Parasitemia / Logger / Logger.fs
1 namespace Logger
2
3 open System
4 open System.Diagnostics
5 open System.IO
6 open System.Threading
7
8 open Logger
9 open Logger.Types
10
11 [<Sealed>]
12 type Log () =
13 static let mutable writer : IWriter = new ConsoleWriter () :> IWriter
14 static let monitor = obj ()
15 static let listeners = Listeners ()
16
17 /// <summary>
18 /// Must be called first before any other action.
19 /// </summary>
20 static member LogDirectory
21 with get () = lock monitor (fun () -> writer.LogDir)
22 and set value =
23 lock monitor (
24 fun () ->
25 Log.Close ()
26 if String.IsNullOrWhiteSpace value then
27 writer <- new ConsoleWriter ()
28 else
29 writer <- new FileWriter (value)
30 )
31
32 /// <summary>
33 /// Close the log. 'LogDirectory' must be set again to reopen it.
34 /// </summary>
35 static member Close () =
36 lock monitor (
37 fun () ->
38 writer.Flush ()
39 (writer :> IDisposable).Dispose ()
40 writer <- new ConsoleWriter () :> IWriter
41 )
42
43 /// <summary>
44 /// Return all log files (the current one and the archived) as full paths.
45 /// </summary>
46 static member LogFiles = writer.LogFiles
47
48 /// <summary>
49 /// Wait that all the previous messages are written.
50 /// </summary>
51 static member Flush () = writer.Flush ()
52
53 static member DebugLoggingEnabled
54 with get () = writer.DebugLoggingEnabled
55 and set value = writer.DebugLoggingEnabled <- value
56
57 /// <summary>
58 /// Avoid to repeat a message by writting a reference to a previous message instead of the message.
59 /// 'false' by default.
60 /// </summary>
61 static member AvoidRepeatingIdenticalMessages
62 with get () = writer.AvoidRepeatingIdenticalMessages
63 and set value = writer.AvoidRepeatingIdenticalMessages <- value
64
65 /// <summary>
66 /// The maximum size of the current file log. If the file exceed this value it will be zipped and a new file will be created.
67 /// The file size is only tested each time a certain number of messages have been written so the file may exceed this value a bit.
68 /// </summary>
69 /// <param name="size"></param>
70 static member SetLogFilesMaxSize (size : int64) =
71 writer.MaxSizeFile <- size
72
73 static member ClearLogFilesOlderThan (timeOld : TimeSpan) =
74 writer.ClearLogFilesOlderThan timeOld
75
76 /// <summary>
77 /// Remove all archived log files and empty the current one.
78 /// </summary>
79 static member ClearLogFiles () =
80 Log.ClearLogFilesOlderThan (TimeSpan 0L)
81
82 /// <summary>
83 /// Total size in bytes.
84 /// </summary>
85 static member CurrentLogSize () : int64 =
86 Log.LogFiles
87 |> Seq.map (fun file -> try (FileInfo file).Length with | _ex -> 0L)
88 |> Seq.sum
89
90 static member AddListener (listener : IListener) =
91 listeners.Add listener
92
93 static member RemoveListener (listener : IListener) =
94 listeners.Remove listener
95
96 static member private Write (message : string) (severity : Severity) =
97 let msg =
98 {
99 Message = message
100 ThreadName = Thread.CurrentThread.Name
101 ThreadId = Thread.CurrentThread.ManagedThreadId
102 ModuleCaller = Utils.callerModuleName ()
103 Severity = severity
104 DateTime = TimeZone.CurrentTimeZone.ToLocalTime DateTime.UtcNow
105 }
106 listeners.NewEntry msg
107 writer.Write msg
108
109 /// <summary>
110 /// [F#] Execute the given function and measure its time.
111 /// </summary>
112 /// <param name="severity">Severity for writing to log</param>
113 /// <param name="f">Function to test</param>
114 /// <param name="format">Format string for output</param>
115 static member LogWithTime (severity : Severity) (f : unit -> 'a) (format : Printf.StringFormat<'b, 'a>) : 'b =
116 let sw = Stopwatch ()
117 sw.Start ()
118 let res = f ()
119 sw.Stop ()
120 Printf.kprintf (fun s -> Log.Write (s + sprintf " (time: %d ms)" sw.ElapsedMilliseconds) severity; res) format
121
122 /// <summary>
123 /// [F#] Write Debug message to log (if DebugLoggingEnabled = true)
124 /// </summary>
125 static member Debug format =
126 if writer.DebugLoggingEnabled then
127 Printf.kprintf (fun s -> Log.Write s Severity.DEBUG) format
128 else
129 // [BGR] FIXME: is it possible to simplify a bit here? It's more CPU consuming than the C# couterpart.
130 Printf.kprintf (fun _ -> ()) format
131
132 /// <summary>
133 /// [F#] Write Info message to log
134 /// </summary>
135 static member Info format =
136 Printf.kprintf (fun s -> Log.Write s Severity.INFO) format
137
138 /// <summary>
139 /// [F#] Write Warning message to log
140 /// </summary>
141 static member Warning format =
142 Printf.kprintf (fun s -> Log.Write s Severity.WARNING) format
143
144 /// <summary>
145 /// [F#] Write Error message to log
146 /// </summary>
147 static member Error format =
148 Printf.kprintf (fun s -> Log.Write s Severity.ERROR) format
149
150 /// <summary>
151 /// [F#] Write Fatal message to log
152 /// </summary>
153 static member Fatal format =
154 Printf.kprintf (fun s -> Log.Write s Severity.FATAL) format
155
156 /// <summary>
157 /// Write DEBUG message to log (if DebugLoggingEnabled = true)
158 /// </summary>
159 static member DEBUG (message : string, [<ParamArray>] args : obj array) =
160 if writer.DebugLoggingEnabled then
161 if isNull args || args.Length = 0 then
162 Log.Write message Severity.DEBUG
163 else
164 Log.Write (String.Format (message, args)) Severity.DEBUG
165
166 /// <summary>
167 /// Write DEBUG message to log (if DebugLoggingEnabled = true)
168 /// </summary>
169 static member DEBUG (message : string) = Log.DEBUG (message, [| |])
170
171 /// <summary>
172 /// Write INFO message to log
173 /// </summary>
174 static member INFO (message : string, [<ParamArray>] args : obj array) =
175 if isNull args || args.Length = 0 then
176 Log.Write message Severity.INFO
177 else
178 Log.Write (String.Format (message, args)) Severity.INFO
179
180 /// <summary>
181 /// Write INFO message to log
182 /// </summary>
183 static member INFO (message : string) = Log.INFO (message, [| |])
184
185 /// <summary>
186 /// Write WARNING message to log
187 /// </summary>
188 static member WARNING (message : string, [<ParamArray>] args : obj array) =
189 if isNull args || args.Length = 0 then
190 Log.Write message Severity.WARNING
191 else
192 Log.Write (String.Format (message, args)) Severity.WARNING
193
194 /// <summary>
195 /// Write WARNING message to log
196 /// </summary>
197 static member WARNING (message : string) = Log.WARNING (message, [| |])
198
199 /// <summary>
200 /// Write ERROR message to log
201 /// </summary>
202 static member ERROR (message : string, [<ParamArray>] args : obj array) =
203 if isNull args || args.Length = 0 then
204 Log.Write message Severity.ERROR
205 else
206 Log.Write (String.Format (message, args)) Severity.ERROR
207
208 /// <summary>
209 /// Write ERROR message to log
210 /// </summary>
211 static member ERROR (message : string) = Log.ERROR (message, [| |])
212
213 /// <summary>
214 /// Write FATAL message to log
215 /// </summary>
216 static member FATAL (message : string, [<ParamArray>] args : obj array) =
217 if isNull args || args.Length = 0 then
218 Log.Write message Severity.FATAL
219 else
220 Log.Write (String.Format (message, args)) Severity.FATAL
221
222 /// <summary>
223 /// Write FATAL message to log
224 /// </summary>
225 static member FATAL (message : string) = Log.FATAL (message, [| |])