feat(traffic): add traffic statistics logging and scheduling
This commit is contained in:
@@ -497,7 +497,6 @@ func (l *OAuthLoginGetTokenLogic) recordLoginStatus(loginStatus bool, userInfo *
|
||||
}
|
||||
content, _ := loginLog.Marshal()
|
||||
if err := l.svcCtx.LogModel.Insert(l.ctx, &log.SystemLog{
|
||||
Id: 0,
|
||||
Type: log.TypeLogin.Uint8(),
|
||||
Date: time.Now().Format("2006-01-02"),
|
||||
ObjectID: userInfo.Id,
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/perfect-panel/server/internal/config"
|
||||
"github.com/perfect-panel/server/internal/model/log"
|
||||
"github.com/perfect-panel/server/internal/svc"
|
||||
"github.com/perfect-panel/server/internal/types"
|
||||
"github.com/perfect-panel/server/pkg/constant"
|
||||
@@ -100,6 +101,29 @@ func (l *TelephoneResetPasswordLogic) TelephoneResetPassword(req *types.Telephon
|
||||
if err = l.svcCtx.Redis.Set(l.ctx, sessionIdCacheKey, userInfo.Id, time.Duration(l.svcCtx.Config.JwtAuth.AccessExpire)*time.Second).Err(); err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "set session id error: %v", err.Error())
|
||||
}
|
||||
defer func() {
|
||||
if token != "" && userInfo.Id != 0 {
|
||||
loginLog := log.Login{
|
||||
LoginIP: req.IP,
|
||||
UserAgent: req.UserAgent,
|
||||
Success: token != "",
|
||||
}
|
||||
content, _ := loginLog.Marshal()
|
||||
if err = l.svcCtx.LogModel.Insert(l.ctx, &log.SystemLog{
|
||||
Id: 0,
|
||||
Type: log.TypeLogin.Uint8(),
|
||||
Date: time.Now().Format("2006-01-02"),
|
||||
ObjectID: userInfo.Id,
|
||||
Content: string(content),
|
||||
}); err != nil {
|
||||
l.Errorw("failed to insert login log",
|
||||
logger.Field("user_id", userInfo.Id),
|
||||
logger.Field("ip", req.IP),
|
||||
logger.Field("error", err.Error()),
|
||||
)
|
||||
}
|
||||
}
|
||||
}()
|
||||
return &types.LoginResponse{
|
||||
Token: token,
|
||||
}, nil
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/perfect-panel/server/internal/model/log"
|
||||
"github.com/perfect-panel/server/pkg/constant"
|
||||
|
||||
"github.com/perfect-panel/server/internal/config"
|
||||
@@ -154,6 +155,51 @@ func (l *TelephoneUserRegisterLogic) TelephoneUserRegister(req *types.TelephoneR
|
||||
if err = l.svcCtx.Redis.Set(l.ctx, sessionIdCacheKey, userInfo.Id, time.Duration(l.svcCtx.Config.JwtAuth.AccessExpire)*time.Second).Err(); err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "set session id error: %v", err.Error())
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if token != "" && userInfo.Id != 0 {
|
||||
loginLog := log.Login{
|
||||
LoginIP: req.IP,
|
||||
UserAgent: req.UserAgent,
|
||||
Success: token != "",
|
||||
}
|
||||
content, _ := loginLog.Marshal()
|
||||
if err = l.svcCtx.LogModel.Insert(l.ctx, &log.SystemLog{
|
||||
Id: 0,
|
||||
Type: log.TypeLogin.Uint8(),
|
||||
Date: time.Now().Format("2006-01-02"),
|
||||
ObjectID: userInfo.Id,
|
||||
Content: string(content),
|
||||
}); err != nil {
|
||||
l.Errorw("failed to insert login log",
|
||||
logger.Field("user_id", userInfo.Id),
|
||||
logger.Field("ip", req.IP),
|
||||
logger.Field("error", err.Error()),
|
||||
)
|
||||
}
|
||||
|
||||
// Register log
|
||||
registerLog := log.Register{
|
||||
AuthMethod: "mobile",
|
||||
Identifier: phoneNumber,
|
||||
RegisterIP: req.IP,
|
||||
UserAgent: req.UserAgent,
|
||||
RegisterTime: time.Now().UnixMilli(),
|
||||
}
|
||||
content, _ = registerLog.Marshal()
|
||||
if err = l.svcCtx.LogModel.Insert(l.ctx, &log.SystemLog{
|
||||
Type: log.TypeRegister.Uint8(),
|
||||
ObjectID: userInfo.Id,
|
||||
Date: time.Now().Format("2006-01-02"),
|
||||
Content: string(content),
|
||||
}); err != nil {
|
||||
l.Errorw("failed to insert login log",
|
||||
logger.Field("user_id", userInfo.Id),
|
||||
logger.Field("ip", req.IP),
|
||||
logger.Field("error", err.Error()))
|
||||
}
|
||||
}
|
||||
}()
|
||||
return &types.LoginResponse{
|
||||
Token: token,
|
||||
}, nil
|
||||
|
||||
@@ -48,7 +48,7 @@ func (l *UserLoginLogic) UserLogin(req *types.UserLoginRequest) (resp *types.Log
|
||||
Success: loginStatus,
|
||||
}
|
||||
content, _ := loginLog.Marshal()
|
||||
if err := l.svcCtx.LogModel.Insert(l.ctx, &log.SystemLog{
|
||||
if err = l.svcCtx.LogModel.Insert(l.ctx, &log.SystemLog{
|
||||
Type: log.TypeLogin.Uint8(),
|
||||
Date: time.Now().Format("2006-01-02"),
|
||||
ObjectID: userInfo.Id,
|
||||
|
||||
@@ -165,6 +165,27 @@ func (l *UserRegisterLogic) UserRegister(req *types.UserRegisterRequest) (resp *
|
||||
logger.Field("error", err.Error()),
|
||||
)
|
||||
}
|
||||
|
||||
// Register log
|
||||
registerLog := log.Register{
|
||||
AuthMethod: "email",
|
||||
Identifier: req.Email,
|
||||
RegisterIP: req.IP,
|
||||
UserAgent: req.UserAgent,
|
||||
RegisterTime: time.Now().UnixMilli(),
|
||||
}
|
||||
content, _ = registerLog.Marshal()
|
||||
if err = l.svcCtx.LogModel.Insert(l.ctx, &log.SystemLog{
|
||||
Type: log.TypeRegister.Uint8(),
|
||||
ObjectID: userInfo.Id,
|
||||
Date: time.Now().Format("2006-01-02"),
|
||||
Content: string(content),
|
||||
}); err != nil {
|
||||
l.Errorw("failed to insert login log",
|
||||
logger.Field("user_id", userInfo.Id),
|
||||
logger.Field("ip", req.IP),
|
||||
logger.Field("error", err.Error()))
|
||||
}
|
||||
}
|
||||
}()
|
||||
return &types.LoginResponse{
|
||||
|
||||
+107
-11
@@ -8,17 +8,19 @@ import (
|
||||
type Type uint8
|
||||
|
||||
const (
|
||||
TypeEmailMessage Type = iota + 1 // Message log
|
||||
TypeMobileMessage // Mobile message log
|
||||
TypeSubscribe // Subscription log
|
||||
TypeSubscribeTraffic // Subscription traffic log
|
||||
TypeServerTraffic // Server traffic log
|
||||
TypeLogin // Login log
|
||||
TypeRegister // Registration log
|
||||
TypeBalance // Balance log
|
||||
TypeCommission // Commission log
|
||||
TypeResetSubscribe // Reset subscription log
|
||||
TypeGift // Gift log
|
||||
TypeEmailMessage Type = iota + 1 // Message log
|
||||
TypeMobileMessage // Mobile message log
|
||||
TypeSubscribe // Subscription log
|
||||
TypeSubscribeTraffic // Subscription traffic log
|
||||
TypeServerTraffic // Server traffic log
|
||||
TypeLogin // Login log
|
||||
TypeRegister // Registration log
|
||||
TypeBalance // Balance log
|
||||
TypeCommission // Commission log
|
||||
TypeResetSubscribe // Reset subscription log
|
||||
TypeGift // Gift log
|
||||
TypeUserTrafficRank // Top 10 User traffic rank log
|
||||
TypeServerTrafficRank // Top 10 Server traffic rank log
|
||||
)
|
||||
|
||||
// Uint8 converts Type to uint8.
|
||||
@@ -296,3 +298,97 @@ func (g *Gift) Unmarshal(data []byte) error {
|
||||
aux := (*Alias)(g)
|
||||
return json.Unmarshal(data, aux)
|
||||
}
|
||||
|
||||
// UserTraffic represents a user traffic log entry.
|
||||
type UserTraffic struct {
|
||||
SubscribeId int64 `json:"subscribe_id"` // Subscribe ID
|
||||
UserId int64 `json:"user_id"` // User ID
|
||||
Upload int64 `json:"upload"` // Upload traffic in bytes
|
||||
Download int64 `json:"download"` // Download traffic in bytes
|
||||
Total int64 `json:"total"` // Total traffic in bytes (Upload + Download)
|
||||
}
|
||||
|
||||
// Marshal implements the json.Marshaler interface for UserTraffic.
|
||||
func (u *UserTraffic) Marshal() ([]byte, error) {
|
||||
type Alias UserTraffic
|
||||
return json.Marshal(&struct {
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(u),
|
||||
})
|
||||
}
|
||||
|
||||
// Unmarshal implements the json.Unmarshaler interface for UserTraffic.
|
||||
func (u *UserTraffic) Unmarshal(data []byte) error {
|
||||
type Alias UserTraffic
|
||||
aux := (*Alias)(u)
|
||||
return json.Unmarshal(data, aux)
|
||||
}
|
||||
|
||||
// UserTrafficRank represents a user traffic rank entry.
|
||||
type UserTrafficRank struct {
|
||||
Rank map[uint8]UserTraffic `json:"rank"` // Key is rank ,type is UserTraffic
|
||||
}
|
||||
|
||||
// Marshal implements the json.Marshaler interface for UserTrafficRank.
|
||||
func (u *UserTrafficRank) Marshal() ([]byte, error) {
|
||||
type Alias UserTrafficRank
|
||||
return json.Marshal(&struct {
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(u),
|
||||
})
|
||||
}
|
||||
|
||||
// Unmarshal implements the json.Unmarshaler interface for UserTrafficRank.
|
||||
func (u *UserTrafficRank) Unmarshal(data []byte) error {
|
||||
type Alias UserTrafficRank
|
||||
aux := (*Alias)(u)
|
||||
return json.Unmarshal(data, aux)
|
||||
}
|
||||
|
||||
// ServerTraffic represents a server traffic log entry.
|
||||
type ServerTraffic struct {
|
||||
ServerId int64 `json:"server_id"` // Server ID
|
||||
Upload int64 `json:"upload"` // Upload traffic in bytes
|
||||
Download int64 `json:"download"` // Download traffic in bytes
|
||||
}
|
||||
|
||||
// Marshal implements the json.Marshaler interface for ServerTraffic.
|
||||
func (s *ServerTraffic) Marshal() ([]byte, error) {
|
||||
type Alias ServerTraffic
|
||||
return json.Marshal(&struct {
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(s),
|
||||
})
|
||||
}
|
||||
|
||||
// Unmarshal implements the json.Unmarshaler interface for ServerTraffic.
|
||||
func (s *ServerTraffic) Unmarshal(data []byte) error {
|
||||
type Alias ServerTraffic
|
||||
aux := (*Alias)(s)
|
||||
return json.Unmarshal(data, aux)
|
||||
}
|
||||
|
||||
// ServerTrafficRank represents a server traffic rank entry.
|
||||
type ServerTrafficRank struct {
|
||||
Rank map[uint8]ServerTraffic `json:"rank"` // Key is rank ,type is ServerTraffic
|
||||
}
|
||||
|
||||
// Marshal implements the json.Marshaler interface for ServerTrafficRank.
|
||||
func (s *ServerTrafficRank) Marshal() ([]byte, error) {
|
||||
type Alias ServerTrafficRank
|
||||
return json.Marshal(&struct {
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(s),
|
||||
})
|
||||
}
|
||||
|
||||
// Unmarshal implements the json.Unmarshaler interface for ServerTrafficRank.
|
||||
func (s *ServerTrafficRank) Unmarshal(data []byte) error {
|
||||
type Alias ServerTrafficRank
|
||||
aux := (*Alias)(s)
|
||||
return json.Unmarshal(data, aux)
|
||||
}
|
||||
|
||||
@@ -1731,6 +1731,7 @@ type TelephoneLoginRequest struct {
|
||||
TelephoneAreaCode string `json:"telephone_area_code" validate:"required"`
|
||||
Password string `json:"password"`
|
||||
IP string `header:"X-Original-Forwarded-For"`
|
||||
UserAgent string `header:"User-Agent"`
|
||||
CfToken string `json:"cf_token,optional"`
|
||||
}
|
||||
|
||||
@@ -1741,6 +1742,7 @@ type TelephoneRegisterRequest struct {
|
||||
Invite string `json:"invite,optional"`
|
||||
Code string `json:"code,optional"`
|
||||
IP string `header:"X-Original-Forwarded-For"`
|
||||
UserAgent string `header:"User-Agent"`
|
||||
CfToken string `json:"cf_token,optional"`
|
||||
}
|
||||
|
||||
@@ -1750,6 +1752,7 @@ type TelephoneResetPasswordRequest struct {
|
||||
Password string `json:"password" validate:"required"`
|
||||
Code string `json:"code,optional"`
|
||||
IP string `header:"X-Original-Forwarded-For"`
|
||||
UserAgent string `header:"User-Agent"`
|
||||
CfToken string `json:"cf_token,optional"`
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user