TransferStatistics v2 应用监控系统

hsk99

TransferStatistics v2

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

系统使用 HTTP 接收上报数据;使用 Redis 进行数据汇总统计;使用 MySql 存储统计数据和上报信息

项目地址

所需环境

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

安装

composer安装

创建项目

composer create-project hsk99/transfer-statistics

下载安装

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

2、执行命令 composer install

导入数据库

  • sql文件位置:database/transfer.sql

配置修改

1、修改文件 config/redis.php 设置 Redis

2、修改文件 config/server.php 设置 HTTP

3、修改目录 config/plugin/webman/redis-queue/ 设置 RedisQueue 相关信息

4、修改文件 config/thinkorm.php 设置 MySql 相关信息

运行

执行命令 php start.php start

查看统计

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

  • 默认账号:admin

  • 默认密码:admin888

  • 相关信息可在 系统管理--系统设置 中进行设置

上报数据

<?php

declare(strict_types=1);

namespace app\middleware;

class Transfer
{
    /**
     * 处理请求
     *
     * @param \think\Request $request
     * @param \Closure       $next
     * @return Response
     */
    public function handle($request, \Closure $next)
    {
        $startTime = microtime(true);  // 开始时间
        $project   = 'tp6';            // 应用名
        $ip        = '127.0.0.1';      // 请求IP
        $transfer  = 'test';           // 调用入口

        $response = $next($request);

        $finishTime = microtime(true);           // 结束时间
        $costTime   = $finishTime - $startTime;  // 运行时长

        $code    = mt_rand(2, 5) * 100;  // 状态码
        $success = $code < 400;          // 是否成功
        // 详细信息,自定义设置
        $details = [
            'time'     => date('Y-m-d H:i:s.', (int)$startTime) . substr((string)$startTime, 11),   // 请求时间(包含毫秒时间)
            'run_time' => $costTime,                                                                // 运行时长
            // .....
        ];

        // 执行上报
        try {
            // 数据打包 多条 换行 隔开
            $data = json_encode([
                'time'     => date('Y-m-d H:i:s.', (int)$startTime) . substr((string)$startTime, 11),
                'project'  => $project,
                'ip'       => $ip,
                'transfer' => $transfer,
                'costTime' => $costTime,
                'success'  => $success ? 1 : 0,
                'code'     => $code,
                'details'  => json_encode($details, 320),
            ], 320) . "\n";

            $client = new \GuzzleHttp\Client(['verify' => false]);
            $client->post(
                // 上报地址
                'http://127.0.0.1:8788/report/statistic/transfer',
                [
                    'headers' => [
                        // 上报认证,不设置默认为当前年份的md5值
                        'authorization' => md5(date('Y'))
                    ],
                    'form_params' => [
                        // 上报数据
                        'transfer' => $data
                    ],
                ]
            );
        } catch (\Throwable $th) {
            //throw $th;
        }

        return $response;
    }
}

更新日志

  • v2.0.3 - 2022-07-24

    1、新增 Elasticsearch全局搜索并高亮展示

    2、新增 调用记录同步至Elasticsearch

    3、新增 MySql数据同步至Elasticsearch,可多进程处理

    4、新增 db搜索并关键字高亮展示

    5、新增 调用记录列表数据筛选、刷新、导出等操作

    6、新增 应用管理 可删除并清空应用数据

    7、优化 数据缓存,进程关闭时存储其缓存数据

    8、优化 页面展示

  • v2.1.1 - 2022-08-31

    1、去除 redis-queue

    2、重构 上报数据处理方式

    3、优化 统计数据同步MySql逻辑

    4、重构 调用记录存储MySql、Elasticsearch

图片展示

截图
截图
截图
截图
截图

备注

v1 版本介绍:https://hsk99.com.cn/blog/4

5013 38 11
38个评论

Tinywan

大赞!

  • 暂无评论
walkor

我去,你这个贼帅啊!!!

  • 暂无评论
evilk

666
太棒了
感谢大佬分享
但不知道能否监控到SQL耗时

  • hsk99 2021-12-24

    上报客户端已更新,SQL监控(ThinkORM 示例)文章已更新

10bang

6666,很赞啊

  • 暂无评论
yzh52521

