不败君

前端萌新&初级后端攻城狮

PHP 日志记录处理类

PHP 日志记录处理类

2021-04-03 00:01:20

围观(6222)

进行项目开发,一定离不开打日志,特别是一些可能存在不受管控的应用场景,就需要打更多的日志。

例如调用 API 接口时发起的网络请求,从发起请求直到返回数据就可以陆续打日志,通过日志就可以准确定位 BUG,否则出了 BUG 没有日志,根本不知道请求前后发生了什么,以及接口返回的数据是什么。


但是日志打多了就又会有新的问题出现,例如有些框架 / 系统打的日志只有一个日志文件,导致日志文件极大,可能几百 M 甚至几十个 G。

有些则是一天打一个日志文件,有时候可能某天的日志量比较大,达到几百 M 以上,这时候想要打开日志文件查看一些信息是极度难受的,因为文件太大,打开太慢甚至会系统奔溃。


于是博主造了一个日志记录的轮子。

它可以按天及按文件大小分开不同的日志文件存储。 

例如打日志时会生成 20210402_0.log 文件,如果该文件超出自定义设置的一定大小时,会将日志存储到 20210402_1.log 中,以此类推没有上限。

每个日志文件内的格式是这样的:

[2021-04-02 16:49:09][debug] 日志内容
[2021-04-02 16:49:09][info] 日志内容
[2021-04-02 16:49:09][error] 日志内容

打日志的方法也极其简单:

Log::error('日志内容');
Log::debug('日志内容');
Log::info('日志内容');

除了 error 和 debug 这些,还可以自定义更多的错误类型。


测试定义每个日志文件 10 M 大小:

1.jpg

可以看到 每个文件都是在 10 M 左右.

当然,有优点肯定会有缺点,缺点就是需要自定义每天最大的日志文件数量,例如设置每天最多三个日志文件,则超出文件后会抛出异常(可另行自定义处理)。


放上博主写的日志记录类:

class Log
{
	private static $path = 'log/';			// 日志存储路径
	private static $maxFileSize = 10240; 	// 单个日志文件最大存储容量 单位 KB
	private static $maxLogFiles = 3;		// 最大支持日志文件数量
	private static $filename = '';
	private static $currentFileNum = null;

	public static function __callStatic($methodName, $params)
	{
		if (empty($params[0])) {
			throw new Exception("Error : Lack message");
		}

		$lstMethod = ['error', 'info', 'debug'];
		if (!in_array($methodName, $lstMethod)) {
			throw new Exception("Error : Not {$methodName} method");
		}

		$msg = "[{$methodName}] {$params[0]}" . "\n";
		self::write($msg);
	}

	private static function getFile()
	{
		if (!is_dir(self::$path)) {
			mkdir(self::$path);
		}

		$filename = date('Ymd') . '_';

		for ($i = self::$maxLogFiles - 1; $i >= 0; --$i) {

			$filenamePath = self::$path . $filename . $i . '.log';
			$currentFilename = $filename . $i . '.log';

			if (!is_file($filenamePath)) {
				self::$currentFileNum = $i;
				self::$filename = $currentFilename;
				continue;
			}

			$fileSize = filesize($filenamePath) / 1024;
			if ($fileSize < self::$maxFileSize) {
				self::$filename = $currentFilename;
				return self::$currentFileNum = $i;
			}

			if (self::$currentFileNum == null && $i + 1 >= self::$maxLogFiles) {
				throw new Exception('日志最大文件数量超出');
			}

			return self::$currentFileNum = ++$i;
		}
	}

	private static function write(string $msg)
	{
		self::getFile();
		$date = date('Y-m-d H:i:s');
		$msg = "[{$date}]{$msg}";
		file_put_contents(self::$path . self::$filename, $msg, FILE_APPEND | LOCK_EX);
	}
}

通过代码可以看到,其实很简单的原理。

无非就是使用定义的文件数量去倒数,倒数到不存在的文件就暂存,直到算出最小的那个文件,如果最小那个文件已经超出存储大小则不暂存,最后如果拿不到暂存的文件就肯定是超出文件数量了,能拿到暂存的文件就可以直接写入文件。

还有个缺点,如果文件数量设置比较大,也会增加每次打日志时判断文件的性能消耗。

本文地址 : bubaijun.com/page.php?id=234

版权声明 : 未经允许禁止转载!

评论:我要评论

去吐槽 沙发

你好!可以交换个友链吗?贵站链接我已经加好了,在首页,您看一下如果有意就加个,谢谢! 网站名称:去吐槽网 网址:https://www.qutucao.com 网址内容:Pi币及Bee币相关资讯,区块链技术等 图标地址:https://www.qutucao.com/wp-content/uploads/2021/03/cropped-qutucao006-65x65.png

评论时间:2021-05-26 09:51:28

回复

不败君 板凳

@去吐槽 抱歉,贵站应该是刚建站没多久,小弟博客友链要求是站龄需半年以上的。

评论时间:2021-05-26 10:29:25

回复

容添下

麻雀虽小五脏俱全

评论时间:2021-06-05 16:49:56

回复

发布评论:
Copyright © 不败君 粤ICP备18102917号-1

不败君

首 页 作 品 微 语