source: nscp/scripts/check_files.vbs @ 8d89d7a

0.4.00.4.10.4.2
Last change on this file since 8d89d7a was 7443b58, checked in by Michael Medin <michael@…>, 2 years ago

0.4.x a lot of tweaks and fixes (now works as a replacement for 0.3.x in many ways)

  • Property mode set to 100644
File size: 14.0 KB
Line 
1'
2'
3' Check files under a given path
4' ==============================
5'
6' based on example scripts fond in nsclient++/scripts directory
7'
8' Author: werner.fuerst@assmann.at  2010-12-21
9'
10' uses NagiosPluginCDbl.vbs  from nsclient++/scripts/lib
11'       - modified Version of NagiosPlugin.vbs which came with nsclient++ vers. 0.3.8.76
12'            - compares bounds to double values, so 10 comes after 9 (numeric sorting)
13'            - bounds definition conforms to nagios plugin guidelines (http://nagiosplug.sourceforge.net/developer-guidelines.html#THRESHOLDFORMAT)
14'
15' modifications in NSC.ini:
16' =========================
17'
18'
19' in [modules]:
20' CheckExternalScripts.dll
21'
22' in [NRPE]:
23' allow_arguments=1
24' allow_nasty_meta_chars=1
25' allowed_hosts=x.x.x.x
26'
27' in [External Script]:
28' allow_arguments=1
29' allow_nasty_meta_chars=1
30'
31' in [Script Wrappings]:
32' vbs=cscript.exe //T:30 //NoLogo scripts\lib\wrapperCDbl.vbs %SCRIPT% %ARGS%
33'
34' in [Wrapped Scripts]:
35' check_files=check_files.vbs $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$ $ARG6$ $ARG7$ $ARG8$ $ARG9$ $ARG10$ $ARG11$ $ARG12$ $ARG13$ $ARG14$
36'
37'
38' nagios usage:
39' =============
40'
41' define command{
42'        command_name check_nrpe_external
43'        command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c $ARG1$ -a $ARG2$
44' }
45'
46' define service{
47'        use                     generic-service
48'        host_name               windowsxx
49'        service_description     Backup DB2
50'        check_command           check_nrpe_external!check_files!/path:"e:\\BACKUP\\DB" /namefilter:"DB2\.DAT" /expectmatch:1 /age:3 /selage:hour /warning:1: /critical:1: /size:9000000000 /weekdays:"2,3"
51'} }
52' give alarm when file DB2.DAT in e:\BACKUP\DB was not written until 3 o clock on Monday or Tuesday (alarm if count is less than 1, so threshold is set to 1:)
53'
54'
55'
56'        check_command           check_nrpe_external!check_files!/path:"d:\\journal" /searchdepth:1 /selage:ignore /warning:30 /critical:40
57' give alarm if there are more than 30 files under d:\journal
58'
59'
60'        check_command           check_nrpe_external!check_files!/path:"T:\\nfs\\interface1"  /searchdepth:2 /age:2d /warning:5: /critical:3: /selage:newer /seldat:created
61' give alarm if there are fewer than 3 files which are newer than 2 days under t:\nfs\interface1, search only 1 subdir down, use the creation date for comparison
62'
63'
64'
65' args:
66' =====
67'
68'
69' warning: threshold warning
70'    alert if x...
71'             10                 < 0 or > 10, (outside the range of {0 .. 10})
72'             10:                < 10, (outside {10 .. 8})
73'             ~:10             > 10, (outside the range of {-8 .. 10})
74'             10:20            < 10 or > 20, (outside the range of {10 .. 20})
75'             @10:20         >= 10 and <= 20, (inside the range of {10 .. 20})
76' critical: threshold critical
77' namefilter: regular expressionon on which files have to match
78' age: files have to be older/newer (see selage) than age
79'    e.g.: 5d: 5 days, 4h: 4 hours, 10n: 10 Minutes, 90s: 90 seconds   
80' selage: older/newer/hour/ignore
81'    older/newer: count only files if the are older/newer
82'    hour: alert if file is not written until hour
83'    ignore: count files independent of their age
84' searchdepth: search down x subdirs (searchdepth:1 - do not go down in directory hierarchy)
85' seldat: modified/created
86'    modified: date, when file was written
87'    created: date, when file was created
88' size: if file is smaller than given size give a warning
89' expectmatch: if less than expectmatch files correspond to namefilter give a warning
90' weekdays:
91'    if selage:hour files have to be written only on weekdays (1:sunday, 2:monday, ...)
92'    if selage:newer or selage:older and the timeunit of age is d (days), we add as many days to age as the last weekday is back
93'    e.g.: weekdays:23456 files are written on Monday, Tuesday, Wednesday, Thursday, Friday
94'
95
96Const PROGNAME = "check_files"
97Const VERSION = "0.1.0"
98
99Dim verbose
100verbose = 0
101
102Dim lastfile
103Dim lastdat
104Dim lastsize
105Dim intdif
106Dim warnsize
107Dim matchcount
108Dim weekdays
109Dim ageint
110Dim ageunit
111Dim agestring
112Dim inlevel
113
114
115' Default settings for script.
116threshold_warning = 10
117threshold_critical = 20
118alias = "default"
119agestring = "5d"    '5 days
120ageint = 5
121ageunit = "d"
122selage = "newer"
123namefilter = ""
124searchdepth = 0
125seldat = "modified"
126size = 0
127expectmatch = 0
128weekdays = "1,2,3,4,5,6,7"
129
130' Create the NagiosPlugin object
131Set np = New NagiosPlugin
132
133' Define what args that should be used
134np.add_arg "path", "Path", 1
135np.add_arg "namefilter", "Filename Filter", 0
136np.add_arg "age", "Age", 0
137np.add_arg "selage", "newer, older, hour, ignore", 0
138np.add_arg "searchdepth", "depth of subdirs to search", 0
139np.add_arg "seldat", "modified or created", 0
140np.add_arg "size", "size", 0
141np.add_arg "warning", "warning threshold", 0
142np.add_arg "critical", "critical threshold", 0
143np.add_arg "expectmatch", "expect at least x matches", 0
144np.add_arg "weekdays", "1,2,3,... 1-Sun 2-Mon 3-Tue...", 0
145np.add_arg "alias", "Alias", 0
146
147' If we have no args or arglist contains /help or not all of the required arguments are fulfilled show the usage output,.
148If Args.Count < 1 Or Args.Exists("help") Or np.parse_args = 0 Then
149        WScript.Echo Args.Count
150        np.Usage
151End If
152
153' If we define /warning /critical on commandline it should override the script default.
154If Args.Exists("warning") Then threshold_warning = Args("warning")
155If Args.Exists("critical") Then threshold_critical = Args("critical")
156If Args.Exists("namefilter") Then namefilter = Args("namefilter")
157If Args.Exists("age") Then agestring = Args("age")
158If Args.Exists("selage") Then selage = Args("selage")
159If Args.Exists("searchdepth") Then searchdepth = Cint(Args("searchdepth"))
160If Args.Exists("seldat") Then seldat = Args("seldat")
161If Args.Exists("size") Then size = CDbl(Args("size"))
162If Args.Exists("expectmatch") Then expectmatch = CInt(Args("expectmatch"))
163If Args.Exists("weekdays") Then weekdays = Args("weekdays")
164If Args.Exists("alias") Then alias = Args("alias")
165
166' Set the msg output to be used (OK/WARNING/CRITICAL/UNKNOWN will be applied automaticly)
167np.set_thresholds threshold_warning, threshold_critical
168
169' Set ageint and ageunit
170Set reage = New RegExp
171reage.IgnoreCase = False
172reage.Pattern = "^([0-9]+)([dhns]*)$"     'd: days h:hours n:minutes s:seconds
173
174Set ages = reage.Execute(agestring)
175
176For Each age In ages
177pt age & " > " & age.SubMatches(0) & " > " & age.SubMatches(1)
178ageint = CInt(age.SubMatches(0))
179ageunit = age.SubMatches(1)
180If ageunit = "" Then
181        If selage = "hour" Then
182        ageunit = "h"
183        Else
184        ageunit = "d"
185        End If
186End If
187Next
188
189' add some days if this and the days before do not belong to the weekdays
190If ageunit="d" And (selage="newer" Or selage="older") Then
191date1 = Now()
192date00 = DateValue(Now)
193date10 = DateValue(Now)
194
195For i = 0 To 7
196        ' datex: last day when the file should have been written according to weekdays
197        datex = SubtractDate(date00,i)
198        'date00 = DateValue(datex)
199        wdnowx = WeekDay(datex)
200        If Instr(weekdays,wdnowx) Then
201        ' exit for if we found the youngest weekday
202        Exit For
203        End If
204Next
205
206datex0 = DateValue(datex)
207diffd = DateDiff("d",datex0,date10)
208ageint = ageint + diffd
209End If
210
211intdif=0
212matchcount=0
213warnsize = 0
214
215' go down the hierarchy, in intdif we get the number of corresponding files
216CheckSubdirs Args("path")
217
218' get return code according to intdif files
219return_code = np.check_threshold(CDbl(intdif))
220
221last = ""
222If Len(namefilter) Then
223        last = "filter: " & namefilter
224End If
225
226' if there was only one file...
227If matchcount = 1 Then
228        last = last & " found one: " & lastfile & " " & lastdat & " " & lastsize
229End If
230
231' warning message if file too small or too few of them
232message = ""
233If warnsize = matchcount And warnsize > 0 Then
234        If return_code = 0 Then
235                return_code = 1
236        End If
237        message = " TOO SMALL!!! "
238End If
239
240If matchcount < expectmatch Then
241        If return_code = 0 Then
242                return_code = 1
243        End If
244        message = " NOT FOUND!!! "
245End If
246
247If selage = "ignore" Then
248        agemessage = " count: "
249ElseIf selage = "newer" Or selage ="older" Then
250        agemessage = selage & " than " & ageint & " " & ageunit & " : "
251ElseIf selage = "hour" Then
252        agemessage = " written before " & ageint & " o-clock on " & weekdays & " : "
253Else
254        agemessage = selage & ": " & age & " " & ageunit & " "
255End If
256
257' for the performance data format warning and critical thresholds (no :@~)
258cintw=np.get_threshold_perfdat("warning")          'PerfDat(np.get_threshold("warning"))
259cintc=np.get_threshold_perfdat("critical")
260
261' if we watch only a single file we will see the size in the performance data
262If expectmatch = 1 and matchcount = 1 Then
263        perfdata = "size=" &  lastsize
264Else
265        perfdata = "count=" & Cint(intdif) & ";" & cintw & ";" & cintc
266End If
267
268msg = "Testing " & Replace(Args("path"),"\","/") & " " & last & " " & agemessage & intdif & " w:" & np.get_threshold("warning") & " c: " & np.get_threshold("critical") & " " & message & " |" & perfdata
269
270' Nice Exit with msg and exitcode
271np.nagios_exit msg, return_code
272
273
274Sub CheckSubdirs(StartDir)
275        Set FSO = CreateObject("Scripting.FileSystemObject")
276        inlevel = 0
277
278        ' go down hierarchy
279        ShowSubfolders FSO.GetFolder(StartDir)
280
281        'Clean up
282        Set FSO = Nothing
283End Sub
284
285
286
287
288
289Sub ShowSubFolders(Folder)
290        'inlevel: we start with 1, so the startdir has level 1!
291        inlevel = inlevel + 1
292        pt "level: " & inlevel & " Folder: " & Folder.Name & " searchdepth: " & searchdepth
293        If (inlevel > searchdepth) And (searchdepth > 0) Then
294                ' we are too deep!
295                inlevel = inlevel - 1
296                pt "level2: " & inlevel & " Folder: " & Folder.Name
297                Exit sub
298        End If
299        pt "level3: " & inlevel & " Folder: " & Folder.Name
300        ListFiles Folder
301        If ((inlevel < searchdepth) And (searchdepth > 0)) Or (searchdepth = 0) Then
302                For Each Subfolder in Folder.SubFolders
303                        ' go further down
304                        ShowSubFolders Subfolder
305                Next
306        End If
307        ' leave level
308        inlevel = inlevel - 1
309End Sub
310
311
312
313Sub ListFiles(Folder)
314        Set colFiles = Folder.Files
315       
316        pt "in folder " & Folder.Name
317        For Each File in colFiles
318                matched = true
319                'pt "namefilter: " &  namefilter & " len:" & Len(namefilter)
320                ' if we defined a namefilter, use it (regexp!)
321                If Len(namefilter) > 0 Then
322               
323                        filename = File.Name
324               
325                        'pt "namefilter1: " &  filename
326                        Set re = new regexp
327                        re.IgnoreCase = True
328                        re.Pattern = namefilter
329                       
330                        'pt "namefilter2: " &  namefilter & " len:" & Len(namefilter)
331                        If re.Test(filename) <> true Then
332                                matched = false
333                        End If
334                End If
335               
336                ' now test the matched files against the age
337                If matched = true Then
338
339                        ' count the matched files (we warn later if there are fewer the expectmatch files)
340                        matchcount = matchcount + 1
341                        pt "match: " & matchcount & " file: " & File.name
342
343                        ' Date2 can be the DateCeated (backup of old machine, which is not time synchronized, so the created date is the date when the file was backed up to our server)
344                        Date1 = Now()
345                        If seldat = "created" Then
346                                Date2 = File.DateCreated
347                        Else
348                                Date2 = File.DateLastModified
349                        End If
350
351                        ' time difference between file and now
352                        dif =  Cint(DateDiff(ageunit,Date2,Date1))
353
354                        'remember the last file checked (we use it later in the message)
355                        lastfile = File.name
356                        lastdat = Date2
357                        lastsize = File.Size
358
359                        ' remember the count of files which where too small
360                        If CDbl(File.Size) < CDbl(size) Then
361                                warnsize = warnsize + 1
362                        End If
363
364                        'pt "c0 dif: " &  dif & " age: " & age & " selage: " & selage & " seldat: " & seldat
365                        ' count the numer of files which are newer/older than given age
366                        If dif < ageint And selage = "newer" Then
367                                intdif = intdif + 1
368                        ElseIf dif > ageint And selage = "older" Then
369                                intdif = intdif + 1
370                        ElseIf selage = "ignore" Then
371                                intdif = intdif + 1
372                        ElseIf selage = "hour" Then
373                        ' if selage:hour check if file has been written not after age (here age is the hour)
374                                If isnotolder(File) Then
375                                        intdif = intdif + 1
376                                End If
377                        End If
378                End If
379        Next
380End Sub
381
382
383
384Function isnotolder(File)
385        date1 = Now()
386        date2 = File.DateLastModified
387        date00 = DateValue(Now)
388        date10 = DateValue(Now)
389        date20 = DateValue(date2)
390
391
392        For i = 0 To 7
393        ' datex: last day when the file should have been written according to weekdays
394        datex = SubtractDate(date00,i)
395        'date00 = DateValue(datex)
396        wdnowx = WeekDay(datex)
397        If Instr(weekdays,wdnowx) Then
398                ' exit for if we found the youngest weekday
399                Exit For
400        End If
401        Next
402
403
404        ' we also need the second youngest weekday, when the file should have been written (is this english?)
405
406        date00 = datex
407
408        For i = 1 To 7
409                datex2 = SubtractDate(date00,i)
410                wdnowx2 = WeekDay(datex2)
411                If Instr(weekdays,wdnowx2) Then
412                        Exit For
413                End If
414        Next
415
416        diffdx = DateDiff("d",datex,Now)     ' days between expected write date and today
417        diffh0 = DateDiff("h",date10,Now)    ' hours since midnight
418        diffd = DateDiff("d",date20,datex)   ' days between written and expect to be written
419        diffd2 = DateDiff("d",date20,datex2) ' days between second oldest expected write day and today
420        diff1 = DateDiff("h",date20,date2)   ' hour of write (we currently do not use it)
421
422        ' we expect the best
423        iswritten = 1
424
425        ' today to be written an hour passed: should be written today!
426        If diffdx = 0 And diffh0 > ageint And diffd > 0 Then
427                iswritten = 0
428        End If
429
430        ' today to be written an hour not passed: should be written at least on second oldest expected day
431        If diffdx = 0 And diffh0 <= ageint And diffd2 > 0 Then
432                iswritten = 0
433        End If
434
435
436        ' it should have been written on a day before, diffd gives a positive value: expected day passed
437        If diffdx > 0 And diffd > 0 Then
438                pt "i31: " & diffdx & " " & diffd
439                iswritten = 0
440        End If
441
442
443        ' older the 7 days!
444        If diffd > 7 Then
445                pt "i0: " & diffd
446                iswritten = 0
447        End If
448
449        ' if none of the bad conditions matched, we still have iswritten=1
450        isnotolder = iswritten
451End Function
452
453
454Function SubtractDate(datea,ii)
455        dateb = DateAdd("d",-ii,datea)
456        SubtractDate = dateb
457End Function
458
459Function pt(strMsg)
460        if verbose = 1 then
461                wscript.echo strMsg
462        end if
463end function
464
Note: See TracBrowser for help on using the repository browser.