@@ -134,8 +134,6 @@ func newPreparedResource(ctx context.Context, project string, resourceOptions []
134
134
}
135
135
136
136
type metricsContext struct {
137
- // project used by exporter
138
- project string
139
137
// client options passed to gRPC channels
140
138
clientOpts []option.ClientOption
141
139
// instance of metric reader used by gRPC client-side metrics
@@ -154,29 +152,36 @@ func createHistogramView(name string, boundaries []float64) metric.View {
154
152
})
155
153
}
156
154
157
- func newGRPCMetricContext (ctx context.Context , project string ) (* metricsContext , error ) {
158
- preparedResource , err := newPreparedResource (ctx , project , []resource.Option {resource .WithDetectors (gcp .NewDetector ())})
159
- if err != nil {
160
- return nil , err
161
- }
162
- // Implementation requires a project, if one is not determined possibly user
163
- // credentials. Then we will fail stating gRPC Metrics require a project-id.
164
- if project == "" && preparedResource .projectToUse != "" {
165
- return nil , fmt .Errorf ("google cloud project is required to start client-side metrics" )
166
- }
167
- // If projectTouse isn't the same as project provided to Storage client, then
168
- // emit a log stating which project is being used to emit metrics to.
169
- if project != preparedResource .projectToUse {
170
- log .Printf ("The Project ID configured for metrics is %s, but the Project ID of the storage client is %s. Make sure that the service account in use has the required metric writing role (roles/monitoring.metricWriter) in the project projectIdToUse or metrics will not be written." , preparedResource .projectToUse , project )
171
- }
172
- meOpts := []mexporter.Option {
173
- mexporter .WithProjectID (preparedResource .projectToUse ),
174
- mexporter .WithMetricDescriptorTypeFormatter (metricFormatter ),
175
- mexporter .WithCreateServiceTimeSeries (),
176
- mexporter .WithMonitoredResourceDescription (monitoredResourceName , []string {"project_id" , "location" , "cloud_platform" , "host_id" , "instance_id" , "api" })}
177
- exporter , err := mexporter .New (meOpts ... )
178
- if err != nil {
179
- return nil , err
155
+ func newGRPCMetricContext (ctx context.Context , project string , config storageConfig ) (* metricsContext , error ) {
156
+ var exporter metric.Exporter
157
+ meterOpts := []metric.Option {}
158
+ if config .metricExporter != nil {
159
+ exporter = * config .metricExporter
160
+ } else {
161
+ preparedResource , err := newPreparedResource (ctx , project , []resource.Option {resource .WithDetectors (gcp .NewDetector ())})
162
+ if err != nil {
163
+ return nil , err
164
+ }
165
+ meterOpts = append (meterOpts , metric .WithResource (preparedResource .resource ))
166
+ // Implementation requires a project, if one is not determined possibly user
167
+ // credentials. Then we will fail stating gRPC Metrics require a project-id.
168
+ if project == "" && preparedResource .projectToUse == "" {
169
+ return nil , fmt .Errorf ("google cloud project is required to start client-side metrics" )
170
+ }
171
+ // If projectTouse isn't the same as project provided to Storage client, then
172
+ // emit a log stating which project is being used to emit metrics to.
173
+ if project != preparedResource .projectToUse {
174
+ log .Printf ("The Project ID configured for metrics is %s, but the Project ID of the storage client is %s. Make sure that the service account in use has the required metric writing role (roles/monitoring.metricWriter) in the project projectIdToUse or metrics will not be written." , preparedResource .projectToUse , project )
175
+ }
176
+ meOpts := []mexporter.Option {
177
+ mexporter .WithProjectID (preparedResource .projectToUse ),
178
+ mexporter .WithMetricDescriptorTypeFormatter (metricFormatter ),
179
+ mexporter .WithCreateServiceTimeSeries (),
180
+ mexporter .WithMonitoredResourceDescription (monitoredResourceName , []string {"project_id" , "location" , "cloud_platform" , "host_id" , "instance_id" , "api" })}
181
+ exporter , err = mexporter .New (meOpts ... )
182
+ if err != nil {
183
+ return nil , err
184
+ }
180
185
}
181
186
// Metric views update histogram boundaries to be relevant to GCS
182
187
// otherwise default OTel histogram boundaries are used.
@@ -185,11 +190,13 @@ func newGRPCMetricContext(ctx context.Context, project string) (*metricsContext,
185
190
createHistogramView ("grpc.client.attempt.rcvd_total_compressed_message_size" , sizeHistogramBoundaries ()),
186
191
createHistogramView ("grpc.client.attempt.sent_total_compressed_message_size" , sizeHistogramBoundaries ()),
187
192
}
188
- provider := metric .NewMeterProvider (
189
- metric .WithReader (metric .NewPeriodicReader (& exporterLogSuppressor {exporter : exporter }, metric .WithInterval (time .Minute ))),
190
- metric .WithResource (preparedResource .resource ),
191
- metric .WithView (metricViews ... ),
192
- )
193
+ interval := time .Minute
194
+ if config .metricInterval > 0 {
195
+ interval = config .metricInterval
196
+ }
197
+ meterOpts = append (meterOpts , metric .WithReader (metric .NewPeriodicReader (& exporterLogSuppressor {exporter : exporter }, metric .WithInterval (interval ))),
198
+ metric .WithView (metricViews ... ))
199
+ provider := metric .NewMeterProvider (meterOpts ... )
193
200
mo := opentelemetry.MetricsOptions {
194
201
MeterProvider : provider ,
195
202
Metrics : opentelemetry .DefaultMetrics ().Add (
@@ -209,22 +216,21 @@ func newGRPCMetricContext(ctx context.Context, project string) (*metricsContext,
209
216
option .WithGRPCDialOption (grpc .WithDefaultCallOptions (grpc.StaticMethodCallOption {})),
210
217
}
211
218
context := & metricsContext {
212
- project : preparedResource .projectToUse ,
213
219
clientOpts : opts ,
214
220
provider : provider ,
215
221
close : createShutdown (ctx , provider ),
216
222
}
217
223
return context , nil
218
224
}
219
225
220
- func enableClientMetrics (ctx context.Context , s * settings ) (* metricsContext , error ) {
226
+ func enableClientMetrics (ctx context.Context , s * settings , config storageConfig ) (* metricsContext , error ) {
221
227
var project string
222
228
c , err := transport .Creds (ctx , s .clientOption ... )
223
229
if err == nil {
224
230
project = c .ProjectID
225
231
}
226
232
// Enable client-side metrics for gRPC
227
- metricsContext , err := newGRPCMetricContext (ctx , project )
233
+ metricsContext , err := newGRPCMetricContext (ctx , project , config )
228
234
if err != nil {
229
235
return nil , fmt .Errorf ("gRPC Metrics: %w" , err )
230
236
}
0 commit comments