当前位置:AIGC资讯 > 数据采集 > 正文

TransferStatistics使用实例:应用和SQL监控系统workerman

本文环境 CentOS8.0,PHP8.1,Nginx1.8,Workerman 4.0
不懂的可以评论或联系我邮箱:owen@owenzhang.com
著作权归OwenZhang所有。商业转载请联系OwenZhang获得授权,非商业转载请注明出处。

TransferStatistics项目

TransferStatistics 使用webman开发的一个应用监控系统,用于查看应用调用记录、请求量、调用耗时、调用分析等。

系统使用UDP接收上报数据;使用Redis存储、汇总数据

项目地址

https://github.com/hsk99/transfer-statistics

所需环境

PHP版本不低于7.3,并安装 Redis 拓展

安装

composer安装

创建项目

composer create-project hsk99/transfer-statistics

下载安装

1、下载 或git clone https://github.com/hsk99/transfer-statistics

2、执行命令composer install

配置

1、config/redis.php 设置 Redis

<?php

return [
    'default' => [
        'host'     => env('REDIS_HOST', '127.0.0.1'),
        'password' => env('REDIS_PASSWORD', ''),
        'port'     => env('REDIS_PORT', '6379'),
        'database' => 7,
        'prefix'   => 'statistic:',
    ],
];

2、config/app.php 设置 登录用户名、密码

<?php

return [
    'debug'            => true,
    'default_timezone' => 'Asia/Shanghai',
    'admin_name'       => 'root',
    'admin_password'   => 'owenzhang',
];

3、config/server.php 设置 WebServer

<?php

return [
    'listen'           => 'http://127.0.0.1:8788',
    'transport'        => 'tcp',
    'context'          => [],
    'name'             => 'server',
    'count'            => 1,
    'user'             => '',
    'group'            => '',
    'pid_file'         => runtime_path() . '/master.pid',
    'stdout_file'      => runtime_path() . '/stdout.log',
    'log_file'         => runtime_path() . '/master.log',
    'max_request'      => 1000000,
    'max_package_size' => 100 * 1024 * 1024,
];

4、config/process.php 设置 采集服务

<?php

return [
    // File update detection and automatic reload
    'monitor' => [
        'handler'     => process\FileMonitor::class,
        'reloadable'  => false,
        'constructor' => [
            // Monitor these directories
            'monitor_dir' => [
                app_path(),
                config_path(),
                base_path() . '/process',
                base_path() . '/support',
                base_path() . '/resource',
                base_path() . '/.env',
                base_path() . '/expand',
                base_path() . '/Protocols',
            ],
            // Files with these suffixes will be monitored
            'monitor_extensions' => [
                'php', 'html', 'htm', 'env'
            ]
        ],
        'bootstrap' => []
    ],
    // Statistic
    'statistic' => [
        'handler'   => process\Statistic::class,
        'listen'    => 'statistic://0.0.0.0:55674',
        'count'     => 1,
        'transport' => 'udp',
        'bootstrap' => []
    ],
];

运行

执行命令php start.php start

查看统计

浏览器访问http://ip地址:8788

workerman项目的配置

config/app.php

添加上报地址

    'statisticAddress' => 'udp://127.0.0.1:55674', // udp上报地址 一般用于api接口请求

config/middleware.php

添加上报中间件

    'admin' => [
        \app\middleware\Statistic::class, // 接口请求即时上报
        \app\middleware\StatisticSQL::class, // SQL监控即时上报
        \app\middleware\ApiRoute::class,
        \app\middleware\ApiBaseRequest::class,
        \app\middleware\ActionHook::class,
    ],

app/middleware/Statistic.php

添加接口请求即时上报类

<?php

namespace app\middleware;

use Webman\MiddlewareInterface;
use Webman\Http\Response;
use Webman\Http\Request;
use app\extend\Client\StatisticClient;

class Statistic implements MiddlewareInterface
{
    public function process(Request $request, callable $next): Response
    {
        $ip         = $request->getRealIp(true);
        $controller = $request->controller;
        $action     = $request->action;
        $transfer   = $controller . '::' . $action;
        $project    = '充电动画项目';
        // 开始计时
        $unique   = StatisticClient::tick($project, $ip, $transfer);
        $response = $next($request);
        $code     = $response->getStatusCode();
        $success  = $code < 400;
        $details  = [
            'ip'              => $request->getRealIp(true) ?? '',                                             // 请求客户端IP
            'url'             => $request->fullUrl() ?? '',                                                             // 请求URL
            'method'          => $request->method() ?? '',                                                              // 请求方法
            'request_param'   => $request->all() ?? [],                                                                 // 请求参数
            'request_header'  => $request->header() ?? [],                                                              // 请求头
            'cookie'          => $request->cookie() ?? [],                                                              // 请求cookie
            'session'         => $request->session()->all() ?? [],                                                      // 请求session
            'response_code'   => $response->getStatusCode() ?? '',                                                      // 响应码
            'response_header' => $response->getHeaders() ?? [],                                                         // 响应头
            'response_body'   => $response->rawBody() ? json_decode($response->rawBody(), true) : [],             // 响应数据(发生异常)
        ];
        // 数据上报
        StatisticClient::report($unique, $project, $ip, $transfer, $success, $code, json_encode($details, JSON_PRESERVE_ZERO_FRACTION | JSON_NUMERIC_CHECK | JSON_UNESCAPED_UNICODE));
        return $response;
    }
}

app/middleware/StatisticSQL.php

开启ThinkORM SQL监听配置

// 监听SQL
        'trigger_sql'     => true,

文档网址: https://static.kancloud.cn/manual/think-orm/1257999

添加SQL监控即时上报类(ThinkORM )

<?php

namespace app\middleware;

use Webman\MiddlewareInterface;
use Webman\Http\Response;
use Webman\Http\Request;
use app\extend\Client\StatisticClient;

class StatisticSQL implements MiddlewareInterface
{
    public function process(Request $request, callable $next): Response
    {
        $response = $next($request);

        // SQL监控
        \think\facade\Db::listen(function ($sql, $runtime, $master) {
		    if ($sql == 'select 1') return true;
			
            $ip      = \request()->getRealIp(true) ?? '';
            $project = '充电动画项目SQL';

            switch (true) {
                case is_numeric($runtime):
                    $transfer = $sql;
                    $cost     = $runtime;
                    break;
                case !is_numeric($runtime) && 'CONNECT' === substr($sql, 0, 7):
                    @preg_match("/UseTime:([0-9]+(\\.[0-9]+)?|[0-9]+(\\.[0-9]+))/", $sql, $result);
                    if (count($result) > 1) {
                        $transfer = substr($sql, strpos($sql, "s ] ") + 4);
                        $cost     = $result[1];
                    } else {
                        $transfer = $sql;;
                        $cost = 0;
                    }
                    break;
                default:
                    $transfer = $sql;;
                    $cost = 0;
                    break;
            }
            StatisticClient::report('', $project, $ip, $transfer, true, 1, json_encode([
                'sql'     => $sql,
                'runtime' => $cost . 's',
                'master'  => $master,
            ], 320), $cost);
        });

        return $response;
    }
}

看效果图

Buy me a cup of coffee :)

觉得对你有帮助,就给我打赏吧,谢谢!

Buy me a cup of coffee :)

https://www.owenzhang.com/wechat_reward.png

更新时间 2023-11-08