From 211e2c079d818174128343c2dceb65dd6899be20 Mon Sep 17 00:00:00 2001 From: mercury Date: Mon, 13 Jan 2025 15:32:54 +0400 Subject: [PATCH] collect xray metrics --- app/bot.php | 48 ++++++++++++++++++++++++++++++++++++++++++++---- config/xray.json | 40 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 83 insertions(+), 5 deletions(-) diff --git a/app/bot.php b/app/bot.php index 222721c..a67eabc 100644 --- a/app/bot.php +++ b/app/bot.php @@ -667,13 +667,33 @@ class Bot } } - public function restartXray($c) + public function restartXray($c, $norestart = false) { $c['inbounds'][0]['settings']['clients'] = array_values($c['inbounds'][0]['settings']['clients']); $c['log']['access'] = '/logs/xray'; - $this->ssh('pkill xray', 'xr'); - file_put_contents('/config/xray.json', json_encode($c, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); - $this->ssh('xray run -config /xray.json > /dev/null 2>&1 &', 'xr'); + $c['stats'] = new stdClass(); + $l = new stdClass(); + $l->{'0'} = [ + "statsUserUplink" => true, + "statsUserDownlink" => true + ]; + $c['policy']['levels'] = $l; + if (empty($norestart)) { + $c = $this->collectSession($c); + file_put_contents('/config/xray.json', json_encode($c, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + $this->ssh('pkill xray', 'xr'); + $this->ssh('xray run -config /xray.json > /dev/null 2>&1 &', 'xr'); + } else { + file_put_contents('/config/xray.json', json_encode($c, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + } + } + + public function collectSession($c) { + foreach ($c['inbounds'][0]['settings']['clients'] as $k => $v) { + $c['inbounds'][0]['settings']['clients'][$k]['global']['download'] += $v['session']['download']; + $c['inbounds'][0]['settings']['clients'][$k]['global']['upload'] += $v['session']['upload']; + } + return $c; } public function linkMtproto() @@ -1251,10 +1271,30 @@ class Bot $this->checkBackup($period); $this->checkCert(); $this->autoAnalyzeLogs(); + $this->xrayStatsUser(); sleep($period); } } + public function xrayStatsUser() + { + try { + $x = $this->getXray(); + if (!empty($users = $x['inbounds'][0]['settings']['clients'])) { + foreach ($users as $k => $v) { + $d = json_decode($this->ssh('xray api stats --server=127.0.0.1:8080 -name "user>>>' . $v['email'] . '>>>traffic>>>downlink" 2>&1', 'xr'), true)['stat']['value'] ?: 0; + $u = json_decode($this->ssh('xray api stats --server=127.0.0.1:8080 -name "user>>>' . $v['email'] . '>>>traffic>>>uplink" 2>&1', 'xr'), true)['stat']['value'] ?: 0; + $x['inbounds'][0]['settings']['clients'][$k]['session'] = [ + 'download' => $d, + 'upload' => $u, + ]; + } + $this->restartXray($x, norestart: 1); + } + } catch (\Throwable $th) { + } + } + public function autoAnalyzeLogs() { try { diff --git a/config/xray.json b/config/xray.json index 99be923..647fcf5 100644 --- a/config/xray.json +++ b/config/xray.json @@ -22,6 +22,15 @@ } }, "tag": "vless_tls" + }, + { + "listen": "127.0.0.1", + "port": 8080, + "protocol": "dokodemo-door", + "settings": { + "address": "127.0.0.1" + }, + "tag": "api" } ], "log": { @@ -40,6 +49,35 @@ ], "routing": { "domainStrategy": "AsIs", - "rules": [] + "rules": [ + { + "inboundTag": [ + "api" + ], + "outboundTag": "api", + "type": "field" + } + ] + }, + "stats": {}, + "api": { + "services": [ + "StatsService" + ], + "tag": "api" + }, + "policy": { + "levels": { + "0": { + "statsUserUplink": true, + "statsUserDownlink": true + } + }, + "system": { + "statsInboundUplink": true, + "statsInboundDownlink": true, + "statsOutboundUplink": true, + "statsOutboundDownlink": true + } } } \ No newline at end of file