'Script to get number of erros by each hour from the IIS site 'Author: Felipe Ferreira , contact fel.h2o'AT'gmail.com 'Date: 16/06/2010 'Version: 5 'REQUIREMENTS: MSUtil.LogQuery logparser.dll (IIS) 'tested on Win2003 IIS 6 'For Nagios: 'OK Ouput just one line ex: 'OK - WARNING - 2000 erros of type 404 in IIS log | 2000,500,4000 'OK Get Parameters, WARN,CRIT,site,ERRORTYPE 'TODO: 'get query from last X minutes not from entire hour 'OK - get current time convert to GMT and subtract - X time 'PROBELM: query takes to long to execute, plus uses high CPU 'SOLUTIOn: execute every hour, and nagios just collect log info and report 'Option Explicit Const ForReading=1,ForWriting=2,ForAppending=3 Const intOK = 0 Const intWarning = 1 Const intCritical = 2 Const intError = 3 Const intUnknown = 3 Dim objLogParser,objInputFormat,objOutputFormat,strQuery Dim fso,logfile,outputlog,logday,pathlogfile,terros Dim debug,log,aSites(1) Dim aTxt,logname,RunTime,logOutputFileName Dim t1 : t1 = Timer 'time the script Dim logOutputFile 'Arquivo Final de Log Dim intDia 'De que dia olhar os logs, 0 = hoje, 1 = ontem etc... Dim line,hora,intGMToff,hourTarget,intMinDiff,intHourDiff Dim WARN,CRIT,strSite,ERRORTYPE,strFinalOutput,erros Dim argcountcommand,arg(9) '#################VARS################## logsroot = "E:\Logs-Sites\" 'the top level place where IIS save logs, default c:\windows\system32\logfiles debug = 0 '1 for debug, 0 for silent intDia = 0 ' 0 = hoje, 1 = ontem etc... WARN = 30 ' Apartir desse numero de erros p/ hora ira pro log log = 1 '1 for logging to a file, 0 for silent intGMToff = 3 'Diferença entre hora GMT e local time, nosso caso +3 intMinDiff = 30 'Quantos Minutos atras iremos olhar no Log intHourDiff = 0 'Quantas Horas atras iremos olhar no Log 'Default settings: erros = 0 erros1 = 0 CRIT=2000 strSite="site" Errortype="404" '#################VARS################## Set fso = CreateObject("Scripting.FileSystemObject") call getArgs() call getArgsSet() logday = getday(date) logOutputFileName = "c:\scripts\logs\LogIIS_Check_"&logday&".txt" Set logOutputFile = fso.OpenTextFile(logOutputFileName, ForWriting, True)'status output for running as a daily scheduled task hora = getTime(time) 'pt "NOW(GMT):" & hora 'pt "TARGET:" & hourTarget pt "Parameters, SITE= "& strSite & " WARNING= " & WARN & " ERRORTYPE= " & ErrorType pt "Querying IIS Logs - Start time: "& Time 'autoget location of IIS log files call getPath(logsroot & strSite &"\") 'pt pathlogfile logfile = pathlogfile & "ex" & logday & ".log" 'pt logfile outputlog = "c:\scripts\logs\Logs_"& strSite & ".csv" pt vbcrlf & "Processing file : " & logfile & " Start time : " & Time Set objLogParser = CreateObject("MSUtil.LogQuery") 'these will fail if you haven't registered the .dll Set objInputFormat = CreateObject("MSUtil.LogQuery.IISW3CInputFormat")'set input type as Event Logs Set objOutputFormat = CreateObject("MSUtil.LogQuery.CSVOutputFormat")'set output type as CSV objOutputFormat.headers=False 'no header row 'date time s-ip cs-method cs-uri-stem cs-uri-query cs-username c-ip cs(User-Agent) cs(Cookie) cs(Referer) sc-status sc-substatus sc-win32-status sc-bytes time-taken strQuery="select date as Date, QUANTIZE(time, 3600) AS Hour, sc-status as Status, count(*) AS ErrorCount " &_ "from " & chr(39) & logfile & chr(39) & " to " & chr(39) & outputlog & chr(39)& _ " WHERE sc-status >= " & Errortype &" AND Hour >= " & chr(39) & hourTarget & chr(39) & " and Hour <= " & chr(39) & hora & chr(39) & " GROUP BY date, hour,sc-status HAVING ErrorCount > " & WARN & " ORDER BY ErrorCount DESC" pt "Query = " & vbcrlf & strQuery & vbcrlf 'pt "" objLogParser.ExecuteBatch strQuery, objInputFormat, objOutputFormat 'run the query If Err.Number <> 0 Then'write any errors to the status file pt "ERROR - " & strSite & Time & " - "&Err.Number & " - "&Err.Description & " - "&Err.Source Err.Clear End If Set objOutputFormat = nothing Set objInputFormat = nothing Set objLogParser = nothing 'Should parse the file and throw all in just one log pt "Chamando Parser: " & outputlog & ", " & strSite call ParseResult(outputlog) logOutputFile.Close 'Print Message to Screen If (erros > WARN) and (erros < CRIT) Then strFinalOutput = "WARNING - " intExit = intWarning Elseif (erros > CRIT) Then strFinalOutput = "CRITICAL - " intExit = intCritical Elseif erros <= WARN Then strFinalOutput = "OK - " intExit = intOK end if 'EX: WARNING - 2000 erros of type 404 in IIS log | 2000,500,4000 '"CRTICAL - Existem $cnterros erros no IIS do oglobo!|IIS Erros: $cnterros , $WARN, $CRIT" wscript.echo strFinalOutput & erros & " erros no site do " & strSite & " |IIS Erros: " & erros & ", " & WARN & ", " & CRIT wscript.quit(intExit) '################################ SUBS AND FUNCTIONS ##################################################### Function ParseResult(inFile) 'Parse logparser output and put into one single txt log on error resume next Dim objFSO : Set objFSO = CreateObject("Scripting.FileSystemObject") Dim oFileIn,strLine 'Open In File For Reading If objFSO.FileExists(inFile) = true Then pt "______________________________________________________" pt strSite & vbcrlf set oFileIn = objFso.OpenTextFile(inFile, ForReading) Do While Not oFileIn.AtEndOfStream strLine = cstr(oFileIn.ReadLine) totalErr = split(strLine,",") 'Parse and Get Last DIgits = total errors found erros1 = cint(totalErr(3)) pt strLine & " - ErrorCount:" & erros1 erros = erros + erros1 Loop End If 'inFile Check pt "______________________________________________________" oFileIn.Close 'close scan txt end Function sub getPath(folderspec) 'On error resume next Dim oFSO, oFolder, oFileCollection,copyto Dim oFolderCollection, oSubFolder,fs,folder 'pt "PATH=" & folderspec Set oFSO = CreateObject("Scripting.FileSystemObject") Set fs = CreateObject("Scripting.FileSystemObject") Set oFolder = oFSO.GetFolder(folderspec) Set oFolderCollection = oFolder.SubFolders For Each folder in oFolderCollection 'pt folder.name if instr(folder.name,"W3SVC") then pathlogfile = folderspec & folder.name & "\" pt "Source=" & pathlogfile end if next set fs = nothing set oFSO = nothing end sub Function getday(inputDate) Dim intMonth : intMonth = Right("00" & Month(inputDate), 2) Dim intDay : intDay = Right("00" & Day(inputDate), 2) Dim intYear : intYear = Right("00" & Year(inputDate), 2) 'Forçar Dia intDay = intDay - intDia if len(intDay) = 1 then intDay = 0 & intDay end if getday = intYear & intMonth & intDay End Function Function getTime(inputTime) 'get current hour, set miuntes start to 00 and end to 59 Dim intMin : intMin = Right("00" & minute(inputTime), 2) Dim intHour : intHour = Right("00" & hour(inputTime), 2) intHour = cint(intHour) intGMToff = cint(intGMToff) intHour = intHour + intGMToff pt intHour getTime = intHour &":59:00" hourTarget = intHour &":00:00" end function sub GetArgsSet() if argcountcommand=1 or argcountcommand=0 then call help() else 'pt "Getting Values" strSite = GetOneArg("-s") errortype = cstr(GetOneArg("-t")) WARN = cint(GetOneArg("-w")) CRIT = cint(GetOneArg("-c")) end if end sub Function Help() 'Prints out help Dim str Dim strScriptFile : strScriptFile = "parselog_iis.vbs" str="Check the Log Files os IIS server and output error count of current hour." & vbcrlf str=str&"Requires logparser.dll, customized to be used by Nagios" &vbCrlF str=str&vbCrlF str=str&"cscript "& strScriptFile &" -s SiteName -t Tipo de Erro -w warning -c critical"&vbCrlF str=str&vbCrlF & "Example:" & vbcrlf str=str&"cscript "& strScriptFile &" -s myweb -t 404 -w 50 -c 100"&vbCrlF str=str&vbCrlF str=str&"-h [--help] Help."&vbCrlF str=str&"-s sitename Website name in IIS 6 "&vbCrlF str=str&"-t ErrorType IIS errortype:400,404,501,500 etc... "&vbCrlF str=str&vbCrlF str=str&"By Felipe Ferreira May 2010, version 3.0." & vbCrlF wscript.echo str wscript.quit End Function Function GetOneArg(strName) On Error Resume Next Dim i for i=0 to argcountcommand-1 if (Ucase(arg(i))=Ucase(strName)) then GetOneArg=arg(i+1) Exit Function end if next End Function Function GetArgs() 'Get ALL arguments passed to the script On Error Resume Next Dim i argcountcommand=WScript.Arguments.Count for i=0 to argcountcommand-1 arg(i)=WScript.Arguments(i) ' wscript.echo i & " - " & arg(i) next End Function function pt(txt) if debug = 1 and log = 1 then wscript.echo txt logOutputFile.WriteLine txt elseif debug = 0 and log = 1 then logOutputFile.WriteLine txt elseif debug = 1 and log = 0 then wscript.echo txt end if end function