Skip to content

Commit f7487eb

Browse files
committed
feat(core): 最初版本提交
1 parent 346fdd2 commit f7487eb

File tree

6 files changed

+718
-0
lines changed

6 files changed

+718
-0
lines changed

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
composer.phar
2+
/vendor/
3+
4+
# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control
5+
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
6+
# composer.lock
7+
8+
test.php

README.md

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
# hejunjie/lazylog
2+
3+
<div align="center">
4+
<a href="./README.md">English</a>|<a href="./README.zh-CN.md">简体中文</a>
5+
<hr width="50%"/>
6+
</div>
7+
8+
A lightweight PHP logging library providing **safe local log writing** and **remote exception reporting** (both synchronous and asynchronous).
9+
10+
> Why this library exists:
11+
> While working on my Go project [oh-shit-logger](https://github.com/zxc7563598/oh-shit-logger), I needed a centralized way to collect error information.
12+
> Some friends were concerned about the performance overhead of PHP error reporting, so I wrapped my usual approach into a Composer package for easier reuse.
13+
14+
**This project has been parsed and summarized by Zread. For a quick overview, check here:** [Project Overview](https://zread.ai/zxc7563598/php-milvus)
15+
16+
---
17+
18+
## Installation
19+
20+
```bash
21+
composer require hejunjie/lazylog
22+
```
23+
24+
---
25+
26+
## Usage
27+
28+
`lazylog` provides three core methods:
29+
30+
---
31+
32+
### Write Local Logs
33+
34+
```php
35+
use Hejunjie\Lazylog\Logger;
36+
37+
/**
38+
* Write logs safely to local files (thread-safe + auto file rotation)
39+
*
40+
* @param string $basePath Base log directory (e.g. /var/logs or runtime/logs)
41+
* @param string $fileName Log filename (can include subpath like "error/app.log")
42+
* @param string $title Log title (e.g. "Error in Task #12")
43+
* @param string|array|object $content Log content (array, object, or string)
44+
* @param int $maxLines Max lines per file before rotation (default: 10,000)
45+
* @param int $maxSizeKB Max file size in KB before rotation (default: 2048 = 2MB)
46+
*
47+
* @return void
48+
*/
49+
Logger::write(
50+
'/var/logs',
51+
'error/app.log',
52+
'Task Failed',
53+
['message' => 'Something went wrong']
54+
);
55+
```
56+
57+
---
58+
59+
### Asynchronous Exception Reporting
60+
61+
- Uses `exec()` / `proc_open()` to spawn a background PHP process that sends a POST request
62+
- Non-blocking for the main process
63+
- **Not recommended** in long-running frameworks (Webman / Swoole)
64+
since they keep workers alive for a long time — frequent forking may accumulate resources (zombie processes, memory leaks, etc.)
65+
66+
```php
67+
try {
68+
// Code that may throw
69+
} catch (\Throwable $exception) {
70+
/**
71+
* Report exception asynchronously to a remote endpoint.
72+
*
73+
* @param Throwable $exception The captured exception
74+
* @param string $url Remote endpoint URL
75+
* @param string $project Project identifier (default: unknown-project)
76+
* @param array $context Additional context data (e.g. request info, env vars)
77+
* @param string $phpBinary PHP binary path for subprocess (default: php)
78+
*
79+
* @return void
80+
*/
81+
Logger::reportAsync($exception, 'https://error.example.com/collect', 'my-project');
82+
}
83+
```
84+
85+
> For low-frequency error reporting, the performance cost of forking a PHP subprocess is negligible.
86+
87+
---
88+
89+
### Synchronous Exception Reporting
90+
91+
- Recommended for long-running frameworks or when immediate reporting is needed
92+
- Avoids creating subprocesses, preventing potential zombie or leaked processes
93+
Long-running workers in frameworks like Webman/Swoole are reused between requests — even if synchronous calls block, they only affect the current worker, not others.
94+
95+
```php
96+
try {
97+
// Code that may throw
98+
} catch (\Throwable $exception) {
99+
/**
100+
* Report exception synchronously to a remote endpoint.
101+
*
102+
* @param Throwable $exception The captured exception
103+
* @param string $url Remote endpoint URL
104+
* @param string $project Project identifier (default: unknown-project)
105+
* @param array $context Additional context data
106+
* @param int $timeout Timeout in seconds
107+
*
108+
* @return void
109+
*/
110+
Logger::reportSync($exception, 'https://error.example.com/collect', 'my-project');
111+
}
112+
```
113+
114+
#### Optimization Suggestion
115+
116+
For long-running frameworks, it’s often better to enqueue exceptions and handle reporting via a background worker:
117+
118+
```php
119+
try {
120+
// Code that may throw
121+
} catch (\Throwable $exception) {
122+
/**
123+
* Format exception data before sending
124+
*
125+
* @param Throwable $exception The captured exception
126+
* @param string $project Project name
127+
* @param array $context Additional context info (default: empty)
128+
*
129+
* @return array
130+
*/
131+
$formatted = Logger::formatThrowable($exception, 'my-project');
132+
// Push $formatted into a queue
133+
// Then let your worker consume and send it
134+
}
135+
```
136+
137+
---
138+
139+
## Motivation
140+
141+
- To provide a **lightweight, unified logging solution** for quickly sending PHP exception data to my Go project **[oh-shit-logger](https://github.com/zxc7563598/oh-shit-logger)**
142+
- To avoid writing repetitive error reporting logic across multiple projects
143+
- Supports **safe local logging + async/sync remote reporting**, suitable for PHP-FPM, CLI, and long-running frameworks
144+
145+
---
146+
147+
## Additional Notes
148+
149+
- Asynchronous reporting works by forking a PHP CLI subprocess
150+
- For low-frequency errors, overhead is minimal and generally safe
151+
- Under high concurrency (thousands per second), consider using a queue + worker or coroutine async (Though realistically, error reporting shouldn’t reach that volume 😅)
152+
- Local logging includes automatic rotation to prevent oversized files during long-term use
153+
154+
---
155+
156+
## Issues & Contributions
157+
158+
Have ideas, feedback, or bug reports?
159+
Feel free to open an Issue or Pull Request on GitHub! 🚀

README.zh-CN.md

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
# hejunjie/lazylog
2+
3+
<div align="center">
4+
<a href="./README.md">English</a>|<a href="./README.zh-CN.md">简体中文</a>
5+
<hr width="50%"/>
6+
</div>
7+
8+
轻量级 PHP 日志库,提供**本地日志安全写入**以及**异常信息远程上报**(同步/异步)。
9+
10+
> 这个库诞生的原因:我在做一个 Go 项目 [oh-shit-logger](https://github.com/zxc7563598/oh-shit-logger) 时,需要集中收集错误信息
11+
>
12+
> 有些朋友一直担心 PHP 错误上报的性能问题,所以我把在项目中常用的方式封装成了一个 Composer 库,方便直接使用。
13+
14+
**本项目已经经由 Zread 解析完成,如果需要快速了解项目,可以点击此处进行查看:[了解本项目](https://zread.ai/zxc7563598/php-milvus)**
15+
16+
---
17+
18+
## 安装
19+
20+
```bash
21+
composer require hejunjie/lazylog
22+
```
23+
24+
---
25+
26+
## 使用方法
27+
28+
`lazylog` 提供三个核心方法:
29+
30+
---
31+
32+
### 写本地日志
33+
34+
```php
35+
use Hejunjie\Lazylog\Logger;
36+
37+
/**
38+
* 写入本地日志(线程安全 + 自动分文件)
39+
*
40+
* @param string $basePath 日志基础目录(例如 /var/logs 或 runtime/logs)
41+
* @param string $fileName 日志文件名(可包含子路径,如 "error/app.log")
42+
* @param string $title 日志标题(如 "Error in Task #12")
43+
* @param string|array|object $content 日志内容(详细描述,可为数组、对象、字符串)
44+
* @param int $maxLines 超过多少行自动切分(默认 10_000)
45+
* @param int $maxSizeKB 超过多少 KB 自动切分(默认 2048,即 2MB)
46+
*
47+
* @return void
48+
*/
49+
Logger::write(
50+
'/var/logs',
51+
'error/app.log',
52+
'Task Failed',
53+
['message' => 'Something went wrong']
54+
)
55+
```
56+
57+
---
58+
59+
### 异步上报异常
60+
61+
- 使用 `exec()` / `proc_open()` 在后台异步发送 POST 请求
62+
- 主进程不阻塞
63+
- 不推荐在常驻内存框架(Webman/Swoole)中使用,仅适用于传统方式
64+
常驻内存框架长期保持进程,如果频繁 fork 子进程,可能导致资源累积(如僵尸进程、内存泄漏)
65+
66+
```php
67+
try {
68+
// 可能抛出异常的代码
69+
} catch (\Throwable $exception) {
70+
/**
71+
* 异步上报异常信息到远程服务。
72+
*
73+
* @param Throwable $exception 捕获的异常对象,将被格式化后上报
74+
* @param string $url 远程上报服务的 URL
75+
* @param string $project 项目标识(默认:unknown-project)
76+
* @param array $context 额外上下文数据(例如请求信息、环境变量等、默认空数组)
77+
* @param string $phpBinary PHP 可执行文件路径(用于子进程执行,默认:php)
78+
*
79+
* @return void
80+
*/
81+
Logger::reportAsync($exception, 'https://error.example.com/collect', 'my-project');
82+
}
83+
```
84+
85+
> 对于低频错误上报,异步 fork 子进程的性能开销非常小,足够使用。
86+
87+
---
88+
89+
### 同步上报异常
90+
91+
- 在常驻内存框架或需要立即上报时使用
92+
- 避免 fork 子进程带来的资源累积和潜在僵尸进程问题
93+
常驻内存框架的 Worker 可以复用,不会像短生命周期的请求那样频繁创建/销毁进程,即使阻塞,也只占用该 Worker,不会影响其他 Worker
94+
95+
```php
96+
try {
97+
// 可能抛出异常的代码
98+
} catch (\Throwable $exception) {
99+
/**
100+
* 同步上报异常信息到远程服务。
101+
*
102+
* @param Throwable $exception 捕获的异常对象,将被格式化后上报
103+
* @param string $url 远程上报服务的 URL
104+
* @param string $project 项目标识(默认:unknown-project)
105+
* @param array $context 额外上下文数据(例如请求信息、环境变量等)
106+
* @param int $timeout 超时时间(秒)
107+
*
108+
* @return void
109+
*/
110+
Logger::reportSync($exception, 'https://error.example.com/collect', 'my-project');
111+
}
112+
```
113+
114+
#### 优化方案
115+
116+
通常情况下,常驻内存框架建议开一条队列来处理异常上报
117+
118+
```php
119+
try {
120+
// 可能抛出异常的代码
121+
} catch (\Throwable $exception) {
122+
/**
123+
* 格式化错误信息
124+
*
125+
* @param Throwable $exception 捕获的异常对象
126+
* @param string $project 项目名称
127+
* @param array $context 额外的上下文信息,默认空数组
128+
*
129+
* @return array
130+
*/
131+
$formatThrowable = Logger::formatThrowable($exception, 'my-project');
132+
// 将 formatThrowable 投递到队列中
133+
// 直接在队列中发送数据
134+
}
135+
```
136+
137+
---
138+
139+
## 制作初衷
140+
141+
- 提供一个轻量级、统一的日志方案,用于**快速将 PHP 项目的异常信息上报到我的 Go 项目** **[oh-shit-logger](https://github.com/zxc7563598/oh-shit-logger)**
142+
- 避免在每个项目里重复实现错误收集和远程上报逻辑
143+
- 支持​**本地安全写入 + 异步/同步远程上报**,方便不同环境(PHP-FPM、CLI、常驻内存框架)使用
144+
145+
---
146+
147+
## 额外说明
148+
149+
- 异步上报采用 fork PHP CLI 子进程实现
150+
- 低频错误上报场景下性能消耗非常小,无需担心系统压力
151+
- 高并发场景(每秒上千次)可能会产生系统开销,可考虑队列 + worker 或协程异步(但应该不会出现错误信息高并发吧???)
152+
- 本地日志支持自动切分,保证长期运行不会单文件过大
153+
154+
---
155+
156+
## 欢迎 Issues
157+
158+
有任何问题、建议或改进思路,欢迎在 GitHub 提交 Issues!

composer.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "hejunjie/lazylog",
3+
"description": "轻量级 PHP 日志库,提供本地日志安全写入以及异常信息远程上报(同步/异步) | A lightweight PHP logging library providing safe local log writing and remote exception reporting (both synchronous and asynchronous)",
4+
"type": "library",
5+
"license": "MIT",
6+
"autoload": {
7+
"psr-4": {
8+
"Hejunjie\\Lazylog\\": "src/"
9+
}
10+
},
11+
"authors": [
12+
{
13+
"name": "何俊杰",
14+
"email": "junjie.he.925@gmail.com"
15+
}
16+
],
17+
"require": {}
18+
}
19+

0 commit comments

Comments
 (0)