mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-18 08:16:39 +00:00
add pagination for access logs
This commit is contained in:
@@ -6,5 +6,5 @@ import (
|
||||
|
||||
type Manager interface {
|
||||
SaveAccessLog(ctx context.Context, proxyLog *AccessLogEntry) error
|
||||
GetAllAccessLogs(ctx context.Context, accountID, userID string) ([]*AccessLogEntry, error)
|
||||
GetAllAccessLogs(ctx context.Context, accountID, userID string, filter AccessLogFilter) ([]*AccessLogEntry, int64, error)
|
||||
}
|
||||
|
||||
@@ -30,7 +30,11 @@ func (h *handler) getAccessLogs(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
logs, err := h.manager.GetAllAccessLogs(r.Context(), userAuth.AccountId, userAuth.UserId)
|
||||
// Parse pagination parameters from request
|
||||
var filter accesslogs.AccessLogFilter
|
||||
filter.ParseFromRequest(r)
|
||||
|
||||
logs, totalCount, err := h.manager.GetAllAccessLogs(r.Context(), userAuth.AccountId, userAuth.UserId, filter)
|
||||
if err != nil {
|
||||
util.WriteError(r.Context(), err, w)
|
||||
return
|
||||
@@ -41,5 +45,22 @@ func (h *handler) getAccessLogs(w http.ResponseWriter, r *http.Request) {
|
||||
apiLogs = append(apiLogs, *log.ToAPIResponse())
|
||||
}
|
||||
|
||||
util.WriteJSONObject(r.Context(), w, apiLogs)
|
||||
// Return paginated response
|
||||
response := &api.ProxyAccessLogsResponse{
|
||||
Data: apiLogs,
|
||||
Page: filter.Page,
|
||||
PageSize: filter.PageSize,
|
||||
TotalRecords: int(totalCount),
|
||||
TotalPages: getTotalPageCount(int(totalCount), filter.PageSize),
|
||||
}
|
||||
|
||||
util.WriteJSONObject(r.Context(), w, response)
|
||||
}
|
||||
|
||||
// getTotalPageCount calculates the total number of pages
|
||||
func getTotalPageCount(totalCount, pageSize int) int {
|
||||
if pageSize <= 0 {
|
||||
return 0
|
||||
}
|
||||
return (totalCount + pageSize - 1) / pageSize
|
||||
}
|
||||
|
||||
@@ -55,20 +55,20 @@ func (m *managerImpl) SaveAccessLog(ctx context.Context, logEntry *accesslogs.Ac
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetAllAccessLogs retrieves all access logs for an account
|
||||
func (m *managerImpl) GetAllAccessLogs(ctx context.Context, accountID, userID string) ([]*accesslogs.AccessLogEntry, error) {
|
||||
// GetAllAccessLogs retrieves access logs for an account with pagination
|
||||
func (m *managerImpl) GetAllAccessLogs(ctx context.Context, accountID, userID string, filter accesslogs.AccessLogFilter) ([]*accesslogs.AccessLogEntry, int64, error) {
|
||||
ok, err := m.permissionsManager.ValidateUserPermissions(ctx, accountID, userID, modules.Services, operations.Read)
|
||||
if err != nil {
|
||||
return nil, status.NewPermissionValidationError(err)
|
||||
return nil, 0, status.NewPermissionValidationError(err)
|
||||
}
|
||||
if !ok {
|
||||
return nil, status.NewPermissionDeniedError()
|
||||
return nil, 0, status.NewPermissionDeniedError()
|
||||
}
|
||||
|
||||
logs, err := m.store.GetAccountAccessLogs(ctx, store.LockingStrengthNone, accountID)
|
||||
logs, totalCount, err := m.store.GetAccountAccessLogs(ctx, store.LockingStrengthNone, accountID, filter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return logs, nil
|
||||
return logs, totalCount, nil
|
||||
}
|
||||
|
||||
@@ -5061,14 +5061,27 @@ func (s *SqlStore) CreateAccessLog(ctx context.Context, logEntry *accesslogs.Acc
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetAccountAccessLogs retrieves all access logs for a given account
|
||||
func (s *SqlStore) GetAccountAccessLogs(ctx context.Context, lockStrength LockingStrength, accountID string) ([]*accesslogs.AccessLogEntry, error) {
|
||||
// GetAccountAccessLogs retrieves access logs for a given account with pagination
|
||||
func (s *SqlStore) GetAccountAccessLogs(ctx context.Context, lockStrength LockingStrength, accountID string, filter accesslogs.AccessLogFilter) ([]*accesslogs.AccessLogEntry, int64, error) {
|
||||
var logs []*accesslogs.AccessLogEntry
|
||||
var totalCount int64
|
||||
|
||||
// Count total records for pagination metadata
|
||||
countQuery := s.db.WithContext(ctx).
|
||||
Model(&accesslogs.AccessLogEntry{}).
|
||||
Where(accountIDCondition, accountID)
|
||||
|
||||
if err := countQuery.Count(&totalCount).Error; err != nil {
|
||||
log.WithContext(ctx).Errorf("failed to count access logs: %v", err)
|
||||
return nil, 0, status.Errorf(status.Internal, "failed to count access logs")
|
||||
}
|
||||
|
||||
// Query with pagination
|
||||
query := s.db.WithContext(ctx).
|
||||
Where(accountIDCondition, accountID).
|
||||
Order("timestamp DESC").
|
||||
Limit(1000)
|
||||
Limit(filter.GetLimit()).
|
||||
Offset(filter.GetOffset())
|
||||
|
||||
if lockStrength != LockingStrengthNone {
|
||||
query = query.Clauses(clause.Locking{Strength: string(lockStrength)})
|
||||
@@ -5077,10 +5090,10 @@ func (s *SqlStore) GetAccountAccessLogs(ctx context.Context, lockStrength Lockin
|
||||
result := query.Find(&logs)
|
||||
if result.Error != nil {
|
||||
log.WithContext(ctx).Errorf("failed to get access logs from store: %v", result.Error)
|
||||
return nil, status.Errorf(status.Internal, "failed to get access logs from store")
|
||||
return nil, 0, status.Errorf(status.Internal, "failed to get access logs from store")
|
||||
}
|
||||
|
||||
return logs, nil
|
||||
return logs, totalCount, nil
|
||||
}
|
||||
|
||||
func (s *SqlStore) GetReverseProxyTargetByTargetID(ctx context.Context, lockStrength LockingStrength, accountID string, targetID string) (*reverseproxy.Target, error) {
|
||||
|
||||
@@ -266,7 +266,7 @@ type Store interface {
|
||||
DeleteCustomDomain(ctx context.Context, accountID string, domainID string) error
|
||||
|
||||
CreateAccessLog(ctx context.Context, log *accesslogs.AccessLogEntry) error
|
||||
GetAccountAccessLogs(ctx context.Context, lockStrength LockingStrength, accountID string) ([]*accesslogs.AccessLogEntry, error)
|
||||
GetAccountAccessLogs(ctx context.Context, lockStrength LockingStrength, accountID string, filter accesslogs.AccessLogFilter) ([]*accesslogs.AccessLogEntry, int64, error)
|
||||
GetReverseProxyTargetByTargetID(ctx context.Context, lockStrength LockingStrength, accountID string, targetID string) (*reverseproxy.Target, error)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user