Code:
/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / xsp / System / Web / Management / SqlWebEventProvider.cs / 2 / 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)]
[AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
[AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
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)]
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);
}
}
}
}
}
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XmlAnyElementAttribute.cs
- ArrangedElement.cs
- TreeNodeStyleCollectionEditor.cs
- ReferenceConverter.cs
- ContentPathSegment.cs
- CodeDomLoader.cs
- FrameworkEventSource.cs
- VirtualPath.cs
- ImageAnimator.cs
- ValidationSummary.cs
- Size.cs
- DataTableReader.cs
- NonSerializedAttribute.cs
- HttpTransportSecurityElement.cs
- DataGridViewElement.cs
- FilteredXmlReader.cs
- JpegBitmapEncoder.cs
- Int32CollectionValueSerializer.cs
- FirstMatchCodeGroup.cs
- HtmlAnchor.cs
- TransformProviderWrapper.cs
- TextDecorations.cs
- SoapExtensionTypeElementCollection.cs
- RoleManagerModule.cs
- ProgressPage.cs
- SlipBehavior.cs
- RegexCapture.cs
- XmlIlVisitor.cs
- WebPartZoneCollection.cs
- LayoutTableCell.cs
- SymmetricKey.cs
- LayoutManager.cs
- CacheModeConverter.cs
- ActivityXRefConverter.cs
- FrameworkContextData.cs
- SystemKeyConverter.cs
- IDReferencePropertyAttribute.cs
- XsltInput.cs
- PreloadedPackages.cs
- HttpVersion.cs
- WindowInteractionStateTracker.cs
- EntitySetRetriever.cs
- SQLBytesStorage.cs
- BuildManagerHost.cs
- WsatConfiguration.cs
- CroppedBitmap.cs
- EntityWrapperFactory.cs
- PathFigure.cs
- TypePropertyEditor.cs
- FieldDescriptor.cs
- ListViewItemMouseHoverEvent.cs
- ValueExpressions.cs
- StringUtil.cs
- SchemaElementLookUpTableEnumerator.cs
- CacheDependency.cs
- Choices.cs
- AppearanceEditorPart.cs
- ChangeBlockUndoRecord.cs
- MaterialGroup.cs
- TextEditorThreadLocalStore.cs
- RequestQueue.cs
- DesignTimeVisibleAttribute.cs
- WorkerRequest.cs
- XslException.cs
- BoundColumn.cs
- ChangePassword.cs
- DataGridViewCellStyleBuilderDialog.cs
- AuthorizationBehavior.cs
- WebPartMinimizeVerb.cs
- GeneralTransform.cs
- RegexCode.cs
- TrackingExtract.cs
- DependencyObject.cs
- BlurBitmapEffect.cs
- BlurBitmapEffect.cs
- Drawing.cs
- UnsafeNativeMethods.cs
- DefinitionBase.cs
- xmlsaver.cs
- AdornerLayer.cs
- HwndHost.cs
- SafeArrayTypeMismatchException.cs
- GPPOINT.cs
- CollectionViewGroupInternal.cs
- BitmapInitialize.cs
- ToolStripSplitStackLayout.cs
- PassportAuthenticationEventArgs.cs
- Light.cs
- ValueUtilsSmi.cs
- WorkflowLayouts.cs
- DefinitionBase.cs
- DrawingServices.cs
- SizeF.cs
- ToolStripDropDownItem.cs
- PropertyInformation.cs
- WorkflowRuntimeElement.cs
- SemanticTag.cs
- Clipboard.cs
- SizeKeyFrameCollection.cs
- NamespaceDisplayAutomationPeer.cs