Commit ce6782d9 authored by Tsaiilin's avatar Tsaiilin

配置文件使用 viper,改为yaml 格式,不再支持命令行参数指定除 conf 和 daemon 外的参数

parent 0e870c80
...@@ -15,23 +15,15 @@ import ( ...@@ -15,23 +15,15 @@ import (
"runtime" "runtime"
"syscall" "syscall"
"time" "time"
"virjar.com/majora-go/client" "virjar.com/majora-go/client"
"virjar.com/majora-go/common" "virjar.com/majora-go/global"
"virjar.com/majora-go/env" "virjar.com/majora-go/initialize"
"virjar.com/majora-go/log" "virjar.com/majora-go/log"
"virjar.com/majora-go/model"
"virjar.com/majora-go/safe" "virjar.com/majora-go/safe"
) )
var ( var (
configure string configure string
logLevel string
pprofPort int
natServer string
account string
dnsServer string
localAddr string
daemon bool daemon bool
) )
...@@ -47,51 +39,47 @@ var ( ...@@ -47,51 +39,47 @@ var (
func init() { func init() {
rand.Seed(time.Now().UnixNano()) rand.Seed(time.Now().UnixNano())
flag.StringVar(&configure, "conf", "", "./majora -c path/to/your/majora.ini") flag.StringVar(&configure, "conf", "", "./majora -c path/to/your/majora.ini")
flag.StringVar(&logLevel, "log", "info", "log logLevel")
flag.IntVar(&pprofPort, "pprof", 0, "enable pprof")
flag.StringVar(&natServer, "natServer", common.DefNatAddr, "natServer")
flag.StringVar(&account, "account", "unknown", "account")
flag.StringVar(&dnsServer, "dnsServer", common.DNSServer, "custom dns server")
flag.StringVar(&localAddr, "localIp", "", "bind local ip")
flag.BoolVar(&daemon, "daemon", false, "daemon") flag.BoolVar(&daemon, "daemon", false, "daemon")
flag.Parse() flag.Parse()
} }
func initial(cfg *model.Configure) { func initial() {
// 忽略错误,默认 product 环境 if global.Config.PprofPort > 0 {
_ = env.CurrentEnv.Set(cfg.Env)
log.Init(cfg.LogLevel)
if cfg.PprofPort > 0 {
safe.SageGo(func() { safe.SageGo(func() {
addr := fmt.Sprintf("127.0.0.1:%d", cfg.PprofPort) addr := fmt.Sprintf("127.0.0.1:%d", global.Config.PprofPort)
log.Run().Infof("enable pprof: %s", addr) log.Run().Infof("enable pprof: %s", addr)
log.Run().Error(http.ListenAndServe(addr, nil)) log.Run().Error(http.ListenAndServe(addr, nil))
}) })
} }
if len(cfg.DNSServer) > 0 { if len(global.Config.DNSServer) > 0 {
net.DefaultResolver = &net.Resolver{ net.DefaultResolver = &net.Resolver{
PreferGo: true, PreferGo: true,
Dial: func(ctx context.Context, network, address string) (net.Conn, error) { Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
return net.Dial("udp", dnsServer) return net.Dial("udp", global.Config.DNSServer)
}, },
} }
} }
}
func parseFromCmd(cfg *model.Configure) { if daemon {
cfg.TunnelAddr = natServer var args []string
cfg.LogLevel = logLevel for _, arg := range os.Args[1:] {
cfg.DNSServer = dnsServer if arg != "-daemon" {
cfg.LocalAddr = localAddr args = append(args, arg)
// 先兼容吧 }
cfg.Extra.Account = account }
cfg.PprofPort = pprofPort cmd = exec.Command(os.Args[0], args...)
cmd.Env = os.Environ()
if err := cmd.Start(); err != nil {
panic(err)
}
log.Run().Infof("%s [pid-%d] running...\n", os.Args[0], cmd.Process.Pid)
os.Exit(0)
}
} }
func cli(cfg *model.Configure) { func cli() {
defer func() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
log.Error().Errorf("cli panic %+v", err) log.Error().Errorf("cli panic %+v", err)
...@@ -100,22 +88,9 @@ func cli(cfg *model.Configure) { ...@@ -100,22 +88,9 @@ func cli(cfg *model.Configure) {
log.Run().Infof("cpu count %d proc %d", runtime.NumCPU(), runtime.NumCPU()*2) log.Run().Infof("cpu count %d proc %d", runtime.NumCPU(), runtime.NumCPU()*2)
log.Run().Infof("current Version %s, build at %s", Version, Date) log.Run().Infof("current Version %s, build at %s", Version, Date)
log.Run().Infof("hostInfo os:%s, arch:%s", runtime.GOOS, runtime.GOARCH) log.Run().Infof("hostInfo os:%s, arch:%s", runtime.GOOS, runtime.GOARCH)
cfgInfo, _ := json.Marshal(cfg) cfgInfo, _ := json.Marshal(global.Config)
log.Run().Infof("config info:%s", string(cfgInfo)) log.Run().Infof("config info:%s", string(cfgInfo))
client.NewClientWithConf(cfg).StartUp() client.NewClientWithConf(global.Config).StartUp()
}
func initConf() *model.Configure {
cfg := model.NewDefMajoraConf()
if len(configure) > 0 {
cfg = model.InitConf(configure)
} else {
parseFromCmd(cfg)
}
//runtime.GOMAXPROCS(runtime.NumCPU() * 2)
//debug.SetGCPercent(200)
initial(cfg)
return cfg
} }
//main start //main start
...@@ -124,26 +99,14 @@ func main() { ...@@ -124,26 +99,14 @@ func main() {
fmt.Println(Version) fmt.Println(Version)
os.Exit(0) os.Exit(0)
} }
cfg := initConf()
if daemon { initialize.MustInitConfig(configure, global.Config)
var args []string initialize.InitLogger()
for _, arg := range os.Args[1:] { initial()
if arg != "-daemon" { cli()
args = append(args, arg)
}
}
cmd = exec.Command(os.Args[0], args...)
cmd.Env = os.Environ()
if err := cmd.Start(); err != nil {
panic(err)
}
log.Run().Infof("%s [pid-%d] running...\n", os.Args[0], cmd.Process.Pid)
os.Exit(0)
}
signalChan := make(chan os.Signal, 1) signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, os.Interrupt, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) signal.Notify(signalChan, os.Interrupt, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
cli(cfg)
select { select {
case <-signalChan: case <-signalChan:
time.Sleep(time.Second * 3) time.Sleep(time.Second * 3)
......
...@@ -62,15 +62,6 @@ func (client *Client) handleConnect(packet *protocol.MajoraPacket, session getty ...@@ -62,15 +62,6 @@ func (client *Client) handleConnect(packet *protocol.MajoraPacket, session getty
dialer := net.Dialer{ dialer := net.Dialer{
Timeout: common.UpstreamTimeout, Timeout: common.UpstreamTimeout,
LocalAddr: client.localAddr, LocalAddr: client.localAddr,
//Resolver: &net.Resolver{
// PreferGo: true,
// Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
// d := net.Dialer{
// Timeout: 10 * time.Second,
// }
// return d.DialContext(ctx, "udp", "8.8.8.8:53")
// },
//},
} }
conn, err := dialer.Dial(common.TCP, packet.Extra) conn, err := dialer.Dial(common.TCP, packet.Extra)
...@@ -231,7 +222,7 @@ func (client *Client) handleDisconnectMessage(session getty.Session, packet *pro ...@@ -231,7 +222,7 @@ func (client *Client) handleDisconnectMessage(session getty.Session, packet *pro
log.Run().Debugf("[handleDisconnectMessage] %d->session closed %v extra:%s", packet.SerialNumber, session.IsClosed()) log.Run().Debugf("[handleDisconnectMessage] %d->session closed %v extra:%s", packet.SerialNumber, session.IsClosed())
if conn, ok := client.connStore.Load(packet.SerialNumber); ok { if conn, ok := client.connStore.Load(packet.SerialNumber); ok {
upstreamConn := conn.(*net.TCPConn) upstreamConn := conn.(*net.TCPConn)
readDeadLine := time.Now().Add(10 * time.Millisecond) readDeadLine := time.Now().Add(3 * time.Millisecond)
traceRecorder.RecordEvent(trace.DisconnectEvent, fmt.Sprintf("Set upstream read deadline:%s (sn:%d)", traceRecorder.RecordEvent(trace.DisconnectEvent, fmt.Sprintf("Set upstream read deadline:%s (sn:%d)",
readDeadLine.Format("2006-01-02 15:04:05.000000"), packet.SerialNumber)) readDeadLine.Format("2006-01-02 15:04:05.000000"), packet.SerialNumber))
err := upstreamConn.SetReadDeadline(readDeadLine) err := upstreamConn.SetReadDeadline(readDeadLine)
......
env = debug
tunnel_addr = 127.0.0.1:5879
;tunnel_addr = aoba.vip:5879
dns_server = 114.114.114.114:53
;bind to local ip
;local_ip = 192.168.0.100
;for performance pprof 0 is close
pprof_port = 16666
log_level = debug
reconn_interval = 5s
net_check_interval = 5s
net_check_url = https://www.baidu.com[extra]
account = superman
[redial]
; on windows is cmd.exe
; on *nix is /bin/bash
;command = /bin/bash
; windows bat 脚本的绝对路径
; *nix shell脚本的绝对路径 D:\redial\redial.bat
;exec_path = ls
;redial_duration = 30s
;wait_time = 10s
env: debug
tunnel_addr: 127.0.0.1:5879
dns_server: 114.114.114.114:53
pprof_port: 16666
log_level: debug
log_path: ./output/log/
reconn_intervalz: 5s
net_check_interval: 5s
net_check_url: https://www.baidu.com[extra]
account: superman
tunnel_addr = majora-vps-zj.virjar.com:5879
dns_server = 114.114.114.114:53
;bind to local ip
;local_ip = 192.168.0.100
; default is info
log_level = 1
reconn_interval = 5s
net_check_interval = 5s
net_check_url = https://www.baidu.com
[extra]
account = superman
[redial]
;command = /bin/bash
;exec_path = /root/ppp_redial.sh
;redial_duration = 10m
;wait_time = 10s
env: debug
tunnel_addr: majora-vps-zj.virjar.com:5879
dns_server: 114.114.114.114:53
log_level: info
reconn_interval: 5s
net_check_interval: 5s
net_check_url: https://www.baidu.com
\ No newline at end of file
...@@ -15,4 +15,4 @@ echo "clean old ..." ...@@ -15,4 +15,4 @@ echo "clean old ..."
mkdir -p output/log mkdir -p output/log
exec ./majora -daemon -conf majora.ini exec ./majora -daemon -conf majora.yaml
\ No newline at end of file \ No newline at end of file
...@@ -5,9 +5,9 @@ wget https://oss.virjar.com/majora/bin/latest/majora-cli_latest_linux_amd64.tar. ...@@ -5,9 +5,9 @@ wget https://oss.virjar.com/majora/bin/latest/majora-cli_latest_linux_amd64.tar.
rm -fr majora rm -fr majora
rm -fr exec.sh rm -fr exec.sh
rm -fr start.sh rm -fr start.sh
rm -fr majora.ini rm -fr majora.yaml
rm -fr majora.service rm -fr majora.service
rm -fr majora-dev.ini rm -fr majora-dev.yaml
rm -fr majora.log rm -fr majora.log
rm -fr output rm -fr output
rm -fr std.log rm -fr std.log
......
...@@ -6,9 +6,6 @@ import ( ...@@ -6,9 +6,6 @@ import (
"fmt" "fmt"
) )
var CurrentEnv = Product
var errUnmarshalEnv = errors.New("can't unmarshal a nil *Level") var errUnmarshalEnv = errors.New("can't unmarshal a nil *Level")
type Env int8 type Env int8
......
package global
import (
"virjar.com/majora-go/env"
"virjar.com/majora-go/model"
)
var (
Config = model.NewDefMajoraConf()
CurrentEnv = env.Product
)
...@@ -6,12 +6,14 @@ require ( ...@@ -6,12 +6,14 @@ require (
github.com/adamweixuan/getty v0.0.1 github.com/adamweixuan/getty v0.0.1
github.com/adamweixuan/gostnops v0.0.1 github.com/adamweixuan/gostnops v0.0.1
github.com/google/uuid v1.3.0 github.com/google/uuid v1.3.0
gopkg.in/ini.v1 v1.63.2 gopkg.in/ini.v1 v1.66.2
) )
require ( require (
github.com/BurntSushi/toml v0.4.1 // indirect github.com/BurntSushi/toml v0.4.1 // indirect
github.com/fsnotify/fsnotify v1.5.1
github.com/natefinch/lumberjack v2.0.0+incompatible github.com/natefinch/lumberjack v2.0.0+incompatible
github.com/spf13/viper v1.10.1
go.uber.org/multierr v1.7.0 // indirect go.uber.org/multierr v1.7.0 // indirect
go.uber.org/zap v1.19.1 go.uber.org/zap v1.19.1
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
......
This diff is collapsed.
package initialize
import (
"github.com/fsnotify/fsnotify"
"github.com/spf13/viper"
)
// MustInitConfigAndWatch 第一次初始化 config 时必须成功,否则 panic;
func MustInitConfigAndWatch(configFileName string, config interface{}, watch func(config interface{}, err error)) {
v, err := initConfig(configFileName, config)
if err != nil {
panic(err)
}
watchConfigFile(v, func(in fsnotify.Event) {
err = readAndUnmarshalConfig(v, config)
watch(config, err)
})
}
// MustInitConfig 初始化 config 时必须成功,否则 panic;
func MustInitConfig(configFileName string, config interface{}) {
_, err := initConfig(configFileName, config)
if err != nil {
panic(err)
}
}
func initConfig(configFileName string, config interface{}) (*viper.Viper, error) {
if configFileName == "" {
configFileName = "./conf/majora-dev.yaml"
}
v := viper.New()
v.SetConfigFile(configFileName)
err := readAndUnmarshalConfig(v, config)
if err != nil {
return nil, err
}
return v, nil
}
func watchConfigFile(v *viper.Viper, run func(in fsnotify.Event)) {
v.WatchConfig()
v.OnConfigChange(run)
}
func readAndUnmarshalConfig(v *viper.Viper, config interface{}) error {
err := v.ReadInConfig()
if err != nil {
return err
}
err = v.Unmarshal(config)
if err != nil {
return err
}
return nil
}
package initialize
import (
"fmt"
"testing"
"virjar.com/majora-go/global"
)
func TestMustInitConfig(t *testing.T) {
MustInitConfigAndWatch("/Users/tsaiilin/src/go/majora-go/conf/majora-dev.yaml", global.Config, func(config interface{}) {
fmt.Printf("config: %+v", global.Config)
})
select {
}
}
package initialize
import (
"virjar.com/majora-go/global"
"virjar.com/majora-go/log"
)
func InitLogger() {
// 暂时在这里初始化环境
_ = global.CurrentEnv.Set(global.Config.Env)
log.Init(global.Config.LogLevel, global.Config.LogPath)
}
\ No newline at end of file
package initialize
import (
"testing"
"virjar.com/majora-go/log"
)
func TestInitLogger(t *testing.T) {
log.Init("debug", "")
log.Run().Info("adfdfsfsf")
}
package log package log
import ( import (
"github.com/natefinch/lumberjack"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"os" "os"
"path/filepath" "path/filepath"
"time" "time"
"github.com/adamweixuan/getty" "github.com/adamweixuan/getty"
"github.com/natefinch/lumberjack"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"virjar.com/majora-go/env" "virjar.com/majora-go/env"
"virjar.com/majora-go/global"
) )
var ( var (
...@@ -19,10 +21,10 @@ var ( ...@@ -19,10 +21,10 @@ var (
) )
const ( const (
logDir = "./output/log/" logDir = "./output/log/"
run = "run.log" run = "run.log"
trace = "trace.log" trace = "trace.log"
error = "error.log" errorLog = "error.log"
logTmFmtWithMS = "2006-01-02 15:04:05.000" logTmFmtWithMS = "2006-01-02 15:04:05.000"
) )
...@@ -36,7 +38,7 @@ func getLogWriter(path string) zapcore.WriteSyncer { ...@@ -36,7 +38,7 @@ func getLogWriter(path string) zapcore.WriteSyncer {
MaxAge: 30, MaxAge: 30,
Compress: false, Compress: false,
} }
if env.CurrentEnv == env.Debug { if global.CurrentEnv == env.Debug {
return zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(lumberJackLogger)) return zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(lumberJackLogger))
} }
return zapcore.AddSync(lumberJackLogger) return zapcore.AddSync(lumberJackLogger)
...@@ -61,34 +63,15 @@ func getEncoder() zapcore.Encoder { ...@@ -61,34 +63,15 @@ func getEncoder() zapcore.Encoder {
return zapcore.NewConsoleEncoder(encoderConfig) return zapcore.NewConsoleEncoder(encoderConfig)
} }
func getCurPath() string { func Init(level string, logPath string) {
exePath, err := os.Executable()
if err != nil {
panic(err)
}
return filepath.Dir(exePath)
}
func Init(level string) {
curPath := getCurPath()
base := filepath.Join(curPath, logDir)
if _, err := os.Stat(base); err != nil {
if os.IsNotExist(err) {
if err := os.MkdirAll(base, os.ModePerm); err != nil {
panic(err)
}
} else {
panic(err)
}
}
if len(curPath) == 0 { if len(logPath) == 0 {
panic("invalid current path") logPath = logDir
} }
runLogger = initSugaredLogger(filepath.Join(base, run), true, level) runLogger = initSugaredLogger(filepath.Join(logPath, run), true, level)
errorLogger = initSugaredLogger(filepath.Join(base, error), true, level) errorLogger = initSugaredLogger(filepath.Join(logPath, errorLog), true, level)
traceLogger = initSugaredLogger(filepath.Join(base, trace), false, level) traceLogger = initSugaredLogger(filepath.Join(logPath, trace), false, level)
// 框架的日志也输入到 run.log 中 // 框架的日志也输入到 run.log 中
getty.SetLogger(runLogger) getty.SetLogger(runLogger)
} }
......
...@@ -9,29 +9,30 @@ import ( ...@@ -9,29 +9,30 @@ import (
) )
type Redial struct { type Redial struct {
Command string `ini:"command" json:"command"` Command string `mapstructure:"command"`
ExecPath string `ini:"exec_path" json:"exec_path"` ExecPath string `mapstructure:"exec_path"`
RedialDuration time.Duration `ini:"redial_duration" json:"redial_duration"` RedialDuration time.Duration `mapstructure:"redial_duration"`
WaitTime time.Duration `ini:"wait_time" json:"wait_time"` WaitTime time.Duration `mapstructure:"wait_time"`
} }
type Extra struct { type Extra struct {
Account string `ini:"account" json:"account"` Account string `mapstructure:"account"`
} }
type Configure struct { type Configure struct {
Env string `ini:"env" json:"env"` Env string `mapstructure:"env"`
LogLevel string `ini:"log_level" json:"log_level"` LogLevel string `mapstructure:"log_level"`
PprofPort int `ini:"pprof_port" json:"pprof_port"` LogPath string `mapstructure:"log_path"`
TunnelAddr string `ini:"tunnel_addr" json:"tunnel_addr"` PprofPort int `mapstructure:"pprof_port"`
DNSServer string `ini:"dns_server" json:"dns_server"` TunnelAddr string `mapstructure:"tunnel_addr"`
LocalAddr string `ini:"local_ip" json:"local_ip"` DNSServer string `mapstructure:"dns_server"`
ReconnInterval time.Duration `ini:"reconn_interval" json:"reconn_interval"` LocalAddr string `mapstructure:"local_ip"`
ClientID string `ini:"client_id" json:"client_id"` ReconnInterval time.Duration `mapstructure:"reconn_interval"`
NetCheckInterval time.Duration `ini:"net_check_interval" json:"net_check_interval"` ClientID string `mapstructure:"client_id"`
NetCheckUrl string `ini:"net_check_url" json:"net_check_url"` NetCheckInterval time.Duration `mapstructure:"net_check_interval"`
Extra Extra `ini:"extra" json:"extra"` NetCheckUrl string `mapstructure:"net_check_url"`
Redial Redial `ini:"redial" json:"redial"` Extra Extra `mapstructure:"extra"`
Redial Redial `mapstructure:"redial"`
} }
const ( const (
......
package model
import (
"testing"
"github.com/google/uuid"
)
func TestInitConf(t *testing.T) {
conf := InitConf("/Users/weixuan/code/gcode/majora-go/conf/majora.ini")
t.Logf("conf %+v", conf)
t.Logf("%s", uuid.NewString())
}
...@@ -6,12 +6,13 @@ import ( ...@@ -6,12 +6,13 @@ import (
"time" "time"
"virjar.com/majora-go/env" "virjar.com/majora-go/env"
"virjar.com/majora-go/global"
"virjar.com/majora-go/log" "virjar.com/majora-go/log"
"virjar.com/majora-go/safe" "virjar.com/majora-go/safe"
) )
var ( var (
sessionEventChan = make(chan *sessionEvent, runtime.GOMAXPROCS(-1) * 100) sessionEventChan = make(chan *sessionEvent, runtime.GOMAXPROCS(-1)*100)
ConnectEvent = "ConnectEvent" ConnectEvent = "ConnectEvent"
TransferEvent = "TransferEvent" TransferEvent = "TransferEvent"
MajoraSessionName = "MajoraSessionId" MajoraSessionName = "MajoraSessionId"
...@@ -116,7 +117,7 @@ var defaultNopRecorder = nopRecorder{} ...@@ -116,7 +117,7 @@ var defaultNopRecorder = nopRecorder{}
var slots = make([]int64, 30) var slots = make([]int64, 30)
func acquireRecorder(sessionId string) Recorder { func acquireRecorder(sessionId string) Recorder {
if env.CurrentEnv == env.Debug { if global.CurrentEnv == env.Debug {
return &recorderImpl{sessionId: sessionId} return &recorderImpl{sessionId: sessionId}
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment