我有一组powershell脚本,用于管理Windows服务器的启动过程。在某个时刻,powershell启动tomcat服务器。tomcat被设置为windows服务,并使用net start
启动。一旦命令返回,tomcat就会启动,但不会启动应用程序。该应用程序还需要15-30分钟才能启动。
确定它已启动的方法是检查日志文件并查看行";服务器启动成功";。请注意,由于较早的重新启动,该行可能已存在于文件中。
另一种方法(不太可靠(是在相应的端口号上向localhost发送https请求,并检查响应的实际内容。与之相关的还有一些单独的问题,特别是访问localhost时的HTTP证书错误,以及在某些情况下,即使是正确的响应也不能保证应用程序完全启动的事实。
在继续执行下一个任务之前,如何从powershell确定应用程序已完全启动?
一个选项是将日志文件在开始之前和之后的内容与do-intile循环进行比较,并在找到字符串后继续脚本:
$beforestart = Get-Content -Path C:pathtotomcat.log
net start ...
do
{
Start-Sleep -Seconds 3
$afterstart = Get-Content -Path C:pathtotomcat.log
$compare = Compare-Object $beforestart $afterstart
}
until ($compare -match 'Server startup successful')
正如automateorder所评论的,如果行有时间戳,则可以使用这些时间戳来确定条目的顺序。
您可以考虑的另一个选项是Select-String
。每个匹配都将附带一个行号。由于您还没有提供示例日志数据,我将补充一些。你说";服务器启动成功";用于启动应用程序。我添加了";服务启动成功";在本例中作为服务的条目。
伪造的示例日志我添加了两个条目,每个条目模拟以前的服务/应用程序启动。
$logfile = 'c:tempapache-test.log'
@'
Service start successful
some other logging
more logging
not important
Server startup successful
Service start successful
some other logging
more logging
not important
Server startup successful
'@ | Out-File $logfile -Encoding utf8
在这里,我们将为每个活动进行最后一场比赛。它们将被分配给每个相应的变量。
$service,$application = 'Service start successful','Server startup successful' | foreach {
Select-String -Path $logfile -Pattern $_ | select -Last 1
}
每个可变的内容
$service
C:tempapache-test.log:6:Service start successful
$application
C:tempapache-test.log:10:Server startup successful
现在,我们只需检查应用程序行号是否大于服务行号,即可确认应用程序已启动。
if($application.linenumber -gt $service.linenumber){"Application started successfully"}
您可以模拟一个测试,其中日志是新的,并且只包含服务启动消息。
@'
Service start successful
some other logging
more logging
not important
'@ | Out-File $logfile -Encoding utf8
$service,$application = 'Service start successful','Server startup successful' | foreach {
Select-String -Path $logfile -Pattern $_ | select -Last 1
}
if($application.linenumber -gt $service.linenumber){"Application started successfully"}
除非你在严格模式下运行,否则你不会得到任何错误,当然还有消息";应用程序成功启动";(或确认后运行的任何程序(将不会执行。
编辑:
就速度而言,Select-String
在较大文件上的速度将比Get-Content
快得多。您将需要在您的环境中进行测试,以查看它的运行速度。如果要缩小正在测试的文本的大小,可以选择使用Get-Content
的-Tail
参数。例如,您可以只获取日志文件的最后100行,并对此进行测试。
$tempfile = New-TemporaryFile
Get-Content -Tail 100 $logfile | Out-File $tempfile -Encoding utf8
$service,$application = 'Service start successful','Server startup successful' | foreach {
Select-String -path $tempfile -Pattern $_ | select -Last 1
}
if($application.linenumber -gt $service.linenumber){"Application started successfully"}