@@ -2,15 +2,10 @@ package scheduled_execution
2
2
3
3
import (
4
4
"context"
5
- "slices"
6
5
"time"
7
6
8
7
"github.com/checkmarble/marble-backend/models"
9
- "github.com/checkmarble/marble-backend/repositories"
10
- "github.com/checkmarble/marble-backend/usecases/executor_factory"
11
- "github.com/checkmarble/marble-backend/usecases/metrics_collection"
12
8
"github.com/checkmarble/marble-backend/utils"
13
- "github.com/google/uuid"
14
9
"github.com/riverqueue/river"
15
10
)
16
11
@@ -33,23 +28,21 @@ func NewMetricsCollectionPeriodicJob() *river.PeriodicJob {
33
28
)
34
29
}
35
30
31
+ type MetricsCollectionUsecase interface {
32
+ CollectMetrics (ctx context.Context , from time.Time , to time.Time ) (models.MetricsCollection , error )
33
+ }
34
+
36
35
type MetricCollectionWorker struct {
37
36
river.WorkerDefaults [models.MetricsCollectionArgs ]
38
37
39
- executorFactory executor_factory.ExecutorFactory
40
- organizationRepository repositories.OrganizationRepository
41
- collectors metrics_collection.Collectors
38
+ collectors MetricsCollectionUsecase
42
39
}
43
40
44
41
func NewMetricCollectionWorker (
45
- executorFactory executor_factory.ExecutorFactory ,
46
- organizationRepository repositories.OrganizationRepository ,
47
- collectors metrics_collection.Collectors ,
42
+ collectors MetricsCollectionUsecase ,
48
43
) MetricCollectionWorker {
49
44
return MetricCollectionWorker {
50
- executorFactory : executorFactory ,
51
- organizationRepository : organizationRepository ,
52
- collectors : collectors ,
45
+ collectors : collectors ,
53
46
}
54
47
}
55
48
@@ -66,100 +59,20 @@ func (w MetricCollectionWorker) Work(ctx context.Context, job *river.Job[models.
66
59
from := time .Date (2025 , 1 , 1 , 0 , 0 , 0 , 0 , time .UTC )
67
60
68
61
// Create the metric collection usecase
69
- metrics , err := w .collectMetrics (ctx , from , now )
62
+ metricsCollection , err := w .collectors . CollectMetrics (ctx , from , now )
70
63
if err != nil {
71
64
logger .ErrorContext (ctx , "Failed to collect metrics" , "error" , err )
72
65
return err
73
66
}
74
67
75
- logger .DebugContext (ctx , "Collected metrics" , "metrics" , metrics )
68
+ logger .DebugContext (ctx , "Collected metrics" , "metrics" , metricsCollection )
76
69
77
70
// TODO: Update the watermarks with now value
78
71
logger .DebugContext (ctx , "Updating watermarks" , "new_timestamp" , now )
79
72
80
73
// TODO: Store or send the metrics somewhere
81
74
// For now, just log the number of metrics collected
82
- logger .DebugContext (ctx , "Metric collection completed" , "metrics_count" , len (metrics .Metrics ))
75
+ logger .DebugContext (ctx , "Metric collection completed" , "metrics_count" , len (metricsCollection .Metrics ))
83
76
84
77
return nil
85
78
}
86
-
87
- func (w * MetricCollectionWorker ) collectMetrics (ctx context.Context , from time.Time , to time.Time ) (models.MetricsPayload , error ) {
88
- metrics := make ([]models.MetricData , 0 )
89
-
90
- // Collect global metrics
91
- globalMetrics , err := w .collectGlobalMetrics (ctx , from , to )
92
- if err != nil {
93
- return models.MetricsPayload {}, err
94
- }
95
- metrics = slices .Concat (metrics , globalMetrics )
96
-
97
- // Collect organization-specific metrics
98
- orgMetrics , err := w .collectOrganizationMetrics (ctx , from , to )
99
- if err != nil {
100
- return models.MetricsPayload {}, err
101
- }
102
- metrics = slices .Concat (metrics , orgMetrics )
103
-
104
- payload := models.MetricsPayload {
105
- CollectionID : uuid .New (),
106
- Timestamp : time .Now (),
107
- Metrics : metrics ,
108
- Version : w .collectors .GetVersion (),
109
- }
110
-
111
- return payload , nil
112
- }
113
-
114
- // Collects global metrics from all collectors
115
- // If a collector fails, it will log a warning and continue to the next collector (don't fail the whole function)
116
- func (w * MetricCollectionWorker ) collectGlobalMetrics (ctx context.Context , from time.Time , to time.Time ) ([]models.MetricData , error ) {
117
- metrics := make ([]models.MetricData , 0 )
118
- logger := utils .LoggerFromContext (ctx )
119
-
120
- for _ , collector := range w .collectors .GetGlobalCollectors () {
121
- value , err := collector .Collect (ctx , from , to )
122
- if err != nil {
123
- logger .WarnContext (ctx , "Failed to collect global metrics" , "error" , err )
124
- continue
125
- }
126
- metrics = slices .Concat (metrics , value )
127
- }
128
-
129
- return metrics , nil
130
- }
131
-
132
- // Collects organization metrics from all collectors, fetching all organizations from the database first
133
- // If a collector fails, it will log a warning and continue to the next collector (don't fail the whole function)
134
- func (w * MetricCollectionWorker ) collectOrganizationMetrics (ctx context.Context , from time.Time , to time.Time ) ([]models.MetricData , error ) {
135
- metrics := make ([]models.MetricData , 0 )
136
- logger := utils .LoggerFromContext (ctx )
137
-
138
- orgs , err := w .getListOfOrganizations (ctx )
139
- if err != nil {
140
- return []models.MetricData {}, err
141
- }
142
-
143
- for _ , org := range orgs {
144
- for _ , collector := range w .collectors .GetCollectors () {
145
- value , err := collector .Collect (ctx , org .Id , from , to )
146
- if err != nil {
147
- logger .WarnContext (ctx , "Failed to collect organization metrics" , "error" , err )
148
- continue
149
- }
150
- metrics = slices .Concat (metrics , value )
151
- }
152
- }
153
-
154
- return metrics , nil
155
- }
156
-
157
- // Fetches all organizations from the database
158
- // NOTE: Add caching to avoid fetching the same organizations every time (but how can we invalidate the cache?)
159
- func (w * MetricCollectionWorker ) getListOfOrganizations (ctx context.Context ) ([]models.Organization , error ) {
160
- orgs , err := w .organizationRepository .AllOrganizations (ctx , w .executorFactory .NewExecutor ())
161
- if err != nil {
162
- return []models.Organization {}, err
163
- }
164
- return orgs , nil
165
- }
0 commit comments