我有一些java组件有时会死掉,我知道的唯一方法是当用户抱怨他们得到了一个错误。
我在我们的监控系统上所做的就是计算在服务器上运行的java进程的数量。如果一个组件死了,我就会收到java阈值低于正常的警报,我就会登录找出哪个java组件死了。它可以工作,但我认为它可以细化到哪个组件死了,并能够远程启动java进程。
所以我在想的是写一个Powershell脚本,从监控系统中执行。我想我已经掌握了大部分的'one liner‘,但我需要更多的帮助来帮助我到达终点线,因为我认为这个脚本不需要详细说明。
到目前为止,我所拥有的是:
$theProcess = Get-WmiObject win32_process -Filter "name like '%java%'" | select commandLine此命令的输出提供了发送到JVM的所有参数,包括组件的名称,让我们将组件称为"COMP_Number1",通常有5个java组件进程在运行,因此组件的名称为"COMP_Number2“、"COMP_Number3”等等。
我的问题是:给定$theProcess的输出,如何检查所有java进程以验证所有组件是否都在运行?如果不是,哪一个没有运行?
非常感谢!
TT
发布于 2011-10-21 23:47:37
你可以这样做:
$components = @("COMP_Number1","COMP_Number2")
$theProcess | %{
$p = $_
$running = $components | ?{$p.commandline -match $_}
$notrunning = $components | ?{ $running -notcontains $_ }
}
$notrunning发布于 2011-10-22 12:56:13
如果可以在服务器上使用WMI,则可以使用WMI事件来检测已停止的进程。
Register-WMIEvent -Query "SELECT * FROM Win32_ProcessStopTrace WHERE ProcessName like 'notepad%'" -Action {Write-Host "kind of notepad process is died"; Write-Host $args}在这里,您将检测到notepad.exe die和notepad++.exe。
您可以使用Get-EventSubscriber检索您要取消的事件,使用Unregister-Event取消您要取消的事件。
脚本块被视为一个作业,因此要小心地导入其中所需的所有模块。
脚本块接收两个参数:
1) System.Management.ManagementEventWatcher
2) System.Management.EventArrivedEventArgs
以下是$args[1].newevent的参数:
ExitStatus Property System.UInt32 ExitStatus {get;set;}
ParentProcessID Property System.UInt32 ParentProcessID {get;set;}
ProcessID Property System.UInt32 ProcessID {get;set;}
ProcessName Property System.String ProcessName {get;set;}
SECURITY_DESCRIPTOR Property System.Byte[] SECURITY_DESCRIPTOR {get;set;}
SessionID Property System.UInt32 SessionID {get;set;}
Sid Property System.Byte[] Sid {get;set;}例如:
Register-WMIEvent -Query "SELECT * FROM Win32_ProcessStopTrace WHERE ProcessName like 'notepad%'" -Action {Write-Host "$($args[1].newevent.ProcessName) process is died"}发布于 2011-10-22 00:08:09
$components = @("COMP_Number1","COMP_Number2")
$running = @()
do {
Get-WmiObject win32_process -Filter "name like '%java%'" | select commandLine | Foreach-Object {
$running += ($_.commandLine -replace ".*(COMP_Number\d).*",'$1')
}
if ($running.Count -lt $components.Count) {
Compare-Object ($running | Sort-Object) ($components | Sort-Object)
}
$running = @()
Start-Sleep 50000
} until (1 -lt 0)regexp肯定需要改进。您可以添加一些其他警告方法(电子邮件?)或者甚至尝试自动重新启动if语句中丢失的进程。
https://stackoverflow.com/questions/7851401
复制相似问题