夜鶯修改日志


前端代碼


一. 代碼結(jié)構(gòu)


- config: 開發(fā) & 構(gòu)建配置
  - proxy.config.js:代理配置
  - theme.js:antd 主題配置
  - webpack.config.js:webpack 開發(fā)環(huán)境補充配置,覆蓋默認配置
  - webpack.build.config.js:webpack 構(gòu)建補充配置,覆蓋默認配置
  - webpack.build.config.js:webpack dll補充配置,覆蓋默認配置
  - webpackConfigResolveAlias.js 文件路徑別名配置
- src:源代碼所在目錄
  - assets:全局資源 img、css
  - common: 全局配置、通用方法
  - components:公共組件
  - pages:路由匹配的頁面組件
  - app.jsx 菜單、路由配置組件
  - index.html:單頁
  - index.jsx:入口文件
  - fetk.config.js 開發(fā)工具配置頁面

二. 修改內(nèi)容

1.添加接口查詢功能

2.修改頁面圖標和公司名稱

3.添加報警提示音

三. 代碼修改記錄

  • common/request.tsx
//新增
if (!data) {
    return data;
  }
  if(data.notify_type){
    return data;
  }
  • components/Layout/index.tsx
//新增定時任務(wù) 提示報警信息
    this.timerID =self.setInterval(()=>{
      request("/api/alarm").then((res: any) => {
        console.log(res);
        console.log("查詢");
        if(res){
          if(res.event.endpoint){
            message.warn(res.event.sname);
            var url= "http://tts.baidu.com/text2audio?lan=zh&ie=UTF-8&spd=5&text=" + encodeURI("創(chuàng)林監(jiān)控系統(tǒng)報警,   ip為"+res.event.endpoint+"    錯誤為"+res.event.sname);   
            new Audio(url).play()
          }
        }
      });
      
    },60000)
  • interface/index.tsx
//interface返回參數(shù)新增notify_type屬性
notify_type:any | ResponseDat,
  • locales/zh.ts
//新增接口頁面屬性名
'collect.api': '接口',
'collect.api.name': '接口',
'collect.api.name.placeholder': 'http://xxx.xxxx.xxx/xxx',
'collect.api.ip': '主機ip',
'collect.api.ip.placeholder': '192.168.0.1',
  • pages/Monitor
    • Collect
      • CollectForm
        • APIForm.tsx
         //整頁新增
        
        • index.tsx
         //新增頁面
         export default {
           log: LOGForm,
           port: PORTForm,
           proc: PROCForm,
           plugin: PLUGINForm,
           api:APIForm, //新增
        };
        
      • config.tsx
       //typeMap新增api接口屬性
       export const typeMap: any = {
        log: '日志',
        port: '端口',
        proc: '進程',
        plugin: '插件',
        api:'接口'//新增屬性
      };
      
    • Dashboard
      • config.tsx
        //metricMap新增redis,nginx,pgsql分類
        nginx: {
          key: 'nginx',
          alias: 'nginx',
          dynamic: true,
          filter: { type: 'prefix', value: 'nginx.,NGINX.' },
        },
        pgsql: {
          key: 'pgsql',
          alias: 'pgsql',
          dynamic: true,
          filter: { type: 'prefix', value: 'pgsql.,PGSQL.' },
        },
        redis: {
          key: 'redis',
          alias: 'redis',
          dynamic: true,
          filter: { type: 'prefix', value: 'redis.,Redis.' },
        },
      
      • MetricSelect.tsx
       //新增采集數(shù)據(jù)信息提示
       title={() => {
          const currentMetricMeta = getCurrentMetricMeta(metric);
           if (currentMetricMeta) {
             return (
                <div>
                   <p>含義:{currentMetricMeta.meaning}</p>
                   <p>單位:{currentMetricMeta.unit}</p>
                </div>
             );
           }
        return '';
      }}
      

郵件服務(wù)


一. 代碼結(jié)構(gòu)

- mail-sender
- config          //配置
- cron            //發(fā)送數(shù)據(jù)
- dataobj         //警報結(jié)構(gòu)體
- etc             //配置文件
- redisc          //redis操作方法

二. 修改內(nèi)容

1.在報警郵件發(fā)送前向Redis存儲報警信息

2.對外暴露一個報警信息查詢接口,接口用成功后刪除當前報警信息

