174 lines
6.0 KiB
Go
174 lines
6.0 KiB
Go
package errorlog
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"chatapp3-golang/internal/model"
|
|
"chatapp3-golang/internal/utils"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// ReportAgoraError persists one client-reported Agora error log.
|
|
func (s *Service) ReportAgoraError(ctx context.Context, user AuthUser, req AgoraErrorReportRequest, meta AgoraErrorReportContext) (*AgoraErrorReportResponse, error) {
|
|
if s == nil || s.db == nil {
|
|
return nil, NewAppError(http.StatusServiceUnavailable, "error_log_unavailable", "error log service is unavailable")
|
|
}
|
|
roomID := req.RoomID.String()
|
|
if roomID == "" {
|
|
return nil, NewAppError(http.StatusBadRequest, "room_id_required", "roomId is required")
|
|
}
|
|
reasonType := firstNonBlank(req.ConnectionChangedReasonType, req.ReasonType, req.Reason)
|
|
bannedByServer := isBannedByServer(reasonType)
|
|
|
|
id, err := utils.NextID()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
now := time.Now()
|
|
row := model.AgoraErrorLog{
|
|
ID: id,
|
|
SysOrigin: normalizeSysOrigin(user.SysOrigin),
|
|
UserID: user.UserID,
|
|
RoomID: trimMax(roomID, 64),
|
|
AgoraUID: trimMax(req.AgoraUID.String(), 64),
|
|
ErrorCodeType: trimMax(req.ErrorCodeType, 128),
|
|
ConnectionChangedReasonType: trimMax(reasonType, 128),
|
|
BannedByServer: bannedByServer,
|
|
IsTimeout: boolValue(req.Timeout, req.IsTimeout),
|
|
TokenRequestSuccess: boolPtrValue(req.TokenRequestSuccess, req.TokenSuccess),
|
|
NetworkType: trimMax(req.NetworkType, 64),
|
|
ReqClient: trimMax(meta.ReqClient, 32),
|
|
ReqAppIntel: trimMax(meta.ReqAppIntel, 255),
|
|
ClientIP: trimMax(meta.ClientIP, 64),
|
|
UserAgent: trimMax(meta.UserAgent, 255),
|
|
RawPayload: strings.TrimSpace(meta.RawPayload),
|
|
CreateTime: now,
|
|
UpdateTime: now,
|
|
}
|
|
if err := s.db.WithContext(ctx).Create(&row).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return &AgoraErrorReportResponse{
|
|
ID: strconv.FormatInt(id, 10),
|
|
BannedByServer: bannedByServer,
|
|
}, nil
|
|
}
|
|
|
|
// PageAgoraErrorLogs returns admin Agora error logs.
|
|
func (s *Service) PageAgoraErrorLogs(ctx context.Context, query AgoraErrorLogQuery) (*AgoraErrorLogPageResponse, error) {
|
|
if s == nil || s.db == nil {
|
|
return nil, NewAppError(http.StatusServiceUnavailable, "error_log_unavailable", "error log service is unavailable")
|
|
}
|
|
cursor, limit := normalizePage(query.Cursor, query.Limit)
|
|
startTime, endTime, err := parseAdminTimeRange(query.StartTime, query.EndTime)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
filter := query
|
|
filter.Cursor = cursor
|
|
filter.Limit = limit
|
|
filter.StartAt = startTime
|
|
filter.EndAt = endTime
|
|
|
|
base := s.agoraErrorLogQuery(ctx, filter)
|
|
var total int64
|
|
if err := base.Count(&total).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var rows []model.AgoraErrorLog
|
|
if err := s.agoraErrorLogQuery(ctx, filter).
|
|
Order("create_time desc, id desc").
|
|
Offset((cursor - 1) * limit).
|
|
Limit(limit).
|
|
Find(&rows).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return &AgoraErrorLogPageResponse{
|
|
Records: agoraErrorLogItems(rows),
|
|
Total: total,
|
|
Current: cursor,
|
|
Size: limit,
|
|
}, nil
|
|
}
|
|
|
|
// AgoraErrorLogQuery is the admin filter for Agora error logs.
|
|
type AgoraErrorLogQuery struct {
|
|
SysOrigin string
|
|
UserID int64
|
|
RoomID string
|
|
AgoraUID string
|
|
ErrorCodeType string
|
|
ReasonType string
|
|
BannedOnly bool
|
|
NetworkType string
|
|
StartTime string
|
|
EndTime string
|
|
Cursor int
|
|
Limit int
|
|
StartAt time.Time
|
|
EndAt time.Time
|
|
}
|
|
|
|
func (s *Service) agoraErrorLogQuery(ctx context.Context, filter AgoraErrorLogQuery) *gorm.DB {
|
|
query := s.db.WithContext(ctx).Model(&model.AgoraErrorLog{}).
|
|
Where("create_time >= ? AND create_time <= ?", filter.StartAt, filter.EndAt)
|
|
if sysOrigin := normalizeSysOrigin(filter.SysOrigin); sysOrigin != "" {
|
|
query = query.Where("sys_origin = ?", sysOrigin)
|
|
}
|
|
if filter.UserID > 0 {
|
|
query = query.Where("user_id = ?", filter.UserID)
|
|
}
|
|
if roomID := strings.TrimSpace(filter.RoomID); roomID != "" {
|
|
query = query.Where("room_id = ?", roomID)
|
|
}
|
|
if agoraUID := strings.TrimSpace(filter.AgoraUID); agoraUID != "" {
|
|
query = query.Where("agora_uid = ?", agoraUID)
|
|
}
|
|
if codeType := strings.TrimSpace(filter.ErrorCodeType); codeType != "" {
|
|
query = query.Where("error_code_type LIKE ?", "%"+codeType+"%")
|
|
}
|
|
if reasonType := strings.TrimSpace(filter.ReasonType); reasonType != "" {
|
|
query = query.Where("connection_changed_reason_type LIKE ?", "%"+reasonType+"%")
|
|
}
|
|
if filter.BannedOnly {
|
|
query = query.Where("banned_by_server = ?", true)
|
|
}
|
|
if networkType := strings.TrimSpace(filter.NetworkType); networkType != "" {
|
|
query = query.Where("network_type = ?", networkType)
|
|
}
|
|
return query
|
|
}
|
|
|
|
func agoraErrorLogItems(rows []model.AgoraErrorLog) []AgoraErrorLogItem {
|
|
items := make([]AgoraErrorLogItem, 0, len(rows))
|
|
for _, row := range rows {
|
|
items = append(items, AgoraErrorLogItem{
|
|
ID: strconv.FormatInt(row.ID, 10),
|
|
SysOrigin: row.SysOrigin,
|
|
UserID: strconv.FormatInt(row.UserID, 10),
|
|
RoomID: row.RoomID,
|
|
AgoraUID: row.AgoraUID,
|
|
ErrorCodeType: row.ErrorCodeType,
|
|
ConnectionChangedReasonType: row.ConnectionChangedReasonType,
|
|
BannedByServer: row.BannedByServer,
|
|
IsTimeout: row.IsTimeout,
|
|
TokenRequestSuccess: row.TokenRequestSuccess,
|
|
NetworkType: row.NetworkType,
|
|
ReqClient: row.ReqClient,
|
|
ReqAppIntel: row.ReqAppIntel,
|
|
ClientIP: row.ClientIP,
|
|
UserAgent: row.UserAgent,
|
|
RawPayload: row.RawPayload,
|
|
CreateTime: formatDateTime(row.CreateTime),
|
|
UpdateTime: formatDateTime(row.UpdateTime),
|
|
})
|
|
}
|
|
return items
|
|
}
|