666666 威武

  • 暂无评论
不败少龙

帅 帅

  • 暂无评论
evilk

问一下
如果一直监控着
redis里面的数据,是不是会一直增长下去?

  • 暂无评论
小阳光

作者做的不错,其实还可以用tideways收集到每个函数的耗时,以及每条sql的耗时,绘制火焰图,一眼看出哪里比较慢

宁采陈

看了一下,很棒。就是layuiadmin不是压缩版,可能涉及版权问题

  • 暂无评论
qq285567309

windows下支持吗

  • 暂无评论
mlyykk

还在用在webman1.0版本,没想到社区现在都这么热闹了. 新版界面看起来也清爽多了.

  • 暂无评论
ab0029

666

  • 暂无评论
tanxinchong

很赞 学习了

  • 暂无评论
zjcyjj

win client 服务端可以运行 客户端发送过去 服务端收不到 linux还没试试

  • 暂无评论
owenzhang

我写了一篇使用实例 大家可以参考看看
TransferStatistics使用实例:应用和SQL监控系统workerman
https://my.oschina.net/owenzhang24/blog/5522317

  • wskgmy520 2022-06-28

    为什么$response = $next($request);放在上面,就监听不了mysql,而是要放在监听下面

  • owenzhang 2022-08-06

    @wskgmy520 啥?

evilk

非常棒!
如果可以将请求和请求中的SQL绑定就好了

  • owenzhang 2022-05-06

    那里可以在请求的Statistic类内$details-》response_body内填写你的sql即可啊

  • wskgmy520 2022-06-28

    有具体方法吗?

没茅台

能否说一下 加上自定义进程UDP进行传输有什么好处呢,跟直接执行redis有什么区别呢。

  • li914 2022-05-15

    方便其他应用程序进行上报数据吧

  • ziyoren 2022-05-16

    微服务,分布式,transfer-statistics是一个独立服务;其他应用只需要一个StatisticClient就可以把采集数据上报到这个服务中。直接执行Redis不就融合到某个应用一起了

  • 没茅台 2022-05-18

    受教

ziyoren
ErrorException: Undefined array key 0 in /path/vendor/workerman/workerman/Protocols/Http/Response.php:396
Stack trace:
#0 /path/vendor/workerman/workerman/Protocols/Http/Response.php(396): {closure}(2, 'Undefined array...', '/Users/ziyoren/...', 396)
#1 /path/vendor/workerman/workerman/Protocols/Http.php(254): Workerman\Protocols\Http\Response->__toString()
#2 /path/vendor/workerman/workerman/Connection/TcpConnection.php(321): Workerman\Protocols\Http::encode(Object(Webman\Http\Response), Object(Workerman\Connection\TcpConnection))
#3 /path/vendor/workerman/webman-framework/src/App.php(396): Workerman\Connection\TcpConnection->send(Object(Webman\Http\Response))
#4 /path/vendor/workerman/webman-framework/src/App.php(166): Webman\App::send(Object(Workerman\Connection\TcpConnection), Object(Webman\Http\Response), Object(support\Request))
#5 /path/vendor/workerman/workerman/Connection/TcpConnection.php(638): Webman\App->onMessage(Object(Workerman\Connection\TcpConnection), Object(support\Request))
#6 /path/vendor/workerman/workerman/Events/Select.php(295): Workerman\Connection\TcpConnection->baseRead(Resource id #210)
#7 /path/vendor/workerman/workerman/Worker.php(2431): Workerman\Events\Select->loop()
#8 /path/vendor/workerman/workerman/Worker.php(1555): Workerman\Worker->run()
#9 /path/vendor/workerman/workerman/Worker.php(1397): Workerman\Worker::forkOneWorkerForLinux(Object(Workerman\Worker))
#10 /path/vendor/workerman/workerman/Worker.php(1371): Workerman\Worker::forkWorkersForLinux()
#11 /path/vendor/workerman/workerman/Worker.php(549): Workerman\Worker::forkWorkers()
#12 /path/start.php(108): Workerman\Worker::runAll()
#13 {main}
worker[wechatpay:52968] exit with status 64000

只要加上中间件,就报错。不知道为什么?请问如何排查?

<?php
namespace app\middleware;

