public function __construct() { $this->inotifyEventMask = IN_ATTRIB | IN_MODIFY | IN_DELETE | IN_CREATE | IN_MOVE | IN_MOVE_SELF; $this->inotify = inotify_init(); stream_set_blocking($this->inotify, 0); $this->tracker = new Tracker($this); }
/** * Simple tail program using the inotify extension * Usage: ./tail.php file */ function main_loop($file, $file_fd) { $inotify = inotify_init(); if ($inotify === false) { fprintf(STDERR, "Failed to obtain an inotify instance\n"); return 1; } $watch = inotify_add_watch($inotify, $file, IN_MODIFY); if ($watch === false) { fprintf(STDERR, "Failed to watch file '%s'", $file); return 1; } while (($events = inotify_read($inotify)) !== false) { echo "Event received !\n"; foreach ($events as $event) { if (!($event['mask'] & IN_MODIFY)) { continue; } echo stream_get_contents($file_fd); break; } } // May not happen inotify_rm_watch($inotify, $watch); fclose($inotify); fclose($file_fd); return 0; }
function watchADir($path) { $this->dirs[$path] = $path; $this->ifds[$path] = inotify_init(); $this->wds[$path] = inotify_add_watch($this->ifds[$path], $path, self::DIR_MASK); $this->log("add dir {$path} " . print_r($this->dirs, 1) . print_r($this->wds, 1)); }
function tail($file, &$pos) { // get the size of the file if (!$pos) { $pos = filesize($file); } // Open an inotify instance $fd = inotify_init(); // Watch $file for changes. $watch_descriptor = inotify_add_watch($fd, $file, IN_ALL_EVENTS); // Loop forever (breaks are below) while (true) { // Read events (inotify_read is blocking!) $events = inotify_read($fd); // Loop though the events which occured foreach ($events as $event => $evdetails) { // React on the event type switch (true) { // File was modified case $evdetails['mask'] & IN_MODIFY: // Stop watching $file for changes inotify_rm_watch($fd, $watch_descriptor); // Close the inotify instance fclose($fd); // open the file $fp = fopen($file, 'r'); if (!$fp) { return false; } // seek to the last EOF position fseek($fp, $pos); // read until EOF while (!feof($fp)) { $buf .= fread($fp, 8192); } // save the new EOF to $pos $pos = ftell($fp); // (remember: $pos is called by reference) // close the file pointer fclose($fp); // return the new data and leave the function return $buf; break; // File was moved or deleted // File was moved or deleted case $evdetails['mask'] & IN_MOVE: case $evdetails['mask'] & IN_MOVE_SELF: case $evdetails['mask'] & IN_DELETE: case $evdetails['mask'] & IN_DELETE_SELF: // Stop watching $file for changes inotify_rm_watch($fd, $watch_descriptor); // Close the inotify instance fclose($fd); // Return a failure return false; break; } } } }
/** * Execute the console command. * * @return mixed */ public function fire() { $watches = array(); $in = inotify_init(); // add watches starting from root directory $root = Path::fromRelative(''); $this->addWatches($in, $root, $watches); printf("\nReading for events\n"); while (true) { $events = inotify_read($in); foreach ($events as $event) { $path = $watches[$event['wd']]; $expanded = $this->expandMask($event['mask']); $eventName = trim(implode(', ', $expanded), ', '); // if the event has a name attached, then index that if ($event['name']) { $newPathName = $path->getPathname() . '/' . $event['name']; $newPath = new Path($newPathName); Indexer::index($newPath, 1); // this may be a new directory, so add a watch to it anyway if ($newPath->exists() && $newPath->isDir()) { try { $wd = inotify_add_watch($in, $newPath->getPathname(), $this->computedMask); $watches[$wd] = $newPath; } catch (Exception $e) { echo 'Caught exception: ', $e->getMessage(), "\n"; } } } else { // event must apply to this directory, so index it, 1 level deep Indexer::index($path, 1); } } } }
public function start() { $this->stop = false; $fd = inotify_init(); $wd = inotify_add_watch($fd, $this->path, IN_ALL_EVENTS); $read = [$fd]; $write = null; $except = null; stream_select($read, $write, $except, 0); stream_set_blocking($fd, 0); while (true) { if ($this->stop) { inotify_rm_watch($fd, $wd); return fclose($fd); } if ($events = inotify_read($fd)) { foreach ($events as $details) { if ($details['name']) { $target = rtrim($this->path, '/') . '/' . $details['name']; } else { $target = $this->path; } $file = new \SplFileInfo($target); switch (true) { case $details['mask'] & IN_MODIFY: $this->modify($file); break; } $this->all($file); } } } }
public function __construct() { $this->inotify = inotify_init(); if ($this->inotify == false) { // fail fast die('cannot initialize inotify'); } stream_set_blocking($this->inotify, true); }
/** * Initializes tracker. Creates inotify resource used to track file and directory changes. * * @throws RuntimeException If inotify extension unavailable */ public function __construct() { if (!function_exists('inotify_init')) { throw new RuntimeException('You must install inotify to be able to use this tracker.'); } $this->inotify = inotify_init(); stream_set_blocking($this->inotify, 0); $this->bag = new CheckerBag($this->inotify); }
/** * 初始化 * @return NULL */ public static function init() { self::$inotifySuport = extension_loaded('inotify'); if (!self::$inotifySuport) { return null; } self::$inotifyFd = inotify_init(); stream_set_blocking(self::$inotifyFd, 0); return self::$inotifyFd; }
/** * Adds a path to the list of watched paths * * @param string $path Path to the watched file or directory * @param integer $mask Bitmask of inotify constants * @return integer unique watch identifier, can be used to remove() watch later */ public function add($path, $mask) { if ($this->inotifyHandler === false) { // inotifyHandler not started yet => start a new one $this->inotifyHandler = \inotify_init(); stream_set_blocking($this->inotifyHandler, 0); // wait for any file events by reading from inotify handler asynchronously $this->loop->addReadStream($this->inotifyHandler, $this); } $descriptor = \inotify_add_watch($this->inotifyHandler, $path, $mask); $this->watchDescriptors[$descriptor] = array('path' => $path); return $descriptor; }
/** * Constructor */ public function __construct() { if (Daemon::loadModuleIfAbsent('inotify')) { $this->inotify = inotify_init(); stream_set_blocking($this->inotify, 0); } Timer::add(function ($event) { Daemon::$process->fileWatcher->watch(); if (sizeof(Daemon::$process->fileWatcher->files) > 0) { $event->timeout(); } }, 1000000.0 * 1, 'fileWatcher'); }
public function __construct() { if (is_callable('inotify_init')) { $this->inotify = inotify_init(); stream_set_blocking($this->inotify, 0); } Daemon_TimedEvent::add(function ($event) { Daemon::$process->fileWatcher->watch(); if (sizeof(Daemon::$process->fileWatcher->files) > 0) { $event->timeout(); } }, 1000000.0 * 1, 'fileWatcherTimedEvent'); }
/** * Creates a new instance of Watcher. */ public function __construct() { $this->modifiedTimes = []; $this->listeners = []; $this->paths = []; if (function_exists('inotify_init')) { $this->inotify = inotify_init(); $read = [$this->inotify]; $write = null; $except = null; if (stream_select($read, $write, $except, 0) !== false) { stream_set_blocking($this->inotify, 0); } else { $this->inotify = null; } } }
/** * @return Result */ public function run() { /** @noinspection PhpUndefinedFunctionInspection */ $inotify = inotify_init(); $watches = $this->createInotifyWatches($inotify); stream_set_blocking($inotify, 0); while (true) { /** @noinspection PhpUndefinedFunctionInspection */ $events = inotify_read($inotify); if ($events) { if ($this->clear) { passthru('bash -c clear'); } $this->runTasksForInotifyEvents($events); } sleep(1); } $this->shutdownInotify($inotify, $watches); return $this->gasp->result()->setStatus(Result::SUCCESS)->setMessage('And now his watch is ended.'); }
/** * @param $serverPid * @throws NotFound */ function __construct($serverPid) { $this->pid = $serverPid; if (posix_kill($serverPid, 0) === false) { throw new NotFound("Process#{$serverPid} not found."); } $this->inotify = inotify_init(); $this->events = IN_MODIFY | IN_DELETE | IN_CREATE | IN_MOVE; swoole_event_add($this->inotify, function ($ifd) { $events = inotify_read($this->inotify); if (!$events) { return; } var_dump($events); foreach ($events as $ev) { if ($ev['mask'] == IN_IGNORED) { continue; } else { if ($ev['mask'] == IN_CREATE or $ev['mask'] == IN_DELETE or $ev['mask'] == IN_MODIFY or $ev['mask'] == IN_MOVED_TO or $ev['mask'] == IN_MOVED_FROM) { $fileType = strstr($ev['name'], '.'); //非重启类型 if (!isset($this->reloadFileTypes[$fileType])) { continue; } } } //正在reload,不再接受任何事件,冻结10秒 if (!$this->reloading) { $this->putLog("after 10 seconds reload the server"); //有事件发生了,进行重启 swoole_timer_after($this->afterNSeconds * 1000, array($this, 'reload')); $this->reloading = true; } } }); }
/** * 监控日志文件 * * @param array $logPaths * @return void * @throws ZtChart_Model_Monitor_Exception */ public function tail($logPaths) { if (($inotify = inotify_init()) === false) { throw new ZtChart_Model_Monitor_Daemon_Exception('Failed to obtain an inotify instance.'); } $watchFiles = $watchDirs = array(); foreach ($logPaths as $file) { if (($watch = inotify_add_watch($inotify, $file, IN_CREATE | IN_MODIFY)) === false) { throw new ZtChart_Model_Monitor_Daemon_Exception("Failed to watch file '{$file}'."); } if (is_file($file)) { if (false === ($fd = fopen($file, "r"))) { throw new ZtChart_Model_Monitor_Daemon_Exception("File '{$file}' is not readable."); } $this->_ffseek($fd); $watchFiles[$watch] = $fd; } else { if (is_dir($file)) { $watchFiles[$watch] = array(); $watchDirs[$watch] = $file; } } } while (($events = inotify_read($inotify)) !== false) { foreach ($events as $event) { if ($event['mask'] & IN_Q_OVERFLOW) { throw new ZtChart_Model_Monitor_Daemon_Exception("The number of inotify queued events reaches upper limit."); } if (!$this->accept($event['name'])) { continue; } if ($event['mask'] & (IN_CREATE | IN_MODIFY)) { if (!($event['mask'] & IN_ISDIR)) { if (!array_key_exists($event['name'], $watchFiles[$event['wd']])) { $fn = $fd = null; foreach ($watchFiles[$event['wd']] as $wfn => $wfd) { if (strncasecmp($wfn, $event['name'], strpos($wfn, '.')) == 0) { $fn = $wfn; $fd = $wfd; break; } } // 判断当前创建或修改的日志文件是否最新 if (strcasecmp($fn, $event['name']) < 0) { if (is_resource($fd) && fclose($fd)) { unset($watchFiles[$event['wd']][$fn]); } $filename = $watchDirs[$event['wd']] . DIRECTORY_SEPARATOR . $event['name']; if (false === ($fd = fopen($filename, "r"))) { $this->_logger->err("File '{$filename}' is not readable\n"); continue; } if ($event['mask'] & IN_MODIFY) { $this->_ffseek($fd); } $watchFiles[$event['wd']][$event['name']] = $fd; } else { // 如果不是最新的日志文件(重写的上一个小时的日志文件),则不处理。 continue; } } else { $fd = $watchFiles[$event['wd']][$event['name']]; } } else { continue; // $fd = $watchFiles[$event['wd']]; } // 读取日志并分析 $raw = ''; $lines = 0; while (true) { $raw .= $block = fread($fd, 4096); if (false !== ($pos = strpos($raw, "\n"))) { $rawline = substr($raw, 0, $pos + 1); try { $mlog = new ZtChart_Model_Monitor_Log($rawline); $line = $mlog->transform(); if (!empty($line)) { $this->_shmWrite($mlog->getShmIdentifier(), $line); $lines++; } } catch (ZtChart_Model_Monitor_Log_Exception $e) { $this->_logger->warn("日志处理错误:" . iconv('GBK', 'UTF-8', $rawline)); } $raw = substr($raw, $pos + 1); } else { if (($offset = strlen($block)) > 0) { fseek($fd, -$offset, SEEK_CUR); } break; } } if (0 != $lines) { $this->_logger->info(sprintf("%4s行有效数据已处理:%s", $lines, $watchDirs[$event['wd']] . '/' . $event['name'])); } } } } foreach ($watchFiles as $watch => $fd) { if (is_resource($fd)) { $fd = (array) $fd; } array_walk($fd, 'fclose'); inotify_rm_watch($inotify, $watch); } fclose($inotify); }
/** * Constructor */ public function __construct() { $this->inotifyStreamDescriptor = inotify_init(); stream_set_blocking($this->inotifyStreamDescriptor, 0); register_tick_function([$this, 'tick']); }
/** * Watcher constructor. */ public function __construct() { $this->inotify = inotify_init(); }
<?php class G { static $users = array(); static $files = array(); static $watchList = array(); static $inotify; } $server = new swoole_websocket_server("0.0.0.0", 9502, SWOOLE_BASE); $server->on('WorkerStart', function (swoole_websocket_server $server, $worker_id) { G::$inotify = inotify_init(); swoole_event_add(G::$inotify, function ($ifd) use($server) { $events = inotify_read(G::$inotify); if (!$events) { return; } foreach ($events as $event) { $filename = G::$watchList[$event['wd']]; $line = fgets(G::$files[$filename]['fp']); if (!$line) { echo "fgets failed\n"; } //遍历监听此文件的所有用户,进行广播 foreach (G::$files[$filename]['users'] as $fd) { $server->push($fd, $line); } } }); }); $server->on('Message', function (swoole_websocket_server $server, $frame) {
public function start() { $paths = $this->_paths; if ($this->_followLinks) { $paths = LinksHelper::followLinks($paths, $this->_excludePatterns); } $this->_fd = inotify_init(); $finder = new Finder(); $finder->directories(); foreach ($this->_excludePatterns as $excludePattern) { $finder->notName($excludePattern); } foreach ($paths as $p) { $finder->in($p); } $this->_watches = array(); foreach ($paths as $p) { $this->_addWatch($p); } foreach ($finder as $f) { $this->_addWatch($f->__toString()); } $this->_logger->info("Watches set up..."); $read = array($this->_fd); $write = null; $except = null; stream_select($read, $write, $except, 0); stream_set_blocking($this->_fd, 0); $events = array(); while (!$this->_stopped) { while ($inotifyEvents = inotify_read($this->_fd)) { foreach ($inotifyEvents as $details) { $file = $this->_watches[$details['wd']]; if ($details['name']) { $file .= '/' . $details['name']; } if ($details['mask'] & IN_MODIFY || $details['mask'] & IN_ATTRIB) { $events[] = new ModifyEvent($file); } if ($details['mask'] & IN_CREATE) { $events[] = new CreateEvent($file); } if ($details['mask'] & IN_DELETE) { $events[] = new DeleteEvent($file); } if ($details['mask'] & IN_MOVED_FROM) { $this->_previousMoveFromFile = $file; } if ($details['mask'] & IN_MOVED_TO) { if (!isset($this->_previousMoveFromFile)) { $this->_logger->error('MOVED_FROM event is not followed by a MOVED_TO'); } else { $events[] = new MoveEvent($this->_previousMoveFromFile, $file); unset($this->_previousMoveFromFile); } } if ($details['mask'] & IN_DELETE_SELF) { unset($this->_watches[$details['wd']]); } } } $events = $this->_compressEvents($events); if ($this->_queueSizeLimit && count($events) > $this->_queueSizeLimit) { $this->_dispatchEvent(QueueFullEvent::NAME, new QueueFullEvent($events)); $events = array(); } foreach ($events as $event) { $name = call_user_func(array(get_class($event), 'getEventName')); $this->_dispatchEvent($name, $event); } usleep(100 * 1000); } foreach ($this->_watches as $wd => $path) { inotify_rm_watch($this->_fd, (int) $wd); } fclose($this->_fd); return; }
$worker = new Worker(); // worker的名字,方便status时标识 $worker->name = 'FileMonitor'; // 改进程收到reload信号时,不执行reload $worker->reloadable = false; // 所有被监控的文件,key为inotify id $monitor_files = array(); // 进程启动后创建inotify监控句柄 $worker->onWorkerStart = function ($worker) { if (!extension_loaded('inotify')) { echo "FileMonitor : Please install inotify extension.\n"; return; } global $monitor_dir, $monitor_files; // 初始化inotify句柄 $worker->inotifyFd = inotify_init(); // 设置为非阻塞 stream_set_blocking($worker->inotifyFd, 0); // 递归遍历目录里面的文件 $dir_iterator = new RecursiveDirectoryIterator($monitor_dir); $iterator = new RecursiveIteratorIterator($dir_iterator); foreach ($iterator as $file) { // 只监控php文件 if (pathinfo($file, PATHINFO_EXTENSION) != 'php') { continue; } // 把文件加入inotify监控,这里只监控了IN_MODIFY文件更新事件 $wd = inotify_add_watch($worker->inotifyFd, $file, IN_MODIFY); $monitor_files[$wd] = $file; } // 监控inotify句柄可读事件
public function init() { $this->ifd = inotify_init(); $this->wd = inotify_add_watch($this->ifd, $this->path, self::MASK); }
protected function watchPackages(InputInterface $input, OutputInterface $output) { if (!function_exists('inotify_init')) { throw new \RuntimeException('Watch require inotify support, please install the inotify extension http://php.net/inotify'); } $packageNames = $input->getArgument('package'); if (empty($packageNames)) { $packageNames = array_keys($this->packages); } $inotify = inotify_init(); $watches = []; $mapping = []; foreach ($packageNames as $packageName) { if (!isset($this->packages[$packageName])) { throw new \RuntimeException('The package "' . $packageName . '" does not exist'); } if ($output->getVerbosity() >= OutputInterface::VERBOSITY_NORMAL) { $output->writeln(sprintf('* start watching package <comment>%s</comment>', $packageName)); } $package = $this->packages[$packageName]; $this->addWatches($package, $package, $mapping, $watches, $inotify, $output); } while (true) { if ($output->getVerbosity() >= OutputInterface::VERBOSITY_NORMAL) { $output->writeln('* <info>waiting for modifications</info>'); } $events = inotify_read($inotify); if (is_array($events)) { foreach ($events as $event) { $pathname = $watches[$event['wd']]; $packages = $mapping[$pathname]; if ($output->getVerbosity() >= OutputInterface::VERBOSITY_NORMAL) { $output->writeln(sprintf('modification on <comment>%s</comment> detected', $pathname)); } foreach ($packages as $package) { try { $this->buildPackage($package, $input, $output); } catch (\Exception $e) { $this->getApplication()->renderException($e, $output); } } } } } }
<?php // Open an inotify instance $fd = inotify_init(); // Watch __FILE__ for metadata changes (e.g. mtime) $watch_descriptor = inotify_add_watch($fd, __DIR__ . '/php', IN_MODIFY | IN_MOVED_FROM | IN_CREATE | IN_DELETE | IN_ISDIR); while (true) { // Read events $events = inotify_read($fd); print_r($events); }
function watchDir() { $this->ifds['dir'] = inotify_init(); $this->wds['dir'] = inotify_add_watch($this->ifds['dir'], $this->path, self::DIR_MASK); }