Metrics
更直接(希望更好)的统计导出方式。
相关配置
在基础配置中增加 metrics
"metrics": {
"tag": "Metrics",
"listen": "127.0.0.1:11111"
}2
3
4
tag: string
metrics 对应的出站代理 tag, 通过设置任意门入站+路由将任意门指向此出站即可通过该任意门访问。
listen: string
更简单的方法,直接监听一个地址端口提供服务。
设置该字段时若 tag 为空会自动设置为 Metrics, 如果二者均未设置核心会启动失败。
access_key: string
设置 metrics HTTP/gRPC 的访问密钥。留空表示不启用鉴权。
- HTTP:使用请求头
X-Access-Key或 query 参数access_key - gRPC:使用 metadata
x-access-key(也兼容access-key/access_key)
使用方法
pprof
访问 http://127.0.0.1:11111/debug/pprof/ 或者使用 go tool pprof 进行调试。
反馈内存占用过多/内存泄露问题需要提供 /debug/pprof/heap 和 /debug/pprof/goroutine 的文件
expvars
访问 http://127.0.0.1:11111/debug/vars
包含的变量:
stats包括所有的 inbound outbound user 数据observatory包含了 observatory 观测结果
例如在 luci-app-xray 你可以得到这样的输出 (省略了 cmdline 和 memstats 等标准expvar内容)
点击查看
{
"observatory": {
"tcp_outbound": {
"alive": true,
"delay": 782,
"outbound_tag": "tcp_outbound",
"last_seen_time": 1648477189,
"last_try_time": 1648477189
},
"udp_outbound": {
"alive": true,
"delay": 779,
"outbound_tag": "udp_outbound",
"last_seen_time": 1648477191,
"last_try_time": 1648477191
}
},
"stats": {
"inbound": {
"api": {
"downlink": 0,
"uplink": 0
},
"dns_server_inbound_5300": {
"downlink": 14286,
"uplink": 5857
},
"http_inbound": {
"downlink": 74460,
"uplink": 10231
},
"https_inbound": {
"downlink": 0,
"uplink": 0
},
"metrics": {
"downlink": 6327,
"uplink": 1347
},
"socks_inbound": {
"downlink": 19925615,
"uplink": 5512
},
"tproxy_tcp_inbound": {
"downlink": 4739161,
"uplink": 1568869
},
"tproxy_udp_inbound": {
"downlink": 0,
"uplink": 2608142
}
},
"outbound": {
"blackhole_outbound": {
"downlink": 0,
"uplink": 0
},
"direct": {
"downlink": 97714548,
"uplink": 3234617
},
"dns_server_outbound": {
"downlink": 7116,
"uplink": 2229
},
"manual_tproxy_outbound_tcp_1": {
"downlink": 0,
"uplink": 0
},
"manual_tproxy_outbound_udp_1": {
"downlink": 0,
"uplink": 0
},
"tcp_outbound": {
"downlink": 23873238,
"uplink": 1049595
},
"udp_outbound": {
"downlink": 639282,
"uplink": 74634
}
},
"user": {}
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
为了得到更好的可视化输出, 可以使用 Netdata (with python.d plugin):
- 编辑相关配置文件 (
sudo /etc/netdata/edit-config python.d/go_expvar.conf) - 使用下面这样的实力配置:
点击查看
xray:
name: 'xray'
update_every: 2
url: 'http://127.0.0.1:11111/debug/vars'
collect_memstats: false
extra_charts:
- id: 'inbounds'
options:
name: 'inbounds'
title: 'Xray System Inbounds'
units: bytes
family: xray
context: xray.inbounds
chart_type: line
lines:
- expvar_key: stats.inbound.tproxy_tcp_inbound.downlink
id: 'tcp.downlink'
algorithm: incremental
expvar_type: int
- expvar_key: stats.inbound.tproxy_udp_inbound.downlink
id: 'udp.downlink'
algorithm: incremental
expvar_type: int
- expvar_key: stats.inbound.http_inbound.downlink
id: 'http.downlink'
algorithm: incremental
expvar_type: int
- expvar_key: stats.inbound.https_inbound.downlink
id: 'https.downlink'
algorithm: incremental
expvar_type: int
- expvar_key: stats.inbound.socks_inbound.downlink
id: 'socks.downlink'
algorithm: incremental
expvar_type: int
- expvar_key: stats.inbound.tproxy_tcp_inbound.uplink
id: 'tcp.uplink'
algorithm: incremental
expvar_type: int
- expvar_key: stats.inbound.tproxy_udp_inbound.uplink
id: 'udp.uplink'
algorithm: incremental
expvar_type: int
- expvar_key: stats.inbound.http_inbound.uplink
id: 'http.uplink'
algorithm: incremental
expvar_type: int
- expvar_key: stats.inbound.https_inbound.uplink
id: 'https.uplink'
algorithm: incremental
expvar_type: int
- expvar_key: stats.inbound.socks_inbound.uplink
id: 'socks.uplink'
algorithm: incremental
expvar_type: int
- id: 'outbounds'
options:
name: 'outbounds'
title: 'Xray System Outbounds'
units: bytes
family: xray
context: xray.outbounds
chart_type: line
lines:
- expvar_key: stats.outbound.tcp_outbound.downlink
id: 'tcp.downlink'
algorithm: incremental
expvar_type: int
- expvar_key: stats.outbound.udp_outbound.downlink
id: 'udp.downlink'
algorithm: incremental
expvar_type: int
- expvar_key: stats.outbound.direct.downlink
id: 'direct.downlink'
algorithm: incremental
expvar_type: int
- expvar_key: stats.outbound.tcp_outbound.uplink
id: 'tcp.uplink'
algorithm: incremental
expvar_type: int
- expvar_key: stats.outbound.udp_outbound.uplink
id: 'udp.uplink'
algorithm: incremental
expvar_type: int
- expvar_key: stats.outbound.direct.uplink
id: 'direct.uplink'
algorithm: incremental
expvar_type: int
- id: 'observatory'
options:
name: 'observatory'
title: 'Xray Observatory Metrics'
units: milliseconds
family: xray
context: xray.observatory
chart_type: line
lines:
- expvar_key: observatory.tcp_outbound.delay
id: tcp
expvar_type: int
- expvar_key: observatory.udp_outbound.delay
id: udp
expvar_type: int2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
你可以得到类似这样的结果:
HTTP API(本地)
以下接口均支持 CORS,返回 JSON(SSE 除外)。当设置 access_key 后需要鉴权。
UI 控制台通过 controller-ui 调用这些接口,详见 UI 面板。
连接与流量
GET /connections:连接快照(聚合后的连接组 + 统计)GET /connections/stream?interval=1000:SSE 推送连接快照(默认 1000ms,最小 200ms)POST /connections/close:关闭连接
请求体:{ "ids": [1,2,3] }
返回:{ "requested": 3, "closed": [1,2], "failed": [3] }
连接元数据字段:
network,typesourceIP,sourcePortlocalIP,localPortxraySrcIP,xraySrcPortdestinationIP,destinationPorthostinboundTag,outboundTaguser
节点 / 负载均衡 / 观测
GET /nodes:出站列表、负载均衡组、观测状态POST /balancer/override:手动覆盖 balancer 目标
请求体:{ "balancerTag": "auto", "target": "proxy-a" }
说明:balancerTag必填;target传空字符串可清除覆盖并恢复自动选择;target可填写 outbound tag(也可填写 balancer tag,由路由器在运行时继续解析)。GET /observatory/probe:读取探测模式(tcp/http)POST /observatory/probe:设置探测模式
请求体:{ "mode": "tcp" }POST /observatory/probe/trigger:触发一次观测探测
路由与规则
GET /rules:返回当前路由规则与 balancer 配置(含原始 proto)
配置读写(JSON/JSONC)
GET /config/routing:读取 routing 配置POST /config/routing:写入 routing 配置(支持destination合并与兼容字段)
请求体可为{ "routing": { ... } }或直接传 routing 对象GET /config/outbounds:读取 outbounds 配置POST /config/outbounds:覆盖 outbounds 配置(仅接受outbounds数组)GET /config/subscription:读取 subscription 配置POST /config/subscription:写入/删除 subscription 配置
请求体示例(写入):{ "subscription": { ... }, "path": "/path/to/config.json" }
请求体示例(删除):{ "subscription": null }GET /config/observatory:读取 observatoryPOST /config/observatory:写入 observatory
TIP
上述 /config/* 写接口仅负责落盘,不会立即重建运行时实例。修改后请再调用 /core/hotreload 或 /core/restart 使配置生效。
启动信息
GET /startup:返回启动参数、配置文件、工作目录等
UI 设置与状态
GET /settings:读取xray.ui.json(主配置为 YAML 时为xray.ui.yaml)POST /settings:更新xray.ui.json(主配置为 YAML 时为xray.ui.yaml)GET /ui/state:读取xray.ui.json中的controller.uiState(主配置为 YAML 时为xray.ui.yaml)POST /ui/state:更新 UI 状态(合并写入到controller.uiState)
日志与重启
GET /logs?tail=200&level=info:读取日志尾部(默认 200 行,最大 2000)GET /logs/stream?tail=200&level=info:SSE 推送日志(事件类型init/append/error)GET /logs/config:查询日志等级覆盖POST /logs/config:设置日志等级
请求体:{ "level": "debug" }或{ "debug": true }POST /core/restart:读取启动配置并执行内核重启GET /core/restart/status:查询最近一次重启任务状态(可选?id=指定任务)POST /core/hotreload:重新载入启动配置文件,并在不重启内核的情况下尽可能应用可热更新的部分(不会主动断开已有连接;通常只影响新连接)。当返回needsRestart=true时,表示存在无法热更新的变更,需要用/core/restart完整重载。
TIP
metrics 启动时会为启动配置文件生成 .xrayui.bak 备份;若 /core/restart 启动失败,会尝试回滚到备份并再次启动。
Metrics gRPC(MetricsService)
通过 api.services 启用 MetricsService/MetricsGrpcService。
鉴权使用 metadata x-access-key(同 access_key 设置)。
支持的 RPC:
- Connections:
GetConnections/StreamConnections/CloseConnections - Nodes/Observatory:
GetNodes/OverrideBalancer/GetObservatoryProbe/SetObservatoryProbe/TriggerObservatoryProbe - Routing:
GetRules/GetRoutingConfig/UpdateRoutingConfig - Outbounds:
GetOutboundsConfig/UpdateOutboundsConfig - Settings/Startup:
GetSettings/UpdateSettings/GetStartupInfo - Logs:
GetLogs/GetLogsConfig/SetLogsConfig/StreamLogs - Control:
RestartCore
ConnectionMetadata 附带 local_ip/local_port 与 xray_src_ip/xray_src_port 字段,便于定位真实落地连接。