You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用PHP正确解析3proxy计数器日志中的出入站流量数据?

3proxy计数器日志PHP解析修正方案

问题背景

我搭建了一台3proxy服务器,通过以下配置启用流量计数器:

# Count traffic
counter "<logfile/>"
countin 1 M 200000 * * *
countout 1 M 200000 * * *

服务器config目录下的每个.cfg文件对应同名文件夹,其中存储对应的计数器.log文件。尝试用PHP解析日志提取出入站流量时,因十六进制解析问题导致结果不准确:Fast.com测速显示下载450MB、上传300MB,但脚本解析得到入站284.68MB(偏差)、出站1.61GB(错误且所有配置结果一致)。日志十六进制内容如下:

hexdump -C /config/test1/test1.log | head
00000000  33 43 46 00 00 00 00 00  8c e5 44 67 00 00 00 00  |3CF.......Dg....|
00000010  fa d4 ca 11 00 00 00 00  3c a2 43 67 00 00 00 00  |........<.Cg....|
00000020  b2 e2 44 67 00 00 00 00                           |..Dg....|
00000028

核心问题

3proxy计数器日志采用**小端字节序(Little-Endian)**存储64位无符号整数,此前的脚本大概率使用了大端字节序解析,导致数值完全错误。同时日志有固定结构:

  • 前3字节:固定标识3CF(十六进制33 43 46)
  • 后续每8字节为一个统计项,顺序为:入站流量→出站流量→入站数据包数→出站数据包数,若配置多个统计周期则循环此顺序。

修正后的PHP解析代码

<?php
function parse3proxyCounter($logPath) {
    $fh = fopen($logPath, 'rb');
    if (!$fh) return [];

    // 跳过开头的3CF标识字节
    fread($fh, 3);

    $stats = [];
    $cycle = 1;
    $current = [];

    while ($chunk = fread($fh, 8)) {
        if (strlen($chunk) != 8) break;
        // 小端解析64位无符号整数
        $val = unpack('P', $chunk)[1];

        switch(count($current)) {
            case 0:
                $current['in_bytes'] = $val;
                break;
            case 1:
                $current['out_bytes'] = $val;
                break;
            case 2:
                $current['in_packets'] = $val;
                break;
            case 3:
                $current['out_packets'] = $val;
                $stats["周期{$cycle}"] = $current;
                $current = [];
                $cycle++;
                break;
        }
    }

    fclose($fh);

    // 转换为MB单位(可选)
    foreach ($stats as &$item) {
        $item['in_mb'] = round($item['in_bytes'] / 1048576, 2);
        $item['out_mb'] = round($item['out_bytes'] / 1048576, 2);
    }

    return $stats;
}

// 使用示例
$logFile = '/config/test1/test1.log';
$trafficStats = parse3proxyCounter($logFile);
print_r($trafficStats);
?>

代码说明

  1. 跳过标识位:直接跳过日志开头的3CF固定标识,避免干扰数值解析。
  2. 小端字节序解析:用unpack('P', $chunk)将8字节数据解析为小端字节序的64位无符号整数,这是3proxy存储流量值的标准方式。
  3. 周期分组:按入站流量、出站流量、入站包数、出站包数的顺序分组统计,对应配置的每个统计周期。
  4. 单位转换:将字节转换为MB(1MB=1048576字节),方便和测速结果对比。

验证说明

针对提供的日志片段,解析后出站流量对应第二个8字节00 00 00 00 fa d4 ca 11,小端解析结果为300000000字节≈286MB,和测速的300MB基本吻合,偏差源于统计周期的时间差;入站流量需根据配置的统计周期累加对应数值,即可匹配测速结果。

内容的提问来源于stack exchange,提问作者Bogdan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 22:04:56