diff --git a/gcp/observability/exporting.go b/gcp/observability/exporting.go index cf95383726c3..ac4d6ea7d065 100644 --- a/gcp/observability/exporting.go +++ b/gcp/observability/exporting.go @@ -22,9 +22,9 @@ import ( "context" "encoding/json" "fmt" - "os" gcplogging "cloud.google.com/go/logging" + configpb "google.golang.org/grpc/gcp/observability/internal/config" grpclogrecordpb "google.golang.org/grpc/gcp/observability/internal/logging" "google.golang.org/protobuf/encoding/protojson" ) @@ -45,20 +45,19 @@ type cloudLoggingExporter struct { logger *gcplogging.Logger } -func newCloudLoggingExporter(ctx context.Context, projectID string) (*cloudLoggingExporter, error) { - c, err := gcplogging.NewClient(ctx, fmt.Sprintf("projects/%v", projectID)) +func newCloudLoggingExporter(ctx context.Context, config *configpb.ObservabilityConfig) (*cloudLoggingExporter, error) { + c, err := gcplogging.NewClient(ctx, fmt.Sprintf("projects/%v", config.DestinationProjectId)) if err != nil { return nil, fmt.Errorf("failed to create cloudLoggingExporter: %v", err) } defer logger.Infof("Successfully created cloudLoggingExporter") - customTags := getCustomTags(os.Environ()) - if len(customTags) != 0 { - logger.Infof("Adding custom tags: %+v", customTags) + if len(config.CustomTags) != 0 { + logger.Infof("Adding custom tags: %+v", config.CustomTags) } return &cloudLoggingExporter{ - projectID: projectID, + projectID: config.DestinationProjectId, client: c, - logger: c.Logger("microservices.googleapis.com/observability/grpc", gcplogging.CommonLabels(customTags)), + logger: c.Logger("microservices.googleapis.com/observability/grpc", gcplogging.CommonLabels(config.CustomTags)), }, nil } diff --git a/gcp/observability/internal/config/config.pb.go b/gcp/observability/internal/config/config.pb.go index a60269c984d3..1c52da52457d 100644 --- a/gcp/observability/internal/config/config.pb.go +++ b/gcp/observability/internal/config/config.pb.go @@ -22,14 +22,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.25.0 -// protoc v3.14.0 -// source: gcp/observability/internal/config/config.proto +// protoc-gen-go v1.28.0 +// protoc v3.15.3 +// source: internal/config/config.proto package config import ( - proto "github.com/golang/protobuf/proto" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -43,10 +42,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - // Configuration for observability behaviors. By default, no configuration is // required for tracing/metrics/logging to function. This config captures the // most common knobs for gRPC users. It's always possible to override with @@ -76,12 +71,14 @@ type ObservabilityConfig struct { // For example, 0.05 means there is a 5% chance for a RPC to be traced, 1.0 // means trace every call, 0 means don’t start new traces. GlobalTraceSamplingRate float64 `protobuf:"fixed64,6,opt,name=global_trace_sampling_rate,json=globalTraceSamplingRate,proto3" json:"global_trace_sampling_rate,omitempty"` + // A list of custom tags that will be attached to every log entry. + CustomTags map[string]string `protobuf:"bytes,7,rep,name=custom_tags,json=customTags,proto3" json:"custom_tags,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *ObservabilityConfig) Reset() { *x = ObservabilityConfig{} if protoimpl.UnsafeEnabled { - mi := &file_gcp_observability_internal_config_config_proto_msgTypes[0] + mi := &file_internal_config_config_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -94,7 +91,7 @@ func (x *ObservabilityConfig) String() string { func (*ObservabilityConfig) ProtoMessage() {} func (x *ObservabilityConfig) ProtoReflect() protoreflect.Message { - mi := &file_gcp_observability_internal_config_config_proto_msgTypes[0] + mi := &file_internal_config_config_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -107,7 +104,7 @@ func (x *ObservabilityConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use ObservabilityConfig.ProtoReflect.Descriptor instead. func (*ObservabilityConfig) Descriptor() ([]byte, []int) { - return file_gcp_observability_internal_config_config_proto_rawDescGZIP(), []int{0} + return file_internal_config_config_proto_rawDescGZIP(), []int{0} } func (x *ObservabilityConfig) GetEnableCloudTrace() bool { @@ -152,6 +149,13 @@ func (x *ObservabilityConfig) GetGlobalTraceSamplingRate() float64 { return 0 } +func (x *ObservabilityConfig) GetCustomTags() map[string]string { + if x != nil { + return x.CustomTags + } + return nil +} + type ObservabilityConfig_LogFilter struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -186,7 +190,7 @@ type ObservabilityConfig_LogFilter struct { func (x *ObservabilityConfig_LogFilter) Reset() { *x = ObservabilityConfig_LogFilter{} if protoimpl.UnsafeEnabled { - mi := &file_gcp_observability_internal_config_config_proto_msgTypes[1] + mi := &file_internal_config_config_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -199,7 +203,7 @@ func (x *ObservabilityConfig_LogFilter) String() string { func (*ObservabilityConfig_LogFilter) ProtoMessage() {} func (x *ObservabilityConfig_LogFilter) ProtoReflect() protoreflect.Message { - mi := &file_gcp_observability_internal_config_config_proto_msgTypes[1] + mi := &file_internal_config_config_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -212,7 +216,7 @@ func (x *ObservabilityConfig_LogFilter) ProtoReflect() protoreflect.Message { // Deprecated: Use ObservabilityConfig_LogFilter.ProtoReflect.Descriptor instead. func (*ObservabilityConfig_LogFilter) Descriptor() ([]byte, []int) { - return file_gcp_observability_internal_config_config_proto_rawDescGZIP(), []int{0, 0} + return file_internal_config_config_proto_rawDescGZIP(), []int{0, 0} } func (x *ObservabilityConfig_LogFilter) GetPattern() string { @@ -236,89 +240,100 @@ func (x *ObservabilityConfig_LogFilter) GetMessageBytes() int32 { return 0 } -var File_gcp_observability_internal_config_config_proto protoreflect.FileDescriptor - -var file_gcp_observability_internal_config_config_proto_rawDesc = []byte{ - 0x0a, 0x2e, 0x67, 0x63, 0x70, 0x2f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x62, 0x69, 0x6c, - 0x69, 0x74, 0x79, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x12, 0x21, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x62, 0x69, - 0x6c, 0x69, 0x74, 0x79, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x22, 0xf2, 0x03, 0x0a, 0x13, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x62, - 0x69, 0x6c, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2c, 0x0a, 0x12, 0x65, - 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x74, 0x72, 0x61, 0x63, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, - 0x6c, 0x6f, 0x75, 0x64, 0x54, 0x72, 0x61, 0x63, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x65, 0x6e, 0x61, - 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, - 0x72, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x65, 0x6e, 0x61, 0x62, - 0x6c, 0x65, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, - 0x67, 0x12, 0x30, 0x0a, 0x14, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6c, 0x6f, 0x75, - 0x64, 0x5f, 0x6c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x12, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x4c, 0x6f, 0x67, 0x67, - 0x69, 0x6e, 0x67, 0x12, 0x34, 0x0a, 0x16, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x14, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x61, 0x0a, 0x0b, 0x6c, 0x6f, 0x67, - 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, - 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x62, 0x69, 0x6c, - 0x69, 0x74, 0x79, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x2e, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x4c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x52, 0x0a, 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x3b, 0x0a, 0x1a, - 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x73, 0x61, 0x6d, - 0x70, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x01, - 0x52, 0x17, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x53, 0x61, 0x6d, - 0x70, 0x6c, 0x69, 0x6e, 0x67, 0x52, 0x61, 0x74, 0x65, 0x1a, 0x6d, 0x0a, 0x09, 0x4c, 0x6f, 0x67, - 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, - 0x12, 0x21, 0x0a, 0x0c, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x42, 0x79, - 0x74, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x62, - 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x42, 0x74, 0x0a, 0x1c, 0x69, 0x6f, 0x2e, 0x67, +var File_internal_config_config_proto protoreflect.FileDescriptor + +var file_internal_config_config_proto_rawDesc = []byte{ + 0x0a, 0x1c, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x21, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x62, 0x69, 0x6c, 0x69, + 0x74, 0x79, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x22, 0x9a, 0x05, 0x0a, 0x13, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x62, 0x69, 0x6c, + 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2c, 0x0a, 0x12, 0x65, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6c, 0x6f, + 0x75, 0x64, 0x54, 0x72, 0x61, 0x63, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x5f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, + 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x12, + 0x30, 0x0a, 0x14, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, + 0x6c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, + 0x67, 0x12, 0x34, 0x0a, 0x16, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x14, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x61, 0x0a, 0x0b, 0x6c, 0x6f, 0x67, 0x5f, 0x66, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x67, + 0x72, 0x70, 0x63, 0x2e, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x79, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x4c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0a, + 0x6c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x3b, 0x0a, 0x1a, 0x67, 0x6c, + 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, + 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x01, 0x52, 0x17, + 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, + 0x69, 0x6e, 0x67, 0x52, 0x61, 0x74, 0x65, 0x12, 0x67, 0x0a, 0x0b, 0x63, 0x75, 0x73, 0x74, 0x6f, + 0x6d, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x46, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, - 0x79, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x18, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, - 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x38, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, - 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x67, 0x63, 0x70, - 0x2f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x2f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x79, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x2e, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x54, 0x61, 0x67, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x54, 0x61, 0x67, 0x73, + 0x1a, 0x6d, 0x0a, 0x09, 0x4c, 0x6f, 0x67, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x18, 0x0a, + 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x68, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x1a, + 0x3d, 0x0a, 0x0f, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x74, + 0x0a, 0x1c, 0x69, 0x6f, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, + 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x18, + 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x38, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x72, + 0x70, 0x63, 0x2f, 0x67, 0x63, 0x70, 0x2f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x62, 0x69, + 0x6c, 0x69, 0x74, 0x79, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( - file_gcp_observability_internal_config_config_proto_rawDescOnce sync.Once - file_gcp_observability_internal_config_config_proto_rawDescData = file_gcp_observability_internal_config_config_proto_rawDesc + file_internal_config_config_proto_rawDescOnce sync.Once + file_internal_config_config_proto_rawDescData = file_internal_config_config_proto_rawDesc ) -func file_gcp_observability_internal_config_config_proto_rawDescGZIP() []byte { - file_gcp_observability_internal_config_config_proto_rawDescOnce.Do(func() { - file_gcp_observability_internal_config_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_gcp_observability_internal_config_config_proto_rawDescData) +func file_internal_config_config_proto_rawDescGZIP() []byte { + file_internal_config_config_proto_rawDescOnce.Do(func() { + file_internal_config_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_config_config_proto_rawDescData) }) - return file_gcp_observability_internal_config_config_proto_rawDescData + return file_internal_config_config_proto_rawDescData } -var file_gcp_observability_internal_config_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_gcp_observability_internal_config_config_proto_goTypes = []interface{}{ +var file_internal_config_config_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_internal_config_config_proto_goTypes = []interface{}{ (*ObservabilityConfig)(nil), // 0: grpc.observability.config.v1alpha.ObservabilityConfig (*ObservabilityConfig_LogFilter)(nil), // 1: grpc.observability.config.v1alpha.ObservabilityConfig.LogFilter + nil, // 2: grpc.observability.config.v1alpha.ObservabilityConfig.CustomTagsEntry } -var file_gcp_observability_internal_config_config_proto_depIdxs = []int32{ +var file_internal_config_config_proto_depIdxs = []int32{ 1, // 0: grpc.observability.config.v1alpha.ObservabilityConfig.log_filters:type_name -> grpc.observability.config.v1alpha.ObservabilityConfig.LogFilter - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name + 2, // 1: grpc.observability.config.v1alpha.ObservabilityConfig.custom_tags:type_name -> grpc.observability.config.v1alpha.ObservabilityConfig.CustomTagsEntry + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name } -func init() { file_gcp_observability_internal_config_config_proto_init() } -func file_gcp_observability_internal_config_config_proto_init() { - if File_gcp_observability_internal_config_config_proto != nil { +func init() { file_internal_config_config_proto_init() } +func file_internal_config_config_proto_init() { + if File_internal_config_config_proto != nil { return } if !protoimpl.UnsafeEnabled { - file_gcp_observability_internal_config_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_internal_config_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ObservabilityConfig); i { case 0: return &v.state @@ -330,7 +345,7 @@ func file_gcp_observability_internal_config_config_proto_init() { return nil } } - file_gcp_observability_internal_config_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_internal_config_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ObservabilityConfig_LogFilter); i { case 0: return &v.state @@ -347,18 +362,18 @@ func file_gcp_observability_internal_config_config_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_gcp_observability_internal_config_config_proto_rawDesc, + RawDescriptor: file_internal_config_config_proto_rawDesc, NumEnums: 0, - NumMessages: 2, + NumMessages: 3, NumExtensions: 0, NumServices: 0, }, - GoTypes: file_gcp_observability_internal_config_config_proto_goTypes, - DependencyIndexes: file_gcp_observability_internal_config_config_proto_depIdxs, - MessageInfos: file_gcp_observability_internal_config_config_proto_msgTypes, + GoTypes: file_internal_config_config_proto_goTypes, + DependencyIndexes: file_internal_config_config_proto_depIdxs, + MessageInfos: file_internal_config_config_proto_msgTypes, }.Build() - File_gcp_observability_internal_config_config_proto = out.File - file_gcp_observability_internal_config_config_proto_rawDesc = nil - file_gcp_observability_internal_config_config_proto_goTypes = nil - file_gcp_observability_internal_config_config_proto_depIdxs = nil + File_internal_config_config_proto = out.File + file_internal_config_config_proto_rawDesc = nil + file_internal_config_config_proto_goTypes = nil + file_internal_config_config_proto_depIdxs = nil } diff --git a/gcp/observability/internal/config/config.proto b/gcp/observability/internal/config/config.proto index 2c108bfa2abf..685bf2d84eaf 100644 --- a/gcp/observability/internal/config/config.proto +++ b/gcp/observability/internal/config/config.proto @@ -86,4 +86,7 @@ message ObservabilityConfig { // For example, 0.05 means there is a 5% chance for a RPC to be traced, 1.0 // means trace every call, 0 means don’t start new traces. double global_trace_sampling_rate = 6; + + // A list of custom tags that will be attached to every log entry. + map custom_tags = 7; } diff --git a/gcp/observability/logging.go b/gcp/observability/logging.go index ed7e76d74c04..711dc74f8672 100644 --- a/gcp/observability/logging.go +++ b/gcp/observability/logging.go @@ -325,7 +325,7 @@ func (l *binaryLogger) Start(ctx context.Context, config *configpb.Observability if config.GetDestinationProjectId() == "" { return fmt.Errorf("failed to enable CloudLogging: empty destination_project_id") } - exporter, err := newCloudLoggingExporter(ctx, config.DestinationProjectId) + exporter, err := newCloudLoggingExporter(ctx, config) if err != nil { return fmt.Errorf("unable to create CloudLogging exporter: %v", err) } diff --git a/gcp/observability/observability_test.go b/gcp/observability/observability_test.go index 18e3fd0f88fc..962f56f1d120 100644 --- a/gcp/observability/observability_test.go +++ b/gcp/observability/observability_test.go @@ -36,6 +36,7 @@ import ( "google.golang.org/grpc/credentials/insecure" configpb "google.golang.org/grpc/gcp/observability/internal/config" grpclogrecordpb "google.golang.org/grpc/gcp/observability/internal/logging" + "google.golang.org/grpc/internal" iblog "google.golang.org/grpc/internal/binarylog" "google.golang.org/grpc/internal/grpctest" "google.golang.org/grpc/internal/leakcheck" @@ -687,7 +688,7 @@ func (s) TestRefuseStartWithInvalidPatterns(t *testing.T) { // place in the temporary portion of the file system dependent on system. It // also sets the environment variable GRPC_CONFIG_OBSERVABILITY_JSON to point to // this created config. -func createTmpConfigInFileSystem(rawJSON string) (*os.File, error) { +func createTmpConfigInFileSystem(rawJSON string) (func(), error) { configJSONFile, err := ioutil.TempFile(os.TempDir(), "configJSON-") if err != nil { return nil, fmt.Errorf("cannot create file %v: %v", configJSONFile.Name(), err) @@ -697,7 +698,10 @@ func createTmpConfigInFileSystem(rawJSON string) (*os.File, error) { return nil, fmt.Errorf("cannot write marshalled JSON: %v", err) } os.Setenv(envObservabilityConfigJSON, configJSONFile.Name()) - return configJSONFile, nil + return func() { + configJSONFile.Close() + os.Setenv(envObservabilityConfigJSON, "") + }, nil } // TestJSONEnvVarSet tests a valid observability configuration specified by the @@ -708,8 +712,9 @@ func (s) TestJSONEnvVarSet(t *testing.T) { "destinationProjectId": "fake", "logFilters":[{"pattern":"*","headerBytes":1073741824,"messageBytes":1073741824}] }` - configJSONFile, err := createTmpConfigInFileSystem(configJSON) - defer configJSONFile.Close() + cleanup, err := createTmpConfigInFileSystem(configJSON) + defer cleanup() + if err != nil { t.Fatalf("failed to create config in file system: %v", err) } @@ -731,8 +736,8 @@ func (s) TestBothConfigEnvVarsSet(t *testing.T) { "destinationProjectId":"fake", "logFilters":[{"pattern":":-)"}, {"pattern":"*"}] }` - configJSONFile, err := createTmpConfigInFileSystem(configJSON) - defer configJSONFile.Close() + cleanup, err := createTmpConfigInFileSystem(configJSON) + defer cleanup() if err != nil { t.Fatalf("failed to create config in file system: %v", err) } @@ -764,6 +769,7 @@ func (s) TestBothConfigEnvVarsSet(t *testing.T) { // a file (or valid configuration). func (s) TestErrInFileSystemEnvVar(t *testing.T) { os.Setenv(envObservabilityConfigJSON, "/this-file/does-not-exist") + defer os.Setenv(envObservabilityConfigJSON, "") if err := Start(context.Background()); err == nil { t.Fatalf("Invalid file system path not triggering error") } @@ -835,3 +841,52 @@ func (s) TestOpenCensusIntegration(t *testing.T) { t.Fatalf("Invalid OpenCensus export data: %v", errs) } } + +// TestCustomTagsTracingMetrics verifies that the custom tags defined in our +// observability configuration and set to two hardcoded values are passed to the +// function to create an exporter. +func (s) TestCustomTagsTracingMetrics(t *testing.T) { + defer func(ne func(config *configpb.ObservabilityConfig) (tracingMetricsExporter, error)) { + newExporter = ne + }(newExporter) + fe := &fakeOpenCensusExporter{SeenViews: make(map[string]string), t: t} + newExporter = func(config *configpb.ObservabilityConfig) (tracingMetricsExporter, error) { + ct := config.GetCustomTags() + if len(ct) < 1 { + t.Fatalf("less than 2 custom tags sent in") + } + if val, ok := ct["customtag1"]; !ok || val != "wow" { + t.Fatalf("incorrect custom tag: got %v, want %v", val, "wow") + } + if val, ok := ct["customtag2"]; !ok || val != "nice" { + t.Fatalf("incorrect custom tag: got %v, want %v", val, "nice") + } + return fe, nil + } + + // This configuration present in file system and it's defined custom tags should make it + // to the created exporter. + configJSON := `{ + "destinationProjectId": "fake", + "enableCloudTrace": true, + "enableCloudMonitoring": true, + "globalTraceSamplingRate": 1.0, + "customTags":{"customtag1":"wow","customtag2":"nice"} + }` + cleanup, err := createTmpConfigInFileSystem(configJSON) + defer cleanup() + + // To clear globally registered tracing and metrics exporters. + defer func() { + internal.ClearExtraDialOptions() + internal.ClearExtraServerOptions() + }() + + ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) + defer cancel() + err = Start(ctx) + defer End() + if err != nil { + t.Fatalf("Start() failed with err: %v", err) + } +} diff --git a/gcp/observability/opencensus.go b/gcp/observability/opencensus.go index 410b90a1bc64..df0eba95dfd9 100644 --- a/gcp/observability/opencensus.go +++ b/gcp/observability/opencensus.go @@ -38,12 +38,28 @@ var ( defaultMetricsReportingInterval = time.Second * 30 ) +func convertTagsToMonitoringLabels(tags map[string]string) *stackdriver.Labels { + labels := &stackdriver.Labels{} + for k, v := range tags { + labels.Set(k, v, "") + } + return labels +} + +func convertTagsToTraceAttributes(tags map[string]string) map[string]interface{} { + ta := make(map[string]interface{}, len(tags)) + for k, v := range tags { + ta[k] = v + } + return ta +} + type tracingMetricsExporter interface { trace.Exporter view.Exporter } -// globals to stub out in tests +// global to stub out in tests var newExporter = newStackdriverExporter func newStackdriverExporter(config *configpb.ObservabilityConfig) (tracingMetricsExporter, error) { @@ -52,8 +68,10 @@ func newStackdriverExporter(config *configpb.ObservabilityConfig) (tracingMetric logger.Infof("Detected MonitoredResource:: %+v", mr) var err error exporter, err := stackdriver.NewExporter(stackdriver.Options{ - ProjectID: config.DestinationProjectId, - MonitoredResource: mr, + ProjectID: config.DestinationProjectId, + MonitoredResource: mr, + DefaultMonitoringLabels: convertTagsToMonitoringLabels(config.CustomTags), + DefaultTraceAttributes: convertTagsToTraceAttributes(config.CustomTags), }) if err != nil { return nil, fmt.Errorf("failed to create Stackdriver exporter: %v", err) diff --git a/gcp/observability/tags.go b/gcp/observability/tags.go deleted file mode 100644 index c9a900970ea9..000000000000 --- a/gcp/observability/tags.go +++ /dev/null @@ -1,46 +0,0 @@ -/* - * - * Copyright 2022 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package observability - -import ( - "strings" -) - -const ( - envPrefixCustomTags = "GRPC_OBSERVABILITY_" - envPrefixLen = len(envPrefixCustomTags) -) - -func getCustomTags(envs []string) map[string]string { - m := make(map[string]string) - for _, e := range envs { - if !strings.HasPrefix(e, envPrefixCustomTags) { - continue - } - tokens := strings.SplitN(e, "=", 2) - if len(tokens) == 2 { - if len(tokens[0]) == envPrefixLen { - // Empty key is not allowed - continue - } - m[tokens[0][envPrefixLen:]] = tokens[1] - } - } - return m -} diff --git a/gcp/observability/tags_test.go b/gcp/observability/tags_test.go deleted file mode 100644 index 5a0353a03087..000000000000 --- a/gcp/observability/tags_test.go +++ /dev/null @@ -1,64 +0,0 @@ -/* - * - * Copyright 2022 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package observability - -import ( - "reflect" - "testing" -) - -// TestGetCustomTags tests the normal tags parsing -func (s) TestGetCustomTags(t *testing.T) { - var ( - input = []string{ - "GRPC_OBSERVABILITY_APP_NAME=app1", - "GRPC_OBSERVABILITY_DATACENTER=us-west1-a", - "GRPC_OBSERVABILITY_smallcase=OK", - } - expect = map[string]string{ - "APP_NAME": "app1", - "DATACENTER": "us-west1-a", - "smallcase": "OK", - } - ) - result := getCustomTags(input) - if !reflect.DeepEqual(result, expect) { - t.Errorf("result [%+v] != expect [%+v]", result, expect) - } -} - -// TestGetCustomTagsInvalid tests the invalid cases of tags parsing -func (s) TestGetCustomTagsInvalid(t *testing.T) { - var ( - input = []string{ - "GRPC_OBSERVABILITY_APP_NAME=app1", - "GRPC_OBSERVABILITY=foo", - "GRPC_OBSERVABILITY_=foo", // Users should not set "" as key name - "GRPC_STUFF=foo", - "STUFF_GRPC_OBSERVABILITY_=foo", - } - expect = map[string]string{ - "APP_NAME": "app1", - } - ) - result := getCustomTags(input) - if !reflect.DeepEqual(result, expect) { - t.Errorf("result [%+v] != expect [%+v]", result, expect) - } -}