+ let openLogFile (entryNumber : int64) =
+ if not (isNull logDir) then
+ try
+ if isNull stream || (entryNumber % (int64 NB_ENTRIES_CHECK_SIZE) = 0L) && stream.BaseStream.Length > MAX_SIZE_FILE
+ then
+ if not (isNull stream)
+ then
+ stream.Close()
+ if COMPRESS_ARCHIVED_FILES then
+ compress filename
+ File.Delete(filename)
+
+ // Search the last id among the log files.
+ let mutable n = 1
+ for existingFile in Directory.GetFiles(logDir) do
+ match extractNumberFromLogfilepath existingFile with
+ | Some n' when n' > n -> n <- n'
+ | _ -> ()
+
+ filename <- Path.Combine(logDir, String.Format(FILENAME_FORMAT, n))
+ try
+ if File.Exists(filename + COMPRESSED_FILE_POSTFIX) || FileInfo(filename).Length > MAX_SIZE_FILE
+ then
+ filename <- Path.Combine(logDir, String.Format(FILENAME_FORMAT, n + 1))
+ with
+ | :? FileNotFoundException -> () // The file may not exist.
+
+ stream <- new StreamWriter(filename, true, encoding)
+ with
+ | ex -> Console.Error.WriteLine("Can't open the file log: {0}", ex)
+
+ let write (msg : Message) (entryNumber : int64) =
+ openLogFile entryNumber
+
+ let header =
+ String.Format(
+ "{0:yyyy-MM-dd HH:mm:ss.fff} [{1}] {{{2}}} ({3})",
+ TimeZone.CurrentTimeZone.ToLocalTime(DateTime.UtcNow),
+ string msg.Severity,
+ msg.ModuleCaller,
+ (if String.IsNullOrEmpty(msg.ThreadName) then string msg.ThreadId else sprintf "%s-%i" msg.ThreadName msg.ThreadId)
+ )
+
+ for listener in listeners do
+ listener.NewEntry msg.Severity header msg.Message
+
+ if not (isNull stream)
+ then
+ try
+ stream.WriteLine("{0} : {1}", header, msg.Message)
+ stream.Flush()
+ with
+ | :? IOException as ex -> Console.Error.WriteLine("Unable to write to the log file: {0}", ex)
+
+ let writeAgent =
+ new MailboxProcessor<Command>(
+ fun inbox ->
+ let rec loop (nbEntries : int64) =
+ async {
+ let! command = inbox.Receive()
+ match command with
+ | Write message ->
+ write message nbEntries
+ return! loop (nbEntries + 1L)
+ | Stop replyChannel ->
+ replyChannel.Reply ()
+ }
+ loop 1L
+ )
+
+ do
+ writeAgent.Start()
+