internal bool CheckAndUpdate(WebBaseEvent eventRaised) { DateTime now = DateTime.Now; HealthMonitoringManager manager = HealthMonitoringManager.Manager(); int num = Interlocked.Increment(ref this._timesRaised); if (manager == null) { return(false); } if (this._ruleInfo._customEvaluatorType != null) { IWebEventCustomEvaluator evaluator = (IWebEventCustomEvaluator)manager._sectionHelper._customEvaluatorInstances[this._ruleInfo._customEvaluatorType]; try { eventRaised.PreProcessEventInit(); if (!evaluator.CanFire(eventRaised, this)) { return(false); } } catch { return(false); } } if (num < this._ruleInfo._minInstances) { return(false); } if (num > this._ruleInfo._maxLimit) { return(false); } if (this._ruleInfo._minInterval == TimeSpan.Zero) { this.UpdateLastFired(now, false); return(true); } if ((now - this._lastFired) <= this._ruleInfo._minInterval) { return(false); } lock (this) { if ((now - this._lastFired) <= this._ruleInfo._minInterval) { return(false); } this.UpdateLastFired(now, true); return(true); } }
internal bool CheckAndUpdate(WebBaseEvent eventRaised) { DateTime now = DateTime.Now; HealthMonitoringManager manager = HealthMonitoringManager.Manager(); int num = Interlocked.Increment(ref this._timesRaised); if (manager == null) { return false; } if (this._ruleInfo._customEvaluatorType != null) { IWebEventCustomEvaluator evaluator = (IWebEventCustomEvaluator) manager._sectionHelper._customEvaluatorInstances[this._ruleInfo._customEvaluatorType]; try { eventRaised.PreProcessEventInit(); if (!evaluator.CanFire(eventRaised, this)) { return false; } } catch { return false; } } if (num < this._ruleInfo._minInstances) { return false; } if (num > this._ruleInfo._maxLimit) { return false; } if (this._ruleInfo._minInterval == TimeSpan.Zero) { this.UpdateLastFired(now, false); return true; } if ((now - this._lastFired) <= this._ruleInfo._minInterval) { return false; } lock (this) { if ((now - this._lastFired) <= this._ruleInfo._minInterval) { return false; } this.UpdateLastFired(now, true); return true; } }
internal static void RaiseInternal(WebBaseEvent eventRaised, ArrayList firingRuleInfos, int index0, int index1) { bool flag = false; bool flag2 = false; ProcessImpersonationContext context = null; HttpContext current = HttpContext.Current; object data = CallContext.GetData("_WEvtRIP"); if ((data == null) || !((bool)data)) { eventRaised.IncrementPerfCounters(); eventRaised.IncrementTotalCounters(index0, index1); if (firingRuleInfos == null) { firingRuleInfos = HealthMonitoringManager.Manager()._sectionHelper.FindFiringRuleInfos(eventRaised.GetType(), eventRaised.EventCode); } if (firingRuleInfos.Count != 0) { try { bool[] flagArray = null; if (EtwTrace.IsTraceEnabled(5, 1) && (current != null)) { EtwTrace.Trace(EtwTraceType.ETW_TYPE_WEB_EVENT_RAISE_START, current.WorkerRequest, eventRaised.GetType().FullName, eventRaised.EventCode.ToString(CultureInfo.InstalledUICulture), eventRaised.EventDetailCode.ToString(CultureInfo.InstalledUICulture), null); } try { foreach (HealthMonitoringSectionHelper.FiringRuleInfo info in firingRuleInfos) { HealthMonitoringSectionHelper.RuleInfo info2 = info._ruleInfo; if (info2._ruleFiringRecord.CheckAndUpdate(eventRaised) && (info2._referencedProvider != null)) { if (!flag) { eventRaised.PreProcessEventInit(); flag = true; } if (info._indexOfFirstRuleInfoWithSameProvider != -1) { if (flagArray == null) { flagArray = new bool[firingRuleInfos.Count]; } if (flagArray[info._indexOfFirstRuleInfoWithSameProvider]) { continue; } flagArray[info._indexOfFirstRuleInfoWithSameProvider] = true; } if (EtwTrace.IsTraceEnabled(5, 1) && (current != null)) { EtwTrace.Trace(EtwTraceType.ETW_TYPE_WEB_EVENT_DELIVER_START, current.WorkerRequest, info2._ruleSettings.Provider, info2._ruleSettings.Name, info2._ruleSettings.EventName, null); } try { if (context == null) { context = new ProcessImpersonationContext(); } if (!flag2) { CallContext.SetData("_WEvtRIP", true); flag2 = true; } info2._referencedProvider.ProcessEvent(eventRaised); } catch (Exception exception) { try { info2._referencedProvider.LogException(exception); } catch { } } finally { if (EtwTrace.IsTraceEnabled(5, 1) && (current != null)) { EtwTrace.Trace(EtwTraceType.ETW_TYPE_WEB_EVENT_DELIVER_END, current.WorkerRequest); } } } } } finally { if (context != null) { context.Undo(); } if (flag2) { CallContext.FreeNamedDataSlot("_WEvtRIP"); } if (EtwTrace.IsTraceEnabled(5, 1) && (current != null)) { EtwTrace.Trace(EtwTraceType.ETW_TYPE_WEB_EVENT_RAISE_END, current.WorkerRequest); } } } catch { throw; } } } }
internal static void RaiseInternal(WebBaseEvent eventRaised, ArrayList firingRuleInfos, int index0, int index1) { bool flag = false; bool flag2 = false; ProcessImpersonationContext context = null; HttpContext current = HttpContext.Current; object data = CallContext.GetData("_WEvtRIP"); if ((data == null) || !((bool) data)) { eventRaised.IncrementPerfCounters(); eventRaised.IncrementTotalCounters(index0, index1); if (firingRuleInfos == null) { firingRuleInfos = HealthMonitoringManager.Manager()._sectionHelper.FindFiringRuleInfos(eventRaised.GetType(), eventRaised.EventCode); } if (firingRuleInfos.Count != 0) { try { bool[] flagArray = null; if (EtwTrace.IsTraceEnabled(5, 1) && (current != null)) { EtwTrace.Trace(EtwTraceType.ETW_TYPE_WEB_EVENT_RAISE_START, current.WorkerRequest, eventRaised.GetType().FullName, eventRaised.EventCode.ToString(CultureInfo.InstalledUICulture), eventRaised.EventDetailCode.ToString(CultureInfo.InstalledUICulture), null); } try { foreach (HealthMonitoringSectionHelper.FiringRuleInfo info in firingRuleInfos) { HealthMonitoringSectionHelper.RuleInfo info2 = info._ruleInfo; if (info2._ruleFiringRecord.CheckAndUpdate(eventRaised) && (info2._referencedProvider != null)) { if (!flag) { eventRaised.PreProcessEventInit(); flag = true; } if (info._indexOfFirstRuleInfoWithSameProvider != -1) { if (flagArray == null) { flagArray = new bool[firingRuleInfos.Count]; } if (flagArray[info._indexOfFirstRuleInfoWithSameProvider]) { continue; } flagArray[info._indexOfFirstRuleInfoWithSameProvider] = true; } if (EtwTrace.IsTraceEnabled(5, 1) && (current != null)) { EtwTrace.Trace(EtwTraceType.ETW_TYPE_WEB_EVENT_DELIVER_START, current.WorkerRequest, info2._ruleSettings.Provider, info2._ruleSettings.Name, info2._ruleSettings.EventName, null); } try { if (context == null) { context = new ProcessImpersonationContext(); } if (!flag2) { CallContext.SetData("_WEvtRIP", true); flag2 = true; } info2._referencedProvider.ProcessEvent(eventRaised); } catch (Exception exception) { try { info2._referencedProvider.LogException(exception); } catch { } } finally { if (EtwTrace.IsTraceEnabled(5, 1) && (current != null)) { EtwTrace.Trace(EtwTraceType.ETW_TYPE_WEB_EVENT_DELIVER_END, current.WorkerRequest); } } } } } finally { if (context != null) { context.Undo(); } if (flag2) { CallContext.FreeNamedDataSlot("_WEvtRIP"); } if (EtwTrace.IsTraceEnabled(5, 1) && (current != null)) { EtwTrace.Trace(EtwTraceType.ETW_TYPE_WEB_EVENT_RAISE_END, current.WorkerRequest); } } } catch { throw; } } } }
static internal void RaiseInternal(WebBaseEvent eventRaised, ArrayList firingRuleInfos, int index0, int index1) { bool preProcessEventInitCalled = false; bool inProgressSet = false; object o; ProcessImpersonationContext ictx = null; HttpContext context = HttpContext.Current; Debug.Trace( "WebEventRaiseDetails", "Event is raised; event class = " + eventRaised.GetType().Name); // Use CallContext to make sure we detect an infinite loop where a provider calls Raise(). o = CallContext.GetData(WEBEVENT_RAISE_IN_PROGRESS); if (o != null && (bool)o) { Debug.Trace( "WebEventRaiseDetails", "An event is raised while we're raising an event. Ignore it."); return; } eventRaised.IncrementPerfCounters(); eventRaised.IncrementTotalCounters(index0, index1); // Find the list of rules that match this event if (firingRuleInfos == null) { HealthMonitoringManager manager = HealthMonitoringManager.Manager(); Debug.Assert(manager != null, "manager != null"); firingRuleInfos = manager._sectionHelper.FindFiringRuleInfos(eventRaised.GetType(), eventRaised.EventCode); } if (firingRuleInfos.Count == 0) { return; } try { bool[] matchingProviderArray = null; if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure) && context != null) EtwTrace.Trace(EtwTraceType.ETW_TYPE_WEB_EVENT_RAISE_START, context.WorkerRequest, eventRaised.GetType().FullName, eventRaised.EventCode.ToString(CultureInfo.InstalledUICulture), eventRaised.EventDetailCode.ToString(CultureInfo.InstalledUICulture), null); try { foreach (HealthMonitoringSectionHelper.FiringRuleInfo firingRuleInfo in firingRuleInfos) { HealthMonitoringSectionHelper.RuleInfo ruleInfo = firingRuleInfo._ruleInfo; RuleFiringRecord record = ruleInfo._ruleFiringRecord; // Check if we should fire the event based on its throttling settings if (!record.CheckAndUpdate(eventRaised)) { Debug.Trace("WebEventRaiseDetails", "Throttling settings not met; not fired"); continue; } // It's valid for a rule to have no referenced provider if (ruleInfo._referencedProvider != null) { if (!preProcessEventInitCalled) { // The event may need to do pre-ProcessEvent initialization eventRaised.PreProcessEventInit(); preProcessEventInitCalled = true; } // For rule infos that share the same provider, the _indexOfFirstRuleInfoWithSameProvider field // is the index of the first ruleInfo among them. We use that index in the boolean array // matchingProviderArray to remember if we've already fired that provider. // This is for the scenario where several rules are pointing to the same provider, // and even if >1 rule actually fire and pass all throttling check, // the provider is stilled fired only once. if (firingRuleInfo._indexOfFirstRuleInfoWithSameProvider != -1) { if (matchingProviderArray == null) { matchingProviderArray = new bool[firingRuleInfos.Count]; } if (matchingProviderArray[firingRuleInfo._indexOfFirstRuleInfoWithSameProvider]) { Debug.Trace("WebEventRaiseDetails", "Rule with a matching provider already fired."); continue; } matchingProviderArray[firingRuleInfo._indexOfFirstRuleInfoWithSameProvider] = true; } if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure) && context != null) EtwTrace.Trace(EtwTraceType.ETW_TYPE_WEB_EVENT_DELIVER_START, context.WorkerRequest, ruleInfo._ruleSettings.Provider, ruleInfo._ruleSettings.Name, ruleInfo._ruleSettings.EventName, null); // In retail build, ignore errors from provider try { if (ictx == null) { ictx = new ProcessImpersonationContext(); } if (!inProgressSet) { CallContext.SetData(WEBEVENT_RAISE_IN_PROGRESS, true); inProgressSet = true; } Debug.Trace("WebEventRaiseDetails", "Calling ProcessEvent under " + HttpApplication.GetCurrentWindowsIdentityWithAssert().Name); ruleInfo._referencedProvider.ProcessEvent(eventRaised); } catch (Exception e) { try { ruleInfo._referencedProvider.LogException(e); } catch { // ignore all errors } } finally { if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure) && context != null) EtwTrace.Trace(EtwTraceType.ETW_TYPE_WEB_EVENT_DELIVER_END, context.WorkerRequest); } } } } finally { // Resume client impersonation if (ictx != null) { ictx.Undo(); } if (inProgressSet) { CallContext.FreeNamedDataSlot(WEBEVENT_RAISE_IN_PROGRESS); } if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure) && context != null) EtwTrace.Trace(EtwTraceType.ETW_TYPE_WEB_EVENT_RAISE_END, context.WorkerRequest); } } catch { throw; } // Prevent Exception Filter Security Issue (ASURT 122835) }
// Note: this method is thread safe internal bool CheckAndUpdate(WebBaseEvent eventRaised) { DateTime now = DateTime.Now; int timesRaised; HealthMonitoringManager manager = HealthMonitoringManager.Manager(); timesRaised = Interlocked.Increment(ref _timesRaised); if (manager == null) { // Won't fire because we cannot configure healthmonitor Debug.Trace("RuleFiringRecord", "Can't configure healthmonitor"); return false; } // Call custom evaluator first if (_ruleInfo._customEvaluatorType != null) { IWebEventCustomEvaluator icustom = (IWebEventCustomEvaluator) manager._sectionHelper._customEvaluatorInstances[_ruleInfo._customEvaluatorType]; #if (!DBG) try { #endif // The event may need to do pre-ProcessEvent initialization eventRaised.PreProcessEventInit(); if (!icustom.CanFire(eventRaised, this)) { Debug.Trace("RuleFiringRecord", "Custom evaluator returns false."); return false; } #if (!DBG) } catch { Debug.Trace("RuleFiringRecord", "Hit an exception when calling Custom evaluator"); // Return if we hit an error return false; } #endif } if (timesRaised < _ruleInfo._minInstances) { Debug.Trace("RuleFiringRecord", "MinInterval not met; timesRaised=" + timesRaised + "; _minInstances=" + _ruleInfo._minInstances); return false; } if (timesRaised > _ruleInfo._maxLimit) { Debug.Trace("RuleFiringRecord", "MaxLimit exceeded; timesRaised=" + timesRaised + "; _maxLimit=" + _ruleInfo._maxLimit); return false; } // Last step: Check MinInterval and update _lastFired if (_ruleInfo._minInterval == TimeSpan.Zero) { UpdateLastFired(now, false); return true; } if ((now - _lastFired) <= _ruleInfo._minInterval) { Debug.Trace("RuleFiringRecord", "MinInterval not met; now=" + now + "; _lastFired=" + _lastFired + "; _ruleInfo._minInterval=" + _ruleInfo._minInterval); return false; } // The lock is to prevent multiple threads from passing the // same test simultaneously. lock (this) { if ((now - _lastFired) <= _ruleInfo._minInterval) { Debug.Trace("RuleFiringRecord", "MinInterval not met; now=" + now + "; _lastFired=" + _lastFired + "; _ruleInfo._tsMinInterval=" + _ruleInfo._minInterval); return false; } UpdateLastFired(now, true); return true; } }