use Webman\MiddlewareInterface;
use Webman\Http\Response;
use Webman\Http\Request;
use app\services\StatisticClient; //客户端类放在这里

class Statistic implements MiddlewareInterface
{
    public function process(Request $request, callable $next) : Response
    {
        $ip         = $request->getRealIp();
        $controller = $request->controller;
        $action     = $request->action;
        $transfer   = $controller . '::' . $action;

        // 开始计时
        $unique = StatisticClient::tick('project', $ip, $transfer); //只要调用到这里就会报错

        $response = $next($request);

        $code    = $response->getStatusCode();
        $success = $code < 400;
        $details = [
            'ip'              => $ip ?? '',   // 请求客户端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'   => $success ?: (string)$response->rawBody(),       // 响应数据(发生异常)
        ];
        // 数据上报
        StatisticClient::report($unique, 'project', $ip, $transfer, $success, $code, json_encode($details, 320));

        return $response;
    }

}
  • ziyoren 2022-05-16

    Workerman version:4.0.31 PHP version:8.0.8
    Webman-framework v1.3.4

  • ziyoren 2022-05-16

    原因:PHP8报错了,导致后面的程序无法按预期的运行。

    StatisticClient类的tick方法,第一个参数给了默认值,函数的参数带有默认值时,如果不再参数最后,PHP8会提示deprecated。

        public static function tick(string $project = '', string $ip, string $transfer = ''): string
        {
            $unique = uniqid();
    
            self::$timeMap[md5($project . $ip . $transfer . $unique)] = microtime(true);
    
            return $unique;
        }

    将上面的代码改一下

        public static function tick(string $project, string $ip, string $transfer = ''): string
        {
            $unique = uniqid();
    
            self::$timeMap[md5($project . $ip . $transfer . $unique)] = microtime(true);
    
            return $unique;
        }

    注意:其他几个方法也要修改。

    代码还是要规范啊!!!!

  • ziyoren 2022-05-16

    @walkor 老大,这个php8的报错webman好像没捕获到啊

kinross

  • 暂无评论
hungmou

帅,能否整合 一个windows版

  • 暂无评论
hungmou

测试了php7.2.24也能运行正常

  • 暂无评论
zhanqi123

这个TP框架可以使用吗? 是否可以用在分布式中

  • 暂无评论
江月闲谈

在mac上有权限问题?
php start.php start时提示PHP Warning: mkdir(): Read-only file system in /path/to/my/projects/transfer-statistics/start.php on line 36

  • 暂无评论
zhanqi123

这里面有个登录 帐号和密码是多少呀

  • hsk99 2022-06-23

    默认账号:admin 默认密码:admin888 文章已更新

zhanqi123

在请教下,这个是独立部署吗?还是放在TP框架里运行。 假如我想独立部署的话。怎么监控独立的TP框架应用?

  • 暂无评论
zhanqi123

这个在windows本地环境下是不是不会生效呀。

  • 暂无评论
abei

这个会不会影响程序运行

  • 暂无评论
zhanqi123

用这个怎么监听TP6 框架的MYSQL 日志呀

  • 暂无评论
xianrenqh

好 嗨呦 ~~~

  • 暂无评论
cuixuefeng

怎么才能设置redis 的过期时间呢 这样会把redis干满

  • hsk99 2022-07-07

    默认过期时间为第二天 12:50 ;修改过期时间 文件地址:app/queue/redis/statistic/Statistic.php

  • cuixuefeng 2022-07-07

    谢谢看到了

cuixuefeng

有封装好的上报的 类吗 我看1.0版本有 2.0版本我没看到

  • 暂无评论
cuixuefeng

感觉不如1.0版本好用 这个版本上报数据是用的http 会导致很慢 之前的udp的 很快

  • 暂无评论
evilk

v2版本,安装好以后,中间有生效,但查看后台,没有内容显示

  • 暂无评论
zhangbo

StatisticClient类在什么地方啊

  • 暂无评论
99hz8

按照文档安装后,浏览器执行localhost:8788
报404,怎么解决?或者从哪查问题?

  • hsk99 2022-08-19

    执行 composer require workerman/webman-framework 1.3.21 降级webman-framework 版本,或重新安装 已发布 v2.0.4 限制了 webman-framework 版本

  • 99hz8 2022-08-19

    降级webman-framework 版本未解决问题,但重新安装v2.0.4成功了

  • efnic 24天前

    帅气

