feat(api): add traffic log details filtering and enhance traffic log structures
This commit is contained in:
@@ -4,9 +4,13 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/perfect-panel/server/internal/model/log"
|
||||
"github.com/perfect-panel/server/internal/model/traffic"
|
||||
"github.com/perfect-panel/server/internal/svc"
|
||||
"github.com/perfect-panel/server/internal/types"
|
||||
"github.com/perfect-panel/server/pkg/logger"
|
||||
"github.com/perfect-panel/server/pkg/xerr"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type FilterServerTrafficLogLogic struct {
|
||||
@@ -23,21 +27,124 @@ func NewFilterServerTrafficLogLogic(ctx context.Context, svcCtx *svc.ServiceCont
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *FilterServerTrafficLogLogic) FilterServerTrafficLog(req *types.FilterServerTrafficLogRequest) (resp *types.FilterServerTrafficLogResponse, err error) {
|
||||
today := time.Now().Format("2006-01-02")
|
||||
if req.Date == "" || req.Date == today {
|
||||
return l.handlerToday(req)
|
||||
} else {
|
||||
return l.handlerSpecify(req)
|
||||
var list []types.ServerTrafficLog
|
||||
var total int64
|
||||
|
||||
if req.Date == today || req.Date == "" {
|
||||
now := time.Now()
|
||||
start := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local)
|
||||
end := start.Add(24 * time.Hour).Add(-time.Nanosecond)
|
||||
|
||||
var serverTraffic []log.ServerTraffic
|
||||
err = l.svcCtx.DB.WithContext(l.ctx).
|
||||
Model(&traffic.TrafficLog{}).
|
||||
Select("server_id, SUM(download + upload) AS total, SUM(download) AS download, SUM(upload) AS upload").
|
||||
Where("timestamp BETWEEN ? AND ?", start, end).
|
||||
Group("server_id").
|
||||
Order("id DESC").
|
||||
Scan(&serverTraffic).Error
|
||||
if err != nil {
|
||||
l.Errorw("[FilterServerTrafficLog] Query Database Error", logger.Field("error", err.Error()))
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "today traffic query error: %s", err.Error())
|
||||
}
|
||||
|
||||
for _, v := range serverTraffic {
|
||||
list = append(list, types.ServerTrafficLog{
|
||||
ServerId: v.ServerId,
|
||||
Upload: v.Upload,
|
||||
Download: v.Download,
|
||||
Total: v.Total,
|
||||
Date: today,
|
||||
Details: true,
|
||||
})
|
||||
}
|
||||
|
||||
todayTotal := len(list)
|
||||
|
||||
startIdx := (req.Page - 1) * req.Size
|
||||
endIdx := startIdx + req.Size
|
||||
|
||||
if startIdx < todayTotal {
|
||||
if endIdx > todayTotal {
|
||||
endIdx = todayTotal
|
||||
}
|
||||
pageData := list[startIdx:endIdx]
|
||||
return &types.FilterServerTrafficLogResponse{
|
||||
List: pageData,
|
||||
Total: int64(todayTotal),
|
||||
}, nil
|
||||
}
|
||||
|
||||
need := endIdx - todayTotal
|
||||
historyPage := (need + req.Size - 1) / req.Size // 算出需要的历史页数
|
||||
historyData, historyTotal, err := l.svcCtx.LogModel.FilterSystemLog(l.ctx, &log.FilterParams{
|
||||
Page: historyPage,
|
||||
Size: need,
|
||||
Type: log.TypeServerTraffic.Uint8(),
|
||||
})
|
||||
if err != nil {
|
||||
l.Errorw("[FilterServerTrafficLog] Query History Error", logger.Field("error", err.Error()))
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "history query error: %s", err.Error())
|
||||
}
|
||||
|
||||
for _, item := range historyData {
|
||||
var content log.ServerTraffic
|
||||
if err = content.Unmarshal([]byte(item.Content)); err != nil {
|
||||
l.Errorw("[FilterServerTrafficLog] Unmarshal Error", logger.Field("error", err.Error()), logger.Field("content", item.Content))
|
||||
continue
|
||||
}
|
||||
list = append(list, types.ServerTrafficLog{
|
||||
ServerId: item.ObjectID,
|
||||
Upload: content.Upload,
|
||||
Download: content.Download,
|
||||
Total: content.Total,
|
||||
Date: item.Date,
|
||||
Details: false,
|
||||
})
|
||||
}
|
||||
|
||||
// 返回最终分页数据
|
||||
if endIdx > len(list) {
|
||||
endIdx = len(list)
|
||||
}
|
||||
pageData := list[startIdx:endIdx]
|
||||
|
||||
return &types.FilterServerTrafficLogResponse{
|
||||
List: pageData,
|
||||
Total: int64(todayTotal) + historyTotal,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (l *FilterServerTrafficLogLogic) handlerToday(req *types.FilterServerTrafficLogRequest) (resp *types.FilterServerTrafficLogResponse, err error) {
|
||||
data, total, err := l.svcCtx.LogModel.FilterSystemLog(l.ctx, &log.FilterParams{
|
||||
Page: req.Page,
|
||||
Size: req.Size,
|
||||
Type: log.TypeServerTraffic.Uint8(),
|
||||
})
|
||||
if err != nil {
|
||||
l.Errorw("[FilterServerTrafficLog] Query Database Error", logger.Field("error", err.Error()))
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "history query error: %s", err.Error())
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
for _, item := range data {
|
||||
var content log.ServerTraffic
|
||||
if err = content.Unmarshal([]byte(item.Content)); err != nil {
|
||||
l.Errorw("[FilterServerTrafficLog] Unmarshal Error", logger.Field("error", err.Error()), logger.Field("content", item.Content))
|
||||
continue
|
||||
}
|
||||
list = append(list, types.ServerTrafficLog{
|
||||
ServerId: item.ObjectID,
|
||||
Upload: content.Upload,
|
||||
Download: content.Download,
|
||||
Total: content.Total,
|
||||
Date: item.Date,
|
||||
Details: false,
|
||||
})
|
||||
}
|
||||
|
||||
func (l *FilterServerTrafficLogLogic) handlerSpecify(req *types.FilterServerTrafficLogRequest) (resp *types.FilterServerTrafficLogResponse, err error) {
|
||||
return
|
||||
return &types.FilterServerTrafficLogResponse{
|
||||
List: list,
|
||||
Total: total,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/perfect-panel/server/internal/model/traffic"
|
||||
"github.com/perfect-panel/server/internal/svc"
|
||||
"github.com/perfect-panel/server/internal/types"
|
||||
"github.com/perfect-panel/server/pkg/logger"
|
||||
"github.com/perfect-panel/server/pkg/xerr"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type FilterTrafficLogDetailsLogic struct {
|
||||
logger.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
// Filter traffic log details
|
||||
func NewFilterTrafficLogDetailsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *FilterTrafficLogDetailsLogic {
|
||||
return &FilterTrafficLogDetailsLogic{
|
||||
Logger: logger.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *FilterTrafficLogDetailsLogic) FilterTrafficLogDetails(req *types.FilterTrafficLogDetailsRequest) (resp *types.FilterTrafficLogDetailsResponse, err error) {
|
||||
var start, end time.Time
|
||||
if req.Date != "" {
|
||||
day, err := time.ParseInLocation("2006-01-02", req.Date, time.Local)
|
||||
if err != nil {
|
||||
l.Errorw("[FilterTrafficLogDetails] Date Parse Error", logger.Field("error", err.Error()))
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidParams), " date parse error: %s", err.Error())
|
||||
}
|
||||
start = day
|
||||
end = day.Add(24*time.Hour - time.Nanosecond)
|
||||
}
|
||||
var data []*traffic.TrafficLog
|
||||
tx := l.svcCtx.DB.WithContext(l.ctx).Model(&traffic.TrafficLog{})
|
||||
if req.ServerId != 0 {
|
||||
tx = tx.Where("server_id = ?", req.ServerId)
|
||||
}
|
||||
if !start.IsZero() && !end.IsZero() {
|
||||
tx = tx.Where("timestamp BETWEEN ? AND ?", start, end)
|
||||
}
|
||||
if req.UserId != 0 {
|
||||
tx = tx.Where("user_id = ?", req.UserId)
|
||||
}
|
||||
if req.SubscribeId != 0 {
|
||||
tx = tx.Where("subscribe_id = ?", req.SubscribeId)
|
||||
}
|
||||
var total int64
|
||||
err = tx.Count(&total).Limit(req.Size).Offset((req.Page - 1) * req.Size).Find(&data).Error
|
||||
if err != nil {
|
||||
l.Errorw("[FilterTrafficLogDetails] Query Database Error", logger.Field("error", err.Error()))
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), " database query error: %s", err.Error())
|
||||
}
|
||||
|
||||
var logs []types.TrafficLogDetails
|
||||
for _, v := range data {
|
||||
logs = append(logs, types.TrafficLogDetails{
|
||||
Id: v.Id,
|
||||
UserId: v.UserId,
|
||||
ServerId: v.ServerId,
|
||||
SubscribeId: v.SubscribeId,
|
||||
Download: v.Download,
|
||||
Upload: v.Upload,
|
||||
Timestamp: v.Timestamp.UnixMilli(),
|
||||
})
|
||||
}
|
||||
|
||||
return &types.FilterTrafficLogDetailsResponse{
|
||||
List: logs,
|
||||
Total: total,
|
||||
}, nil
|
||||
}
|
||||
@@ -2,10 +2,15 @@ package log
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/perfect-panel/server/internal/model/log"
|
||||
"github.com/perfect-panel/server/internal/model/traffic"
|
||||
"github.com/perfect-panel/server/internal/svc"
|
||||
"github.com/perfect-panel/server/internal/types"
|
||||
"github.com/perfect-panel/server/pkg/logger"
|
||||
"github.com/perfect-panel/server/pkg/xerr"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type FilterUserSubscribeTrafficLogLogic struct {
|
||||
@@ -24,7 +29,125 @@ func NewFilterUserSubscribeTrafficLogLogic(ctx context.Context, svcCtx *svc.Serv
|
||||
}
|
||||
|
||||
func (l *FilterUserSubscribeTrafficLogLogic) FilterUserSubscribeTrafficLog(req *types.FilterSubscribeTrafficRequest) (resp *types.FilterSubscribeTrafficResponse, err error) {
|
||||
// todo: add your logic here and delete this line
|
||||
today := time.Now().Format("2006-01-02")
|
||||
var list []types.UserSubscribeTrafficLog
|
||||
var total int64
|
||||
|
||||
return
|
||||
if req.Date == today || req.Date == "" {
|
||||
now := time.Now()
|
||||
start := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local)
|
||||
end := start.Add(24 * time.Hour).Add(-time.Nanosecond)
|
||||
|
||||
var userTraffic []types.UserSubscribeTrafficLog
|
||||
err = l.svcCtx.DB.WithContext(l.ctx).
|
||||
Model(&traffic.TrafficLog{}).
|
||||
Select("user_id, subscribe_id, SUM(download + upload) AS total, SUM(download) AS download, SUM(upload) AS upload").
|
||||
Where("timestamp BETWEEN ? AND ?", start, end).
|
||||
Group("user_id, subscribe_id").
|
||||
Order("id DESC").
|
||||
Scan(&userTraffic).Error
|
||||
if err != nil {
|
||||
l.Errorw("[FilterUserSubscribeTrafficLog] Query Database Error", logger.Field("error", err.Error()))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, v := range userTraffic {
|
||||
list = append(list, types.UserSubscribeTrafficLog{
|
||||
UserId: v.UserId,
|
||||
SubscribeId: v.SubscribeId,
|
||||
Upload: v.Upload,
|
||||
Download: v.Download,
|
||||
Total: v.Total,
|
||||
Date: today,
|
||||
Details: true,
|
||||
})
|
||||
}
|
||||
todayTotal := len(list)
|
||||
|
||||
startIdx := (req.Page - 1) * req.Size
|
||||
endIdx := startIdx + req.Size
|
||||
if startIdx < todayTotal {
|
||||
if endIdx > todayTotal {
|
||||
endIdx = todayTotal
|
||||
}
|
||||
pageData := list[startIdx:endIdx]
|
||||
return &types.FilterSubscribeTrafficResponse{
|
||||
List: pageData,
|
||||
Total: int64(todayTotal),
|
||||
}, nil
|
||||
}
|
||||
|
||||
need := endIdx - todayTotal
|
||||
historyPage := (need + req.Size - 1) / req.Size // 算出需要的历史页数
|
||||
historyData, historyTotal, err := l.svcCtx.LogModel.FilterSystemLog(l.ctx, &log.FilterParams{
|
||||
Page: historyPage,
|
||||
Size: need,
|
||||
Type: log.TypeSubscribeTraffic.Uint8(),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
l.Errorw("[FilterUserSubscribeTrafficLog] Query Database Error", logger.Field("error", err.Error()))
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "[FilterUserSubscribeTrafficLog] Query Database Error")
|
||||
}
|
||||
|
||||
for _, datum := range historyData {
|
||||
var item log.UserTraffic
|
||||
err = item.Unmarshal([]byte(datum.Content))
|
||||
if err != nil {
|
||||
l.Errorw("[FilterUserSubscribeTrafficLog] Unmarshal Content Error", logger.Field("error", err.Error()))
|
||||
continue
|
||||
}
|
||||
list = append(list, types.UserSubscribeTrafficLog{
|
||||
UserId: item.UserId,
|
||||
SubscribeId: item.SubscribeId,
|
||||
Upload: item.Upload,
|
||||
Download: item.Download,
|
||||
Total: item.Total,
|
||||
Date: datum.Date,
|
||||
Details: false,
|
||||
})
|
||||
}
|
||||
// 返回最终分页数据
|
||||
if endIdx > len(list) {
|
||||
endIdx = len(list)
|
||||
}
|
||||
pageData := list[startIdx:endIdx]
|
||||
|
||||
return &types.FilterSubscribeTrafficResponse{
|
||||
List: pageData,
|
||||
Total: int64(todayTotal) + historyTotal,
|
||||
}, nil
|
||||
}
|
||||
var data []*log.SystemLog
|
||||
data, total, err = l.svcCtx.LogModel.FilterSystemLog(l.ctx, &log.FilterParams{
|
||||
Page: req.Page,
|
||||
Size: req.Size,
|
||||
Type: log.TypeSubscribeTraffic.Uint8(),
|
||||
Data: req.Date,
|
||||
})
|
||||
if err != nil {
|
||||
l.Errorw("[FilterUserSubscribeTrafficLog] Query Database Error", logger.Field("error", err.Error()))
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "[FilterUserSubscribeTrafficLog] Query Database Error")
|
||||
}
|
||||
for _, datum := range data {
|
||||
var item log.UserTraffic
|
||||
err = item.Unmarshal([]byte(datum.Content))
|
||||
if err != nil {
|
||||
l.Errorw("[FilterUserSubscribeTrafficLog] Unmarshal Content Error", logger.Field("error", err.Error()))
|
||||
continue
|
||||
}
|
||||
list = append(list, types.UserSubscribeTrafficLog{
|
||||
UserId: item.UserId,
|
||||
SubscribeId: item.SubscribeId,
|
||||
Upload: item.Upload,
|
||||
Download: item.Download,
|
||||
Total: item.Total,
|
||||
Date: datum.Date,
|
||||
Details: false,
|
||||
})
|
||||
}
|
||||
return &types.FilterSubscribeTrafficResponse{
|
||||
List: list,
|
||||
Total: total,
|
||||
}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user