@@ -134,8 +134,6 @@ func newPreparedResource(ctx context.Context, project string, resourceOptions []
134134}
135135
136136type metricsContext struct {
137- // project used by exporter
138- project string
139137 // client options passed to gRPC channels
140138 clientOpts []option.ClientOption
141139 // instance of metric reader used by gRPC client-side metrics
@@ -154,29 +152,36 @@ func createHistogramView(name string, boundaries []float64) metric.View {
154152 })
155153}
156154
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+ }
180185 }
181186 // Metric views update histogram boundaries to be relevant to GCS
182187 // otherwise default OTel histogram boundaries are used.
@@ -185,11 +190,13 @@ func newGRPCMetricContext(ctx context.Context, project string) (*metricsContext,
185190 createHistogramView ("grpc.client.attempt.rcvd_total_compressed_message_size" , sizeHistogramBoundaries ()),
186191 createHistogramView ("grpc.client.attempt.sent_total_compressed_message_size" , sizeHistogramBoundaries ()),
187192 }
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 ... )
193200 mo := opentelemetry.MetricsOptions {
194201 MeterProvider : provider ,
195202 Metrics : opentelemetry .DefaultMetrics ().Add (
@@ -209,22 +216,21 @@ func newGRPCMetricContext(ctx context.Context, project string) (*metricsContext,
209216 option .WithGRPCDialOption (grpc .WithDefaultCallOptions (grpc.StaticMethodCallOption {})),
210217 }
211218 context := & metricsContext {
212- project : preparedResource .projectToUse ,
213219 clientOpts : opts ,
214220 provider : provider ,
215221 close : createShutdown (ctx , provider ),
216222 }
217223 return context , nil
218224}
219225
220- func enableClientMetrics (ctx context.Context , s * settings ) (* metricsContext , error ) {
226+ func enableClientMetrics (ctx context.Context , s * settings , config storageConfig ) (* metricsContext , error ) {
221227 var project string
222228 c , err := transport .Creds (ctx , s .clientOption ... )
223229 if err == nil {
224230 project = c .ProjectID
225231 }
226232 // Enable client-side metrics for gRPC
227- metricsContext , err := newGRPCMetricContext (ctx , project )
233+ metricsContext , err := newGRPCMetricContext (ctx , project , config )
228234 if err != nil {
229235 return nil , fmt .Errorf ("gRPC Metrics: %w" , err )
230236 }
0 commit comments