一,需求
对于一条链路来说,它有几个基本属性:链路类型linktype,通道号ChanId,链路状态linkStatus,丢包率dropRate,错包率errorRate,抖动shake
当前有N条SCCP链路,SCCP链路类型为SCCP,通道ID为1—N
现在需要为该类型的链路实现一个报警系统:
当前某条链路如果有以下异常需要上报告警
1. 链路状态故障,告警ID为1:当该链路的linkStatus 为0的时候上报该告警。
2. 上报丢包率过大告警,告警ID为2: 当链路的dropRate大于5时,上报该告警。
由于链路太多,一次全部检查影响性能,因此需要每次轮询1/5的链路。如果该链路有以上异常,则上报对应告警。
3. 上报抖动过大告警,告警ID为3:当该链路的shake大于20的时候上报该告警。
4. 上报错包率过大告警,告警ID为4: 当链路的errorRate大于10时,上报该告警。
新增 M3UA链路类型,当M3UA有以下异常需要上报告警
1. 链路状态故障,告警ID为100:当该链路的linkStatus 为0的时候上报该告警。
2. 上报丢包率过大告警,告警ID为101: 当链路的dropRate大于13时,上报该告警。
3. 上报抖动过大告警,告警ID为102:当该链路的shake大于19的时候上报该告警。
新增 M2UA链路类型,当M2UA有以下异常需要上报告警
1. 链路状态故障,告警ID为200:当该链路的linkStatus 为0的时候上报该告警。
2. 上报抖动过大告警,告警ID为201:当该链路的shake大于11的时候上报该告警。
3. 上报错包率过大告警,告警ID为202: 当链路的errorRate大于15时,上报该告警。
注:类型不一致的链路,通道ID可以相同
二,实现
头文件
#include "mylist.h"
#include "stdlib.h"
#include "stdio.h"
#ifdef __cplusplus
extern "C" {
#endif
#define LINKTYPENUM 3
typedef enum LinkType{
SCCP,
M3UA,
M2UA
}LinkType;
typedef struct Link{
LinkType linkType;
int chanId;
int linkstatus;
int dropRate;
int errorRate;
int shake;
}Link;
typedef struct Alert{
int alertId;
int chanId;
}Alert;
typedef struct Checker{
int (*checkFunc)(Link link);
int alertId[LINKTYPENUM];
}Checker;
void Init();
void CheckLinks();
int getAlertNum();
#ifdef __cplusplus
}
#endif
源文件
//
// Created by w00371255 on 2020/11/17.
//
#include "unitest.h"
#define MAXLINK 400
#define N 100
#define MAXLALERT (MAXLINK*2)
static Link links[MAXLINK];
static int linkNum;
static Alert alerts[MAXLALERT];
static int alertNum;
void Init()
{
memset((void *)links, 0, sizeof(links));
linkNum = N*3;
alertNum = 0;
for(int i=1; i<=linkNum; i++){
links[i].linkType = i/N;
links[i].chanId = i%N;
links[i].linkstatus = i%2;
links[i].dropRate = i%20;
links[i].errorRate = i%20;
links[i].shake = i%40;
}
}
static int IsBadLink(Link link)
{
return link.linkstatus==0;
}
int overDropDeadLine[]={5,13,100};
static int IsOverDropLink(Link link)
{
return link.dropRate>overDropDeadLine[link.linkType];
}
int overShakeDeadLine[]={20,19,11};
static int IsOverShake(Link link)
{
return link.shake>overShakeDeadLine[link.linkType];
}
int overErrDeadLine[]={10,100,15};
static int IsOverError(Link link)
{
return link.errorRate>overErrDeadLine[link.linkType];
}
static void Alertlink(Alert alert)
{
printf("alertId: %d, chanId: %d \n", alert.alertId, alert.chanId);
if(alertNum<MAXLALERT) {
alerts[alertNum++] = alert;
}else{
printf("too much alert!");
}
}
Checker checker[]={
{IsBadLink,{1,100,200}},
{IsOverDropLink,{2,101,-1}},
{IsOverShake,{3,102,201}},
{IsOverError,{4,-1,202}}
};
static void CheckALink(Link link)
{
Alert alert;
alert.chanId=link.chanId;
int checkerNum=sizeof(checker)/sizeof(checker[0]);
for(int i=0;i<checkerNum;i++) {
if (checker[i].checkFunc(link)) {
alert.alertId = checker[i].alertId[link.linkType];
Alertlink(alert);
}
}
}
void CheckLinks()
{
int len=N*LINKTYPENUM/5;
for(int i=0;i<len;i++){
CheckALink(links[i*5+1]);
}
}
int getAlertNum()
{
return alertNum;
}
测试
TEST(MockCppTest, checkLinks) {
Init();
CheckLinks();
ASSERT_EQ(getAlertNum(),96);
}