dataMonitor.go 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997
  1. package monitor
  2. import (
  3. "fmt"
  4. "log"
  5. "math"
  6. "os"
  7. "os/exec"
  8. "regexp"
  9. "runtime"
  10. "scd_check_tools/conf"
  11. Db "scd_check_tools/db"
  12. "scd_check_tools/email"
  13. "scd_check_tools/global"
  14. "scd_check_tools/logger"
  15. "scd_check_tools/models/bo"
  16. "scd_check_tools/sms"
  17. "scd_check_tools/tools"
  18. "strconv"
  19. "strings"
  20. "sync"
  21. "time"
  22. "github.com/shirou/gopsutil/cpu"
  23. "github.com/shirou/gopsutil/disk"
  24. //"github.com/shirou/gopsutil/load"
  25. "github.com/shirou/gopsutil/mem"
  26. "github.com/astaxie/beego/orm"
  27. )
  28. type DataMonitor struct {
  29. performanceRuntimeMonitorState bool
  30. performanceRuntimeMonitorResult map[string]interface{}
  31. pmResultLock sync.RWMutex
  32. }
  33. var SignDataMonitor = new(DataMonitor)
  34. var DataMonitorMsgChan chan map[string]interface{}
  35. //设备数据处理监控
  36. func StartDataMonitor() {
  37. DataMonitorMsgChan = make(chan map[string]interface{}, 10)
  38. sendMsg := func() {
  39. log.Println("启动短信发送进程")
  40. for {
  41. msgdata, ok := <-DataMonitorMsgChan
  42. if ok {
  43. if msgdata != nil {
  44. smsplatform := conf.GlobalConfig["sms.platform"]
  45. if smsplatform == "" {
  46. log.Println("未配置短信消息发送平台")
  47. } else {
  48. smsSend := sms.GetSmsInstance(smsplatform)
  49. datatype := msgdata["datatype"].(string)
  50. params := msgdata["params"].([]string)
  51. phone := msgdata["phone"].([]string)
  52. if conf.GlobalConfig["loglevel"] == "5" {
  53. log.Println(fmt.Sprintf("%v", msgdata))
  54. }
  55. _, err := smsSend.Send(datatype, params, phone)
  56. if err != nil {
  57. log.Println(err)
  58. }
  59. }
  60. }
  61. }
  62. }
  63. }
  64. go sendMsg()
  65. go dataTimoutMonitorStart()
  66. go dataAlterMonitorStart()
  67. go performanceMonitorStart()
  68. go attachmentMonitorStart()
  69. go StartClearTempScd()
  70. go StateOptimizeTable()
  71. go func() {
  72. for {
  73. select {
  74. case v := <-global.PerformanceRuntimeMonitorChan:
  75. log.Println(fmt.Sprintf("=======================性能监测标识:%d", v))
  76. if v == 1 {
  77. go SignDataMonitor.PerformanceRuntimeMonitorStart()
  78. } else {
  79. go SignDataMonitor.PerformanceRuntimeMonitorStop()
  80. }
  81. }
  82. }
  83. log.Println(fmt.Sprintf("=======================性能监测终止"))
  84. }()
  85. }
  86. //启动每周数据表优化进程
  87. func StateOptimizeTable() {
  88. log.Println("启动每周数据表优化进程")
  89. for {
  90. nowDay, _ := strconv.Atoi(time.Now().Format("02"))
  91. nowHour := time.Now().Format("15")
  92. //每5天优化一次
  93. dbOptimizeMonitorIntervalDay, _ := bo.GetSysParamValue("dbOptimizeMonitorInterval", "5")
  94. dbOptimizeMonitorIntervalDayI, _ := strconv.Atoi(dbOptimizeMonitorIntervalDay)
  95. if nowHour != "02" || (nowDay%dbOptimizeMonitorIntervalDayI != 0) {
  96. time.Sleep(time.Hour * 1)
  97. continue
  98. }
  99. m := new(DataMonitor)
  100. m.OptimizeTable()
  101. time.Sleep(time.Hour * 1)
  102. }
  103. }
  104. //启动定时清理临时SCD数据进程
  105. //每小时清理一次
  106. func StartClearTempScd() {
  107. logger.Logger.Println("启动定时(每小时)清理临时SCD数据进程")
  108. for {
  109. m := new(DataMonitor)
  110. m.tempScdClear()
  111. time.Sleep(time.Minute * 60 * 24)
  112. }
  113. }
  114. //数据采集超时处理进程启动
  115. func dataTimoutMonitorStart() {
  116. log.Println("启动数据超时检查处理进程")
  117. }
  118. //设备告警监测进程启动
  119. func dataAlterMonitorStart() {
  120. log.Println("启动数据告警监测处理进程")
  121. }
  122. //常规性能监控.每1分钟监测一次
  123. func performanceMonitorStart() {
  124. log.Println("启动性能监控处理进程")
  125. var err error
  126. osname := string(runtime.GOOS)
  127. cpuHC, _ := strconv.Atoi(tools.IsEmpty(conf.GlobalConfig["alarm_cpu_value"], "90")) //cpu高耗用率
  128. memHC, _ := strconv.Atoi(tools.IsEmpty(conf.GlobalConfig["alarm_mem_value"], "90")) //内存高耗用率
  129. diskHCC, _ := strconv.Atoi(tools.IsEmpty(conf.GlobalConfig["alarm_disk_value"], "90")) //C磁盘高耗用率
  130. diskHCI := diskHCC //程序所在磁盘高耗用率
  131. cpuHC_lst := map[string]int{"ishc": 0, "hcnt": 0, "lcnt": 0}
  132. memHC_lst := map[string]int{"ishc": 0, "hcnt": 0, "lcnt": 0}
  133. diskHCC_lst := map[string]int{"ishc": 0, "hcnt": 0, "lcnt": 0}
  134. diskHCI_lst := map[string]int{"ishc": 0, "hcnt": 0, "lcnt": 0}
  135. thisIp, _ := tools.LocalIPv4()
  136. if thisIp != "" {
  137. thisIp = "[" + thisIp + "]"
  138. }
  139. appname := conf.GlobalConfig["appname"]
  140. //fmt.Println("======================IP:" + thisIp)
  141. db := orm.NewOrm()
  142. logalarming := false
  143. memalarming := false
  144. cpualarming := false
  145. diskalarming := false
  146. diskcalarming := false //c盘空间
  147. for {
  148. log_alarm_email, _ := bo.GetSysParamValue("log_alarm_email", "")
  149. go func() {
  150. //日志容量监测
  151. sql := "select round(sum(DATA_LENGTH/1024/1024),2) v from information_schema.tables where table_schema=? AND table_name='global_syslog'"
  152. spaceRowset := []orm.Params{}
  153. _, dberr := db.Raw(sql, Db.DbCfg.Db).Values(&spaceRowset)
  154. if dberr != nil {
  155. logger.Logger.Error(dberr)
  156. }
  157. if len(spaceRowset) > 0 {
  158. logspce, _ := strconv.Atoi(tools.IsEmpty(spaceRowset[0]["v"]))
  159. if logspce > 0 {
  160. vmod, _ := bo.GetSysParamValue("log_size_max", "0")
  161. logmax, _ := strconv.Atoi(vmod)
  162. logalarm1, _ := bo.GetSysParamValue("log_size_alarm1", "0")
  163. logalarmv1, _ := strconv.Atoi(logalarm1)
  164. logalarm2, _ := bo.GetSysParamValue("log_size_alarm2", "0")
  165. logalarmv2, _ := strconv.Atoi(logalarm2)
  166. if logmax > 0 {
  167. desc := ""
  168. if logalarmv2*logmax <= logspce {
  169. //告警
  170. desc = fmt.Sprintf("%s日志告警:当前系统日志容量已达 %d MB", appname, logspce)
  171. } else if logalarmv1*logmax <= logspce {
  172. //预警
  173. desc = fmt.Sprintf("%s日志预警:当前系统日志容量已达 %d MB", appname, logspce)
  174. }
  175. if !logalarming && desc != "" {
  176. new(bo.SystemAlarm).Save("1", "log", desc, 0)
  177. logalarming = true
  178. } else if logalarming && desc == "" {
  179. desc = appname + "日志容量预(告)警已解除"
  180. new(bo.SystemAlarm).Save("1", "log", desc, 1)
  181. logalarming = false
  182. }
  183. if desc != "" {
  184. if log_alarm_email != "" {
  185. err := new(email.Send).SendEmail(log_alarm_email, appname+"日志容量预(告)警", desc)
  186. if err != nil {
  187. logger.Logger.Error(err)
  188. }
  189. }
  190. }
  191. }
  192. }
  193. }
  194. }()
  195. sql := "select mobilephone from t_data_user u,global_const_code t where u.role=t.id and t.code='role_sysadmin'"
  196. ps := []orm.Params{}
  197. _, err = db.Raw(sql).Values(&ps)
  198. if err != nil {
  199. log.Println(err)
  200. time.Sleep(5 * time.Minute)
  201. continue
  202. }
  203. devicePhone := []string{}
  204. for _, row := range ps {
  205. p1 := tools.IsEmpty(row["mobilephone"])
  206. if p1 == "" {
  207. continue
  208. }
  209. devicePhone = append(devicePhone, strings.Split(p1, ",")...)
  210. }
  211. if osname == "windows" {
  212. cpuuse_command := "wmic cpu get loadpercentage"
  213. memFree_command := "wmic OS get FreePhysicalMemory"
  214. memTotal_command := "wmic ComputerSystem get TotalPhysicalMemory"
  215. diskuse_command_c := "wmic LogicalDisk where Caption='C:' get FreeSpace,Size /value"
  216. cmd := exec.Command("cmd", "/C", cpuuse_command)
  217. info1, _ := cmd.Output()
  218. info := []byte{}
  219. for _, b := range info1 {
  220. if b == 32 || b == 13 || b == 10 {
  221. continue
  222. }
  223. info = append(info, b)
  224. }
  225. v := string(info)
  226. if v != "" {
  227. v = strings.Trim(strings.ReplaceAll(v, "LoadPercentage", ""), " ")
  228. vint, _ := strconv.Atoi(v)
  229. cpuHC_lst["ishc"] = vint
  230. if vint >= cpuHC {
  231. cpuHC_lst["hcnt"] = cpuHC_lst["hcnt"] + 1
  232. if cpuHC_lst["hcnt"] >= 3 {
  233. if !cpualarming {
  234. msgobj := map[string]interface{}{}
  235. msgobj["datatype"] = sms.TemplateCode_Device_Performance
  236. msgobj["params"] = []string{appname + thisIp, "CPU", fmt.Sprintf("已达%d", vint) + "%"}
  237. msgobj["phone"] = devicePhone
  238. DataMonitorMsgChan <- msgobj
  239. desc := fmt.Sprintf("[%s]系统CPU耗用告警:当前CPU耗用率已达%d%%,请尽快处理!同时系统将限制同时访问的SCD数量!", appname, vint)
  240. new(bo.SystemAlarm).Save("1", "cpu", desc, 0)
  241. if log_alarm_email != "" {
  242. new(email.Send).SendEmail(log_alarm_email, appname+"系统CPU耗用告警", desc)
  243. }
  244. }
  245. cpualarming = true
  246. }
  247. logger.Logger.Println(fmt.Sprintf("!!!警告:当前CPU耗用率已达%d,请尽快处理!同时系统将限制同时访问的SCD数量!", vint))
  248. } else {
  249. cpuHC_lst["hcnt"] = 0
  250. if cpualarming {
  251. desc := fmt.Sprintf("[%s]系统CPU耗用告警解除,当前CPU耗用率%d%%", appname, vint)
  252. new(bo.SystemAlarm).Save("1", "cpu", desc, 1)
  253. if log_alarm_email != "" {
  254. new(email.Send).SendEmail(log_alarm_email, appname+"系统CPU耗用告警解除", desc)
  255. }
  256. }
  257. cpualarming = false
  258. }
  259. global.PerformanceRuntimeMonitorResult.Store("cpu", vint)
  260. }
  261. //总内存.结果的单位为b
  262. cmd = exec.Command("cmd", "/C", memTotal_command)
  263. info1, _ = cmd.Output()
  264. info = []byte{}
  265. for _, b := range info1 {
  266. if b == 32 || b == 13 || b == 10 {
  267. continue
  268. }
  269. info = append(info, b)
  270. }
  271. v = string(info)
  272. totalmem := 0
  273. if v != "" {
  274. v = strings.Trim(strings.ReplaceAll(v, "TotalPhysicalMemory", ""), " ")
  275. totalmem, _ = strconv.Atoi(v)
  276. }
  277. //剩余内存.结果的单位为Kb
  278. cmd = exec.Command("cmd", "/C", memFree_command)
  279. info1, _ = cmd.Output()
  280. info = []byte{}
  281. for _, b := range info1 {
  282. if b == 32 || b == 13 || b == 10 {
  283. continue
  284. }
  285. info = append(info, b)
  286. }
  287. v = string(info)
  288. //logger.Logger.Debug(fmt.Sprintf("====总内存:%d 当前空闲内存:%s", totalmem, v))
  289. if v != "" {
  290. v = strings.Trim(strings.ReplaceAll(v, "FreePhysicalMemory", ""), " ")
  291. vint, _ := strconv.Atoi(v)
  292. if vint > 0 {
  293. memuserate := int((1 - (float32(vint)/1024/1024)/(float32(totalmem)/1024/1024/1024)) * 100)
  294. memHC_lst["ishc"] = memuserate
  295. if memuserate >= memHC {
  296. memHC_lst["hcnt"] = memHC_lst["hcnt"] + 1
  297. if memHC_lst["hcnt"] >= 3 {
  298. if !memalarming {
  299. msgobj := map[string]interface{}{}
  300. msgobj["datatype"] = sms.TemplateCode_Device_Performance
  301. msgobj["params"] = []string{appname + thisIp, "内存", fmt.Sprintf("已达%d", memuserate) + "%"}
  302. msgobj["phone"] = devicePhone
  303. DataMonitorMsgChan <- msgobj
  304. desc := fmt.Sprintf("[%s]系统内存耗用告警:当前内存耗用率已达%d%%,请尽快处理!同时系统将尝试清除访问频率较低的SCD缓存数据!", appname, memuserate)
  305. new(bo.SystemAlarm).Save("1", "mem", desc, 0)
  306. if log_alarm_email != "" {
  307. new(email.Send).SendEmail(log_alarm_email, appname+"系统内存耗用告警", desc)
  308. }
  309. }
  310. memalarming = true
  311. //释放SCD缓存
  312. go new(bo.ScdParse).RemoveScdCache()
  313. }
  314. logger.Logger.Println(fmt.Sprintf("!!!警告:当前内存耗用率已达%d,请尽快处理!同时系统将尝试清除访问频率较低的SCD缓存数据!", memuserate))
  315. } else {
  316. memHC_lst["hcnt"] = 0
  317. if memalarming {
  318. desc := fmt.Sprintf("[%s]系统内存耗用告警解除,当前内存使用率%d%%", appname, memuserate)
  319. new(bo.SystemAlarm).Save("1", "mem", desc, 1)
  320. if log_alarm_email != "" {
  321. new(email.Send).SendEmail(log_alarm_email, appname+"系统内存耗用告警解除", desc)
  322. }
  323. }
  324. memalarming = false
  325. }
  326. global.PerformanceRuntimeMonitorResult.Store("mem", memuserate)
  327. }
  328. }
  329. cmd = exec.Command("cmd", "/C", diskuse_command_c)
  330. info, _ = cmd.Output()
  331. v = string(info)
  332. freeSpace := 0
  333. totalSpace := 0
  334. //logger.Logger.Debug(fmt.Sprintf("====C盘信息:%+v", v))
  335. if v != "" {
  336. for _, tmpv := range strings.Split(strings.Trim(v, " "), "\r\n") {
  337. if strings.TrimSpace(tmpv) == "" {
  338. continue
  339. }
  340. tmpv = strings.ReplaceAll(tmpv, "\r", "")
  341. if strings.HasPrefix(tmpv, "FreeSpace") {
  342. freeSpace, err = strconv.Atoi(strings.ReplaceAll(tmpv, "FreeSpace=", ""))
  343. if err != nil {
  344. log.Println(err)
  345. }
  346. }
  347. if strings.HasPrefix(tmpv, "Size") {
  348. totalSpace, err = strconv.Atoi(strings.ReplaceAll(tmpv, "Size=", ""))
  349. if err != nil {
  350. log.Println(err)
  351. }
  352. }
  353. }
  354. //logger.Logger.Debug(fmt.Sprint("====total:%d free:%d ===alarm:%d", totalSpace, freeSpace, diskHCC))
  355. if freeSpace > 0 {
  356. diskHCC_lst["ishc"] = 100 - int(freeSpace*100/totalSpace)
  357. if diskHCC_lst["ishc"] >= diskHCC {
  358. diskHCC_lst["hcnt"] = diskHCC_lst["hcnt"] + 1
  359. if diskHCC_lst["hcnt"] >= 3 {
  360. if !diskcalarming {
  361. msgobj := map[string]interface{}{}
  362. msgobj["datatype"] = sms.TemplateCode_Device_Performance
  363. msgobj["params"] = []string{appname + thisIp, "系统C盘", fmt.Sprintf("已达%d", diskHCC_lst["ishc"]) + "%"}
  364. msgobj["phone"] = devicePhone
  365. DataMonitorMsgChan <- msgobj
  366. desc := fmt.Sprintf("[%s]磁盘C盘剩余空间告警:当前磁盘空间已使用%d%%,请尽快处理!", appname, diskHCC_lst["ishc"])
  367. new(bo.SystemAlarm).Save("1", "disk", desc, 0)
  368. if log_alarm_email != "" {
  369. new(email.Send).SendEmail(log_alarm_email, appname+"系统C盘剩余空间告警", desc)
  370. }
  371. diskcalarming = true
  372. }
  373. }
  374. logger.Logger.Println(fmt.Sprintf("!!!警告:当前系统磁盘占用率已达%d,请尽快处理!", diskHCC_lst["ishc"]))
  375. } else {
  376. diskHCC_lst["hcnt"] = 0
  377. if diskcalarming {
  378. desc := fmt.Sprintf("[%s]磁盘C盘剩余空间告警解除,当前使用空间%d%%", appname, diskHCC_lst["ishc"])
  379. new(bo.SystemAlarm).Save("1", "disk", desc, 1)
  380. if log_alarm_email != "" {
  381. new(email.Send).SendEmail(log_alarm_email, appname+"系统C盘剩余空间告警解除", desc)
  382. }
  383. }
  384. diskcalarming = false
  385. }
  386. global.PerformanceRuntimeMonitorResult.Store("disk_c", diskHCC_lst["ishc"])
  387. }
  388. }
  389. //当前执行路径
  390. exePath := os.Args[0]
  391. //fmt.Println("exePath:", exePath)
  392. exeDisk := strings.Split(exePath, "\\")[0]
  393. diskuse_command_n := "wmic LogicalDisk where Caption='" + exeDisk + "' get FreeSpace,Size /value"
  394. cmd = exec.Command("cmd", "/C", diskuse_command_n)
  395. info, _ = cmd.Output()
  396. v = string(info)
  397. if v != "" {
  398. for _, tmpv := range strings.Split(strings.Trim(v, " "), "\r\n") {
  399. if strings.TrimSpace(tmpv) == "" {
  400. continue
  401. }
  402. tmpv = strings.ReplaceAll(tmpv, "\r", "")
  403. if strings.HasPrefix(tmpv, "FreeSpace") {
  404. freeSpace, err = strconv.Atoi(strings.ReplaceAll(tmpv, "FreeSpace=", ""))
  405. if err != nil {
  406. log.Println(err)
  407. }
  408. }
  409. if strings.HasPrefix(tmpv, "Size") {
  410. totalSpace, err = strconv.Atoi(strings.ReplaceAll(tmpv, "Size=", ""))
  411. if err != nil {
  412. log.Println(err)
  413. }
  414. }
  415. }
  416. if freeSpace > 0 {
  417. diskHCI_lst["ishc"] = 100 - int(freeSpace*100/totalSpace)
  418. if diskHCI_lst["ishc"] >= diskHCI {
  419. diskHCI_lst["hcnt"] = diskHCI_lst["hcnt"] + 1
  420. if diskHCI_lst["hcnt"] >= 3 {
  421. if !diskalarming {
  422. msgobj := map[string]interface{}{}
  423. msgobj["datatype"] = sms.TemplateCode_Device_Performance
  424. msgobj["params"] = []string{appname + thisIp, "应用" + exeDisk[0:1] + "盘", fmt.Sprintf("已达%d", diskHCI_lst["ishc"]) + "%"}
  425. msgobj["phone"] = devicePhone
  426. DataMonitorMsgChan <- msgobj
  427. desc := fmt.Sprintf("[%s]磁盘%s盘剩余空间告警:当前磁盘空间已使用%d%%,请尽快处理!", appname, exeDisk[0:1], diskHCI_lst["ishc"])
  428. new(bo.SystemAlarm).Save("1", "disk", desc, 0)
  429. if log_alarm_email != "" {
  430. new(email.Send).SendEmail(log_alarm_email, appname+"系统"+exeDisk[0:1]+"盘剩余空间告警", desc)
  431. }
  432. diskalarming = true
  433. }
  434. logger.Logger.Println(fmt.Sprintf("!!!警告:当前磁盘%s占用率已达%d,请尽快处理!", exeDisk[0:1], diskHCI_lst["ishc"]))
  435. }
  436. } else {
  437. diskHCI_lst["hcnt"] = 0
  438. if diskalarming {
  439. desc := fmt.Sprintf("[%s]磁盘%s盘剩余空间告警已解除,当前磁盘使用%d%%", appname, exeDisk[0:1], diskHCI_lst["ishc"])
  440. new(bo.SystemAlarm).Save("1", "disk", desc, 1)
  441. if log_alarm_email != "" {
  442. new(email.Send).SendEmail(log_alarm_email, appname+"系统"+exeDisk[0:1]+"盘剩余空间告警解除", desc)
  443. }
  444. }
  445. diskalarming = false
  446. }
  447. global.PerformanceRuntimeMonitorResult.Store("disk", diskHCC_lst["ishc"])
  448. }
  449. }
  450. } else {
  451. //linux系统
  452. v, errmem := mem.VirtualMemory()
  453. if errmem != nil {
  454. logger.Logger.Error(errmem)
  455. } else {
  456. //fmt.Printf("内存使用率%d\n", v.UsedPercent)
  457. memuserate := int(v.UsedPercent)
  458. memHC_lst["ishc"] = memuserate
  459. if memuserate >= memHC {
  460. memHC_lst["hcnt"] = memHC_lst["hcnt"] + 1
  461. if memHC_lst["hcnt"] >= 3 {
  462. if !memalarming {
  463. msgobj := map[string]interface{}{}
  464. msgobj["datatype"] = sms.TemplateCode_Device_Performance
  465. msgobj["params"] = []string{appname + thisIp, "内存", fmt.Sprintf("已达%d", memuserate) + "%"}
  466. msgobj["phone"] = devicePhone
  467. DataMonitorMsgChan <- msgobj
  468. desc := fmt.Sprintf("[%s]系统内存耗用告警:当前内存已耗用%d%%,请尽快处理!同时系统将尝试清除访问频率较低的SCD缓存数据!", appname, memuserate)
  469. new(bo.SystemAlarm).Save("1", "mem", desc, 0)
  470. if log_alarm_email != "" {
  471. new(email.Send).SendEmail(log_alarm_email, appname+"系统内存耗用告警", desc)
  472. }
  473. }
  474. memalarming = true
  475. //释放SCD缓存
  476. go new(bo.ScdParse).RemoveScdCache()
  477. }
  478. logger.Logger.Println(fmt.Sprintf("!!!警告:当前内存耗用率已达%d,请尽快处理!同时系统将尝试清除访问频率较低的SCD缓存数据!", memuserate))
  479. } else {
  480. memHC_lst["hcnt"] = 0
  481. if memalarming {
  482. desc := fmt.Sprintf("[%s]系统内存耗用告警已解除,当前内存耗用%d%%", appname, memuserate)
  483. new(bo.SystemAlarm).Save("1", "mem", desc, 1)
  484. if log_alarm_email != "" {
  485. new(email.Send).SendEmail(log_alarm_email, appname+"系统内存耗用告警解除", desc)
  486. }
  487. }
  488. memalarming = false
  489. }
  490. global.PerformanceRuntimeMonitorResult.Store("mem", memuserate)
  491. }
  492. // CPU使用率
  493. //for {
  494. percent, errcpu := cpu.Percent(time.Second, true)
  495. if errcpu != nil {
  496. logger.Logger.Error(errcpu)
  497. } else {
  498. //fmt.Printf("cpu percent:%v", percent)
  499. cpuT := 0.0
  500. for _, v := range percent {
  501. cpuT = cpuT + v
  502. }
  503. cpuavg := int(cpuT / float64(len(percent)))
  504. cpuHC_lst["ishc"] = cpuavg
  505. //fmt.Printf("CPU使用率%d\n", cpuavg)
  506. if cpuavg >= cpuHC {
  507. cpuHC_lst["hcnt"] = cpuHC_lst["hcnt"] + 1
  508. if cpuHC_lst["hcnt"] >= 3 {
  509. if !cpualarming {
  510. msgobj := map[string]interface{}{}
  511. msgobj["datatype"] = sms.TemplateCode_Device_Performance
  512. msgobj["params"] = []string{appname + thisIp, "CPU", fmt.Sprintf("已达%d", cpuavg) + "%"}
  513. msgobj["phone"] = devicePhone
  514. DataMonitorMsgChan <- msgobj
  515. desc := fmt.Sprintf("[%s]系统CPU耗用告警:当前CPU已耗用%d%%,请尽快处理!同时系统将限制同时访问的SCD数量!", appname, cpuavg)
  516. new(bo.SystemAlarm).Save("1", "cpu", desc, 0)
  517. if log_alarm_email != "" {
  518. new(email.Send).SendEmail(log_alarm_email, appname+"系统CPU耗用告警", desc)
  519. }
  520. }
  521. cpualarming = true
  522. }
  523. logger.Logger.Println(fmt.Sprintf("!!!警告:当前CPU耗用率已达%d,请尽快处理!同时系统将限制同时访问的SCD数量!", cpuavg))
  524. } else {
  525. cpuHC_lst["hcnt"] = 0
  526. if cpualarming {
  527. desc := fmt.Sprintf("[%s]系统CPU耗用告警已解除", appname, cpuavg)
  528. new(bo.SystemAlarm).Save("1", "cpu", desc, 1)
  529. if log_alarm_email != "" {
  530. new(email.Send).SendEmail(log_alarm_email, appname+"系统CPU耗用告警解除", desc)
  531. }
  532. }
  533. cpualarming = false
  534. }
  535. global.PerformanceRuntimeMonitorResult.Store("cpu", cpuavg)
  536. }
  537. parts, err2 := disk.Partitions(true)
  538. if err2 != nil {
  539. logger.Logger.Error(err2)
  540. } else {
  541. diskT := 0.0
  542. diskC := 0
  543. for _, part := range parts {
  544. if !strings.HasPrefix(part.Device, "/dev") {
  545. continue
  546. }
  547. //fmt.Printf("part:%v", part.String())
  548. diskInfo, _ := disk.Usage(part.Mountpoint)
  549. diskT = diskT + diskInfo.UsedPercent
  550. diskC = diskC + 1
  551. //fmt.Printf("disk info:used:%v free:%v", diskInfo.UsedPercent, diskInfo.Free)
  552. }
  553. avg := int(diskT / float64(diskC))
  554. diskHCC_lst["ishc"] = avg
  555. //fmt.Printf("磁盘使用率%d\n", avg)
  556. if diskHCC_lst["ishc"] >= diskHCC {
  557. diskHCC_lst["hcnt"] = diskHCC_lst["hcnt"] + 1
  558. if diskHCC_lst["hcnt"] >= 3 {
  559. if !diskalarming {
  560. msgobj := map[string]interface{}{}
  561. msgobj["datatype"] = sms.TemplateCode_Device_Performance
  562. msgobj["params"] = []string{appname + thisIp, "数据磁盘", fmt.Sprintf("已达%d", avg) + "%"}
  563. msgobj["phone"] = devicePhone
  564. DataMonitorMsgChan <- msgobj
  565. desc := fmt.Sprintf("[%s]磁盘空间告警:当前磁盘空间已使用%d%%,请尽快释放多余的空间!", appname, avg)
  566. new(bo.SystemAlarm).Save("1", "disk", desc, 0)
  567. if log_alarm_email != "" {
  568. new(email.Send).SendEmail(log_alarm_email, appname+"系统CPU耗用告警", desc)
  569. }
  570. }
  571. diskalarming = true
  572. }
  573. logger.Logger.Println(fmt.Sprintf("!!!警告:当前磁盘空间占用率已达%d,请尽快释放多余的空间!", avg))
  574. } else {
  575. diskHCC_lst["hcnt"] = 0
  576. if diskalarming {
  577. desc := fmt.Sprintf("[%s]磁盘空间告警已解除", appname, avg)
  578. new(bo.SystemAlarm).Save("1", "disk", desc, 1)
  579. if log_alarm_email != "" {
  580. new(email.Send).SendEmail(log_alarm_email, appname+"磁盘空间告警解除", desc)
  581. }
  582. }
  583. diskalarming = false
  584. }
  585. global.PerformanceRuntimeMonitorResult.Store("disk", avg)
  586. }
  587. }
  588. time.Sleep(1 * time.Minute)
  589. }
  590. }
  591. //启动实时性能监控。每5秒一次并返回结果
  592. func (t *DataMonitor) PerformanceRuntimeMonitorStart() {
  593. if t.performanceRuntimeMonitorState {
  594. return
  595. }
  596. t.pmResultLock = sync.RWMutex{}
  597. t.performanceRuntimeMonitorResult = map[string]interface{}{}
  598. var err error
  599. osname := string(runtime.GOOS)
  600. cpuHC := 80 //cpu高耗用率
  601. memHC := 80 //内存高耗用率
  602. diskHCC := 90 //C磁盘高耗用率
  603. diskHCI := 90 //程序所在磁盘高耗用率
  604. cpuHC_lst := map[string]int{"ishc": 0, "hcnt": 0, "lcnt": 0}
  605. memHC_lst := map[string]int{"ishc": 0, "hcnt": 0, "lcnt": 0}
  606. diskHCC_lst := map[string]int{"ishc": 0, "hcnt": 0, "lcnt": 0}
  607. diskHCI_lst := map[string]int{"ishc": 0, "hcnt": 0, "lcnt": 0}
  608. t.performanceRuntimeMonitorState = true
  609. for {
  610. if !t.performanceRuntimeMonitorState {
  611. break
  612. }
  613. t.pmResultLock.Lock()
  614. if osname == "windows" {
  615. cpuuse_command := "wmic cpu get loadpercentage"
  616. memFree_command := "wmic OS get FreePhysicalMemory"
  617. memTotal_command := "wmic ComputerSystem get TotalPhysicalMemory"
  618. diskuse_command_c := "wmic LogicalDisk where Caption='C:' get FreeSpace,Size /value"
  619. cmd := exec.Command("cmd", "/C", cpuuse_command)
  620. info1, _ := cmd.Output()
  621. info := []byte{}
  622. for _, b := range info1 {
  623. if b == 32 || b == 13 || b == 10 {
  624. continue
  625. }
  626. info = append(info, b)
  627. }
  628. v := string(info)
  629. //log.Println(fmt.Sprintf("====CPU:%s", v))
  630. if v != "" {
  631. v = strings.Trim(strings.ReplaceAll(v, "LoadPercentage", ""), " ")
  632. vint, _ := strconv.Atoi(v)
  633. cpuHC_lst["ishc"] = vint
  634. if vint >= cpuHC {
  635. cpuHC_lst["hcnt"] = cpuHC_lst["hcnt"] + 1
  636. if cpuHC_lst["hcnt"] >= 3 {
  637. t.performanceRuntimeMonitorResult["cpu"] = cpuHC_lst
  638. log.Println(fmt.Sprintf("====CPU:%s", v))
  639. }
  640. } else {
  641. cpuHC_lst["hcnt"] = 0
  642. }
  643. }
  644. //总内存
  645. cmd = exec.Command("cmd", "/C", memTotal_command)
  646. info1, _ = cmd.Output()
  647. info = []byte{}
  648. for _, b := range info1 {
  649. if b == 32 || b == 13 || b == 10 {
  650. continue
  651. }
  652. info = append(info, b)
  653. }
  654. v = string(info)
  655. totalmem := int64(0)
  656. if v != "" {
  657. v = strings.Trim(strings.ReplaceAll(v, "TotalPhysicalMemory", ""), " ")
  658. totalmem, _ = strconv.ParseInt(v, 10, 64)
  659. }
  660. cmd = exec.Command("cmd", "/C", memFree_command)
  661. info1, _ = cmd.Output()
  662. info = []byte{}
  663. for _, b := range info1 {
  664. if b == 32 || b == 13 || b == 10 {
  665. continue
  666. }
  667. info = append(info, b)
  668. }
  669. v = string(info)
  670. //log.Println(fmt.Sprintf("====总内存%d free:%s", totalmem, v))
  671. if v != "" {
  672. v = strings.Trim(strings.ReplaceAll(v, "FreePhysicalMemory", ""), " ")
  673. vint, _ := strconv.ParseInt(v, 10, 64)
  674. if vint > 0 {
  675. var useMem = totalmem - vint*1024
  676. memuserate := (useMem * 100 / totalmem)
  677. //log.Println(fmt.Sprintf("====内存占用率:%d/%d %d", useMem, totalmem, memuserate))
  678. memHC_lst["ishc"] = int(memuserate)
  679. if int(memuserate) >= memHC {
  680. memHC_lst["hcnt"] = memHC_lst["hcnt"] + 1
  681. if memHC_lst["hcnt"] >= 3 {
  682. t.performanceRuntimeMonitorResult["mem"] = memHC_lst
  683. log.Println(fmt.Sprintf("====内存占用率:%d/%d %d", useMem, totalmem, memuserate))
  684. }
  685. } else {
  686. memHC_lst["hcnt"] = 0
  687. }
  688. }
  689. }
  690. cmd = exec.Command("cmd", "/C", diskuse_command_c)
  691. info, _ = cmd.Output()
  692. v = string(info)
  693. freeSpace := 0
  694. totalSpace := 0
  695. if v != "" {
  696. for _, tmpv := range strings.Split(strings.Trim(v, " "), "\r\n") {
  697. if strings.TrimSpace(tmpv) == "" {
  698. continue
  699. }
  700. tmpv = strings.ReplaceAll(tmpv, "\r", "")
  701. if strings.HasPrefix(tmpv, "FreeSpace") {
  702. freeSpace, err = strconv.Atoi(strings.ReplaceAll(tmpv, "FreeSpace=", ""))
  703. if err != nil {
  704. log.Println(err)
  705. }
  706. }
  707. if strings.HasPrefix(tmpv, "Size") {
  708. totalSpace, err = strconv.Atoi(strings.ReplaceAll(tmpv, "Size=", ""))
  709. if err != nil {
  710. log.Println(err)
  711. }
  712. }
  713. }
  714. if freeSpace > 0 {
  715. diskHCC_lst["ishc"] = 100 - int(freeSpace*100/totalSpace)
  716. if diskHCC_lst["ishc"] >= diskHCC {
  717. diskHCC_lst["hcnt"] = diskHCC_lst["hcnt"] + 1
  718. if diskHCC_lst["hcnt"] >= 3 {
  719. t.performanceRuntimeMonitorResult["disk"] = diskHCC_lst
  720. }
  721. } else {
  722. diskHCC_lst["hcnt"] = 0
  723. }
  724. }
  725. }
  726. //当前执行路径
  727. exePath := os.Args[0]
  728. //fmt.Println("exePath:", exePath)
  729. exeDisk := strings.Split(exePath, "\\")[0]
  730. diskuse_command_n := "wmic LogicalDisk where Caption='" + exeDisk + "' get FreeSpace,Size /value"
  731. cmd = exec.Command("cmd", "/C", diskuse_command_n)
  732. info, _ = cmd.Output()
  733. v = string(info)
  734. if v != "" {
  735. for _, tmpv := range strings.Split(strings.Trim(v, " "), "\r\n") {
  736. if strings.TrimSpace(tmpv) == "" {
  737. continue
  738. }
  739. tmpv = strings.ReplaceAll(tmpv, "\r", "")
  740. if strings.HasPrefix(tmpv, "FreeSpace") {
  741. freeSpace, err = strconv.Atoi(strings.ReplaceAll(tmpv, "FreeSpace=", ""))
  742. if err != nil {
  743. log.Println(err)
  744. }
  745. }
  746. if strings.HasPrefix(tmpv, "Size") {
  747. totalSpace, err = strconv.Atoi(strings.ReplaceAll(tmpv, "Size=", ""))
  748. if err != nil {
  749. log.Println(err)
  750. }
  751. }
  752. }
  753. if freeSpace > 0 {
  754. diskHCI_lst["ishc"] = 100 - int(freeSpace*100/totalSpace)
  755. if diskHCI_lst["ishc"] >= diskHCI {
  756. diskHCI_lst["hcnt"] = diskHCI_lst["hcnt"] + 1
  757. if diskHCI_lst["hcnt"] >= 3 {
  758. t.performanceRuntimeMonitorResult["disk_"+exeDisk] = diskHCC_lst
  759. }
  760. } else {
  761. diskHCI_lst["hcnt"] = 0
  762. }
  763. }
  764. }
  765. } else {
  766. //linux系统
  767. v, errmem := mem.VirtualMemory()
  768. if errmem != nil {
  769. log.Println(errmem)
  770. } else {
  771. //log.Printf("内存使用率%d\n", v.UsedPercent)
  772. memuserate := int(v.UsedPercent)
  773. memHC_lst["ishc"] = memuserate
  774. if memuserate >= memHC {
  775. memHC_lst["hcnt"] = memHC_lst["hcnt"] + 1
  776. if memHC_lst["hcnt"] >= 3 {
  777. t.performanceRuntimeMonitorResult["mem"] = memHC_lst
  778. log.Printf("内存使用率%d\n", v.UsedPercent)
  779. }
  780. } else {
  781. memHC_lst["hcnt"] = 0
  782. }
  783. }
  784. percent, errcpu := cpu.Percent(time.Second, true)
  785. if errcpu != nil {
  786. log.Println(errcpu)
  787. } else {
  788. //fmt.Printf("cpu percent:%v", percent)
  789. cpuT := 0.0
  790. for _, v := range percent {
  791. cpuT = cpuT + v
  792. }
  793. cpuavg := int(cpuT / float64(len(percent)))
  794. cpuHC_lst["ishc"] = cpuavg
  795. //fmt.Printf("CPU使用率%d\n", cpuavg)
  796. if cpuavg >= cpuHC {
  797. cpuHC_lst["hcnt"] = cpuHC_lst["hcnt"] + 1
  798. if cpuHC_lst["hcnt"] >= 3 {
  799. t.performanceRuntimeMonitorResult["cpu"] = cpuHC_lst
  800. log.Printf("CPU使用率%d\n", cpuavg)
  801. }
  802. } else {
  803. cpuHC_lst["hcnt"] = 0
  804. }
  805. }
  806. parts, err2 := disk.Partitions(true)
  807. if err2 != nil {
  808. log.Println("get Partitions failed, err:%v", err2)
  809. } else {
  810. diskT := 0.0
  811. diskC := 0
  812. for _, part := range parts {
  813. if !strings.HasPrefix(part.Device, "/dev") {
  814. continue
  815. }
  816. //fmt.Printf("part:%v", part.String())
  817. diskInfo, _ := disk.Usage(part.Mountpoint)
  818. diskT = diskT + diskInfo.UsedPercent
  819. diskC = diskC + 1
  820. //fmt.Printf("disk info:used:%v free:%v", diskInfo.UsedPercent, diskInfo.Free)
  821. }
  822. avg := int(diskT / float64(diskC))
  823. diskHCC_lst["ishc"] = avg
  824. //fmt.Printf("磁盘使用率%d\n", avg)
  825. if diskHCC_lst["ishc"] >= diskHCC {
  826. diskHCC_lst["hcnt"] = diskHCC_lst["hcnt"] + 1
  827. if diskHCC_lst["hcnt"] >= 3 {
  828. t.performanceRuntimeMonitorResult["disk"] = diskHCC_lst
  829. log.Printf("磁盘使用率%d\n", avg)
  830. }
  831. } else {
  832. diskHCC_lst["hcnt"] = 0
  833. }
  834. }
  835. }
  836. t.pmResultLock.Unlock()
  837. //log.Println(fmt.Sprintf("====实时性能监控结果:%v", t.performanceRuntimeMonitorResult))
  838. time.Sleep(5 * time.Second)
  839. }
  840. }
  841. //停止实时性能监控
  842. func (t *DataMonitor) PerformanceRuntimeMonitorStop() {
  843. t.performanceRuntimeMonitorState = false
  844. }
  845. //过期附件监测
  846. func attachmentMonitorStart() {
  847. log.Println("启动过期附件自动清理进程")
  848. for {
  849. nowHour := time.Now().Format("15")
  850. //每天早上0点清理一次
  851. dataTimoutMonitorHour, _ := bo.GetSysParamValue("attachmentClearHour", "00")
  852. if nowHour != dataTimoutMonitorHour {
  853. time.Sleep(time.Minute * 50)
  854. continue
  855. }
  856. m := new(DataMonitor)
  857. m.attachmentAutoClear()
  858. time.Sleep(time.Minute * 50)
  859. }
  860. }
  861. func (t *DataMonitor) OptimizeTable() {
  862. db := orm.NewOrm()
  863. //获取scd属性表
  864. sql := "select table_name , table_comment from information_schema.tables where table_schema = (select database()) and table_name like 't_%' "
  865. rowset := []orm.Params{}
  866. _, err := db.Raw(sql).Values(&rowset)
  867. if err != nil {
  868. log.Println(err)
  869. return
  870. }
  871. for _, row := range rowset {
  872. tb := tools.IsEmpty(row["TABLE_NAME"]) + tools.IsEmpty(row["table_name"])
  873. _, err = db.Raw("optimize table " + tb).Exec()
  874. if err != nil {
  875. log.Println(err)
  876. }
  877. _, err = db.Raw("analyze table " + tb).Exec()
  878. if err != nil {
  879. log.Println(err)
  880. }
  881. }
  882. }
  883. //临时scd数据清理
  884. func (t *DataMonitor) tempScdClear() {
  885. db := orm.NewOrm()
  886. t1 := time.Now().Unix()
  887. clearT := t1 - int64(1*60*60) //1小时之前
  888. clearDate := time.Unix(clearT, 0).Format("2006-01-02 15:04:05")
  889. sql := "select * from t_scd_scl where id not in(select scd_id from t_data_task) and created_time<?"
  890. rowset := []orm.Params{}
  891. _, err := db.Raw(sql, clearDate).Values(&rowset)
  892. if err != nil {
  893. log.Println(err)
  894. } else {
  895. if len(rowset) == 0 {
  896. return
  897. }
  898. uinfo := map[string]interface{}{}
  899. uinfo["name"] = "临时SCD清理任务"
  900. for _, row := range rowset {
  901. scd := new(bo.ScdMgr)
  902. scd.SetUserInfo(uinfo)
  903. scd.DeleteScd(tools.IsEmpty(row["id"]), true)
  904. }
  905. }
  906. }
  907. //附件自动清理
  908. func (t *DataMonitor) attachmentAutoClear() {
  909. db := orm.NewOrm()
  910. sql := "select * from t_data_attachment where skeepday>0"
  911. list := []orm.Params{}
  912. _, err := db.Raw(sql).Values(&list)
  913. if err != nil {
  914. log.Println(err)
  915. return
  916. }
  917. if len(list) == 0 {
  918. return
  919. }
  920. for _, row := range list {
  921. skeepday := tools.IsEmpty(row["skeepday"])
  922. colname := tools.IsEmpty(row["colname"])
  923. tname := tools.IsEmpty(row["tablename"])
  924. sql1 := "select id," + colname + " from " + tname + " where " + colname + "!='' and CREATED_TIME<DATE_ADD(now(),INTERVAL -" + skeepday + " DAY)"
  925. where := tools.IsEmpty(row["filterwhere"])
  926. if where != "" {
  927. sql1 = sql1 + " and " + where
  928. }
  929. sql1 = sql1 + " limit 0,500 "
  930. for {
  931. tmpresultset := []orm.Params{}
  932. _, err = db.Raw(sql1).Values(&tmpresultset)
  933. if err != nil {
  934. log.Println(err)
  935. break
  936. }
  937. if len(tmpresultset) == 0 {
  938. break
  939. }
  940. ids := []string{}
  941. for _, r := range tmpresultset {
  942. ids = append(ids, tools.IsEmpty(r["id"]))
  943. imgsrc := tools.IsEmpty(r[colname])
  944. if strings.Index(imgsrc, "static/download/") > -1 {
  945. reg, _ := regexp.Compile("http.*?static/download/")
  946. imgsrc = reg.ReplaceAllString(imgsrc, "static/download/")
  947. imgsrc = "./" + imgsrc //物理存储路径
  948. //删除文件
  949. os.Remove(imgsrc)
  950. }
  951. }
  952. _, err = db.Raw("update " + tname + " set " + colname + "='' where id in('" + strings.Join(ids, "','") + "')").Exec()
  953. if err != nil {
  954. log.Println(err)
  955. break
  956. }
  957. }
  958. }
  959. }
  960. func (t *DataMonitor) sendDeviceSms(devicename string, devicelist []string, datatype string, timeout int, devicePhone string) {
  961. if len(devicelist) > 0 {
  962. h := float64(timeout / 3600)
  963. cnt := len(devicelist)
  964. //最多显示5个设备名称
  965. if cnt > 5 {
  966. cnt = 5
  967. }
  968. devicelistNames := strings.Join(devicelist[:cnt], ",")
  969. msgobj := map[string]interface{}{}
  970. msgobj["datatype"] = sms.TemplateCode_Device_Offline
  971. msgobj["params"] = []string{devicename, fmt.Sprintf("%s(共%d台)", devicelistNames, cnt), fmt.Sprintf("%d小时", int(math.Floor(h)))}
  972. msgobj["phone"] = strings.Split(devicePhone, ",")
  973. DataMonitorMsgChan <- msgobj
  974. }
  975. }