SqlWebEventProvider.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / xsp / System / Web / Management / SqlWebEventProvider.cs / 1305376 / SqlWebEventProvider.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.Management { 
    using System.Configuration.Provider; 
    using System.Collections;
    using System.Collections.Specialized; 
    using System.Configuration;
    using System.Globalization;
    using System.Data;
    using System.Data.SqlClient; 
    using System.Security.Permissions;
    using System.Security.Principal; 
    using System.Text; 
    using System.Threading;
    using System.Web.DataAccess; 
    using System.Web.Util;

    ////////////
    // Events 
    ////////////
 
    [PermissionSet(SecurityAction.InheritanceDemand, Unrestricted = true)] 
    public class SqlWebEventProvider : BufferedWebEventProvider, IInternalWebEventProvider {
        const int       SQL_MAX_NTEXT_SIZE = 1073741823; 
        const int       NO_LIMIT = -1;
        const string    SP_LOG_EVENT = "dbo.aspnet_WebEvent_LogEvent";

        string          _sqlConnectionString; 
        int             _maxEventDetailsLength = NO_LIMIT;
        int             _commandTimeout = -1; 
        int             _SchemaVersionCheck; 
        int             _connectionCount = 0;
 
        DateTime        _retryDate = DateTime.MinValue; // Won't try sending unless DateTime.UtcNow is > _retryDate

        protected internal SqlWebEventProvider() { }
 
        public override void Initialize(string name, NameValueCollection config) {
 
            Debug.Trace("SqlWebEventProvider", "Initializing: name=" + name); 
            _SchemaVersionCheck = 0;
            string  temp = null; 

            ProviderUtil.GetAndRemoveStringAttribute(config, "connectionStringName", name, ref temp);
            ProviderUtil.GetAndRemoveStringAttribute(config, "connectionString", name, ref _sqlConnectionString);
            if (!String.IsNullOrEmpty(temp)) { 
                if (!String.IsNullOrEmpty(_sqlConnectionString)) {
                    throw new ConfigurationErrorsException(SR.GetString(SR.Only_one_connection_string_allowed)); 
                } 

                _sqlConnectionString = SqlConnectionHelper.GetConnectionString(temp, true, true); 
                if (_sqlConnectionString == null || _sqlConnectionString.Length < 1) {
                    throw new ConfigurationErrorsException(SR.GetString(SR.Connection_string_not_found, temp));
                }
            } 
            else {
                // If a connection string is specified explicitly, verify that its not using integrated security 
                SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(_sqlConnectionString); 
                if (builder.IntegratedSecurity) {
                    throw new ConfigurationErrorsException(SR.GetString(SR.Cannot_use_integrated_security)); 
                }
            }

            if (String.IsNullOrEmpty(_sqlConnectionString)) { 
                throw new ConfigurationErrorsException(SR.GetString(SR.Must_specify_connection_string_or_name, temp));
            } 
 

            ProviderUtil.GetAndRemovePositiveOrInfiniteAttribute(config, "maxEventDetailsLength", name, ref _maxEventDetailsLength); 
            if (_maxEventDetailsLength == ProviderUtil.Infinite) {
                _maxEventDetailsLength = NO_LIMIT;
            }
            else if (_maxEventDetailsLength > SQL_MAX_NTEXT_SIZE) { 
                throw new ConfigurationErrorsException(SR.GetString(SR.Invalid_max_event_details_length, name, _maxEventDetailsLength.ToString(CultureInfo.CurrentCulture)));
            } 
 
            ProviderUtil.GetAndRemovePositiveAttribute(config, "commandTimeout", name, ref _commandTimeout);
 
            base.Initialize(name, config);
        }

        private void CheckSchemaVersion(SqlConnection connection) { 
            string[] features = { "Health Monitoring" };
            string   version  = "1"; 
            SecUtility.CheckSchemaVersion( this, connection, features, version, ref _SchemaVersionCheck ); 
        }
 
        public override void ProcessEventFlush(WebEventBufferFlushInfo flushInfo) {
            Debug.Trace("SqlWebEventProvider", "EventBufferFlush called: " +
                "NotificationType=" + flushInfo.NotificationType +
                ", NotificationSequence=" + flushInfo.NotificationSequence + 
                ", Events.Count=" + flushInfo.Events.Count);
 
            WriteToSQL(flushInfo.Events, flushInfo.EventsDiscardedSinceLastNotification, 
                flushInfo.LastNotificationUtc);
        } 

        void PrepareParams(SqlCommand sqlCommand) {
            sqlCommand.Parameters.Add(new SqlParameter("@EventId", SqlDbType.Char, 32));
            sqlCommand.Parameters.Add(new SqlParameter("@EventTimeUtc", SqlDbType.DateTime)); 
            sqlCommand.Parameters.Add(new SqlParameter("@EventTime", SqlDbType.DateTime));
            sqlCommand.Parameters.Add(new SqlParameter("@EventType", SqlDbType.NVarChar, 256)); 
            sqlCommand.Parameters.Add(new SqlParameter("@EventSequence", SqlDbType.Decimal)); 
            sqlCommand.Parameters.Add(new SqlParameter("@EventOccurrence", SqlDbType.Decimal));
            sqlCommand.Parameters.Add(new SqlParameter("@EventCode", SqlDbType.Int)); 
            sqlCommand.Parameters.Add(new SqlParameter("@EventDetailCode", SqlDbType.Int));
            sqlCommand.Parameters.Add(new SqlParameter("@Message", SqlDbType.NVarChar, 1024));
            sqlCommand.Parameters.Add(new SqlParameter("@ApplicationPath", SqlDbType.NVarChar, 256));
            sqlCommand.Parameters.Add(new SqlParameter("@ApplicationVirtualPath", SqlDbType.NVarChar, 256)); 
            sqlCommand.Parameters.Add(new SqlParameter("@MachineName", SqlDbType.NVarChar, 256));
            sqlCommand.Parameters.Add(new SqlParameter("@RequestUrl", SqlDbType.NVarChar, 1024)); 
            sqlCommand.Parameters.Add(new SqlParameter("@ExceptionType", SqlDbType.NVarChar, 256)); 
            sqlCommand.Parameters.Add(new SqlParameter("@Details", SqlDbType.NText));
        } 

        void FillParams(SqlCommand sqlCommand, WebBaseEvent eventRaised) {
            Exception               exception = null;
            WebRequestInformation   reqInfo = null; 
            string                  details = null;
            WebApplicationInformation   appInfo = WebBaseEvent.ApplicationInformation; 
            int                     n = 0; 

            sqlCommand.Parameters[n++].Value = eventRaised.EventID.ToString("N", CultureInfo.InstalledUICulture);   // @EventId 
            sqlCommand.Parameters[n++].Value = eventRaised.EventTimeUtc;      // @EventTimeUtc
            sqlCommand.Parameters[n++].Value = eventRaised.EventTime;         // @EventTime
            sqlCommand.Parameters[n++].Value = eventRaised.GetType().ToString();  // @EventType
            sqlCommand.Parameters[n++].Value = eventRaised.EventSequence;     // @EventSequence 
            sqlCommand.Parameters[n++].Value = eventRaised.EventOccurrence;     // @EventOccurrence
            sqlCommand.Parameters[n++].Value = eventRaised.EventCode;         // @EventCode 
            sqlCommand.Parameters[n++].Value = eventRaised.EventDetailCode;   // @EventDetailCode 
            sqlCommand.Parameters[n++].Value = eventRaised.Message;           // @Message
            sqlCommand.Parameters[n++].Value = appInfo.ApplicationPath;       // @ApplicationPath 
            sqlCommand.Parameters[n++].Value = appInfo.ApplicationVirtualPath; // @ApplicationVirtualPath
            sqlCommand.Parameters[n++].Value = appInfo.MachineName; // @MachineName

            // 

            // @RequestUrl 
            if (eventRaised is WebRequestEvent) { 
                reqInfo = ((WebRequestEvent)eventRaised).RequestInformation;
            } 
            else if (eventRaised is WebRequestErrorEvent) {
                reqInfo = ((WebRequestErrorEvent)eventRaised).RequestInformation;
            }
            else if (eventRaised is WebErrorEvent) { 
                reqInfo = ((WebErrorEvent)eventRaised).RequestInformation;
            } 
            else if (eventRaised is WebAuditEvent) { 
                reqInfo = ((WebAuditEvent)eventRaised).RequestInformation;
            } 
            sqlCommand.Parameters[n++].Value = (reqInfo != null) ? reqInfo.RequestUrl : Convert.DBNull;

            // @ExceptionType
            if (eventRaised is WebBaseErrorEvent) { 
                exception = ((WebBaseErrorEvent)eventRaised).ErrorException;
            } 
            sqlCommand.Parameters[n++].Value = (exception != null) ? exception.GetType().ToString() : Convert.DBNull; 

            // @Details 
            details = eventRaised.ToString();
            if (_maxEventDetailsLength != NO_LIMIT &&
                details.Length > _maxEventDetailsLength) {
                details = details.Substring(0, _maxEventDetailsLength); 
            }
            sqlCommand.Parameters[n++].Value = details; 
        } 

        [PermissionSet(SecurityAction.InheritanceDemand, Unrestricted = true)] 
        [SqlClientPermission(SecurityAction.Assert, Unrestricted = true)]
        [PermissionSet(SecurityAction.Assert, Unrestricted = true)]
        void WriteToSQL(WebBaseEventCollection events, int eventsDiscardedByBuffer, DateTime lastNotificationUtc) {
            // We don't want to send any more events until we've waited until the _retryDate (which defaults to minValue) 
            if (_retryDate > DateTime.UtcNow) {
                return; 
            } 

            try { 
                SqlConnectionHolder sqlConnHolder = SqlConnectionHelper.GetConnection(_sqlConnectionString, true);

                SqlCommand sqlCommand = new SqlCommand(SP_LOG_EVENT);
 
                CheckSchemaVersion(sqlConnHolder.Connection);
 
                sqlCommand.CommandType = CommandType.StoredProcedure; 
                sqlCommand.Connection = sqlConnHolder.Connection;
 
                if (_commandTimeout > -1) {
                    sqlCommand.CommandTimeout = _commandTimeout;
                }
 
                PrepareParams(sqlCommand);
 
                try { 
                    sqlConnHolder.Open(null, true);
                    Interlocked.Increment(ref _connectionCount); 

                    if (eventsDiscardedByBuffer != 0) {
                        WebBaseEvent infoEvent = new WebBaseEvent(
                            SR.GetString(SR.Sql_webevent_provider_events_dropped, 
                                eventsDiscardedByBuffer.ToString(CultureInfo.InstalledUICulture),
                                lastNotificationUtc.ToString("r", CultureInfo.InstalledUICulture)), 
                                null, 
                                WebEventCodes.WebEventProviderInformation,
                                WebEventCodes.SqlProviderEventsDropped); 

                        FillParams(sqlCommand, infoEvent);
                        sqlCommand.ExecuteNonQuery();
                    } 

                    foreach (WebBaseEvent eventRaised in events) { 
                        FillParams(sqlCommand, eventRaised); 
                        sqlCommand.ExecuteNonQuery();
                    } 
                }
#if DBG
                catch (Exception e) {
                    Debug.Trace("SqlWebEventProvider", "ExecuteNonQuery failed: " + e); 
                    throw;
                } 
#endif 
                finally {
                    sqlConnHolder.Close(); 
                    Interlocked.Decrement(ref _connectionCount);
                }

#if (!DBG) 
                try {
#endif 
                    EventProcessingComplete(events); 
#if (!DBG)
                } 
                catch {
                    // Ignore all errors.
                }
#endif 
            }
            catch { 
                // For any failure, we will wait at least 30 seconds or _commandTimeout before trying again 
                double timeout = 30;
                if (_commandTimeout > -1) { 
                    timeout = (double)_commandTimeout;
                }
                _retryDate = DateTime.UtcNow.AddSeconds(timeout);
                throw; 
            }
        } 
 
        public override void ProcessEvent(WebBaseEvent eventRaised)
        { 
            if (UseBuffering) {
                base.ProcessEvent(eventRaised);
            }
            else { 
                Debug.Trace("SqlWebEventProvider", "Writing event to SQL: event=" + eventRaised.GetType().Name);
                WriteToSQL(new WebBaseEventCollection(eventRaised), 0, new DateTime(0)); 
            } 
        }
 
        protected virtual void EventProcessingComplete(WebBaseEventCollection raisedEvents) {
        }

        public override void Shutdown() { 
            try {
                Flush(); 
            } 
            finally {
                base.Shutdown(); 
            }

            // VSWhidbey 531556: Need to wait until all connections are gone before returning here
            // Sleep for 2x the command timeout in 1 sec intervals then give up, default timeout is 30 sec 
            if (_connectionCount > 0) {
                int sleepAttempts = _commandTimeout*2; 
                if (sleepAttempts <= 0) { 
                    sleepAttempts = 60;
                } 
                // Check every second
                while (_connectionCount > 0 && sleepAttempts > 0) {
                    --sleepAttempts;
                    Thread.Sleep(1000); 
                }
            } 
        } 
    }
} 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK