func registerToConfigServer() error { substrs := strings.SplitN(cmddConfig.ListenAddr, ":", 2) ip, port := substrs[0], substrs[1] if ip == "" { conn, err := net.Dial("udp", "baidu.com:80") if err != nil { cmdlog.EPrintln(err.Error()) return err } //fmt.Printf("client addr :%s\n", conn.LocalAddr().String()) ip = strings.Split(conn.LocalAddr().String(), ":")[0] + ":" + port conn.Close() } else { ip = ip + ":" + port } //todo:register to config server. _, err := configClient.CreateDir(cmddConfig.ConfigDir, 0) if err != nil { cmdlog.EPrintln(err.Error()) } _, err = configClient.Set((cmddConfig.ConfigDir + "/" + ip), ip, 0) if err != nil { cmdlog.EPrintln(err.Error()) return err } return nil }
func SafeHandler(handler http.Handler) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { defer func() { if err, ok := recover().(error); ok { http.Error(w, err.Error(), http.StatusInternalServerError) cmdlog.EPrintln("WARN: panic in %v - %v", handler, err) cmdlog.EPrintln(string(debug.Stack())) } }() handler.ServeHTTP(w, req) } }
func statsHandler(mc *MgoCmd, req *cmdproto.MgoRequest) (res interface{}, err error) { result := make(map[string]interface{}) err = mc.mgoSession.DB(req.DB).Run(req.DBCmd.DBCmd, result) if err != nil { cmdlog.EPrintln(err.Error()) return } res, err = json.Marshal(result) if err != nil { cmdlog.EPrintln(err.Error()) return } return }
func dbMon(mc *MgoCmd, req *cmdproto.MgoRequest) { atomic.StoreInt32(&mc.dbMonState, 1) stop := false pingCount := 5 errCount := 0 var err error ticker := time.NewTicker(time.Second * 2) defer func() { ticker.Stop() atomic.StoreInt32(&mc.dbMonState, 0) }() dialInfo := &mgo.DialInfo{Addrs: mc.MgoAddrs, Timeout: (10 * time.Second)} mgoSession, err := mgo.DialWithInfo(dialInfo) mgoSession.SetSocketTimeout(time.Second * 10) addrs, _ := net.InterfaceAddrs() if err != nil { cmdlog.EPrintln(err.Error()) cmds.SendMail("mongod", fmt.Sprintf("[%s]---%+v---mongod ping failed, please notice!", time.Now().UTC().String(), addrs)) return } for { select { case <-ticker.C: for i := 0; i < pingCount; i++ { err = mgoSession.Ping() if err != nil { cmdlog.EPrintln(err.Error()) errCount++ } } if errCount == pingCount { for i := 0; i < 5; i++ { cmds.SendMail("mongod", fmt.Sprintf("[%s]---%+v---mongod ping failed, please notice!", time.Now().UTC().String(), addrs)) } errCount = 0 stop = true } } if stop == true { break } } }
func syscmdHandler(sc *SystemCmd, req *cmdproto.SysRequest) (interface{}, error) { cmdlog.Println(req) cmdType := strings.ToLower(req.Args[0]) cmd := exec.Command(cmdType, req.Args[1:]...) stdout, err := cmd.StdoutPipe() if err != nil { cmdlog.EPrintln(err.Error()) return nil, err } if err := cmd.Start(); err != nil { cmdlog.EPrintln(err.Error()) return nil, err } return stdout, nil }
func (mc *MgoCmd) Init(config interface{}) (err error) { mc.MgoCmdConfig = config.(*MgoCmdConfig) cmdlog.Printf("MgoCmd Init config :(%+v)\n", mc.MgoCmdConfig) mc.cmdHandlers = make(map[string]func(mc *MgoCmd, req *cmdproto.MgoRequest) (interface{}, error)) mc.cmdReqPool = make(chan *cmdproto.MgoRequest, mc.MgoReqPoolSize) //allocates fixed size request pool. for i := 0; i < mc.MgoReqPoolSize; i++ { mgoReq := &cmdproto.MgoRequest{} mc.cmdReqPool <- mgoReq } dialInfo := &mgo.DialInfo{Addrs: mc.MgoAddrs, Timeout: (500 * time.Millisecond)} mc.mgoSession, err = mgo.DialWithInfo(dialInfo) if err != nil { cmdlog.EPrintln(err.Error()) return err } mc.stopDiskMonCh = make(chan bool) mc.register("dbStats", statsHandler) mc.register("diskMonB", diskMonStartHandler) mc.register("diskMonE", diskMonEndHandler) mc.register("dbMonB", dbMonStartHandler) //mc.register("dbMonE", dbMonEndHandler) cmdlog.Printf("MgoCmd Init ok\n") return nil }
func (sc *SystemCmd) ServeHTTP(w http.ResponseWriter, req *http.Request) { data, err := ioutil.ReadAll(req.Body) if err != nil { cmdlog.EPrintf("%s\n", err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } cmdlog.Printf("%s\n", string(data)) defer req.Body.Close() sysReq := sc.getAvalibleReq() defer sc.recycle(sysReq) err = json.Unmarshal(data, sysReq) if err != nil { cmdlog.EPrintf("%s\n", err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } op := strings.ToLower(sysReq.Op) if handler, ok := sc.cmdHandlers[op]; ok { res, err := handler(sc, sysReq) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "text/plain; charset=utf-8") w.WriteHeader(http.StatusOK) switch res.(type) { case string: fmt.Fprintln(w, res.(string)) case []byte: fmt.Fprintln(w, string(res.([]byte))) case []string: fmt.Fprintln(w, res.([]string)) case int: fmt.Fprintln(w, res.(int)) case io.ReadCloser: stdout := res.(io.ReadCloser) defer stdout.Close() reader := bufio.NewReader(stdout) for { line, err := reader.ReadBytes('\n') if err != nil { cmdlog.EPrintf("err:%s\n", err.Error()) break } // fmt.Println("%s is executing...", sysReq.Op) fmt.Fprintf(w, "%s", string(line)) w.(http.Flusher).Flush() } } } else { cmdlog.EPrintln("method not implemented") http.Error(w, fmt.Sprintf("server do not support command %s", sysReq.Op), http.StatusNotImplemented) return } }
func diskMon(mc *MgoCmd, req *cmdproto.MgoRequest) { ticker := time.NewTicker(mc.DiskCheckInterval.Duration) stop := false collDays := 0 collName := "" percent := 100 var err1 error atomic.StoreInt32(&mc.diskMonState, 1) for { select { case <-mc.stopDiskMonCh: stop = true case <-ticker.C: //check if need to lru. ds := cmds.DiskUsage("/") percent = int(float64(ds.Free) / float64(ds.All) * 100) if percent < mc.MgoLRUGate { //cmdlog.Printf("mongodb is lru...\n") //do delete collections. names, err := mc.mgoSession.DB(req.DB).CollectionNames() if err != nil { cmdlog.EPrintln(err.Error()) continue } resNames := filterCollNames(names) for _, v := range resNames { collDays = len(v) for i := 0; i < collDays/3; i++ { collName = v[i] //cmdlog.Printf("mongodb drop collection %s\n", collName) err1 = mc.mgoSession.DB(req.DB).C(collName).DropCollection() if err1 != nil { cmdlog.EPrintln(err1.Error()) } } } } } if stop == true { ticker.Stop() atomic.StoreInt32(&mc.diskMonState, 0) break } } }
func InitHandlerConf(confs map[string]toml.Primitive, md *toml.MetaData) error { var err error for k, handler := range CmdHandlers { if conf, ok := confs[k]; ok { handlerConf := handler.ConfigStruct() err = md.PrimitiveDecode(conf, handlerConf) if err != nil { cmdlog.EPrintln(err.Error()) return err } err = handler.Init(handlerConf) if err != nil { cmdlog.EPrintln(err.Error()) return err } } } return err }
func (scc *ServiceCtrlCmd) ServeHTTP(w http.ResponseWriter, req *http.Request) { data, err := ioutil.ReadAll(req.Body) if err != nil { cmdlog.EPrintf("%s\n", err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } cmdlog.Printf("%s\n", string(data)) defer req.Body.Close() scReq := scc.getAvalibleReq() defer scc.recycle(scReq) err = json.Unmarshal(data, scReq) if err != nil { cmdlog.EPrintf("%s\n", err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } if handler, ok := scc.cmdHandlers[scReq.Op]; ok { res, err := handler(scc, scReq) if err != nil { cmdlog.EPrintf("%s\n", err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "text/plain; charset=utf-8") w.WriteHeader(http.StatusOK) //fmt.Fprintln(w, error) switch res.(type) { case string: fmt.Fprintln(w, res.(string)) case []byte: fmt.Fprintln(w, string(res.([]byte))) case []string: fmt.Fprintln(w, res.([]string)) case int: fmt.Println(w, res.(int)) } } else { cmdlog.EPrintln("method not implemented") http.Error(w, fmt.Sprintf("server do not support command %s", scReq.Op), http.StatusNotImplemented) return } }