夜鶯修改日志


前端代碼


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


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

二. 修改內(nèi)容

1.添加接口查詢功能

2.修改頁(yè)面圖標(biāo)和公司名稱

3.添加報(bào)警提示音

三. 代碼修改記錄

  • common/request.tsx
//新增
if (!data) {
    return data;
  }
  if(data.notify_type){
    return data;
  }
  • components/Layout/index.tsx
//新增定時(shí)任務(wù) 提示報(bào)警信息
    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)報(bào)警消恍,   ip為"+res.event.endpoint+"    錯(cuò)誤為"+res.event.sname);   
            new Audio(url).play()
          }
        }
      });
      
    },60000)
  • interface/index.tsx
//interface返回參數(shù)新增notify_type屬性
notify_type:any | ResponseDat,
  • locales/zh.ts
//新增接口頁(yè)面屬性名
'collect.api': '接口',
'collect.api.name': '接口',
'collect.api.name.placeholder': 'http://xxx.xxxx.xxx/xxx',
'collect.api.ip': '主機(jī)ip',
'collect.api.ip.placeholder': '192.168.0.1',
  • pages/Monitor
    • Collect
      • CollectForm
        • APIForm.tsx
         //整頁(yè)新增
        
        • index.tsx
         //新增頁(yè)面
         export default {
           log: LOGForm,
           port: PORTForm,
           proc: PROCForm,
           plugin: PLUGINForm,
           api:APIForm, //新增
        };
        
      • config.tsx
       //typeMap新增api接口屬性
       export const typeMap: any = {
        log: '日志',
        port: '端口',
        proc: '進(jìn)程',
        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         //警報(bào)結(jié)構(gòu)體
- etc             //配置文件
- redisc          //redis操作方法

二. 修改內(nèi)容

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

2.對(duì)外暴露一個(gè)報(bào)警信息查詢接口车伞,接口用成功后刪除當(dāng)前報(bào)警信息

三. 修改記錄

  • cron/sender.go
//sendMail方法中新增
redisc.AddMessage(message)
  • redisc/poper.go
//新增兩個(gè)數(shù)據(jù)
/**
添加報(bào)警數(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
    
}

/**
查找報(bào)警數(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)聽(tīng)
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í)例數(shù)據(jù)
    - pgsqlInfo     //獲取pgsql實(shí)例數(shù)據(jù)
    - redisInfo     //獲取redis實(shí)例數(shù)據(jù)
    - stra          //采集配置結(jié)構(gòu)體
    - sys           //采集配置實(shí)現(xiàn)
    - util          //網(wǎng)絡(luò)請(qǐng)求工具包
    - 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
    //新增自定義插件運(yùn)行日志
    
    • yaml.go
    //新增自定義插件配置文件 
    //文件位置  etc/configuration.yml
    
  • nginxInfo
 //新增nginx.go文件
 //采集nginx實(shí)例
  • pgsqlInfo
 //新增pgsql.go文件
 //采集pgsql實(shí)例
  • redisInfo
 //新增redis.go文件
 //采集redis實(shí)例
  • sys
    -fengjiePlugins
    //新增cron.go
    //1.讀取自定義插件配置內(nèi)容
    //2.調(diào)用自定義插件采集方法
    
    • funcs
      • cron.go
      //該文件主要負(fù)責(zé)收集程序采集的數(shù)據(jù)并push到服務(wù)器
      //rpc 改用http 并發(fā)太高導(dǎo)致連接超時(shí)
      //修改方案:賦予每個(gè)并發(fā)請(qǐng)求一個(gè)隨機(jī)延遲
      //動(dòng)態(tài)判斷 進(jìn)行休眠
          b := rand.Intn(6000) //取隨機(jī)數(shù)
          time.Sleep(time.Duration(b/100) * time.Second) //睡眠相應(yīng)時(shí)間
      
      • push.go
      //新增 接口返回參數(shù)結(jié)構(gòu)體
      type reportRes struct {
        Err string `json:"err"`
        Dat string `json:"dat"`
      }
      //當(dāng)前方法先讀取配置文件中的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
    //給一個(gè)隨機(jī)延遲
    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í)例數(shù)據(jù)
    - pgsqlInfo     //獲取pgsql實(shí)例數(shù)據(jù)
    - redisInfo     //獲取redis實(shí)例數(shù)據(jù)
    - stra          //采集配置結(jié)構(gòu)體
    - sys           //采集配置實(shí)現(xiàn)
    - util          //網(wǎng)絡(luò)請(qǐng)求工具包
    - collector.go  //入口

二. 修改內(nèi)容

1.新增接口定時(shí)查詢功能

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

三. 修改記錄

  • stra/api.go
 //新增api.go文件
 //新增api結(jié)構(gòu)體和獲取用戶配置的接口列表
  • sys/apiTest
//新增api.go,cron.go,scheduler.go文件
//所有關(guān)于接口的函數(shù)都在這里
  • collector.go
//啟動(dòng)接口數(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é)點(diǎn)下策略名稱 %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
    
          //校驗(yàn)采集是否存在
          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é)點(diǎn)下策略名稱 %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)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末日矫,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子绑榴,更是在濱河造成了極大的恐慌哪轿,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件翔怎,死亡現(xiàn)場(chǎng)離奇詭異窃诉,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)赤套,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門飘痛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人容握,你說(shuō)我怎么就攤上這事宣脉。” “怎么了剔氏?”我有些...
    開封第一講書人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵塑猖,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我谈跛,道長(zhǎng)羊苟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任感憾,我火速辦了婚禮蜡励,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己巍虫,他們只是感情好彭则,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著占遥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪输瓜。 梳的紋絲不亂的頭發(fā)上瓦胎,一...
    開封第一講書人閱讀 51,462評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音尤揣,去河邊找鬼搔啊。 笑死,一個(gè)胖子當(dāng)著我的面吹牛北戏,可吹牛的內(nèi)容都是我干的负芋。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼嗜愈,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼旧蛾!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起蠕嫁,我...
    開封第一講書人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤锨天,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后剃毒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體病袄,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年赘阀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了益缠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡基公,死狀恐怖幅慌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情酌媒,我是刑警寧澤欠痴,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站秒咨,受9級(jí)特大地震影響喇辽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜雨席,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一菩咨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦抽米、人聲如沸特占。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)是目。三九已至,卻和暖如春标捺,著一層夾襖步出監(jiān)牢的瞬間懊纳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工亡容, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嗤疯,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓闺兢,卻偏偏與公主長(zhǎng)得像茂缚,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子屋谭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354