Skip to content

Commit 9eecabd

Browse files
committed
adding cloud function detector
1 parent 576a237 commit 9eecabd

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

detectors/gcp/cloud-function.go

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// Copyright The OpenTelemetry Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package gcp
16+
17+
import (
18+
"context"
19+
"errors"
20+
"os"
21+
"strings"
22+
23+
"cloud.google.com/go/compute/metadata"
24+
"go.opentelemetry.io/otel/attribute"
25+
"go.opentelemetry.io/otel/sdk/resource"
26+
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
27+
)
28+
29+
var (
30+
errNotOnGoogleCloudFunction = errors.New("cannot detect environment variables from Google Cloud Function")
31+
)
32+
33+
const (
34+
gcpFunctionNameKey = "K_SERVICE"
35+
)
36+
37+
//NewResourceDetector will return an implementation for gcp cloud function resource detector
38+
func NewResourceDetector() resource.Detector {
39+
return &CloudFunction{
40+
client: &gcpClientImpl{},
41+
}
42+
}
43+
44+
type gcpClient interface {
45+
gcpProjectID() (string, error)
46+
gcpRegion() (string, error)
47+
}
48+
type gcpClientImpl struct{}
49+
50+
func (gi *gcpClientImpl) gcpProjectID() (string, error) {
51+
return metadata.ProjectID()
52+
}
53+
54+
func (gi *gcpClientImpl) gcpRegion() (string, error) {
55+
var region string
56+
zone, err := metadata.Zone()
57+
if zone != "" {
58+
splitArr := strings.SplitN(zone, "-", 3)
59+
if len(splitArr) == 3 {
60+
region = strings.Join(splitArr[0:2], "-")
61+
}
62+
}
63+
return region, err
64+
}
65+
66+
type CloudFunction struct {
67+
client gcpClient
68+
}
69+
70+
// Detect detects associated resources when running in cloud function.
71+
func (f *CloudFunction) Detect(ctx context.Context) (*resource.Resource, error) {
72+
functionName, ok := f.googleCloudFunctionName()
73+
if !ok {
74+
return nil, errNotOnGoogleCloudFunction
75+
}
76+
77+
projectID, err := f.client.gcpProjectID()
78+
if err != nil {
79+
return nil, err
80+
}
81+
region, err := f.client.gcpRegion()
82+
if err != nil {
83+
return nil, err
84+
}
85+
86+
attributes := []attribute.KeyValue{
87+
semconv.CloudProviderGCP,
88+
semconv.CloudPlatformGCPCloudFunctions,
89+
attribute.String(string(semconv.FaaSNameKey), functionName),
90+
semconv.CloudAccountIDKey.String(projectID),
91+
semconv.CloudRegionKey.String(region),
92+
}
93+
return resource.NewSchemaless(attributes...), nil
94+
95+
}
96+
97+
func (f *CloudFunction) googleCloudFunctionName() (string, bool) {
98+
return os.LookupEnv(gcpFunctionNameKey)
99+
}

0 commit comments

Comments
 (0)