通过Web应用程序创建自定义计数器
时间:2020-03-05 18:51:29 来源:igfitidea点击:
我有一个.NET 3.5 Web应用程序,为此我实现了一个称为CalculationsCounterManager的类(下面的代码)。此类具有一些共享/静态成员,这些成员管理两个自定义性能计数器的创建和递增,该两个自定义性能计数器监视对SQL Server数据库的数据调用。如果不存在,则执行这些数据调用将驱动计数器的创建。当然,通过此类的nUnit GUI执行的单元测试,一切都可以正常工作。计数器被创建并逐渐增加。
但是,当通过ASPNET工作进程执行相同的代码时,会出现以下错误消息:"不允许请求的注册表访问。"。进行读取以检查计数器类别是否已存在时,在CalculationsCounterManager类的第44行上会发生此错误。
有谁知道一种为工作进程帐户提供足够特权的方法,以便允许它在生产环境中创建计数器而又不会使服务器面临安全问题?
Namespace eA.Analytics.DataLayer.PerformanceMetrics ''' <summary> ''' Manages performance counters for the calculatioins data layer assembly ''' </summary> ''' <remarks>GAJ 09/10/08 - Initial coding and testing</remarks> Public Class CalculationCounterManager Private Shared _AvgRetrieval As PerformanceCounter Private Shared _TotalRequests As PerformanceCounter Private Shared _ManagerInitialized As Boolean Private Shared _SW As Stopwatch ''' <summary> ''' Creates/recreates the perf. counters if they don't exist ''' </summary> ''' <param name="recreate"></param> ''' <remarks></remarks> Public Shared Sub SetupCalculationsCounters(ByVal recreate As Boolean) If PerformanceCounterCategory.Exists(CollectionSettings.CalculationMetricsCollectionName) = False Or recreate = True Then Dim AvgCalcsProductRetrieval As New CounterCreationData(CounterSettings.AvgProductRetrievalTimeCounterName, _ CounterSettings.AvgProductRetrievalTimeCounterHelp, _ CounterSettings.AvgProductRetrievalTimeCounterType) Dim TotalCalcsProductRetrievalRequests As New CounterCreationData(CounterSettings.TotalRequestsCounterName, _ CounterSettings.AvgProductRetrievalTimeCounterHelp, _ CounterSettings.TotalRequestsCounterType) Dim CounterData As New CounterCreationDataCollection() ' Add counters to the collection. CounterData.Add(AvgCalcsProductRetrieval) CounterData.Add(TotalCalcsProductRetrievalRequests) If recreate = True Then If PerformanceCounterCategory.Exists(CollectionSettings.CalculationMetricsCollectionName) = True Then PerformanceCounterCategory.Delete(CollectionSettings.CalculationMetricsCollectionName) End If End If If PerformanceCounterCategory.Exists(CollectionSettings.CalculationMetricsCollectionName) = False Then PerformanceCounterCategory.Create(CollectionSettings.CalculationMetricsCollectionName, CollectionSettings.CalculationMetricsDescription, _ PerformanceCounterCategoryType.SingleInstance, CounterData) End If End If _AvgRetrieval = New PerformanceCounter(CollectionSettings.CalculationMetricsCollectionName, CounterSettings.AvgProductRetrievalTimeCounterName, False) _TotalRequests = New PerformanceCounter(CollectionSettings.CalculationMetricsCollectionName, CounterSettings.TotalRequestsCounterName, False) _ManagerInitialized = True End Sub Public Shared ReadOnly Property CategoryName() As String Get Return CollectionSettings.CalculationMetricsCollectionName End Get End Property ''' <summary> ''' Determines if the performance counters have been initialized ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> Public Shared ReadOnly Property ManagerInitializaed() As Boolean Get Return _ManagerInitialized End Get End Property Public Shared ReadOnly Property AvgRetrieval() As PerformanceCounter Get Return _AvgRetrieval End Get End Property Public Shared ReadOnly Property TotalRequests() As PerformanceCounter Get Return _TotalRequests End Get End Property ''' <summary> ''' Initializes the Average Retrieval Time counter by starting a stopwatch ''' </summary> ''' <remarks></remarks> Public Shared Sub BeginIncrementAvgRetrieval() If _SW Is Nothing Then _SW = New Stopwatch End If _SW.Start() End Sub ''' <summary> ''' Increments the Average Retrieval Time counter by stopping the stopwatch and changing the ''' raw value of the perf counter. ''' </summary> ''' <remarks></remarks> Public Shared Sub EndIncrementAvgRetrieval(ByVal resetStopwatch As Boolean, ByVal outputToTrace As Boolean) _SW.Stop() _AvgRetrieval.RawValue = CLng(_SW.ElapsedMilliseconds) If outPutToTrace = True Then Trace.WriteLine(_AvgRetrieval.NextValue.ToString) End If If resetStopwatch = True Then _SW.Reset() End If End Sub ''' <summary> ''' Increments the total requests counter ''' </summary> ''' <remarks></remarks> Public Shared Sub IncrementTotalRequests() _TotalRequests.IncrementBy(1) End Sub Public Shared Sub DeleteAll() If PerformanceCounterCategory.Exists(CollectionSettings.CalculationMetricsCollectionName) = True Then PerformanceCounterCategory.Delete(CollectionSettings.CalculationMetricsCollectionName) End If End Sub End Class End Namespace
解决方案
回答
是的,不可能。我们不能在工作进程中添加特权,而无需在生产环境中打开服务器以解决潜在的安全性/ DOS问题。安装程序(如MSI)通常以提升的权限运行,并安装/卸载性能计数器类别和计数器以及其他锁定的对象。
例如,Windows Installer XML(WiX)支持性能计数器。