PHP简单实现定时监控nginx日志文件功能示例
<?php
namespace App\Repositories;
use Illuminate\Support\Facades\Redis;
class LogRepository extends BaseRepository
{
public $logNameArr = ''; //读取的日志文件列表
public $logName = ''; //读取的日志文件
public $notifyUrl = ''; //企微机器人通知地址
public $size = '2000'; //分页数据大小
public $redisPrefix = 'LogController:getFilesize5'; //redis前缀,每个文件re对应不同的key!!!
function __construct()
{
$this->logNameArr = [
storage_path() . '/logs/laravel-' . date('Y-m-d') . '.log',//日志路径
];
}
/**
* 将错误日志通知到微信
*/
public function handle()
{
if (!empty($this->logNameArr)) {
foreach ($this->logNameArr as $logName) {
$this->logName = $logName;
if (!file_exists($this->logName)) {
continue;
}
try {
$logSize = $this->getFilesize();
//运行时log文件原始大小
if (empty($logSize)) {//没有记录上次位置,则从初始位置开始
$file_size = 0;
} else { //从上次记录的位置开始
$file_size = $logSize;
}
$fp = fopen($this->logName, "r");
$n = 1;
while ($n < 2) {
clearstatcache();
$file_size_new = filesize($this->logName);
$add_size = $file_size_new - $file_size;
$add_log = '';
if ($add_size > 0) {
fseek($fp, $file_size);
//当增加量超过8192,需要分页读取增加量
$page = ceil($add_size / $this->size);
for ($i = 1; $i <= $page; $i++) {
if ($i == $page) {//最后一页
$end_add = $add_size - ($page - 1) * $this->size;
$add_log = fread($fp, $end_add);
} else {
$add_log = fread($fp, $this->size);
$file_size_step = $file_size + $i * $this->size;
fseek($fp, $file_size_step);
}
sleep(1);
$this->sendWeiXin($add_log);
}
$file_size = $file_size_new;
//记录当前位置
$this->saveFilesize($file_size);
}
$n++;
}
fclose($fp);
} catch (\Exception $e) {
var_dump($e->getMessage());;
}
}
}
echo 'LogRepository done';
exit();
}
/**
* 每次启动时获取上次打开文件位置
*/
public function getFilesize()
{
$size = redis::get($this->redisPrefix . $this->logName);
return $size ?: 0;
}
/**
* 每次提交后保存这次读取文件的位置
*/
public function saveFilesize($size)
{
return redis::setex($this->redisPrefix . $this->logName, 86400, $size);
}
public function sendWeiXin($content)
{
$app = env('APP_ENV', '');
if ($app == 'master') {
$title = '正式环境告警:' . PHP_EOL;
} else if ($app == 'dev') {
$title = '测试环境告警:' . PHP_EOL;
}
$data = [
'msgtype' => 'text',
'text' => [
'content' => $title . '日志路径' . $this->logName . PHP_EOL . $content,
],
];
$return_header = ["Content-Type: application/json"];
$data = json_encode($data);
$res = $this->httpPost($this->notifyUrl, $data, $return_header);
return $res;
}
/**
* http请求
*
* @param array $data
*
* @return boolean
*/
public function httpPost($url = '', $data = [], $header)
{
if (empty($url)) {
return FALSE;
}
if ($data) {
//$data = http_build_query($data);
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
if (!empty($header)) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
}
$return = curl_exec($ch);
curl_close($ch);
return $return;
}
}