三. 修改記錄

  • cron/sender.go
//sendMail方法中新增
redisc.AddMessage(message)
  • redisc/poper.go
//新增兩個數(shù)據(jù)
/**
添加報警數(shù)據(jù)
 */
func AddMessage(message *dataobj.Message) (string,error) {
    var lst []*dataobj.Message
    rc := RedisConnPool.Get()
    defer rc.Close()
    reply, err := redis.String(rc.Do("GET", "alarm-message"))
    if err != nil {
        if err != redis.ErrNil {
            logger.Errorf("rpop queue:%s failed, err: %v", "alarm-message", err)
        }
    }
    if reply == "" || reply == "nil" {
        //讀取到的是空 新增alarm-message數(shù)據(jù)
        lst=append(lst,message)

    }else{
        err = json.Unmarshal([]byte(reply), &lst)
        if err != nil {
            logger.Errorf("unmarshal message failed, err: %v, redis reply: %v", err, reply)
            return "json轉(zhuǎn)換失敗", err
        }
        lst=append(lst,message)
    }
    jsonArr,err:=json.Marshal(lst)
    if err != nil {
        logger.Errorf("unmarshal message failed, err: %v, redis reply: %v", err, reply)
        return "json轉(zhuǎn)換失敗", err
    }

    setres,err:=redis.String(rc.Do("SET","alarm-message",jsonArr))
    if err != nil {
        logger.Errorf("unmarshal message failed, err: %v, redis reply: %v", err, reply)
        return "json轉(zhuǎn)換失敗", err
    }
    if(setres=="" || setres=="nil"){
        logger.Errorf("返回空")
    }
    return "ok", nil
    
}

/**
查找報警數(shù)據(jù)
 */
func FindMessage()   (*dataobj.Message,error){
    var lst []*dataobj.Message
    rc := RedisConnPool.Get()
    defer rc.Close()
    reply, err := redis.String(rc.Do("GET", "alarm-message"))
    if err != nil {
        if err != redis.ErrNil {
            logger.Errorf("rpop queue:%s failed, err: %v", "alarm-message", err)
        }
        return nil, err
    }
    if reply == "" || reply == "nil" {
        //讀取到的是空 新增alarm-message數(shù)據(jù)
        return nil, err

    } else{
        err = json.Unmarshal([]byte(reply), &lst)
        if err != nil {
            logger.Errorf("unmarshal message failed, err: %v, redis reply: %v", err, reply)
            return nil, err
        }
        if(len(lst)<=0){
            return nil, err
        }

        res :=lst[0]
        lst=lst[1:len(lst)]
        jsonArr,err:=json.Marshal(lst)
        if err != nil {
            logger.Errorf("unmarshal message failed, err: %v, redis reply: %v", err, reply)
            return nil, err
        }
        //刪除
        del,err := redis.Bool(rc.Do("DEL","alarm-message"))
        if err != nil {
            logger.Errorf("unmarshal message failed, err: %v, redis reply: %v", err, reply)
            return nil, err
        }
        fmt.Println(del)
        //設(shè)置message
        setres,err:=redis.String(rc.Do("SET","alarm-message",jsonArr))
        if err != nil {
            logger.Errorf("unmarshal message failed, err: %v, redis reply: %v", err, reply)
            return nil, err
        }
        if(setres=="" || setres=="nil"){
            logger.Errorf("返回空")
        }
        return res, nil

    }
}
  • main.go
//main函數(shù)下新增端口監(jiān)聽
http.HandleFunc("/", indexHandler)
    port := os.Getenv("PORT")
    if port == "" {
        port = "8082"
        log.Printf("Defaulting to port %s", port)
    }
    log.Printf("Listening on port %s", port)
    log.Printf("Open http://localhost:%s in the browser", port)
    log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))

