SqlDatabaseSink doesnt log into Logging DB

Topics: Semantic Logging Application Block
Mar 31 at 6:03 PM
Edited Mar 31 at 7:59 PM
Im trying to log into SQL Db using SqlDatabaseSink. However doesn't matter what settings i try, the message doesn't get log into Logging DB.
I have downloaded package using NuGet
  • Microsoft.Practices.EnterpriseLibrary.SemanticLogging.Database.dll 1.1.1403.0
  • Microsoft.Practices.EnterpriseLibrary.SemanticLogging.dll 1.1.1403.0
I have also tried from Microsoft Enterprise Library 6.0 Binaries
  • Microsoft.Practices.EnterpriseLibrary.SemanticLogging.dll 1.0.1304.0
  • Microsoft.Practices.EnterpriseLibrary.SemanticLogging.Database.dll 1.0.1304.0
I set the buffer count to 1, expecting that the message will get logged after every call. Also i set the buffering level to 30 sec, that means if i wait for 30 sec the message should get log.

Below is my code. ( note that it only logs if i explicitly flush the buffer).
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
  </startup>
  <connectionStrings>
    <add name="MyConnectionString" connectionString="Data Source=.\sqlexpress; Initial Catalog=Logging;Integrated Security=SSPI;"/>
  </connectionStrings>
</configuration>
    [EventSource(Name = "SemanticLoggingPOC")]
    public class MyEventSource : EventSource
    {
        public class Keywords
        {
            public const EventKeywords Page = (EventKeywords)1;
            public const EventKeywords DataBase = (EventKeywords)2;
            public const EventKeywords Diagnostic = (EventKeywords)4;
            public const EventKeywords Perf = (EventKeywords)8;
        }

        public class Tasks
        {
            public const EventTask Page = (EventTask)1;
            public const EventTask DBQuery = (EventTask)2;
        }

        private static MyEventSource _log = new MyEventSource();
        private MyEventSource() { }
        public static MyEventSource Log { get { return _log; } }

        [Event(1, Message = "Application Failure: {0}",
        Level = EventLevel.Critical, Keywords = Keywords.Diagnostic)]
        internal void Failure(string message)
        {
            this.WriteEvent(1, message);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var listener1 = new ObservableEventListener();

            listener1.EnableEvents(MyEventSource.Log, EventLevel.Verbose, Keywords.All);

            SinkSubscription<SqlDatabaseSink> subscription =
                listener1.LogToSqlDatabase("MyTest",
                ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString,
                "Traces",
                Microsoft.Practices.EnterpriseLibrary.SemanticLogging.Utility.Buffering.DefaultBufferingInterval,
                1, // it shuld get log after every message
                Timeout.InfiniteTimeSpan,
                500);

            MyEventSource.Log.Failure("This is test message!!");


            // Im sure that connection string & other settings are correct 
            // because it logs into DB if i explicitly flush or dispose listener as below
            // subscription.Sink.FlushAsync().Wait();            
            // listener1.Dispose();
        }
    }
Editor
Apr 1 at 4:18 AM
You have to remember that all of the logging is happening asynchronously. Log events are fired asynchronously and the SqlDatabaseSink also logs asynchronously. If you don't flush the sink before the application ends then the messages will not/may not be logged. From the Developer's Guide: "You should set up your listeners at bootstrap time and dispose of them when you shut down your application". As you say, for the SqlDatabaseSink this also means flushing.

If I set the bufferingCount to 1 and a sleep of 1 second after call Log.Failure, I see the record in the database table (although that is not 100% guaranteed). The buffering interval does not come into play here because with the bufferingCount set to 1 the buffer is flushed after every call.

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Apr 1 at 2:39 PM
i do understand that its async but i put the break point before the code exit Main function, and waited more than 30 sec to see if that logs the message. but it didnt work.
Editor
Apr 2 at 11:38 PM
If you are debugging and stopped at a break point then the other threads will not be running (and if you try to step you'll exit the program). You could freeze the main thread and then run the worker thread.

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Aug 28 at 7:31 PM
You probably don't have the database scripts. It's not like it gives you an error or anything when it doesn't find the procs or tables it's expecting. They are in \packages\EnterpriseLibrary.SemanticLogging.Database.1.0.1304.0\scripts.