storm 打印debug日志

本文介绍如何通过修改storm集群中的logback配置文件来启用debug级别的日志记录,并提供了不需要重启storm即可生效的方法。
storm 打印debug日志

storm采用了slf4j+logback方式,storm根路径下有个logback文件夹,下面有cluster.xml ,对storm日志的配置。
想要输出debug模式的数据,修改Supervisors 下cluster.xml文件即可,
<root level="DEBUG">
<appender-ref ref="A1"/>
</root>
另:不用重启storm,就能生效

http://www.cnblogs.com/zhuawang/p/3999235.html
http://www.cnblogs.com/aquastone/p/storm_log4j_or_logback.html
http://m.blog.youkuaiyun.com/blog/caodaoxi/8961575
给这个代码加上详细的注释: static STATUS _qosPortMibUpdateCb() { // DW("_qosPortMibUpdateCb"); int ret = ERR_NO_ERROR; char *key = NULL; void *handler = NULL; user_port logicPort = {}; user_port physicalPort = {}; QOS_PORT_RATE_DIFF_STRUCT rateDiff = {}; UINT64 ingressVal = 0; UINT64 egressVal = 0; UINT64 bcVal = 0; UINT64 mcVal = 0; UINT32 rate = 0; TIMER_ID recoverTimer; TIMER_ID_INIT(recoverTimer); struct timespec timer = {}; char strUp[STR_STRUP_SIZE] = {}; char timerName[STR_TIMER_NAME_SIZE] = {}; APPQOS_ADCFG_OPT optCfg = {}; QOS_PORT_STATUS portStatus = {}; UINT32 lagId = 0; UINT8 shutdownFlag = 0; NTFY_QOS qosNtfy = {}; MAC_ADDRESS sysMac = {}; char macStr[STR_MAC_SIZE] = {}; char portStr[STR_STRUP_SIZE] = {}; memset(macStr, 0, 20); libStkSysDevMacGet(UNIT_CURRENT, sysMac); ether2str(macStr, sysMac, CSL_UPCASE, STR_TRANS_CLI); qosTrapCounter++; if (qosTrapCounter >= QOS_STORM_EXCEED_LOG_CYCLE) { qosTrapCounter = 0; l_ingressLogEnable = TRUE; l_egressLogEnable = TRUE; l_bcLogEnable = TRUE; l_mcLogEnable = TRUE; } /* 置位flag */ BOOL f_ingressLogEnable = FALSE; BOOL f_egressLogEnable = FALSE; BOOL f_bcLogEnable = FALSE; BOOL f_mcLogEnable = FALSE; dal_ado_t *adoi; adoi = dalAsdoiCreate(DMP_DEV_NAME_SWITCHMAC, DAL_MOD_PORT, DAL_CFG_TYPE_ENTRY); APPL_ENSURE_DONE(ret, adoi, ERR_NO_MEMORY); dalAdoiEntryTableAppend(adoi, DAL_PORT_K_MIB); dalAdoiEntryOperAppend(adoi, DAL_PORT_K_MIB, DAL_OPER_GET_ALL); if (PFM_ERR_C_OK != dalGet(adoi)) { ret = ERR_BAD_PARAM; goto done; } if (NULL != (handler = DAL_ADOI_ENTRY(adoi, DAL_PORT_K_MIB))) { DAL_ADOI_ENTRY_LOOP(handler) { if(NULL == (key = DAL_ADOI_ENTRY_KEY(handler)) || !DAL_ADOI_ENTRY_KEY_MATCH(handler, DAL_PORT_K_MIB_ALL)) { continue; } DAL_PORT_KEY_MIB_PARSE_TO_UP(key, physicalPort); /* QOS_TODO:所有端口启用功能并且link-up时存在性能问题 get交换机的时间戳,通过绝对时间来处理 */ adQosGetPortLinkStatus(physicalPort, &portStatus); if (portStatus.status == DISABLE) { continue; } /* KEY inner field&value loop */ if (DAL_ADOI_ENTRY_KEY_EMPTY(handler)) { QOS_DEBUG_COMMON("Invalid operation: deleting Fixed entries!"); } else { DAL_ADOI_ENTRY_FIELD_LOOP(handler, key) { if (DAL_ADOI_ENTRY_FIELD_MATCH(handler, DAL_PORT_K_MIB_F_RXBYTEDIFF)) { dalAdoiGetEntryUI64(adoi, DAL_PORT_K_MIB, &rateDiff.rxbyteDiff); } else if (DAL_ADOI_ENTRY_FIELD_MATCH(handler, DAL_PORT_K_MIB_F_TXBYTEDIFF)) { dalAdoiGetEntryUI64(adoi, DAL_PORT_K_MIB, &rateDiff.txbyteDiff); } else if (DAL_ADOI_ENTRY_FIELD_MATCH(handler, DAL_PORT_K_MIB_F_BCNUMDIFF)) { dalAdoiGetEntryUI64(adoi, DAL_PORT_K_MIB, &rateDiff.bcNumDiff); } else if (DAL_ADOI_ENTRY_FIELD_MATCH(handler, DAL_PORT_K_MIB_F_MCNUMDIFF)) { dalAdoiGetEntryUI64(adoi, DAL_PORT_K_MIB, &rateDiff.mcNumDiff); } } } qosGetLagIdOfPort(physicalPort, &lagId); if (lagId) { UP_FROM_LAG(logicPort, lagId); } else { memcpy(&logicPort, &physicalPort, sizeof(user_port)); } ret = dataQosGetPortConfig(logicPort, &optCfg); if (ret != ERR_NO_ERROR) { continue; } if(optCfg.stormLogging) { QOS_DEBUG("upIdx:%d, rxbyteDiff:%d, txbyteDiff:%d, bcNumDiff:%d, mcNumDiff:%d", UP_INDEX(logicPort), rateDiff.rxbyteDiff, rateDiff.txbyteDiff, rateDiff.bcNumDiff, rateDiff.mcNumDiff); } /* 入口带宽阈值 Byte/s */ ingressVal = (UINT64)(optCfg.ingressRateValue) * QOS_RATE_KBPS_THOUSAND / QOS_IFG_DELAY; /*1(sec)*1000*/ /* 口带宽阈值 Byte/s */ egressVal = (UINT64)(optCfg.egressRateValue) * QOS_RATE_KBPS_THOUSAND / QOS_IFG_DELAY; if (QOS_RATE_MODE_PPS != optCfg.rateMode) //PPS(包速率模式)、KBPS(kbit模式)、RATIO(端口带宽模式) { if (QOS_RATE_MODE_KBPS == optCfg.rateMode) { /* 广播流量阈值 */ bcVal = (UINT64)(optCfg.bcRate) * QOS_RATE_KBPS_THOUSAND / QOS_IFG_DELAY; /* 组播流量阈值 */ mcVal = (UINT64)(optCfg.mcRate) * QOS_RATE_KBPS_THOUSAND / QOS_IFG_DELAY; } else if (QOS_RATE_MODE_RATIO == optCfg.rateMode) { rate = optCfg.bcRate; _rateValueTransform(logicPort, &rate); bcVal = (UINT64)(rate)*QOS_RATE_KBPS_THOUSAND / QOS_IFG_DELAY; rate = optCfg.mcRate; _rateValueTransform(logicPort, &rate); mcVal = (UINT64)(rate)*QOS_RATE_KBPS_THOUSAND / QOS_IFG_DELAY; } } else { bcVal = (UINT64)optCfg.bcRate; /*1 sec*/ mcVal = (UINT64)optCfg.mcRate; } /* 入口带宽超限 */ if (optCfg.ingressRateValue && rateDiff.rxbyteDiff > ingressVal) { if (l_ingressLogEnable) { //QOS_TODO: snmp trap、controller log f_ingressLogEnable = TRUE; QDW("ingress exceed:%d", UP_PORT(physicalPort)); memset(&qosNtfy, 0, sizeof(qosNtfy)); qosNtfy.physicalPort = physicalPort; qosNtfy.ingressRate = optCfg.ingressRateValue; stateQosSnmpTrapSet(QOS_SNMP_TRAP_TYPE_BANDWIDTH_INGRESS, &qosNtfy); //触发告警 PORT_UP2STR(physicalPort, portStr); QOS_ADD_LOG_ONE_PARA(LOG_QOS_PORT_INGRESS_REACH, portStr); //触发日志 } } else { /*bc trap & notify*/ if (optCfg.bcRate && QOS_RATE_MODE_PPS != optCfg.rateMode && (rateDiff.rxbyteDiff > bcVal)&&(QOS_RATE_ADJUST_PAR * rateDiff.bcNumDiff >= bcVal)) { double factor = 1; int packet_length = rateDiff.rxbyteDiff/rateDiff.bcNumDiff; AD_QOS_RATE_ADJUST_BY_PACKET_LENGTH(factor, packet_length); QOS_DEBUG_COMMON("factor %4f, rateValNew.rxbyteDiff %d",factor,rateDiff.rxbyteDiff); if(rateDiff.rxbyteDiff >= factor * bcVal) { shutdownFlag = TRUE; if (l_bcLogEnable) { //QOS_TODO: snmp trap、controller log f_bcLogEnable = TRUE; QDW("bc exceed:%d",UP_PORT(physicalPort)); memset(&qosNtfy, 0, sizeof(qosNtfy)); qosNtfy.physicalPort = physicalPort; qosNtfy.bcastRate = optCfg.bcRate; qosNtfy.bcastMode = optCfg.rateMode; stateQosSnmpTrapSet(QOS_SNMP_TRAP_TYPE_STORM_CTRL_BCAST, &qosNtfy); stateQosPortStormOccursSet(physicalPort, QOS_RATE_STORM_MODE_BC, TRUE); if (optCfg.stormLogging) { PORT_UP2STR(physicalPort, portStr); QOS_ADD_LOG_ONE_PARA(LOG_QOS_BCSTORM_CONTROL_REACH, portStr); syslogAdd_omada(QOS_LOG_MODULE_NAME, LOG_OMADA_STORM_DETECTED, OMADA_KEY_OSW_STORM, OMD_ALERT_REPORT, portStr, (ULONG)"Broadcast", (ULONG)macStr, (ULONG)portStr, 0, 0, 0); } } } } if (optCfg.bcRate && QOS_RATE_MODE_PPS == optCfg.rateMode && rateDiff.bcNumDiff >= bcVal) { shutdownFlag = TRUE; if (l_bcLogEnable) { //QOS_TODO: snmp trap、controller log f_bcLogEnable = TRUE; QDW("bc exceed:%d",UP_PORT(physicalPort)); memset(&qosNtfy, 0, sizeof(qosNtfy)); qosNtfy.physicalPort = physicalPort; qosNtfy.bcastRate = optCfg.bcRate; qosNtfy.bcastMode = optCfg.rateMode; stateQosSnmpTrapSet(QOS_SNMP_TRAP_TYPE_STORM_CTRL_BCAST, &qosNtfy); stateQosPortStormOccursSet(physicalPort, QOS_RATE_STORM_MODE_BC, TRUE); if (optCfg.stormLogging) { PORT_UP2STR(physicalPort, portStr); QOS_ADD_LOG_ONE_PARA(LOG_QOS_BCSTORM_CONTROL_REACH, portStr); syslogAdd_omada(QOS_LOG_MODULE_NAME, LOG_OMADA_STORM_DETECTED, OMADA_KEY_OSW_STORM, OMD_ALERT_REPORT, portStr, (ULONG)"Broadcast", (ULONG)macStr, (ULONG)portStr, 0, 0, 0); } } } /*mc trap & notify*/ if (optCfg.mcRate && QOS_RATE_MODE_PPS != optCfg.rateMode && (rateDiff.rxbyteDiff > mcVal) && (QOS_RATE_ADJUST_PAR * rateDiff.mcNumDiff >= mcVal)) { double factor = 1; int packet_length = rateDiff.rxbyteDiff/rateDiff.mcNumDiff; AD_QOS_RATE_ADJUST_BY_PACKET_LENGTH(factor, packet_length); QOS_DEBUG_COMMON("factor %4f, rateValNew.rxbyteDiff %d",factor,rateDiff.rxbyteDiff); if(rateDiff.rxbyteDiff >= factor * mcVal) { shutdownFlag = TRUE; if (l_mcLogEnable) { //QOS_TODO: snmp trap、controller log f_mcLogEnable = TRUE; QDW("mc exceed:%d",UP_PORT(physicalPort)); memset(&qosNtfy, 0, sizeof(qosNtfy)); qosNtfy.physicalPort = physicalPort; qosNtfy.mcastRate = optCfg.mcRate; qosNtfy.mcastMode = optCfg.rateMode; stateQosSnmpTrapSet(QOS_SNMP_TRAP_TYPE_STORM_CTRL_MCAST, &qosNtfy); stateQosPortStormOccursSet(physicalPort, QOS_RATE_STORM_MODE_MC, TRUE); if (optCfg.stormLogging) { PORT_UP2STR(physicalPort, portStr); QOS_ADD_LOG_ONE_PARA(LOG_QOS_MCSTORM_CONTROL_REACH, portStr); syslogAdd_omada(QOS_LOG_MODULE_NAME, LOG_OMADA_STORM_DETECTED, OMADA_KEY_OSW_STORM, OMD_ALERT_REPORT, portStr, (ULONG)"Multicast", (ULONG)macStr, (ULONG)portStr, 0, 0, 0); } } } } } if (optCfg.egressRateValue && rateDiff.txbyteDiff > egressVal) { if (l_egressLogEnable) { //QOS_TODO: snmp trap、syslog、controller log f_egressLogEnable = TRUE; QDW("egress exceed:%d",UP_PORT(physicalPort)); memset(&qosNtfy, 0, sizeof(qosNtfy)); qosNtfy.physicalPort = physicalPort; qosNtfy.egressRate = optCfg.egressRateValue; stateQosSnmpTrapSet(QOS_SNMP_TRAP_TYPE_BANDWIDTH_EGRESS, &qosNtfy); PORT_UP2STR(physicalPort, portStr); QOS_ADD_LOG_ONE_PARA(LOG_QOS_PORT_EGRESS_REACH, portStr); } } /*if port belong to a LAG, the optCfg is LAG rate Config*/ if (optCfg.stormOper == QOS_STORM_EXCEED_SHUTDOWN && shutdownFlag /* && portStatus */) { QOS_DEBUG("QOS_STORM_EXCEED_SHUTDOWN"); shutdownFlag = FALSE; adQosSetPortState(physicalPort, DISABLE); stateQosPortBlockStatusSet(physicalPort, ENABLE); PORT_UP2STR(physicalPort, portStr); QOS_ADD_LOG_ONE_PARA(LOG_QOS_PORT_STORM_CONTROL_SHUTDOWN, portStr); syslogAdd_omada(QOS_LOG_MODULE_NAME, LOG_OMADA_STORM_SHUTDOWN, OMADA_KEY_OSW_PB, OMD_ALERT_REPORT, portStr, (ULONG)macStr, (ULONG)portStr, 0, 0, 0, 0); //QOS_TODO:堆叠时,向master发送notify更新block信息 if (optCfg.recoverTime) { if (UP_IS_LAG(logicPort)) dataQosRcvrTimerIdLagGet(physicalPort,&recoverTimer); else dataQosRcvrTimerIdPhyGet(logicPort,&recoverTimer); /*add timer, LAG member set their own logic timer ID: check the timer value, if not 0, LAG has a timer*/ /* controller独有bug,定时器存在,需删除*/ if (TIMER_ID_IS_VALID(recoverTimer)) { DEL_TIMER(recoverTimer); } timer.tv_sec = optCfg.recoverTime; timer.tv_nsec = 0; user_port upArr[2] = {}; upArr[0] = physicalPort; upArr[1] = logicPort; usUp2Str(upArr[0],strUp,UP_STR_BRF_PRFX); snprintf(timerName, sizeof(timerName), "qosRecoverTime:%s",strUp); if (UP_IS_LAG(logicPort)) { recoverTimer = add_timer(timerName, &timer, _qosRateRecoverTimerNotify, upArr, sizeof(upArr), EXECUTE_SINGLE); if (TIMER_ID_IS_VALID(recoverTimer)) dataQosRcvrTimerIdLagSet(physicalPort, recoverTimer); } else { recoverTimer = add_timer(timerName, &timer, _qosRateRecoverTimerNotify, upArr, sizeof(upArr), EXECUTE_SINGLE); if (TIMER_ID_IS_VALID(recoverTimer)) dataQosRcvrTimerIdPhySet(physicalPort, recoverTimer); } } } if(f_ingressLogEnable) { l_ingressLogEnable = FALSE; f_ingressLogEnable = FALSE; } if(f_egressLogEnable) { l_egressLogEnable = FALSE; f_egressLogEnable = FALSE; } if(f_bcLogEnable) { l_bcLogEnable = FALSE; f_bcLogEnable = FALSE; } if(f_mcLogEnable) { l_mcLogEnable = FALSE; f_mcLogEnable = FALSE; } }//end loop handler } done: if(adoi) { dalAdoiDestroy(adoi); } return ret; }
最新发布
11-27
<think> 我们正在为一段C语言函数添加详细注释。这段代码看起来是用于网络设备中QoS(服务质量)端口监控的回调函数,主要功能是检查端口的流量是否超过设定阈值,并在超过时触发相应的操作(如告警、日志、端口关闭等)。 我们将逐行或逐段添加注释,解释代码的功能。 注意:由于代码较长,我们将分段注释。同时,由于代码中使用了大量宏和自定义数据类型,我们只能根据上下文和命名推测其含义,但会尽量清晰地解释。 开始注释: </think>以下是为代码添加的详细注释,解释了每个关键部分的功能和逻辑: ```c static STATUS _qosPortMibUpdateCb() { // 函数返回值初始化 int ret = ERR_NO_ERROR; char *key = NULL; // 用于存储MIB表项的键 void *handler = NULL; // MIB表项处理句柄 // 定义逻辑端口和物理端口结构 user_port logicPort = {}; user_port physicalPort = {}; // 存储端口速率差异的结构体 QOS_PORT_RATE_DIFF_STRUCT rateDiff = {}; // 各种流量统计值 UINT64 ingressVal = 0; // 入口带宽阈值 UINT64 egressVal = 0; // 口带宽阈值 UINT64 bcVal = 0; // 广播流量阈值 UINT64 mcVal = 0; // 组播流量阈值 UINT32 rate = 0; // 临时速率值 // 定时器相关变量(用于端口恢复) TIMER_ID recoverTimer; TIMER_ID_INIT(recoverTimer); // 初始化定时器ID struct timespec timer = {}; // 定时器时间结构 char strUp[STR_STRUP_SIZE] = {}; // 端口字符串缓冲区 char timerName[STR_TIMER_NAME_SIZE] = {}; // 定时器名称缓冲区 // QoS配置和状态变量 APPQOS_ADCFG_OPT optCfg = {}; // 端口QoS配置 QOS_PORT_STATUS portStatus = {}; // 端口状态 UINT32 lagId = 0; // LAG(链路聚合组)ID UINT8 shutdownFlag = 0; // 端口关闭标志 // 通知和日志相关变量 NTFY_QOS qosNtfy = {}; // SNMP陷阱通知结构 MAC_ADDRESS sysMac = {}; // 系统MAC地址 char macStr[STR_MAC_SIZE] = {}; // MAC字符串缓冲区 char portStr[STR_STRUP_SIZE] = {}; // 端口字符串缓冲区 // 获取系统MAC并转换为字符串 memset(macStr, 0, 20); libStkSysDevMacGet(UNIT_CURRENT, sysMac); ether2str(macStr, sysMac, CSL_UPCASE, STR_TRANS_CLI); // 风暴控制日志周期管理 qosTrapCounter++; if (qosTrapCounter >= QOS_STORM_EXCEED_LOG_CYCLE) { qosTrapCounter = 0; // 启用所有类型的日志记录 l_ingressLogEnable = TRUE; l_egressLogEnable = TRUE; l_bcLogEnable = TRUE; l_mcLogEnable = TRUE; } // 临时日志标志 BOOL f_ingressLogEnable = FALSE; BOOL f_egressLogEnable = FALSE; BOOL f_bcLogEnable = FALSE; BOOL f_mcLogEnable = FALSE; // 创建ADOI对象(抽象数据对象接口)用于获取MIB数据 dal_ado_t *adoi; adoi = dalAsdoiCreate(DMP_DEV_NAME_SWITCHMAC, DAL_MOD_PORT, DAL_CFG_TYPE_ENTRY); APPL_ENSURE_DONE(ret, adoi, ERR_NO_MEMORY); // 确保对象创建成功 // 配置ADOI操作:获取所有端口的MIB数据 dalAdoiEntryTableAppend(adoi, DAL_PORT_K_MIB); dalAdoiEntryOperAppend(adoi, DAL_PORT_K_MIB, DAL_OPER_GET_ALL); if (PFM_ERR_C_OK != dalGet(adoi)) { ret = ERR_BAD_PARAM; goto done; // 获取数据失败则跳转到清理环节 } // 遍历所有MIB表项 if (NULL != (handler = DAL_ADOI_ENTRY(adoi, DAL_PORT_K_MIB))) { DAL_ADOI_ENTRY_LOOP(handler) { // 遍历每个表项 // 获取当前表项的key if (NULL == (key = DAL_ADOI_ENTRY_KEY(handler)) || !DAL_ADOI_ENTRY_KEY_MATCH(handler, DAL_PORT_K_MIB_ALL)) { continue; // 无效key则跳过 } // 从key解析物理端口 DAL_PORT_KEY_MIB_PARSE_TO_UP(key, physicalPort); // 检查端口状态(禁用则跳过) adQosGetPortLinkStatus(physicalPort, &portStatus); if (portStatus.status == DISABLE) { continue; } // 遍历表项的所有字段 if (DAL_ADOI_ENTRY_KEY_EMPTY(handler)) { QOS_DEBUG_COMMON("Invalid operation: deleting Fixed entries!"); } else { DAL_ADOI_ENTRY_FIELD_LOOP(handler, key) { // 提取不同MIB字段的值到rateDiff结构 if (DAL_ADOI_ENTRY_FIELD_MATCH(handler, DAL_PORT_K_MIB_F_RXBYTEDIFF)) { dalAdoiGetEntryUI64(adoi, DAL_PORT_K_MIB, &rateDiff.rxbyteDiff); } else if (DAL_ADOI_ENTRY_FIELD_MATCH(handler, DAL_PORT_K_MIB_F_TXBYTEDIFF)) { dalAdoiGetEntryUI64(adoi, DAL_PORT_K_MIB, &rateDiff.txbyteDiff); } else if (DAL_ADOI_ENTRY_FIELD_MATCH(handler, DAL_PORT_K_MIB_F_BCNUMDIFF)) { dalAdoiGetEntryUI64(adoi, DAL_PORT_K_MIB, &rateDiff.bcNumDiff); } else if (DAL_ADOI_ENTRY_FIELD_MATCH(handler, DAL_PORT_K_MIB_F_MCNUMDIFF)) { dalAdoiGetEntryUI64(adoi, DAL_PORT_K_MIB, &rateDiff.mcNumDiff); } } } // 获取端口所属的LAG组(如果存在) qosGetLagIdOfPort(physicalPort, &lagId); if (lagId) { UP_FROM_LAG(logicPort, lagId); // 如果是LAG成员,使用逻辑端口 } else { memcpy(&logicPort, &physicalPort, sizeof(user_port)); // 否则使用物理端口 } // 获取端口的QoS配置 ret = dataQosGetPortConfig(logicPort, &optCfg); if (ret != ERR_NO_ERROR) { continue; // 获取失败则跳过 } // 调试日志打印流量统计 if (optCfg.stormLogging) { QOS_DEBUG("upIdx:%d, rxbyteDiff:%d, txbyteDiff:%d, bcNumDiff:%d, mcNumDiff:%d", UP_INDEX(logicPort), rateDiff.rxbyteDiff, rateDiff.txbyteDiff, rateDiff.bcNumDiff, rateDiff.mcNumDiff); } // 计算入口/口带宽阈值(转换为字节/秒) ingressVal = (UINT64)(optCfg.ingressRateValue) * QOS_RATE_KBPS_THOUSAND / QOS_IFG_DELAY; egressVal = (UINT64)(optCfg.egressRateValue) * QOS_RATE_KBPS_THOUSAND / QOS_IFG_DELAY; // 根据速率模式计算广播/组播阈值 if (QOS_RATE_MODE_PPS != optCfg.rateMode) { if (QOS_RATE_MODE_KBPS == optCfg.rateMode) { bcVal = (UINT64)(optCfg.bcRate) * QOS_RATE_KBPS_THOUSAND / QOS_IFG_DELAY; mcVal = (UINT64)(optCfg.mcRate) * QOS_RATE_KBPS_THOUSAND / QOS_IFG_DELAY; } else if (QOS_RATE_MODE_RATIO == optCfg.rateMode) { rate = optCfg.bcRate; _rateValueTransform(logicPort, &rate); // 比例模式转换 bcVal = (UINT64)(rate) * QOS_RATE_KBPS_THOUSAND / QOS_IFG_DELAY; rate = optCfg.mcRate; _rateValueTransform(logicPort, &rate); mcVal = (UINT64)(rate) * QOS_RATE_KBPS_THOUSAND / QOS_IFG_DELAY; } } else { // 包速率模式(PPS) bcVal = (UINT64)optCfg.bcRate; mcVal = (UINT64)optCfg.mcRate; } /* ========== 阈值检测与响应 ========== */ // 入口带宽超限检测 if (optCfg.ingressRateValue && rateDiff.rxbyteDiff > ingressVal) { if (l_ingressLogEnable) { f_ingressLogEnable = TRUE; QDW("ingress exceed:%d", UP_PORT(physicalPort)); memset(&qosNtfy, 0, sizeof(qosNtfy)); qosNtfy.physicalPort = physicalPort; qosNtfy.ingressRate = optCfg.ingressRateValue; // 触发SNMP陷阱和系统日志 stateQosSnmpTrapSet(QOS_SNMP_TRAP_TYPE_BANDWIDTH_INGRESS, &qosNtfy); PORT_UP2STR(physicalPort, portStr); QOS_ADD_LOG_ONE_PARA(LOG_QOS_PORT_INGRESS_REACH, portStr); } } else { // 广播风暴检测(非PPS模式) if (optCfg.bcRate && QOS_RATE_MODE_PPS != optCfg.rateMode && (rateDiff.rxbyteDiff > bcVal) && (QOS_RATE_ADJUST_PAR * rateDiff.bcNumDiff >= bcVal)) { // 基于包长度调整阈值 double factor = 1; int packet_length = rateDiff.rxbyteDiff / rateDiff.bcNumDiff; AD_QOS_RATE_ADJUST_BY_PACKET_LENGTH(factor, packet_length); QOS_DEBUG_COMMON("factor %4f, rateValNew.rxbyteDiff %d", factor, rateDiff.rxbyteDiff); if (rateDiff.rxbyteDiff >= factor * bcVal) { shutdownFlag = TRUE; if (l_bcLogEnable) { f_bcLogEnable = TRUE; QDW("bc exceed:%d", UP_PORT(physicalPort)); memset(&qosNtfy, 0, sizeof(qosNtfy)); qosNtfy.physicalPort = physicalPort; qosNtfy.bcastRate = optCfg.bcRate; qosNtfy.bcastMode = optCfg.rateMode; // 触发广播风暴事件 stateQosSnmpTrapSet(QOS_SNMP_TRAP_TYPE_STORM_CTRL_BCAST, &qosNtfy); stateQosPortStormOccursSet(physicalPort, QOS_RATE_STORM_MODE_BC, TRUE); if (optCfg.stormLogging) { PORT_UP2STR(physicalPort, portStr); QOS_ADD_LOG_ONE_PARA(LOG_QOS_BCSTORM_CONTROL_REACH, portStr); syslogAdd_omada(QOS_LOG_MODULE_NAME, LOG_OMADA_STORM_DETECTED, OMADA_KEY_OSW_STORM, OMD_ALERT_REPORT, portStr, (ULONG)"Broadcast", (ULONG)macStr, (ULONG)portStr, 0, 0, 0); } } } } // 广播风暴检测(PPS模式) if (optCfg.bcRate && QOS_RATE_MODE_PPS == optCfg.rateMode && rateDiff.bcNumDiff >= bcVal) { shutdownFlag = TRUE; if (l_bcLogEnable) { f_bcLogEnable = TRUE; QDW("bc exceed:%d", UP_PORT(physicalPort)); memset(&qosNtfy, 0, sizeof(qosNtfy)); qosNtfy.physicalPort = physicalPort; qosNtfy.bcastRate = optCfg.bcRate; qosNtfy.bcastMode = optCfg.rateMode; stateQosSnmpTrapSet(QOS_SNMP_TRAP_TYPE_STORM_CTRL_BCAST, &qosNtfy); stateQosPortStormOccursSet(physicalPort, QOS_RATE_STORM_MODE_BC, TRUE); if (optCfg.stormLogging) { PORT_UP2STR(physicalPort, portStr); QOS_ADD_LOG_ONE_PARA(LOG_QOS_BCSTORM_CONTROL_REACH, portStr); syslogAdd_omada(QOS_LOG_MODULE_NAME, LOG_OMADA_STORM_DETECTED, OMADA_KEY_OSW_STORM, OMD_ALERT_REPORT, portStr, (ULONG)"Broadcast", (ULONG)macStr, (ULONG)portStr, 0, 0, 0); } } } // 组播风暴检测 if (optCfg.mcRate && QOS_RATE_MODE_PPS != optCfg.rateMode && (rateDiff.rxbyteDiff > mcVal) && (QOS_RATE_ADJUST_PAR * rateDiff.mcNumDiff >= mcVal)) { double factor = 1; int packet_length = rateDiff.rxbyteDiff / rateDiff.mcNumDiff; AD_QOS_RATE_ADJUST_BY_PACKET_LENGTH(factor, packet_length); QOS_DEBUG_COMMON("factor %4f, rateValNew.rxbyteDiff %d", factor, rateDiff.rxbyteDiff); if (rateDiff.rxbyteDiff >= factor * mcVal) { shutdownFlag = TRUE; if (l_mcLogEnable) { f_mcLogEnable = TRUE; QDW("mc exceed:%d", UP_PORT(physicalPort)); memset(&qosNtfy, 0, sizeof(qosNtfy)); qosNtfy.physicalPort = physicalPort; qosNtfy.mcastRate = optCfg.mcRate; qosNtfy.mcastMode = optCfg.rateMode; // 触发组播风暴事件 stateQosSnmpTrapSet(QOS_SNMP_TRAP_TYPE_STORM_CTRL_MCAST, &qosNtfy); stateQosPortStormOccursSet(physicalPort, QOS_RATE_STORM_MODE_MC, TRUE); if (optCfg.stormLogging) { PORT_UP2STR(physicalPort, portStr); QOS_ADD_LOG_ONE_PARA(LOG_QOS_MCSTORM_CONTROL_REACH, portStr); syslogAdd_omada(QOS_LOG_MODULE_NAME, LOG_OMADA_STORM_DETECTED, OMADA_KEY_OSW_STORM, OMD_ALERT_REPORT, portStr, (ULONG)"Multicast", (ULONG)macStr, (ULONG)portStr, 0, 0, 0); } } } } } // 口带宽超限检测 if (optCfg.egressRateValue && rateDiff.txbyteDiff > egressVal) { if (l_egressLogEnable) { f_egressLogEnable = TRUE; QDW("egress exceed:%d", UP_PORT(physicalPort)); memset(&qosNtfy, 0, sizeof(qosNtfy)); qosNtfy.physicalPort = physicalPort; qosNtfy.egressRate = optCfg.egressRateValue; stateQosSnmpTrapSet(QOS_SNMP_TRAP_TYPE_BANDWIDTH_EGRESS, &qosNtfy); PORT_UP2STR(physicalPort, portStr); QOS_ADD_LOG_ONE_PARA(LOG_QOS_PORT_EGRESS_REACH, portStr); } } /* ========== 端口关闭与恢复 ========== */ // 如果检测到风暴且配置要求关闭端口 if (optCfg.stormOper == QOS_STORM_EXCEED_SHUTDOWN && shutdownFlag) { QOS_DEBUG("QOS_STORM_EXCEED_SHUTDOWN"); shutdownFlag = FALSE; // 禁用物理端口 adQosSetPortState(physicalPort, DISABLE); stateQosPortBlockStatusSet(physicalPort, ENABLE); PORT_UP2STR(physicalPort, portStr); QOS_ADD_LOG_ONE_PARA(LOG_QOS_PORT_STORM_CONTROL_SHUTDOWN, portStr); syslogAdd_omada(QOS_LOG_MODULE_NAME, LOG_OMADA_STORM_SHUTDOWN, OMADA_KEY_OSW_PB, OMD_ALERT_REPORT, portStr, (ULONG)macStr, (ULONG)portStr, 0, 0, 0, 0); // 配置端口恢复定时器 if (optCfg.recoverTime) { // 获取现有定时器(如果存在) if (UP_IS_LAG(logicPort)) dataQosRcvrTimerIdLagGet(physicalPort, &recoverTimer); else dataQosRcvrTimerIdPhyGet(logicPort, &recoverTimer); // 删除现有定时器 if (TIMER_ID_IS_VALID(recoverTimer)) { DEL_TIMER(recoverTimer); } // 设置新定时器 timer.tv_sec = optCfg.recoverTime; timer.tv_nsec = 0; user_port upArr[2] = {}; upArr[0] = physicalPort; upArr[1] = logicPort; usUp2Str(upArr[0], strUp, UP_STR_BRF_PRFX); snprintf(timerName, sizeof(timerName), "qosRecoverTime:%s", strUp); // 创建定时器(区分LAG和物理端口) if (UP_IS_LAG(logicPort)) { recoverTimer = add_timer(timerName, &timer, _qosRateRecoverTimerNotify, upArr, sizeof(upArr), EXECUTE_SINGLE); if (TIMER_ID_IS_VALID(recoverTimer)) dataQosRcvrTimerIdLagSet(physicalPort, recoverTimer); } else { recoverTimer = add_timer(timerName, &timer, _qosRateRecoverTimerNotify, upArr, sizeof(upArr), EXECUTE_SINGLE); if (TIMER_ID_IS_VALID(recoverTimer)) dataQosRcvrTimerIdPhySet(physicalPort, recoverTimer); } } } // 重置临时日志标志 if (f_ingressLogEnable) { l_ingressLogEnable = FALSE; f_ingressLogEnable = FALSE; } if (f_egressLogEnable) { l_egressLogEnable = FALSE; f_egressLogEnable = FALSE; } if (f_bcLogEnable) { l_bcLogEnable = FALSE; f_bcLogEnable = FALSE; } if (f_mcLogEnable) { l_mcLogEnable = FALSE; f_mcLogEnable = FALSE; } } // end of handler loop } done: // 清理ADOI对象 if (adoi) { dalAdoiDestroy(adoi); } return ret; } ``` ### 代码功能总结 1. **数据采集**:通过ADOI接口获取所有端口的MIB(管理信息库)统计信息 2. **端口处理**: - 区分物理端口和逻辑端口(LAG成员) - 跳过禁用/断开状态的端口 3. **阈值计算**: - 根据配置的QoS策略(PPS/KBPS/RATIO模式)计算各类流量阈值 - 包含包长度自适应调整因子 4. **风暴检测**: - 入口/口带宽超限 - 广播/组播风暴(分PPS和非PPS模式) 5. **响应机制**: - 生成SNMP陷阱 - 记录系统日志 - 关闭违规端口(可配置自动恢复定时器) 6. **日志控制**: - 周期性启用详细日志 - 单次事件后禁用同类日志(防风暴) ### 关键设计特点 - 支持链路聚合组(LAG)的集中管理 - 提供三种流量控制模式(包速率/比特速率/端口比例) - 包长度自适应的阈值调整机制 - 定时器驱动的端口自动恢复 - 日志风暴保护(周期计数器控制)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值