мониторинг файла журнала для определенного шаблона

Я пытаюсь написать пакетный файл, чтобы отслеживать файл журнала для слова «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

Я написал базовый сценарий (все еще на моем L), который отслеживает файл 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 

Не могли бы вы посоветовать, где я ошибаюсь? Любая помощь будет здорово.

Спасибо


person Rage    schedule 23.06.2013    source источник
comment
if %%j LEQ 200 что такое %%j ??   -  person Endoro    schedule 23.06.2013


Ответы (4)


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

Хммм, а теперь интересно, что произойдет, если вы замените %%a, скажем, на %%i?

Похоже, вы тоже не проверяете, что %%i==rdy. Если вы этого не сделаете, вы можете получить довольно странные результаты.

person Magoo    schedule 23.06.2013

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"

Теперь я понимаю, что это не ваша цель.

Похоже, вы используете то же имя файла журнала, что и файл, который вы обрабатываете.

У вас есть разделители=; где нет ; во фрагменте журнала.

Вы повторно используете %%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 (
person foxidrive    schedule 23.06.2013

Предложение с кодом для класса GNUWin32 grep:

@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
)
person captcha    schedule 23.06.2013

Вы используете определенный файл в своих циклах 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
person dbenham    schedule 23.06.2013