提交 c580bfa9 编写于 作者: Y Your Name

#console 整理代码

上级 dc5082a8
/.idea/ /.idea/
/vendor/
/out/
/vendor
/.vscode/
\ No newline at end of file
cluster: cluster:
- - name: "Default"
name: "Default"
title: "默认机房" title: "默认机房"
note: "默认机房" note: "默认机房"
db: db:
......
...@@ -15,17 +15,16 @@ var ( ...@@ -15,17 +15,16 @@ var (
UserPassword string UserPassword string
UserName string UserName string
ConfFilepath = "./config/goku.conf" ConfFilepath = "./config/goku.conf"
) )
func main() { func main() {
flag.StringVar(&ConfFilepath, "c", "./config/goku.conf", "Please provide a valid configuration file path") flag.StringVar(&ConfFilepath, "c", "./config/goku.conf", "Please provide a valid configuration file path")
flag.StringVar(&UserName, "u", "", "Please provide user name") flag.StringVar(&UserName, "u", "", "Please provide user name")
flag.StringVar(&UserPassword, "p", "", "Please provide user password") flag.StringVar(&UserPassword, "p", "", "Please provide user password")
isDebug := flag.Bool("debug",false,"") isDebug := flag.Bool("debug", false, "")
flag.Parse() flag.Parse()
if *isDebug{ if *isDebug {
log.StartDebug() log.StartDebug()
} }
// 初始化配置 // 初始化配置
...@@ -42,11 +41,10 @@ func main() { ...@@ -42,11 +41,10 @@ func main() {
_ = general.General() _ = general.General()
// 检测是否安装 // 检测是否安装
if s, err := account.CheckSuperAdminCount(); err != nil {
if s, err := account.CheckSuperAdminCount(); err!= nil {
log.Panic(err) log.Panic(err)
return return
}else if s == 0 { } else if s == 0 {
if UserName == "" { if UserName == "" {
log.Fatal("[ERROR] Fail to create administrator. Please try again or contact technical support of eoLinker GOKU API Gateway.") log.Fatal("[ERROR] Fail to create administrator. Please try again or contact technical support of eoLinker GOKU API Gateway.")
//fmt.Println("[ERROR] Fail to create administrator. Please try again or contact technical support of eoLinker GOKU API Gateway.") //fmt.Println("[ERROR] Fail to create administrator. Please try again or contact technical support of eoLinker GOKU API Gateway.")
...@@ -68,7 +66,6 @@ func main() { ...@@ -68,7 +66,6 @@ func main() {
} }
} }
console.Router() console.Router()
console.Server() console.Server()
} }
...@@ -40,16 +40,15 @@ func initConfig(resultInfo map[string]interface{}) *entity.ClusterInfo { ...@@ -40,16 +40,15 @@ func initConfig(resultInfo map[string]interface{}) *entity.ClusterInfo {
func main() { func main() {
runtime.GOMAXPROCS(runtime.NumCPU()) runtime.GOMAXPROCS(runtime.NumCPU())
flag.StringVar(&adminHost, "admin", "127.0.0.1:7005", "Please provide a valid host!") flag.StringVar(&adminHost, "admin", "127.0.0.1:7005", "Please provide a valid host!")
//flag.IntVar(&adminPort, "P", 7005, "Please provide a valid port") //flag.IntVar(&adminPort, "P", 7005, "Please provide a valid port")
flag.IntVar(&listenPort, "port", 6689, "Please provide a valid listen port!") flag.IntVar(&listenPort, "port", 6689, "Please provide a valid listen port!")
isDebug := flag.Bool("debug",false,"") isDebug := flag.Bool("debug", false, "")
flag.Parse() flag.Parse()
if *isDebug{ if *isDebug {
log.StartDebug() log.StartDebug()
} }
// //
...@@ -64,9 +63,9 @@ func main() { ...@@ -64,9 +63,9 @@ func main() {
node_common.SetClusterName(config.Name) node_common.SetClusterName(config.Name)
err:=database.InitConnection(&config.DB) err := database.InitConnection(&config.DB)
if err!=nil{ if err != nil {
log.Fatal("Fail to Init db:",err) log.Fatal("Fail to Init db:", err)
return return
} }
goku_node.InitLog() goku_node.InitLog()
...@@ -76,7 +75,7 @@ func main() { ...@@ -76,7 +75,7 @@ func main() {
log.Debug("redis_manager.SetDefault") log.Debug("redis_manager.SetDefault")
// 其他需要初始化的模块 // 其他需要初始化的模块
_=general.General() _ = general.General()
log.Debug("general.General()") log.Debug("general.General()")
goku_node.InitServer() goku_node.InitServer()
...@@ -89,5 +88,4 @@ func main() { ...@@ -89,5 +88,4 @@ func main() {
} }
log.Fatalf("Server on :%d stoped \n", listenPort) log.Fatalf("Server on :%d stoped \n", listenPort)
} }
package auto package auto
import ( import (
"errors" "errors"
"fmt" "fmt"
"net" "net"
...@@ -90,10 +89,10 @@ func setValues(ctx Values, c interface{}) error { ...@@ -90,10 +89,10 @@ func setValues(ctx Values, c interface{}) error {
if !has { if !has {
continue continue
} }
if tag == "-"{ if tag == "-" {
continue continue
} }
name,opts := parseTag(tag) name, opts := parseTag(tag)
if !isValidTag(name) { if !isValidTag(name) {
continue continue
} }
...@@ -104,8 +103,8 @@ func setValues(ctx Values, c interface{}) error { ...@@ -104,8 +103,8 @@ func setValues(ctx Values, c interface{}) error {
return err return err
} }
} else { } else {
if opts.Contains("require"){ if opts.Contains("require") {
return fmt.Errorf("require value of [%s] but has no",name) return fmt.Errorf("require value of [%s] but has no", name)
} }
defaultVal := field.Tag.Get("default") defaultVal := field.Tag.Get("default")
......
...@@ -137,7 +137,7 @@ func NewServer(addr string, handler http.Handler) (srv *endlessServer) { ...@@ -137,7 +137,7 @@ func NewServer(addr string, handler http.Handler) (srv *endlessServer) {
srv.Server.Handler = handler srv.Server.Handler = handler
srv.BeforeBegin = func(addr string) { srv.BeforeBegin = func(addr string) {
log.Info("start service:",syscall.Getpid(), addr) log.Info("start service:", syscall.Getpid(), addr)
} }
runningServersOrder = append(runningServersOrder, addr) runningServersOrder = append(runningServersOrder, addr)
......
...@@ -28,20 +28,20 @@ func get(name string) (Redis, bool) { ...@@ -28,20 +28,20 @@ func get(name string) (Redis, bool) {
return r, h return r, h
} }
func Get(name string) (Redis, bool) { func Get(name string) (Redis, bool) {
r,has:=get(name) r, has := get(name)
if has{ if has {
return r,r!=nil return r, r != nil
} }
locker.Lock() locker.Lock()
defer locker.Unlock() defer locker.Unlock()
r, has = redisOfCluster[name] r, has = redisOfCluster[name]
if has{ if has {
return r,has return r, has
} }
c,h:= redisConfCluster[name] c, h := redisConfCluster[name]
if h{ if h {
r = Create(c) r = Create(c)
redisOfCluster[name] = r redisOfCluster[name] = r
return r, h return r, h
...@@ -49,5 +49,5 @@ func Get(name string) (Redis, bool) { ...@@ -49,5 +49,5 @@ func Get(name string) (Redis, bool) {
redisOfCluster[name] = nil redisOfCluster[name] = nil
return nil,false return nil, false
} }
...@@ -9,18 +9,16 @@ type redisProxy struct { ...@@ -9,18 +9,16 @@ type redisProxy struct {
config RedisConfig config RedisConfig
} }
func (p *redisProxy) Nodes() []string { func (p *redisProxy) Nodes() []string {
ch := make(chan string, 1)
ch:= make(chan string,1)
switch p.config.GetMode() { switch p.config.GetMode() {
case RedisModeCluster: case RedisModeCluster:
{ {
conn := p.Cmdable.(*redis.ClusterClient) conn := p.Cmdable.(*redis.ClusterClient)
go func(ch chan string ) { go func(ch chan string) {
conn.ForEachMaster(func(client *redis.Client) error { conn.ForEachMaster(func(client *redis.Client) error {
ch<-client.Options().Addr ch <- client.Options().Addr
return nil return nil
}) })
close(ch) close(ch)
...@@ -31,9 +29,9 @@ func (p *redisProxy) Nodes() []string { ...@@ -31,9 +29,9 @@ func (p *redisProxy) Nodes() []string {
{ {
conn := p.Cmdable.(*redis.SentinelRing) conn := p.Cmdable.(*redis.SentinelRing)
go func(ch chan string ) { go func(ch chan string) {
conn.ForEachAddr(func(addr string) error { conn.ForEachAddr(func(addr string) error {
ch<-addr ch <- addr
return nil return nil
}) })
close(ch) close(ch)
...@@ -43,9 +41,9 @@ func (p *redisProxy) Nodes() []string { ...@@ -43,9 +41,9 @@ func (p *redisProxy) Nodes() []string {
{ {
conn := p.Cmdable.(*redis.Ring) conn := p.Cmdable.(*redis.Ring)
go func(ch chan string ) { go func(ch chan string) {
conn.ForEachShard(func(client *redis.Client) error { conn.ForEachShard(func(client *redis.Client) error {
ch<-client.Options().Addr ch <- client.Options().Addr
return nil return nil
}) })
close(ch) close(ch)
...@@ -53,10 +51,9 @@ func (p *redisProxy) Nodes() []string { ...@@ -53,10 +51,9 @@ func (p *redisProxy) Nodes() []string {
} }
} }
nodes := make([]string, 0, 10)
nodes:= make([]string,0,10) for addr := range ch {
for addr:=range ch{ nodes = append(nodes, addr)
nodes = append(nodes,addr)
} }
return nodes return nodes
} }
......
...@@ -8,12 +8,11 @@ const ( ...@@ -8,12 +8,11 @@ const (
RedisModeStand = "stand" RedisModeStand = "stand"
) )
type Redis interface { type Redis interface {
redis.Cmdable redis.Cmdable
GetConfig() RedisConfig GetConfig() RedisConfig
//Foreach(fn func(client *localRedis.Client) error) error //Foreach(fn func(client *localRedis.Client) error) error
Nodes()[]string Nodes() []string
} }
type RedisConfig interface { type RedisConfig interface {
......
...@@ -30,4 +30,3 @@ func GetConnection() Redis { ...@@ -30,4 +30,3 @@ func GetConnection() Redis {
def = Create(defaultConfig) def = Create(defaultConfig)
return def return def
} }
...@@ -17,13 +17,12 @@ import ( ...@@ -17,13 +17,12 @@ import (
"github.com/eolinker/goku/common/redis/internal" "github.com/eolinker/goku/common/redis/internal"
) )
// RingOptions are used to configure a ring client and should be // RingOptions are used to configure a ring client and should be
// passed to NewRing. // passed to NewRing.
type SentinelRingOptions struct { type SentinelRingOptions struct {
// Map of name => host:port addresses of ring shards. // Map of name => host:port addresses of ring shards.
Addrs []string Addrs []string
Masters[]string Masters []string
// Frequency of PING commands sent to check shards availability. // Frequency of PING commands sent to check shards availability.
// Shard is considered down after 3 subsequent failed checks. // Shard is considered down after 3 subsequent failed checks.
HeartbeatFrequency time.Duration HeartbeatFrequency time.Duration
...@@ -98,8 +97,8 @@ func (opt *SentinelRingOptions) init() { ...@@ -98,8 +97,8 @@ func (opt *SentinelRingOptions) init() {
func (opt *SentinelRingOptions) clientOptions(masterName string) *FailoverOptions { func (opt *SentinelRingOptions) clientOptions(masterName string) *FailoverOptions {
return &FailoverOptions{ return &FailoverOptions{
MasterName:masterName, MasterName: masterName,
SentinelAddrs:opt.Addrs, SentinelAddrs: opt.Addrs,
DB: opt.DB, DB: opt.DB,
Password: opt.Password, Password: opt.Password,
...@@ -322,8 +321,8 @@ func NewSentinelRing(opt *SentinelRingOptions) *SentinelRing { ...@@ -322,8 +321,8 @@ func NewSentinelRing(opt *SentinelRingOptions) *SentinelRing {
clopt := opt.clientOptions(masterName) clopt := opt.clientOptions(masterName)
ring.shards.Add(masterName, NewFailoverClient(clopt)) ring.shards.Add(masterName, NewFailoverClient(clopt))
} }
ring.sentinelClients = make([]*SentinelClient,0,len(opt.Addrs)) ring.sentinelClients = make([]*SentinelClient, 0, len(opt.Addrs))
for _, addr:=range opt.Addrs{ for _, addr := range opt.Addrs {
sentinel := NewSentinelClient(&Options{ sentinel := NewSentinelClient(&Options{
Addr: addr, Addr: addr,
...@@ -339,7 +338,7 @@ func NewSentinelRing(opt *SentinelRingOptions) *SentinelRing { ...@@ -339,7 +338,7 @@ func NewSentinelRing(opt *SentinelRingOptions) *SentinelRing {
IdleTimeout: opt.IdleTimeout, IdleTimeout: opt.IdleTimeout,
IdleCheckFrequency: opt.IdleCheckFrequency, IdleCheckFrequency: opt.IdleCheckFrequency,
}) })
ring.sentinelClients = append(ring.sentinelClients,sentinel) ring.sentinelClients = append(ring.sentinelClients, sentinel)
} }
go ring.shards.Heartbeat(opt.HeartbeatFrequency) go ring.shards.Heartbeat(opt.HeartbeatFrequency)
...@@ -429,21 +428,18 @@ func (c *SentinelRing) PSubscribe(channels ...string) *PubSub { ...@@ -429,21 +428,18 @@ func (c *SentinelRing) PSubscribe(channels ...string) *PubSub {
//// It returns the first error if any. //// It returns the first error if any.
func (c *SentinelRing) ForEachAddr(fn func(addr string) error) error { func (c *SentinelRing) ForEachAddr(fn func(addr string) error) error {
for _, masterName := range c.opt.Masters { for _, masterName := range c.opt.Masters {
for _, sentinel := range c.sentinelClients { for _, sentinel := range c.sentinelClients {
masterAddrs, err := sentinel.GetMasterAddrByName(masterName).Result() masterAddrs, err := sentinel.GetMasterAddrByName(masterName).Result()
if err != nil { if err != nil {
internal.Logf("sentinel: GetMasterAddrByName master=%q failed: %s",masterName, err) internal.Logf("sentinel: GetMasterAddrByName master=%q failed: %s", masterName, err)
continue continue
} }
fn(fmt.Sprintf("%s:%s",masterAddrs[0],masterAddrs[1])) fn(fmt.Sprintf("%s:%s", masterAddrs[0], masterAddrs[1]))
break break
} }
......
...@@ -5,7 +5,8 @@ import ( ...@@ -5,7 +5,8 @@ import (
"strconv" "strconv"
"strings" "strings"
) )
func GetIpPort(r *http.Request) (string,int,error){
func GetIpPort(r *http.Request) (string, int, error) {
ip := r.RemoteAddr ip := r.RemoteAddr
ip = ip[:strings.Index(ip, ":")] ip = ip[:strings.Index(ip, ":")]
if realIP := strings.TrimSpace(r.Header.Get("X-Real-Ip")); realIP != "" { if realIP := strings.TrimSpace(r.Header.Get("X-Real-Ip")); realIP != "" {
...@@ -15,9 +16,7 @@ func GetIpPort(r *http.Request) (string,int,error){ ...@@ -15,9 +16,7 @@ func GetIpPort(r *http.Request) (string,int,error){
p := r.FormValue("port") p := r.FormValue("port")
port, err := strconv.Atoi(p) port, err := strconv.Atoi(p)
if err != nil { if err != nil {
return ip,port,err return ip, port, err
} }
return ip,port,nil return ip, port, nil
} }
...@@ -15,20 +15,18 @@ func heartbead(w http.ResponseWriter, r *http.Request) { ...@@ -15,20 +15,18 @@ func heartbead(w http.ResponseWriter, r *http.Request) {
controller.WriteError(w, "700000", "node", err.Error(), err) controller.WriteError(w, "700000", "node", err.Error(), err)
return return
} }
node.Refresh(ip,strconv.Itoa(port)) node.Refresh(ip, strconv.Itoa(port))
controller.WriteResultInfo(w, "node", "node", nil) controller.WriteResultInfo(w, "node", "node", nil)
} }
func stopNode(w http.ResponseWriter, r *http.Request) { func stopNode(w http.ResponseWriter, r *http.Request) {
ip, port, err := GetIpPort(r) ip, port, err := GetIpPort(r)
if err != nil { if err != nil {
controller.WriteError(w, "700000", "node", err.Error(), err) controller.WriteError(w, "700000", "node", err.Error(), err)
return return
} }
node.NodeStop(ip,strconv.Itoa(port)) node.NodeStop(ip, strconv.Itoa(port))
controller.WriteResultInfo(w, "node", "node", nil) controller.WriteResultInfo(w, "node", "node", nil)
} }
...@@ -22,7 +22,7 @@ func Register(w http.ResponseWriter, r *http.Request) { ...@@ -22,7 +22,7 @@ func Register(w http.ResponseWriter, r *http.Request) {
controller.WriteError(w, "700001", "cluster", err.Error()+ip, err) controller.WriteError(w, "700001", "cluster", err.Error()+ip, err)
return return
} }
node.Refresh(ip,strconv.Itoa(port)) node.Refresh(ip, strconv.Itoa(port))
controller.WriteResultInfo(w, "cluster", "cluster", cluster) controller.WriteResultInfo(w, "cluster", "cluster", cluster)
} }
......
...@@ -7,7 +7,7 @@ func router() http.Handler { ...@@ -7,7 +7,7 @@ func router() http.Handler {
serverHandler := http.NewServeMux() serverHandler := http.NewServeMux()
serverHandler.HandleFunc("/register", Register) serverHandler.HandleFunc("/register", Register)
serverHandler.HandleFunc("/node/heartbeat", heartbead) serverHandler.HandleFunc("/node/heartbeat", heartbead)
serverHandler.HandleFunc("/node/stop",stopNode) serverHandler.HandleFunc("/node/stop", stopNode)
serverHandler.HandleFunc("/alert/msg/add", AddAlertMsg) serverHandler.HandleFunc("/alert/msg/add", AddAlertMsg)
return serverHandler return serverHandler
} }
...@@ -9,8 +9,6 @@ import ( ...@@ -9,8 +9,6 @@ import (
"strconv" "strconv"
) )
// 用户登录 // 用户登录
func Login(httpResponse http.ResponseWriter, httpRequest *http.Request) { func Login(httpResponse http.ResponseWriter, httpRequest *http.Request) {
......
package node package node
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
log "github.com/eolinker/goku/goku-log" log "github.com/eolinker/goku/goku-log"
"net/http" "net/http"
"strconv" "strconv"
"github.com/eolinker/goku/console/controller" "github.com/eolinker/goku/console/controller"
"github.com/eolinker/goku/console/module/node" "github.com/eolinker/goku/console/module/node"
cluster2 "github.com/eolinker/goku/server/cluster" cluster2 "github.com/eolinker/goku/server/cluster"
...@@ -42,7 +39,6 @@ func AddNode(httpResponse http.ResponseWriter, httpRequest *http.Request) { ...@@ -42,7 +39,6 @@ func AddNode(httpResponse http.ResponseWriter, httpRequest *http.Request) {
groupID := httpRequest.PostFormValue("groupID") groupID := httpRequest.PostFormValue("groupID")
gatewayPath := httpRequest.PostFormValue("gatewayPath") gatewayPath := httpRequest.PostFormValue("gatewayPath")
gID, err := strconv.Atoi(groupID) gID, err := strconv.Atoi(groupID)
if err != nil && groupID != "" { if err != nil && groupID != "" {
controller.WriteError(httpResponse, "230015", "", "[ERROR]Illegal groupID!", err) controller.WriteError(httpResponse, "230015", "", "[ERROR]Illegal groupID!", err)
...@@ -72,7 +68,6 @@ func AddNode(httpResponse http.ResponseWriter, httpRequest *http.Request) { ...@@ -72,7 +68,6 @@ func AddNode(httpResponse http.ResponseWriter, httpRequest *http.Request) {
} }
} }
exits := node.CheckIsExistRemoteAddr(0, nodeIP, nodePort) exits := node.CheckIsExistRemoteAddr(0, nodeIP, nodePort)
if exits { if exits {
...@@ -84,8 +79,6 @@ func AddNode(httpResponse http.ResponseWriter, httpRequest *http.Request) { ...@@ -84,8 +79,6 @@ func AddNode(httpResponse http.ResponseWriter, httpRequest *http.Request) {
return return
} }
flag, result, err := node.AddNode(clusterId, nodeName, nodeIP, nodePort, gatewayPath, gID) flag, result, err := node.AddNode(clusterId, nodeName, nodeIP, nodePort, gatewayPath, gID)
if !flag { if !flag {
...@@ -292,7 +285,6 @@ func GetNodeInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { ...@@ -292,7 +285,6 @@ func GetNodeInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) {
return return
} }
// 节点IP查重 // 节点IP查重
func CheckIsExistRemoteAddr(httpResponse http.ResponseWriter, httpRequest *http.Request) { func CheckIsExistRemoteAddr(httpResponse http.ResponseWriter, httpRequest *http.Request) {
...@@ -331,7 +323,6 @@ func CheckIsExistRemoteAddr(httpResponse http.ResponseWriter, httpRequest *http. ...@@ -331,7 +323,6 @@ func CheckIsExistRemoteAddr(httpResponse http.ResponseWriter, httpRequest *http.
return return
} }
// 批量修改节点分组 // 批量修改节点分组
func BatchEditNodeGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { func BatchEditNodeGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) {
......
...@@ -188,8 +188,8 @@ func GetNodeGroupList(httpResponse http.ResponseWriter, httpRequest *http.Reques ...@@ -188,8 +188,8 @@ func GetNodeGroupList(httpResponse http.ResponseWriter, httpRequest *http.Reques
} }
cluserName := httpRequest.FormValue("cluster") cluserName := httpRequest.FormValue("cluster")
clusterId,has := cluster2.GetId(cluserName) clusterId, has := cluster2.GetId(cluserName)
if !has{ if !has {
controller.WriteError(httpResponse, controller.WriteError(httpResponse,
"280001", "280001",
"nodeGroup", "nodeGroup",
......
...@@ -8,8 +8,8 @@ import ( ...@@ -8,8 +8,8 @@ import (
func InitLog() { func InitLog() {
c, _ := module.Get(module.ConsoleLog) c, _ := module.Get(module.ConsoleLog)
period,_:=log.ParsePeriod(c.Period) period, _ := log.ParsePeriod(c.Period)
log.SetOutPut(c.Enable ,c.Dir,c.File,period,c.Expire) log.SetOutPut(c.Enable, c.Dir, c.File, period, c.Expire)
l,_:= log.ParseLevel(c.Level) l, _ := log.ParseLevel(c.Level)
log.SetLevel(l) log.SetLevel(l)
} }
...@@ -19,7 +19,7 @@ func Register(loginCall, loginPassword string) bool { ...@@ -19,7 +19,7 @@ func Register(loginCall, loginPassword string) bool {
return console_mysql.Register(loginCall, loginPassword) return console_mysql.Register(loginCall, loginPassword)
} }
func CheckSuperAdminCount()(int,error){ func CheckSuperAdminCount() (int, error) {
b,err:=console_mysql.CheckSuperAdminCount() b, err := console_mysql.CheckSuperAdminCount()
return b,err return b, err
} }
...@@ -3,6 +3,7 @@ package account ...@@ -3,6 +3,7 @@ package account
import ( import (
"github.com/eolinker/goku/server/dao/console-mysql" "github.com/eolinker/goku/server/dao/console-mysql"
) )
// 获取具有编辑权限的用户列表 // 获取具有编辑权限的用户列表
func GetUserListWithPermission(operationType, operation string) (bool, []map[string]interface{}, error) { func GetUserListWithPermission(operationType, operation string) (bool, []map[string]interface{}, error) {
return console_mysql.GetUserListWithPermission(operationType, operation) return console_mysql.GetUserListWithPermission(operationType, operation)
......
package api package api
import ( import (
dao "github.com/eolinker/goku/server/dao" "github.com/eolinker/goku/server/dao"
console_mysql "github.com/eolinker/goku/server/dao/console-mysql" console_mysql "github.com/eolinker/goku/server/dao/console-mysql"
entity "github.com/eolinker/goku/server/entity/console-entity" entity "github.com/eolinker/goku/server/entity/console-entity"
) )
......
package api package api
import ( import (
dao "github.com/eolinker/goku/server/dao" "github.com/eolinker/goku/server/dao"
console_mysql "github.com/eolinker/goku/server/dao/console-mysql" console_mysql "github.com/eolinker/goku/server/dao/console-mysql"
) )
......
...@@ -4,7 +4,7 @@ import ( ...@@ -4,7 +4,7 @@ import (
"strconv" "strconv"
"strings" "strings"
dao "github.com/eolinker/goku/server/dao" "github.com/eolinker/goku/server/dao"
console_mysql "github.com/eolinker/goku/server/dao/console-mysql" console_mysql "github.com/eolinker/goku/server/dao/console-mysql"
) )
......
package api package api
import ( import (
dao "github.com/eolinker/goku/server/dao" "github.com/eolinker/goku/server/dao"
console_mysql "github.com/eolinker/goku/server/dao/console-mysql" console_mysql "github.com/eolinker/goku/server/dao/console-mysql"
) )
......
...@@ -14,28 +14,30 @@ import ( ...@@ -14,28 +14,30 @@ import (
func Add(info *Param) (string, error) { func Add(info *Param) (string, error) {
const TableName = "goku_balance" const TableName = "goku_balance"
serviceInfo,err:= service.Get(info.ServiceName) serviceInfo, err := service.Get(info.ServiceName)
if err!=nil{ if err != nil {
return fmt.Sprintf("serviceName:%s",err.Error()),err return fmt.Sprintf("serviceName:%s", err.Error()), err
} }
switch serviceInfo.Type { switch serviceInfo.Type {
case driver2.Static:{ case driver2.Static:
if info.Static == ""&& info.StaticCluster ==""{ {
return "param:static 和 staticCluster 不能同时为空",errors.New( "param:static 和 staticCluster 不能同时为空") if info.Static == "" && info.StaticCluster == "" {
return "param:static 和 staticCluster 不能同时为空", errors.New("param:static 和 staticCluster 不能同时为空")
} }
now := time.Now().Format("2006-01-02 15:04:05") now := time.Now().Format("2006-01-02 15:04:05")
result, err :=dao_balance.AddStatic(info.Name,info.ServiceName,info.Static,info.StaticCluster,info.Desc,now) result, err := dao_balance.AddStatic(info.Name, info.ServiceName, info.Static, info.StaticCluster, info.Desc, now)
if err == nil { if err == nil {
dao.UpdateTable(TableName) dao.UpdateTable(TableName)
} }
return result, err return result, err
} }
case driver2.Discovery:{ case driver2.Discovery:
if info.AppName == ""{ {
return "param:appName 不能为空",errors.New( "param:appName 不能为空") if info.AppName == "" {
return "param:appName 不能为空", errors.New("param:appName 不能为空")
} }
now := time.Now().Format("2006-01-02 15:04:05") now := time.Now().Format("2006-01-02 15:04:05")
result, err :=dao_balance.AddDiscovery(info.Name,info.ServiceName,info.AppName,info.Desc,now) result, err := dao_balance.AddDiscovery(info.Name, info.ServiceName, info.AppName, info.Desc, now)
if err == nil { if err == nil {
dao.UpdateTable(TableName) dao.UpdateTable(TableName)
} }
...@@ -47,31 +49,32 @@ func Add(info *Param) (string, error) { ...@@ -47,31 +49,32 @@ func Add(info *Param) (string, error) {
return "无效serviceName", errors.New("invalid serviceName") return "无效serviceName", errors.New("invalid serviceName")
} }
func Save(info *Param) (string, error) { func Save(info *Param) (string, error) {
const TableName = "goku_balance" const TableName = "goku_balance"
serviceInfo,err:= service.Get(info.ServiceName) serviceInfo, err := service.Get(info.ServiceName)
if err!=nil{ if err != nil {
return fmt.Sprintf("serviceName:%s",err.Error()),err return fmt.Sprintf("serviceName:%s", err.Error()), err
} }
switch serviceInfo.Type { switch serviceInfo.Type {
case driver2.Static:{ case driver2.Static:
if info.Static == ""&& info.StaticCluster ==""{ {
return "param:static 和 staticCluster 不能同时为空",errors.New( "param:static 和 staticCluster 不能同时为空") if info.Static == "" && info.StaticCluster == "" {
return "param:static 和 staticCluster 不能同时为空", errors.New("param:static 和 staticCluster 不能同时为空")
} }
now := time.Now().Format("2006-01-02 15:04:05") now := time.Now().Format("2006-01-02 15:04:05")
result, err :=dao_balance.SaveStatic(info.Name,info.ServiceName,info.Static,info.StaticCluster,info.Desc,now) result, err := dao_balance.SaveStatic(info.Name, info.ServiceName, info.Static, info.StaticCluster, info.Desc, now)
if err == nil { if err == nil {
dao.UpdateTable(TableName) dao.UpdateTable(TableName)
} }
return result, err return result, err
} }
case driver2.Discovery:{ case driver2.Discovery:
if info.AppName == ""{ {
return "param:appName 不能为空",errors.New( "param:appName 不能为空") if info.AppName == "" {
return "param:appName 不能为空", errors.New("param:appName 不能为空")
} }
now := time.Now().Format("2006-01-02 15:04:05") now := time.Now().Format("2006-01-02 15:04:05")
result, err :=dao_balance.SaveDiscover(info.Name,info.ServiceName,info.AppName,info.Desc,now) result, err := dao_balance.SaveDiscover(info.Name, info.ServiceName, info.AppName, info.Desc, now)
if err == nil { if err == nil {
dao.UpdateTable(TableName) dao.UpdateTable(TableName)
} }
...@@ -88,18 +91,18 @@ func Get(name string) (*Info, error) { ...@@ -88,18 +91,18 @@ func Get(name string) (*Info, error) {
return nil, e return nil, e
} }
return ReadInfo(b),nil return ReadInfo(b), nil
} }
func Search(keyworkd string)([]*Info, error){ func Search(keyworkd string) ([]*Info, error) {
var entities []*entity.Balance var entities []*entity.Balance
if keyworkd == ""{ if keyworkd == "" {
es, e:= dao_balance.GetAll() es, e := dao_balance.GetAll()
if e != nil { if e != nil {
return nil, e return nil, e
} }
entities = es entities = es
}else{ } else {
es, e:= dao_balance.Search(keyworkd) es, e := dao_balance.Search(keyworkd)
if e != nil { if e != nil {
return nil, e return nil, e
} }
......
...@@ -14,7 +14,6 @@ type Param struct { ...@@ -14,7 +14,6 @@ type Param struct {
Desc string `opt:"balanceDesc"` Desc string `opt:"balanceDesc"`
} }
type Info struct { type Info struct {
Name string `json:"balanceName"` Name string `json:"balanceName"`
ServiceName string `json:"serviceName"` ServiceName string `json:"serviceName"`
...@@ -29,7 +28,7 @@ type Info struct { ...@@ -29,7 +28,7 @@ type Info struct {
} }
func ReadInfo(balance *entity.Balance) *Info { func ReadInfo(balance *entity.Balance) *Info {
info:=&Info{ info := &Info{
Name: balance.Name, Name: balance.Name,
ServiceName: balance.ServiceName, ServiceName: balance.ServiceName,
ServiceType: balance.ServiceType, ServiceType: balance.ServiceType,
...@@ -41,6 +40,6 @@ func ReadInfo(balance *entity.Balance) *Info { ...@@ -41,6 +40,6 @@ func ReadInfo(balance *entity.Balance) *Info {
CreateTime: balance.CreateTime, CreateTime: balance.CreateTime,
UpdateTime: balance.UpdateTime, UpdateTime: balance.UpdateTime,
} }
json.Unmarshal([]byte(balance.StaticCluster),&info.StaticCluster) json.Unmarshal([]byte(balance.StaticCluster), &info.StaticCluster)
return info return info
} }
...@@ -10,31 +10,29 @@ import ( ...@@ -10,31 +10,29 @@ import (
func init() { func init() {
general.RegeditLater(Update) general.RegeditLater(Update)
} }
func Update()error { func Update() error {
l,e:= dao_balance_update.GetAllOldVerSion() l, e := dao_balance_update.GetAllOldVerSion()
if e!=nil{ if e != nil {
return e return e
} }
defStaticServiceName :=dao_balance_update.GetDefaultServiceStatic() defStaticServiceName := dao_balance_update.GetDefaultServiceStatic()
for _,e:=range l{ for _, e := range l {
update(e,defStaticServiceName) update(e, defStaticServiceName)
} }
return nil return nil
} }
func update(e *entity.BalanceInfoEntity,serviceName string) { func update(e *entity.BalanceInfoEntity, serviceName string) {
if e==nil{ if e == nil {
return return
} }
param:=&Param{ param := &Param{
Name: e.Name, Name: e.Name,
ServiceName: serviceName, ServiceName: serviceName,
AppName: "", AppName: "",
...@@ -43,27 +41,26 @@ func update(e *entity.BalanceInfoEntity,serviceName string) { ...@@ -43,27 +41,26 @@ func update(e *entity.BalanceInfoEntity,serviceName string) {
Desc: e.Desc, Desc: e.Desc,
} }
info,err:=e.Decode() info, err := e.Decode()
if err!=nil{ if err != nil {
return return
} }
if info.Default != nil {
if info.Default!= nil{
param.Static = info.Default.ServersConfigOrg param.Static = info.Default.ServersConfigOrg
} }
if info.Cluster !=nil{ if info.Cluster != nil {
cluster:=make(map[string]string) cluster := make(map[string]string)
for clusterName,server:=range info.Cluster{ for clusterName, server := range info.Cluster {
cluster[clusterName] = server.ServersConfigOrg cluster[clusterName] = server.ServersConfigOrg
} }
data ,err:= json.Marshal(cluster) data, err := json.Marshal(cluster)
if err==nil{ if err == nil {
param.StaticCluster = string(data) param.StaticCluster = string(data)
} }
...@@ -71,5 +68,4 @@ func update(e *entity.BalanceInfoEntity,serviceName string) { ...@@ -71,5 +68,4 @@ func update(e *entity.BalanceInfoEntity,serviceName string) {
Save(param) Save(param)
} }
...@@ -7,25 +7,25 @@ import ( ...@@ -7,25 +7,25 @@ import (
dao "github.com/eolinker/goku/server/dao/config-log" dao "github.com/eolinker/goku/server/dao/config-log"
) )
func Get(name string) (*LogConfig,error) { func Get(name string) (*LogConfig, error) {
if _,has:=logNames[name];!has{ if _, has := logNames[name]; !has {
return nil,fmt.Errorf("not has that log config of %s",name) return nil, fmt.Errorf("not has that log config of %s", name)
} }
c:=&LogConfig{} c := &LogConfig{}
c.Levels = Levels c.Levels = Levels
c.Periods = Periods c.Periods = Periods
c.Expires = Expires c.Expires = Expires
config, e := dao.Get(name) config, e := dao.Get(name)
if e!= nil || config == nil{ if e != nil || config == nil {
auto.SetDefaults(c) auto.SetDefaults(c)
c.Name = name c.Name = name
c.File = name c.File = name
c.Level = log.ErrorLevel.String() c.Level = log.ErrorLevel.String()
c.Period = log.PeriodHour.String() c.Period = log.PeriodHour.String()
c.Expire = ExpireDefault c.Expire = ExpireDefault
}else{ } else {
c.Read(config) c.Read(config)
} }
...@@ -34,17 +34,17 @@ func Get(name string) (*LogConfig,error) { ...@@ -34,17 +34,17 @@ func Get(name string) (*LogConfig,error) {
func GetAccess() (*AccessConfig, error) { func GetAccess() (*AccessConfig, error) {
config, e := dao.Get(AccessLog) config, e := dao.Get(AccessLog)
c:=new(AccessConfig) c := new(AccessConfig)
c.Periods = Periods c.Periods = Periods
c.Expires = Expires c.Expires = Expires
if e!= nil || config == nil{ if e != nil || config == nil {
auto.SetDefaults(c) auto.SetDefaults(c)
c.Name = AccessLog c.Name = AccessLog
c.Period = log.PeriodHour.String() c.Period = log.PeriodHour.String()
c.Expire = ExpireDefault c.Expire = ExpireDefault
c.InitFields() c.InitFields()
}else{ } else {
c.Read(config) c.Read(config)
} }
return c, nil return c, nil
......
...@@ -24,24 +24,24 @@ var ( ...@@ -24,24 +24,24 @@ var (
} }
Expires = []ValueTitle{ Expires = []ValueTitle{
{ {
Value:3, Value: 3,
Title:"3天", Title: "3天",
}, },
{ {
Value:7, Value: 7,
Title:"7天", Title: "7天",
}, },
{ {
Value:30, Value: 30,
Title:"30天", Title: "30天",
}, },
{ {
Value:90, Value: 90,
Title:"90天", Title: "90天",
}, },
{ {
Value:180, Value: 180,
Title:"180天", Title: "180天",
}, },
} }
Periods = []NameTitle{ Periods = []NameTitle{
...@@ -169,7 +169,7 @@ func (c *LogConfig) Read(ent *entity.LogConfig) { ...@@ -169,7 +169,7 @@ func (c *LogConfig) Read(ent *entity.LogConfig) {
c.Level = ent.Level c.Level = ent.Level
c.Period = ent.Period c.Period = ent.Period
c.Expire = ent.Expire c.Expire = ent.Expire
if c.Expire < ExpireDefault{ if c.Expire < ExpireDefault {
c.Expire = ExpireDefault c.Expire = ExpireDefault
} }
} }
......
...@@ -8,41 +8,40 @@ import ( ...@@ -8,41 +8,40 @@ import (
entity "github.com/eolinker/goku/server/entity/config-log" entity "github.com/eolinker/goku/server/entity/config-log"
) )
func Set(name string,param *Param)error { func Set(name string, param *Param) error {
if _,has:=logNames[name];!has{ if _, has := logNames[name]; !has {
return fmt.Errorf("not has that log config of %s",name) return fmt.Errorf("not has that log config of %s", name)
} }
c:=new(entity.LogConfig) c := new(entity.LogConfig)
c.Name = name c.Name = name
c.Level = param.Level c.Level = param.Level
c.Period = param.Period c.Period = param.Period
c.File = param.File c.File = param.File
c.Dir = param.Dir c.Dir = param.Dir
if param.Enable { if param.Enable {
c.Enable = 1 c.Enable = 1
}else{ } else {
c.Enable = 0 c.Enable = 0
} }
c.Fields = param.Fields c.Fields = param.Fields
c.Expire = param.Expire c.Expire = param.Expire
err :=dao.Set(c) err := dao.Set(c)
if err!=nil{ if err != nil {
return err return err
} }
_=dao2.UpdateTable("goku_config_log") _ = dao2.UpdateTable("goku_config_log")
if name == ConsoleLog{ if name == ConsoleLog {
go reset(c) go reset(c)
} }
return nil return nil
} }
func reset(c *entity.LogConfig) { func reset(c *entity.LogConfig) {
period,_:=log.ParsePeriod(c.Period) period, _ := log.ParsePeriod(c.Period)
log.SetOutPut(c.Enable == 1,c.Dir,c.File,period,c.Expire) log.SetOutPut(c.Enable == 1, c.Dir, c.File, period, c.Expire)
l,_:= log.ParseLevel(c.Level) l, _ := log.ParseLevel(c.Level)
log.SetLevel(l) log.SetLevel(l)
} }
...@@ -5,30 +5,31 @@ import ( ...@@ -5,30 +5,31 @@ import (
"time" "time"
) )
func genHour(beginTime, endTime string, period int)( int,int ){ func genHour(beginTime, endTime string, period int) (int, int) {
startHour := 0 startHour := 0
endHour,_ := strconv.Atoi(time.Now().Add(time.Hour).Format("2006010215")) endHour, _ := strconv.Atoi(time.Now().Add(time.Hour).Format("2006010215"))
switch period { switch period {
case 3:{ case 3:
{
bt,e:=time.Parse("2006-01-02", beginTime) bt, e := time.Parse("2006-01-02", beginTime)
if e==nil{ if e == nil {
startHour,_= strconv.Atoi(bt.Format("2006010215")) startHour, _ = strconv.Atoi(bt.Format("2006010215"))
} }
et,e:=time.Parse("2006-01-02", endTime) et, e := time.Parse("2006-01-02", endTime)
if e == nil{ if e == nil {
et.Add(time.Hour*24-time.Minute) et.Add(time.Hour*24 - time.Minute)
endHour,_= strconv.Atoi(et.Format("2006010215")) endHour, _ = strconv.Atoi(et.Format("2006010215"))
} }
} }
case 2: case 2:
startHour ,_= strconv.Atoi(time.Now().Add(- time.Hour*24*7).Format("2006010215")) startHour, _ = strconv.Atoi(time.Now().Add(- time.Hour * 24 * 7).Format("2006010215"))
case 1: case 1:
startHour ,_= strconv.Atoi(time.Now().Add(- time.Hour*24*3).Format("2006010215")) startHour, _ = strconv.Atoi(time.Now().Add(- time.Hour * 24 * 3).Format("2006010215"))
default: default:
startHour ,_= strconv.Atoi(time.Now().Format("2006010200")) startHour, _ = strconv.Atoi(time.Now().Format("2006010200"))
} }
return startHour,endHour return startHour, endHour
} }
...@@ -25,30 +25,28 @@ func DeleteNode(nodeID int) (bool, string, error) { ...@@ -25,30 +25,28 @@ func DeleteNode(nodeID int) (bool, string, error) {
func GetNodeInfo(nodeID int) (bool, *entity.Node, error) { func GetNodeInfo(nodeID int) (bool, *entity.Node, error) {
b, node, e := console_mysql.GetNodeInfo(nodeID) b, node, e := console_mysql.GetNodeInfo(nodeID)
ResetNodeStatus(node) ResetNodeStatus(node)
return b,node,e return b, node, e
} }
// 获取节点信息 // 获取节点信息
func GetNodeInfoByIpPort(ip string, port int) (bool, *entity.Node, error) { func GetNodeInfoByIpPort(ip string, port int) (bool, *entity.Node, error) {
b, node, e := console_mysql.GetNodeByIpPort(ip, port) b, node, e := console_mysql.GetNodeByIpPort(ip, port)
ResetNodeStatus(node) ResetNodeStatus(node)
return b,node,e return b, node, e
} }
// GetNodeList 获取节点列表 // GetNodeList 获取节点列表
func GetNodeList(clusterID, groupID int, keyword string) (bool, []*entity.Node, error) { func GetNodeList(clusterID, groupID int, keyword string) (bool, []*entity.Node, error) {
b, nodes, e := console_mysql.GetNodeList(clusterID, groupID, keyword) b, nodes, e := console_mysql.GetNodeList(clusterID, groupID, keyword)
ResetNodeStatus(nodes...) ResetNodeStatus(nodes...)
return b,nodes,e return b, nodes, e
} }
// 节点IP查重 // 节点IP查重
func CheckIsExistRemoteAddr(nodeID int, nodeIP, nodePort string) bool { func CheckIsExistRemoteAddr(nodeID int, nodeIP, nodePort string) bool {
return console_mysql.CheckIsExistRemoteAddr(nodeID, nodeIP, nodePort) return console_mysql.CheckIsExistRemoteAddr(nodeID, nodeIP, nodePort)
} }
// 批量删除节点 // 批量删除节点
func BatchDeleteNode(nodeIDList string) (bool, string, error) { func BatchDeleteNode(nodeIDList string) (bool, string, error) {
flag, nodeIDList, err := console_mysql.GetAvaliableNodeListFromNodeList(nodeIDList, 0) flag, nodeIDList, err := console_mysql.GetAvaliableNodeListFromNodeList(nodeIDList, 0)
...@@ -65,9 +63,7 @@ func BatchEditNodeGroup(nodeIDList string, groupID int) (bool, string, error) { ...@@ -65,9 +63,7 @@ func BatchEditNodeGroup(nodeIDList string, groupID int) (bool, string, error) {
return console_mysql.BatchEditNodeGroup(nodeIDList, groupID) return console_mysql.BatchEditNodeGroup(nodeIDList, groupID)
} }
// 获取节点IP列表 // 获取节点IP列表
func GetNodeIPList() (bool, []map[string]interface{}, error) { func GetNodeIPList() (bool, []map[string]interface{}, error) {
return console_mysql.GetNodeIPList() return console_mysql.GetNodeIPList()
} }
...@@ -8,69 +8,71 @@ import ( ...@@ -8,69 +8,71 @@ import (
) )
const EXPIRE = time.Second * 10 const EXPIRE = time.Second * 10
var(
var (
manager = _StatusManager{ manager = _StatusManager{
locker:sync.RWMutex{}, locker: sync.RWMutex{},
lastHeartBeat:make(map[string]time.Time), lastHeartBeat: make(map[string]time.Time),
} }
) )
type _StatusManager struct { type _StatusManager struct {
locker sync.RWMutex locker sync.RWMutex
lastHeartBeat map[string]time.Time lastHeartBeat map[string]time.Time
} }
func (m *_StatusManager)refresh(id string) { func (m *_StatusManager) refresh(id string) {
t:=time.Now() t := time.Now()
m.locker.Lock() m.locker.Lock()
m.lastHeartBeat[id]=t m.lastHeartBeat[id] = t
m.locker.Unlock() m.locker.Unlock()
} }
func (m *_StatusManager)stop(id string) { func (m *_StatusManager) stop(id string) {
m.locker.Lock() m.locker.Lock()
delete(m.lastHeartBeat,id) delete(m.lastHeartBeat, id)
m.locker.Unlock() m.locker.Unlock()
} }
func (m *_StatusManager)get(id string) (time.Time, bool) { func (m *_StatusManager) get(id string) (time.Time, bool) {
m.locker.RLock() m.locker.RLock()
t,b:=m.lastHeartBeat[id] t, b := m.lastHeartBeat[id]
m.locker.RUnlock() m.locker.RUnlock()
return t,b return t, b
} }
func Refresh(ip string,port string) { func Refresh(ip string, port string) {
id:=fmt.Sprintf("%s:%d",ip,port) id := fmt.Sprintf("%s:%d", ip, port)
manager.refresh(id) manager.refresh(id)
} }
func NodeStop(ip,port string) { func NodeStop(ip, port string) {
id:=fmt.Sprintf("%s:%d",ip,port) id := fmt.Sprintf("%s:%d", ip, port)
manager.stop(id) manager.stop(id)
} }
func IsLive(ip string,port string) bool { func IsLive(ip string, port string) bool {
id:=fmt.Sprintf("%s:%d",ip,port) id := fmt.Sprintf("%s:%d", ip, port)
t,has:=manager.get(id) t, has := manager.get(id)
if !has{ if !has {
return false return false
} }
if time.Now().Sub(t) > EXPIRE{ if time.Now().Sub(t) > EXPIRE {
return false return false
} }
return true return true
} }
func ResetNodeStatus(nodes... *entity.Node) { func ResetNodeStatus(nodes ...*entity.Node) {
for _, node:=range nodes{ for _, node := range nodes {
if IsLive(node.NodeIP,node.NodePort){ if IsLive(node.NodeIP, node.NodePort) {
node.NodeStatus = 1 node.NodeStatus = 1
}else{ } else {
node.NodeStatus = 0 node.NodeStatus = 0
} }
} }
......
...@@ -24,16 +24,16 @@ func CheckConfig(pluginName string, config []byte) (bool, error) { ...@@ -24,16 +24,16 @@ func CheckConfig(pluginName string, config []byte) (bool, error) {
case *json.SyntaxError: case *json.SyntaxError:
{ {
end := int64(bytes.IndexFunc(config[v.Offset:], isEnd)) end := int64(bytes.IndexFunc(config[v.Offset:], isEnd))
if end == -1{ if end == -1 {
end = int64(len(config)-1) end = int64(len(config) - 1)
}else{ } else {
end = end + v.Offset end = end + v.Offset
} }
start := 0 start := 0
if v.Offset > 0 { if v.Offset > 0 {
start = bytes.LastIndexFunc(config[:v.Offset], isEnd) start = bytes.LastIndexFunc(config[:v.Offset], isEnd)
} }
if start == -1{ if start == -1 {
start = 0 start = 0
} }
...@@ -41,7 +41,7 @@ func CheckConfig(pluginName string, config []byte) (bool, error) { ...@@ -41,7 +41,7 @@ func CheckConfig(pluginName string, config []byte) (bool, error) {
} }
case *json.UnmarshalTypeError: case *json.UnmarshalTypeError:
{ {
return false, fmt.Errorf("数据类型不正确:\"%s\":%s", v.Field,v.Value) return false, fmt.Errorf("数据类型不正确:\"%s\":%s", v.Field, v.Value)
} }
} }
......
package plugin_config package plugin_config
func init() { func init() {
allConfigOfPlugin=map[string]interface{}{ allConfigOfPlugin = map[string]interface{}{
"goku-apikey_auth":new(APIKeyConf), "goku-apikey_auth": new(APIKeyConf),
"goku-basic_auth":new(basicAuthConf), "goku-basic_auth": new(basicAuthConf),
"goku-circuit_breaker":new(CircuitBreakerConf), "goku-circuit_breaker": new(CircuitBreakerConf),
"goku-cors":new(gokuCorsConfig), "goku-cors": new(gokuCorsConfig),
"goku-data_format_transformer":new(dataFormatTranformerConf), "goku-data_format_transformer": new(dataFormatTranformerConf),
"goku-default_response":new(defaultResponseConf), "goku-default_response": new(defaultResponseConf),
"goku-extra_params":new(extraParamsConf), "goku-extra_params": new(extraParamsConf),
"goku-http_log":new(Log), "goku-http_log": new(Log),
"goku-ip_restriction":new(IPList), "goku-ip_restriction": new(IPList),
"goku-jwt_auth":new(JwtConf), "goku-jwt_auth": new(JwtConf),
"goku-oauth2_auth":new(Oauth2Conf), "goku-oauth2_auth": new(Oauth2Conf),
"goku-params_check":new(paramsCheckConf), "goku-params_check": new(paramsCheckConf),
"goku-params_transformer":new(paramsTransformerconf), "goku-params_transformer": new(paramsTransformerconf),
"goku-proxy_caching":new(ProxyCachingConf), "goku-proxy_caching": new(ProxyCachingConf),
"goku-rate_limiting":new(_RateLimitingConf), "goku-rate_limiting": new(_RateLimitingConf),
"goku-replay_attack_defender":new(ReplayAttackDefenderConf), "goku-replay_attack_defender": new(ReplayAttackDefenderConf),
"goku-request_size_limiting":new(requestSizeLimit), "goku-request_size_limiting": new(requestSizeLimit),
"goku-response_headers":new(responseHeader), "goku-response_headers": new(responseHeader),
"goku-service_downgrade":new(serviceDowngradeConf), "goku-service_downgrade": new(serviceDowngradeConf),
} }
} }
...@@ -170,7 +168,6 @@ type ProxyCachingConf struct { ...@@ -170,7 +168,6 @@ type ProxyCachingConf struct {
RedisDatabase int `json:"redisDatabase"` RedisDatabase int `json:"redisDatabase"`
} }
type _RateLimitingConf struct { type _RateLimitingConf struct {
Second int64 `json:"second,omitempty"` Second int64 `json:"second,omitempty"`
Minute int64 `json:"minute,omitempty"` Minute int64 `json:"minute,omitempty"`
......
...@@ -9,6 +9,7 @@ import ( ...@@ -9,6 +9,7 @@ import (
) )
const _TableName = "goku_service_config" const _TableName = "goku_service_config"
func Add(param *AddParam) error { func Add(param *AddParam) error {
err := dao_service.Add(param.Name, param.Driver, param.Desc, param.Config, param.ClusterConfig, false, param.HealthCheck, param.HealthCheckPath, param.HealthCheckCode, param.HealthCheckPeriod, param.HealthCheckTimeOut) err := dao_service.Add(param.Name, param.Driver, param.Desc, param.Config, param.ClusterConfig, false, param.HealthCheck, param.HealthCheckPath, param.HealthCheckCode, param.HealthCheckPeriod, param.HealthCheckTimeOut)
...@@ -30,7 +31,7 @@ func Save(param *AddParam) error { ...@@ -30,7 +31,7 @@ func Save(param *AddParam) error {
return fmt.Errorf("not allowed change dirver from %s to %s for service", v.Driver, param.Driver) return fmt.Errorf("not allowed change dirver from %s to %s for service", v.Driver, param.Driver)
} }
err:= dao_service.Save(param.Name, param.Desc, param.Config, param.ClusterConfig, param.HealthCheck, param.HealthCheckPath, param.HealthCheckCode, param.HealthCheckPeriod, param.HealthCheckTimeOut) err := dao_service.Save(param.Name, param.Desc, param.Config, param.ClusterConfig, param.HealthCheck, param.HealthCheckPath, param.HealthCheckCode, param.HealthCheckPeriod, param.HealthCheckTimeOut)
if err == nil { if err == nil {
dao.UpdateTable(_TableName) dao.UpdateTable(_TableName)
} }
...@@ -77,7 +78,7 @@ func tran(v *entity.Service) *Service { ...@@ -77,7 +78,7 @@ func tran(v *entity.Service) *Service {
IsDefault: v.IsDefault, IsDefault: v.IsDefault,
HealthCheck: v.HealthCheck, HealthCheck: v.HealthCheck,
UpdateTime: v.UpdateTime, UpdateTime: v.UpdateTime,
CreateTime:v.CreateTime, CreateTime: v.CreateTime,
} }
d, has := driver2.Get(v.Driver) d, has := driver2.Get(v.Driver)
......
...@@ -31,7 +31,7 @@ type Info struct { ...@@ -31,7 +31,7 @@ type Info struct {
} }
func (i *Info) Decode() { func (i *Info) Decode() {
json.Unmarshal([]byte(i.ClusterConfig),&i.ClusterConfigObj) json.Unmarshal([]byte(i.ClusterConfig), &i.ClusterConfigObj)
} }
type AddParam struct { type AddParam struct {
......
...@@ -45,9 +45,6 @@ func Router() { ...@@ -45,9 +45,6 @@ func Router() {
http.HandleFunc("/monitor/gateway/getSummaryInfo", monitor.GetGatewayMonitorSummaryByPeriod) http.HandleFunc("/monitor/gateway/getSummaryInfo", monitor.GetGatewayMonitorSummaryByPeriod)
// 项目 // 项目
http.HandleFunc("/project/add", project.AddProject) http.HandleFunc("/project/add", project.AddProject)
http.HandleFunc("/project/edit", project.EditProject) http.HandleFunc("/project/edit", project.EditProject)
...@@ -157,11 +154,9 @@ func Router() { ...@@ -157,11 +154,9 @@ func Router() {
http.HandleFunc("/node/getList", node.GetNodeList) http.HandleFunc("/node/getList", node.GetNodeList)
http.HandleFunc("/node/checkIsExistRemoteAddr", node.CheckIsExistRemoteAddr) http.HandleFunc("/node/checkIsExistRemoteAddr", node.CheckIsExistRemoteAddr)
http.HandleFunc("/node/batchEditGroup", node.BatchEditNodeGroup) http.HandleFunc("/node/batchEditGroup", node.BatchEditNodeGroup)
http.HandleFunc("/node/batchDelete", node.BatchDeleteNode) http.HandleFunc("/node/batchDelete", node.BatchDeleteNode)
// 节点分组 // 节点分组
http.HandleFunc("/node/group/add", node.AddNodeGroup) http.HandleFunc("/node/group/add", node.AddNodeGroup)
http.HandleFunc("/node/group/edit", node.EditNodeGroup) http.HandleFunc("/node/group/edit", node.EditNodeGroup)
......
...@@ -3,7 +3,7 @@ module github.com/eolinker/goku ...@@ -3,7 +3,7 @@ module github.com/eolinker/goku
go 1.12 go 1.12
require ( require (
github.com/360EntSecGroup-Skylar/excelize v1.4.1 github.com/360EntSecGroup-Skylar/excelize v1.4.1 // indirect
github.com/eolinker/goku-plugin v0.1.3 github.com/eolinker/goku-plugin v0.1.3
github.com/go-redis/redis v6.15.2+incompatible github.com/go-redis/redis v6.15.2+incompatible
github.com/go-sql-driver/mysql v1.4.1 github.com/go-sql-driver/mysql v1.4.1
...@@ -11,9 +11,8 @@ require ( ...@@ -11,9 +11,8 @@ require (
github.com/json-iterator/go v1.1.7 github.com/json-iterator/go v1.1.7
github.com/onsi/ginkgo v1.8.0 // indirect github.com/onsi/ginkgo v1.8.0 // indirect
github.com/onsi/gomega v1.5.0 // indirect github.com/onsi/gomega v1.5.0 // indirect
github.com/pkg/errors v0.8.1
github.com/sirupsen/logrus v1.4.0 github.com/sirupsen/logrus v1.4.0
github.com/yuchenfw/gocrypt v0.0.0-20190627061521-ee7b5965ec93 github.com/yuchenfw/gocrypt v0.0.0-20190627061521-ee7b5965ec93 // indirect
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4
google.golang.org/appengine v1.6.0 // indirect google.golang.org/appengine v1.6.0 // indirect
gopkg.in/yaml.v2 v2.2.2 gopkg.in/yaml.v2 v2.2.2
......
...@@ -12,7 +12,6 @@ func StartDebug() { ...@@ -12,7 +12,6 @@ func StartDebug() {
} }
type debugHook struct { type debugHook struct {
} }
func (h *debugHook) Levels() []logrus.Level { func (h *debugHook) Levels() []logrus.Level {
...@@ -29,7 +28,7 @@ func (h *debugHook) Levels() []logrus.Level { ...@@ -29,7 +28,7 @@ func (h *debugHook) Levels() []logrus.Level {
func (h *debugHook) Fire(entry *logrus.Entry) error { func (h *debugHook) Fire(entry *logrus.Entry) error {
s, e := logger.Formatter.Format(entry) s, e := logger.Formatter.Format(entry)
if e!=nil{ if e != nil {
fmt.Println(entry) fmt.Println(entry)
return nil return nil
} }
......
package goku_log package goku_log
...@@ -8,9 +8,11 @@ import ( ...@@ -8,9 +8,11 @@ import (
"strings" "strings"
"time" "time"
) )
const ( const (
defaultTimestampFormat = time.RFC3339 defaultTimestampFormat = time.RFC3339
) )
type LineFormatter struct { type LineFormatter struct {
TimestampFormat string TimestampFormat string
CallerPrettyfier func(*runtime.Frame) (function string, file string) CallerPrettyfier func(*runtime.Frame) (function string, file string)
...@@ -30,7 +32,6 @@ func (f *LineFormatter) Format(entry *logrus.Entry) ([]byte, error) { ...@@ -30,7 +32,6 @@ func (f *LineFormatter) Format(entry *logrus.Entry) ([]byte, error) {
b = &bytes.Buffer{} b = &bytes.Buffer{}
} }
timestampFormat := f.TimestampFormat timestampFormat := f.TimestampFormat
if timestampFormat == "" { if timestampFormat == "" {
timestampFormat = defaultTimestampFormat timestampFormat = defaultTimestampFormat
...@@ -39,9 +40,8 @@ func (f *LineFormatter) Format(entry *logrus.Entry) ([]byte, error) { ...@@ -39,9 +40,8 @@ func (f *LineFormatter) Format(entry *logrus.Entry) ([]byte, error) {
levelText := strings.ToUpper(entry.Level.String()) levelText := strings.ToUpper(entry.Level.String())
levelText = levelText[0:4] levelText = levelText[0:4]
b.WriteString(fmt.Sprint("[", entry.Time.Format(timestampFormat),"] ")) b.WriteString(fmt.Sprint("[", entry.Time.Format(timestampFormat), "] "))
b.WriteString(fmt.Sprint("[", levelText,"] ")) b.WriteString(fmt.Sprint("[", levelText, "] "))
if entry.HasCaller() { if entry.HasCaller() {
...@@ -61,10 +61,9 @@ func (f *LineFormatter) Format(entry *logrus.Entry) ([]byte, error) { ...@@ -61,10 +61,9 @@ func (f *LineFormatter) Format(entry *logrus.Entry) ([]byte, error) {
b.WriteString(strings.TrimSuffix(entry.Message, "\n")) b.WriteString(strings.TrimSuffix(entry.Message, "\n"))
for k, v := range data {
for k ,v:= range data { appendKeyValue(b, k, v)
appendKeyValue(b,k,v)
} }
b.WriteByte('\n') b.WriteByte('\n')
...@@ -77,7 +76,7 @@ func needsQuoting(text string) bool { ...@@ -77,7 +76,7 @@ func needsQuoting(text string) bool {
return true return true
} }
if text[0] =='"' { if text[0] == '"' {
return false return false
} }
for _, ch := range text { for _, ch := range text {
......
...@@ -7,18 +7,18 @@ import ( ...@@ -7,18 +7,18 @@ import (
type LogPeriod interface { type LogPeriod interface {
String() string String() string
FormatLayout()string FormatLayout() string
} }
type LogPeriodType int type LogPeriodType int
func ParsePeriod(v string)(LogPeriod,error) { func ParsePeriod(v string) (LogPeriod, error) {
switch strings.ToLower(v) { switch strings.ToLower(v) {
case "month": case "month":
return PeriodMonth,nil return PeriodMonth, nil
case "day": case "day":
return PeriodDay,nil return PeriodDay, nil
case "hour": case "hour":
return PeriodHour,nil return PeriodHour, nil
} }
return nil, fmt.Errorf("not a valid period: %q", v) return nil, fmt.Errorf("not a valid period: %q", v)
...@@ -42,7 +42,6 @@ const ( ...@@ -42,7 +42,6 @@ const (
PeriodHour PeriodHour
) )
func (period LogPeriodType) FormatLayout() string { func (period LogPeriodType) FormatLayout() string {
switch period { switch period {
case PeriodHour: case PeriodHour:
......
...@@ -11,14 +11,17 @@ import ( ...@@ -11,14 +11,17 @@ import (
"sync" "sync"
"time" "time"
) )
const MaxBufferd = 1024*500
var( const MaxBufferd = 1024 * 500
var (
bufferPool = &sync.Pool{ bufferPool = &sync.Pool{
New: func() interface{} { New: func() interface{} {
return new(bytes.Buffer) return new(bytes.Buffer)
}, },
} }
) )
type FileWriterByPeriod struct { type FileWriterByPeriod struct {
wC chan *bytes.Buffer wC chan *bytes.Buffer
dir string dir string
...@@ -32,23 +35,22 @@ type FileWriterByPeriod struct { ...@@ -32,23 +35,22 @@ type FileWriterByPeriod struct {
} }
func NewFileWriteBytePeriod() *FileWriterByPeriod { func NewFileWriteBytePeriod() *FileWriterByPeriod {
w:=&FileWriterByPeriod{ w := &FileWriterByPeriod{
locker:sync.Mutex{}, locker: sync.Mutex{},
wg:sync.WaitGroup{}, wg: sync.WaitGroup{},
enable:false, enable: false,
} }
return w return w
} }
func (w *FileWriterByPeriod)getExpire()time.Duration{ func (w *FileWriterByPeriod) getExpire() time.Duration {
w.locker.Lock() w.locker.Lock()
expire:= w.expire expire := w.expire
w.locker.Unlock() w.locker.Unlock()
return expire return expire
} }
func (w *FileWriterByPeriod)Set(dir,file string,period LogPeriod,expire time.Duration){ func (w *FileWriterByPeriod) Set(dir, file string, period LogPeriod, expire time.Duration) {
fileName:=strings.TrimSuffix(file,".log") fileName := strings.TrimSuffix(file, ".log")
w.locker.Lock() w.locker.Lock()
w.file = fileName w.file = fileName
...@@ -61,13 +63,13 @@ func (w *FileWriterByPeriod) Open() { ...@@ -61,13 +63,13 @@ func (w *FileWriterByPeriod) Open() {
w.locker.Lock() w.locker.Lock()
defer w.locker.Unlock() defer w.locker.Unlock()
if w.enable{ if w.enable {
return return
} }
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
w.cancelFunc = cancel w.cancelFunc = cancel
w.wC = make(chan *bytes.Buffer,100) w.wC = make(chan *bytes.Buffer, 100)
w.wg.Add(1) w.wg.Add(1)
w.enable = true w.enable = true
go w.do(ctx) go w.do(ctx)
...@@ -76,57 +78,56 @@ func (w *FileWriterByPeriod) Close() { ...@@ -76,57 +78,56 @@ func (w *FileWriterByPeriod) Close() {
isClose := false isClose := false
w.locker.Lock() w.locker.Lock()
if !w.enable{ if !w.enable {
w.locker.Unlock() w.locker.Unlock()
return return
} }
if w.cancelFunc != nil{ if w.cancelFunc != nil {
isClose = true isClose = true
w.cancelFunc() w.cancelFunc()
w.cancelFunc = nil w.cancelFunc = nil
} }
w.enable = false w.enable = false
w.locker.Unlock() w.locker.Unlock()
if isClose{ if isClose {
w.wg.Wait() w.wg.Wait()
} }
} }
func (w *FileWriterByPeriod) Write(p []byte) (n int, err error) { func (w *FileWriterByPeriod) Write(p []byte) (n int, err error) {
l := len(p)
l:=len(p)
if !w.enable { if !w.enable {
return l,nil return l, nil
} }
buffer := bufferPool.Get().(*bytes.Buffer) buffer := bufferPool.Get().(*bytes.Buffer)
buffer.Reset() buffer.Reset()
buffer.Write(p) buffer.Write(p)
w.wC<-buffer w.wC <- buffer
return l,nil return l, nil
} }
func (w *FileWriterByPeriod) do(ctx context.Context) { func (w *FileWriterByPeriod) do(ctx context.Context) {
w.initFile() w.initFile()
f,lastTag,e:=w.openFile() f, lastTag, e := w.openFile()
if e!=nil{ if e != nil {
fmt.Printf("open log file:%s\n",e.Error()) fmt.Printf("open log file:%s\n", e.Error())
return return
} }
buf:=bufio.NewWriter(f) buf := bufio.NewWriter(f)
t:=time.NewTicker(time.Second*5) t := time.NewTicker(time.Second * 5)
defer t.Stop() defer t.Stop()
tflusth:=time.NewTimer(time.Second) tflusth := time.NewTimer(time.Second)
for{ for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
{ {
for len(w.wC)>0{ for len(w.wC) > 0 {
p:=<-w.wC p := <-w.wC
buf.Write(p.Bytes()) buf.Write(p.Bytes())
bufferPool.Put(p) bufferPool.Put(p)
} }
...@@ -139,20 +140,20 @@ func (w *FileWriterByPeriod) do(ctx context.Context) { ...@@ -139,20 +140,20 @@ func (w *FileWriterByPeriod) do(ctx context.Context) {
case <-t.C: case <-t.C:
{ {
if buf.Buffered() >0{ if buf.Buffered() > 0 {
buf.Flush() buf.Flush()
tflusth.Reset(time.Second) tflusth.Reset(time.Second)
} }
if lastTag != w.timeTag(time.Now()){ if lastTag != w.timeTag(time.Now()) {
f.Close() f.Close()
w.history(lastTag) w.history(lastTag)
fnew,tag,err:=w.openFile() fnew, tag, err := w.openFile()
if err!=nil{ if err != nil {
return return
} }
lastTag = tag lastTag = tag
f=fnew f = fnew
buf.Reset(f) buf.Reset(f)
go w.dropHistory() go w.dropHistory()
...@@ -161,15 +162,16 @@ func (w *FileWriterByPeriod) do(ctx context.Context) { ...@@ -161,15 +162,16 @@ func (w *FileWriterByPeriod) do(ctx context.Context) {
} }
case <-tflusth.C: case <-tflusth.C:
{ {
if buf.Buffered()> 0{ if buf.Buffered() > 0 {
buf.Flush() buf.Flush()
} }
tflusth.Reset(time.Second) tflusth.Reset(time.Second)
} }
case p:=<-w.wC:{ case p := <-w.wC:
{
buf.Write(p.Bytes()) buf.Write(p.Bytes())
bufferPool.Put(p) bufferPool.Put(p)
if buf.Buffered()>MaxBufferd{ if buf.Buffered() > MaxBufferd {
buf.Flush() buf.Flush()
} }
tflusth.Reset(time.Second) tflusth.Reset(time.Second)
...@@ -180,41 +182,41 @@ func (w *FileWriterByPeriod) do(ctx context.Context) { ...@@ -180,41 +182,41 @@ func (w *FileWriterByPeriod) do(ctx context.Context) {
func (w *FileWriterByPeriod) timeTag(t time.Time) string { func (w *FileWriterByPeriod) timeTag(t time.Time) string {
w.locker.Lock() w.locker.Lock()
tag:= t.Format(w.period.FormatLayout()) tag := t.Format(w.period.FormatLayout())
w.locker.Unlock() w.locker.Unlock()
return tag return tag
} }
func (w *FileWriterByPeriod) history(tag string) { func (w *FileWriterByPeriod) history(tag string) {
path := filepath.Join(w.dir,fmt.Sprintf("%s.log",w.file)) path := filepath.Join(w.dir, fmt.Sprintf("%s.log", w.file))
histroy:= filepath.Join(w.dir,fmt.Sprintf("%s-%s.log",w.file,tag)) histroy := filepath.Join(w.dir, fmt.Sprintf("%s-%s.log", w.file, tag))
_=os.Rename(path,histroy) _ = os.Rename(path, histroy)
} }
func (w *FileWriterByPeriod) dropHistory(){ func (w *FileWriterByPeriod) dropHistory() {
expire:=w.getExpire() expire := w.getExpire()
expireTime := time.Now().Add(- expire) expireTime := time.Now().Add(- expire)
pathPatten := filepath.Join(w.dir,fmt.Sprintf("%s-*",w.file)) pathPatten := filepath.Join(w.dir, fmt.Sprintf("%s-*", w.file))
files, err := filepath.Glob(pathPatten) files, err := filepath.Glob(pathPatten)
if err==nil{ if err == nil {
for _,f:=range files{ for _, f := range files {
if info, e := os.Stat(f);e==nil{ if info, e := os.Stat(f); e == nil {
if expireTime.After(info.ModTime()){ if expireTime.After(info.ModTime()) {
_=os.Remove(f) _ = os.Remove(f)
} }
} }
} }
} }
} }
func (w *FileWriterByPeriod) initFile() { func (w *FileWriterByPeriod) initFile() {
_=os.MkdirAll(w.dir,os.ModePerm) _ = os.MkdirAll(w.dir, os.ModePerm)
path := filepath.Join(w.dir,fmt.Sprintf("%s.log",w.file)) path := filepath.Join(w.dir, fmt.Sprintf("%s.log", w.file))
nowTag:= w.timeTag(time.Now()) nowTag := w.timeTag(time.Now())
if info, e := os.Stat(path);e==nil{ if info, e := os.Stat(path); e == nil {
timeTag:=w.timeTag(info.ModTime()) timeTag := w.timeTag(info.ModTime())
if timeTag !=nowTag{ if timeTag != nowTag {
w.history(timeTag) w.history(timeTag)
} }
} }
...@@ -223,14 +225,14 @@ func (w *FileWriterByPeriod) initFile() { ...@@ -223,14 +225,14 @@ func (w *FileWriterByPeriod) initFile() {
} }
func (w *FileWriterByPeriod)openFile()(*os.File,string,error) { func (w *FileWriterByPeriod) openFile() (*os.File, string, error) {
path := filepath.Join(w.dir,fmt.Sprintf("%s.log",w.file)) path := filepath.Join(w.dir, fmt.Sprintf("%s.log", w.file))
nowTag:= w.timeTag(time.Now()) nowTag := w.timeTag(time.Now())
f,err:=os.OpenFile(path,os.O_WRONLY|os.O_CREATE|os.O_APPEND,0666) f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
if err!= nil{ if err != nil {
return nil,"",err return nil, "", err
} }
return f,nowTag,err return f, nowTag, err
} }
...@@ -8,7 +8,6 @@ import ( ...@@ -8,7 +8,6 @@ import (
) )
type MinPeriod struct { type MinPeriod struct {
} }
func (p *MinPeriod) String() string { func (p *MinPeriod) String() string {
...@@ -20,13 +19,13 @@ func (p *MinPeriod) FormatLayout() string { ...@@ -20,13 +19,13 @@ func (p *MinPeriod) FormatLayout() string {
} }
func TestFileWriterByPeriod(t *testing.T) { func TestFileWriterByPeriod(t *testing.T) {
w:=NewFileWriteBytePeriod("/Users/huangmengzhu/test/log","app.log",new(MinPeriod)) w := NewFileWriteBytePeriod("/Users/huangmengzhu/test/log", "app.log", new(MinPeriod))
defer w.Close() defer w.Close()
ctx,_:=context.WithTimeout(context.Background(),time.Minute*3) ctx, _ := context.WithTimeout(context.Background(), time.Minute*3)
tick:=time.NewTicker(time.Millisecond) tick := time.NewTicker(time.Millisecond)
defer tick.Stop() defer tick.Stop()
index:= 0 index := 0
for { for {
select { select {
...@@ -39,7 +38,7 @@ func TestFileWriterByPeriod(t *testing.T) { ...@@ -39,7 +38,7 @@ func TestFileWriterByPeriod(t *testing.T) {
case <-tick.C: case <-tick.C:
{ {
index++ index++
fmt.Fprintf(w,"line:%d\n",index) fmt.Fprintf(w, "line:%d\n", index)
} }
} }
} }
......
...@@ -3,6 +3,6 @@ package access_log ...@@ -3,6 +3,6 @@ package access_log
import "time" import "time"
const ( const (
DefaultTimeStampFormatter ="[2006-01-02 15:04:05]" DefaultTimeStampFormatter = "[2006-01-02 15:04:05]"
TimeIso8601Formatter = "["+time.RFC3339+"]" TimeIso8601Formatter = "[" + time.RFC3339 + "]"
) )
...@@ -14,6 +14,7 @@ type AccessLogFormatter struct { ...@@ -14,6 +14,7 @@ type AccessLogFormatter struct {
locker sync.RWMutex locker sync.RWMutex
TimestampFormat string TimestampFormat string
} }
func (f *AccessLogFormatter) SetFields(fields []access_field.AccessFieldKey) { func (f *AccessLogFormatter) SetFields(fields []access_field.AccessFieldKey) {
f.locker.Lock() f.locker.Lock()
f.fields = fields f.fields = fields
...@@ -32,27 +33,27 @@ func (f *AccessLogFormatter) Format(entry *logrus.Entry) ([]byte, error) { ...@@ -32,27 +33,27 @@ func (f *AccessLogFormatter) Format(entry *logrus.Entry) ([]byte, error) {
timestampFormat = DefaultTimeStampFormatter timestampFormat = DefaultTimeStampFormatter
} }
data:= entry.Data data := entry.Data
data[access_field.TimeLocal] = entry.Time.Format(timestampFormat) data[access_field.TimeLocal] = entry.Time.Format(timestampFormat)
data[access_field.TimeIso8601] = entry.Time.Format(TimeIso8601Formatter) data[access_field.TimeIso8601] = entry.Time.Format(TimeIso8601Formatter)
msec := entry.Time.UnixNano()/int64(time.Millisecond) msec := entry.Time.UnixNano() / int64(time.Millisecond)
data[access_field.Msec] = fmt.Sprintf("%d.%d",msec/1000,msec%1000) data[access_field.Msec] = fmt.Sprintf("%d.%d", msec/1000, msec%1000)
requestTIme:= data[access_field.RequestTime].(time.Duration) requestTIme := data[access_field.RequestTime].(time.Duration)
data[access_field.RequestTime] = fmt.Sprintf("%dms",requestTIme/time.Millisecond) data[access_field.RequestTime] = fmt.Sprintf("%dms", requestTIme/time.Millisecond)
for _,key:=range f.fields{ for _, key := range f.fields {
b.WriteByte('\t') b.WriteByte('\t')
if v,has := data[key.Key()];has{ if v, has := data[key.Key()]; has {
f.appendValue(b,v) f.appendValue(b, v)
}else{ } else {
f.appendValue(b,"-") f.appendValue(b, "-")
} }
} }
b.WriteByte('\n') b.WriteByte('\n')
p:=b.Bytes() p := b.Bytes()
return p[1:],nil return p[1:], nil
} }
// //
...@@ -80,6 +81,6 @@ func (f *AccessLogFormatter) appendValue(b *bytes.Buffer, value interface{}) { ...@@ -80,6 +81,6 @@ func (f *AccessLogFormatter) appendValue(b *bytes.Buffer, value interface{}) {
// b.WriteString(fmt.Sprintf("%q", stringVal)) // b.WriteString(fmt.Sprintf("%q", stringVal))
//} //}
} }
func NewAccessLogFormatter(fields []access_field.AccessFieldKey)*AccessLogFormatter { func NewAccessLogFormatter(fields []access_field.AccessFieldKey) *AccessLogFormatter {
return &AccessLogFormatter{fields:fields} return &AccessLogFormatter{fields: fields}
} }
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"time" "time"
) )
var ( var (
logger *logrus.Logger logger *logrus.Logger
formatter *AccessLogFormatter formatter *AccessLogFormatter
...@@ -19,38 +20,39 @@ var ( ...@@ -19,38 +20,39 @@ var (
// //
//} //}
type Fields = logrus.Fields type Fields = logrus.Fields
func Log(fields Fields) { func Log(fields Fields) {
if logger ==nil{ if logger == nil {
return return
} }
logger.WithFields(fields).Info() logger.WithFields(fields).Info()
} }
func SetFields(fields []access_field.AccessFieldKey){ func SetFields(fields []access_field.AccessFieldKey) {
if formatter == nil{ if formatter == nil {
formatter = NewAccessLogFormatter(fields) formatter = NewAccessLogFormatter(fields)
}else{ } else {
formatter.SetFields(fields) formatter.SetFields(fields)
} }
} }
func SetOutput(enable bool,dir, file string, period log.LogPeriod,expire int) { func SetOutput(enable bool, dir, file string, period log.LogPeriod, expire int) {
if enable{ if enable {
if writer == nil{ if writer == nil {
writer = log.NewFileWriteBytePeriod() writer = log.NewFileWriteBytePeriod()
} }
writer.Set(dir,file,period,time.Duration(expire)*time.Hour*24) writer.Set(dir, file, period, time.Duration(expire)*time.Hour*24)
writer.Open() writer.Open()
if logger == nil{ if logger == nil {
logger = logrus.New() logger = logrus.New()
logger.SetFormatter(formatter) logger.SetFormatter(formatter)
logger.SetOutput(writer) logger.SetOutput(writer)
logger.SetLevel(logrus.InfoLevel) logger.SetLevel(logrus.InfoLevel)
} }
}else{ } else {
if writer!=nil{ if writer != nil {
writer.Close() writer.Close()
} }
......
...@@ -8,41 +8,40 @@ import ( ...@@ -8,41 +8,40 @@ import (
func Test(t *testing.T) { func Test(t *testing.T) {
dir:="/Users/huangmengzhu/test/log" dir := "/Users/huangmengzhu/test/log"
file:="access.log" file := "access.log"
period:=log.PeriodDay period := log.PeriodDay
SetFields(access_field.All()) SetFields(access_field.All())
log.SetOutPut(true,dir,file,period) log.SetOutPut(true, dir, file, period)
demoCtx:=Fields{ demoCtx := Fields{
"$remote_addr":"192.168.0.1", "$remote_addr": "192.168.0.1",
"$http_x_forwarded_for":"192.168.0.99", "$http_x_forwarded_for": "192.168.0.99",
//"$remote_user":"", //"$remote_user":"",
"$request":"\"GET /kingsword\"", "$request": "\"GET /kingsword\"",
"$status":200, "$status": 200,
"$body_bytes_sent":300, "$body_bytes_sent": 300,
"$bytes_sent":500, "$bytes_sent": 500,
//"$msec":"日志写入时间。单位为秒,精度是毫秒。", //"$msec":"日志写入时间。单位为秒,精度是毫秒。",
//"$http_referer":"", //"$http_referer":"",
"$http_user_agent":"\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36\"", "$http_user_agent": "\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36\"",
"$request_length":100, "$request_length": 100,
"$request_time":100, "$request_time": 100,
//"$time_iso8601":"ISO8601标准格式下的本地时间。", //"$time_iso8601":"ISO8601标准格式下的本地时间。",
//"$time_local":"通用日志格式下的本地时间。", //"$time_local":"通用日志格式下的本地时间。",
"$requestId":"xxffsdffadf", "$requestId": "xxffsdffadf",
"$finally_server":"127.0.0.1:8080", "$finally_server": "127.0.0.1:8080",
"$balance":"Static_Load", "$balance": "Static_Load",
"$strategy":"FKdCm2", "$strategy": "FKdCm2",
"$api":"\"1657 kingsword\"", "$api": "\"1657 kingsword\"",
"$retry":"10.1.0.1:80,10.1.0.2:800", "$retry": "10.1.0.1:80,10.1.0.2:800",
"$proxy":"\"POST /proxy HTTPS\"", "$proxy": "\"POST /proxy HTTPS\"",
"$proxy_status":200, "$proxy_status": 200,
} }
Log(demoCtx) Log(demoCtx)
writer.Close() writer.Close()
t.Log("xx") t.Log("xx")
} }
...@@ -11,6 +11,7 @@ import ( ...@@ -11,6 +11,7 @@ import (
node_common "github.com/eolinker/goku/goku-node/node-common" node_common "github.com/eolinker/goku/goku-node/node-common"
) )
// 新增报警信息 // 新增报警信息
func AddAlertMessage(apiID int, apiName, requestURL, targetServer, targetURL, requestMethod, proxyMethod, headerList, queryParamList, formParamList, responseHeaderList string, alertPeriodType, alertCount, responseStatus int, isAlert string, strategyID string, strategyName, requestID string) (bool, string, error) { func AddAlertMessage(apiID int, apiName, requestURL, targetServer, targetURL, requestMethod, proxyMethod, headerList, queryParamList, formParamList, responseHeaderList string, alertPeriodType, alertCount, responseStatus int, isAlert string, strategyID string, strategyName, requestID string) (bool, string, error) {
client := &http.Client{ client := &http.Client{
......
...@@ -40,7 +40,7 @@ func (ctx *Context) SetRetryTargetServers(retryTargetServers string) { ...@@ -40,7 +40,7 @@ func (ctx *Context) SetRetryTargetServers(retryTargetServers string) {
ctx.retryTargetServers = retryTargetServers ctx.retryTargetServers = retryTargetServers
} }
func (ctx *Context) Finish() (n int,statusCode int){ func (ctx *Context) Finish() (n int, statusCode int) {
header := ctx.PriorityHeader.header header := ctx.PriorityHeader.header
...@@ -91,10 +91,10 @@ func (ctx *Context) Finish() (n int,statusCode int){ ...@@ -91,10 +91,10 @@ func (ctx *Context) Finish() (n int,statusCode int){
ctx.w.WriteHeader(statusCode) ctx.w.WriteHeader(statusCode)
if !bodyAllowed { if !bodyAllowed {
return 0,statusCode return 0, statusCode
} }
n, _ = ctx.w.Write(ctx.Body) n, _ = ctx.w.Write(ctx.Body)
return n,statusCode return n, statusCode
} }
func (ctx *Context) RequestId() string { func (ctx *Context) RequestId() string {
return ctx.requestId return ctx.requestId
......
package common package common
import ( import (
goku_plugin "github.com/eolinker/goku-plugin" goku_plugin "github.com/eolinker/goku-plugin"
"net/http" "net/http"
"net/url" "net/url"
) )
type Header struct { type Header struct {
...@@ -20,7 +18,7 @@ func (h *Header) Headers() http.Header { ...@@ -20,7 +18,7 @@ func (h *Header) Headers() http.Header {
} }
return n return n
} }
func (h *Header) String()string { func (h *Header) String() string {
return url.Values(h.header).Encode() return url.Values(h.header).Encode()
//buf:=bytes.NewBuffer(nil) //buf:=bytes.NewBuffer(nil)
......
package goku_node package goku_node
import ( import (
_ "github.com/eolinker/goku/goku-node/manager/service-manager" _ "github.com/eolinker/goku/goku-node/manager/service-manager"
_ "github.com/eolinker/goku/goku-service/driver/consul" _ "github.com/eolinker/goku/goku-service/driver/consul"
_ "github.com/eolinker/goku/goku-service/driver/eureka" _ "github.com/eolinker/goku/goku-service/driver/eureka"
......
...@@ -8,21 +8,21 @@ type Entry struct { ...@@ -8,21 +8,21 @@ type Entry struct {
Pattern string Pattern string
HandlerFunc func(w http.ResponseWriter, r *http.Request) HandlerFunc func(w http.ResponseWriter, r *http.Request)
} }
func init() { func init() {
} }
func Handler() []Entry { func Handler() []Entry {
return []Entry{ return []Entry{
{ {
Pattern:"/goku-update", HandlerFunc:gokuUpdate, Pattern: "/goku-update", HandlerFunc: gokuUpdate,
}, },
{ {
Pattern:"/goku-check_update",HandlerFunc: gokuCheckUpdate}, Pattern: "/goku-check_update", HandlerFunc: gokuCheckUpdate},
{ {
Pattern:"/goku-check_plugin" , HandlerFunc:gokuCheckPlugin}, Pattern: "/goku-check_plugin", HandlerFunc: gokuCheckPlugin},
{ {
Pattern:"/goku-monitor",HandlerFunc:gokuMonitor}, Pattern: "/goku-monitor", HandlerFunc: gokuMonitor},
} }
} }
...@@ -8,7 +8,7 @@ import ( ...@@ -8,7 +8,7 @@ import (
"net/http" "net/http"
) )
func gokuCheckPlugin( w http.ResponseWriter,req *http.Request) { func gokuCheckPlugin(w http.ResponseWriter, req *http.Request) {
req.ParseForm() req.ParseForm()
pluginName := req.PostFormValue("pluginName") pluginName := req.PostFormValue("pluginName")
......
...@@ -2,7 +2,6 @@ package handler ...@@ -2,7 +2,6 @@ package handler
import ( import (
"encoding/json" "encoding/json"
. "github.com/eolinker/goku/common/version"
"github.com/eolinker/goku/goku-node/manager/updater" "github.com/eolinker/goku/goku-node/manager/updater"
"net/http" "net/http"
) )
......
...@@ -47,7 +47,7 @@ func genBalance(e *entity.Balance) *balance.Balance { ...@@ -47,7 +47,7 @@ func genBalance(e *entity.Balance) *balance.Balance {
b.AppConfig = e.Static b.AppConfig = e.Static
if err := json.Unmarshal([]byte(e.StaticCluster), &m); err == nil { if err := json.Unmarshal([]byte(e.StaticCluster), &m); err == nil {
if v, has := m[node_common.ClusterName()]; has { if v, has := m[node_common.ClusterName()]; has {
if len(strings.Trim(v, " "))>0{ if len(strings.Trim(v, " ")) > 0 {
b.AppConfig = v b.AppConfig = v
} }
} }
......
package config_manager package config_manager
type AccessField struct { type AccessField struct {
Name string `json:"name"` Name string `json:"name"`
Select bool `json:"select"` Select bool `json:"select"`
......
...@@ -16,9 +16,9 @@ const ( ...@@ -16,9 +16,9 @@ const (
) )
func init() { func init() {
updater.Add(reloadLogConfig,1, "goku_config_log") updater.Add(reloadLogConfig, 1, "goku_config_log")
} }
func defaultAccessLogConfig()*entity.LogConfig { func defaultAccessLogConfig() *entity.LogConfig {
return &entity.LogConfig{ return &entity.LogConfig{
Name: AccessLog, Name: AccessLog,
Enable: 1, Enable: 1,
...@@ -29,7 +29,7 @@ func defaultAccessLogConfig()*entity.LogConfig { ...@@ -29,7 +29,7 @@ func defaultAccessLogConfig()*entity.LogConfig {
Fields: "", Fields: "",
} }
} }
func defaultNodeAppLogConfig()*entity.LogConfig { func defaultNodeAppLogConfig() *entity.LogConfig {
return &entity.LogConfig{ return &entity.LogConfig{
Name: AccessLog, Name: AccessLog,
Enable: 1, Enable: 1,
...@@ -37,7 +37,6 @@ func defaultNodeAppLogConfig()*entity.LogConfig { ...@@ -37,7 +37,6 @@ func defaultNodeAppLogConfig()*entity.LogConfig {
File: "node.log", File: "node.log",
Level: "error", Level: "error",
Period: "hour", Period: "hour",
} }
} }
func InitLog() { func InitLog() {
...@@ -49,62 +48,61 @@ func reloadLogConfig() { ...@@ -49,62 +48,61 @@ func reloadLogConfig() {
} }
func reloadAppLog() { func reloadAppLog() {
c,e:= dao.Get(NodeLog) c, e := dao.Get(NodeLog)
if e!=nil{ if e != nil {
log.Warn("manager/config load goku_config_log fro node error:",e) log.Warn("manager/config load goku_config_log fro node error:", e)
c = defaultNodeAppLogConfig() c = defaultNodeAppLogConfig()
} }
period,err:=log.ParsePeriod(c.Period) period, err := log.ParsePeriod(c.Period)
if err!=nil{ if err != nil {
period = log.PeriodDay period = log.PeriodDay
log.Warn("manager/config unmarshal access log period failed for nod , use the default config:%s",e) log.Warn("manager/config unmarshal access log period failed for nod , use the default config:%s", e)
} }
level,err:= log.ParseLevel(c.Level) level, err := log.ParseLevel(c.Level)
if err!=nil{ if err != nil {
level = log.WarnLevel level = log.WarnLevel
log.Warn("manager/config unmarshal access log level failed for nod , use the default config:%s",e) log.Warn("manager/config unmarshal access log level failed for nod , use the default config:%s", e)
} }
enable:= c.Enable == 1 enable := c.Enable == 1
log.SetOutPut(enable,c.Dir,c.File,period,c.Expire) log.SetOutPut(enable, c.Dir, c.File, period, c.Expire)
log.SetLevel(level) log.SetLevel(level)
} }
func reloadAccessLog() { func reloadAccessLog() {
c, e := dao.Get(AccessLog) c, e := dao.Get(AccessLog)
if e!=nil{ if e != nil {
log.Warn("manager/config load goku_config_log for access log error:",e) log.Warn("manager/config load goku_config_log for access log error:", e)
c= defaultAccessLogConfig() c = defaultAccessLogConfig()
} }
period,err:=log.ParsePeriod(c.Period) period, err := log.ParsePeriod(c.Period)
if err!=nil{ if err != nil {
period = log.PeriodDay period = log.PeriodDay
log.Warn("manager/config unmarshal period failed for , use the default config:%s",e) log.Warn("manager/config unmarshal period failed for , use the default config:%s", e)
} }
enable:= c.Enable == 1 enable := c.Enable == 1
fieldsConfig:= make([]AccessField ,0,access_field.Size()) fieldsConfig := make([]AccessField, 0, access_field.Size())
err =json.Unmarshal([]byte(c.Fields),&fieldsConfig) err = json.Unmarshal([]byte(c.Fields), &fieldsConfig)
if err!= nil || len(fieldsConfig) == 0{ if err != nil || len(fieldsConfig) == 0 {
log.Warn("manager/config unmarshal access log fields error:",err) log.Warn("manager/config unmarshal access log fields error:", err)
access_log.SetFields(access_field.Default()) access_log.SetFields(access_field.Default())
}else{ } else {
fields:=make([]access_field.AccessFieldKey,0,access_field.Size()) fields := make([]access_field.AccessFieldKey, 0, access_field.Size())
for _,f:=range fieldsConfig{ for _, f := range fieldsConfig {
if f.Select{ if f.Select {
if access_field.Has(f.Name){ if access_field.Has(f.Name) {
fields = append(fields,access_field.Parse(f.Name)) fields = append(fields, access_field.Parse(f.Name))
} }
} }
} }
access_log.SetFields(fields) access_log.SetFields(fields)
} }
access_log.SetOutput( enable,c.Dir,c.File,period,c.Expire) access_log.SetOutput(enable, c.Dir, c.File, period, c.Expire)
} }
...@@ -68,7 +68,7 @@ func LoadPlugin(pis map[string]*entity.PluginInfo) (allFactory map[string]*entit ...@@ -68,7 +68,7 @@ func LoadPlugin(pis map[string]*entity.PluginInfo) (allFactory map[string]*entit
for key, value := range pis { for key, value := range pis {
handle, err, _ := globalPluginManager.loadPlugin(key) handle, err, _ := globalPluginManager.loadPlugin(key)
if err != nil { if err != nil {
goku_plugin.Warn("LoadPlugin:",err.Error()) goku_plugin.Warn("LoadPlugin:", err.Error())
continue continue
} }
factory := &entity.PluginFactoryHandler{ factory := &entity.PluginFactoryHandler{
...@@ -144,14 +144,14 @@ func (m *_GlodPluginManager) loadPlugin(name string) (goku_plugin.PluginFactory, ...@@ -144,14 +144,14 @@ func (m *_GlodPluginManager) loadPlugin(name string) (goku_plugin.PluginFactory,
vp, ok := v.(func() goku_plugin.PluginFactory) vp, ok := v.(func() goku_plugin.PluginFactory)
if !ok { if !ok {
e := fmt.Errorf("The builder func can not implemented interface named goku_plugin.PluginFactory:%s ",name) e := fmt.Errorf("The builder func can not implemented interface named goku_plugin.PluginFactory:%s ", name)
m.errors[name] = e m.errors[name] = e
m.errorCodes[name] = LoadInterFaceError m.errorCodes[name] = LoadInterFaceError
return nil, e, LoadInterFaceError return nil, e, LoadInterFaceError
} }
factory := vp() factory := vp()
if factory == nil || reflect.ValueOf(factory).IsNil() { if factory == nil || reflect.ValueOf(factory).IsNil() {
e := fmt.Errorf("The builder result is nil:%s ",name) e := fmt.Errorf("The builder result is nil:%s ", name)
m.errors[name] = e m.errors[name] = e
m.errorCodes[name] = LoadInterFaceError m.errorCodes[name] = LoadInterFaceError
return nil, e, LoadInterFaceError return nil, e, LoadInterFaceError
......
...@@ -51,7 +51,7 @@ func toDiscoverConfig(e *entity.Service) *discovery.Config { ...@@ -51,7 +51,7 @@ func toDiscoverConfig(e *entity.Service) *discovery.Config {
clusterName := node_common.ClusterName() clusterName := node_common.ClusterName()
if v, has := clusterConfigObj[clusterName]; has { if v, has := clusterConfigObj[clusterName]; has {
if len(strings.Trim(v, " "))>0{ if len(strings.Trim(v, " ")) > 0 {
c.Config = v c.Config = v
} }
} }
......
...@@ -36,7 +36,7 @@ func CheckApiFromStrategy(strategyId, requestPath string, requestMethod string) ...@@ -36,7 +36,7 @@ func CheckApiFromStrategy(strategyId, requestPath string, requestMethod string)
apiextend.Target = apiInfo.BalanceName apiextend.Target = apiInfo.BalanceName
} }
apiextend.Target = utils.TrimSuffixAll(apiextend.Target,"/") apiextend.Target = utils.TrimSuffixAll(apiextend.Target, "/")
//apiextend.TargetServer = balance_manager.ParseTargetServer(apiextend.Target) //apiextend.TargetServer = balance_manager.ParseTargetServer(apiextend.Target)
return apiextend, splitURL, param, true return apiextend, splitURL, param, true
......
...@@ -19,11 +19,11 @@ func ClusterName() string { ...@@ -19,11 +19,11 @@ func ClusterName() string {
} }
func SetAdmin(host string) { func SetAdmin(host string) {
h:= strings.TrimPrefix(host,"http://") h := strings.TrimPrefix(host, "http://")
h = strings.TrimSuffix(h,"/") h = strings.TrimSuffix(h, "/")
adminUrl = fmt.Sprintf("http://%s", h) adminUrl = fmt.Sprintf("http://%s", h)
} }
func GetAdminUrl(path string) string { func GetAdminUrl(path string) string {
p:=strings.TrimPrefix(path,"/") p := strings.TrimPrefix(path, "/")
return fmt.Sprintf("%s/%s", adminUrl, p) return fmt.Sprintf("%s/%s", adminUrl, p)
} }
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"reflect" "reflect"
"time" "time"
) )
var ( var (
authNames = map[string]string{ authNames = map[string]string{
"Oauth2": "goku-oauth2_auth", "Oauth2": "goku-oauth2_auth",
...@@ -23,40 +24,37 @@ var ( ...@@ -23,40 +24,37 @@ var (
} }
) )
func getPluginNameByType(authType string) (string, bool) { func getPluginNameByType(authType string) (string, bool) {
name, has := authNames[authType] name, has := authNames[authType]
return name, has return name, has
} }
// 执行插件的Access函数 // 执行插件的Access函数
func AccessFunc(ctx *common.Context, handleFunc []*entity.PluginHandlerExce) (bool, int) { func AccessFunc(ctx *common.Context, handleFunc []*entity.PluginHandlerExce) (bool, int) {
requestId := ctx.RequestId() requestId := ctx.RequestId()
authType := ctx.Request().GetHeader("Authorization-Type") authType := ctx.Request().GetHeader("Authorization-Type")
authName, _ := getPluginNameByType(authType) authName, _ := getPluginNameByType(authType)
defer func(ctx *common.Context) { defer func(ctx *common.Context) {
log.Debug(requestId," access plugin default: begin") log.Debug(requestId, " access plugin default: begin")
for _, handler := range plugin_manager.GetDefaultPlugins() { for _, handler := range plugin_manager.GetDefaultPlugins() {
if handler.PluginObj.Access==nil || reflect.ValueOf(handler.PluginObj.Access).IsNil() { if handler.PluginObj.Access == nil || reflect.ValueOf(handler.PluginObj.Access).IsNil() {
continue continue
} }
ctx.SetPlugin(handler.Name) ctx.SetPlugin(handler.Name)
log.Info(requestId," access plugin:",handler.Name) log.Info(requestId, " access plugin:", handler.Name)
now:=time.Now() now := time.Now()
_, err:=handler.PluginObj.Access.Access(ctx) _, err := handler.PluginObj.Access.Access(ctx)
log.Debug(requestId," access plugin:",handler.Name," Duration",time.Since(now)) log.Debug(requestId, " access plugin:", handler.Name, " Duration", time.Since(now))
if err!=nil{ if err != nil {
log.Warn(requestId," access plugin:",handler.Name," error:",err.Error()) log.Warn(requestId, " access plugin:", handler.Name, " error:", err.Error())
} }
} }
log.Debug(requestId," access plugin default: end") log.Debug(requestId, " access plugin default: end")
}(ctx) }(ctx)
isAuthSucess := false isAuthSucess := false
isNeedAuth := false isNeedAuth := false
log.Debug(requestId," access plugin auth check: begin") log.Debug(requestId, " access plugin auth check: begin")
for _, handler := range handleFunc { for _, handler := range handleFunc {
if _, has := authPluginNames[handler.Name]; has { if _, has := authPluginNames[handler.Name]; has {
isNeedAuth = true isNeedAuth = true
...@@ -67,33 +65,33 @@ func AccessFunc(ctx *common.Context, handleFunc []*entity.PluginHandlerExce) (bo ...@@ -67,33 +65,33 @@ func AccessFunc(ctx *common.Context, handleFunc []*entity.PluginHandlerExce) (bo
continue continue
} }
ctx.SetPlugin(handler.Name) ctx.SetPlugin(handler.Name)
log.Debug(requestId," access plugin:",handler.Name," begin") log.Debug(requestId, " access plugin:", handler.Name, " begin")
now:=time.Now() now := time.Now()
flag, err := handler.PluginObj.Access.Access(ctx) flag, err := handler.PluginObj.Access.Access(ctx)
log.Debug(requestId," access plugin:",handler.Name," Duration",time.Since(now)) log.Debug(requestId, " access plugin:", handler.Name, " Duration", time.Since(now))
if flag == false { if flag == false {
// 校验失败 // 校验失败
if err != nil { if err != nil {
log.Warn(requestId," access auth:[",handler.Name,"] error:",err.Error()) log.Warn(requestId, " access auth:[", handler.Name, "] error:", err.Error())
} }
log.Info(requestId," auth [",authName,"] refuse") log.Info(requestId, " auth [", authName, "] refuse")
return false, 0 return false, 0
} }
log.Debug(requestId," auth [",authName,"] pass") log.Debug(requestId, " auth [", authName, "] pass")
isAuthSucess = true isAuthSucess = true
} }
} }
log.Debug(requestId," access plugin auth check: end") log.Debug(requestId, " access plugin auth check: end")
// 需要校验但是没有执行校验 // 需要校验但是没有执行校验
if isNeedAuth && !isAuthSucess { if isNeedAuth && !isAuthSucess {
log.Warn(requestId," Illegal authorization type:",authType) log.Warn(requestId, " Illegal authorization type:", authType)
ctx.SetStatus(403, "403") ctx.SetStatus(403, "403")
ctx.SetBody([]byte("[ERROR]Illegal authorization type!")) ctx.SetBody([]byte("[ERROR]Illegal authorization type!"))
return false, 0 return false, 0
} }
lastIndex := 0 lastIndex := 0
log.Debug(requestId," access plugin : begin") log.Debug(requestId, " access plugin : begin")
// 执行校验以外的插件 // 执行校验以外的插件
for index, handler := range handleFunc { for index, handler := range handleFunc {
lastIndex = index lastIndex = index
...@@ -106,19 +104,19 @@ func AccessFunc(ctx *common.Context, handleFunc []*entity.PluginHandlerExce) (bo ...@@ -106,19 +104,19 @@ func AccessFunc(ctx *common.Context, handleFunc []*entity.PluginHandlerExce) (bo
} }
ctx.SetPlugin(handler.Name) ctx.SetPlugin(handler.Name)
log.Debug(requestId," access plugin:",handler.Name) log.Debug(requestId, " access plugin:", handler.Name)
now:=time.Now() now := time.Now()
flag, err := handler.PluginObj.Access.Access(ctx) flag, err := handler.PluginObj.Access.Access(ctx)
log.Debug(requestId," access plugin:",handler.Name," Duration:",time.Since(now)) log.Debug(requestId, " access plugin:", handler.Name, " Duration:", time.Since(now))
if err != nil { if err != nil {
log.Warn(requestId," access plugin:",handler.Name," error:",err.Error()) log.Warn(requestId, " access plugin:", handler.Name, " error:", err.Error())
} }
if flag == false && handler.IsStop { if flag == false && handler.IsStop {
log.Info(requestId," access plugin:",handler.Name," stop") log.Info(requestId, " access plugin:", handler.Name, " stop")
return false, index return false, index
} }
log.Debug(requestId," access plugin:",handler.Name," continue") log.Debug(requestId, " access plugin:", handler.Name, " continue")
} }
log.Debug(requestId," access plugin : end") log.Debug(requestId, " access plugin : end")
return true, lastIndex return true, lastIndex
} }
...@@ -12,24 +12,24 @@ import ( ...@@ -12,24 +12,24 @@ import (
func BeforeMatch(ctx *common.Context) bool { func BeforeMatch(ctx *common.Context) bool {
requestId := ctx.RequestId() requestId := ctx.RequestId()
defer func(ctx *common.Context) { defer func(ctx *common.Context) {
log.Debug(requestId," before plugin default: begin") log.Debug(requestId, " before plugin default: begin")
for _, handler := range plugin_manager.GetDefaultPlugins() { for _, handler := range plugin_manager.GetDefaultPlugins() {
if handler.PluginObj.BeforeMatch == nil || reflect.ValueOf(handler.PluginObj.BeforeMatch).IsNil() { if handler.PluginObj.BeforeMatch == nil || reflect.ValueOf(handler.PluginObj.BeforeMatch).IsNil() {
continue continue
} }
ctx.SetPlugin(handler.Name) ctx.SetPlugin(handler.Name)
log.Debug(requestId," before plugin :",handler.Name," start") log.Debug(requestId, " before plugin :", handler.Name, " start")
now:=time.Now() now := time.Now()
_,err:=handler.PluginObj.BeforeMatch.BeforeMatch(ctx) _, err := handler.PluginObj.BeforeMatch.BeforeMatch(ctx)
log.Debug(requestId," before plugin :",handler.Name," Duration:",time.Since(now)) log.Debug(requestId, " before plugin :", handler.Name, " Duration:", time.Since(now))
log.Debug(requestId," before plugin :",handler.Name," end") log.Debug(requestId, " before plugin :", handler.Name, " end")
if err != nil { if err != nil {
log.Warn(requestId," before plugin:",handler.Name," error:",err.Error()) log.Warn(requestId, " before plugin:", handler.Name, " error:", err.Error())
} }
} }
log.Debug(requestId," before plugin default: end") log.Debug(requestId, " before plugin default: end")
}(ctx) }(ctx)
log.Debug(requestId," before plugin : begin") log.Debug(requestId, " before plugin : begin")
for _, handler := range plugin_manager.GetBeforPlugins() { for _, handler := range plugin_manager.GetBeforPlugins() {
if handler.PluginObj.BeforeMatch == nil || reflect.ValueOf(handler.PluginObj.BeforeMatch).IsNil() { if handler.PluginObj.BeforeMatch == nil || reflect.ValueOf(handler.PluginObj.BeforeMatch).IsNil() {
...@@ -37,14 +37,14 @@ func BeforeMatch(ctx *common.Context) bool { ...@@ -37,14 +37,14 @@ func BeforeMatch(ctx *common.Context) bool {
} }
ctx.SetPlugin(handler.Name) ctx.SetPlugin(handler.Name)
log.Debug(requestId," before plugin :",handler.Name," start") log.Debug(requestId, " before plugin :", handler.Name, " start")
now:=time.Now() now := time.Now()
flag, err := handler.PluginObj.BeforeMatch.BeforeMatch(ctx) flag, err := handler.PluginObj.BeforeMatch.BeforeMatch(ctx)
log.Debug(requestId," before plugin :",handler.Name," Duration:",time.Since(now)) log.Debug(requestId, " before plugin :", handler.Name, " Duration:", time.Since(now))
log.Debug(requestId," before plugin :",handler.Name," end") log.Debug(requestId, " before plugin :", handler.Name, " end")
if err != nil { if err != nil {
log.Warn(requestId," before plugin:",handler.Name," error:",err.Error()) log.Warn(requestId, " before plugin:", handler.Name, " error:", err.Error())
} }
if flag == false { if flag == false {
if handler.IsStop == true { if handler.IsStop == true {
...@@ -52,6 +52,6 @@ func BeforeMatch(ctx *common.Context) bool { ...@@ -52,6 +52,6 @@ func BeforeMatch(ctx *common.Context) bool {
} }
} }
} }
log.Debug(requestId," before plugin : end") log.Debug(requestId, " before plugin : end")
return true return true
} }
...@@ -14,26 +14,26 @@ import ( ...@@ -14,26 +14,26 @@ import (
func ProxyFunc(ctx *common.Context, handleFunc []*entity.PluginHandlerExce) (bool, int) { func ProxyFunc(ctx *common.Context, handleFunc []*entity.PluginHandlerExce) (bool, int) {
requestId := ctx.RequestId() requestId := ctx.RequestId()
defer func(ctx *common.Context) { defer func(ctx *common.Context) {
log.Debug(requestId," Proxy plugin default: begin") log.Debug(requestId, " Proxy plugin default: begin")
for _, handler := range plugin_manager.GetDefaultPlugins() { for _, handler := range plugin_manager.GetDefaultPlugins() {
if handler.PluginObj.Proxy == nil || reflect.ValueOf(handler.PluginObj.Proxy).IsNil() { if handler.PluginObj.Proxy == nil || reflect.ValueOf(handler.PluginObj.Proxy).IsNil() {
continue continue
} }
ctx.SetPlugin(handler.Name) ctx.SetPlugin(handler.Name)
log.Debug(requestId," Proxy plugin :",handler.Name," start") log.Debug(requestId, " Proxy plugin :", handler.Name, " start")
now:=time.Now() now := time.Now()
_, err:= handler.PluginObj.Proxy.Proxy(ctx) _, err := handler.PluginObj.Proxy.Proxy(ctx)
log.Debug(requestId," Proxy plugin :",handler.Name," Duration:",time.Since(now)) log.Debug(requestId, " Proxy plugin :", handler.Name, " Duration:", time.Since(now))
log.Debug(requestId," Proxy plugin :",handler.Name," end") log.Debug(requestId, " Proxy plugin :", handler.Name, " end")
if err != nil { if err != nil {
log.Warn(requestId," Proxy plugin:",handler.Name," error:",err.Error()) log.Warn(requestId, " Proxy plugin:", handler.Name, " error:", err.Error())
} }
} }
log.Debug(requestId," Proxy plugin default: begin") log.Debug(requestId, " Proxy plugin default: begin")
}(ctx) }(ctx)
lastIndex := 0 lastIndex := 0
log.Debug(requestId," Proxy plugin : begin") log.Debug(requestId, " Proxy plugin : begin")
for index, handler := range handleFunc { for index, handler := range handleFunc {
lastIndex = index lastIndex = index
if handler.PluginObj.Proxy == nil || reflect.ValueOf(handler.PluginObj.Proxy).IsNil() { if handler.PluginObj.Proxy == nil || reflect.ValueOf(handler.PluginObj.Proxy).IsNil() {
...@@ -41,21 +41,20 @@ func ProxyFunc(ctx *common.Context, handleFunc []*entity.PluginHandlerExce) (boo ...@@ -41,21 +41,20 @@ func ProxyFunc(ctx *common.Context, handleFunc []*entity.PluginHandlerExce) (boo
} }
ctx.SetPlugin(handler.Name) ctx.SetPlugin(handler.Name)
log.Debug(requestId," Proxy plugin :",handler.Name," start") log.Debug(requestId, " Proxy plugin :", handler.Name, " start")
now:=time.Now() now := time.Now()
flag, err := handler.PluginObj.Proxy.Proxy(ctx) flag, err := handler.PluginObj.Proxy.Proxy(ctx)
log.Debug(requestId," Proxy plugin :",handler.Name," Duration:",time.Since(now)) log.Debug(requestId, " Proxy plugin :", handler.Name, " Duration:", time.Since(now))
log.Debug(requestId," Proxy plugin :",handler.Name," end") log.Debug(requestId, " Proxy plugin :", handler.Name, " end")
if err != nil { if err != nil {
log.Warn(requestId," Proxy plugin :",handler.Name," error: ",err.Error()) log.Warn(requestId, " Proxy plugin :", handler.Name, " error: ", err.Error())
} }
if flag == false && handler.IsStop == true { if flag == false && handler.IsStop == true {
return false, lastIndex return false, lastIndex
} }
} }
log.Debug(requestId," Proxy plugin : end") log.Debug(requestId, " Proxy plugin : end")
return true, lastIndex return true, lastIndex
} }
...@@ -14,23 +14,23 @@ import ( ...@@ -14,23 +14,23 @@ import (
) )
// 创建转发请求 // 创建转发请求
func CreateRequest(ctx *common.Context, apiInfo *entity.ApiExtend, timeout, retry int) ( error, *http.Response) { func CreateRequest(ctx *common.Context, apiInfo *entity.ApiExtend, timeout, retry int) (error, *http.Response) {
app,has:=balance_manager.Get(apiInfo.Target) app, has := balance_manager.Get(apiInfo.Target)
if !has{ if !has {
err:= fmt.Errorf("get balance error:%s",apiInfo.Target) err := fmt.Errorf("get balance error:%s", apiInfo.Target)
return err,nil return err, nil
} }
rawbody, _ := ctx.ProxyRequest.RawBody() rawbody, _ := ctx.ProxyRequest.RawBody()
response,finalTargetServer,retryTargetServers,err:=app.Send(apiInfo.Protocol,ctx.ProxyRequest.Method,ctx.ProxyRequest.TargetURL(),ctx.ProxyRequest.Querys(),ctx.ProxyRequest.Headers() ,rawbody,time.Duration(timeout)*time.Millisecond,retry) response, finalTargetServer, retryTargetServers, err := app.Send(apiInfo.Protocol, ctx.ProxyRequest.Method, ctx.ProxyRequest.TargetURL(), ctx.ProxyRequest.Querys(), ctx.ProxyRequest.Headers(), rawbody, time.Duration(timeout)*time.Millisecond, retry)
ctx.SetRetryTargetServers(strings.Join(retryTargetServers, ",")) ctx.SetRetryTargetServers(strings.Join(retryTargetServers, ","))
ctx.SetFinalTargetServer(finalTargetServer) ctx.SetFinalTargetServer(finalTargetServer)
if err!= nil{ if err != nil {
return err,nil return err, nil
} }
return nil,response return nil, response
} }
...@@ -7,7 +7,6 @@ import ( ...@@ -7,7 +7,6 @@ import (
access_log "github.com/eolinker/goku/goku-node/access-log" access_log "github.com/eolinker/goku/goku-node/access-log"
"github.com/eolinker/goku/goku-node/handler" "github.com/eolinker/goku/goku-node/handler"
"github.com/eolinker/goku/goku-node/plugin-flow" "github.com/eolinker/goku/goku-node/plugin-flow"
. "github.com/eolinker/goku/server/access-field"
"net/http" "net/http"
"strconv" "strconv"
"strings" "strings"
...@@ -30,7 +29,7 @@ type Router struct { ...@@ -30,7 +29,7 @@ type Router struct {
mu map[string]http.HandlerFunc mu map[string]http.HandlerFunc
} }
func (mux*Router) ServeHTTP(w http.ResponseWriter, r*http.Request) { func (mux *Router) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.RequestURI == "*" { if r.RequestURI == "*" {
if r.ProtoAtLeast(1, 1) { if r.ProtoAtLeast(1, 1) {
w.Header().Set("Connection", "close") w.Header().Set("Connection", "close")
...@@ -38,26 +37,25 @@ func (mux*Router) ServeHTTP(w http.ResponseWriter, r*http.Request) { ...@@ -38,26 +37,25 @@ func (mux*Router) ServeHTTP(w http.ResponseWriter, r*http.Request) {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
path:=r.URL.Path path := r.URL.Path
h, has:= mux.mu[path] h, has := mux.mu[path]
if has{ if has {
h.ServeHTTP(w, r) h.ServeHTTP(w, r)
return return
} }
ServeHTTP(w,r) ServeHTTP(w, r)
} }
func NewRouter() http.Handler { func NewRouter() http.Handler {
r:=&Router{ r := &Router{
mu :make(map[string]http.HandlerFunc), mu: make(map[string]http.HandlerFunc),
} }
hs := handler.Handler()
hs:= handler.Handler() for _, h := range hs {
for _,h:=range hs{
r.mu[h.Pattern] = h.HandlerFunc r.mu[h.Pattern] = h.HandlerFunc
} }
...@@ -73,37 +71,35 @@ func ServeHTTP(w http.ResponseWriter, req *http.Request) { ...@@ -73,37 +71,35 @@ func ServeHTTP(w http.ResponseWriter, req *http.Request) {
} }
}() }()
timeStart := time.Now()
timeStart:=time.Now() logFields := make(log.Fields)
logFields:=make(log.Fields)
// 记录访问次数 // 记录访问次数
requestID := GetRandomString(16) requestID := GetRandomString(16)
ctx := common.NewContext(req, requestID, w) ctx := common.NewContext(req, requestID, w)
proxyStatusCode := 0 proxyStatusCode := 0
log.Debug(requestID," url: ",req.URL.String()) log.Debug(requestID, " url: ", req.URL.String())
log.Debug(requestID," header: ",ctx.RequestOrg.Header.String()) log.Debug(requestID, " header: ", ctx.RequestOrg.Header.String())
rawBody ,err:=ctx.RequestOrg.RawBody() rawBody, err := ctx.RequestOrg.RawBody()
if err==nil{ if err == nil {
log.Debug(requestID," body: ",string(rawBody)) log.Debug(requestID, " body: ", string(rawBody))
} }
defer func() { defer func() {
n,status:=ctx.Finish() n, status := ctx.Finish()
if ctx.ProxyResponseHandler != nil { if ctx.ProxyResponseHandler != nil {
proxyStatusCode = ctx.ProxyResponseHandler.StatusCode() proxyStatusCode = ctx.ProxyResponseHandler.StatusCode()
} }
logFields[RequestId]= requestID logFields[RequestId] = requestID
logFields[StatusCode] = status logFields[StatusCode] = status
logFields[HttpUserAgent] = fmt.Sprint("\"",req.UserAgent(),"\"") logFields[HttpUserAgent] = fmt.Sprint("\"", req.UserAgent(), "\"")
logFields[HttpReferer] = req.Referer() logFields[HttpReferer] = req.Referer()
logFields[RequestTime] = time.Since(timeStart) logFields[RequestTime] = time.Since(timeStart)
logFields[Request] = fmt.Sprint("\"",req.Method," ",req.URL.Path," ",req.Proto,"\"") logFields[Request] = fmt.Sprint("\"", req.Method, " ", req.URL.Path, " ", req.Proto, "\"")
logFields[BodyBytesSent] = n logFields[BodyBytesSent] = n
logFields[Host] = req.Host logFields[Host] = req.Host
access_log.Log(logFields) access_log.Log(logFields)
...@@ -120,12 +116,12 @@ func ServeHTTP(w http.ResponseWriter, req *http.Request) { ...@@ -120,12 +116,12 @@ func ServeHTTP(w http.ResponseWriter, req *http.Request) {
}() }()
remoteAddr := Intercept(req.RemoteAddr, ":") remoteAddr := Intercept(req.RemoteAddr, ":")
logFields[RemoteAddr]= remoteAddr logFields[RemoteAddr] = remoteAddr
if realIp := ctx.GetHeader("X-Real-Ip") ;realIp == ""{ if realIp := ctx.GetHeader("X-Real-Ip"); realIp == "" {
ctx.ProxyRequest.SetHeader("X-Real-Ip", remoteAddr) ctx.ProxyRequest.SetHeader("X-Real-Ip", remoteAddr)
logFields[HttpXForwardedFor] = remoteAddr logFields[HttpXForwardedFor] = remoteAddr
}else{ } else {
logFields[HttpXForwardedFor] = realIp logFields[HttpXForwardedFor] = realIp
} }
...@@ -133,21 +129,20 @@ func ServeHTTP(w http.ResponseWriter, req *http.Request) { ...@@ -133,21 +129,20 @@ func ServeHTTP(w http.ResponseWriter, req *http.Request) {
var isBefor bool var isBefor bool
start := time.Now() start := time.Now()
isBefor = plugin_flow.BeforeMatch(ctx) isBefor = plugin_flow.BeforeMatch(ctx)
log.Info(requestID," BeforeMatch plugin duration:",time.Since(start)) log.Info(requestID, " BeforeMatch plugin duration:", time.Since(start))
if !isBefor { if !isBefor {
log.Info(requestID," stop by BeforeMatch plugin") log.Info(requestID, " stop by BeforeMatch plugin")
return return
} }
var timeout, retryCount int var timeout, retryCount int
strategyID, ok := retrieveStrategyID(ctx) strategyID, ok := retrieveStrategyID(ctx)
if !ok { if !ok {
return return
} }
logFields[Strategy] = fmt.Sprintf("\"%s %s\"", strategyID,ctx.StrategyName()) logFields[Strategy] = fmt.Sprintf("\"%s %s\"", strategyID, ctx.StrategyName())
requestPath := req.URL.Path requestPath := req.URL.Path
requestMenthod := ctx.Request().Method() requestMenthod := ctx.Request().Method()
...@@ -160,7 +155,6 @@ func ServeHTTP(w http.ResponseWriter, req *http.Request) { ...@@ -160,7 +155,6 @@ func ServeHTTP(w http.ResponseWriter, req *http.Request) {
//ctx.IsMatch = true //ctx.IsMatch = true
timeout = apiInfo.Timeout timeout = apiInfo.Timeout
ctx.ProxyRequest.SetTargetServer(fmt.Sprintf("%s://%s", apiInfo.Protocol, apiInfo.Target)) ctx.ProxyRequest.SetTargetServer(fmt.Sprintf("%s://%s", apiInfo.Protocol, apiInfo.Target))
targetUrl := apiInfo.TargetURL + requestPath targetUrl := apiInfo.TargetURL + requestPath
...@@ -185,7 +179,7 @@ func ServeHTTP(w http.ResponseWriter, req *http.Request) { ...@@ -185,7 +179,7 @@ func ServeHTTP(w http.ResponseWriter, req *http.Request) {
} }
start = time.Now() start = time.Now()
isAccess, _ := plugin_flow.AccessFunc(ctx, handleFunc) isAccess, _ := plugin_flow.AccessFunc(ctx, handleFunc)
log.Info(requestID," Access plugin duration:",time.Since(start)) log.Info(requestID, " Access plugin duration:", time.Since(start))
if !isAccess { if !isAccess {
// todo // todo
...@@ -193,18 +187,18 @@ func ServeHTTP(w http.ResponseWriter, req *http.Request) { ...@@ -193,18 +187,18 @@ func ServeHTTP(w http.ResponseWriter, req *http.Request) {
} }
if apiInfo == nil { if apiInfo == nil {
log.Info(requestID," URL dose not exist!") log.Info(requestID, " URL dose not exist!")
ctx.SetStatus(404, "404") ctx.SetStatus(404, "404")
ctx.SetBody([]byte("[ERROR]URL dose not exist!")) ctx.SetBody([]byte("[ERROR]URL dose not exist!"))
return return
} }
logFields[Api] = fmt.Sprintf("\"%d %s\"",apiInfo.ApiID,apiInfo.ApiName) logFields[Api] = fmt.Sprintf("\"%d %s\"", apiInfo.ApiID, apiInfo.ApiName)
logFields[Proxy] = fmt.Sprintf("\"%s %s %s\"",ctx.ProxyRequest.Method,ctx.ProxyRequest.TargetURL(),apiInfo.Protocol) logFields[Proxy] = fmt.Sprintf("\"%s %s %s\"", ctx.ProxyRequest.Method, ctx.ProxyRequest.TargetURL(), apiInfo.Protocol)
logFields[Balance] = apiInfo.Target logFields[Balance] = apiInfo.Target
start = time.Now() start = time.Now()
err, response := CreateRequest(ctx, apiInfo, timeout, retryCount) err, response := CreateRequest(ctx, apiInfo, timeout, retryCount)
log.Info(requestID," Proxy request duration:",time.Since(start)) log.Info(requestID, " Proxy request duration:", time.Since(start))
if err != nil { if err != nil {
log.Warn(err.Error()) log.Warn(err.Error())
} }
...@@ -243,7 +237,7 @@ func ServeHTTP(w http.ResponseWriter, req *http.Request) { ...@@ -243,7 +237,7 @@ func ServeHTTP(w http.ResponseWriter, req *http.Request) {
start = time.Now() start = time.Now()
isProxy, _ := plugin_flow.ProxyFunc(ctx, handleFunc) isProxy, _ := plugin_flow.ProxyFunc(ctx, handleFunc)
log.Info(requestID," Proxy plugin Duration:",time.Since(start)) log.Info(requestID, " Proxy plugin Duration:", time.Since(start))
if !isProxy { if !isProxy {
return return
} }
......
...@@ -14,8 +14,6 @@ import ( ...@@ -14,8 +14,6 @@ import (
"strings" "strings"
) )
func InitPluginUtils() { func InitPluginUtils() {
goku_plugin.SetRedisManager(redis_plugin_proxy.Create()) goku_plugin.SetRedisManager(redis_plugin_proxy.Create())
goku_plugin.InitLog(log.GetLogger()) goku_plugin.InitLog(log.GetLogger())
...@@ -29,7 +27,7 @@ func InitDiscovery() { ...@@ -29,7 +27,7 @@ func InitDiscovery() {
func InitLog() { func InitLog() {
config_manager.InitLog() config_manager.InitLog()
} }
func InitServer(){ func InitServer() {
log.Debug("init InitServer start") log.Debug("init InitServer start")
InitPluginUtils() InitPluginUtils()
......
...@@ -51,4 +51,3 @@ func PanicTrace(kb int) []byte { ...@@ -51,4 +51,3 @@ func PanicTrace(kb int) []byte {
stack = bytes.TrimRight(stack, "\n") stack = bytes.TrimRight(stack, "\n")
return stack return stack
} }
...@@ -226,19 +226,19 @@ func UpdateProxyFailureCount(apiInfo *entity.ApiExtend, ...@@ -226,19 +226,19 @@ func UpdateProxyFailureCount(apiInfo *entity.ApiExtend,
// 记录告警日志 // 记录告警日志
func AlertLog(requestURL, targetServer, targetURL, requestMethod, proxyMethod, headerList, queryParamList, formParamList, responseHeaderList string, responseStatus int, strategyID string, strategyName, requestID string) { func AlertLog(requestURL, targetServer, targetURL, requestMethod, proxyMethod, headerList, queryParamList, formParamList, responseHeaderList string, responseStatus int, strategyID string, strategyName, requestID string) {
log.WithFields(log.Fields{ log.WithFields(log.Fields{
"request_id":requestID, "request_id": requestID,
"strategy_name":strategyName, "strategy_name": strategyName,
"strategy_id":strategyID, "strategy_id": strategyID,
"request_method":requestMethod, "request_method": requestMethod,
"request_url":requestURL, "request_url": requestURL,
"target_method":proxyMethod, "target_method": proxyMethod,
"target_server":targetServer, "target_server": targetServer,
"target_url":targetURL, "target_url": targetURL,
"request_query":queryParamList, "request_query": queryParamList,
"request_header":headerList, "request_header": headerList,
"request_form_param":formParamList, "request_form_param": formParamList,
"response_statusCode":strconv.Itoa(responseStatus), "response_statusCode": strconv.Itoa(responseStatus),
"response_header":responseHeaderList, "response_header": responseHeaderList,
}).Warning("alert") }).Warning("alert")
//_= logutils.Log("log/alertLog", "alert", log.PeriodDay, logInfo) //_= logutils.Log("log/alertLog", "alert", log.PeriodDay, logInfo)
......
...@@ -7,5 +7,5 @@ import ( ...@@ -7,5 +7,5 @@ import (
) )
type IHttpApplication interface { type IHttpApplication interface {
Send(Proto string, method string,path string,querys url.Values,header http.Header,body []byte,timeout time.Duration,retry int)(*http.Response,string,[]string,error) Send(Proto string, method string, path string, querys url.Values, header http.Header, body []byte, timeout time.Duration, retry int) (*http.Response, string, []string, error)
} }
...@@ -11,36 +11,36 @@ import ( ...@@ -11,36 +11,36 @@ import (
type Org struct { type Org struct {
server string server string
} }
// 忽略重试
func (app *Org) Send(proto string,method string, path string,querys url.Values, header http.Header, body []byte,timeout time.Duration, retry int) (*http.Response,string,[]string,error) {
// 忽略重试
func (app *Org) Send(proto string, method string, path string, querys url.Values, header http.Header, body []byte, timeout time.Duration, retry int) (*http.Response, string, []string, error) {
var response *http.Response = nil var response *http.Response = nil
var err error = nil var err error = nil
FinalTargetServer := "" FinalTargetServer := ""
RetryTargetServers :=make([]string,0,retry+1) RetryTargetServers := make([]string, 0, retry+1)
path = utils.TrimPrefixAll(path,"/") path = utils.TrimPrefixAll(path, "/")
for doTrice := retry +1;doTrice>0;doTrice--{ for doTrice := retry + 1; doTrice > 0; doTrice-- {
u:= fmt.Sprintf("%s://%s/%s",proto,app.server,path) u := fmt.Sprintf("%s://%s/%s", proto, app.server, path)
FinalTargetServer = app.server FinalTargetServer = app.server
RetryTargetServers = append(RetryTargetServers,FinalTargetServer) RetryTargetServers = append(RetryTargetServers, FinalTargetServer)
response,err =request(method,u,querys,header,body,timeout) response, err = request(method, u, querys, header, body, timeout)
if err != nil{ if err != nil {
continue continue
}else{ } else {
return response,FinalTargetServer,RetryTargetServers,err return response, FinalTargetServer, RetryTargetServers, err
} }
} }
return response,FinalTargetServer,RetryTargetServers,err return response, FinalTargetServer, RetryTargetServers, err
} }
func NewOrg(server string)IHttpApplication { func NewOrg(server string) IHttpApplication {
return &Org{ return &Org{
server:server, server: server,
} }
} }
...@@ -7,33 +7,27 @@ import ( ...@@ -7,33 +7,27 @@ import (
"time" "time"
) )
func request(method string, backendDomain string,query url.Values, header http.Header, body []byte,timeout time.Duration) (*http.Response,error) { func request(method string, backendDomain string, query url.Values, header http.Header, body []byte, timeout time.Duration) (*http.Response, error) {
if backendDomain == "" { if backendDomain == "" {
return nil,fmt.Errorf("invaild url") return nil, fmt.Errorf("invaild url")
} }
u, err := url.ParseRequestURI(backendDomain) u, err := url.ParseRequestURI(backendDomain)
if err != nil { if err != nil {
return nil, err return nil, err
} }
req, err := NewRequest(method, u) req, err := NewRequest(method, u)
if err != nil { if err != nil {
return nil,err return nil, err
} }
req.headers = header req.headers = header
req.queryParams = query req.queryParams = query
req.SetRawBody(body) req.SetRawBody(body)
if timeout != 0 { if timeout != 0 {
req.SetTimeout(timeout) req.SetTimeout(timeout)
......
...@@ -15,46 +15,44 @@ type Application struct { ...@@ -15,46 +15,44 @@ type Application struct {
healthCheckHandler health.CheckHandler healthCheckHandler health.CheckHandler
} }
func NewApplication(service *common.Service,healthCheckHandler health.CheckHandler) *Application { func NewApplication(service *common.Service, healthCheckHandler health.CheckHandler) *Application {
return &Application{ return &Application{
service: service, service: service,
healthCheckHandler: healthCheckHandler, healthCheckHandler: healthCheckHandler,
} }
} }
func (app *Application) Send(proto string,method string, path string,querys url.Values, header http.Header, body []byte,timeout time.Duration, retry int)( *http.Response,string,[]string,error) { func (app *Application) Send(proto string, method string, path string, querys url.Values, header http.Header, body []byte, timeout time.Duration, retry int) (*http.Response, string, []string, error) {
var response *http.Response = nil var response *http.Response = nil
var err error = nil var err error = nil
FinalTargetServer := "" FinalTargetServer := ""
RetryTargetServers :=make([]string,0,retry+1) RetryTargetServers := make([]string, 0, retry+1)
lastIndex := -1 lastIndex := -1
path = utils.TrimPrefixAll(path,"/") path = utils.TrimPrefixAll(path, "/")
for doTrice := retry +1;doTrice>0;doTrice--{ for doTrice := retry + 1; doTrice > 0; doTrice-- {
instance,index,has:=app.service.Next(lastIndex) instance, index, has := app.service.Next(lastIndex)
lastIndex = index lastIndex = index
if !has{ if !has {
return nil,FinalTargetServer,RetryTargetServers,fmt.Errorf("not found instance for app:%s",app.service.Name) return nil, FinalTargetServer, RetryTargetServers, fmt.Errorf("not found instance for app:%s", app.service.Name)
} }
FinalTargetServer = fmt.Sprintf("%s:%d",instance.IP,instance.Port) FinalTargetServer = fmt.Sprintf("%s:%d", instance.IP, instance.Port)
RetryTargetServers = append(RetryTargetServers,FinalTargetServer) RetryTargetServers = append(RetryTargetServers, FinalTargetServer)
u:= fmt.Sprintf("%s://%s:%d/%s",proto,instance.IP,instance.Port,path) u := fmt.Sprintf("%s://%s:%d/%s", proto, instance.IP, instance.Port, path)
response,err =request(method,u,querys,header,body,timeout) response, err = request(method, u, querys, header, body, timeout)
if err != nil{ if err != nil {
if app.healthCheckHandler.IsNeedCheck(){ if app.healthCheckHandler.IsNeedCheck() {
app.healthCheckHandler.Check(instance) app.healthCheckHandler.Check(instance)
} }
}else{ } else {
return response,FinalTargetServer,RetryTargetServers,err return response, FinalTargetServer, RetryTargetServers, err
} }
} }
return response,FinalTargetServer,RetryTargetServers,err return response, FinalTargetServer, RetryTargetServers, err
} }
...@@ -5,5 +5,3 @@ type Balance struct { ...@@ -5,5 +5,3 @@ type Balance struct {
Discovery string Discovery string
AppConfig string AppConfig string
} }
...@@ -7,9 +7,9 @@ import ( ...@@ -7,9 +7,9 @@ import (
func ResetBalances(balances []*Balance) { func ResetBalances(balances []*Balance) {
bmap:=make(map[string]*Balance) bmap := make(map[string]*Balance)
for _,b:=range balances{ for _, b := range balances {
bmap[b.Name] = b bmap[b.Name] = b
} }
...@@ -18,20 +18,20 @@ func ResetBalances(balances []*Balance) { ...@@ -18,20 +18,20 @@ func ResetBalances(balances []*Balance) {
} }
func GetByName(name string)(application.IHttpApplication,bool) { func GetByName(name string) (application.IHttpApplication, bool) {
b,has:=manager.get(name) b, has := manager.get(name)
if !has{ if !has {
return application.NewOrg(name),true return application.NewOrg(name), true
} }
sources,has:=discovery.GetDiscoverer(b.Discovery) sources, has := discovery.GetDiscoverer(b.Discovery)
if has{ if has {
service, handler, yes:= sources.GetApp(b.AppConfig) service, handler, yes := sources.GetApp(b.AppConfig)
if yes{ if yes {
return application.NewApplication(service,handler),true return application.NewApplication(service, handler), true
} }
} }
return nil,false return nil, false
} }
...@@ -5,30 +5,26 @@ import ( ...@@ -5,30 +5,26 @@ import (
) )
var manager = &Manager{ var manager = &Manager{
locker:sync.RWMutex{}, locker: sync.RWMutex{},
balances:make(map[string]*Balance), balances: make(map[string]*Balance),
} }
type Manager struct { type Manager struct {
locker sync.RWMutex locker sync.RWMutex
balances map[string]*Balance balances map[string]*Balance
} }
func (m *Manager)set(balances map[string]*Balance) { func (m *Manager) set(balances map[string]*Balance) {
m.locker.Lock() m.locker.Lock()
m.balances = balances m.balances = balances
m.locker.Unlock() m.locker.Unlock()
} }
func (m *Manager)get(name string)( *Balance,bool) { func (m *Manager) get(name string) (*Balance, bool) {
m.locker.RLock() m.locker.RLock()
b,has:=m.balances[name] b, has := m.balances[name]
m.locker.RUnlock() m.locker.RUnlock()
return b,has return b, has
} }
...@@ -17,28 +17,28 @@ func NewInstanceFactory() *InstanceFactory { ...@@ -17,28 +17,28 @@ func NewInstanceFactory() *InstanceFactory {
} }
} }
func (m *InstanceFactory) General(ip string,port int,weight int)*Instance { func (m *InstanceFactory) General(ip string, port int, weight int) *Instance {
if weight<1{ if weight < 1 {
weight = 1 weight = 1
} }
key:=fmt.Sprintf("%s:%d-%d",ip,port,weight) key := fmt.Sprintf("%s:%d-%d", ip, port, weight)
m.locker.RLock() m.locker.RLock()
i,h:=m.instances[key] i, h := m.instances[key]
m.locker.RUnlock() m.locker.RUnlock()
if h{ if h {
i.Weight = weight i.Weight = weight
return i return i
} }
m.locker.Lock() m.locker.Lock()
i,h =m.instances[key] i, h = m.instances[key]
if h{ if h {
m.locker.Unlock() m.locker.Unlock()
i.Weight = weight i.Weight = weight
return i return i
} }
i =&Instance{ i = &Instance{
InstanceId: fmt.Sprintf("%s:%d",ip,port), InstanceId: fmt.Sprintf("%s:%d", ip, port),
IP: ip, IP: ip,
Port: port, Port: port,
Weight: weight, Weight: weight,
......
...@@ -17,32 +17,31 @@ func (p PInstances) Len() int { ...@@ -17,32 +17,31 @@ func (p PInstances) Len() int {
} }
func (p PInstances) Less(i, j int) bool { func (p PInstances) Less(i, j int) bool {
return p[i].Weight<p[j].Weight return p[i].Weight < p[j].Weight
} }
func (p PInstances) Swap(i, j int) { func (p PInstances) Swap(i, j int) {
p[i],p[j]=p[j],p[i] p[i], p[j] = p[j], p[i]
} }
func (i*Instance)CheckStatus(status InstanceStatus) bool { func (i *Instance) CheckStatus(status InstanceStatus) bool {
i.locker.RLock() i.locker.RLock()
b:= i.Status == status b := i.Status == status
i.locker.RUnlock() i.locker.RUnlock()
return b return b
} }
//ChangeStatus set status to desc where status is org //ChangeStatus set status to desc where status is org
func (i *Instance)ChangeStatus(org,dest InstanceStatus)bool { func (i *Instance) ChangeStatus(org, dest InstanceStatus) bool {
if org == dest{ if org == dest {
return i.CheckStatus(org) return i.CheckStatus(org)
} }
i.locker.RLock() i.locker.RLock()
b:= i.Status == org b := i.Status == org
i.locker.RUnlock() i.locker.RUnlock()
if !b{ if !b {
return false return false
} }
......
...@@ -6,17 +6,14 @@ import ( ...@@ -6,17 +6,14 @@ import (
"sync" "sync"
) )
type Service struct { type Service struct {
Name string Name string
instances []*Instance instances []*Instance
//lastIndex int //lastIndex int
locker sync.RWMutex locker sync.RWMutex
} }
func NewService(name string,Instances []*Instance) *Service{ func NewService(name string, Instances []*Instance) *Service {
return &Service{ return &Service{
Name: name, Name: name,
instances: Instances, instances: Instances,
...@@ -25,7 +22,7 @@ func NewService(name string,Instances []*Instance) *Service{ ...@@ -25,7 +22,7 @@ func NewService(name string,Instances []*Instance) *Service{
} }
} }
func (s*Service)SetInstances(instances []*Instance) { func (s *Service) SetInstances(instances []*Instance) {
sort.Sort(sort.Reverse(PInstances(instances))) sort.Sort(sort.Reverse(PInstances(instances)))
s.locker.Lock() s.locker.Lock()
...@@ -39,57 +36,57 @@ func (s*Service)SetInstances(instances []*Instance) { ...@@ -39,57 +36,57 @@ func (s*Service)SetInstances(instances []*Instance) {
//} //}
} }
func (s*Service)Weighting()(*Instance,int,bool) { func (s *Service) Weighting() (*Instance, int, bool) {
s.locker.RLock() s.locker.RLock()
instances:=s.instances instances := s.instances
s.locker.RUnlock() s.locker.RUnlock()
if len(instances)==0{ if len(instances) == 0 {
return nil,0,false return nil, 0, false
} }
weightSum:= 0 weightSum := 0
for _,ins:=range instances{ for _, ins := range instances {
if ins.CheckStatus(InstanceRun){ if ins.CheckStatus(InstanceRun) {
weightSum += ins.Weight weightSum += ins.Weight
} }
} }
if weightSum ==0{ if weightSum == 0 {
return nil,0,false return nil, 0, false
} }
weightValue:= rand.Intn(weightSum)+1 weightValue := rand.Intn(weightSum) + 1
for i,ins:=range instances{ for i, ins := range instances {
if ins.CheckStatus(InstanceRun){ if ins.CheckStatus(InstanceRun) {
weightValue = weightValue - ins.Weight weightValue = weightValue - ins.Weight
if weightValue <=0{ if weightValue <= 0 {
return ins,i,true return ins, i, true
} }
} }
} }
return nil,0,false return nil, 0, false
} }
func (s*Service)Next(lastIndex int)(*Instance,int ,bool) { func (s *Service) Next(lastIndex int) (*Instance, int, bool) {
if lastIndex == -1{ if lastIndex == -1 {
return s.Weighting() return s.Weighting()
} }
s.locker.RLock() s.locker.RLock()
instances := s.instances instances := s.instances
s.locker.RUnlock() s.locker.RUnlock()
size:= len(instances) size := len(instances)
if size == 0{ if size == 0 {
return nil,0,false return nil, 0, false
} }
for i:=0;i<size;i++{ for i := 0; i < size; i++ {
index:=(lastIndex +i)%size index := (lastIndex + i) % size
instance:=instances[index] instance := instances[index]
if instance != nil{ if instance != nil {
if instance.CheckStatus(InstanceRun){ if instance.CheckStatus(InstanceRun) {
return instance,index,true return instance, index, true
} }
} }
} }
return nil,0,false return nil, 0, false
} }
...@@ -4,10 +4,8 @@ import "strings" ...@@ -4,10 +4,8 @@ import "strings"
type InstanceStatus int type InstanceStatus int
const ( const (
InstanceRun= iota InstanceRun = iota
InstanceDown InstanceDown
InstanceChecking InstanceChecking
) )
...@@ -24,8 +22,8 @@ func (status InstanceStatus) String() string { ...@@ -24,8 +22,8 @@ func (status InstanceStatus) String() string {
return "unkown" return "unkown"
} }
func ParseStatus(status string)InstanceStatus { func ParseStatus(status string) InstanceStatus {
s:=strings.ToLower(status) s := strings.ToLower(status)
switch s { switch s {
case "down": case "down":
......
...@@ -6,7 +6,6 @@ type HealthCheckConfig struct { ...@@ -6,7 +6,6 @@ type HealthCheckConfig struct {
Second int Second int
TimeOutMill int TimeOutMill int
StatusCode string StatusCode string
} }
type Config struct { type Config struct {
Name string Name string
......
...@@ -4,14 +4,11 @@ import ( ...@@ -4,14 +4,11 @@ import (
"github.com/eolinker/goku/goku-service/common" "github.com/eolinker/goku/goku-service/common"
) )
type Discovery interface { type Discovery interface {
SetConfig(config string)error SetConfig(config string) error
Driver()string Driver() string
SetCallback(callback func(services []*common.Service)) SetCallback(callback func(services []*common.Service))
GetServers()([]*common.Service,error) GetServers() ([]*common.Service, error)
Close()error Close() error
Open()error Open() error
} }
...@@ -7,13 +7,14 @@ import ( ...@@ -7,13 +7,14 @@ import (
var ( var (
//isLock =false //isLock =false
drivers =make(map[string]Driver) drivers = make(map[string]Driver)
driverNames =make([]string,0) driverNames = make([]string, 0)
) )
func AllDrivers()[]string { func AllDrivers() []string {
return driverNames return driverNames
} }
// main里应该调用这个方法,以锁住driver, @为了线程安全并且避免锁操作@ // main里应该调用这个方法,以锁住driver, @为了线程安全并且避免锁操作@
//func LockDriver(){ //func LockDriver(){
// if isLock{ // if isLock{
...@@ -22,7 +23,7 @@ func AllDrivers()[]string { ...@@ -22,7 +23,7 @@ func AllDrivers()[]string {
// isLock=true // isLock=true
//} //}
func RegisteredDiscovery(name string,driver Driver) { func RegisteredDiscovery(name string, driver Driver) {
//if isLock{ //if isLock{
// panic("can not Register now") // panic("can not Register now")
...@@ -30,11 +31,11 @@ func RegisteredDiscovery(name string,driver Driver) { ...@@ -30,11 +31,11 @@ func RegisteredDiscovery(name string,driver Driver) {
name = strings.ToLower(name) name = strings.ToLower(name)
_,has:=drivers[name] _, has := drivers[name]
if has{ if has {
log.Panic("driver duplicate:"+name) log.Panic("driver duplicate:" + name)
} }
drivers[name]=driver drivers[name] = driver
driverNames =append(driverNames,name) driverNames = append(driverNames, name)
} }
...@@ -3,10 +3,10 @@ package discovery ...@@ -3,10 +3,10 @@ package discovery
import "sync" import "sync"
type Driver interface { type Driver interface {
Open(name string,config string)(ISource,error) Open(name string, config string) (ISource, error)
} }
type CreateHandler func(config string)Discovery type CreateHandler func(config string) Discovery
type DriverBase struct { type DriverBase struct {
createFunc CreateHandler createFunc CreateHandler
...@@ -14,7 +14,7 @@ type DriverBase struct { ...@@ -14,7 +14,7 @@ type DriverBase struct {
sources map[string]*SourceDiscovery sources map[string]*SourceDiscovery
} }
func NewDriver( createFunc CreateHandler) *DriverBase{ func NewDriver(createFunc CreateHandler) *DriverBase {
return &DriverBase{ return &DriverBase{
createFunc: createFunc, createFunc: createFunc,
locker: sync.RWMutex{}, locker: sync.RWMutex{},
...@@ -25,26 +25,24 @@ func NewDriver( createFunc CreateHandler) *DriverBase{ ...@@ -25,26 +25,24 @@ func NewDriver( createFunc CreateHandler) *DriverBase{
func (d *DriverBase) Open(name string, config string) (ISource, error) { func (d *DriverBase) Open(name string, config string) (ISource, error) {
d.locker.RLock() d.locker.RLock()
s,h:= d.sources[name] s, h := d.sources[name]
d.locker.RUnlock() d.locker.RUnlock()
if h{ if h {
return s,s.SetDriverConfig(config) return s, s.SetDriverConfig(config)
} }
d.locker.Lock() d.locker.Lock()
s,h = d.sources[name] s, h = d.sources[name]
if h{ if h {
d.locker.Unlock() d.locker.Unlock()
return s,s.SetDriverConfig(config) return s, s.SetDriverConfig(config)
} }
ds:=d.createFunc(config) ds := d.createFunc(config)
s,_ = NewSource(name,ds) s, _ = NewSource(name, ds)
d.sources[name]=s d.sources[name] = s
d.locker.Unlock() d.locker.Unlock()
return s,nil return s, nil
} }
...@@ -5,9 +5,9 @@ import ( ...@@ -5,9 +5,9 @@ import (
"sync" "sync"
) )
var manager=&Manager{ var manager = &Manager{
locker:sync.RWMutex{}, locker: sync.RWMutex{},
sources:make( map[string]ISource), sources: make(map[string]ISource),
} }
type Manager struct { type Manager struct {
...@@ -18,47 +18,47 @@ type Manager struct { ...@@ -18,47 +18,47 @@ type Manager struct {
func ResetAllServiceConfig(confs []*Config) { func ResetAllServiceConfig(confs []*Config) {
sources:=make( map[string]ISource) sources := make(map[string]ISource)
manager.locker.RLock() manager.locker.RLock()
oldSources:= manager.sources oldSources := manager.sources
manager.locker.RUnlock() manager.locker.RUnlock()
for _,conf:=range confs{ for _, conf := range confs {
name := conf.Name name := conf.Name
s,has:= oldSources[name] s, has := oldSources[name]
if has && !s.CheckDriver(conf.Driver){ if has && !s.CheckDriver(conf.Driver) {
// 如果驱动不一样,关闭旧的 // 如果驱动不一样,关闭旧的
has = false has = false
s.Close() s.Close()
s=nil s = nil
delete(oldSources,name) delete(oldSources, name)
} }
if !has{ if !has {
driverName:=conf.Driver driverName := conf.Driver
driver,has:=drivers[driverName] driver, has := drivers[driverName]
if !has{ if !has {
log.Error("invalid driver:",driverName) log.Error("invalid driver:", driverName)
continue continue
} }
ns, err:=driver.Open(name,conf.Config) ns, err := driver.Open(name, conf.Config)
if err!=nil{ if err != nil {
continue continue
} }
s=ns s = ns
} }
sources[name]=s sources[name] = s
s.SetHealthConfig(&conf.HealthCheckConfig) s.SetHealthConfig(&conf.HealthCheckConfig)
err:=s.SetDriverConfig(conf.Config) err := s.SetDriverConfig(conf.Config)
if err!=nil{ if err != nil {
continue continue
} }
} }
for name,s:=range oldSources{ for name, s := range oldSources {
if _,has:=sources[name];!has{ if _, has := sources[name]; !has {
s.Close() s.Close()
} }
} }
...@@ -68,9 +68,9 @@ func ResetAllServiceConfig(confs []*Config) { ...@@ -68,9 +68,9 @@ func ResetAllServiceConfig(confs []*Config) {
manager.locker.Unlock() manager.locker.Unlock()
} }
func GetDiscoverer(discoveryName string)(ISource,bool) { func GetDiscoverer(discoveryName string) (ISource, bool) {
manager.locker.RLock() manager.locker.RLock()
s,has:=manager.sources[discoveryName] s, has := manager.sources[discoveryName]
manager.locker.RUnlock() manager.locker.RUnlock()
return s,has return s, has
} }
...@@ -10,14 +10,13 @@ import ( ...@@ -10,14 +10,13 @@ import (
) )
type ISource interface { type ISource interface {
GetApp(app string)(*common.Service ,health.CheckHandler,bool) GetApp(app string) (*common.Service, health.CheckHandler, bool)
SetHealthConfig(conf *HealthCheckConfig) SetHealthConfig(conf *HealthCheckConfig)
SetDriverConfig(config string)error SetDriverConfig(config string) error
Close() Close()
CheckDriver(driverName string)bool CheckDriver(driverName string) bool
} }
type SourceDiscovery struct { type SourceDiscovery struct {
name string name string
discovery Discovery discovery Discovery
...@@ -27,31 +26,29 @@ type SourceDiscovery struct { ...@@ -27,31 +26,29 @@ type SourceDiscovery struct {
services map[string]*common.Service services map[string]*common.Service
} }
func (s *SourceDiscovery) SetDriverConfig(config string) error {
func (s *SourceDiscovery) SetDriverConfig(config string)error {
return s.discovery.SetConfig(config) return s.discovery.SetConfig(config)
} }
func (s *SourceDiscovery) Close() { func (s *SourceDiscovery) Close() {
instances := s.healthCheckHandler.Close() instances := s.healthCheckHandler.Close()
for _,instance:=range instances{ for _, instance := range instances {
instance.ChangeStatus(common.InstanceChecking,common.InstanceRun) instance.ChangeStatus(common.InstanceChecking, common.InstanceRun)
} }
} }
func (s *SourceDiscovery) CheckDriver(driverName string) bool { func (s *SourceDiscovery) CheckDriver(driverName string) bool {
if s.discovery == nil{ if s.discovery == nil {
return false return false
} }
if s.discovery.Driver() == driverName{ if s.discovery.Driver() == driverName {
return true return true
} }
return false return false
} }
func (s *SourceDiscovery) SetHealthConfig(conf *HealthCheckConfig) { func (s *SourceDiscovery) SetHealthConfig(conf *HealthCheckConfig) {
if conf==nil || !conf.IsHealthCheck { if conf == nil || !conf.IsHealthCheck {
s.Close() s.Close()
return return
} }
...@@ -63,21 +60,21 @@ func (s *SourceDiscovery) SetHealthConfig(conf *HealthCheckConfig) { ...@@ -63,21 +60,21 @@ func (s *SourceDiscovery) SetHealthConfig(conf *HealthCheckConfig) {
time.Duration(conf.TimeOutMill)*time.Millisecond) time.Duration(conf.TimeOutMill)*time.Millisecond)
} }
func (s *SourceDiscovery) GetApp(name string) (*common.Service,health.CheckHandler ,bool){ func (s *SourceDiscovery) GetApp(name string) (*common.Service, health.CheckHandler, bool) {
s.locker.RLock() s.locker.RLock()
service,has:=s.services[name] service, has := s.services[name]
s.locker.RUnlock() s.locker.RUnlock()
if has{ if has {
return service,s.healthCheckHandler,true return service, s.healthCheckHandler, true
} }
return nil, nil,false return nil, nil, false
} }
func (s*SourceDiscovery)SetServices(services []*common.Service) { func (s *SourceDiscovery) SetServices(services []*common.Service) {
serviceMap := make(map[string]*common.Service) serviceMap := make(map[string]*common.Service)
for _,se:=range services{ for _, se := range services {
serviceMap[se.Name] = se serviceMap[se.Name] = se
} }
...@@ -88,18 +85,19 @@ func (s*SourceDiscovery)SetServices(services []*common.Service) { ...@@ -88,18 +85,19 @@ func (s*SourceDiscovery)SetServices(services []*common.Service) {
} }
var ErrorEmptyDiscovery = errors.New("discovery is nil") var ErrorEmptyDiscovery = errors.New("discovery is nil")
func NewSource(name string,d Discovery) (*SourceDiscovery ,error){
if d==nil || reflect.ValueOf(d).IsNil(){ func NewSource(name string, d Discovery) (*SourceDiscovery, error) {
return nil,ErrorEmptyDiscovery
if d == nil || reflect.ValueOf(d).IsNil() {
return nil, ErrorEmptyDiscovery
} }
s:=&SourceDiscovery{ s := &SourceDiscovery{
name:name, name: name,
discovery:d, discovery: d,
healthCheckHandler:new(health.CheckBox), healthCheckHandler: new(health.CheckBox),
services:make(map[string]*common.Service), services: make(map[string]*common.Service),
locker:sync.RWMutex{}, locker: sync.RWMutex{},
} }
//services, e := d.GetServers() //services, e := d.GetServers()
...@@ -111,5 +109,5 @@ func NewSource(name string,d Discovery) (*SourceDiscovery ,error){ ...@@ -111,5 +109,5 @@ func NewSource(name string,d Discovery) (*SourceDiscovery ,error){
d.SetCallback(s.SetServices) d.SetCallback(s.SetServices)
return s,d.Open() return s, d.Open()
} }
...@@ -5,13 +5,11 @@ import ( ...@@ -5,13 +5,11 @@ import (
) )
type Driver struct { type Driver struct {
} }
func (d *Driver) Open(name string,config string)(discovery.ISource,error) { func (d *Driver) Open(name string, config string) (discovery.ISource, error) {
panic("implement me") panic("implement me")
} }
type ConsulKeyValueDiscovery struct { type ConsulKeyValueDiscovery struct {
} }
...@@ -3,7 +3,9 @@ package consul_kv ...@@ -3,7 +3,9 @@ package consul_kv
import ( import (
"github.com/eolinker/goku/goku-service/discovery" "github.com/eolinker/goku/goku-service/discovery"
) )
const DriverName = "consulKv" const DriverName = "consulKv"
func init() { func init() {
discovery.RegisteredDiscovery(DriverName,new(Driver)) discovery.RegisteredDiscovery(DriverName, new(Driver))
} }
...@@ -35,8 +35,6 @@ func (d *ConsulDiscovery) SetConfig(config string) error { ...@@ -35,8 +35,6 @@ func (d *ConsulDiscovery) SetConfig(config string) error {
} }
d.client = client d.client = client
return nil return nil
} }
...@@ -99,7 +97,7 @@ func (d *ConsulDiscovery) GetServicesInTime() (map[string][]string, map[string][ ...@@ -99,7 +97,7 @@ func (d *ConsulDiscovery) GetServicesInTime() (map[string][]string, map[string][
catalogServices := make(map[string][]*api.ServiceEntry) catalogServices := make(map[string][]*api.ServiceEntry)
for serviceName := range services { for serviceName := range services {
cs, _, err := d.client.Health().Service(serviceName, "",true, q) cs, _, err := d.client.Health().Service(serviceName, "", true, q)
if err != nil { if err != nil {
log.Info(err.Error()) log.Info(err.Error())
continue continue
...@@ -159,7 +157,7 @@ func (d *ConsulDiscovery) execCallbacks(services map[string][]string, catalogSer ...@@ -159,7 +157,7 @@ func (d *ConsulDiscovery) execCallbacks(services map[string][]string, catalogSer
for appName, catalogInstances := range catalogServices { for appName, catalogInstances := range catalogServices {
size := len(catalogInstances) size := len(catalogInstances)
if size == 0{ if size == 0 {
continue continue
} }
hosts := make([]*common.Instance, size) hosts := make([]*common.Instance, size)
......
...@@ -3,13 +3,15 @@ package consul ...@@ -3,13 +3,15 @@ package consul
import ( import (
"github.com/eolinker/goku/goku-service/discovery" "github.com/eolinker/goku/goku-service/discovery"
) )
const DriverName = "consul" const DriverName = "consul"
func init() { func init() {
discovery.RegisteredDiscovery(DriverName,discovery.NewDriver(Create)) discovery.RegisteredDiscovery(DriverName, discovery.NewDriver(Create))
} }
func Create(config string)discovery.Discovery { func Create(config string) discovery.Discovery {
return NewConsulDiscovery(config) return NewConsulDiscovery(config)
} }
...@@ -16,7 +16,6 @@ import ( ...@@ -16,7 +16,6 @@ import (
) )
type Eureka struct { type Eureka struct {
services []*common.Service services []*common.Service
//AppNames map[string]string //AppNames map[string]string
eurekaUrl []string eurekaUrl []string
...@@ -27,21 +26,20 @@ type Eureka struct { ...@@ -27,21 +26,20 @@ type Eureka struct {
instanceFactory *common.InstanceFactory instanceFactory *common.InstanceFactory
} }
func (d *Eureka) SetConfig(config string) error { func (d *Eureka) SetConfig(config string) error {
tags:=strings.Split(config,";") tags := strings.Split(config, ";")
weightKey := "" weightKey := ""
if len(tags)>1{ if len(tags) > 1 {
weightKey=tags[1] weightKey = tags[1]
} }
urls:=strings.Split(tags[0],",") urls := strings.Split(tags[0], ",")
d.setConfig(urls,weightKey) d.setConfig(urls, weightKey)
return nil return nil
} }
func (d *Eureka)setConfig(eurekaUrl []string,weightKey string) { func (d *Eureka) setConfig(eurekaUrl []string, weightKey string) {
d.eurekaUrl = eurekaUrl d.eurekaUrl = eurekaUrl
d.weightKey = weightKey d.weightKey = weightKey
} }
...@@ -54,11 +52,11 @@ func (d *Eureka) SetCallback(callback func(services []*common.Service)) { ...@@ -54,11 +52,11 @@ func (d *Eureka) SetCallback(callback func(services []*common.Service)) {
} }
func (d *Eureka) GetServers() ([]*common.Service, error) { func (d *Eureka) GetServers() ([]*common.Service, error) {
return d.services,nil return d.services, nil
} }
func (d *Eureka) Close() error { func (d *Eureka) Close() error {
if d.cancelFunc !=nil{ if d.cancelFunc != nil {
d.cancelFunc() d.cancelFunc()
d.cancelFunc = nil d.cancelFunc = nil
} }
...@@ -66,12 +64,12 @@ func (d *Eureka) Close() error { ...@@ -66,12 +64,12 @@ func (d *Eureka) Close() error {
} }
func (d *Eureka) Open() error { func (d *Eureka) Open() error {
d.ScheduleAtFixedRate(time.Second*5) d.ScheduleAtFixedRate(time.Second * 5)
return nil return nil
} }
func NewEurekaDiscovery(config string) *Eureka { func NewEurekaDiscovery(config string) *Eureka {
e:= &Eureka{ e := &Eureka{
services: nil, services: nil,
callback: nil, callback: nil,
ct: 0, ct: 0,
...@@ -82,45 +80,44 @@ func NewEurekaDiscovery(config string) *Eureka { ...@@ -82,45 +80,44 @@ func NewEurekaDiscovery(config string) *Eureka {
return e return e
} }
func (d *Eureka) execCallbacks(apps *Applications) { func (d *Eureka) execCallbacks(apps *Applications) {
if d.callback == nil{ if d.callback == nil {
return return
} }
if apps ==nil{ if apps == nil {
d.callback(nil) d.callback(nil)
return return
} }
if len(apps.Applications) == 0{ if len(apps.Applications) == 0 {
d.callback(nil) d.callback(nil)
return return
} }
services:=make([]*common.Service,0,len(apps.Applications)) services := make([]*common.Service, 0, len(apps.Applications))
for _,app:=range apps.Applications{ for _, app := range apps.Applications {
inses:= make([]*common.Instance,0,len(app.Instances)) inses := make([]*common.Instance, 0, len(app.Instances))
for _,ins:=range app.Instances{ for _, ins := range app.Instances {
if ins.Status != EurekaStatusUp{ if ins.Status != EurekaStatusUp {
continue continue
} }
weight:= 0 weight := 0
if w,has:=ins.Metadata.Map[d.weightKey];has{ if w, has := ins.Metadata.Map[d.weightKey]; has {
weight,_ = strconv.Atoi(w) weight, _ = strconv.Atoi(w)
} }
if weight == 0{ if weight == 0 {
weight = 1 weight = 1
} }
port:= 0 port := 0
if ins.Port.Enabled{ if ins.Port.Enabled {
port = ins.Port.Port port = ins.Port.Port
} else if ins.SecurePort.Enabled{ } else if ins.SecurePort.Enabled {
port = ins.SecurePort.Port port = ins.SecurePort.Port
} }
inses = append(inses, d.instanceFactory.General(ins.IpAddr, port,weight)) inses = append(inses, d.instanceFactory.General(ins.IpAddr, port, weight))
} }
server:=common.NewService(app.Name,inses) server := common.NewService(app.Name, inses)
services = append(services,server) services = append(services, server)
} }
d.callback(services) d.callback(services)
...@@ -129,17 +126,17 @@ func (d *Eureka) execCallbacks(apps *Applications) { ...@@ -129,17 +126,17 @@ func (d *Eureka) execCallbacks(apps *Applications) {
func (d *Eureka) ScheduleAtFixedRate(second time.Duration) { func (d *Eureka) ScheduleAtFixedRate(second time.Duration) {
d.run() d.run()
if d.cancelFunc !=nil{ if d.cancelFunc != nil {
d.cancelFunc() d.cancelFunc()
d.cancelFunc = nil d.cancelFunc = nil
} }
ctx,cancel:=context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
d.cancelFunc = cancel d.cancelFunc = cancel
go d.runTask(second,ctx) go d.runTask(second, ctx)
} }
func (d *Eureka) runTask(second time.Duration,ctx context.Context) { func (d *Eureka) runTask(second time.Duration, ctx context.Context) {
timer := time.NewTicker(second) timer := time.NewTicker(second)
for { for {
select { select {
...@@ -164,11 +161,11 @@ func (d *Eureka) run() { ...@@ -164,11 +161,11 @@ func (d *Eureka) run() {
func (d *Eureka) GetApplications() (*Applications, error) { func (d *Eureka) GetApplications() (*Applications, error) {
//url := c.eurekaUrl + "/apps" //url := c.eurekaUrl + "/apps"
url, err:= d.getEurekaServerUrl() url, err := d.getEurekaServerUrl()
if err!= nil{ if err != nil {
return nil,err return nil, err
} }
url = fmt.Sprintf("%s/apps",url) url = fmt.Sprintf("%s/apps", url)
res, err := http.Get(url) res, err := http.Get(url)
if err != nil { if err != nil {
...@@ -190,20 +187,20 @@ func (d *Eureka) GetApplications() (*Applications, error) { ...@@ -190,20 +187,20 @@ func (d *Eureka) GetApplications() (*Applications, error) {
return applications, err return applications, err
} }
func (d *Eureka) getEurekaServerUrl()( string ,error){ func (d *Eureka) getEurekaServerUrl() (string, error) {
ct := atomic.AddUint64(&d.ct, 1) ct := atomic.AddUint64(&d.ct, 1)
size := len(d.eurekaUrl) size := len(d.eurekaUrl)
if size == 0 { if size == 0 {
e:= NilPointError("eureka url is empty") e := NilPointError("eureka url is empty")
return "",e return "", e
} }
index := int(ct) % size index := int(ct) % size
url := d.eurekaUrl[index] url := d.eurekaUrl[index]
//if strings.LastIndex(url,"/")>-1{ //if strings.LastIndex(url,"/")>-1{
url = strings.TrimSuffix(url, "/") url = strings.TrimSuffix(url, "/")
//} //}
return url,nil return url, nil
} }
func (d *Eureka) Health() (bool, string) { func (d *Eureka) Health() (bool, string) {
......
...@@ -3,11 +3,13 @@ package eureka ...@@ -3,11 +3,13 @@ package eureka
import ( import (
"github.com/eolinker/goku/goku-service/discovery" "github.com/eolinker/goku/goku-service/discovery"
) )
const DriverName = "eureka" const DriverName = "eureka"
const EurekaStatusUp ="UP" const EurekaStatusUp = "UP"
func init() { func init() {
discovery.RegisteredDiscovery(DriverName,discovery.NewDriver(Create)) discovery.RegisteredDiscovery(DriverName, discovery.NewDriver(Create))
} }
func Create(config string) discovery.Discovery { func Create(config string) discovery.Discovery {
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册