Rev 77 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
52 | daniel-mar | 1 | <?php |
2 | |||
3 | /* |
||
4 | * VNag - Nagios Framework for PHP |
||
5 | * Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com> |
||
6 | * Licensed under the terms of the Apache 2.0 license |
||
7 | * |
||
77 | daniel-mar | 8 | * Revision 2023-10-13 |
52 | daniel-mar | 9 | */ |
10 | |||
11 | declare(ticks=1); |
||
12 | |||
13 | define('OUTPUT_UOM', 'MB'); |
||
14 | define('ROUND_TO', 0); |
||
15 | |||
16 | class OpenDeletedFilesCheck extends VNag { |
||
17 | protected $argDir = null; |
||
18 | |||
19 | public function __construct() { |
||
20 | parent::__construct(); |
||
21 | |||
22 | $this->registerExpectedStandardArguments('Vhtwc'); |
||
23 | |||
24 | $this->getHelpManager()->setPluginName('open_deleted_files'); |
||
79 | daniel-mar | 25 | $this->getHelpManager()->setVersion('2023-10-13'); |
52 | daniel-mar | 26 | $this->getHelpManager()->setShortDescription('This plugin checks for open deleted files (which require space but are not visible/accessible anymore).'); |
27 | $this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.'); |
||
28 | $this->getHelpManager()->setSyntax('$SCRIPTNAME$ [-d directory] [-w warnSizeKB] [-c critSizeKB]'); |
||
29 | $this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com'); |
||
30 | |||
31 | # $this->warningSingleValueRangeBehaviors[0] = self::SINGLEVALUE_RANGE_VAL_GT_X_BAD; |
||
32 | # $this->criticalSingleValueRangeBehaviors[0] = self::SINGLEVALUE_RANGE_VAL_GT_X_BAD; |
||
33 | |||
34 | // Individual (non-standard) arguments: |
||
35 | $this->addExpectedArgument($this->argDir = new VNagArgument('d', 'directory', VNagArgument::VALUE_REQUIRED, 'directory', 'Directory to check (e.g. /tmp)Directory to check (e.g. /tmp)')); |
||
36 | } |
||
37 | |||
38 | protected static function check_open_deleted_files($dir_to_check = '/') { |
||
53 | daniel-mar | 39 | // Note: Requires root |
40 | exec('lsof -n', $lines, $ec); |
||
52 | daniel-mar | 41 | if ($ec != 0) return false; |
42 | |||
43 | /* |
||
44 | $lines = explode("\n", |
||
45 | 'COMMAND PID TID TASKCMD USER FD TYPE DEVICE SIZE/OFF NODE NAME |
||
46 | php-cgi 430 oidplus 3u REG 0,42 0 1502217042 /tmp/.ZendSem.uhCRtC (deleted) |
||
47 | apache2 838 root 150u REG 0,42 0 1499023202 /tmp/.ZendSem.RFcTM9 (deleted) |
||
48 | postgres 1060 gitlab-psql txt REG 9,0 9291488 47189384 /opt/gitlab/embedded/postgresql/12/bin/postgres (deleted) |
||
49 | php-cgi 1573 owncloud 3u REG 0,42 0 1499024339 /tmp/.ZendSem.2Qh70x (deleted) |
||
50 | php-fpm7. 1738 root 3u REG 0,42 0 434907183 /tmp/.ZendSem.unGJqF |
||
51 | php-fpm7. 1739 www-data 3u REG 0,42 0 434907183 /tmp/.ZendSem.unGJqF (deleted) |
||
52 | php-fpm7. 1740 www-data 3u REG 0,42 0 434907183 /tmp/.ZendSem.unGJqF (deleted) |
||
53 | runsvdir 1932 root txt REG 9,0 27104 45351338 /opt/gitlab/embedded/bin/runsvdir (deleted) |
||
54 | '); |
||
55 | */ |
||
56 | |||
57 | $line_desc = array_shift($lines); |
||
58 | $p_name = strpos($line_desc, 'NAME'); |
||
59 | if ($p_name === false) return false; |
||
60 | |||
61 | $nodes = array(); |
||
62 | |||
63 | foreach ($lines as $line) { |
||
64 | if (trim($line) == '') continue; |
||
65 | |||
66 | $name = substr($line, $p_name); |
||
67 | |||
68 | preg_match('@.+\s(\d+)\$@ism', substr($line, 0, $p_name-1), $m); |
||
69 | $tmp = rtrim(substr($line, 0, $p_name-1)); |
||
70 | $tmp = explode(" ", $tmp); |
||
71 | $node = end($tmp); |
||
72 | |||
73 | $tmp = rtrim(substr($line, 0, $p_name-strlen($node)-1)); |
||
74 | $tmp = explode(" ", $tmp); |
||
75 | $size = end($tmp); |
||
76 | |||
77 | if (substr($name, 0, strlen($dir_to_check)) !== $dir_to_check) continue; |
||
78 | |||
79 | if (strpos($name, ' (deleted)') === false) continue; |
||
80 | if ($size == 0) continue; |
||
81 | |||
82 | $nodes[$node] = $size; |
||
83 | } |
||
84 | |||
85 | $size_total = 0; |
||
86 | foreach ($nodes as $node => $size) { |
||
87 | $size_total += $size; |
||
88 | } |
||
89 | return $size_total; |
||
90 | } |
||
91 | |||
92 | protected function cbRun($optional_args=array()) { |
||
93 | $dir = $this->argDir->getValue(); |
||
94 | if (empty($dir)) $dir = '/'; |
||
95 | $dir = realpath($dir) === false ? $dir : realpath($dir); |
||
96 | if (substr($dir,-1) !== '/') $dir .= '/'; |
||
97 | |||
98 | $size = self::check_open_deleted_files($dir); |
||
77 | daniel-mar | 99 | if ($size === false) throw new VNagException("Cannot get information from 'lsof'"); |
52 | daniel-mar | 100 | |
101 | $this->checkAgainstWarningRange( array($size.'B'), false, true, 0); |
||
102 | $this->checkAgainstCriticalRange(array($size.'B'), false, true, 0); |
||
103 | |||
104 | $m = (new VNagValueUomPair($size.'B')); |
||
105 | $m->roundTo = ROUND_TO; |
||
106 | $sizeOut = $m->normalize(OUTPUT_UOM); |
||
107 | |||
108 | $msg = "$sizeOut opened deleted files in $dir"; |
||
109 | $this->setHeadline($msg); |
||
110 | } |
||
111 | } |