Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable create metric descriptors #532

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 6 additions & 1 deletion exporter/metric/metric.go
Expand Up @@ -129,6 +129,10 @@ func (me *metricExporter) Export(ctx context.Context, rm metricdata.ResourceMetr
// exportMetricDescriptor create MetricDescriptor from the record
// if the descriptor is not registered in Cloud Monitoring yet.
func (me *metricExporter) exportMetricDescriptor(ctx context.Context, rm metricdata.ResourceMetrics) error {
if me.o.disableCreateMetricDescriptors {
return nil
}

me.mdLock.Lock()
defer me.mdLock.Unlock()
mds := make(map[key]*googlemetricpb.MetricDescriptor)
Expand Down Expand Up @@ -600,7 +604,8 @@ func numberDataPointToValue[N int64 | float64](
// > allowed.
// > * Label name must start with a letter or digit.
// > * The maximum length of a label name is 100 characters.
// Note: this does not truncate if a label is too long.
//
// Note: this does not truncate if a label is too long.
func normalizeLabelKey(s string) string {
if len(s) == 0 {
return s
Expand Down
78 changes: 78 additions & 0 deletions exporter/metric/metric_test.go
Expand Up @@ -707,6 +707,84 @@ func (m *mock) CreateMetricDescriptor(ctx context.Context, req *monitoringpb.Cre
return m.createMetricDescriptor(ctx, req)
}

func TestExportWithDisableCreateMetricDescriptors(t *testing.T) {
for _, tc := range []struct {
desc string
disableCreateMetricsDescriptor bool
expectExportMetricDescriptor bool
}{
{
desc: "default",
disableCreateMetricsDescriptor: false,
expectExportMetricDescriptor: true,
},
{
desc: "Disable CreateMetricsDescriptor",
disableCreateMetricsDescriptor: true,
expectExportMetricDescriptor: false,
},
} {
t.Run(tc.desc, func(t *testing.T) {
server := grpc.NewServer()

metricDescriptorCreated := false

m := mock{
createTimeSeries: func(ctx context.Context, r *monitoringpb.CreateTimeSeriesRequest) (*emptypb.Empty, error) {
return &emptypb.Empty{}, nil
},
createMetricDescriptor: func(ctx context.Context, req *monitoringpb.CreateMetricDescriptorRequest) (*googlemetricpb.MetricDescriptor, error) {
metricDescriptorCreated = true
return req.MetricDescriptor, nil
},
}

monitoringpb.RegisterMetricServiceServer(server, &m)

lis, err := net.Listen("tcp", "127.0.0.1:0")
require.NoError(t, err)
go server.Serve(lis)

clientOpts := []option.ClientOption{
option.WithEndpoint(lis.Addr().String()),
option.WithoutAuthentication(),
option.WithGRPCDialOption(grpc.WithTransportCredentials(insecure.NewCredentials())),
}
res := &resource.Resource{}
ctx := context.Background()

opts := []Option{
WithProjectID("PROJECT_ID_NOT_REAL"),
WithMonitoringClientOptions(clientOpts...),
WithMetricDescriptorTypeFormatter(formatter),
}

if tc.disableCreateMetricsDescriptor {
opts = append(opts, WithDisableCreateMetricDescriptors())
}

exporter, err := New(opts...)
if err != nil {
t.Errorf("Error occurred when creating exporter: %v", err)
}
provider := metric.NewMeterProvider(
metric.WithReader(metric.NewPeriodicReader(exporter)),
metric.WithResource(res),
)

meter := provider.Meter("test")

counter, err := meter.SyncInt64().Counter("name.lastvalue")
require.NoError(t, err)

counter.Add(ctx, 1)
require.NoError(t, provider.ForceFlush(ctx))
server.Stop()
require.Equal(t, tc.expectExportMetricDescriptor, metricDescriptorCreated)
})
}
}

func TestExportMetricsWithUserAgent(t *testing.T) {
for _, tc := range []struct {
desc string
Expand Down
11 changes: 11 additions & 0 deletions exporter/metric/option.go
Expand Up @@ -60,6 +60,9 @@ type options struct {
// to the underlying Stackdriver Monitoring API client.
// Optional.
monitoringClientOptions []apioption.ClientOption

// disableCreateMetricDescriptors disables automatic MetricDescriptor creation
disableCreateMetricDescriptors bool
}

// WithProjectID sets Google Cloud Platform project as projectID.
Expand Down Expand Up @@ -116,3 +119,11 @@ func DefaultResourceAttributesFilter(kv attribute.KeyValue) bool {
func NoAttributes(attribute.KeyValue) bool {
return false
}

// WithDisableCreateMetricDescriptors will disable the automatic creation of
// MetricDescriptors when an unknown metric is set to be exported.
func WithDisableCreateMetricDescriptors() func(o *options) {
return func(o *options) {
o.disableCreateMetricDescriptors = true
}
}