流量统计,修复问题

This commit is contained in:
sprov
2021-05-30 22:41:02 +08:00
parent 4bae13dcc6
commit 810dad53d5
18 changed files with 690 additions and 149 deletions

View File

@@ -1,6 +1,9 @@
package xray
import "encoding/json"
import (
"encoding/json"
"x-ui/util/json_util"
)
type Config struct {
LogConfig json.RawMessage `json:"log"`
@@ -15,3 +18,7 @@ type Config struct {
Reverse json.RawMessage `json:"reverse"`
FakeDNS json.RawMessage `json:"fakeDns"`
}
func (c *Config) MarshalJSON() ([]byte, error) {
return json_util.MarshalJSON(c)
}

View File

@@ -1,9 +1,12 @@
package xray
import "encoding/json"
import (
"encoding/json"
"x-ui/util/json_util"
)
type InboundConfig struct {
Listen string `json:"listen"`
Listen json.RawMessage `json:"listen"` // listen 不能为空字符串
Port int `json:"port"`
Protocol string `json:"protocol"`
Settings json.RawMessage `json:"settings"`
@@ -11,3 +14,7 @@ type InboundConfig struct {
Tag string `json:"tag"`
Sniffing json.RawMessage `json:"sniffing"`
}
func (i *InboundConfig) MarshalJSON() ([]byte, error) {
return json_util.MarshalJSON(i)
}

View File

@@ -3,18 +3,25 @@ package xray
import (
"bufio"
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"github.com/Workiva/go-datastructures/queue"
statsservice "github.com/xtls/xray-core/app/stats/command"
"google.golang.org/grpc"
"io/fs"
"os"
"os/exec"
"regexp"
"runtime"
"strings"
"time"
"x-ui/util/common"
)
var trafficRegex = regexp.MustCompile("(inbound|outbound)>>>([^>]+)>>>traffic>>>(downlink|uplink)")
func GetBinaryName() string {
return fmt.Sprintf("xray-%s-%s", runtime.GOOS, runtime.GOARCH)
}
@@ -53,6 +60,7 @@ type process struct {
cmd *exec.Cmd
version string
apiPort int
xrayConfig *Config
lines *queue.Queue
@@ -96,6 +104,19 @@ func (p *process) GetVersion() string {
return p.version
}
func (p *Process) GetAPIPort() int {
return p.apiPort
}
func (p *process) refreshAPIPort() {
for _, inbound := range p.xrayConfig.InboundConfigs {
if inbound.Tag == "api" {
p.apiPort = inbound.Port
break
}
}
}
func (p *process) refreshVersion() {
cmd := exec.Command(GetBinaryPath(), "-version")
data, err := cmd.Output()
@@ -182,6 +203,7 @@ func (p *process) Start() error {
}()
p.refreshVersion()
p.refreshAPIPort()
return nil
}
@@ -192,3 +214,52 @@ func (p *process) Stop() error {
}
return p.cmd.Process.Kill()
}
func (p *process) GetTraffic(reset bool) ([]*Traffic, error) {
if p.apiPort == 0 {
return nil, common.NewError("xray api port wrong:", p.apiPort)
}
conn, err := grpc.Dial(fmt.Sprintf("127.0.0.1:%v", p.apiPort), grpc.WithInsecure())
if err != nil {
return nil, err
}
defer conn.Close()
client := statsservice.NewStatsServiceClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
request := &statsservice.QueryStatsRequest{
Reset_: reset,
}
resp, err := client.QueryStats(ctx, request)
if err != nil {
return nil, err
}
tagTrafficMap := map[string]*Traffic{}
traffics := make([]*Traffic, 0)
for _, stat := range resp.GetStat() {
matchs := trafficRegex.FindStringSubmatch(stat.Name)
isInbound := matchs[1] == "inbound"
tag := matchs[2]
isDown := matchs[3] == "downlink"
if tag == "api" {
continue
}
traffic, ok := tagTrafficMap[tag]
if !ok {
traffic = &Traffic{
IsInbound: isInbound,
Tag: tag,
}
tagTrafficMap[tag] = traffic
traffics = append(traffics, traffic)
}
if isDown {
traffic.Down = stat.Value
} else {
traffic.Up = stat.Value
}
}
return traffics, nil
}

8
xray/traffic.go Normal file
View File

@@ -0,0 +1,8 @@
package xray
type Traffic struct {
IsInbound bool
Tag string
Up int64
Down int64
}