mirror of
https://github.com/XTLS/Xray-core.git
synced 2025-04-29 16:58:34 +00:00
Observatory related fixes (#788)
* fix:observatory not supported by multi-json * Fix: observatory starts with empty config & fails to close (#957) * Update strategy_leastping.go (#1019) * add custom probe URL support for observatory * add custom probe interval for observer * apply coding style * Fix: observatory log & JSON config(#1211) Co-authored-by: ihotte <ihotte@yeah.net> * Change default probe url from api.v2fly.org to www.google.com * Cherry-pick missing code from branch 'dev-advloadblancer-2' Co-authored-by: Shelikhoo <xiaokangwang@outlook.com> Co-authored-by: Loyalsoldier <10487845+Loyalsoldier@users.noreply.github.com> Co-authored-by: fanyiguan <52657276+fanyiguang@users.noreply.github.com> Co-authored-by: ihotte <3087168217@qq.com> Co-authored-by: ihotte <ihotte@yeah.net>
This commit is contained in:
parent
7038bded7b
commit
abb8ba8b0e
20 changed files with 601 additions and 22 deletions
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"github.com/xtls/xray-core/app/commander"
|
||||
loggerservice "github.com/xtls/xray-core/app/log/command"
|
||||
observatoryservice "github.com/xtls/xray-core/app/observatory/command"
|
||||
handlerservice "github.com/xtls/xray-core/app/proxyman/command"
|
||||
statsservice "github.com/xtls/xray-core/app/stats/command"
|
||||
"github.com/xtls/xray-core/common/serial"
|
||||
|
@ -31,6 +32,8 @@ func (c *APIConfig) Build() (*commander.Config, error) {
|
|||
services = append(services, serial.ToTypedMessage(&loggerservice.Config{}))
|
||||
case "statsservice":
|
||||
services = append(services, serial.ToTypedMessage(&statsservice.Config{}))
|
||||
case "observatoryservice":
|
||||
services = append(services, serial.ToTypedMessage(&observatoryservice.Config{}))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
33
infra/conf/cfgcommon/duration/duration.go
Normal file
33
infra/conf/cfgcommon/duration/duration.go
Normal file
|
@ -0,0 +1,33 @@
|
|||
package duration
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Duration int64
|
||||
|
||||
func (d *Duration) MarshalJSON() ([]byte, error) {
|
||||
dr := time.Duration(*d)
|
||||
return json.Marshal(dr.String())
|
||||
}
|
||||
|
||||
func (d *Duration) UnmarshalJSON(b []byte) error {
|
||||
var v interface{}
|
||||
if err := json.Unmarshal(b, &v); err != nil {
|
||||
return err
|
||||
}
|
||||
switch value := v.(type) {
|
||||
case string:
|
||||
var err error
|
||||
dr, err := time.ParseDuration(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*d = Duration(dr)
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("invalid duration: %v", v)
|
||||
}
|
||||
}
|
33
infra/conf/cfgcommon/duration/duration_test.go
Normal file
33
infra/conf/cfgcommon/duration/duration_test.go
Normal file
|
@ -0,0 +1,33 @@
|
|||
package duration_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/xtls/xray-core/infra/conf/cfgcommon/duration"
|
||||
)
|
||||
|
||||
type testWithDuration struct {
|
||||
Duration duration.Duration
|
||||
}
|
||||
|
||||
func TestDurationJSON(t *testing.T) {
|
||||
expected := &testWithDuration{
|
||||
Duration: duration.Duration(time.Hour),
|
||||
}
|
||||
data, err := json.Marshal(expected)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
actual := &testWithDuration{}
|
||||
err = json.Unmarshal(data, &actual)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if actual.Duration != expected.Duration {
|
||||
t.Errorf("expected: %s, actual: %s", time.Duration(expected.Duration), time.Duration(actual.Duration))
|
||||
}
|
||||
}
|
|
@ -2,13 +2,17 @@ package conf
|
|||
|
||||
import (
|
||||
"github.com/golang/protobuf/proto"
|
||||
|
||||
"github.com/xtls/xray-core/app/observatory"
|
||||
"github.com/xtls/xray-core/infra/conf/cfgcommon/duration"
|
||||
)
|
||||
|
||||
type ObservatoryConfig struct {
|
||||
SubjectSelector []string `json:"subjectSelector"`
|
||||
SubjectSelector []string `json:"subjectSelector"`
|
||||
ProbeURL string `json:"probeURL"`
|
||||
ProbeInterval duration.Duration `json:"probeInterval"`
|
||||
}
|
||||
|
||||
func (o ObservatoryConfig) Build() (proto.Message, error) {
|
||||
return &observatory.Config{SubjectSelector: o.SubjectSelector}, nil
|
||||
func (o *ObservatoryConfig) Build() (proto.Message, error) {
|
||||
return &observatory.Config{SubjectSelector: o.SubjectSelector, ProbeUrl: o.ProbeURL, ProbeInterval: int64(o.ProbeInterval)}, nil
|
||||
}
|
||||
|
|
|
@ -18,9 +18,16 @@ type RouterRulesConfig struct {
|
|||
DomainStrategy string `json:"domainStrategy"`
|
||||
}
|
||||
|
||||
// StrategyConfig represents a strategy config
|
||||
type StrategyConfig struct {
|
||||
Type string `json:"type"`
|
||||
Settings *json.RawMessage `json:"settings"`
|
||||
}
|
||||
|
||||
type BalancingRule struct {
|
||||
Tag string `json:"tag"`
|
||||
Selectors StringList `json:"selector"`
|
||||
Tag string `json:"tag"`
|
||||
Selectors StringList `json:"selector"`
|
||||
Strategy StrategyConfig `json:"strategy"`
|
||||
}
|
||||
|
||||
func (r *BalancingRule) Build() (*router.BalancingRule, error) {
|
||||
|
@ -31,9 +38,20 @@ func (r *BalancingRule) Build() (*router.BalancingRule, error) {
|
|||
return nil, newError("empty selector list")
|
||||
}
|
||||
|
||||
var strategy string
|
||||
switch strings.ToLower(r.Strategy.Type) {
|
||||
case strategyRandom, "":
|
||||
strategy = strategyRandom
|
||||
case strategyLeastPing:
|
||||
strategy = "leastPing"
|
||||
default:
|
||||
return nil, newError("unknown balancing strategy: " + r.Strategy.Type)
|
||||
}
|
||||
|
||||
return &router.BalancingRule{
|
||||
Tag: r.Tag,
|
||||
OutboundSelector: []string(r.Selectors),
|
||||
Strategy: strategy,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
6
infra/conf/router_strategy.go
Normal file
6
infra/conf/router_strategy.go
Normal file
|
@ -0,0 +1,6 @@
|
|||
package conf
|
||||
|
||||
const (
|
||||
strategyRandom string = "random"
|
||||
strategyLeastPing string = "leastping"
|
||||
)
|
|
@ -107,6 +107,7 @@ func TestRouterConfig(t *testing.T) {
|
|||
{
|
||||
Tag: "b1",
|
||||
OutboundSelector: []string{"test"},
|
||||
Strategy: "random",
|
||||
},
|
||||
},
|
||||
Rule: []*router.RoutingRule{
|
||||
|
|
|
@ -464,6 +464,10 @@ func (c *Config) Override(o *Config, fn string) {
|
|||
c.FakeDNS = o.FakeDNS
|
||||
}
|
||||
|
||||
if o.Observatory != nil {
|
||||
c.Observatory = o.Observatory
|
||||
}
|
||||
|
||||
// deprecated attrs... keep them for now
|
||||
if o.InboundConfig != nil {
|
||||
c.InboundConfig = o.InboundConfig
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue