Skip to content

Commit 73a18b2

Browse files
author
zhanghy
committed
first commit
0 parents  commit 73a18b2

File tree

4 files changed

+243
-0
lines changed

4 files changed

+243
-0
lines changed

composer.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "zanehy/sqlmonitor",
3+
"description": "laravel moniro sql exec",
4+
"license": "MIT",
5+
"authors": [
6+
{
7+
"name": "zanehy",
8+
"email": "[email protected]"
9+
}
10+
],
11+
"require": {},
12+
"autoload": {
13+
"psr-4": {
14+
"Zanehy\\SqlMonitor\\": "src/"
15+
}
16+
},
17+
"autoload-dev": {
18+
"psr-4": {
19+
"Zanehy\\SqlMonitor\\Tests\\": "tests/"
20+
}
21+
}
22+
}

config/monitor.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: zhanghy<[email protected]>
5+
* Date: 2019-11-10
6+
* Time: 09:48
7+
*/
8+
9+
return [
10+
11+
'app' => env("APP_ENV", ''),
12+
'sql-monitor' => env("SQL_MONITOR", false),
13+
];

src/SqlMonitoServiceProvider.php

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: zhanghy<[email protected]>
5+
* Date: 2019-11-04
6+
* Time: 23:49
7+
*/
8+
9+
namespace Zanehy\SqlMonitor;
10+
11+
use Illuminate\Database\Events\QueryExecuted;
12+
use Illuminate\Http\Request;
13+
use Illuminate\Support\Facades\Log;
14+
use Illuminate\Support\ServiceProvider;
15+
16+
class SqlMonitorServiceProvider extends ServiceProvider
17+
{
18+
19+
/**
20+
* The Laravel application instance.
21+
*
22+
* @var \Illuminate\Foundation\Application
23+
*/
24+
public $app;
25+
26+
27+
/**
28+
* SqlMonitorServiceProvider constructor.
29+
* @param $app
30+
*/
31+
public function __construct($app)
32+
{
33+
parent::__construct($app);
34+
$this->app = app();
35+
}
36+
37+
38+
/**
39+
* Register services.
40+
* @return void
41+
*/
42+
public function register()
43+
{
44+
//获取配置文件路径并合并配置
45+
$configPath = __DIR__ . '/../config/monitor.php';
46+
$this->mergeConfigFrom($configPath, 'monitor');
47+
}
48+
49+
50+
/**
51+
* 合并配置文件
52+
* @auther zhanghy<[email protected]>
53+
* @Date 2019-11-10
54+
* @param string $path
55+
* @param string $key
56+
*/
57+
protected function mergeConfigFrom($path, $key)
58+
{
59+
$config = $this->app['config']->get($key, []);
60+
$this->app['config']->set($key, array_merge(require $path, $config));
61+
}
62+
63+
64+
/**
65+
* 启动
66+
* @auther zhanghy<[email protected]>
67+
* @Date 2019-11-06
68+
*/
69+
public function boot()
70+
{
71+
72+
if (($this->app['config']->get('monitor.app') == "local") || $this->app['config']->get('monitor.sql-monitor')) {
73+
74+
$db = $this->app['db'];
75+
$db->listen(
76+
function ($query) {
77+
if ( $query instanceof \Illuminate\Database\Events\QueryExecuted ) {
78+
79+
//获取当前监听的文件和行数
80+
$stacks = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 50);
81+
82+
//打印监听日志
83+
$this->sqlMonitor($query, $stacks);
84+
} else {
85+
Log::error("sqlmonitorError: Not listening QueryExecuted");
86+
}
87+
}
88+
);
89+
}
90+
}
91+
92+
93+
94+
/**
95+
* 监听
96+
* @auther zhanghy<[email protected]>
97+
* @Date 2019-11-05
98+
* @param QueryExecuted $event
99+
*/
100+
private function sqlMonitor(QueryExecuted $event, array $stacks)
101+
{
102+
$sql = str_replace("?", "'%s'", $event->sql);
103+
$sql = vsprintf($sql, $event->bindings);
104+
$urlPath = Request::capture()->path();
105+
106+
//检索执行的文件和行数
107+
$res = [];
108+
foreach ($stacks as $stack) {
109+
if (isset($stack['class']) && isset($stack['file']) && !$this->fileIsInExcludedPath($stack['file'])) {
110+
$stack['file'] = $this->normalizeFilename($stack['file']);
111+
$res = $stack;
112+
break;
113+
}
114+
}
115+
116+
//记录日志
117+
Log::info(json_encode([
118+
'action' => 'sqlmonitor:'. $urlPath,
119+
'path' => $urlPath,
120+
'sql' => $sql,
121+
'time' => $event->time . 'ms',
122+
'file' => ($res['file'] ?? ''),
123+
'line' => ($res['line'] ?? '')
124+
]));
125+
}
126+
127+
/**
128+
* 检查给定文件是否要从分析中排除
129+
* @auther zhanghy<[email protected]>
130+
* @Date 2019-11-05
131+
* @param $file
132+
* @return bool
133+
*/
134+
private function fileIsInExcludedPath($file)
135+
{
136+
$excludedPaths = [
137+
'/vendor/laravel/framework/src/Illuminate/Database',
138+
'/vendor/laravel/framework/src/Illuminate/Events',
139+
'/vendor/barryvdh/laravel-debugbar',
140+
];
141+
142+
$normalizedPath = str_replace('\\', '/', $file);
143+
foreach ($excludedPaths as $excludedPath) {
144+
if (strpos($normalizedPath, $excludedPath) !== false) {
145+
return true;
146+
}
147+
}
148+
return false;
149+
}
150+
151+
/**
152+
* 通过删除相对链接和基本目录来缩短路径
153+
* @auther zhanghy<[email protected]>
154+
* @Date 2019-11-05
155+
* @param $path
156+
* @return mixed
157+
*/
158+
private function normalizeFilename($path)
159+
{
160+
if (file_exists($path)) {
161+
$path = realpath($path);
162+
}
163+
return str_replace(base_path(), '', $path);
164+
}
165+
166+
167+
168+
}

src/SqlMonitor.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: zhanghy<[email protected]>
5+
* Date: 2019-11-04
6+
* Time: 23:52
7+
*/
8+
9+
namespace Zanehy\SqlMonitor;
10+
11+
class SqlMonitor
12+
{
13+
14+
public $sqlQuery;
15+
16+
/**
17+
* 测试输出执行
18+
* @auther zhanghy<[email protected]>
19+
* @Date 2019-11-04
20+
*/
21+
public function printRunning()
22+
{
23+
echo "printRunning running";
24+
}
25+
26+
public function addQuery($sql)
27+
{
28+
$this->sqlQuery = $sql;
29+
}
30+
31+
public function getQuery()
32+
{
33+
dd("getQuery", $this->sqlQuery);
34+
}
35+
36+
37+
38+
39+
}
40+

0 commit comments

Comments
 (0)