InotifyMonitor.php 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. <?php
  2. class InotifyMonitor {
  3. const MONITOR_EVENT = IN_CLOSE_WRITE;
  4. const EVENT_MASK = [
  5. IN_ACCESS => 'File was accessed (read)',
  6. IN_MODIFY => 'File was modified',
  7. IN_ATTRIB => 'Metadata changed',
  8. IN_CLOSE_WRITE => 'File opened for writing was closed',
  9. IN_CLOSE_NOWRITE => 'File not opened for writing was closed',
  10. IN_OPEN => 'File was opened',
  11. IN_MOVED_TO => 'File moved into watched directory',
  12. IN_MOVED_FROM => 'File moved out of watched directory',
  13. IN_CREATE => 'File or directory created in watched directory',
  14. IN_DELETE => 'File or directory deleted in watched directory',
  15. IN_DELETE_SELF => 'Watched file or directory was deleted',
  16. IN_MOVE_SELF => 'Watch file or directory was moved',
  17. IN_CLOSE => 'Equals to IN_CLOSE_WRITE | IN_CLOSE_NOWRITE',
  18. IN_MOVE => 'Equals to IN_MOVED_FROM | IN_MOVED_TO',
  19. IN_ALL_EVENTS => 'Bitmask of all the above constants',
  20. IN_UNMOUNT => 'File system containing watched object was unmounted',
  21. IN_Q_OVERFLOW => 'Event queue overflowed (wd is -1 for this event)',
  22. IN_IGNORED => 'Watch was removed (explicitly by inotify_rm_watch() or because file was removed or filesystem unmounted',
  23. IN_ISDIR => 'Subject of this event is a directory',
  24. IN_ONLYDIR => 'Only watch pathname if it is a directory',
  25. IN_DONT_FOLLOW => 'Do not dereference pathname if it is a symlink',
  26. IN_MASK_ADD => 'Add events to watch mask for this pathname if it already exists',
  27. IN_ONESHOT => 'Monitor pathname for one event, then remove from watch list.',
  28. 1073741840 => 'High-bit: File not opened for writing was closed',
  29. 1073741856 => 'High-bit: File was opened',
  30. 1073742080 => 'High-bit: File or directory created in watched directory',
  31. 1073742336 => 'High-bit: File or directory deleted in watched directory',
  32. ];
  33. public $fds = [];
  34. public $paths = [];
  35. public $wds = [];
  36. public $timeout = 3;
  37. public $redis=null;
  38. public function __construct( $paths,$ip='127.0.0.1',$password='',$post=6379){
  39. if (!empty($paths)) {
  40. foreach ($paths as $path) {
  41. if (file_exists($path)) {
  42. if (is_dir($path)) {
  43. $this->addDir($path);
  44. } else {
  45. $this->addFile($path);
  46. }
  47. }
  48. }
  49. }
  50. // if (!empty($post_url)) {
  51. // $this->url = $post_url;
  52. // }
  53. $this->redis = new Redis();
  54. $this->redis->pconnect($ip,$post,2.5);
  55. $this->redis->auth($password); //设置密码
  56. $this->redis->select(1);
  57. $result = $this->redis->ping();
  58. echo "redis连接结果=>".$result.PHP_EOL;
  59. $this->scan_file($paths[0]);
  60. }
  61. public function __destruct( ){
  62. if (!empty($this->fds)) {
  63. foreach ($this->fds as $fd) {
  64. fclose($fd);
  65. }
  66. }
  67. }
  68. public function addFile( $file ){
  69. $file = realpath($file);
  70. $fd = inotify_init();
  71. $fid = (int)$fd;
  72. //保存inotify资源
  73. $this->fds[$fid] = $fd;
  74. //设置为非阻塞模式
  75. stream_set_blocking($this->fds[$fid], 0);
  76. //保存文件路径
  77. $this->paths[$fid] = $file;
  78. //保存监控描述�?
  79. $this->wds[$fid] =inotify_add_watch($this->fds[$fid], $file, self::MONITOR_EVENT);
  80. }
  81. public function addDir( $dir ){
  82. $dir = realpath($dir);
  83. if ($dh = opendir($dir)) {
  84. //将目录加入监控中
  85. $fd = inotify_init();
  86. //一般文件的资源描述符是一个整形,可以用来当索�?
  87. $fid = (int)$fd;
  88. $this->fds[$fid] = $fd;
  89. stream_set_blocking($this->fds[$fid], 0);
  90. $this->paths[$fid] = $dir;
  91. $this->wds[$fid] = inotify_add_watch($this->fds[$fid], $dir, self::MONITOR_EVENT);
  92. //遍历目录下文�?
  93. while (($file = readdir($dh)) !== false) {
  94. if ($file == '.' || $file == '..') {
  95. continue;
  96. }
  97. $file = $dir . DIRECTORY_SEPARATOR . $file;
  98. if (is_dir($file)) {
  99. $this->addDir($file);
  100. }
  101. }
  102. closedir($dh);
  103. }
  104. }
  105. public function remove( $fid ){
  106. unset($this->paths[$fid]);
  107. fclose($this->fds[$fid]);
  108. unset($this->fds[$fid]);
  109. }
  110. public function run( ){
  111. echo '我开始运行了'.PHP_EOL;
  112. while (true) {
  113. $reads = $this->fds;
  114. $write = [];
  115. $except = [];//异常事件
  116. if (stream_select($reads, $write, $except, $this->timeout) > 0) {
  117. if (!empty($reads)) {
  118. foreach ($reads as $read) {
  119. //从可读流中读取数�?
  120. $events = inotify_read($read);
  121. //资源描述符,整形
  122. $fid = (int)$read;
  123. //获取inotify实例的路�?
  124. $path = $this->paths[$fid];
  125. foreach ($events as $event) {
  126. echo '监听读取'.PHP_EOL;
  127. $file = $path .'/' . $event['name'];
  128. if ($event['mask']==IN_CLOSE_WRITE) {
  129. echo 'create file->'.$file.PHP_EOL;
  130. //写入kafka
  131. $this->set_redis($file);
  132. //$this->postData($data);
  133. }
  134. //echo $event['name'], ' --- ', self::EVENT_MASK[$event['mask']], PHP_EOL;
  135. }
  136. }
  137. }
  138. if (!empty($except)) {
  139. //debug_log('push_vidieo_images_log',json_encode($except));//记录下异常事�?
  140. }
  141. } else {
  142. //echo '------------------', PHP_EOL;
  143. //echo '当前监控的路径列�?, PHP_EOL;
  144. //print_r($this->paths);
  145. //echo '------------------', PHP_EOL;
  146. }
  147. }
  148. }
  149. /**
  150. * function
  151. * 文件目录
  152. * @param [type] $data
  153. * @return void
  154. */
  155. public function set_redis($data)
  156. {
  157. if(!strstr($data,'md5'))
  158. {
  159. rename($data,$data.'.redis');
  160. $this->redis->lpush('redis_to_kafka',$data);
  161. }
  162. }
  163. //扫描目录下所有没有上传到redis文件
  164. public function scan_file($dir)
  165. {
  166. if(is_file($dir))
  167. {
  168. return;
  169. }
  170. $files = scandir($dir);
  171. foreach($files as $k=>$filename) {//务必使用!==,防止目录下出现类似文件名“0”等情况
  172. if ($filename != "." && $filename != ".." && !strstr($filename,'.redis')&&!strstr($filename,'.md5')&&is_file($dir.'/'.$filename)) {
  173. $data = $dir.'/'.$filename;
  174. rename($data,$data.'.redis');
  175. $this->redis->lpush('redis_to_kafka',$data);
  176. }
  177. }
  178. closedir($dir);
  179. return;
  180. }
  181. }
  182. // //调用函数
  183. // $path = "/test";
  184. // $inotify = new InotifyMonitor([$path]);
  185. // echo '进入运行�?;
  186. // $inotify->run();