繁体   English   中英

在Y秒内监控任何进程的CPU峰值超过X%

[英]Monitor CPU spikes of any process over X percent for Y seconds

我想在Windows Server 2008框上运行一个.NET控制台应用程序,该程序每2秒监视一次CPU使用率。

如果任何单个应用程序连续两次使用CPU> 30%,则应对其进行记录。

我将每2秒执行一次“ CheckCpu” ...但是我的问题是, 如何确定每个进程的CPU使用率? 而且,有效地使我不会停滞我们的服务器:)

Dim lStrProcessCurrent As List(Of String)
Dim lStrProcessPrevious As List(Of String)

Private Sub CheckCpu()

    Dim pcc As New PerformanceCounterCategory("Process")

    'Clear "Current" run
    lStrProcessCurrent = New List(Of String)

    For Each instance As String In pcc.GetInstanceNames
        Using cnt As PerformanceCounter = New PerformanceCounter("Process", "ID Process", instance, True)

            Dim processName As String = cnt.InstanceName

 ' ?????  HOW TO DETERMINE CPU USAGE   ????
            Dim cpuUsage As Long = 31

            If cpuUsage >= 30 Then

                'Was over 30% in Previous check
                If lStrProcessPrevious.Contains(processName) Then
                    LogCpuSpike(processName)
                End If

                lStrProcessCurrent.Add(processName)
            End If

        End Using
    Next

    'Update "Previous" run
    lStrProcessPrevious = lStrProcessCurrent

End Sub

您可以尝试以下代码。 实际上,每次调用CheckCpu()时都要检查每个进程的TotalProcessorTime,然后从上一次运行中减去该时间,然后除以两次检查之间经过的总时间。

Sub Main()

    Dim previousCheckTime As New DateTime
    Dim previousProcessList As New List(Of ProcessInformation)

    ' Kick off an initial check
    previousCheckTime = Now
    previousProcessList = CheckCPU(previousProcessList, Nothing)

    For i As Integer = 0 To 10
        Threading.Thread.Sleep(1000)

        previousProcessList = CheckCPU(previousProcessList, Now - previousCheckTime)
        previousCheckTime = Now

        For Each process As ProcessInformation In previousProcessList
            Console.WriteLine(process.Id & " - " & Math.Round(process.CpuUsage, 2).ToString & "%")
        Next
        Console.WriteLine("-- Next check --")
    Next

    Console.ReadLine()
End Sub

Private Function CheckCPU(previousProcessList As List(Of ProcessInformation), timeSinceLastCheck As TimeSpan) As List(Of ProcessInformation)

    Dim currentProcessList As New List(Of ProcessInformation)
    For Each process As Process In Process.GetProcesses()

        ' Id = 0 is the system idle process so we don't check that
        If process.Id <> 0 Then

            ' See if this process existed last time we checked
            Dim cpuUsage As Double = -1
            Dim previousProcess As ProcessInformation = previousProcessList.SingleOrDefault(Function(p) p.Id = process.Id)

            ' If it did then we can calculate the % of CPU time it has consumed
            If previousProcess IsNot Nothing AndAlso timeSinceLastCheck <> Nothing Then
                cpuUsage = ((process.TotalProcessorTime - previousProcess.TotalProcessorTime).Ticks / (Environment.ProcessorCount * timeSinceLastCheck.Ticks)) * 100
            End If

            ' Add to the current process list
            currentProcessList.Add(New ProcessInformation With {.Id = process.Id, .CpuUsage = cpuUsage, .TotalProcessorTime = process.TotalProcessorTime})
        End If

    Next

    Return currentProcessList

End Function

Class ProcessInformation
    Public Id As Integer
    Public TotalProcessorTime As TimeSpan
    Public CpuUsage As Double
End Class

在生产环境中,您可能应该添加更多检查,因为在调用GetProcesses()然后处理列表之间可能会杀死某个进程。 如果该进程已消失,那么当您尝试访问TotalProcessorTime属性时将收到错误消息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM