@@ -18,9 +18,19 @@ import (
18
18
"google.golang.org/protobuf/types/known/timestamppb"
19
19
)
20
20
21
- const MetricTypePrefix = "custom.googleapis.com/comfy_api_frontend"
21
+ const (
22
+ MetricTypePrefix = "custom.googleapis.com/comfy_api_frontend"
23
+ batchInterval = 30 * time .Second // Batch interval for sending metrics
24
+ )
25
+
26
+ var (
27
+ environment = os .Getenv ("DRIP_ENV" )
28
+ metricsCh = make (chan * monitoringpb.TimeSeries , 1000 )
29
+ )
22
30
23
- var environment = os .Getenv ("DRIP_ENV" )
31
+ func init () {
32
+ go processMetricsBatch ()
33
+ }
24
34
25
35
// MetricsMiddleware creates a middleware to capture and send metrics for HTTP requests.
26
36
func MetricsMiddleware (client * monitoring.MetricClient , config * config.Config ) echo.MiddlewareFunc {
@@ -32,7 +42,7 @@ func MetricsMiddleware(client *monitoring.MetricClient, config *config.Config) e
32
42
33
43
// Generate metrics for the request duration, count, and errors.
34
44
if config .DripEnv != "localdev" {
35
- sendMetrics ( c . Request (). Context (), client , config ,
45
+ enqueueMetrics (
36
46
createDurationMetric (c , startTime , endTime ),
37
47
createRequestMetric (c ),
38
48
createErrorMetric (c , err ),
@@ -79,26 +89,60 @@ func (e EndpointMetricKey) toLabels() map[string]string {
79
89
}
80
90
}
81
91
82
- // sendMetrics sends a batch of time series data to Cloud Monitoring.
83
- func sendMetrics (
84
- ctx context.Context ,
85
- client * monitoring.MetricClient ,
86
- config * config.Config ,
87
- series ... * monitoringpb.TimeSeries ,
88
- ) {
89
- req := & monitoringpb.CreateTimeSeriesRequest {
90
- Name : "projects/" + config .ProjectID ,
91
- TimeSeries : make ([]* monitoringpb.TimeSeries , 0 , len (series )),
92
- }
93
-
92
+ func enqueueMetrics (series ... * monitoringpb.TimeSeries ) {
94
93
for _ , s := range series {
95
94
if s != nil {
96
- req .TimeSeries = append (req .TimeSeries , s )
95
+ metricsCh <- s
96
+ }
97
+ }
98
+ }
99
+
100
+ func processMetricsBatch () {
101
+ ticker := time .NewTicker (batchInterval )
102
+ for range ticker .C {
103
+ sendBatchedMetrics ()
104
+ }
105
+ }
106
+
107
+ func sendBatchedMetrics () {
108
+ var series []* monitoringpb.TimeSeries
109
+ for {
110
+ select {
111
+ case s := <- metricsCh :
112
+ series = append (series , s )
113
+ if len (series ) >= 1000 {
114
+ sendMetrics (series )
115
+ series = nil
116
+ }
117
+ default :
118
+ if len (series ) > 0 {
119
+ sendMetrics (series )
120
+ }
121
+ return
97
122
}
98
123
}
124
+ }
125
+
126
+ func sendMetrics (series []* monitoringpb.TimeSeries ) {
127
+ if len (series ) == 0 {
128
+ return
129
+ }
130
+
131
+ ctx := context .Background ()
132
+ client , err := monitoring .NewMetricClient (ctx )
133
+ if err != nil {
134
+ log .Error ().Err (err ).Msg ("Failed to create metric client" )
135
+ return
136
+ }
137
+ defer client .Close ()
138
+
139
+ req := & monitoringpb.CreateTimeSeriesRequest {
140
+ Name : "projects/" + os .Getenv ("PROJECT_ID" ),
141
+ TimeSeries : series ,
142
+ }
99
143
100
144
if err := client .CreateTimeSeries (ctx , req ); err != nil {
101
- log .Ctx ( ctx ). Error ().Err (err ).Msg ("Failed to create time series" )
145
+ log .Error ().Err (err ).Msg ("Failed to create time series" )
102
146
}
103
147
}
104
148
0 commit comments