一,需求

对于一条链路来说,它有几个基本属性:链路类型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);
}