Skip to content

Commit 05a9a17

Browse files
authored
Merge pull request #11 from klirii/xtlsapi-onlineiplist
A new function from the Xray Core API - GetStatsOnlineIpList
2 parents 94c47ac + 089cdd1 commit 05a9a17

8 files changed

Lines changed: 211 additions & 54 deletions

File tree

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@
66

77
grpcio
88
grpcio-tools<2.0.0
9-
protobuf==5.28.3
9+
protobuf==5.29.0

test2.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from xtlsapi import XrayClient
2+
3+
4+
xray = XrayClient("127.0.0.1", 53357)
5+
6+
7+
print(xray.stats_online_ip_list("1"))

tests/test_stats_online_ip_list.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import pytest
2+
from unittest.mock import patch
3+
from xtlsapi import XrayClient
4+
5+
def test_stats_online_ip_list():
6+
xray = XrayClient("127.0.0.1", 53357)
7+
with patch.object(xray, 'stats_online_ip_list', return_value={'212.58.119.246': 1763418412}):
8+
result = xray.stats_online_ip_list("1")
9+
assert result == {'212.58.119.246': 1763418412}

xtlsapi/api_services/stats/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from .get_total_download_traffic import GetTotalDownloadTraffic
77
from .get_statsquery import StatsQuery
88
from .get_statsonline import StatsOnline
9+
from .get_stats_online_ip_list import StatsOnlineIpList
910

