diff --git a/src/modules/nms_cxy/service/performance.impl.go b/src/modules/nms_cxy/service/performance.impl.go index 512b421..7e6549d 100644 --- a/src/modules/nms_cxy/service/performance.impl.go +++ b/src/modules/nms_cxy/service/performance.impl.go @@ -3,19 +3,24 @@ package service import ( "fmt" "nms_cxy/src/framework/constants/uploadsubpath" + "nms_cxy/src/framework/logger" "nms_cxy/src/framework/utils/file" neDataModel "nms_cxy/src/modules/network_data/model" neDataService "nms_cxy/src/modules/network_data/service" + neService "nms_cxy/src/modules/network_element/service" "nms_cxy/src/modules/nms_cxy/utils/common" ) // 实例化数据层 PerformanceImpl 结构体 var NewPerformanceImpl = &PerformanceImpl{ + neInfoService: neService.NewNeInfoImpl, perfKPIService: neDataService.NewPerfKPIImpl, } // 性能数据处理服务 服务层处理 type PerformanceImpl struct { + // 网元信息服务 + neInfoService neService.INeInfo // 统计信息服务 perfKPIService neDataService.IPerfKPI } @@ -23,41 +28,44 @@ type PerformanceImpl struct { // PerformanceUploadOSS 性能数据上报 // 性能数据文件的上报周期为15分钟。 func (s *PerformanceImpl) PerformanceUploadOSS(neType, startTime, endTime string) error { - dataArr := [][]string{} - - // 标题行 - titleData := s.perfKPIService.SelectGoldKPITitle(neType) - titleArr := []string{} - for _, v := range titleData { - titleArr = append(titleArr, v.KPIID) + // 查网元 + neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(neType, "001") + if neInfo.NeType != neType { + logger.Errorf("ConfigUploadOSS ne info not fount") + return fmt.Errorf("no ne info") } - titleArr = append(titleArr, "neType", "neName", "startIndex", "timeGroup") - dataArr = append(dataArr, titleArr) // 数据行 query := neDataModel.GoldKPIQuery{ - NeType: neType, + RmUID: neInfo.RmUID, + NeType: neInfo.NeType, StartTime: startTime, EndTime: endTime, Interval: 900, } data := s.perfKPIService.SelectGoldKPI(query) - for _, v := range data { - itemLen := len(v) - dataItem := make([]string, len(v)) - for j, titleStr := range titleArr { - if strV, ok := v[titleStr]; ok && strV != nil { - fmt.Println("titleArr ", titleStr, strV) - dataItem[j] = fmt.Sprint(strV) - } - } + if len(data) == 0 { + logger.Errorf("PerformanceUploadOSS SelectGoldKPI neType:%s startTime:%s endTime:%s", neType, startTime, endTime) + return fmt.Errorf("not Performance data") + } - dataItem[itemLen-4] = fmt.Sprint(v["neType"]) - dataItem[itemLen-3] = fmt.Sprint(v["neName"]) - dataItem[itemLen-2] = fmt.Sprint(v["startIndex"]) - dataItem[itemLen-1] = fmt.Sprint(v["timeGroup"]) - dataArr = append(dataArr, dataItem) + // 转换数据 + parseDataArr := [][]string{} + if neInfo.NeType == "AMF" { + parseDataArr = s.parseDataAMF(neInfo.RmUID, neInfo.NeName, data) + } + if neInfo.NeType == "UPF" { + parseDataArr = s.parseDataUPF(neInfo.RmUID, neInfo.NeName, data) + } + if neInfo.NeType == "UDM" { + parseDataArr = s.parseDataUDM(neInfo.RmUID, neInfo.NeName, data) + } + if neInfo.NeType == "SMF" { + parseDataArr = s.parseDataSMF(neInfo.RmUID, neInfo.NeName, data) + } + if neInfo.NeType == "NSSF" { + parseDataArr = s.parseDataNSSF(neInfo.RmUID, neInfo.NeName, data) } // 文件名 @@ -66,10 +74,737 @@ func (s *PerformanceImpl) PerformanceUploadOSS(neType, startTime, endTime string } fileName := dataSaveFileName.CSV() filePath := fmt.Sprintf("%s/%s", file.ParseUploadFileDir(uploadsubpath.EXPORT), fileName) - err := file.WriterFileCSV(dataArr, filePath) + err := file.WriterFileCSV(parseDataArr, filePath) if err != nil { return err } return common.UploadOSSByZip(filePath, neType, "PM") } + +// parseDataAMF PM数据AMF +func (s *PerformanceImpl) parseDataAMF(ruid, userLabel string, data []map[string]any) [][]string { + parseDataArr := [][]string{} + // 数据行头 + headerArr := []string{ + // 资源对象的RUID及UserLabel + "RUID", "UserLabel", + // PA + "AMF.AuthReq", // 鉴权请求次数 + "AMF.AuthFail", // 鉴权参数错误次数 + "AMF.AuthFail.20", // MAC错误导致的鉴权参数错误次数 + "AMF.AuthFail.21", // 非5G鉴权导致的鉴权参数错误次数 + "AMF.AuthFail.26", // 同步失败导致的鉴权参数错误次数 + "AMF.AuthReject", // 鉴权拒绝次数 + // PB + "AMF.RegSub", // AMF注册态用户数 + "AMF.RegSub.CmIdle", // AMF空闲态用户数 + "AMF.RegSub.CmConnected", // AMF连接态用户数 + "AMF.RegSub_NS", // 每网络切片的AMF注册用户数 + // PC + "AMF.AttInitReg", // 初始注册请求次数 + "AMF.SuccInitReg", // 初始注册成功次数 + "AMF.FailedInitReg", // 初始注册失败次数 + "AMF.FailedInitReg._Cause", // 分原因值的初始注册失败次数 + "AMF.FailedInitReg.3", // 初始注册失败次数_非法用户 + "AMF.FailedInitReg.5", // 初始注册失败次数_PEI不允许 + "AMF.FailedInitReg.6", // 初始注册失败次数_非法设备 + "AMF.FailedInitReg.7", // 初始注册失败次数_5GS服务不允许 + "AMF.FailedInitReg.7.User", // 初始注册失败次数_5GS服务不允许_用户原因 + "AMF.FailedInitReg.15", // 初始注册失败次数_跟踪区内无合适小区 + "AMF.FailedInitReg.15.User", // 初始注册失败次数_跟踪区内无合适小区_用户原因 + "AMF.InitRegTime", // 初始注册平均时长 + // PD + "AMF.RegUpdReq", // 注册更新请求次数 + "AMF.RegUpdReq.Mob.InterAmf", // AMF间移动性注册更新请求次数 + "AMF.RegUpdReq.Mob.IntraAmf", // AMF内移动性注册更新请求次数 + "AMF.RegUpdReq.Per", // 周期性注册更新请求次数 + "AMF.RegUpdAcpt", // 注册更新接受次数 + "AMF.RegUpdAcpt.Mob.InterAmf", // AMF间移动性注册更新接受次数 + "AMF.RegUpdAcpt.Mob.IntraAmf", // AMF内移动性注册更新接受次数 + "AMF.RegUpdAcpt.Per", // 周期性注册更新接受次数 + "AMF.RegUpdRej", // 注册更新失败次数 + "AMF.RegUpdRej._Cause", // 分原因的注册更新失败次数 + "AMF.RegUpdRej.3", // 注册更新失败次数(非法用户) + "AMF.RegUpdRej.6", // 注册更新失败次数(非法设备) + "AMF.RegUpdRej.7", // 注册更新失败次数(5GS服务不允许) + // PE + "AMF.PagAtt", // 寻呼请求次数 AMF的寻呼请求次数。不包括二次寻呼(二次及二次以上统称为二次寻呼)请求次数。 + "AMF.FirstPagingSucc", // 一次寻呼响应次数 "一次寻呼成功次数。 " + "AMF.SecondPagingSucc", // 二次寻呼响应次数 二次(及二次以上)寻呼成功次数。 + "AMF.AttServiceReq", // 业务请求尝试次数 "UE发起的业务请求次数 " + "AMF.FailServiceReq", // 业务请求被拒次数 UE发起业务请求被拒绝个数 + "AMF.FailServiceReq._Cause", // 分原因的业务请求被拒次数 + // PF + "AMF.AttIntraAmfXn", // AMF内Xn接口切换尝试数 AMF内基于Xn接口的切换尝试次数。" + "AMF.SuccIntraAmfXn", // AMF内Xn接口切换成功次数 AMF内基于Xn接口的切换成功次数。 + "AMF.AttIntraAmfN2", // AMF内N2接口切换尝试次数 AMF内基于N2接口的切换尝试次数。 + "AMF.SuccIntraAmfN2", // AMF内N2接口切换成功次数 AMF内基于N2接口的切换成功次数。 + "AMF.AttOutInterAmf", // AMF间切换出尝试次数 AMF间的切换,切换出源AMF尝试次数。 + "AMF.SuccOutInterAmf", // AMF间切换出成功次数 AMF间的切换,切换出源AMF成功次数。 + "AMF.AttIncInterAmf", // AMF间切换入尝试次数 AMF间的切换,切换入目标AMF尝试次数。 + "AMF.SuccIncInterAmf", // AMF间切换入成功次数 AMF间的切换,切换入目标AMF成功次数。 + // PG + "AMF.Att5GHandoverTo4G", // 从5G网络切换出至4G网络尝试次数 + "AMF.Succ5GHandoverTo4G", // 从5G网络切换出至4G网络成功次数 + "AMF.Att4GHandoverTo5G", // 从4G网络切换入5G网络尝试次数 + "AMF.Succ4GHandoverTo5G", // 从4G网络切换入5G网络成功次数 + "AMF.Req4GReselectTo5G", // 从4G网络重选入5G网络请求次数 + "AMF.Acc4GReselectTo5G", // 从4G网络重选入5G网络接受次数 + // PH + "AMF.MeanLoad", // 系统平均负荷 + // PI + "AMF.UecmRegReq", // UECM注册请求次数 + "AMF.UecmRegSucc", // UECM注册成功次数 + "AMF.UecmRegFail", // UECM注册失败次数 + "AMF.UecmRegFail._Cause", // 分原因的UECM注册失败次数 + "AMF.UecmRegFail.Unknown5GSub", // UECM注册失败次数_未签约5G + "AMF.UecmRegFail.NoPsSub", // UECM注册失败次数_未签约PS业务 + "AMF.UecmRegFail.RoamNotAllowed", // UECM注册失败次数_漫游不允许 + "AMF.UecmRegFail.AccessNotAllowed", // UECM注册失败次数_接入类型不允许 + "AMF.UecmRegFail.RatNotAllowed", // UECM注册失败次数_5GS接入不允许 + "AMF.UecmDeregReq", // AMF发起的UECM去注册请求次数 + "AMF.UecmDeregSucc", // AMF发起的UECM去注册成功次数 + "AMF.UecmDeregNotifyReq", // UDM发起的UECM去注册请求次数 + "AMF.UecmDeregNotifySucc", // UDM发起的UECM去注册成功次数 + // PJ + "AMF.SmContextCreateReq", // 会话上下文建立请求次数 AMF向SMF发起建立会话上下文的次数。 + "AMF.SessionCreateSucc", // 会话上下文建立成功次数 SMF返回AMF建立会话上下文成功的次数 + "AMF.SmContextUpdateReq", // 会话上下文更新请求次数 AMF向SMF发起更新会话上下文的次数。 + "AMF.SessionUpdateSucc", // 会话上下文更新成功次数 SMF返回AMF更新会话上下文成功的次数 + "AMF.SmContextReleaseReq", // 会话上下文释放请求次数 AMF向SMF发起释放会话上下文的次数。 + "AMF.SessionReleaseSucc", // 会话上下文释放成功次数 SMF返回AMF释放会话上下文成功的次数 + "AMF.SmContextRetrieveReq", // 会话上下文查询请求次数 AMF向SMF发起查询会话上下文的次数。 + "AMF.SessionRetrieveSucc", // 会话上下文查询成功次数 SMF返回AMF查询会话上下文成功的次数 + // PK + "AMF.UeAuthReq", // AMF向AUSF发起鉴权请求次数 AMF向AUSF发起鉴权请求消息次数 + "AMF.UeAuthSucc", // AUSF向AMF返回的鉴权成功次数 AUSF向AMF返回的鉴权成功消息次数 + "AMF.UeAuthFail", // 鉴权失败次数 统计AMF收到的AUSF返回的鉴权失败次数,并分application error进行统计。 + "AMF.UeAuthFail._Cause", // 分原因的鉴权失败次数 + "AMF.UeAuthCfmReq", // AMF向AUSF发起鉴权确认请求次数 AMF向AUSF发起鉴权确认请求消息次数 + "AMF.UeAuthCfmSucc", // AUSF向AMF返回的鉴权确认成功次数 AUSF向AMF返回的鉴权确认成功消息次数 + // PL + "AMF.GnbNum", // AMF挂接5G基站数 统计周期结束点时刻,挂接在AMF下的5G基站数量 + + } + parseDataArr = append(parseDataArr, headerArr) + // 单行数据 + rowmArr := make([]string, len(headerArr)) + for i := range rowmArr { + rowmArr[i] = "0" + } + rowmArr[0] = ruid + rowmArr[1] = userLabel + + // 遍历数据插入单行数据 + itemArr := rowmArr + for _, item := range data { + // AMF.01 AMF注册态用户数 + // AMF.02 AMF初始注册请求次数 + // AMF.03 AMF初始注册成功次数 + // AMF.04 AMF初始注册失败次数_非法用户 + // AMF.05 AMF初始注册失败次数_PEI不允许 + // AMF.06 AMF初始注册失败次数_非法设备 + // AMF.07 AMF初始注册失败次数_5GS服务不允许_用户原因 + // AMF.08 AMF初始注册失败次数_跟踪区内无合适小区_用户原因 + // AMF.09 AMF初始注册失败次数_N1模式不允许 + // AMF.10 AMF初始注册失败次数_PLMN不允许 + // AMF.11 AMF初始注册失败次数_跟踪区不允许 + // AMF.12 AMF初始注册失败次数_漫游跟踪区禁止接入 + // AMF.13 AMF初始注册失败次数_无可用网络切片 + // AMF.14 AMF初始注册失败次数_协议错误_用户原因 + // AMF.15 AMF一次寻呼响应次数 + // AMF.16 AMF二次寻呼响应次数 + // AMF.17 AMF寻呼请求次数 + // AMF.18 AMF业务请求被拒次数 + // AMF.19 AMF业务请求尝试次数 + // AMF.20 EPS在线用户数 + // AMF.21 EPS附着成功次数 + // AMF.22 EPS附着请求次数 + // AMF.23 EPS附着失败次数_非法用户 + // AMF.24 EPS附着失败次数_非法终端 + // AMF.25 EPS附着失败次数_非法ME + // AMF.26 EPS附着失败次数_EPS服务不允许_用户原因 + // AMF.27 EPS附着失败次数_EPS和非EPS服务不允许 + // AMF.28 EPS附着失败次数_跟踪区内无合适小区_用户原因 + // AMF.29 EPS附着失败次数_ESM失败_用户原因 + // AMF.30 MME一次寻呼响应次数 + // AMF.31 MME二次寻呼响应次数 + // AMF.32 MME寻呼请求次数 + // AMF.A.02 AMF移动性注册更新成功次数 + // AMF.A.03 AMF移动性注册更新失败次数 + // AMF.A.04 AMF紧急注册请求次数 + // AMF.A.05 AMF紧急注册成功次数 + // AMF.A.06 AMF紧急注册失败次数 + // AMF.A.07 UE发起的去注册请求次数 + // AMF.A.08 UE发起的去注册成功次数 + // AMF.A.09 AMF发起的去注册请求次数 + // AMF.A.10 AMF发起的去注册成功次数 + // AMF.A.11 UDM发起的去注册请求次数 + // AMF.A.12 UDM发起的去注册成功次数 + // AMF.A.13 AMF寻呼失败次数 + // AMF.A.14 AMF隐式去注册次数 + // ===================== + + // AMF.01 AMF注册态用户数 + if v, ok := item["AMF.01"]; ok && v != nil { + vStr := fmt.Sprint(v) + itemArr[2] = vStr + } + + // AMF.A.14 AMF隐式去注册次数 + if v, ok := item["AMF.A.14"]; ok && v != nil { + itemArr[3] = fmt.Sprint(v) + } + // 添加后恢复单行数据 + parseDataArr = append(parseDataArr, itemArr) + itemArr = rowmArr + } + return parseDataArr +} + +// parseDataUPF PM数据UPF +func (s *PerformanceImpl) parseDataUPF(ruid, userLabel string, data []map[string]any) [][]string { + parseDataArr := [][]string{} + // 数据行头 + headerArr := []string{ + // 资源对象的RUID及UserLabel + "RUID", "UserLabel", + // PA + "UPF.PfcpSessionEstabReq", // PFCP会话建立请求次数 PFCP会话建立请求次数。 + "UPF.PfcpSessionEstabReq._Ns", // 分切片的PFCP会话建立请求次数 按照S-NSSAI统计的PFCP会话建立请求次数。 + "UPF.PfcpSessionEstabSucc", // PFCP会话建立成功次数 PFCP会话建立成功次数。 + "UPF.PfcpSessionEstabSucc._Ns", // 分切片的PFCP会话建立成功次数 按照S-NSSAI统计的PFCP会话建立成功次数。 + "UPF.PfcpSessionEstabFail", // PFCP会话建立失败次数 PFCP会话建立被拒绝的次数,并按拒绝原因分类统计。 + "UPF.PfcpSessionEstabFail._Cause", // 分原因的PFCP会话建立失败次数 + "UPF.PfcpSessionEstabFail._Ns", // 分切片的PFCP会话建立失败次数 按照S-NSSAI统计PFCP会话建立被拒绝的次数 + "UPF.PfcpSessionModifyReq", // PFCP会话修改请求次数 PFCP会话修改请求次数。 + "UPF.PfcpSessionModifyReq._Ns", // 分切片的PFCP会话修改请求次数 按照S-NSSAI统计PFCP会话修改请求次数。 + "UPF.PfcpSessionModifySucc", // PFCP会话修改成功次数 PFCP会话修改成功次数。 + "UPF.PfcpSessionModifySucc._Ns", // 分切片的PFCP会话修改成功次数 按照S-NSSAI统计PFCP会话修改成功次数。 + "UPF.PfcpSessionModifyFail", // PFCP会话修改失败次数 PFCP会话修改拒绝的次数,并按拒绝原因分类统计。 + "UPF.PfcpSessionModifyFail._Cause", // 分原因的PFCP会话修改失败次数 + "UPF.PfcpSessionModifyFail._Ns", // 分切片的PFCP会话修改失败次数 按照S-NSSAI统计PFCP会话修改拒绝的次数。 + // PB + "UPF.MeanQosFlows", // 平均QoS流数 一个统计周期内UPF中的平均QoS流数。 + "UPF.MeanQosFlows._Ns", // 分切片的平均QoS流数 一个统计周期内按照S-NSSAI统计UPF中的平均QoS流数。 + "UPF.MeanQosFlows._Dnn", // 分DNN的平均QoS流数 一个统计周期内按照DNN统计UPF中的平均QoS流数。 + "UPF.MaxQosFlows", // 最大QoS流数 一个统计周期内UPF中的最大QoS流数。 + "UPF.MaxQosFlows._Ns", // 分切片的最大QoS流数 一个统计周期内按照S-NSSAI统计UPF中的最大QoS流数。 + "UPF.MaxQosFlows._Dnn", // 分DNN的最大QoS流数 一个统计周期内按照DNN统计UPF中的最大QoS流数。 + // PC + "UPF.N3IncPkt", // N3接口接收GTP包数 UPF从N3接口接收的GTP包数,并按DNN分别进行统计; + "UPF.N3IncPkt._Dnn", // 分DNN的N3接口接收GTP包数 + "UPF.N3OgPkt", // N3接口发送GTP包数 UPF从N3接口发送出去的GTP包数,并按DNN分别进行统计; + "UPF.N3OgPkt._Dnn", // 分DNN的N3接口发送GTP包数 + "UPF.N3IncOct", // N3接口接收GTP包字节数 UPF从N3接口接收的GTP包字节数(含GTP头),并按DNN分别进行统计; + "UPF.N3IncOct._Dnn", // 分DNN的N3接口接收GTP包字节数 + "UPF.N3OgOct", // N3接口发送GTP包字节数 UPF从N3接口发送的GTP包字节数(含GTP头),并按DNN分别进行统计; + "UPF.N3OgOct._Dnn", // 分DNN的N3接口发送GTP包字节数 + "UPF.N3DiscPkt", // N3接口接收错误GTP包数 N3接口因出错丢弃的GTP包个数,并按DNN分别进行统计; + "UPF.N3DiscPkt._Dnn", // 分DNN的N3接口接收错误GTP包数 + // PD + "UPF.N9aIncPkt", // N9a接口接收GTP包数 UPF从左侧N9a接口接收的GTP包数,并按DNN分别进行统计; + "UPF.N9aIncPkt._Dnn", // 分DNN的N9a接口接收GTP包数 + "UPF.N9aOgPkt", // N9a接口发送GTP包数 "UPF从左侧N9a接口发送出去的GTP包数,并按DNN分别进行统计;" + "UPF.N9aOgPkt._Dnn", // 分DNN的N9a接口发送GTP包数 + "UPF.N9aIncOct", // N9a接口接收GTP包字节数 UPF从左侧N9a接口接收的GTP包字节数,并按DNN分别进行统计; + "UPF.N9aIncOct._Dnn", // 分DNN的N9a接口接收GTP包字节数 + "UPF.N9aOgOct", // N9a接口发送GTP包字节数 UPF从左侧N9a接口发送的GTP包字节数,并按DNN分别进行统计; + "UPF.N9aOgOct._Dnn", // 分DNN的N9a接口发送GTP包字节数 + "UPF.N9aDiscPkt", // N9a接口接收错误GTP包数 UPF对左侧N9a接口因出错丢弃的GTP包个数,并按DNN分别进行统计; + "UPF.N9aDiscPkt._Dnn", // 分DNN的N9a接口接收错误GTP包数 + "UPF.N9cIncPkt", // N9c接口接收GTP包数 UPF从右侧N9c接口接收的GTP包数,并按DNN分别进行统计; + "UPF.N9cIncPkt._Dnn", // 分DNN的N9c接口接收GTP包数 + "UPF.N9cOgPkt", // N9c接口发送GTP包数 UPF从右侧N9c接口发送出去的GTP包数,并按DNN分别进行统计; + "UPF.N9cOgPkt._Dnn", // 分DNN的N9c接口发送GTP包数 + "UPF.N9cIncOct", // N9c接口接收GTP包字节数 UPF从右侧N9c接口接收的GTP包字节数,并按DNN分别进行统计; + "UPF.N9cIncOct._Dnn", // 分DNN的N9c接口接收GTP包字节数 + "UPF.N9cOgOct", // N9c接口发送GTP包字节数 UPF从右侧N9c接口发送的GTP包字节数,并按DNN分别进行统计; + "UPF.N9cOgOct._Dnn", // 分DNN的N9c接口发送GTP包字节数 + "UPF.N9cDiscPkt", // N9c接口接收错误GTP包数 UPF对右侧N9c接口因出错丢弃的GTP包个数,并按DNN分别进行统计; + "UPF.N9cDiscPkt._Dnn", // 分DNN的N9c接口接收错误GTP包数 + // PE + "UPF.N6IncPkt", // N6接口接收IP包数 统计UPF在N6接口接收到的IP包个数,并按DNN分别进行统计; + "UPF.N6IncPkt._Dnn", // 分DNN的N6接口接收IP包数 + "UPF.N6OgPkt", // N6接口发送IP包数 统计UPF在N6向发送的IP包个数,并按DNN分别进行统计; + "UPF.N6OgPkt._Dnn", // 分DNN的N6接口发送IP包数 + "UPF.N6IncOct", // N6接口接收字节数 统计UPF在N6接收到的IP包PDU字节数,并按DNN分别进行统计; + "UPF.N6IncOct._Dnn", // 分DNN的N6接口接收字节数 + "UPF.N6OgOct", // N6接口发送字节数 统计UPF在N6发送的IP包PDU字节数,并按DNN分别进行统计; + "UPF.N6OgOct._Dnn", // 分DNN的N6接口发送字节数 + "UPF.N6DiscPkt", // N6接口出错丢弃的IP包数 统计N6口出错丢弃的IP包个数,并按DNN分别进行统计; + "UPF.N6DiscPkt._Dnn", // 分DNN的N6接口出错丢弃的IP包数 + // PF + "UPF.MeanLoad", // 系统平均负荷 对物理网元:指测量周期中,网元的硬件资源负荷的抽样平均值。网元的硬件资源负荷可取对网元影响最大的模块的负荷,或取不同模块的负荷的加权平均值,不同厂商设备的计算方法各不相同 + } + parseDataArr = append(parseDataArr, headerArr) + // 单行数据 + rowmArr := make([]string, len(headerArr)) + for i := range rowmArr { + rowmArr[i] = "0" + } + rowmArr[0] = ruid + rowmArr[1] = userLabel + + // 遍历数据插入单行数据 + itemArr := rowmArr + for _, item := range data { + // UPF.01 PFCP会话建立成功次数 + // UPF.02 PFCP会话建立请求次数 + // UPF.03 N6接口上行字节数 + // UPF.04 N6接口下行字节数 + // UPF.05 N3接口上行字节数 + // UPF.06 N3接口下行字节数 + // UPF.07 SGi接口上行字节数 + // UPF.08 SGi接口下行字节数 + // UPF.09 S1-U接口上行字节数 + // UPF.10 S1-U接口下行字节数 + // ============= + + // PFCP会话建立成功次数 + if v, ok := item["UPF.01"]; ok && v != nil { + itemArr[4] = fmt.Sprint(v) + } + // PFCP会话建立请求次数 + if v, ok := item["UPF.02"]; ok && v != nil { + itemArr[2] = fmt.Sprint(v) + } + // N6接口上行字节数 + if v, ok := item["UPF.03"]; ok && v != nil { + vStr := fmt.Sprint(v) + itemArr[54] = vStr + itemArr[55] = vStr + itemArr[58] = vStr + itemArr[59] = vStr + } + // N6接口下行字节数 + if v, ok := item["UPF.04"]; ok && v != nil { + vStr := fmt.Sprint(v) + itemArr[52] = vStr + itemArr[53] = vStr + itemArr[56] = vStr + itemArr[57] = vStr + } + // N3接口上行字节数 + if v, ok := item["UPF.05"]; ok && v != nil { + vStr := fmt.Sprint(v) + itemArr[22] = vStr + itemArr[23] = vStr + itemArr[26] = vStr + itemArr[27] = vStr + } + // N3接口下行字节数 + if v, ok := item["UPF.06"]; ok && v != nil { + vStr := fmt.Sprint(v) + itemArr[24] = vStr + itemArr[25] = vStr + itemArr[28] = vStr + itemArr[29] = vStr + } + // SGi接口上行字节数 + if v, ok := item["UPF.07"]; ok && v != nil { + vStr := fmt.Sprint(v) + itemArr[32] = vStr + itemArr[33] = vStr + itemArr[36] = vStr + itemArr[37] = vStr + } + // SGi接口下行字节数 + if v, ok := item["UPF.08"]; ok && v != nil { + vStr := fmt.Sprint(v) + itemArr[34] = vStr + itemArr[35] = vStr + itemArr[38] = vStr + itemArr[39] = vStr + } + // S1-U接口上行字节数 + if v, ok := item["UPF.09"]; ok && v != nil { + vStr := fmt.Sprint(v) + itemArr[42] = vStr + itemArr[43] = vStr + itemArr[46] = vStr + itemArr[47] = vStr + } + // S1-U接口下行字节数 + if v, ok := item["UPF.10"]; ok && v != nil { + vStr := fmt.Sprint(v) + itemArr[44] = vStr + itemArr[45] = vStr + itemArr[48] = vStr + itemArr[49] = vStr + } + // 添加后恢复单行数据 + parseDataArr = append(parseDataArr, itemArr) + itemArr = rowmArr + } + return parseDataArr +} + +// parseDataUDM PM数据UDM +func (s *PerformanceImpl) parseDataUDM(ruid, userLabel string, data []map[string]any) [][]string { + parseDataArr := [][]string{} + // 数据行头 + headerArr := []string{ + // 资源对象的RUID及UserLabel + "RUID", "UserLabel", + // PA + "UDM.AmfUecmRegReq", // AMF发起的UECM注册请求次数 统计UDM收到的AMF发起的UECM注册请求次数 + "UDM.AmfUecmRegSucc", // AMF发起的UECM注册成功次数 统计UDM返回的成功的AMF注册响应次数 + "UDM.AmfUecmRegUpdateReq", // 更新注册参数请求次数 更新注册参数请求次数 + "UDM.AmfUecmRegUpdateSucc", // 更新注册参数成功次数 更新注册参数成功次数 + "UDM.AmfUecmDeregReq", // AMF发起的UECM去注册请求次数 统计AMF发起的UECM去注册请求次数 + "UDM.AmfUecmDeregSucc", // AMF发起的UECM去注册成功次数 统计AMF发起的UECM去注册成功次数 + "UDM.SmfUecmRegReq", // SMF发起的UECM注册请求次数 统计SMF发起的用户上下文注册请求次数 + "UDM.SmfUecmRegSucc", // SMF发起的UECM注册成功次数 统计UDM返回的成功的用户上下文注册响应次数 + "UDM.SmfUecmDeregReq", // SMF发起的UECM去注册请求次数 统计SMF发起的用户上下文去注册请求次数 + "UDM.SmfUecmDeregSucc", // SMF发起的UECM去注册成功次数 统计UDM返回的成功的用户上下文去注册响应次数 + "UDM.SdmGetReq", // 获取用户数据请求次数 统计UDM收到的获取用户数据请求次数 + "UDM.SdmGetSucc", // 获取用户数据成功次数 统计UDM成功返回用户数据次数 + "UDM.SdmNotif", // 用户数据变化通知次数 统计UDM发送用户数据变化通知次数 + "UDM.SdmSubscrReq", // 订阅用户数据请求次数 统计UDM收到的订阅用户数据相关通知请求次数 + "UDM.SdmSubscrSucc", // 订阅用户数据成功次数 统计UDM返回的订阅用户数据相关通知成功次数 + "UDM.SdmUnSubscrReq", // 去订阅用户数据请求次数 统计UDM收到的去订阅用户数据相关通知请求次数 + "UDM.SdmUnSubscrSucc", // 去订阅用户数据成功次数 统计UDM返回的去订阅用户数据相关通知成功次数 + "UDM.UecmDeregNotif", // 去注册通知次数 统计UDM发送的去注册通知次数 + // PB + "UDR.5GSubIn", // 5G网络SUPI数 统计UDR存储的SUPI数 + "UDR.5GActSubIn", // 5G用户数 统计UDR存储的5G MSISDN数 + "UDR.5GActSubIn", // 5G活动用户数 统计UDR存储的有位置信息的MSISDN用户数 + // PC + "Ausf.UeAuthReq", // 鉴权请求次数 AUSF收到的鉴权请求次数 + "Ausf.UeAuthAnsSucc", // 鉴权成功次数 AUSF返回鉴权成功响应次数 + } + parseDataArr = append(parseDataArr, headerArr) + // 单行数据 + rowmArr := make([]string, len(headerArr)) + for i := range rowmArr { + rowmArr[i] = "0" + } + rowmArr[0] = ruid + rowmArr[1] = userLabel + + // 遍历数据插入单行数据 + itemArr := rowmArr + for _, item := range data { + // UDM.01 5G注册用户数 + // UDM.02 AMF发起的UECM注册请求次数 + // UDM.03 AMF发起的UECM注册成功次数 + // UDM.04 SMF发起的UECM注册成功次数 + // UDM.05 SMF发起的UECM注册请求次数 + // UDM.06 4G注册用户数 + // UDM.07 4G鉴权信息查询成功次数 + // UDM.08 4G鉴权信息查询请求次数 + // UDM.09 4G更新位置成功次数 + // UDM.10 4G更新位置请求次数 + // UDM.11 SAR成功响应总次数 + // UDM.12 SAR请求总次数 + // UDM.13 LIR成功响应总次数 + // UDM.14 LIR请求总次数 + // ================== + + // 5G注册用户数 + if v, ok := item["UDM.01"]; ok && v != nil { + vStr := fmt.Sprint(v) + itemArr[21] = vStr + itemArr[22] = vStr + } + // AMF发起的UECM注册请求次数 + if v, ok := item["UDM.02"]; ok && v != nil { + vStr := fmt.Sprint(v) + itemArr[2] = vStr + itemArr[6] = vStr + } + // AMF发起的UECM注册成功次数 + if v, ok := item["UDM.03"]; ok && v != nil { + vStr := fmt.Sprint(v) + itemArr[3] = vStr + itemArr[7] = vStr + } + // SMF发起的UECM注册成功次数 + if v, ok := item["UDM.04"]; ok && v != nil { + vStr := fmt.Sprint(v) + itemArr[9] = vStr + itemArr[11] = vStr + } + // SMF发起的UECM注册请求次数 + if v, ok := item["UDM.05"]; ok && v != nil { + vStr := fmt.Sprint(v) + itemArr[8] = vStr + itemArr[10] = vStr + } + // 4G注册用户数 + if v, ok := item["UDM.06"]; ok && v != nil { + itemArr[19] = fmt.Sprint(v) + } + // 4G鉴权信息查询成功次数 + if v, ok := item["UDM.07"]; ok && v != nil { + itemArr[13] = fmt.Sprint(v) + } + // 4G鉴权信息查询请求次数 + if v, ok := item["UDM.08"]; ok && v != nil { + itemArr[12] = fmt.Sprint(v) + } + // 4G更新位置成功次数 + if v, ok := item["UDM.09"]; ok && v != nil { + itemArr[16] = fmt.Sprint(v) + } + // 4G更新位置请求次数 + if v, ok := item["UDM.10"]; ok && v != nil { + itemArr[15] = fmt.Sprint(v) + } + // SAR成功响应总次数 + if v, ok := item["UDM.11"]; ok && v != nil { + itemArr[18] = fmt.Sprint(v) + } + // SAR请求总次数 + if v, ok := item["UDM.12"]; ok && v != nil { + itemArr[17] = fmt.Sprint(v) + } + // LIR成功响应总次数 + if v, ok := item["UDM.13"]; ok && v != nil { + itemArr[24] = fmt.Sprint(v) + } + // LIR请求总次数 + if v, ok := item["UDM.14"]; ok && v != nil { + itemArr[23] = fmt.Sprint(v) + } + // 添加后恢复单行数据 + parseDataArr = append(parseDataArr, itemArr) + itemArr = rowmArr + } + return parseDataArr +} + +// parseDataSMF PM数据SMF +func (s *PerformanceImpl) parseDataSMF(ruid, userLabel string, data []map[string]any) [][]string { + parseDataArr := [][]string{} + // 数据行头 + headerArr := []string{ + // 资源对象的RUID及UserLabel + "RUID", "UserLabel", + // PA + "SMF.AttCreatePduSession", // PDU会话建立请求次数 UE发起的PDU会话建立请求次数。 + "SMF.AttCreatePduSession._Ns", // 分网络切片的PDU会话建立请求次数 按照S-NSSAI统计UE发起的PDU会话建立请求次数。 + "SMF.AttCreatePduSession._Dnn", // 分DNN的PDU会话建立请求次数 按照DNN统计UE发起的PDU会话建立请求次数。 + "SMF.SuccCreatePduSession", // PDU会话建立成功次数 UE发起的PDU会话建立成功次数。 + "SMF.SuccCreatePduSession._Ns", // 分网络切片的PDU会话建立成功次数 按照S-NSSAI统计UE发起的PDU会话建立成功次数。 + "SMF.SuccCreatePduSession._Dnn", // 分DNN的PDU会话建立成功次数 按照DNN统计UE发起的PDU会话建立成功次数。 + "SMF.FailCreatePduSession", // PDU会话建立失败次数 UE发起的PDU会话建立被SMF拒绝的次数,并按拒绝原因分类统计。 + "SMF.FailCreatePduSession._Cause", // 分原因的PDU会话建立失败次数 + "SMF.FailCreatePduSession._Ns", // 分网络切片的PDU会话建立失败次数 按照S-NSSAI统计UE发起的PDU会话建立被SMF拒绝的次数,并按拒绝原因分类统计。 + "SMF.FailCreatePduSession._Dnn", // 分DNN的PDU会话建立失败次数 按照DNN统计UE发起的PDU会话建立被SMF拒绝的次数,并按拒绝原因分类统计。 + "SMF.AttSmfModifyPduSession", // SMF发起的PDU会话修改请求次数 SMF发起的PDU会话修改请求次数。 + "SMF.AttSmfModifyPduSession._Ns", // 分网络切片的PDU会话修改请求次数 按照S-NSSAI统计SMF发起的PDU会话修改请求次数。 + "SMF.AttSmfModifyPduSession._Dnn", // 分DNN的PDU会话修改请求次数 按照DNN统计SMF发起的PDU会话修改请求次数。 + "SMF.SuccSmfModifyPduSession", // SMF发起的PDU会话修改成功次数 SMF发起的PDU会话修改成功次数。 + "SMF.SuccSmfModifyPduSession._Ns", // 分网络切片的SMF发起的PDU会话修改成功次数 按照S-NSSAI统计SMF发起的PDU会话修改成功次数。 + "SMF.SuccSmfModifyPduSession._Dnn", // 分DNN的SMF发起的PDU会话修改成功次数 按照DNN统计SMF发起的PDU会话修改成功次数。 + "SMF.FailSmfModifyPduSession", // SMF发起的PDU会话修改失败次数 "SMF发起的PDU会话修改被UE拒绝的次数,并按拒绝原因分类统计。" + "SMF.FailSmfModifyPduSession._Cause", // 分原因的SMF发起的PDU会话修改失败次数 + "SMF.FailSmfModifyPduSession._Ns", // 分网络切片的SMF发起的PDU会话修改失败次数 按照S-NSSAI统计UE发起的PDU会话建立被SMF拒绝的次数,并按拒绝原因分类统计。 + "SMF.FailSmfModifyPduSession._Dnn", // 分DNN的SMF发起的PDU会话修改失败次数 "按照DNN统计UE发起的PDU会话建立被SMF拒绝的次数,并按拒绝原因分类统计。" + "SMF.PduSessionCreateTime", // PDU会话建立流程平均时长 "成功的PDU会话建立流程的平均时长。" + // PB + "SMF.MeanPduSession", // 平均PDU会话数 + "SMF.MeanPduSession._Ns", // 分网络切片的平均PDU会话数 + "SMF.MeanPduSession._Dnn", // 分DNN的平均PDU会话数 + "SMF.MaxPduSession", // 最大PDU会话数 + "SMF.MaxPduSession._Ns", // 分网络切片的最大PDU会话数 + "SMF.MaxPduSession._Dnn", // 分DNN的最大PDU会话数 + "SMF.MeanQf", // 平均Qos流数 + "SMF.MeanQf._Ns", // 分网络切片的平均Qos流数 + "SMF.MeanQf._Dnn", // 分DNN的平均Qos流数 + "SMF.MaxQf", // 最大Qos流数 + "SMF.MaxQf._Ns", // 分网络切片的最大Qos流数 + "SMF.MaxQf._Dnn", // 分DNN的最大Qos流数 + // PC + "SMF.MeanLoad", // 系统平均负荷 + // PD + "SMF.MeanAllcAddr", // 平均分配的地址数 SMF为UE平均分配的地址数。 + "SMF.MeanAllcAddr._Ns", // 分网络切片的平均分配的地址数 按照S-NSSAI统计统计的SMF为UE平均分配的地址数。 + "SMF.MaxAllcAddr", // 最大分配的地址数 SMF为UE最大分配的地址数。 + "SMF.MaxAllcAddr._Ns", // 分网络切片的最大分配的地址数 按照S-NSSAI统计的SMF为UE最大分配的地址数。 + // PE + "SMF.SmPlcyCtrlCreateReq", // 创建SM策略请求的次数 SMF向PCF发起创建SM策略请求的次数。 + "SMF.SmPlcyCtrlCreateSucc", // 创建SM策略成功次数 PCF向SMF返回创建SM策略成功的次数。 + "SMF.SmPlcyCtrlUpdateReq", // 更新SM策略请求的次数 SMF向PCF发起更新SM策略请求的次数。 + "SMF.SmPlcyCtrlUpdateSucc", // 更新SM策略成功次数 PCF向SMF返回更新SM策略成功的次数。 + "SMF.SmPlcyCtrlDeleteReq", // 删除策略请求的次数 SMF向PCF发起删除SM策略请求的次数。 + "SMF.SmPlcyCtrlDeleteSucc", // 删除SM策略成功次数 PCF向SMF返回删除SM策略成功的次数。 + // PF + "SMF.UecmRegReq", // UE上下文注册请求次数 SMF向UDM发起UE上下文注册请求的次数 + "SMF.UecmRegSucc", // UE上下文注册成功次数 SMF收到UDM返回的UE上下文注册成功的次数 + "SMF.UecmRegFail", // UE上下文注册失败次数 SMF收到UDM返回的UE上下文注册失败的次数 + "SMF.UecmRegFail._Cause", // 分原因的UE上下文注册失败次数 + "SMF.UecmRegFail.Unknown5GSub", // UE上下文注册失败次数_未签约5G + "SMF.UecmRegFail.RoamNotAllowed", // UE上下文注册失败次数_漫游不允许 + "SMF.UecmRegFail.DnnNotAllowed", // UE上下文注册失败次数_DNN未授权 + "SMF.UecmRegFail.UserNotFound", // UE上下文注册失败次数_未找到用户 + "SMF.UecmDeregReq", // UE上下文去注册请求次数 SMF向UDM发起UE上下文去注册请求的次数 + "SMF.UecmDeregSucc", // UE上下文去注册成功次数 SMF向UDM发起UE上下文去注册请求的次数 + "SMF.UecmDeregNotifyReq", // UE上下文去注册通知请求次数 UDM向SMF发送UE上下文去注册通知次数。 + "SMF.UecmDeregNotifySucc", // UE上下文去注册通知成功次数 SMF向UDM返回UE上下文去注册通知确认消息次数。 + } + parseDataArr = append(parseDataArr, headerArr) + // 单行数据 + rowmArr := make([]string, len(headerArr)) + for i := range rowmArr { + rowmArr[i] = "0" + } + rowmArr[0] = ruid + rowmArr[1] = userLabel + + // 遍历数据插入单行数据 + itemArr := rowmArr + for _, item := range data { + // SMF.01 5G实时PDU会话数 + // SMF.02 PDU会话建立成功次数 + // SMF.03 PDU会话建立请求次数 + // SMF.04 IMS PDU会话建立成功次数 + // SMF.05 IMS PDU会话建立请求次数 + // SMF.06 EPS-Fallback成功数 + // SMF.07 EPS-Fallback请求数 + // SMF.08 4G在线会话数 + // SMF.09 PGW缺省承载建立成功个数 + // SMF.10 PGW缺省承载建立请求个数 + // SMF.11 PGW专用承载建立成功个数 + // SMF.12 PGW专用承载建立请求个数 + // SMF.13 IMS缺省承载成功建立个数 + // SMF.14 IMS缺省承载请求建立个数 + // SMF.A.01 PDU会话接受次数 + // SMF.A.02 基站Pdu资源创建成功次数 + // SMF.A.03 查询用户SM数据失败次数 + // SMF.A.04 PFCP会话建立失败次数 + // SMF.A.05 基站Pdu资源创建失败次数 + // SMF.A.06 PFCP会话修改失败次数 + // SMF.A.07 PDU会话拒绝次数 + // SMF.A.08 PDU会话释放指示次数 + // ================== + + // 5G实时PDU会话数 + if v, ok := item["SMF.01"]; ok && v != nil { + vStr := fmt.Sprint(v) + itemArr[26] = vStr + itemArr[27] = vStr + itemArr[28] = vStr + } + // PDU会话建立成功次数 + if v, ok := item["SMF.02"]; ok && v != nil { + vStr := fmt.Sprint(v) + itemArr[5] = vStr + itemArr[6] = vStr + itemArr[7] = vStr + } + // PDU会话建立请求次数 + if v, ok := item["SMF.03"]; ok && v != nil { + vStr := fmt.Sprint(v) + itemArr[2] = vStr + itemArr[3] = vStr + itemArr[4] = vStr + } + // IMS PDU会话建立成功次数 + // IMS PDU会话建立请求次数 + // EPS-Fallback成功数 + // EPS-Fallback请求数 + // 4G在线会话数 + // PGW缺省承载建立成功个数 + // PGW缺省承载建立请求个数 + // PGW专用承载建立成功个数 + // PGW专用承载建立请求个数 + // IMS缺省承载成功建立个数 + // IMS缺省承载请求建立个数 + // PDU会话接受次数 + // 基站Pdu资源创建成功次数 + // 查询用户SM数据失败次数 + // PFCP会话建立失败次数 + // 基站Pdu资源创建失败次数 + // PFCP会话修改失败次数 + // PDU会话拒绝次数 + if v, ok := item["SMF.A.07"]; ok && v != nil { + vStr := fmt.Sprint(v) + itemArr[18] = vStr + itemArr[19] = vStr + itemArr[20] = vStr + itemArr[21] = vStr + } + // PDU会话释放指示次数 + if v, ok := item["SMF.A.08"]; ok && v != nil { + itemArr[23] = fmt.Sprint(v) + } + // 添加后恢复单行数据 + parseDataArr = append(parseDataArr, itemArr) + itemArr = rowmArr + } + return parseDataArr +} + +// parseDataNSSF PM数据NSSF +func (s *PerformanceImpl) parseDataNSSF(ruid, userLabel string, data []map[string]any) [][]string { + parseDataArr := [][]string{} + // 数据行头 + headerArr := []string{ + // 资源对象的RUID及UserLabel + "RUID", "UserLabel", + // PA + "NSSF.NsSelectReq", // 网络切片选择请求次数 NSSF收到的网络切片选择请求次数 + "NSSF.NsSelectReq.Reg", // 注册过程网络切片选择请求次数 注册过程中NSSF收到的网络切片选择请求次数 + "NSSF.NsSelectReq.Pdu", // PDU会话建立过程网络切片选择请求次数 PDU会话建立过程中NSSF收到的网络切片选择请求次数 + "NSSF.NsSelectSucc", // 网络切片选择成功次数 NSSF返回网络切片选择成功次数; + "NSSF.NsSelectSucc.Reg", // 注册过程网络切片选择成功次数 注册过程中NSSF返回网络切片选择成功次数 + "NSSF.NsSelectSucc.Pdu", // PDU会话建立过程网络切片选择成功次数 PDU会话建立过程中NSSF返回网络切片选择成功次数 + "NSSF.NsSelectFail", // 网络切片选择失败次数 NSSF返回网络切片选择失败次数,分原因进行分类统计 + "NSSF.NsSelectFail._Cause", // 分原因的网络切片选择失败次数 + // PB + "NSSF.MeanLoad", //系统平均负荷 + } + parseDataArr = append(parseDataArr, headerArr) + // 单行数据 + rowmArr := make([]string, len(headerArr)) + for i := range rowmArr { + rowmArr[i] = "0" + } + rowmArr[0] = ruid + rowmArr[1] = userLabel + + // 遍历数据插入单行数据 + itemArr := rowmArr + for _, item := range data { + // NSSF.A.01 可用AMF注册更新次数 + // NSSF.A.02 可用AMF注册成功次数 + // NSSF.A.03 可用AMF注册次数 + // NSSF.A.04 可用AMF注册更新成功次数 + // NSSF.A.05 可用AMF去注册成功次数 + // NSSF.A.06 可用AMF去注册次数 + // NSSF.A.07 网元订阅成功次数 + // NSSF.A.08 网元订阅次数 + // NSSF.A.09 网元去订阅成功次数 + // NSSF.A.10 网元去订阅次数 + // NSSF.A.11 向NRF注册成功次数 + // NSSF.A.12 向NRF注册次数 + // NSSF.A.13 向NRF发送心跳次数 + // NSSF.A.14 当前注册AMF个数 + // NSSF.A.15 当前订阅网元个数 + // ===================== + + // NSSF.A.01 可用AMF注册更新次数 + if v, ok := item["NSSF.A.01"]; ok && v != nil { + vStr := fmt.Sprint(v) + itemArr[2] = vStr + itemArr[3] = vStr + itemArr[4] = vStr + } + + // NSSF.A.15 当前订阅网元个数 + if v, ok := item["NSSF.A.15"]; ok && v != nil { + vStr := fmt.Sprint(v) + itemArr[12] = vStr + itemArr[13] = vStr + itemArr[14] = vStr + } + // 添加后恢复单行数据 + parseDataArr = append(parseDataArr, itemArr) + itemArr = rowmArr + } + return parseDataArr +}