SQL Server Trace Listener WriteLog Error

Topics: Logging Application Block
Nov 18, 2011 at 3:06 PM
Edited Nov 18, 2011 at 3:07 PM

When I try to use Sql Trace listener , I'm getting the following errror. When I used the Sql profiler to trace the problem , the stored proc is called with MachineName of null from the Enterpriselibrary dll

Note: When I use the flat  file listener , I can see the machinename properly logged.

Exception Type: System.Data.SqlClient.SqlException
Errors: System.Data.SqlClient.SqlErrorCollection
Class: 16
LineNumber: 26
Number: 515
Procedure: WriteLog
Server: XXXXX

State: 2
Source: .Net SqlClient Data Provider
ErrorCode: -2146232060
Message: Cannot insert the value NULL into column 'MachineName', table 'Logging.dbo.Log'; column does not allow nulls. INSERT fails.
The statement has been terminated.
The 'WriteLog' procedure attempted to return a status of NULL, which is not allowed. A status of 0 will be returned instead.
Data: System.Collections.ListDictionaryInternal
TargetSite: Void OnError(System.Data.SqlClient.SqlException, Boolean)
HelpLink: NULL

StackTrace Information Details: 
======================================
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
   at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
   at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
   at Microsoft.Practices.EnterpriseLibrary.Data.Database.DoExecuteNonQuery(DbCommand command)
   at Microsoft.Practices.EnterpriseLibrary.Data.Database.ExecuteNonQuery(DbCommand command, DbTransaction transaction)
   at Microsoft.Practices.EnterpriseLibrary.Logging.Database.FormattedDatabaseTraceListener.ExecuteWriteLogStoredProcedure(LogEntry logEntry, Database db, DbTransaction transaction)
   at Microsoft.Practices.EnterpriseLibrary.Logging.Database.FormattedDatabaseTraceListener.ExecuteStoredProcedure(LogEntry logEntry)
   at Microsoft.Practices.EnterpriseLibrary.Logging.Database.FormattedDatabaseTraceListener.TraceData(TraceEventCache eventCache, String source, TraceEventType eventType, Int32 id, Object data)
   at Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.TraceListenerWrapper.TraceData(TraceEventCache eventCache, String source, TraceEventType eventType, Int32 id, Object data)
   at Microsoft.Practices.EnterpriseLibrary.Logging.LogSource.TraceData(TraceEventType eventType, Int32 id, LogEntry logEntry, TraceListenerFilter traceListenerFilter, TraceEventCache traceEventCache)
   at Microsoft.Practices.EnterpriseLibrary.Logging.LogWriterImpl.ProcessLog(LogEntry log, TraceEventCache traceEventCache)
Nov 20, 2011 at 4:01 AM

The only way I can recreate your issue is to manually set the MachineName property to null.  

I can't see how MachineName can automatically be set to null.  MachineName is set to Environment.MachineName on initialization.  
Environment.MachineName either throws or returns a (non-null) string reference.  On an exception, Enterprise Library will set the MachineName
property to something like "Unable to read intrinsic property.  Error message:".   So it seems like the only way for that to be null is if it is manually set to null.

Can you provide more information?  E.g. config, code sample, connection string, environment information.

Thanks.

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com

Nov 20, 2011 at 6:55 PM
The interesting aspect of this is, if I use any other listener other than database listener, the machine name is logged properly.

Thank you
Baski

Sent from my Windows Phone

From: randylevy
Sent: 11/19/2011 10:01 PM
To: tobaskaran@hotmail.com
Subject: Re: SQL Server Trace Listener WriteLog Error [entlib:280010]

From: randylevy

The only way I can recreate your issue is to manually set the MachineName property to null.

I can't see how MachineName can automatically be set to null. MachineName is set to Environment.MachineName on initialization.
Environment.MachineName either throws or returns a (non-null) string reference. On an exception, Enterprise Library will set the MachineName
property to something like "Unable to read intrinsic property. Error message:". So it seems like the only way for that to be null is if it is manually set to null.

Can you provide more information? E.g. config, code sample, connection string, environment information.

Thanks.

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com

Nov 20, 2011 at 11:33 PM

I agree -- it's very strange.  If you can get me the additional information maybe we can get to the root of the issue.

 

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com

Nov 21, 2011 at 2:35 PM

I think it happens only from Silverlight service call logging. To verify this issue , I ran the Stocktrade reference implementation application and set the breakpoint in the WCF service call, the logentry has null machine name. Also in this sample implementation code , they do access IPaddress of the system , that's also blank. Do I have to enable any specific settings ???? Surprised to see , even sample implementation is not working either.

Nov 21, 2011 at 11:04 PM

Yes, that makes sense if you are dealing with Silverlight.  Because Silverlight is running in a sandbox, the Silverlight LogEntry object does not support the following properties which are also NOT NULL
in the Logging Database Schema: 

  • MachineName
  • ProcessID
  • ProcessName

This seems to be an oversight when using Silverlight logging combined with the DatabaseTraceListener.

There are 2 options to overcome this: modify the [Log] database table to allow the MachineName, ProcessID, and ProcessName columns to allow NULLs or
create a service which sets those values to be empty string instead.

The service is quite simple and would look like this:

    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class DatabaseLoggingService : LoggingService
    {
        /// <summary>
        /// Translates the incoming <see cref="LogEntryMessage"/> into a <see cref="LogEntry"/>.
        /// </summary>
        /// <param name="entry">The log entry coming from the client.</param>
        /// <returns>A <see cref="LogEntry"/> instance that can be stored in the log.</returns>
        protected override LogEntry Translate(LogEntryMessage entry)
        {
            var logEntry = entry.ToLogEntry();

            if (logEntry.MachineName == null) logEntry.MachineName = string.Empty;
            if (logEntry.ProcessId == null) logEntry.ProcessId = string.Empty;
            if (logEntry.ProcessName == null) logEntry.ProcessName = string.Empty;

            return logEntry;
        }
    }


--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com

Jan 5, 2012 at 4:26 PM
Edited Jan 5, 2012 at 4:26 PM

Oops...wrong thread. 

Jul 25, 2012 at 3:10 AM

Is there no way to Get the machine name in silverlight. otherwise there is no way to distinguish who did what?

 

Nick

Jul 25, 2012 at 6:00 AM

There is no way of retrieving the machine name in Silverlight.  However, you are free to attach other information to the LogEntry.  One technique to get the machine name is to set it in the ASP.NET hosting code.  For example: http://www.dotnetpatterns.net/entries/44-How-to-retrieve-a-machine-name-in-a-Silverlight-Application.

-- 
Randy Levy
Enterprise Library support engineer
entlib.support@live.com