Initial commit: stats-gateway gRPC service + dashboard + CLI

This commit is contained in:
2026-05-05 21:04:32 +05:00
commit 4059e94759
44 changed files with 2513 additions and 0 deletions
+14
View File
@@ -0,0 +1,14 @@
PROTOC := protoc
GEN_OUT := ../gen/stats/v1
.PHONY: gen
gen:
mkdir -p $(GEN_OUT)
$(PROTOC) \
--go_out=$(GEN_OUT) --go_opt=paths=source_relative \
--go-grpc_out=$(GEN_OUT) --go-grpc_opt=paths=source_relative \
-I . stats.proto
.PHONY: clean
clean:
rm -rf $(GEN_OUT)
+62
View File
@@ -0,0 +1,62 @@
syntax = "proto3";
package stats.v1;
option go_package = "github.com/bergabruh/stats-gateway/gen/stats/v1;statsv1";
service SpeedStatus {
// RecentResults streams the last N samples for given filter.
rpc RecentResults(Filter) returns (stream Sample);
// Aggregate returns histogram for a time range.
rpc Aggregate(Range) returns (Histogram);
// Tunnel is a bidirectional stream for authenticated clients.
// Auth: Bearer JWT (HS256) в gRPC metadata "authorization: Bearer <jwt>".
// Server validates: signature, exp, scope=="tunnel", optional revocation list.
rpc Tunnel(stream Frame) returns (stream Frame);
}
message Filter {
string node = 1; // "fl" | "pl1" | "" (all)
int32 limit = 2; // 1..1000
string since = 3; // RFC3339, optional
}
message Sample {
string node = 1;
string timestamp = 2; // RFC3339
double http_latency_ms = 3;
double tcp_rtt_ms = 4;
double dns_resolve_ms = 5;
double tls_handshake_ms = 6;
int64 throughput_kbps = 7;
}
message Range {
string node = 1;
string since = 2;
string until = 3;
}
message Histogram {
repeated Bucket buckets = 1;
}
message Bucket {
double upper_ms = 1;
int64 count = 2;
}
message Frame {
// Control message. First frame from client must be HELLO with target.
enum Kind {
UNKNOWN = 0;
HELLO = 1;
DATA = 2;
CLOSE = 3;
}
Kind kind = 1;
string target = 2; // "ip:port" — only used in HELLO
bytes payload = 3; // raw TCP bytes
bytes padding = 4; // random padding для frame-length obfuscation
}