From b7910afac6ff9867d3f5f0994e58fef34e410227 Mon Sep 17 00:00:00 2001 From: David Ashpole Date: Wed, 1 Jun 2022 16:26:18 -0400 Subject: [PATCH] Unify and improve GCP resource detection, second attempt (#2310) * update GCP resource detection * Apply suggestions from code review Co-authored-by: Tyler Yahn * return partial errors * gotidy * remove host.name from GKE, since GKE doesn't support it Co-authored-by: Tyler Yahn --- detectors/gcp/README.md | 57 ++++++ detectors/gcp/cloud-function.go | 1 + detectors/gcp/cloud-run.go | 2 + detectors/gcp/detector.go | 135 +++++++++++++ detectors/gcp/detector_test.go | 345 ++++++++++++++++++++++++++++++++ detectors/gcp/gce.go | 1 + detectors/gcp/gke.go | 2 + detectors/gcp/go.mod | 5 + detectors/gcp/go.sum | 5 + detectors/gcp/types.go | 39 ++++ 10 files changed, 592 insertions(+) create mode 100644 detectors/gcp/README.md create mode 100644 detectors/gcp/detector.go create mode 100644 detectors/gcp/detector_test.go create mode 100644 detectors/gcp/types.go diff --git a/detectors/gcp/README.md b/detectors/gcp/README.md new file mode 100644 index 00000000000..df8ce1e6235 --- /dev/null +++ b/detectors/gcp/README.md @@ -0,0 +1,57 @@ +# GCP Resource detector + +The GCP resource detector supports detecting resources on: + + * Google Compute Engine (GCE) + * Google Kubernetes Engine (GKE) + * Google App Engine (GAE) + * Cloud Run + * Cloud Functions + +## Usage + +```golang +ctx := context.Background() +// Detect your resources +res, err := resource.New(ctx, + // Use the GCP resource detector! + resource.WithDetectors(gcp.NewDetector()), + // Keep the default detectors + resource.WithTelemetrySDK(), + // Add your own custom attributes to identify your application + resource.WithAttributes( + semconv.ServiceNameKey.String("my-application"), + semconv.ServiceNamespaceKey.String("my-company-frontend-team"), + ), +) +if err != nil { + // Handle err +} +// Use the resource in your tracerprovider (or meterprovider) +tp := trace.NewTracerProvider( + // ... other options + trace.WithResource(res), +) +``` + +## Setting Kubernetes attributes + +Previous iterations of GCP resource detection attempted to detect +`container.name`, `k8s.pod.name` and `k8s.namespace.name`. When using this detector, +you should use this in your Pod Spec to set these using +`OTEL_RESOURCE_ATTRIBUTES`: + +```yaml +env: +- name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name +- name: NAMESPACE_NAME + valueFrom: + fieldRef: + fieldPath: metadata.namespace +- name: CONTAINER_NAME + value: my-container-name +- name: OTEL_RESOURCE_ATTRIBUTES + value: k8s.pod.name=$(POD_NAME),k8s.namespace.name=$(NAMESPACE_NAME),k8s.container.name=$(CONTAINER_NAME) \ No newline at end of file diff --git a/detectors/gcp/cloud-function.go b/detectors/gcp/cloud-function.go index 73752f4cb1f..b99a01c3318 100644 --- a/detectors/gcp/cloud-function.go +++ b/detectors/gcp/cloud-function.go @@ -28,6 +28,7 @@ const ( ) // NewCloudFunction will return a GCP Cloud Function resource detector. +// Deprecated: Use gcp.NewDetector() instead, which sets the same resource attributes. func NewCloudFunction() resource.Detector { return &cloudFunction{ cloudRun: NewCloudRun(), diff --git a/detectors/gcp/cloud-run.go b/detectors/gcp/cloud-run.go index e616c1ae387..dfd7cfdfd36 100644 --- a/detectors/gcp/cloud-run.go +++ b/detectors/gcp/cloud-run.go @@ -38,6 +38,7 @@ type metadataClient interface { } // CloudRun collects resource information of Cloud Run instance. +// Deprecated: Use gcp.NewDetector() instead. Note that it sets faas.* resource attributes instead of service.* attributes. type CloudRun struct { mc metadataClient onGCE func() bool @@ -49,6 +50,7 @@ type CloudRun struct { var _ resource.Detector = (*CloudRun)(nil) // NewCloudRun creates a CloudRun detector. +// Deprecated: Use gcp.NewDetector() instead. Note that it sets faas.* resource attributes instead of service.* attributes. func NewCloudRun() *CloudRun { return &CloudRun{ mc: metadata.NewClient(nil), diff --git a/detectors/gcp/detector.go b/detectors/gcp/detector.go new file mode 100644 index 00000000000..8a26d6d0784 --- /dev/null +++ b/detectors/gcp/detector.go @@ -0,0 +1,135 @@ +// Copyright The OpenTelemetry 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 gcp // import "go.opentelemetry.io/contrib/detectors/gcp" + +import ( + "context" + "fmt" + + "cloud.google.com/go/compute/metadata" + "github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/sdk/resource" + semconv "go.opentelemetry.io/otel/semconv/v1.10.0" +) + +// NewDetector returns a resource detector which detects resource attributes on: +// * Google Compute Engine (GCE). +// * Google Kubernetes Engine (GKE). +// * Google App Engine (GAE). +// * Cloud Run. +// * Cloud Functions. +func NewDetector() resource.Detector { + return &detector{detector: gcp.NewDetector()} +} + +type detector struct { + detector gcpDetector +} + +// Detect detects associated resources when running on GCE, GKE, GAE, +// Cloud Run, and Cloud functions. +func (d *detector) Detect(ctx context.Context) (*resource.Resource, error) { + if !metadata.OnGCE() { + return nil, nil + } + b := &resourceBuilder{} + b.attrs = append(b.attrs, semconv.CloudProviderGCP) + b.add(semconv.CloudAccountIDKey, d.detector.ProjectID) + + switch d.detector.CloudPlatform() { + case gcp.GKE: + b.attrs = append(b.attrs, semconv.CloudPlatformGCPKubernetesEngine) + b.addZoneOrRegion(d.detector.GKEAvailabilityZoneOrRegion) + b.add(semconv.K8SClusterNameKey, d.detector.GKEClusterName) + b.add(semconv.HostIDKey, d.detector.GKEHostID) + case gcp.CloudRun: + b.attrs = append(b.attrs, semconv.CloudPlatformGCPCloudRun) + b.add(semconv.FaaSNameKey, d.detector.FaaSName) + b.add(semconv.FaaSVersionKey, d.detector.FaaSVersion) + b.add(semconv.FaaSIDKey, d.detector.FaaSID) + b.add(semconv.CloudRegionKey, d.detector.FaaSCloudRegion) + case gcp.CloudFunctions: + b.attrs = append(b.attrs, semconv.CloudPlatformGCPCloudFunctions) + b.add(semconv.FaaSNameKey, d.detector.FaaSName) + b.add(semconv.FaaSVersionKey, d.detector.FaaSVersion) + b.add(semconv.FaaSIDKey, d.detector.FaaSID) + b.add(semconv.CloudRegionKey, d.detector.FaaSCloudRegion) + case gcp.AppEngine: + b.attrs = append(b.attrs, semconv.CloudPlatformGCPAppEngine) + b.addZoneAndRegion(d.detector.AppEngineAvailabilityZoneAndRegion) + b.add(semconv.FaaSNameKey, d.detector.AppEngineServiceName) + b.add(semconv.FaaSVersionKey, d.detector.AppEngineServiceVersion) + b.add(semconv.FaaSIDKey, d.detector.AppEngineServiceInstance) + case gcp.GCE: + b.attrs = append(b.attrs, semconv.CloudPlatformGCPComputeEngine) + b.addZoneAndRegion(d.detector.GCEAvailabilityZoneAndRegion) + b.add(semconv.HostTypeKey, d.detector.GCEHostType) + b.add(semconv.HostIDKey, d.detector.GCEHostID) + b.add(semconv.HostNameKey, d.detector.GCEHostName) + default: + // We don't support this platform yet, so just return with what we have + } + return b.build() +} + +// resourceBuilder simplifies constructing resources using GCP detection +// library functions. +type resourceBuilder struct { + errs []error + attrs []attribute.KeyValue +} + +func (r *resourceBuilder) add(key attribute.Key, detect func() (string, error)) { + if v, err := detect(); err == nil { + r.attrs = append(r.attrs, key.String(v)) + } else { + r.errs = append(r.errs, err) + } +} + +// zoneAndRegion functions are expected to return zone, region, err. +func (r *resourceBuilder) addZoneAndRegion(detect func() (string, string, error)) { + if zone, region, err := detect(); err == nil { + r.attrs = append(r.attrs, semconv.CloudAvailabilityZoneKey.String(zone)) + r.attrs = append(r.attrs, semconv.CloudRegionKey.String(region)) + } else { + r.errs = append(r.errs, err) + } +} + +func (r *resourceBuilder) addZoneOrRegion(detect func() (string, gcp.LocationType, error)) { + if v, locType, err := detect(); err == nil { + switch locType { + case gcp.Zone: + r.attrs = append(r.attrs, semconv.CloudAvailabilityZoneKey.String(v)) + case gcp.Region: + r.attrs = append(r.attrs, semconv.CloudRegionKey.String(v)) + default: + r.errs = append(r.errs, fmt.Errorf("location must be zone or region. Got %v", locType)) + } + } else { + r.errs = append(r.errs, err) + } +} + +func (r *resourceBuilder) build() (*resource.Resource, error) { + var err error + if len(r.errs) > 0 { + err = fmt.Errorf("%w: %s", resource.ErrPartialResource, r.errs) + } + return resource.NewWithAttributes(semconv.SchemaURL, r.attrs...), err +} diff --git a/detectors/gcp/detector_test.go b/detectors/gcp/detector_test.go new file mode 100644 index 00000000000..2676e10e502 --- /dev/null +++ b/detectors/gcp/detector_test.go @@ -0,0 +1,345 @@ +// Copyright The OpenTelemetry 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 gcp // import "go.opentelemetry.io/contrib/detectors/gcp" + +import ( + "context" + "fmt" + "os" + "testing" + + "github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp" + "github.com/stretchr/testify/assert" + + "go.opentelemetry.io/otel/sdk/resource" + semconv "go.opentelemetry.io/otel/semconv/v1.10.0" +) + +func TestDetect(t *testing.T) { + // Set this before all tests to ensure metadata.onGCE() returns true + err := os.Setenv("GCE_METADATA_HOST", "169.254.169.254") + assert.NoError(t, err) + + for _, tc := range []struct { + desc string + detector resource.Detector + expectErr bool + expectedResource *resource.Resource + }{ + { + desc: "zonal GKE cluster", + detector: &detector{detector: &fakeGCPDetector{ + projectID: "my-project", + cloudPlatform: gcp.GKE, + gkeHostID: "1472385723456792345", + gkeClusterName: "my-cluster", + gkeAvailabilityZone: "us-central1-c", + }}, + expectedResource: resource.NewWithAttributes(semconv.SchemaURL, + semconv.CloudProviderGCP, + semconv.CloudAccountIDKey.String("my-project"), + semconv.CloudPlatformGCPKubernetesEngine, + semconv.K8SClusterNameKey.String("my-cluster"), + semconv.CloudAvailabilityZoneKey.String("us-central1-c"), + semconv.HostIDKey.String("1472385723456792345"), + ), + }, + { + desc: "regional GKE cluster", + detector: &detector{detector: &fakeGCPDetector{ + projectID: "my-project", + cloudPlatform: gcp.GKE, + gkeHostID: "1472385723456792345", + gkeClusterName: "my-cluster", + gkeRegion: "us-central1", + }}, + expectedResource: resource.NewWithAttributes(semconv.SchemaURL, + semconv.CloudProviderGCP, + semconv.CloudAccountIDKey.String("my-project"), + semconv.CloudPlatformGCPKubernetesEngine, + semconv.K8SClusterNameKey.String("my-cluster"), + semconv.CloudRegionKey.String("us-central1"), + semconv.HostIDKey.String("1472385723456792345"), + ), + }, + { + desc: "GCE", + detector: &detector{detector: &fakeGCPDetector{ + projectID: "my-project", + cloudPlatform: gcp.GCE, + gceHostID: "1472385723456792345", + gceHostName: "my-gke-node-1234", + gceHostType: "n1-standard1", + gceAvailabilityZone: "us-central1-c", + gceRegion: "us-central1", + }}, + expectedResource: resource.NewWithAttributes(semconv.SchemaURL, + semconv.CloudProviderGCP, + semconv.CloudAccountIDKey.String("my-project"), + semconv.CloudPlatformGCPComputeEngine, + semconv.HostIDKey.String("1472385723456792345"), + semconv.HostNameKey.String("my-gke-node-1234"), + semconv.HostTypeKey.String("n1-standard1"), + semconv.CloudRegionKey.String("us-central1"), + semconv.CloudAvailabilityZoneKey.String("us-central1-c"), + ), + }, + { + desc: "Cloud Run", + detector: &detector{detector: &fakeGCPDetector{ + projectID: "my-project", + cloudPlatform: gcp.CloudRun, + faaSID: "1472385723456792345", + faaSCloudRegion: "us-central1", + faaSName: "my-service", + faaSVersion: "123456", + }}, + expectedResource: resource.NewWithAttributes(semconv.SchemaURL, + semconv.CloudProviderGCP, + semconv.CloudAccountIDKey.String("my-project"), + semconv.CloudPlatformGCPCloudRun, + semconv.CloudRegionKey.String("us-central1"), + semconv.FaaSNameKey.String("my-service"), + semconv.FaaSVersionKey.String("123456"), + semconv.FaaSIDKey.String("1472385723456792345"), + ), + }, + { + desc: "Cloud Functions", + detector: &detector{detector: &fakeGCPDetector{ + projectID: "my-project", + cloudPlatform: gcp.CloudFunctions, + faaSID: "1472385723456792345", + faaSCloudRegion: "us-central1", + faaSName: "my-service", + faaSVersion: "123456", + }}, + expectedResource: resource.NewWithAttributes(semconv.SchemaURL, + semconv.CloudProviderGCP, + semconv.CloudAccountIDKey.String("my-project"), + semconv.CloudPlatformGCPCloudFunctions, + semconv.CloudRegionKey.String("us-central1"), + semconv.FaaSNameKey.String("my-service"), + semconv.FaaSVersionKey.String("123456"), + semconv.FaaSIDKey.String("1472385723456792345"), + ), + }, + { + desc: "App Engine", + detector: &detector{detector: &fakeGCPDetector{ + projectID: "my-project", + cloudPlatform: gcp.AppEngine, + appEngineServiceInstance: "1472385723456792345", + appEngineAvailabilityZone: "us-central1-c", + appEngineRegion: "us-central1", + appEngineServiceName: "my-service", + appEngineServiceVersion: "123456", + }}, + expectedResource: resource.NewWithAttributes(semconv.SchemaURL, + semconv.CloudProviderGCP, + semconv.CloudAccountIDKey.String("my-project"), + semconv.CloudPlatformGCPAppEngine, + semconv.CloudRegionKey.String("us-central1"), + semconv.CloudAvailabilityZoneKey.String("us-central1-c"), + semconv.FaaSNameKey.String("my-service"), + semconv.FaaSVersionKey.String("123456"), + semconv.FaaSIDKey.String("1472385723456792345"), + ), + }, + { + desc: "Unknown Platform", + detector: &detector{detector: &fakeGCPDetector{ + projectID: "my-project", + cloudPlatform: gcp.UnknownPlatform, + }}, + expectedResource: resource.NewWithAttributes(semconv.SchemaURL, + semconv.CloudProviderGCP, + semconv.CloudAccountIDKey.String("my-project"), + ), + }, + { + desc: "error", + detector: &detector{detector: &fakeGCPDetector{ + err: fmt.Errorf("failed to get metadata"), + }}, + expectErr: true, + expectedResource: resource.NewWithAttributes(semconv.SchemaURL, + semconv.CloudProviderGCP, + ), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + res, err := tc.detector.Detect(context.TODO()) + if tc.expectErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + assert.Equal(t, tc.expectedResource, res, "Resource object returned is incorrect") + }) + } +} + +// fakeGCPDetector implements gcpDetector and uses fake values. +type fakeGCPDetector struct { + err error + projectID string + cloudPlatform gcp.Platform + gkeAvailabilityZone string + gkeRegion string + gkeClusterName string + gkeHostID string + gkeHostName string + faaSName string + faaSVersion string + faaSID string + faaSCloudRegion string + appEngineAvailabilityZone string + appEngineRegion string + appEngineServiceName string + appEngineServiceVersion string + appEngineServiceInstance string + gceAvailabilityZone string + gceRegion string + gceHostType string + gceHostID string + gceHostName string +} + +func (f *fakeGCPDetector) ProjectID() (string, error) { + if f.err != nil { + return "", f.err + } + return f.projectID, nil +} + +func (f *fakeGCPDetector) CloudPlatform() gcp.Platform { + return f.cloudPlatform +} + +func (f *fakeGCPDetector) GKEAvailabilityZoneOrRegion() (string, gcp.LocationType, error) { + if f.err != nil { + return "", gcp.UndefinedLocation, f.err + } + if f.gkeAvailabilityZone != "" { + return f.gkeAvailabilityZone, gcp.Zone, nil + } + return f.gkeRegion, gcp.Region, nil +} + +func (f *fakeGCPDetector) GKEClusterName() (string, error) { + if f.err != nil { + return "", f.err + } + return f.gkeClusterName, nil +} + +func (f *fakeGCPDetector) GKEHostID() (string, error) { + if f.err != nil { + return "", f.err + } + return f.gkeHostID, nil +} + +func (f *fakeGCPDetector) GKEHostName() (string, error) { + if f.err != nil { + return "", f.err + } + return f.gkeHostName, nil +} + +func (f *fakeGCPDetector) FaaSName() (string, error) { + if f.err != nil { + return "", f.err + } + return f.faaSName, nil +} + +func (f *fakeGCPDetector) FaaSVersion() (string, error) { + if f.err != nil { + return "", f.err + } + return f.faaSVersion, nil +} + +func (f *fakeGCPDetector) FaaSID() (string, error) { + if f.err != nil { + return "", f.err + } + return f.faaSID, nil +} + +func (f *fakeGCPDetector) FaaSCloudRegion() (string, error) { + if f.err != nil { + return "", f.err + } + return f.faaSCloudRegion, nil +} + +func (f *fakeGCPDetector) AppEngineAvailabilityZoneAndRegion() (string, string, error) { + if f.err != nil { + return "", "", f.err + } + return f.appEngineAvailabilityZone, f.appEngineRegion, nil +} + +func (f *fakeGCPDetector) AppEngineServiceName() (string, error) { + if f.err != nil { + return "", f.err + } + return f.appEngineServiceName, nil +} + +func (f *fakeGCPDetector) AppEngineServiceVersion() (string, error) { + if f.err != nil { + return "", f.err + } + return f.appEngineServiceVersion, nil +} + +func (f *fakeGCPDetector) AppEngineServiceInstance() (string, error) { + if f.err != nil { + return "", f.err + } + return f.appEngineServiceInstance, nil +} + +func (f *fakeGCPDetector) GCEAvailabilityZoneAndRegion() (string, string, error) { + if f.err != nil { + return "", "", f.err + } + return f.gceAvailabilityZone, f.gceRegion, nil +} + +func (f *fakeGCPDetector) GCEHostType() (string, error) { + if f.err != nil { + return "", f.err + } + return f.gceHostType, nil +} + +func (f *fakeGCPDetector) GCEHostID() (string, error) { + if f.err != nil { + return "", f.err + } + return f.gceHostID, nil +} + +func (f *fakeGCPDetector) GCEHostName() (string, error) { + if f.err != nil { + return "", f.err + } + return f.gceHostName, nil +} diff --git a/detectors/gcp/gce.go b/detectors/gcp/gce.go index 4a2562949f2..ab3688c0e9e 100644 --- a/detectors/gcp/gce.go +++ b/detectors/gcp/gce.go @@ -28,6 +28,7 @@ import ( ) // GCE collects resource information of GCE computing instances. +// Deprecated: Use gcp.NewDetector() instead, which sets the same resource attributes on GCE. type GCE struct{} // compile time assertion that GCE implements the resource.Detector interface. diff --git a/detectors/gcp/gke.go b/detectors/gcp/gke.go index 321d661487c..23146ab19a6 100644 --- a/detectors/gcp/gke.go +++ b/detectors/gcp/gke.go @@ -27,6 +27,8 @@ import ( ) // GKE collects resource information of GKE computing instances. +// Deprecated: Use gcp.NewDetector() instead, which does NOT detect container, pod, and namespace attributes. +// Set those using name using the OTEL_RESOURCE_ATTRIBUTES env var instead. type GKE struct{} // compile time assertion that GKE implements the resource.Detector interface. diff --git a/detectors/gcp/go.mod b/detectors/gcp/go.mod index 869b23cdc69..561fecd55b9 100644 --- a/detectors/gcp/go.mod +++ b/detectors/gcp/go.mod @@ -4,14 +4,19 @@ go 1.17 require ( cloud.google.com/go/compute v1.6.1 + github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v0.31.0 github.com/google/go-cmp v0.5.8 + github.com/stretchr/testify v1.7.1 go.opentelemetry.io/otel v1.7.0 go.opentelemetry.io/otel/sdk v1.7.0 ) require ( + github.com/davecgh/go-spew v1.1.0 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/otel/trace v1.7.0 // indirect golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect ) diff --git a/detectors/gcp/go.sum b/detectors/gcp/go.sum index 2214f7cf9c1..82f1f1834e6 100644 --- a/detectors/gcp/go.sum +++ b/detectors/gcp/go.sum @@ -54,6 +54,8 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v0.31.0 h1:EnFLvwFv8onlnjYFSrQ4EMSm6uWRBZHOItR/Tz0Jnqk= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v0.31.0/go.mod h1:s7Gpwj0tk7XnVCm4BQEmx/mbS36SuTCY/vMB2SNxe8o= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -173,8 +175,10 @@ github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1: github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -601,6 +605,7 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/detectors/gcp/types.go b/detectors/gcp/types.go new file mode 100644 index 00000000000..1dbe2dad401 --- /dev/null +++ b/detectors/gcp/types.go @@ -0,0 +1,39 @@ +// Copyright The OpenTelemetry 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 gcp // import "go.opentelemetry.io/contrib/detectors/gcp" + +import "github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp" + +// gcpDetector can detect attributes of GCP environments. +type gcpDetector interface { + ProjectID() (string, error) + CloudPlatform() gcp.Platform + GKEAvailabilityZoneOrRegion() (string, gcp.LocationType, error) + GKEClusterName() (string, error) + GKEHostID() (string, error) + GKEHostName() (string, error) + FaaSName() (string, error) + FaaSVersion() (string, error) + FaaSID() (string, error) + FaaSCloudRegion() (string, error) + AppEngineAvailabilityZoneAndRegion() (string, string, error) + AppEngineServiceName() (string, error) + AppEngineServiceVersion() (string, error) + AppEngineServiceInstance() (string, error) + GCEAvailabilityZoneAndRegion() (string, string, error) + GCEHostType() (string, error) + GCEHostID() (string, error) + GCEHostName() (string, error) +}