//新增接口路由
func indexHandler(w http.ResponseWriter, r *http.Request) {
    if r.URL.Path == "/" {
        _, err := fmt.Fprint(w, "Hello, World!````````` ")
        if err != nil {
            w.WriteHeader(http.StatusInternalServerError)
        }
    }
    if r.URL.Path == "/api/alarm" {
        res,err:=redisc.FindMessage()
        b,err:=json.Marshal(res)
        if err != nil {
            fmt.Println("失敗")
        }
        w.Header().Set("Content-Type","application/json; charset=utf-8")
        w.Header().Set("Content-Length", strconv.Itoa(len(b)))
        w.Write(b)

    }else {
        http.NotFound(w, r)
        return
    }

客戶端collector


一. 代碼結(jié)構(gòu)

  - collector
    - cache 
    - config        //結(jié)構(gòu)體配置文件
    - http          //api接口配置
    - log
    - nginxInfo     //獲取nginx實例數(shù)據(jù)
    - pgsqlInfo     //獲取pgsql實例數(shù)據(jù)
    - redisInfo     //獲取redis實例數(shù)據(jù)
    - stra          //采集配置結(jié)構(gòu)體
    - sys           //采集配置實現(xiàn)
    - util          //網(wǎng)絡(luò)請求工具包
    - collector.go  //入口

二. 修改內(nèi)容

1.添加Redis數(shù)據(jù)監(jiān)控

2.添加Pgsql數(shù)據(jù)監(jiān)控

3.添加nginx數(shù)據(jù)監(jiān)控

4.rpc數(shù)據(jù)交互改為http數(shù)據(jù)交互

三. 代碼修改記錄

  • config
    • data.go
    //新增data.go文件
    //夜鶯插件提交規(guī)范結(jié)構(gòu)體
    
    • log.go
    //新增自定義插件運行日志
    
    • yaml.go
    //新增自定義插件配置文件 
    //文件位置  etc/configuration.yml
    
  • nginxInfo
 //新增nginx.go文件
 //采集nginx實例
  • pgsqlInfo
 //新增pgsql.go文件
 //采集pgsql實例
  • redisInfo
 //新增redis.go文件
 //采集redis實例
  • sys
    -fengjiePlugins
    //新增cron.go
    //1.讀取自定義插件配置內(nèi)容
    //2.調(diào)用自定義插件采集方法
    
    • funcs
      • cron.go
      //該文件主要負責收集程序采集的數(shù)據(jù)并push到服務(wù)器
      //rpc 改用http 并發(fā)太高導致連接超時
      //修改方案:賦予每個并發(fā)請求一個隨機延遲
      //動態(tài)判斷 進行休眠
          b := rand.Intn(6000) //取隨機數(shù)
          time.Sleep(time.Duration(b/100) * time.Second) //睡眠相應時間
      
      • push.go
      //新增 接口返回參數(shù)結(jié)構(gòu)體
      type reportRes struct {
        Err string `json:"err"`
        Dat string `json:"dat"`
      }
      //當前方法先讀取配置文件中的openRpc屬性判斷是否啟用rpc
      openRpc:=address.GetOpenRpc("transfer")
      if(openRpc){
          //開啟openrpc
          fmt.Println("openrpc")
          count := len(addrs)
          retry := 0
          for {
              for _, i := range rand.Perm(count) {
                  addr := addrs[i]
                  logger.Error("Push"+addr)
                  reply, err := rpcCall(addr, items)
                  if err != nil {
                      logger.Error(err)
                      continue
                  } else {
                      if reply.Msg != "ok" {
                          err = fmt.Errorf("some item push err: %s", reply.Msg)
                          logger.Error(err)
                      }
                      return err
                  }
              }
      
              time.Sleep(time.Millisecond * 500)
      
              retry += 1
              if retry == 3 {
                  break
              }
          }
      }else {
          //http提交數(shù)據(jù)
          url:=address.GetApi("transfer")
          var res reportRes
          err := httplib.Post(url).JSONBodyQuiet(items).SetTimeout(2000 * time.Millisecond).ToJSON(&res)
          if err != nil {
              logger.Errorf("curl %s fail: %v", url, err)
              fmt.Println("curl %s fail: %v", url, err)
              fmt.Println(items[0].Metric)
      
          }
          if res.Err != "" {
              logger.Error(res.Err)
          }
      }
      
    • plugins | ports | procs
    //修改scheduler.go
    //給一個隨機延遲
    b := rand.Intn(10000)
    time.Sleep(time.Duration(b/1000) * time.Second)
    

-collector.go

//調(diào)用自定義插件采集方法
//自定義插件采集
fengjiePlugins.Detect()

服務(wù)端collector


一. 代碼結(jié)構(gòu)

  - collector
    - cache 
    - config        //結(jié)構(gòu)體配置文件
    - http          //api接口配置
    - log
    - nginxInfo     //獲取nginx實例數(shù)據(jù)
    - pgsqlInfo     //獲取pgsql實例數(shù)據(jù)
    - redisInfo     //獲取redis實例數(shù)據(jù)
    - stra          //采集配置結(jié)構(gòu)體
    - sys           //采集配置實現(xiàn)
    - util          //網(wǎng)絡(luò)請求工具包
    - collector.go  //入口

二. 修改內(nèi)容

1.新增接口定時查詢功能

2.接口返回是否正常使用原rpc數(shù)據(jù)上報功能

三. 修改記錄

  • stra/api.go
 //新增api.go文件
 //新增api結(jié)構(gòu)體和獲取用戶配置的接口列表
  • sys/apiTest
//新增api.go,cron.go,scheduler.go文件
//所有關(guān)于接口的函數(shù)都在這里
  • collector.go
//啟動接口數(shù)據(jù)采集
apiTest.Detect()

服務(wù)端monapi


一. 代碼結(jié)構(gòu)

- monapi
  - config
  - cron
  - http
  - mcache
  - notify
  - redisc
  - scache

二. 修改內(nèi)容

1.新增查詢所有采集配置為api的數(shù)據(jù)列表

2.修改采集配置創(chuàng)建接囗,新增api分類屬性

3.mode 包下collet文件新增結(jié)構(gòu)體ApiCollect,并新增添加,刪除,更新,查詢方法

三. 修改記錄

  • http/routes
    • collect.go
    //collectPost方法下新增 api分類
    case "api":
              collect := new(model.ApiCollect)
    
              b, err := json.Marshal(obj.Data)
              if err != nil {
                  errors.Bomb("marshal body %s err:%v", obj, err)
              }
    
              err = json.Unmarshal(b, collect)
              if err != nil {
                  errors.Bomb("unmarshal body %s err:%v", string(b), err)
              }
    
              collect.Creator = creator
              collect.LastUpdator = creator
    
              nid := collect.Nid
              name := collect.Name
              old, _ := model.GetCollectByName(obj.Type, name)
              if old != nil && int64(old.(map[string]interface{})["nid"].(float64)) == nid {
                  errors.Bomb("同節(jié)點下策略名稱 %s 已存在", name)
              }
              errors.Dangerous(model.CreateCollect(obj.Type, creator, collect))
    
    //給types數(shù)組新增api屬性
    types := []string{"port", "proc", "log", "plugin","api"}
    
    //新增獲取所有api的方法
    func collectsGetApiAll(c *gin.Context)  {
      collects, err := model.GetApiCollect()
      if err != nil {
          logger.Warning("api", err)
      }
    
      if err == nil {
          c.JSON(200, gin.H{"dat": collects, "err": ""})
          return
      }
    
      renderMessage(c, err.Error())
    }
    
    //collectPut方法下新增
    case "api":
          collect := new(model.ApiCollect)
    
          b, err := json.Marshal(recv.Data)
          if err != nil {
              errors.Bomb("marshal body %s err:%v", recv, err)
          }
    
          err = json.Unmarshal(b, collect)
          if err != nil {
              errors.Bomb("unmarshal body %s err:%v", string(b), err)
          }
    
          nid := collect.Nid
          name := collect.Name
    
          //校驗采集是否存在
          obj, err := model.GetCollectById(recv.Type, collect.Id) //id找不到的情況
          if err != nil {
              errors.Bomb("采集不存在 type:%s id:%d", recv.Type, collect.Id)
          }
    
          tmpId := obj.(*model.ApiCollect).Id
          if tmpId == 0 {
              errors.Bomb("采集不存在 type:%s id:%d", recv.Type, collect.Id)
          }
    
          collect.Creator = creator
          collect.LastUpdator = creator
    
          old, _ := model.GetCollectByName(recv.Type, name)
          if old != nil && int64(old.(map[string]interface{})["nid"].(float64)) == nid &&
              tmpId != collect.Id {
              errors.Bomb("同節(jié)點下策略名稱 %s 已存在", name)
          }
    
          errors.Dangerous(collect.Update())
          renderData(c, "ok", nil)
          return
    
    • routes.go
    //新增不需要鑒權(quán)的接口
    api := r.Group("/api/portal")
      {
          api.GET("/collect/apiAllList", collectsGetApiAll)
      }
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容