1011
class StatsAPIService(
1112
GetClientUploadTraffic,
@@ -15,6 +16,7 @@ class StatsAPIService(
1516
GetTotalUploadTraffic,
1617
GetTotalDownloadTraffic,
1718
StatsQuery,
18-
StatsOnline
19+
StatsOnline,
20+
StatsOnlineIpList
1921
):
2022
pass
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import grpc
2+
from xtlsapi.xray_api.app.stats.command import command_pb2
3+
4+
from .._base import BaseService
5+
6+
7+
class StatsOnlineIpList(BaseService):
8+
def stats_online_ip_list(self, user, reset=False) -> dict:
9+
"""
10+
Returns a dictionary of online IPs for the given user.
11+
12+
Args:
13+
user: The email of the user to query.
14+
15+
Returns:
16+
A dictionary mapping IP addresses to last cleanup time of expired ip's.
17+
"""
18+
19+
try:
20+
return self.stats_stub.GetStatsOnlineIpList(
21+
command_pb2.GetStatsRequest(
22+
name=f"user>>>{user}>>>online",
23+
reset=reset
24+
)
25+
).ips
26+
except grpc.RpcError:
27+
raise
28+
return None
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
syntax = "proto3";
2+
3+
package xray.app.stats.command;
4+
option csharp_namespace = "Xray.App.Stats.Command";
5+
option go_package = "github.com/xtls/xray-core/app/stats/command";
6+
option java_package = "com.xray.app.stats.command";
7+
option java_multiple_files = true;
8+
9+
message GetStatsRequest {
10+
// Name of the stat counter.
11+
string name = 1;
12+
// Whether or not to reset the counter to fetching its value.
13+
bool reset = 2;
14+
}
15+
16+
message Stat {
17+
string name = 1;
18+
int64 value = 2;
19+
}
20+
21+
message GetStatsResponse {
22+
Stat stat = 1;
23+
}
24+
25+
message QueryStatsRequest {
26+
string pattern = 1;
27+
bool reset = 2;
28+
}
29+
30+
message QueryStatsResponse {
31+
repeated Stat stat = 1;
32+
}
33+
34+
message SysStatsRequest {}
35+
36+
message SysStatsResponse {
37+
uint32 NumGoroutine = 1;
38+
uint32 NumGC = 2;
39+
uint64 Alloc = 3;
40+
uint64 TotalAlloc = 4;
41+
uint64 Sys = 5;
42+
uint64 Mallocs = 6;
43+
uint64 Frees = 7;
44+
uint64 LiveObjects = 8;
45+
uint64 PauseTotalNs = 9;
46+
uint32 Uptime = 10;
47+
}
48+
49+
message GetStatsOnlineIpListResponse {
50+
string name = 1;
51+
map<string, int64> ips = 2;
52+
}
53+
54+
service StatsService {
55+
rpc GetStats(GetStatsRequest) returns (GetStatsResponse) {}
56+
rpc GetStatsOnline(GetStatsRequest) returns (GetStatsResponse) {}
57+
rpc QueryStats(QueryStatsRequest) returns (QueryStatsResponse) {}
58+
rpc GetSysStats(SysStatsRequest) returns (SysStatsResponse) {}
59+
rpc GetStatsOnlineIpList(GetStatsRequest) returns (GetStatsOnlineIpListResponse) {}
60+
}
61+
62+
message Config {}

xtlsapi/xray_api/app/stats/command/command_pb2.py

Lines changed: 31 additions & 25 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

xtlsapi/xray_api/app/stats/command/command_pb2_grpc.py

Lines changed: 70 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
import grpc
44
import warnings
55

6-
from xtlsapi.xray_api.app.stats.command import command_pb2 as app_dot_stats_dot_command_dot_command__pb2
6+
from . import command_pb2 as command__pb2
77

8-
GRPC_GENERATED_VERSION = '1.67.1'
8+
GRPC_GENERATED_VERSION = '1.71.2'
99
GRPC_VERSION = grpc.__version__
1010
_version_not_supported = False
1111

@@ -18,7 +18,7 @@
1818
if _version_not_supported:
1919
raise RuntimeError(
2020
f'The grpc package installed is at version {GRPC_VERSION},'
21-
+ f' but the generated code in app/stats/command/command_pb2_grpc.py depends on'
21+
+ f' but the generated code in command_pb2_grpc.py depends on'
2222
+ f' grpcio>={GRPC_GENERATED_VERSION}.'
2323
+ f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}'
2424
+ f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.'
@@ -36,23 +36,28 @@ def __init__(self, channel):
3636
"""
3737
self.GetStats = channel.unary_unary(
3838
'/xray.app.stats.command.StatsService/GetStats',
39-
request_serializer=app_dot_stats_dot_command_dot_command__pb2.GetStatsRequest.SerializeToString,
40-
response_deserializer=app_dot_stats_dot_command_dot_command__pb2.GetStatsResponse.FromString,
39+
request_serializer=command__pb2.GetStatsRequest.SerializeToString,
40+
response_deserializer=command__pb2.GetStatsResponse.FromString,
4141
_registered_method=True)
4242
self.GetStatsOnline = channel.unary_unary(
4343
'/xray.app.stats.command.StatsService/GetStatsOnline',
44-
request_serializer=app_dot_stats_dot_command_dot_command__pb2.GetStatsRequest.SerializeToString,
45-
response_deserializer=app_dot_stats_dot_command_dot_command__pb2.GetStatsResponse.FromString,
44+
request_serializer=command__pb2.GetStatsRequest.SerializeToString,
45+
response_deserializer=command__pb2.GetStatsResponse.FromString,
4646
_registered_method=True)
4747
self.QueryStats = channel.unary_unary(
4848
'/xray.app.stats.command.StatsService/QueryStats',
49-
request_serializer=app_dot_stats_dot_command_dot_command__pb2.QueryStatsRequest.SerializeToString,
50-
response_deserializer=app_dot_stats_dot_command_dot_command__pb2.QueryStatsResponse.FromString,
49+
request_serializer=command__pb2.QueryStatsRequest.SerializeToString,
50+
response_deserializer=command__pb2.QueryStatsResponse.FromString,
5151
_registered_method=True)
5252
self.GetSysStats = channel.unary_unary(
5353
'/xray.app.stats.command.StatsService/GetSysStats',
54-
request_serializer=app_dot_stats_dot_command_dot_command__pb2.SysStatsRequest.SerializeToString,
55-
response_deserializer=app_dot_stats_dot_command_dot_command__pb2.SysStatsResponse.FromString,
54+
request_serializer=command__pb2.SysStatsRequest.SerializeToString,
55+
response_deserializer=command__pb2.SysStatsResponse.FromString,
56+
_registered_method=True)
57+
self.GetStatsOnlineIpList = channel.unary_unary(
58+
'/xray.app.stats.command.StatsService/GetStatsOnlineIpList',
59+
request_serializer=command__pb2.GetStatsRequest.SerializeToString,
60+
response_deserializer=command__pb2.GetStatsOnlineIpListResponse.FromString,
5661
_registered_method=True)
5762

5863

@@ -83,28 +88,39 @@ def GetSysStats(self, request, context):
8388
context.set_details('Method not implemented!')
8489
raise NotImplementedError('Method not implemented!')
8590

91+
def GetStatsOnlineIpList(self, request, context):
92+
"""Missing associated documentation comment in .proto file."""
93+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
94+
context.set_details('Method not implemented!')
95+
raise NotImplementedError('Method not implemented!')
96+
8697

8798
def add_StatsServiceServicer_to_server(servicer, server):
8899
rpc_method_handlers = {
89100
'GetStats': grpc.unary_unary_rpc_method_handler(
90101
servicer.GetStats,
91-
request_deserializer=app_dot_stats_dot_command_dot_command__pb2.GetStatsRequest.FromString,
92-
response_serializer=app_dot_stats_dot_command_dot_command__pb2.GetStatsResponse.SerializeToString,
102+
request_deserializer=command__pb2.GetStatsRequest.FromString,
103+
response_serializer=command__pb2.GetStatsResponse.SerializeToString,
93104
),
94105
'GetStatsOnline': grpc.unary_unary_rpc_method_handler(
95106
servicer.GetStatsOnline,
96-
request_deserializer=app_dot_stats_dot_command_dot_command__pb2.GetStatsRequest.FromString,
97-
response_serializer=app_dot_stats_dot_command_dot_command__pb2.GetStatsResponse.SerializeToString,
107+
request_deserializer=command__pb2.GetStatsRequest.FromString,
108+
response_serializer=command__pb2.GetStatsResponse.SerializeToString,
98109
),
99110
'QueryStats': grpc.unary_unary_rpc_method_handler(
100111
servicer.QueryStats,
101-
request_deserializer=app_dot_stats_dot_command_dot_command__pb2.QueryStatsRequest.FromString,
102-
response_serializer=app_dot_stats_dot_command_dot_command__pb2.QueryStatsResponse.SerializeToString,
112+
request_deserializer=command__pb2.QueryStatsRequest.FromString,
113+
response_serializer=command__pb2.QueryStatsResponse.SerializeToString,
103114
),
104115
'GetSysStats': grpc.unary_unary_rpc_method_handler(
105116
servicer.GetSysStats,
106-
request_deserializer=app_dot_stats_dot_command_dot_command__pb2.SysStatsRequest.FromString,
107-
response_serializer=app_dot_stats_dot_command_dot_command__pb2.SysStatsResponse.SerializeToString,
117+
request_deserializer=command__pb2.SysStatsRequest.FromString,
118+
response_serializer=command__pb2.SysStatsResponse.SerializeToString,
119+
),
120+
'GetStatsOnlineIpList': grpc.unary_unary_rpc_method_handler(
121+
servicer.GetStatsOnlineIpList,
122+
request_deserializer=command__pb2.GetStatsRequest.FromString,
123+
response_serializer=command__pb2.GetStatsOnlineIpListResponse.SerializeToString,
108124
),
109125
}
110126
generic_handler = grpc.method_handlers_generic_handler(
@@ -132,8 +148,8 @@ def GetStats(request,
132148
request,
133149
target,
134150
'/xray.app.stats.command.StatsService/GetStats',
135-
app_dot_stats_dot_command_dot_command__pb2.GetStatsRequest.SerializeToString,
136-
app_dot_stats_dot_command_dot_command__pb2.GetStatsResponse.FromString,
151+
command__pb2.GetStatsRequest.SerializeToString,
152+
command__pb2.GetStatsResponse.FromString,
137153
options,
138154
channel_credentials,
139155
insecure,
@@ -159,8 +175,8 @@ def GetStatsOnline(request,
159175
request,
160176
target,
161177
'/xray.app.stats.command.StatsService/GetStatsOnline',
162-
app_dot_stats_dot_command_dot_command__pb2.GetStatsRequest.SerializeToString,
163-
app_dot_stats_dot_command_dot_command__pb2.GetStatsResponse.FromString,
178+
command__pb2.GetStatsRequest.SerializeToString,
179+
command__pb2.GetStatsResponse.FromString,
164180
options,
165181
channel_credentials,
166182
insecure,
@@ -186,8 +202,8 @@ def QueryStats(request,
186202
request,
187203
target,
188204
'/xray.app.stats.command.StatsService/QueryStats',
189-
app_dot_stats_dot_command_dot_command__pb2.QueryStatsRequest.SerializeToString,
190-
app_dot_stats_dot_command_dot_command__pb2.QueryStatsResponse.FromString,
205+
command__pb2.QueryStatsRequest.SerializeToString,
206+
command__pb2.QueryStatsResponse.FromString,
191207
options,
192208
channel_credentials,
193209
insecure,
@@ -213,8 +229,35 @@ def GetSysStats(request,
213229
request,
214230
target,
215231
'/xray.app.stats.command.StatsService/GetSysStats',
216-
app_dot_stats_dot_command_dot_command__pb2.SysStatsRequest.SerializeToString,
217-
app_dot_stats_dot_command_dot_command__pb2.SysStatsResponse.FromString,
232+
command__pb2.SysStatsRequest.SerializeToString,
233+
command__pb2.SysStatsResponse.FromString,
234+
options,
235+
channel_credentials,
236+
insecure,
237+
call_credentials,
238+
compression,
239+
wait_for_ready,
240+
timeout,
241+
metadata,
242+
_registered_method=True)
243+
244+
@staticmethod
245+
def GetStatsOnlineIpList(request,
246+
target,
247+
options=(),
248+
channel_credentials=None,
249+
call_credentials=None,
250+
insecure=False,
251+
compression=None,
252+
wait_for_ready=None,
253+
timeout=None,
254+
metadata=None):
255+
return grpc.experimental.unary_unary(
256+
request,
257+
target,
258+
'/xray.app.stats.command.StatsService/GetStatsOnlineIpList',
259+
command__pb2.GetStatsRequest.SerializeToString,
260+
command__pb2.GetStatsOnlineIpListResponse.FromString,
218261
options,
219262
channel_credentials,
220263
insecure,

0 commit comments

Comments
 (0)