public void CreateByCodeOwnDaemon() { using (var logger = new LogDaemon(NOPApplication.Instance)) { logger.WriteInterval = 0; //set the minimum flush period Aver.Throws <AzosException>(() => logger.Start()); //can not start daemon with no sinks Aver.IsFalse(logger.Running); Aver.IsFalse(logger.Sinks.Any()); using (var sink = new MemoryBufferSink(logger)) { sink.Name.See(); Aver.IsTrue(sink.Name.StartsWith("MemoryBufferSink.")); //anonymous sinks get their name from their: 'type.fid' logger.Start(); //now it can start Aver.IsTrue(logger.Running); Aver.AreSameRef(sink, logger.Sinks.First()); //now there is a sink registered which is this one Aver.IsTrue(sink.Running); //it was auto-started by the logger logger.Write(new Message { Type = MessageType.DebugB, Text = "This is a message #1" }); //so this messages goes in it Thread.Sleep(DAEMON_FLUSH_WAIT_MS); //make sure async flush happens Aver.IsTrue(sink.Buffered.Any()); //because sink was active var logged = sink.Buffered.FirstOrDefault(); // we get the first message buffered Aver.AreEqual("This is a message #1", logged.Text); Aver.IsTrue(MessageType.DebugB == logged.Type); sink.WaitForCompleteStop();//stop the sink Aver.IsFalse(sink.Running); logger.Write(new Message { Type = MessageType.Debug, Text = "This is a message #2" }); Thread.Sleep(DAEMON_FLUSH_WAIT_MS); //make sure async flush happens Aver.AreEqual(1, sink.Buffered.Count()); //because sink was not turned on for 2nd, only the first message got in, 2nd got lost } Aver.IsFalse(logger.Sinks.Any());//again, no sinks left } }
protected override void DoWaitForCompleteStop() { base.DoWaitForCompleteStop(); // at this point the thread has stopped and we can now stop the sinks var iamPrimary = object.ReferenceEquals(App.Log, this); foreach (var sink in m_Sinks.OrderedValues.Reverse()) { try { if (iamPrimary) { sink.WaitForCompleteStop(); continue; } var msTimeout = sink.ExpectedShutdownDurationMs; if (msTimeout < 1) { msTimeout = App.ExpectedComponentShutdownDurationMs; } if (msTimeout < 1) { msTimeout = CommonApplicationLogic.DFLT_EXPECTED_COMPONENT_SHUTDOWN_DURATION_MS; } TimedCall.Run(_ => sink.WaitForCompleteStop(), msTimeout, () => WriteLog(MessageType.WarningExpectation, "{0}.{1}".Args(nameof(DoWaitForCompleteStop), sink.Name), "Awaiting sink '{0}' is taking longer than expected {1:n} ms".Args(sink.Name, msTimeout))); } catch { #warning REVISE - must not eat exceptions - use Conout? use new .core ETW } // Can't do much here in case of an error } m_InstrBuffer.WaitForCompleteStop(); }