通过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)支持性能计数器。