代码拉取完成,页面将自动刷新
同步操作将从 xrkmonitor/plugin_linux_base 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
/*** xrkmonitor license ***
Copyright (c) 2019 by rockdeng
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
字符云监控(xrkmonitor) 开源版 (c) 2019 by rockdeng
当前版本:v1.0
使用授权协议: apache license 2.0
云版本主页:http://xrkmonitor.com
云版本为开源版提供永久免费告警通道支持,告警通道支持短信、邮件、
微信等多种方式,欢迎使用
监控插件 linux_base 功能:
使用监控系统 api 通过读取 proc 文件系统实现 linux 基础信息上报, 包括 cpu/内存/磁盘/网络/进程
cpu :使用率(系统、用户、软中断、其它)、平均负载、cpu 切换次数等
内存:使用率、可用内存、swap使用率等
磁盘:使用率、磁盘IO
网络:流量、包量、tcp 连接数、udp 包量、网络IO等
****/
#include <stdlib.h>
#include <inttypes.h>
#include <errno.h>
#include <unistd.h>
#include <string>
#include <stdio.h>
#include <math.h>
#include <mt_report.h>
#include <string.h>
#include <limits.h>
#include <signal.h>
#include <iostream>
#include <map>
#include "xrk_linux_base.h"
#include "net.h"
#include "cpu.h"
#include "disk.h"
#include "mem.h"
int g_aryPluginAttr[XRK_PLUGIN_ATTRS_COUNT_MAX];
const std::string g_strPluginName(XRK_PLUGIN_NAME);
// 插件实时表格统计时间
int g_iTableBaseInfoStaticTime = 0;
int g_iTableDiskStatAllStaticTime = 0;
int g_iTableNetDevAllStaticTime = 0;
int g_iTableNetTuPackStatStaticTime = 0;
int g_iTableCpuAllStatStaticTime = 0;
int g_iTableMemStatStaticTime = 0;
TcpuUse g_stCpuUse = {0};
TTcpUdpInfo g_stNetTcpUdpInfo = {0};
bool g_bNotSupportTcpUdp = false;
TNetUseInfo g_stNetUse = {0};
TDiskStatInfo * g_pDiskStatAry = NULL;
TDiskStatInfo * g_pDiskStatAryForTable = NULL;
std::map<std::string, TDiskInfo> g_stDiskInfo;
char g_szCpuInfo[32] = "null";
TMemInfo g_stMemInfo = {0};
TMemUse g_stMemUse = {0};
uint32_t g_dwCurTimeSec = 0;
int g_iReadInfoPerTimeSec = 0;
int g_iReportInfoPerTimeSec = 0;
int g_iNotMonitorNetLo = 0;
int g_iMaxDiskStatCount = 0;
int g_iDiskStatCount = 0;
int g_iDiskReadTimesWarnCfg = 0;
int g_iDiskWriteTimesWarnCfg = 0;
int g_iReadSectorsWarnCfg = 0;
int g_iWriteSectorsWarnCfg = 0;
int g_iIoUseTimeMsWarnCfg = 0;
int g_iLocalUdpPackErrorWarnLog = 0;
int g_iLocalTcpPackErrorWarnLog = 0;
int g_iRemoteTcpPackErrorWarnLog = 0;
int g_iRemoteUdpPackErrorWarnLog = 0;
bool s_exit = false;
TBaseInfo g_stBaseInfo;
const char * GetCmdResult(const char *cmd)
{
static char s_buf[4096] = {0};
s_buf[0] = '\0';
FILE *fp = popen(cmd, "r");
if(!fp) {
MtReport_Log_Error("popen failed, cmd:%s, msg:%s", cmd, strerror(errno));
return NULL;
}
int len = fread(s_buf, 1, sizeof(s_buf)-1, fp);
if(len >= (int)sizeof(s_buf) || ferror(fp)) {
MtReport_Log_Error("fread failed ret:%d, msg:%s", len, strerror(errno));
pclose(fp);
return NULL;
}
pclose(fp);
s_buf[len] = '\0';
return s_buf;
}
inline int MemUnitTokB()
{
if(!strcmp(g_stMemInfo.szUnit, "kB"))
return 1;
if(!strcmp(g_stMemInfo.szUnit, "mB"))
return 1000;
if(!strcmp(g_stMemInfo.szUnit, "gB"))
return 1000000;
return 1;
}
static void ReadMemUse()
{
memset(&g_stMemInfo, 0, sizeof(g_stMemInfo));
if(GetMemInfo(g_stMemInfo) < 0)
return;
uint32_t dwFree = g_stMemInfo.dwMemFree + g_stMemInfo.dwCached - g_stMemInfo.dwDirty - g_stMemInfo.dwMapped;
int32_t iUsePer = (int)((g_stMemInfo.dwMemTotal-dwFree)*100/g_stMemInfo.dwMemTotal);
g_stMemUse.iMemUse += iUsePer;
g_stBaseInfo.dwMemSpace = g_stMemInfo.dwMemTotal;
g_stBaseInfo.iMemUsePercent = iUsePer;
int32_t iSwapUse = 0;
if(g_stMemInfo.dwSwapTotal > 0) {
iSwapUse = (int)((g_stMemInfo.dwSwapTotal-g_stMemInfo.dwSwapFree)*100/g_stMemInfo.dwSwapTotal);
g_stMemUse.iSwapUse += iSwapUse;
}
g_stMemUse.bStaticTimes++;
g_stMemUse.dwAvailable = g_stMemInfo.dwMemAvailable*MemUnitTokB();
MtReport_Log_Debug("get meminfo - unit:%s total:%u free:%u buffers:%u cached:%u dirty:%u maped:%u, use:%u%%, avail:%u",
g_stMemInfo.szUnit, g_stMemInfo.dwMemTotal,
g_stMemInfo.dwMemFree, g_stMemInfo.dwBuffers, g_stMemInfo.dwCached, g_stMemInfo.dwDirty,
g_stMemInfo.dwMapped, iUsePer, g_stMemUse.dwAvailable);
}
static void ReportCpuUse(int iCpu, int iUse)
{
switch(iCpu) {
case 0:
MtReport_Attr_Set(XRK_ATTR_CPU_TOAL_USE, iUse);
break;
case 1:
MtReport_Attr_Set(XRK_ATTR_CPU0_USE, iUse);
break;
case 2:
MtReport_Attr_Set(XRK_ATTR_CPU1_USE, iUse);
break;
case 3:
MtReport_Attr_Set(XRK_ATTR_CPU2_USE, iUse);
break;
case 4:
MtReport_Attr_Set(XRK_ATTR_CPU3_USE, iUse);
break;
case 5:
MtReport_Attr_Set(XRK_ATTR_CPU4_USE, iUse);
break;
case 6:
MtReport_Attr_Set(XRK_ATTR_CPU5_USE, iUse);
break;
case 7:
MtReport_Attr_Set(XRK_ATTR_CPU6_USE, iUse);
break;
case 8:
MtReport_Attr_Set(XRK_ATTR_CPU7_USE, iUse);
break;
case 9:
MtReport_Attr_Set(XRK_ATTR_CPU8_USE, iUse);
break;
case 10:
MtReport_Attr_Set(XRK_ATTR_CPU9_USE, iUse);
break;
case 11:
MtReport_Attr_Set(XRK_ATTR_CPU10_USE, iUse);
break;
case 12:
MtReport_Attr_Set(XRK_ATTR_CPU11_USE, iUse);
break;
case 13:
MtReport_Attr_Set(XRK_ATTR_CPU12_USE, iUse);
break;
case 14:
MtReport_Attr_Set(XRK_ATTR_CPU13_USE, iUse);
break;
case 15:
MtReport_Attr_Set(XRK_ATTR_CPU14_USE, iUse);
break;
case 16:
MtReport_Attr_Set(XRK_ATTR_CPU15_USE, iUse);
break;
default:
MtReport_Log_Warn("not support cpu:%d, use:%d%%", iCpu, iUse);
}
}
static void CalcuCpuAvgUse()
{
if(g_stCpuUse.bStaticTimes <= 0) {
MtReport_Log_Warn("static cpu times invalid (%u)", g_stCpuUse.bStaticTimes);
return;
}
int iTotalUse = 0, iTmp = 0;
#define GET_CPU_AVG_USE(f) do { \
iTmp = g_stCpuUse.f / g_stCpuUse.bStaticTimes; \
iTmp /= 10; \
if((iTmp == 0 && (g_stCpuUse.f%10) > 0) || (iTmp%10) > 0) \
iTmp++; \
g_stCpuUse.f = iTmp; \
iTotalUse += g_stCpuUse.f; \
}while(0)
GET_CPU_AVG_USE(iCpuUser);
GET_CPU_AVG_USE(iCpuNice);
GET_CPU_AVG_USE(iCpuSys);
GET_CPU_AVG_USE(iCpuIoWa);
GET_CPU_AVG_USE(iCpuIrq);
GET_CPU_AVG_USE(iCpuSoftIrq);
GET_CPU_AVG_USE(iCpuSteal);
GET_CPU_AVG_USE(iCpuGuest);
GET_CPU_AVG_USE(iCpuGuestNice);
// idle 的计算使用排除其他项使用率的值
// 注意cpu 整合的使用率 iTotalUse 的值因为取整的原因可能不等于 iCpuUse[0]
g_stCpuUse.iCpuIdle=100-iTotalUse;
for(int i=0; i < g_stCpuUse.iCpuCount; i++) {
GET_CPU_AVG_USE(iCpuUse[i]);
}
#undef GET_CPU_AVG_USE
}
static void ClearCpuAvgUse()
{
g_stCpuUse.bStaticTimes = 0;
g_stCpuUse.iCpuUser = 0;
g_stCpuUse.iCpuNice = 0;
g_stCpuUse.iCpuSys = 0;
g_stCpuUse.iCpuIdle = 0;
g_stCpuUse.iCpuIoWa = 0;
g_stCpuUse.iCpuIrq = 0;
g_stCpuUse.iCpuSoftIrq = 0;
g_stCpuUse.iCpuSteal = 0;
g_stCpuUse.iCpuGuest = 0;
g_stCpuUse.iCpuGuestNice = 0;
for(int i=0; i < g_stCpuUse.iCpuCount; i++) {
g_stCpuUse.iCpuUse[i] = 0;
}
g_stCpuUse.dwProcessNew = 0;
g_stCpuUse.dwCtxt = 0;
}
static void WriteCpuUse()
{
if(g_stCpuUse.iCpuCount <= 0)
return;
CalcuCpuAvgUse();
MtReport_Attr_Set(XRK_CPU_TOTAL_USER, g_stCpuUse.iCpuUser);
MtReport_Attr_Set(XRK_CPU_TOTAL_NICE, g_stCpuUse.iCpuNice);
MtReport_Attr_Set(XRK_CPU_TOTAL_SYS, g_stCpuUse.iCpuSys);
MtReport_Attr_Set(XRK_CPU_TOTAL_IDLE, g_stCpuUse.iCpuIdle);
MtReport_Attr_Set(XRK_CPU_TOTAL_IOWA, g_stCpuUse.iCpuIoWa);
MtReport_Attr_Set(XRK_CPU_TOTAL_IRQ, g_stCpuUse.iCpuIrq);
MtReport_Attr_Set(XRK_CPU_TOTAL_SOFTIRQ, g_stCpuUse.iCpuSoftIrq);
MtReport_Attr_Set(XRK_CPU_TOTAL_STEAL, g_stCpuUse.iCpuSteal);
MtReport_Attr_Set(XRK_CPU_TOTAL_GUEST, g_stCpuUse.iCpuGuest);
MtReport_Attr_Set(XRK_CPU_TOTAL_GUESTNI, g_stCpuUse.iCpuGuestNice);
MtReport_Attr_Add(XRK_TOTAL_CPU_CTXT, g_stCpuUse.dwCtxt);
MtReport_Attr_Add(XRK_PROC_CREATE_COUNT, g_stCpuUse.dwProcessNew);
MtReport_Log_Info("times:%d, cpu total - user:%d, nice:%d, sys:%d, idle:%d, iowa:%d, irq:%d, softirq:%d, "
"steal:%d, guest:%d, guestni:%d, new process:%u, ctxt:%u",
g_stCpuUse.bStaticTimes, g_stCpuUse.iCpuUser, g_stCpuUse.iCpuNice, g_stCpuUse.iCpuSys, g_stCpuUse.iCpuIdle,
g_stCpuUse.iCpuIoWa, g_stCpuUse.iCpuIrq, g_stCpuUse.iCpuSoftIrq, g_stCpuUse.iCpuSteal, g_stCpuUse.iCpuGuest,
g_stCpuUse.iCpuGuestNice, g_stCpuUse.dwProcessNew, g_stCpuUse.dwCtxt);
for(int i=0; i < g_stCpuUse.iCpuCount; i++) {
ReportCpuUse(i, g_stCpuUse.iCpuUse[i]);
}
ClearCpuAvgUse();
WriteCpuLoadAvg();
}
void WriteTcpUdpInfo()
{
if(g_bNotSupportTcpUdp)
return;
MtReport_Attr_Set(XRK_TCP_CONN_COUNT, g_stNetUse.iCurTcpEstab);
MtReport_Attr_Add(XRK_TCP_IN_PACKS, g_stNetUse.dwTcpPackIn);
MtReport_Attr_Add(XRK_TCP_OUT_PACKS, g_stNetUse.dwTcpPackOut);
MtReport_Attr_Add(XRK_UDP_IN_PACKS, g_stNetUse.dwUdpPackIn);
MtReport_Attr_Add(XRK_UDP_OUT_PACKS, g_stNetUse.dwUdpPackOut);
MtReport_Attr_Add(XRK_TCP_PACKS_ERROR, g_stNetUse.iTcpErr);
MtReport_Attr_Add(XRK_UDP_PACKS_ERROR, g_stNetUse.iUdpErr);
MtReport_Log_Info("tcp/udp info - conn:%d, udp in:%u, udp out:%u, tcp in:%u, tcp out:%u, udp error:%d, tcp error:%d",
g_stNetUse.iCurTcpEstab, g_stNetUse.dwTcpPackIn, g_stNetUse.dwTcpPackOut,
g_stNetUse.dwUdpPackIn, g_stNetUse.dwUdpPackOut, g_stNetUse.iUdpErr, g_stNetUse.iTcpErr);
memset(&g_stNetUse, 0, sizeof(g_stNetUse));
}
void ReadNetUse()
{
TTcpUdpInfo stInfo;
if(g_bNotSupportTcpUdp || GetNetTcpUdpInfo(&stInfo) < 0)
return;
g_stNetUse.iCurTcpEstab = stInfo.iCurTcpEstab;
if(stInfo.dwUdpPackIn > g_stNetTcpUdpInfo.dwUdpPackIn)
g_stNetUse.dwUdpPackIn += stInfo.dwUdpPackIn - g_stNetTcpUdpInfo.dwUdpPackIn;
if(stInfo.dwUdpPackOut > g_stNetTcpUdpInfo.dwUdpPackOut)
g_stNetUse.dwUdpPackOut += stInfo.dwUdpPackOut - g_stNetTcpUdpInfo.dwUdpPackOut;
if(stInfo.dwTcpPackIn > g_stNetTcpUdpInfo.dwTcpPackIn)
g_stNetUse.dwTcpPackIn += stInfo.dwTcpPackIn - g_stNetTcpUdpInfo.dwTcpPackIn;
if(stInfo.dwTcpPackOut > g_stNetTcpUdpInfo.dwTcpPackOut)
g_stNetUse.dwTcpPackOut += stInfo.dwTcpPackOut - g_stNetTcpUdpInfo.dwTcpPackOut;
// tcp/udp 错误包监控, 上报日志
if(g_iRemoteUdpPackErrorWarnLog && stInfo.dwUdpInErr > g_stNetTcpUdpInfo.dwUdpInErr) {
MtReport_Log_Warn("udp in packet error: %u", stInfo.dwUdpInErr-g_stNetTcpUdpInfo.dwUdpInErr);
g_stNetUse.iUdpErr += stInfo.dwUdpInErr-g_stNetTcpUdpInfo.dwUdpInErr;
}
if(g_iRemoteUdpPackErrorWarnLog && stInfo.dwUdpNoPorts > g_stNetTcpUdpInfo.dwUdpNoPorts) {
MtReport_Log_Warn("udp in packet no ports error: %u", stInfo.dwUdpNoPorts-g_stNetTcpUdpInfo.dwUdpNoPorts);
g_stNetUse.iUdpErr += stInfo.dwUdpNoPorts-g_stNetTcpUdpInfo.dwUdpNoPorts;
}
if(g_iLocalUdpPackErrorWarnLog && stInfo.dwUdpRecvBufErr > g_stNetTcpUdpInfo.dwUdpRecvBufErr) {
MtReport_Log_Warn("udp recvbuf error: %u", stInfo.dwUdpRecvBufErr-g_stNetTcpUdpInfo.dwUdpRecvBufErr);
g_stNetUse.iUdpErr += stInfo.dwUdpRecvBufErr-g_stNetTcpUdpInfo.dwUdpRecvBufErr;
}
if(g_iLocalUdpPackErrorWarnLog && stInfo.dwUdpSendBufErr > g_stNetTcpUdpInfo.dwUdpSendBufErr) {
MtReport_Log_Warn("udp sendbuf error: %u", stInfo.dwUdpSendBufErr-g_stNetTcpUdpInfo.dwUdpSendBufErr);
g_stNetUse.iUdpErr += stInfo.dwUdpSendBufErr-g_stNetTcpUdpInfo.dwUdpSendBufErr;
}
if(g_iRemoteTcpPackErrorWarnLog && stInfo.dwTcpReSends > g_stNetTcpUdpInfo.dwTcpReSends) {
MtReport_Log_Warn("tcp resend packets error: %u", stInfo.dwTcpReSends-g_stNetTcpUdpInfo.dwTcpReSends);
g_stNetUse.iTcpErr += stInfo.dwTcpReSends-g_stNetTcpUdpInfo.dwTcpReSends;
}
if(g_iRemoteTcpPackErrorWarnLog && stInfo.dwTcpInErr > g_stNetTcpUdpInfo.dwTcpInErr) {
MtReport_Log_Warn("tcp in packets error: %u", stInfo.dwTcpInErr-g_stNetTcpUdpInfo.dwTcpInErr);
g_stNetUse.iTcpErr += stInfo.dwTcpInErr-g_stNetTcpUdpInfo.dwTcpInErr;
}
if(g_iLocalTcpPackErrorWarnLog && stInfo.dwTcpOutRsts > g_stNetTcpUdpInfo.dwTcpOutRsts) {
MtReport_Log_Warn("tcp out packets error: %u", stInfo.dwTcpOutRsts-g_stNetTcpUdpInfo.dwTcpOutRsts);
g_stNetUse.iTcpErr += stInfo.dwTcpOutRsts-g_stNetTcpUdpInfo.dwTcpOutRsts;
}
memcpy(&g_stNetTcpUdpInfo, &stInfo, sizeof(stInfo));
}
static void ReadCpuUse()
{
static TcpuUse stCpuUse;
if(g_stCpuUse.iCpuCount <= 0)
return;
memset(&stCpuUse, 0, sizeof(stCpuUse));
if(GetCpuUse(&stCpuUse) <= 0)
{
MtReport_Log_Warn("GetCpuUse failed !");
return;
}
g_stBaseInfo.iCpuUsePercent = stCpuUse.iCpuUse[0]/10;
if(stCpuUse.iCpuUse[0]%10)
g_stBaseInfo.iCpuUsePercent++;
for(int i=0; i < g_stCpuUse.iCpuCount; i++)
g_stCpuUse.iCpuUse[i] += stCpuUse.iCpuUse[i];
g_stCpuUse.iCpuUser += stCpuUse.iCpuUser;
g_stCpuUse.iCpuSys += stCpuUse.iCpuSys;
g_stCpuUse.iCpuIdle += stCpuUse.iCpuIdle;
g_stCpuUse.iCpuIoWa += stCpuUse.iCpuIoWa;
g_stCpuUse.iCpuIrq += stCpuUse.iCpuIrq ;
g_stCpuUse.iCpuSoftIrq += stCpuUse.iCpuSoftIrq;
g_stCpuUse.dwCtxt += stCpuUse.dwCtxt;
g_stCpuUse.dwProcessNew += stCpuUse.dwProcessNew;
g_stCpuUse.bStaticTimes ++;
}
static void WriteMemUse()
{
if(g_stMemUse.bStaticTimes > 0) {
g_stMemUse.iMemUse /= g_stMemUse.bStaticTimes;
g_stMemUse.iSwapUse /= g_stMemUse.bStaticTimes;
MtReport_Attr_Set(XRK_MEM_USE, g_stMemUse.iMemUse);
MtReport_Attr_Set(XRK_SWAP_MEM_USE, g_stMemUse.iSwapUse);
MtReport_Attr_Set(XRK_MEM_AVAILABLE, g_stMemUse.dwAvailable);
MtReport_Log_Info("report mem info, use:%d, swap use:%d, available:%ukB",
g_stMemUse.iMemUse, g_stMemUse.iSwapUse, g_stMemUse.dwAvailable);
memset(&g_stMemUse, 0, sizeof(g_stMemUse));
}
}
static TDiskInfo *GetDiskInfo(const char *pname)
{
std::map<std::string, TDiskInfo>::iterator it = g_stDiskInfo.find(pname);
if(it != g_stDiskInfo.end())
return (TDiskInfo*)&(it->second);
return NULL;
}
static void WriteDiskIoStat()
{
if(!g_pDiskStatAry || !g_pDiskStatAryForTable)
return;
static TDiskStatInfo * s_pDiskStatAry = NULL;
if(!s_pDiskStatAry) {
s_pDiskStatAry = new TDiskStatInfo[g_iMaxDiskStatCount];
if(!s_pDiskStatAry) {
MtReport_Log_Error("new TDiskStatInfo failed, count:%d, msg:%s", g_iMaxDiskStatCount, strerror(errno));
return;
}
}
static uint32_t s_dwLastWriteTableDiskInfoTime = g_dwCurTimeSec;
int iDiskStatCount = 0;
if((iDiskStatCount=ReadDiskStatInfo(s_pDiskStatAry, g_iMaxDiskStatCount)) < 0)
return;
if(iDiskStatCount != g_iDiskStatCount) {
MtReport_Log_Warn("disk stat count changed (%d, %d)", iDiskStatCount, g_iDiskStatCount);
memcpy(g_pDiskStatAry, s_pDiskStatAry, iDiskStatCount*sizeof(*s_pDiskStatAry));
g_iDiskStatCount = iDiskStatCount;
return;
}
uint32_t dwReadTimes = 0;
uint32_t dwMergeReadTimes = 0;
uint32_t dwReadSectors = 0;
uint32_t dwReadTimeMs = 0;
uint32_t dwWriteTimes = 0;
uint32_t dwMergeWriteTimes = 0;
uint32_t dwWriteSectors = 0;
uint32_t dwWriteTimeMs = 0;
uint32_t dwIOTimeMs = 0;
uint32_t dwIOTotalTimeMs = 0;
for(int i=0, len=0; i < iDiskStatCount; i++) {
if(g_iDiskReadTimesWarnCfg > 0
&& s_pDiskStatAry[i].dwReadTimes > g_pDiskStatAry[i].dwReadTimes+g_iDiskReadTimesWarnCfg) {
MtReport_Log_Warn("disk:%s read times:%u over:%d", s_pDiskStatAry[i].szDevName,
s_pDiskStatAry[i].dwReadTimes-g_pDiskStatAry[i].dwReadTimes, g_iDiskReadTimesWarnCfg);
}
if(g_iDiskWriteTimesWarnCfg > 0
&& s_pDiskStatAry[i].dwWriteTimes > g_pDiskStatAry[i].dwWriteTimes+g_iDiskWriteTimesWarnCfg) {
MtReport_Log_Warn("disk:%s writes times:%u over:%d", s_pDiskStatAry[i].szDevName,
s_pDiskStatAry[i].dwWriteTimes-g_pDiskStatAry[i].dwWriteTimes, g_iDiskWriteTimesWarnCfg);
}
if(g_iReadSectorsWarnCfg > 0
&& s_pDiskStatAry[i].dwReadSectors > g_pDiskStatAry[i].dwReadSectors+g_iReadSectorsWarnCfg) {
MtReport_Log_Warn("disk:%s read sectors:%u over:%d", s_pDiskStatAry[i].szDevName,
s_pDiskStatAry[i].dwReadSectors-g_pDiskStatAry[i].dwReadSectors, g_iReadSectorsWarnCfg);
}
if(g_iWriteSectorsWarnCfg > 0
&& s_pDiskStatAry[i].dwWriteSectors > g_pDiskStatAry[i].dwWriteSectors+g_iWriteSectorsWarnCfg) {
MtReport_Log_Warn("disk:%s writes sectors:%u over:%d", s_pDiskStatAry[i].szDevName,
s_pDiskStatAry[i].dwWriteSectors-g_pDiskStatAry[i].dwWriteSectors, g_iWriteSectorsWarnCfg);
}
if(g_iIoUseTimeMsWarnCfg > 0
&& s_pDiskStatAry[i].dwIOTotalTimeMs > g_pDiskStatAry[i].dwIOTotalTimeMs+g_iIoUseTimeMsWarnCfg) {
MtReport_Log_Warn("disk:%s io use time:%u over:%d", s_pDiskStatAry[i].szDevName,
s_pDiskStatAry[i].dwIOTotalTimeMs-g_pDiskStatAry[i].dwIOTotalTimeMs, g_iIoUseTimeMsWarnCfg);
}
len = strlen(s_pDiskStatAry[i].szDevName);
if(isdigit(s_pDiskStatAry[i].szDevName[len-1]))
continue;
#define DISK_STAT_STATICS(field) do { \
if(s_pDiskStatAry[i].field > g_pDiskStatAry[i].field) \
field += s_pDiskStatAry[i].field - g_pDiskStatAry[i].field; \
}while(0)
DISK_STAT_STATICS(dwReadTimes);
DISK_STAT_STATICS(dwMergeReadTimes);
DISK_STAT_STATICS(dwReadSectors);
DISK_STAT_STATICS(dwReadTimeMs);
DISK_STAT_STATICS(dwWriteTimes);
DISK_STAT_STATICS(dwMergeWriteTimes);
DISK_STAT_STATICS(dwWriteSectors);
DISK_STAT_STATICS(dwWriteTimeMs);
DISK_STAT_STATICS(dwIOTimeMs);
DISK_STAT_STATICS(dwIOTotalTimeMs);
#undef DISK_STAT_STATICS
}
MtReport_Attr_Add(XRK_DISK_R_TIMES, dwReadTimes);
MtReport_Attr_Add(XRK_DISK_MERGE_R_TIMES, dwMergeReadTimes);
MtReport_Attr_Add(XRK_DISK_R_SECTORS, dwReadSectors);
MtReport_Attr_Add(XRK_DISK_R_USE_MS, dwReadTimeMs);
MtReport_Attr_Add(XRK_DISK_W_TIMES, dwWriteTimes);
MtReport_Attr_Add(XRK_DISK_MERGE_W_TIMES, dwMergeWriteTimes);
MtReport_Attr_Add(XRK_DISK_W_SECTORS, dwWriteSectors);
MtReport_Attr_Add(XRK_DISK_W_USE_MS, dwWriteTimeMs);
MtReport_Attr_Add(XRK_DISK_IO_USE_MS, dwIOTotalTimeMs);
memcpy(g_pDiskStatAry, s_pDiskStatAry, iDiskStatCount*sizeof(*s_pDiskStatAry));
char sMountBuf[512] = {0};
if(g_dwCurTimeSec >= s_dwLastWriteTableDiskInfoTime+g_iTableDiskStatAllStaticTime) {
for(int i=0, len=0; i < iDiskStatCount; i++) {
len = strlen(s_pDiskStatAry[i].szDevName);
if(!isdigit(s_pDiskStatAry[i].szDevName[len-1]))
continue;
#define DISK_STAT_STATICS_FOR_TABLE(field) do { \
if(s_pDiskStatAry[i].field > g_pDiskStatAryForTable[i].field) \
field = s_pDiskStatAry[i].field - g_pDiskStatAryForTable[i].field; \
else \
field = 0; \
}while(0)
DISK_STAT_STATICS_FOR_TABLE(dwReadTimes);
DISK_STAT_STATICS_FOR_TABLE(dwMergeReadTimes);
DISK_STAT_STATICS_FOR_TABLE(dwReadSectors);
DISK_STAT_STATICS_FOR_TABLE(dwReadTimeMs);
DISK_STAT_STATICS_FOR_TABLE(dwWriteTimes);
DISK_STAT_STATICS_FOR_TABLE(dwMergeWriteTimes);
DISK_STAT_STATICS_FOR_TABLE(dwWriteSectors);
DISK_STAT_STATICS_FOR_TABLE(dwWriteTimeMs);
DISK_STAT_STATICS_FOR_TABLE(dwIOTimeMs);
DISK_STAT_STATICS_FOR_TABLE(dwIOTotalTimeMs);
TDiskInfo *pdiskInfo = GetDiskInfo(s_pDiskStatAry[i].szDevName);
if(pdiskInfo)
strncpy(sMountBuf, pdiskInfo->strMount.c_str(), sizeof(sMountBuf)-1);
else
strcpy(sMountBuf, "null");
int iRet = MtReport_Plugin_Table(
XRK_PLUGIN_ID, XRK_TABLE_DISK_STAT_ALL, g_iTableDiskStatAllStaticTime, g_dwCurTimeSec,
"%d#%s$%d#%s$%d#%lu$%d#%u$%d#%u$%d#%u$%d#%u$%d#%u$%d#%u$%d#%u$%d#%u",
XRK_FLD_DISK_PART_NAME, XRK_PLUGIN_TABLE_STR_CHANGE(s_pDiskStatAry[i].szDevName),
XRK_FLD_DISK_MOUNT, XRK_PLUGIN_TABLE_STR_CHANGE(sMountBuf),
XRK_FLD_DISK_SPACE, (pdiskInfo ? pdiskInfo->qwSizeK: 0),
XRK_FLD_DISK_R_TIMES, dwReadTimes,
XRK_FLD_DISK_W_TIMES, dwWriteTimes,
XRK_FLD_DISK_R_SECTORS, dwReadSectors,
XRK_FLD_DISK_W_SECTORS, dwWriteSectors,
XRK_FLD_DISK_R_USE_MS, dwReadTimeMs,
XRK_FLD_DISK_W_USE_MS, dwWriteTimeMs,
XRK_FLD_DISK_IO_USE_MS, dwIOTotalTimeMs,
XRK_FLD_DISK_USE_PERCENT,
(pdiskInfo ? (uint32_t)ceil(pdiskInfo->qwUsed*100.0/(pdiskInfo->qwUsed+pdiskInfo->qwRemain)) : 0));
if(iRet != 0)
MtReport_Log_Error("report realtime table(%d) failed, ret:%d", XRK_TABLE_NET_DEV_ALL, iRet);
#undef DISK_STAT_STATICS_FOR_TABLE_FOR_TABLE
}
s_dwLastWriteTableDiskInfoTime = g_dwCurTimeSec;
memcpy(g_pDiskStatAryForTable, s_pDiskStatAry, iDiskStatCount*sizeof(*s_pDiskStatAry));
}
MtReport_Log_Info("disk io stat: read:%u, write:%u, merge read:%u, mrege write:%u, read sector:%u, write sector:%u"
", read use ms:%u, write use ms:%u, io total use:(%u, %u)",
dwReadTimes, dwWriteTimes, dwMergeReadTimes, dwMergeWriteTimes, dwReadSectors, dwWriteSectors,
dwReadTimeMs, dwWriteTimeMs, dwIOTimeMs, dwIOTotalTimeMs);
}
static void WriteDiskUse()
{
uint64_t qwTotalSpace = 0, qwTotalUse = 0;
uint32_t maxUsePer = 0;
if(GetDiskInfo(qwTotalSpace, qwTotalUse, maxUsePer) < 0)
return;
uint32_t dwUsePerTotal = (uint32_t)ceil((qwTotalUse*100.0/qwTotalSpace));
g_stBaseInfo.dwDiskTotalSpace = qwTotalSpace;
g_stBaseInfo.iDiskUsePercent = dwUsePerTotal;
MtReport_Attr_Set(XRK_DISK_TOTAL_USE, dwUsePerTotal);
MtReport_Attr_Set(XRK_DISK_USE_MAX, maxUsePer);
if(maxUsePer > 95)
MtReport_Attr_Add(XRK_DISK_USE_OVER_95, 1);
else if(maxUsePer > 90)
MtReport_Attr_Add(XRK_DISK_USE_OVER_90, 1);
else if(maxUsePer > 80)
MtReport_Attr_Add(XRK_DISK_USE_OVER_80, 1);
else if(maxUsePer > 70)
MtReport_Attr_Add(XRK_DISK_USE_OVER_70, 1);
MtReport_Log_Info("get disk use total percent:%u%%, max use percent:%u%%", dwUsePerTotal, maxUsePer);
}
int InitAttrConfig(std::string &conf)
{
char *pattrs = strdup(XRK_PLUGIN_ALL_ATTRS);
if(pattrs == NULL)
return ERROR_LINE;
char *pmem = pattrs;
char *pattr = NULL, *psave = NULL;
const char *pfirst = NULL, *plast = NULL;
int i = 0, iAttrId = 0;
for(; i < XRK_PLUGIN_ATTRS_COUNT_MAX; i++)
{
pattr = strtok_r(pattrs, " ", &psave);
if(NULL == pattr) {
i++;
break;
}
if(LoadConfig(conf.c_str(), pattr, CFG_INT, &iAttrId, 0, (void*)NULL) < 0) {
MtReport_Log_Error("read attr:%s from file:%s failed", pattr, conf.c_str());
break;
}
g_aryPluginAttr[i] = iAttrId;
MtReport_Log_Debug("read attr config:%s, attr id:%d, ary index:%d", pattr, iAttrId, i);
if(i==0)
pfirst = pattr;
else if(i+1 == XRK_PLUGIN_ATTRS_COUNT_MAX)
plast = pattr;
pattrs = NULL;
}
if(i < XRK_PLUGIN_ATTRS_COUNT_MAX) {
MtReport_Log_Error("read attr failed (%d, %d), pattr:%p", i, XRK_PLUGIN_ATTRS_COUNT_MAX, pattr);
free(pmem);
return ERROR_LINE;
}
MtReport_Log_Info("read attr count:%d, first:(%s,%d), last:(%s,%d)",
i, pfirst, g_aryPluginAttr[0], plast, g_aryPluginAttr[i-1]);
free(pmem);
return 0;
}
// 插件初始化函数
int SlogPlusInit()
{
// 读取配置文件
std::string strPlugConfFile("./xrk_");
strPlugConfFile += g_strPluginName;
strPlugConfFile += ".conf";
int iRet = 0, iPluginId = 0;
char szVersion[32] = {0};
if((iRet=LoadConfig(strPlugConfFile.c_str(),
"XRK_PLUGIN_CONFIG_FILE_VER", CFG_STRING, szVersion, "", sizeof(szVersion),
"READ_BASEINFO_PER_TIME_SEC", CFG_INT, &g_iReadInfoPerTimeSec, 5,
"REPORT_BASEINFO_PER_TIME_SEC", CFG_INT, &g_iReportInfoPerTimeSec, 20,
"NOT_MONITOR_NET_LO", CFG_INT, &g_iNotMonitorNetLo, 0,
"MAX_DISKSTAT_COUNT", CFG_INT, &g_iMaxDiskStatCount, 500,
"XRK_PLUGIN_ID", CFG_INT, &iPluginId, 0,
"DISK_IO_READ_TIMES_WARN", CFG_INT, &g_iDiskReadTimesWarnCfg, 0,
"DISK_IO_WRITE_TIMES_WARN", CFG_INT, &g_iDiskWriteTimesWarnCfg, 0,
"DISK_IO_READ_SECTORS_WARN", CFG_INT, &g_iReadSectorsWarnCfg, 0,
"DISK_IO_WRITE_SECTORS_WARN", CFG_INT, &g_iWriteSectorsWarnCfg, 0,
"TCP_PACK_LOCAL_ERROR_WARN", CFG_INT, &g_iLocalTcpPackErrorWarnLog, 1,
"UDP_PACK_LOCAL_ERROR_WARN", CFG_INT, &g_iLocalUdpPackErrorWarnLog, 1,
"TCP_PACK_REMOTE_ERROR_WARN", CFG_INT, &g_iRemoteTcpPackErrorWarnLog, 0,
"UDP_PACK_REMOTE_ERROR_WARN", CFG_INT, &g_iRemoteUdpPackErrorWarnLog, 0,
"XRK_TABLE_BASE_INFO_STATIC_TIME", CFG_INT, &g_iTableBaseInfoStaticTime, XRK_TABLE_BASE_INFO_DEF_STAT_TIME,
"XRK_TABLE_DISK_STAT_ALL_STATIC_TIME", CFG_INT, &g_iTableDiskStatAllStaticTime, XRK_TABLE_DISK_STAT_ALL_DEF_STAT_TIME,
"XRK_TABLE_NET_DEV_ALL_STATIC_TIME", CFG_INT, &g_iTableNetDevAllStaticTime, XRK_TABLE_NET_DEV_ALL_DEF_STAT_TIME,
"XRK_TABLE_NET_TU_PACK_STAT_STATIC_TIME", CFG_INT, &g_iTableNetTuPackStatStaticTime, XRK_TABLE_NET_TU_PACK_STAT_DEF_STAT_TIME,
"XRK_TABLE_CPU_ALL_STAT_STATIC_TIME", CFG_INT, &g_iTableCpuAllStatStaticTime, XRK_TABLE_CPU_ALL_STAT_DEF_STAT_TIME,
"XRK_TABLE_MEM_STAT_STATIC_TIME", CFG_INT, &g_iTableMemStatStaticTime, XRK_TABLE_MEM_STAT_DEF_STAT_TIME,
(void*)NULL)) < 0)
{
fprintf(stderr, "loadconfig from:%s failed, msg:%s !\n", strPlugConfFile.c_str(), strerror(errno));
return ERROR_LINE;
}
#define CHECK_TABLE_STATIC_TIME(table_time) \
if(table_time < 10) \
table_time = 10; \
else if(table_time > 86400) \
table_time = 86400; \
if(g_iReadInfoPerTimeSec > table_time) \
g_iReadInfoPerTimeSec = table_time; \
if(g_iReportInfoPerTimeSec > table_time) \
g_iReportInfoPerTimeSec = table_time;
CHECK_TABLE_STATIC_TIME(g_iTableBaseInfoStaticTime);
CHECK_TABLE_STATIC_TIME(g_iTableDiskStatAllStaticTime);
CHECK_TABLE_STATIC_TIME(g_iTableNetDevAllStaticTime);
CHECK_TABLE_STATIC_TIME(g_iTableNetTuPackStatStaticTime);
CHECK_TABLE_STATIC_TIME(g_iTableCpuAllStatStaticTime);
CHECK_TABLE_STATIC_TIME(g_iTableMemStatStaticTime);
#undef CHECK_TABLE_STATIC_TIME
if(g_iReadInfoPerTimeSec < 1)
g_iReadInfoPerTimeSec = 1;
else if(g_iReadInfoPerTimeSec > 30)
g_iReadInfoPerTimeSec = 30;
if(g_iReportInfoPerTimeSec < 10)
g_iReportInfoPerTimeSec = 10;
else if(g_iReportInfoPerTimeSec > 50)
g_iReportInfoPerTimeSec = 50;
if(g_iReportInfoPerTimeSec <= g_iReadInfoPerTimeSec)
g_iReportInfoPerTimeSec = g_iReadInfoPerTimeSec+1;
if(g_iMaxDiskStatCount < 10)
g_iMaxDiskStatCount = 10;
else if(g_iMaxDiskStatCount > 1024)
g_iMaxDiskStatCount = 1024;
iRet = MtReport_Plus_Init(
strPlugConfFile.c_str(), iPluginId, XRK_PLUGIN_NAME, XRK_PLUGIN_HEADER_FILE_VER);
if(iRet < 0 || g_mtReport.pMtShm == NULL) {
return ERROR_LINE;
}
// 从这里开始可以使用库的相关接口了
if((iRet=InitAttrConfig(strPlugConfFile)) < 0)
{
fprintf(stderr, "read plugin attr info failed, ret:%d\n", iRet);
MtReport_Log_Error("read plugin attr info failed:%d", iRet);
return ERROR_LINE;
}
// 版本号检查, 配置文件版本号需要大于等于编译版本号,即插件配置向后兼容
// 配置文件的版本号不断增长,但可执行文件版本号变化较少
if(!IsPluginVersionOk(szVersion, XRK_PLUGIN_HEADER_FILE_VER)) {
MtReport_Log_Warn("check version failed, %s < %s", szVersion, XRK_PLUGIN_HEADER_FILE_VER);
}
memset(&g_stBaseInfo, 0, sizeof(g_stBaseInfo));
// cpu 监控 -- start
if((iRet=InitGetCpuUse()) <= 0) {
MtReport_Log_Error("InitGetCpuUse failed !");
g_stCpuUse.iCpuCount = 0;
}
else {
int iCount = MAX_CPU_SUPPORT+1;
if(iCount > iRet)
iCount = iRet;
g_stCpuUse.iCpuCount = iCount;
}
// 网络
InitGetNet();
if(GetNetTcpUdpInfo(&g_stNetTcpUdpInfo) < 0)
g_bNotSupportTcpUdp = true;
else
g_bNotSupportTcpUdp = false;
// 磁盘
g_pDiskStatAry = new TDiskStatInfo[g_iMaxDiskStatCount];
g_pDiskStatAryForTable = new TDiskStatInfo[g_iMaxDiskStatCount];
if(!g_pDiskStatAry || !g_pDiskStatAryForTable) {
MtReport_Log_Error("new TDiskStatInfo failed, count:%d, msg:%s", g_iMaxDiskStatCount, strerror(errno));
return -1;
}
if((g_iDiskStatCount=InitReadDiskStatInfo(g_pDiskStatAry, g_iMaxDiskStatCount)) < 0) {
delete [] g_pDiskStatAry;
g_pDiskStatAry = NULL;
}
memcpy(g_pDiskStatAryForTable, g_pDiskStatAry, g_iDiskStatCount*sizeof(TDiskStatInfo));
GetCpuInfo();
MtReport_Log_Info("plugin:%s init ok, cpu count:%d, disk stat count:%d, cpu info:%s",
XRK_PLUGIN_NAME, g_stCpuUse.iCpuCount-1, g_iDiskStatCount, g_szCpuInfo);
return 0;
}
// 插件逻辑实现函数,请勿在该函数中睡眠/阻塞
void SlogPlusOnLoop(uint32_t dwTimeNow)
{
static uint32_t s_dwLastReadTime=dwTimeNow;
static uint32_t s_dwLastWriteTime=dwTimeNow;
// for table
static uint32_t s_dwLastWriteTableBaseTime = dwTimeNow;
// 实时表格
if(dwTimeNow >= s_dwLastWriteTableBaseTime+g_iTableBaseInfoStaticTime)
{
int iRet = MtReport_Plugin_Table(
XRK_PLUGIN_ID, XRK_TABLE_BASE_INFO, g_iTableBaseInfoStaticTime, g_dwCurTimeSec,
"%d#%u$%d#%d$%d#%u$%d#%d$%d#%d$%d#%s$%d#%lu$%d#%lu",
XRK_FLD_DISK_TOTAL_SPACE, g_stBaseInfo.dwDiskTotalSpace,
XRK_FLD_DISK_USE, g_stBaseInfo.iDiskUsePercent,
XRK_FLD_MEM_SIZE, g_stBaseInfo.dwMemSpace,
XRK_FLD_MEM_USE, g_stBaseInfo.iMemUsePercent,
XRK_FLD_CPU_USE, g_stBaseInfo.iCpuUsePercent,
XRK_FLD_CPU_INFO, g_szCpuInfo,
XRK_FLD_NET_T_SENDB, g_stBaseInfo.qwSendBytes/1024,
XRK_FLD_NET_T_RECVB, g_stBaseInfo.qwRecvBytes/1024);
if(iRet != 0)
MtReport_Log_Error("report realtime table(%d) failed, ret:%d", XRK_TABLE_NET_DEV_ALL, iRet);
g_stBaseInfo.qwSendBytes = 0;
g_stBaseInfo.qwRecvBytes = 0;
s_dwLastWriteTableBaseTime = dwTimeNow;
}
// 采集数据
if(dwTimeNow >= s_dwLastReadTime+g_iReadInfoPerTimeSec)
{
ReadCpuUse();
ReadNetUse();
ReadMemUse();
s_dwLastReadTime = dwTimeNow;
}
// 上报数据
if(dwTimeNow >= s_dwLastWriteTime+g_iReportInfoPerTimeSec)
{
WriteCpuUse();
ReportNetInfo();
WriteTcpUdpInfo();
WriteDiskUse();
WriteDiskIoStat();
WriteMemUse();
s_dwLastWriteTime = dwTimeNow;
}
int iRet = MtReport_Plus_Hello(dwTimeNow);
if(iRet) {
MtReport_Log_Error("plugin check failed, ret:%d", iRet);
// 避免被 crontab 自动拉起
system("./stop.sh > /dev/null 2>&1");
s_exit = true;
}
}
void deal_exist_sig(int sig)
{
MtReport_Log_Info("plugin:%s, get exist signal:%d", XRK_PLUGIN_NAME, sig);
s_exit = true;
}
void Deamon()
{
daemon(1, 1);
RegisterSignal(CORE_INFO_FILE, NULL, NULL);
signal(SIGUSR1, deal_exist_sig);
}
int main(int argc, char *argv[])
{
if(SlogPlusInit() < 0)
return -1;
Deamon();
while(!s_exit) {
g_dwCurTimeSec = time(NULL);
SlogPlusOnLoop(g_dwCurTimeSec);
usleep(1000+rand()%1000000);
}
if(g_pDiskStatAry) {
delete [] g_pDiskStatAry;
delete [] g_pDiskStatAryForTable;
}
return 0;
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。