webmanchin

php 8.1.9 运行报错

[2022-09-02 11:02:57]   Workerﻳync.statistics.to.mysql
ErrorException: Implicit conversion from float 1662087777.472007 to int loses precision in /root/transfer-statistics/support/hsk99/bootstrap/ThinkOrmLog.php:29
Stack trace:
#0 [internal function]: {closure}()
#1 /root/transfer-statistics/support/hsk99/bootstrap/ThinkOrmLog.php(29): date()
#2 /root/transfer-statistics/vendor/topthink/think-orm/src/db/Connection.php(264): support\hsk99\bootstrap\ThinkOrmLog::support\hsk99\bootstrap\{closure}()
#3 /root/transfer-statistics/vendor/topthink/think-orm/src/db/PDOConnection.php(776): think\db\Connection->trigger()
#4 /root/transfer-statistics/vendor/topthink/think-orm/src/db/connector/Mysql.php(66): think\db\PDOConnection->getPDOStatement()
#5 /root/transfer-statistics/vendor/topthink/think-orm/src/db/PDOConnection.php(422): think\db\connector\Mysql->getFields()
#6 /root/transfer-statistics/vendor/topthink/think-orm/src/db/PDOConnection.php(362): think\db\PDOConnection->getTableFieldsInfo()
#7 /root/transfer-statistics/vendor/topthink/think-orm/src/db/PDOConnection.php(409): think\db\PDOConnection->getSchemaInfo()
#8 /root/transfer-statistics/vendor/topthink/think-orm/src/db/PDOConnection.php(459): think\db\PDOConnection->getTableInfo()
#9 /root/transfer-statistics/vendor/topthink/think-orm/src/db/Query.php(291): think\db\PDOConnection->getPk()
#10 /root/transfer-statistics/vendor/topthink/think-orm/src/db/concern/WhereQuery.php(442): think\db\Query->getPk()
#11 /root/transfer-statistics/vendor/topthink/think-orm/src/db/concern/WhereQuery.php(422): think\db\BaseQuery->whereEq()
#12 /root/transfer-statistics/vendor/topthink/think-orm/src/db/concern/WhereQuery.php(386): think\db\BaseQuery->parseWhereItem()
#13 /root/transfer-statistics/vendor/topthink/think-orm/src/db/concern/WhereQuery.php(41): think\db\BaseQuery->parseWhereExp()
#14 /root/transfer-statistics/app/common/service/SyncStatisticsToMySql.php(49): think\db\BaseQuery->where()
#15 /root/transfer-statistics/process/SyncStatisticsToMySql.php(18): app\common\service\SyncStatisticsToMySql::run()
#16 /root/transfer-statistics/vendor/workerman/workerman/Events/Select.php(238): process\SyncStatisticsToMySql->process\{closure}()
#17 /root/transfer-statistics/vendor/workerman/workerman/Events/Select.php(299): Workerman\Events\Select->tick()
#18 /root/transfer-statistics/vendor/workerman/workerman/Worker.php(2463): Workerman\Events\Select->loop()
#19 /root/transfer-statistics/vendor/workerman/workerman/Worker.php(1574): Workerman\Worker->run()
#20 /root/transfer-statistics/vendor/workerman/workerman/Worker.php(1416): Workerman\Worker::forkOneWorkerForLinux()
#21 /root/transfer-statistics/vendor/workerman/workerman/Worker.php(1390): Workerman\Worker::forkWorkersForLinux()
#22 /root/transfer-statistics/vendor/workerman/workerman/Worker.php(557): Workerman\Worker::forkWorkers()
#23 /root/transfer-statistics/start.php(117): Workerman\Worker::runAll()
  • 暂无评论
zkchuck

应用监控里面,调用ip和调用入口那里(因为一进去就卡住了不太确定,应该是这里),不知道出于什么考虑没有分页 数据量一多了页面就崩了

aimuc

期待发布应用插件 这样就不用再创个项目单独跑啦🧐

hsk99

125
积分
0
获赞数
0
粉丝数
2019-06-29 加入
🔝