feat: AMF-audit日志文件获取接口

This commit is contained in:
TsMask
2025-09-28 18:15:29 +08:00
parent f4fdde0cf3
commit 63dfdd2f47
2 changed files with 226 additions and 0 deletions

View File

@@ -3,12 +3,14 @@ package controller
import (
"encoding/json"
"fmt"
"sort"
"strconv"
"strings"
"time"
"be.ems/src/framework/i18n"
"be.ems/src/framework/logger"
"be.ems/src/framework/resp"
"be.ems/src/framework/utils/ctx"
"be.ems/src/framework/utils/date"
"be.ems/src/framework/utils/file"
@@ -370,3 +372,129 @@ func (s *AMFController) NbStateList(c *gin.Context) {
c.JSON(200, result.OkData(data))
}
// 获取审计日志
//
// GET /log/audit
//
// @Tags network_data/amf
// @Accept json
// @Produce json
// @Param neId query string true "NE ID" default(001)
// @Success 200 {object} object "Response Results"
// @Security TokenAuth
// @Summary Access to the audit log
// @Description Access to the audit log
// @Router /neData/amf/log/audit [get]
func (s *AMFController) AuditLog(c *gin.Context) {
var query struct {
NeId string `form:"neId" binding:"required"`
BeginTime int64 `json:"beginTime" form:"beginTime"`
EndTime int64 `json:"endTime" form:"endTime"`
}
if err := c.ShouldBindQuery(&query); err != nil {
errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
return
}
// 处理时间范围
if query.BeginTime != 0 && query.BeginTime < 1e12 {
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "begin time must ms"))
return
}
if query.EndTime != 0 && query.EndTime < 1e12 {
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "end time must ms"))
return
}
auditLog, err := neDataService.NewAMF.GetAuditLog(query.NeId)
if err != nil {
c.JSON(200, result.ErrMsg(err.Error()))
return
}
if len(auditLog) == 0 {
c.JSON(200, result.ErrMsg("audit log is empty"))
return
}
// 对auditLog按time字段排序
sort.SliceStable(auditLog, func(i, j int) bool {
// 获取i的time值
timeI, okI := auditLog[i]["time"].(string)
// 获取j的time值
timeJ, okJ := auditLog[j]["time"].(string)
// 如果任何一个不包含有效time字段将它们放在后面
if !okI || !okJ {
return okI && !okJ
}
// 解析时间字符串
tI, errI := time.Parse(time.DateTime, timeI)
tJ, errJ := time.Parse(time.DateTime, timeJ)
// 如果任何一个解析失败,将它们放在后面
if errI != nil || errJ != nil {
return errJ != nil && errI == nil
}
// 按时间升序排序如果需要降序改为tI.After(tJ)
return tI.After(tJ)
})
// 响应格式
timeStr := ""
data := make([]map[string]any, 0)
if query.BeginTime > 1e12 && query.EndTime > 1e12 {
// 时间处理
beginT := time.UnixMilli(query.BeginTime)
endT := time.UnixMilli(query.EndTime)
timeStr = fmt.Sprintf("%s - %s", beginT.Format(time.DateTime), endT.Format(time.DateTime))
for _, v := range auditLog {
timeV, ok := v["time"].(string)
if !ok {
continue
}
// 解析时间
t, err := time.Parse(time.DateTime, timeV)
if err != nil {
continue
}
// 检查时间是否在范围内
if t.After(beginT) && t.After(endT) {
data = append(data, map[string]any{
"supi": fmt.Sprint(v["supi"]),
"amf_ue_ngap_id": parse.Number(v["amf_ue_ngap_id"]),
"ran_ue_ngap_id": parse.Number(v["ran_ue_ngap_id"]),
"gnb_id": parse.Number(v["gnb_id"]),
"time": timeV,
})
}
}
} else {
lastItem := auditLog[0]
lastTime := ""
if timeV, ok := lastItem["time"].(string); ok {
lastTime = timeV[:19]
}
timeStr = lastTime
for _, v := range auditLog {
timeV, ok := v["time"].(string)
if !ok {
continue
}
if !strings.HasPrefix(timeV, lastTime) {
continue
}
data = append(data, map[string]any{
"supi": fmt.Sprint(v["supi"]),
"amf_ue_ngap_id": parse.Number(v["amf_ue_ngap_id"]),
"ran_ue_ngap_id": parse.Number(v["ran_ue_ngap_id"]),
"gnb_id": parse.Number(v["gnb_id"]),
})
}
}
c.JSON(200, map[string]any{
"time": timeStr,
"ngap_context": data,
})
}