Skip to content

Commit 23742c3

Browse files
committed
记录 laravel - sql 日志
1 parent 5678cb7 commit 23742c3

File tree

4 files changed

+167
-5
lines changed

4 files changed

+167
-5
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
.idea/
12
/vendor/
23
node_modules/
34
npm-debug.log
@@ -21,3 +22,5 @@ Homestead.yaml
2122
Homestead.json
2223
/.vagrant
2324
.phpunit.result.cache
25+
26+
composer.lock

composer.json

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
{
2-
"name": "zhy/laravel-sql-trace",
2+
"name": "zhy-code/laravel-sql-trace",
33
"description": "SQL Trace For Laravel",
44
"type": "composer-plugin",
5-
"license": "Apache-2.0 license",
5+
"require": {
6+
"php": "^7.3"
7+
},
8+
"license": "MIT",
69
"autoload": {
710
"psr-4": {
8-
"Zhy\\LaravelSqlTrace\\": "src/"
11+
"ZhyCode\\LaravelSqlTrace\\": "src/"
912
}
1013
},
1114
"authors": [
1215
{
1316
"name": "zhy"
1417
}
15-
],
16-
"require": {}
18+
]
1719
}

config/sql_trace.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
return [
4+
5+
/**
6+
* 是否开启监听
7+
*/
8+
'open_listen_sql' => true,
9+
10+
/**
11+
* 日志的路径, 默认在 storage/logs/ 下
12+
*/
13+
'sql_log_path' => '',
14+
15+
/**
16+
* 慢 SQL 时间 (ms)
17+
*/
18+
'slow_sql_time' => 1000,
19+
20+
/**
21+
* 严重警告的 sql 执行时间 (ms)
22+
*/
23+
'danger_sql_time' => 3000
24+
25+
];

src/SQLTraceServiceProvider.php

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
<?php
2+
3+
namespace ZhyCode\LaravelSqlTrace;
4+
5+
use Illuminate\Database\Events\QueryExecuted;
6+
use Illuminate\Support\ServiceProvider;
7+
use DB;
8+
9+
class SQLTraceServiceProvider extends ServiceProvider
10+
{
11+
/**
12+
* Perform post-registration booting of services.
13+
* @return void
14+
*/
15+
public function boot(): void
16+
{
17+
// Publishing is only necessary when using the CLI.
18+
if ($this->app->runningInConsole()) {
19+
$this->bootForConsole();
20+
}
21+
22+
$isOpenListen = config('sql_trace.open_listen_sql');
23+
$sqlLogPath = config('sql_trace.sql_log_path', storage_path('/logs/'));
24+
25+
if ($isOpenListen) {
26+
$traceId = $_REQUEST['trace_id'] ?? uniqid(bin2hex(random_bytes(10)),true);
27+
28+
DB::listen(function (QueryExecuted $sql) use ($traceId, $sqlLogPath) {
29+
// 处理绑定的数据
30+
foreach ($sql->bindings as $i => $binding) {
31+
if ($binding instanceof \DateTime) {
32+
$sql->bindings[$i] = $binding->format('\'Y-m-d H:i:s\'');
33+
} else {
34+
if (is_string($binding)) {
35+
$sql->bindings[$i] = "'$binding'";
36+
}
37+
}
38+
}
39+
40+
$trace_sql = str_replace(array('%', '?'), array('%%', '%s'), $sql->sql);
41+
$trace_sql = str_replace(array('\r\n', '\r', '\n'),' ', $trace_sql);
42+
$trace_sql = vsprintf($trace_sql, $sql->bindings);
43+
foreach ($sql->bindings as $key => $val) {
44+
if (!is_numeric($key)) {
45+
$trace_sql = str_replace(':' . $key, $val, $trace_sql);
46+
}
47+
}
48+
49+
$dbConf = $sql->connection->getConfig();
50+
if (isset($dbConf['password'])) {
51+
unset($dbConf['password']);
52+
}
53+
54+
$logPath = $sqlLogPath . '.sql_trace.' . now()->toDateString() . '.log';
55+
56+
file_put_contents($logPath,json_encode([
57+
'level' => $this->getSqlLevelByExecTime($sql->time),
58+
'app_env' => config('app.env') ?? '',
59+
'app_name' => config('app.name') ?? '',
60+
'req_uri' => request()->url() ?? '',
61+
'req_method' => request()->method() ?? '',
62+
'req_body' => request()->all() ?? null,
63+
'db_conf' => $dbConf,
64+
'db_connection_name' => $sql->connectionName,
65+
'trace_id' => $traceId,
66+
'trace_datetime' => now()->toDateTimeString(),
67+
'trace_sql_bindings' => $sql->bindings,
68+
'execute_sql' => $trace_sql,
69+
'execute_ms' => $sql->time,
70+
]).PHP_EOL,FILE_APPEND);
71+
});
72+
}
73+
}
74+
75+
/**
76+
* Register any package services.
77+
*
78+
* @return void
79+
*/
80+
public function register(): void
81+
{
82+
$this->mergeConfigFrom(__DIR__.'/../config/sql_trace.php', 'sqlTrace');
83+
}
84+
85+
/**
86+
* Get the services provided by the provider.
87+
*
88+
* @return array
89+
*/
90+
public function provides()
91+
{
92+
return ['SqlTrace'];
93+
}
94+
95+
/**
96+
* Console-specific booting.
97+
*
98+
* @return void
99+
*/
100+
protected function bootForConsole(): void
101+
{
102+
// Publishing the configuration file.
103+
$this->publishes(
104+
[
105+
__DIR__.'/../config/sql_trace.php' => config_path('config.php'),
106+
],
107+
'sql_trace.config'
108+
);
109+
}
110+
111+
/**
112+
* 根据执行时间,返回 SQL 执行等级
113+
* @param $time
114+
* @return string
115+
*/
116+
protected function getSqlLevelByExecTime($time)
117+
{
118+
$traceConfig = config('trace');
119+
120+
$dangerTime = $traceConfig['danger_sql_time'] ?? 0;
121+
122+
$warnTime = $traceConfig['slow_sql_time'] ?? 0;
123+
124+
if ($dangerTime && $time >= $dangerTime) {
125+
return 'danger';
126+
} elseif ($warnTime && $time >= $warnTime) {
127+
return 'warning';
128+
} else {
129+
return 'info';
130+
}
131+
}
132+
}

0 commit comments

Comments
 (0)