监视特定模式的日志文件

时间:2013-06-23 13:00:30

标签: regex windows batch-file cmd findstr

我正在尝试编写一个批处理文件来监视一行中“rdy”一词的日志文件,并警告rdy的值是否小于200

从我的日志文件中提取如下:

[Sun Jun 23 11:00:00 2013] [notice] mpmstats: rdy 249 bsy 1 rd 0 wr 1 ka 0 log 0 dns 0 cls 0
[Sun Jun 23 11:00:02 2013] [error] [client 10.25.134.1] File does not exist: E:/htdocs/default/KeepAlive.html

我编写了一个基本脚本(Still on my L's),它监视特定目录中的error.log文件。问题是有多天的错误日志,我想监视当前的错误日志。

@echo off

set log=E:\scripts\busycheckalert.log
set Time=%time:~0,5%
set Today=%date:~4,2%
set Month=%date:~7,2%
set Year=%date:~12,2%
set file=E:\logs\ihs\Default\error.log.%Month%.%Today%.%Year%

echo Polling %file% at %Time% >> %log%
for /f "usebackq delims=;" %%a in (`dir /b   E:\logs\ihs\Default\error.log.%Month%.%Today%.%Year%`) do (
    echo Checking now >> %log%
    for /f "tokens=8,9 delims= " %%a in     (E:\logs\ihs\Default\error.log.%Month%.%Today%.%Year%) do (
        echo Doing Checks >> %log%
        if %%j LEQ 200 echo %Today%-%Month%-%Year% at %Time% Error - Ready threshold exceeded >> %log% in %%a ))

我设法直到第一个检查点“立即检查”。但是,它似乎没有进入第二个循环。

这是结果日志文件的摘录:

Polling E:\logs\ihs\Default\error.log.06.23.13 at 22:48 
Checking now 
Polling E:\logs\ihs\Default\error.log.06.23.13 at 22:49 
Checking now 
Polling E:\logs\ihs\Default\error.log.06.23.13 at 22:50 
Checking now 

你能告诉我哪里出错吗?任何帮助都会很棒。

由于

4 个答案:

答案 0 :(得分:2)

The issue is there are error logs from multiple days and I want to monitor the current error log.

for /f "delims=" %%a in (' dir /b /a-d /od *.log ') do set "latest_file=%%a"

我现在收集到这不是你的目标。

您似乎使用与正在处理的文件相同的日志文件名。

你有delims =;哪里没有;在您的日志片段中。

您正在两个循环中重复使用%% a。

set file=E:\logs\ihs\Default\error.log.%Month%.%Today%.%Year%

echo Polling %file% at %Time% >> %log%
for /f "usebackq delims=;" %%a in (`dir /b   E:\logs\ihs\Default\error.log.%Month%.%Today%.%Year%`) do (
    echo Checking now >> %log%
    for /f "tokens=8,9 delims= " %%a in     (E:\logs\ihs\Default\error.log.%Month%.%Today%.%Year%) do (

答案 1 :(得分:2)

for /f "tokens=8,9 delims= " %%a in     (E:\logs\ihs\Default error.log.%Month%.%Today%.%Year%) do (

嗯 - 现在我想知道如果你要将%%a改为%%i会怎么样?

您似乎也没有检查%%i == rdy。如果你不这样做,你可能会得到一些相当奇怪的结果。

答案 2 :(得分:2)

建议使用GNUWin32 的代码:

@echo off & setlocal
set "cTime=%time:~0,5%"
set "Today=%date:~3,2%"
set "Month=%date:~6,2%"
set "Year=%date:~11,2%"
set "file=E:\logs\ihs\Default\error.log.%Month%.%Today%.%Year%"
SET "log=resultant.log"

echo Polling %file% at %Time% >> "%log%"
for /f "delims=" %%a in ('dir /b /a-d "%file%') do (
     echo Checking now >> "%log%"
     for /f "tokens=3" %%b IN ('grep -o "mpmstats: rdy [0-9]\+" "%file%"') do SET "rdy=%%b"
     echo Doing Checks >> "%log%"
     SETLOCAL ENABLEDELAYEDEXPANSION
     if !rdy! LEQ 200 echo %Today%-%Month%-%Year% at %cTime% Error - Ready threshold exceeded IN %%a >> "%log%"
     endlocal
)

答案 3 :(得分:2)

您在FOR循环中使用特定文件,因此不需要其中两个。第一个只是确认该文件存在。使用以下内容可以更轻松,更有效地完成:

if exist "E:\logs\ihs\Default\error.log.%Month%.%Today%.%Year%" ( ... )

其他人说你在两个循环中使用%%a时遇到问题。实际上,在嵌套循环中重用一个字符没有任何问题。但是你的内部循环无法访问外部循环值。鉴于你的内部循环DO引用%%j,我怀疑你打算让你的内循环使用%%i代替%%a

你的逻辑是错误的,因为你的循环正在处理所有行,而它应该只处理包含“rdy”的行。 FIND或FINDSTR可用于有效滤除不需要的线路。

您永远不应将自己的值分配给名为TIME的变量(请注意,变量名称不区分大小写)。这样做会阻止您以后访问动态时间值。

我还没弄清楚当外循环工作时会阻止进入内循环的内容。但我会重构你的整个代码。

不是从当前日期派生日志文件的名称,而是按日期/时间顺序列出所有日志文件,并使用FOR / F捕获最后找到的日志文件。

然后我会用另一个FOR / F来解析FINDSTR搜索“rdy”的输出

@echo off
setlocal
set "log=E:\scripts\busycheckalert.log"
set "checkTime=%time:~0,5%"
pushd "E:\logs\ihs\Default"

set "currentLog="
for /f "delims=" %%F in ('dir /b /a-d /od "error.log.*"') do set "currentLog=%%F"
if defined currentLog (
  >>"%log%" echo Polling %currentLog% at %checkTime%
  for /f "tokens=9" %%A in ('findstr /c:" rdy " "%currentLog%"') do (
    if %%A leq 200 >>"%log%" echo Error at %time%: Ready threshold exceeded in %currentLog% 
  )
) else  >>"%log%" echo No log found at %checkTime%"

popd