| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- package service
- import (
- "context"
- "database/sql"
- "encoding/json"
- "errors"
- "log"
- "strings"
- "time"
- infraerrors "github.com/Wei-Shaw/sub2api/internal/pkg/errors"
- )
- func (s *OpsService) ListSystemLogs(ctx context.Context, filter *OpsSystemLogFilter) (*OpsSystemLogList, error) {
- if err := s.RequireMonitoringEnabled(ctx); err != nil {
- return nil, err
- }
- if s.opsRepo == nil {
- return &OpsSystemLogList{
- Logs: []*OpsSystemLog{},
- Total: 0,
- Page: 1,
- PageSize: 50,
- }, nil
- }
- if filter == nil {
- filter = &OpsSystemLogFilter{}
- }
- if filter.Page <= 0 {
- filter.Page = 1
- }
- if filter.PageSize <= 0 {
- filter.PageSize = 50
- }
- if filter.PageSize > 200 {
- filter.PageSize = 200
- }
- result, err := s.opsRepo.ListSystemLogs(ctx, filter)
- if err != nil {
- return nil, infraerrors.InternalServer("OPS_SYSTEM_LOG_LIST_FAILED", "Failed to list system logs").WithCause(err)
- }
- return result, nil
- }
- func (s *OpsService) CleanupSystemLogs(ctx context.Context, filter *OpsSystemLogCleanupFilter, operatorID int64) (int64, error) {
- if err := s.RequireMonitoringEnabled(ctx); err != nil {
- return 0, err
- }
- if s.opsRepo == nil {
- return 0, infraerrors.ServiceUnavailable("OPS_REPO_UNAVAILABLE", "Ops repository not available")
- }
- if operatorID <= 0 {
- return 0, infraerrors.BadRequest("OPS_SYSTEM_LOG_CLEANUP_INVALID_OPERATOR", "invalid operator")
- }
- if filter == nil {
- filter = &OpsSystemLogCleanupFilter{}
- }
- if filter.EndTime != nil && filter.StartTime != nil && filter.StartTime.After(*filter.EndTime) {
- return 0, infraerrors.BadRequest("OPS_SYSTEM_LOG_CLEANUP_INVALID_RANGE", "invalid time range")
- }
- deletedRows, err := s.opsRepo.DeleteSystemLogs(ctx, filter)
- if err != nil {
- if errors.Is(err, sql.ErrNoRows) {
- return 0, nil
- }
- if strings.Contains(strings.ToLower(err.Error()), "requires at least one filter") {
- return 0, infraerrors.BadRequest("OPS_SYSTEM_LOG_CLEANUP_FILTER_REQUIRED", "cleanup requires at least one filter condition")
- }
- return 0, infraerrors.InternalServer("OPS_SYSTEM_LOG_CLEANUP_FAILED", "Failed to cleanup system logs").WithCause(err)
- }
- if auditErr := s.opsRepo.InsertSystemLogCleanupAudit(ctx, &OpsSystemLogCleanupAudit{
- CreatedAt: time.Now().UTC(),
- OperatorID: operatorID,
- Conditions: marshalSystemLogCleanupConditions(filter),
- DeletedRows: deletedRows,
- }); auditErr != nil {
- // 审计失败不影响主流程,避免运维清理被阻塞。
- log.Printf("[OpsSystemLog] cleanup audit failed: %v", auditErr)
- }
- return deletedRows, nil
- }
- func marshalSystemLogCleanupConditions(filter *OpsSystemLogCleanupFilter) string {
- if filter == nil {
- return "{}"
- }
- payload := map[string]any{
- "host": strings.TrimSpace(filter.Host),
- "level": strings.TrimSpace(filter.Level),
- "component": strings.TrimSpace(filter.Component),
- "request_id": strings.TrimSpace(filter.RequestID),
- "client_request_id": strings.TrimSpace(filter.ClientRequestID),
- "platform": strings.TrimSpace(filter.Platform),
- "model": strings.TrimSpace(filter.Model),
- "query": strings.TrimSpace(filter.Query),
- }
- if filter.UserID != nil {
- payload["user_id"] = *filter.UserID
- }
- if filter.APIKeyID != nil {
- payload["api_key_id"] = *filter.APIKeyID
- }
- if filter.AccountID != nil {
- payload["account_id"] = *filter.AccountID
- }
- if filter.StartTime != nil && !filter.StartTime.IsZero() {
- payload["start_time"] = filter.StartTime.UTC().Format(time.RFC3339Nano)
- }
- if filter.EndTime != nil && !filter.EndTime.IsZero() {
- payload["end_time"] = filter.EndTime.UTC().Format(time.RFC3339Nano)
- }
- raw, err := json.Marshal(payload)
- if err != nil {
- return "{}"
- }
- return string(raw)
- }
- func (s *OpsService) GetSystemLogSinkHealth() OpsSystemLogSinkHealth {
- if s == nil || s.systemLogSink == nil {
- return OpsSystemLogSinkHealth{}
- }
- return s.systemLogSink.Health()
- }
|