From 78c5beed3ec2de0f34b89cb1f4a8715ee652203c Mon Sep 17 00:00:00 2001 From: Sam Xie Date: Fri, 26 Nov 2021 11:21:59 +0800 Subject: [PATCH 01/10] Add container id support to Resource --- sdk/resource/config.go | 5 ++ sdk/resource/container.go | 130 +++++++++++++++++++++++++++++++++ sdk/resource/container_test.go | 114 +++++++++++++++++++++++++++++ sdk/resource/export_test.go | 2 + sdk/resource/process_test.go | 1 + sdk/resource/resource_test.go | 54 ++++++++++++++ 6 files changed, 306 insertions(+) create mode 100644 sdk/resource/container.go create mode 100644 sdk/resource/container_test.go diff --git a/sdk/resource/config.go b/sdk/resource/config.go index 5fa45859b53..1e220b6d374 100644 --- a/sdk/resource/config.go +++ b/sdk/resource/config.go @@ -169,3 +169,8 @@ func WithProcessRuntimeVersion() Option { func WithProcessRuntimeDescription() Option { return WithDetectors(processRuntimeDescriptionDetector{}) } + +// WithContainerID adds an attribute with the id of the container to the configured Resource. +func WithContainerID() Option { + return WithDetectors(containerIDDetector{}) +} diff --git a/sdk/resource/container.go b/sdk/resource/container.go new file mode 100644 index 00000000000..7045b1c81a7 --- /dev/null +++ b/sdk/resource/container.go @@ -0,0 +1,130 @@ +// 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 resource // import "go.opentelemetry.io/otel/sdk/resource" + +import ( + "bufio" + "context" + "errors" + "io" + "os" + "strings" + + semconv "go.opentelemetry.io/otel/semconv/v1.7.0" +) + +type containerIDProvider func() (string, error) + +var ( + defaultContainerIDProvider containerIDProvider = getContainerIDFromCGroup +) + +type containerIDDetector struct{} + +const cgroupPath = "/proc/self/cgroup" + +// Detect returns a *Resource that describes the id of the container. +// If no container id found, an empty resource will be returned. +func (containerIDDetector) Detect(ctx context.Context) (*Resource, error) { + containerID, err := defaultContainerIDProvider() + if err != nil { + return nil, err + } + + if containerID == "" { + return Empty(), nil + } + return NewWithAttributes(semconv.SchemaURL, semconv.ContainerIDKey.String(containerID)), nil +} + +// getContainerIDFromCGroup returns the id of the container from the cgroup file. +// If no container id found, an empty string will be returned. +func getContainerIDFromCGroup() (string, error) { + if _, err := os.Stat(cgroupPath); errors.Is(err, os.ErrNotExist) { + // File does not exists, skip + return "", nil + } + + file, err := os.Open(cgroupPath) + if err != nil { + return "", err + } + defer file.Close() + + containerID := getContainerIDFromReader(file) + if containerID == "" { + // Container ID not found + return "", nil + } + return containerID, nil +} + +// getContainerIDFromReader returns the id of the container from reader. +func getContainerIDFromReader(reader io.Reader) string { + scanner := bufio.NewScanner(reader) + for scanner.Scan() { + line := scanner.Text() + + if id := getContainerIDFromLine(line); id != "" { + return id + } + } + return "" +} + +// getContainerIDFromLine returns the id of the container from one string line. +func getContainerIDFromLine(line string) string { + line = strings.TrimSpace(line) + + lastSlashIndexOfLine := strings.LastIndexByte(line, '/') + if lastSlashIndexOfLine == -1 { + return "" + } + + lastSection := line[lastSlashIndexOfLine+1:] + dashIndex := strings.IndexByte(lastSection, '-') + lastDotIndex := strings.LastIndexByte(lastSection, '.') + + startIndex := 0 + if dashIndex != -1 { + startIndex = dashIndex + 1 + } + + endIndex := len(lastSection) + if lastDotIndex != -1 { + endIndex = lastDotIndex + } + + containerID := lastSection[startIndex:endIndex] + if !isHex(containerID) { + return "" + } + return containerID +} + +// isHex returns true when input is a hex string. +func isHex(h string) bool { + for _, r := range h { + switch { + case 'a' <= r && r <= 'f': + continue + case '0' <= r && r <= '9': + continue + default: + return false + } + } + return true +} diff --git a/sdk/resource/container_test.go b/sdk/resource/container_test.go new file mode 100644 index 00000000000..d35982d587a --- /dev/null +++ b/sdk/resource/container_test.go @@ -0,0 +1,114 @@ +// 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 resource + +import ( + "io" + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +func setDefaultContainerProviders() { + setContainerProviders( + getContainerIDFromCGroup, + ) +} + +func setContainerProviders( + idProvider containerIDProvider, +) { + defaultContainerIDProvider = idProvider +} + +func TestGetContainerIDFromLine(t *testing.T) { + testCases := []struct { + name string + line string + expectedContainerID string + }{ + { + name: "with suffix", + line: "13:name=systemd:/podruntime/docker/kubepods/ac679f8a8319c8cf7d38e1adf263bc08d23.aaaa", + expectedContainerID: "ac679f8a8319c8cf7d38e1adf263bc08d23", + }, + { + name: "with prefix and suffix", + line: "13:name=systemd:/podruntime/docker/kubepods/crio-dc679f8a8319c8cf7d38e1adf263bc08d23.stuff", + expectedContainerID: "dc679f8a8319c8cf7d38e1adf263bc08d23", + }, + { + name: "no prefix and suffix", + line: "13:name=systemd:/pod/d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356", + expectedContainerID: "d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356", + }, + { + name: "with space", + line: " 13:name=systemd:/pod/d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356 ", + expectedContainerID: "d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356", + }, + { + name: "invalid hex string", + line: "13:name=systemd:/podruntime/docker/kubepods/ac679f8a8319c8cf7d38e1adf263bc08d23zzzz", + }, + { + name: "no container id - 1", + line: "pids: /", + }, + { + name: "no container id - 2", + line: "pids: ", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + containerID := getContainerIDFromLine(tc.line) + assert.Equal(t, tc.expectedContainerID, containerID) + }) + } +} + +func TestGetContainerIDFromReader(t *testing.T) { + testCases := []struct { + name string + reader io.Reader + expectedContainerID string + }{ + { + name: "multiple lines", + reader: strings.NewReader(`// +1:name=systemd:/podruntime/docker/kubepods/docker-dc579f8a8319c8cf7d38e1adf263bc08d23 +1:name=systemd:/podruntime/docker/kubepods/docker-dc579f8a8319c8cf7d38e1adf263bc08d24 +`), + expectedContainerID: "dc579f8a8319c8cf7d38e1adf263bc08d23", + }, + { + name: "no container id", + reader: strings.NewReader(`// +1:name=systemd:/podruntime/docker +`), + expectedContainerID: "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + containerID := getContainerIDFromReader(tc.reader) + assert.Equal(t, tc.expectedContainerID, containerID) + }) + } +} diff --git a/sdk/resource/export_test.go b/sdk/resource/export_test.go index 4cad64f0b65..6c767e595c5 100644 --- a/sdk/resource/export_test.go +++ b/sdk/resource/export_test.go @@ -23,6 +23,8 @@ var ( SetUserProviders = setUserProviders SetDefaultOSDescriptionProvider = setDefaultOSDescriptionProvider SetOSDescriptionProvider = setOSDescriptionProvider + SetDefaultContainerProviders = setDefaultContainerProviders + SetContainerProviders = setContainerProviders ) var ( diff --git a/sdk/resource/process_test.go b/sdk/resource/process_test.go index d60c48411c4..b753d901efc 100644 --- a/sdk/resource/process_test.go +++ b/sdk/resource/process_test.go @@ -102,6 +102,7 @@ func restoreAttributesProviders() { resource.SetDefaultRuntimeProviders() resource.SetDefaultUserProviders() resource.SetDefaultOSDescriptionProvider() + resource.SetDefaultContainerProviders() } func TestWithProcessFuncsErrors(t *testing.T) { diff --git a/sdk/resource/resource_test.go b/sdk/resource/resource_test.go index 526ad13008f..a903cffd4ae 100644 --- a/sdk/resource/resource_test.go +++ b/sdk/resource/resource_test.go @@ -649,3 +649,57 @@ func hostname() string { } return hn } + +func TestWithContainerID(t *testing.T) { + t.Cleanup(restoreAttributesProviders) + + fakeContainerID := "fake-container-id" + + testCases := []struct { + name string + containerIDProvider func() (string, error) + + expectedResource map[string]string + expectedErr bool + }{ + { + name: "get container id", + containerIDProvider: func() (string, error) { + return fakeContainerID, nil + }, + expectedResource: map[string]string{ + string(semconv.ContainerIDKey): fakeContainerID, + }, + }, + { + name: "no container id found", + containerIDProvider: func() (string, error) { + return "", nil + }, + expectedResource: map[string]string{}, + }, + { + name: "error", + containerIDProvider: func() (string, error) { + return "", fmt.Errorf("unable to get container id") + }, + expectedResource: map[string]string{}, + expectedErr: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + resource.SetContainerProviders(tc.containerIDProvider) + + res, err := resource.New(context.Background(), + resource.WithContainerID(), + ) + + if tc.expectedErr { + assert.Error(t, err) + } + assert.Equal(t, tc.expectedResource, toMap(res)) + }) + } +} From 700c0a334e2ac5bb93bdbd89b45e51daf1397f5a Mon Sep 17 00:00:00 2001 From: Sam Xie Date: Fri, 26 Nov 2021 11:27:45 +0800 Subject: [PATCH 02/10] Fix wrong test case name --- sdk/resource/process_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/resource/process_test.go b/sdk/resource/process_test.go index b753d901efc..c76fcf1c1dc 100644 --- a/sdk/resource/process_test.go +++ b/sdk/resource/process_test.go @@ -108,8 +108,8 @@ func restoreAttributesProviders() { func TestWithProcessFuncsErrors(t *testing.T) { mockProcessAttributesProvidersWithErrors() - t.Run("WithPID", testWithProcessExecutablePathError) - t.Run("WithExecutableName", testWithProcessOwnerError) + t.Run("WithExecutablePath", testWithProcessExecutablePathError) + t.Run("WithOwner", testWithProcessOwnerError) restoreAttributesProviders() } From 95b4a14d4b623ca285e28dbb13dfd07dae8a946e Mon Sep 17 00:00:00 2001 From: Sam Xie Date: Fri, 26 Nov 2021 11:39:25 +0800 Subject: [PATCH 03/10] Add WithContainer option --- sdk/resource/config.go | 8 ++++++++ sdk/resource/resource_test.go | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/sdk/resource/config.go b/sdk/resource/config.go index 1e220b6d374..b0227761f3e 100644 --- a/sdk/resource/config.go +++ b/sdk/resource/config.go @@ -170,6 +170,14 @@ func WithProcessRuntimeDescription() Option { return WithDetectors(processRuntimeDescriptionDetector{}) } +// WithContainer adds all the Container attributes to the configured Resource. +// See individual WithContainer* functions to configure specific attributes. +func WithContainer() Option { + return WithDetectors( + containerIDDetector{}, + ) +} + // WithContainerID adds an attribute with the id of the container to the configured Resource. func WithContainerID() Option { return WithDetectors(containerIDDetector{}) diff --git a/sdk/resource/resource_test.go b/sdk/resource/resource_test.go index a903cffd4ae..5fd7a69a32a 100644 --- a/sdk/resource/resource_test.go +++ b/sdk/resource/resource_test.go @@ -703,3 +703,21 @@ func TestWithContainerID(t *testing.T) { }) } } + +func TestWithContainer(t *testing.T) { + t.Cleanup(restoreAttributesProviders) + + fakeContainerID := "fake-container-id" + resource.SetContainerProviders(func() (string, error) { + return fakeContainerID, nil + }) + + res, err := resource.New(context.Background(), + resource.WithContainer(), + ) + + assert.NoError(t, err) + assert.Equal(t, map[string]string{ + string(semconv.ContainerIDKey): fakeContainerID, + }, toMap(res)) +} From bf3c93cb81f262e77b9839443d1c46395fc48466 Mon Sep 17 00:00:00 2001 From: Sam Xie Date: Fri, 26 Nov 2021 12:01:17 +0800 Subject: [PATCH 04/10] Update CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8133966888c..9d6f08aab75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Remove the metric Processor's ability to convert cumulative to delta aggregation temporality. (#2350) - Remove the metric Bound Instruments interface and implementations. (#2399) +### Added + +- Add container id support to Resource. (#2418) + ## [1.2.0] - 2021-11-12 ### Changed From 6af401720bd7277ba1a72795a8060125a7abace0 Mon Sep 17 00:00:00 2001 From: Sam Xie Date: Mon, 7 Feb 2022 11:53:07 +0800 Subject: [PATCH 05/10] Fix comments --- sdk/resource/config.go | 4 ++-- sdk/resource/container.go | 8 ++++---- sdk/resource/container_test.go | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/sdk/resource/config.go b/sdk/resource/config.go index b0227761f3e..68701b4ebb6 100644 --- a/sdk/resource/config.go +++ b/sdk/resource/config.go @@ -174,11 +174,11 @@ func WithProcessRuntimeDescription() Option { // See individual WithContainer* functions to configure specific attributes. func WithContainer() Option { return WithDetectors( - containerIDDetector{}, + cgroupContainerIDDetector{}, ) } // WithContainerID adds an attribute with the id of the container to the configured Resource. func WithContainerID() Option { - return WithDetectors(containerIDDetector{}) + return WithDetectors(cgroupContainerIDDetector{}) } diff --git a/sdk/resource/container.go b/sdk/resource/container.go index 7045b1c81a7..f21f48bb0cd 100644 --- a/sdk/resource/container.go +++ b/sdk/resource/container.go @@ -28,17 +28,17 @@ import ( type containerIDProvider func() (string, error) var ( - defaultContainerIDProvider containerIDProvider = getContainerIDFromCGroup + containerID containerIDProvider = getContainerIDFromCGroup ) -type containerIDDetector struct{} +type cgroupContainerIDDetector struct{} const cgroupPath = "/proc/self/cgroup" // Detect returns a *Resource that describes the id of the container. // If no container id found, an empty resource will be returned. -func (containerIDDetector) Detect(ctx context.Context) (*Resource, error) { - containerID, err := defaultContainerIDProvider() +func (cgroupContainerIDDetector) Detect(ctx context.Context) (*Resource, error) { + containerID, err := containerID() if err != nil { return nil, err } diff --git a/sdk/resource/container_test.go b/sdk/resource/container_test.go index d35982d587a..be69edca21e 100644 --- a/sdk/resource/container_test.go +++ b/sdk/resource/container_test.go @@ -31,7 +31,7 @@ func setDefaultContainerProviders() { func setContainerProviders( idProvider containerIDProvider, ) { - defaultContainerIDProvider = idProvider + containerID = idProvider } func TestGetContainerIDFromLine(t *testing.T) { From 4f0c1faa22a7789101ba35b2b295074aca34b686 Mon Sep 17 00:00:00 2001 From: Sam Xie Date: Mon, 7 Feb 2022 11:56:30 +0800 Subject: [PATCH 06/10] Update CHANGELOG --- CHANGELOG.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c15afed1326..5cbe416004b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Support `OTEL_EXPORTER_ZIPKIN_ENDPOINT` env to specify zipkin collector endpoint (#2490) - Log the configuration of TracerProviders, and Tracers for debugging. To enable use a logger with Verbosity (V level) >=1 - Added environment variables for: `OTEL_BSP_SCHEDULE_DELAY`, `OTEL_BSP_EXPORT_TIMEOUT`, `OTEL_BSP_MAX_QUEUE_SIZE` and `OTEL_BSP_MAX_EXPORT_BATCH_SIZE` (#2515) +- Add container id support to Resource. (#2418) ### Changed @@ -81,10 +82,6 @@ We have updated the project minimum supported Go version to 1.16 - Remove the metric MinMaxSumCount kind aggregation and the corresponding OTLP export path. (#2423) - Metric SDK removes the "exact" aggregator for histogram instruments, as it performed a non-standard aggregation for OTLP export (creating repeated Gauge points) and worked its way into a number of confusing examples. (#2348) -### Added - -- Add container id support to Resource. (#2418) - ## [1.2.0] - 2021-11-12 ### Changed From 58fb968bf664cd941f0afe7ba3deb7068affb551 Mon Sep 17 00:00:00 2001 From: Sam Xie Date: Thu, 3 Mar 2022 15:40:46 +0800 Subject: [PATCH 07/10] Use regex to find container id --- sdk/resource/container.go | 48 ++++++--------------------------------- 1 file changed, 7 insertions(+), 41 deletions(-) diff --git a/sdk/resource/container.go b/sdk/resource/container.go index f21f48bb0cd..a74e46a4b6c 100644 --- a/sdk/resource/container.go +++ b/sdk/resource/container.go @@ -20,7 +20,7 @@ import ( "errors" "io" "os" - "strings" + "regexp" semconv "go.opentelemetry.io/otel/semconv/v1.7.0" ) @@ -35,6 +35,8 @@ type cgroupContainerIDDetector struct{} const cgroupPath = "/proc/self/cgroup" +var cgroupContainerIDRe = regexp.MustCompile(`^.*/(?:.*-)?([0-9a-f]+)(?:\.|\s*$)`) + // Detect returns a *Resource that describes the id of the container. // If no container id found, an empty resource will be returned. func (cgroupContainerIDDetector) Detect(ctx context.Context) (*Resource, error) { @@ -86,45 +88,9 @@ func getContainerIDFromReader(reader io.Reader) string { // getContainerIDFromLine returns the id of the container from one string line. func getContainerIDFromLine(line string) string { - line = strings.TrimSpace(line) - - lastSlashIndexOfLine := strings.LastIndexByte(line, '/') - if lastSlashIndexOfLine == -1 { - return "" - } - - lastSection := line[lastSlashIndexOfLine+1:] - dashIndex := strings.IndexByte(lastSection, '-') - lastDotIndex := strings.LastIndexByte(lastSection, '.') - - startIndex := 0 - if dashIndex != -1 { - startIndex = dashIndex + 1 - } - - endIndex := len(lastSection) - if lastDotIndex != -1 { - endIndex = lastDotIndex + matches := cgroupContainerIDRe.FindStringSubmatch(line) + if len(matches) > 1 { + return matches[1] } - - containerID := lastSection[startIndex:endIndex] - if !isHex(containerID) { - return "" - } - return containerID -} - -// isHex returns true when input is a hex string. -func isHex(h string) bool { - for _, r := range h { - switch { - case 'a' <= r && r <= 'f': - continue - case '0' <= r && r <= '9': - continue - default: - return false - } - } - return true + return "" } From 7ce64e957e9b9d8e1f1658bfb85a603c4c5e4d7a Mon Sep 17 00:00:00 2001 From: Sam Xie Date: Thu, 3 Mar 2022 18:04:54 +0800 Subject: [PATCH 08/10] Add tests for reading cgroup file --- sdk/resource/container.go | 23 ++++++++------ sdk/resource/container_test.go | 55 ++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 9 deletions(-) diff --git a/sdk/resource/container.go b/sdk/resource/container.go index a74e46a4b6c..21bb72977e1 100644 --- a/sdk/resource/container.go +++ b/sdk/resource/container.go @@ -51,26 +51,31 @@ func (cgroupContainerIDDetector) Detect(ctx context.Context) (*Resource, error) return NewWithAttributes(semconv.SchemaURL, semconv.ContainerIDKey.String(containerID)), nil } +var ( + defaultOSStat = os.Stat + osStat = defaultOSStat + + defaultOSOpen = func(name string) (io.ReadCloser, error) { + return os.Open(name) + } + osOpen = defaultOSOpen +) + // getContainerIDFromCGroup returns the id of the container from the cgroup file. // If no container id found, an empty string will be returned. func getContainerIDFromCGroup() (string, error) { - if _, err := os.Stat(cgroupPath); errors.Is(err, os.ErrNotExist) { - // File does not exists, skip + if _, err := osStat(cgroupPath); errors.Is(err, os.ErrNotExist) { + // File does not exist, skip return "", nil } - file, err := os.Open(cgroupPath) + file, err := osOpen(cgroupPath) if err != nil { return "", err } defer file.Close() - containerID := getContainerIDFromReader(file) - if containerID == "" { - // Container ID not found - return "", nil - } - return containerID, nil + return getContainerIDFromReader(file), nil } // getContainerIDFromReader returns the id of the container from reader. diff --git a/sdk/resource/container_test.go b/sdk/resource/container_test.go index be69edca21e..b09160da872 100644 --- a/sdk/resource/container_test.go +++ b/sdk/resource/container_test.go @@ -15,7 +15,9 @@ package resource import ( + "errors" "io" + "os" "strings" "testing" @@ -112,3 +114,56 @@ func TestGetContainerIDFromReader(t *testing.T) { }) } } + +func TestGetContainerIDFromCGroup(t *testing.T) { + t.Cleanup(func() { + osStat = defaultOSStat + osOpen = defaultOSOpen + }) + + testCases := []struct { + name string + cgroupFileNotExist bool + openFileError error + content string + expectedContainerID string + expectedError bool + }{ + { + name: "the cgroup file does not exist", + cgroupFileNotExist: true, + }, + { + name: "error when opening cgroup file", + openFileError: errors.New("test"), + expectedError: true, + }, + { + name: "cgroup file", + content: "1:name=systemd:/podruntime/docker/kubepods/docker-dc579f8a8319c8cf7d38e1adf263bc08d23", + expectedContainerID: "dc579f8a8319c8cf7d38e1adf263bc08d23", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + osStat = func(name string) (os.FileInfo, error) { + if tc.cgroupFileNotExist { + return nil, os.ErrNotExist + } + return nil, nil + } + + osOpen = func(name string) (io.ReadCloser, error) { + if tc.openFileError != nil { + return nil, tc.openFileError + } + return io.NopCloser(strings.NewReader(tc.content)), nil + } + + containerID, err := getContainerIDFromCGroup() + assert.Equal(t, tc.expectedError, err != nil) + assert.Equal(t, tc.expectedContainerID, containerID) + }) + } +} From a4c61458eddde2827a553b12f155e37c838aefcd Mon Sep 17 00:00:00 2001 From: Sam Xie Date: Thu, 3 Mar 2022 18:37:40 +0800 Subject: [PATCH 09/10] Update sdk/resource/container.go Co-authored-by: Chester Cheung --- sdk/resource/container.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/resource/container.go b/sdk/resource/container.go index 21bb72977e1..49d93951010 100644 --- a/sdk/resource/container.go +++ b/sdk/resource/container.go @@ -94,8 +94,8 @@ func getContainerIDFromReader(reader io.Reader) string { // getContainerIDFromLine returns the id of the container from one string line. func getContainerIDFromLine(line string) string { matches := cgroupContainerIDRe.FindStringSubmatch(line) - if len(matches) > 1 { - return matches[1] + if len(matches) <= 1 { + return "" } - return "" + return matches[1] } From 06ef3383104574a282c2e4e6c88abd02a4a983f7 Mon Sep 17 00:00:00 2001 From: Sam Xie Date: Thu, 3 Mar 2022 18:44:26 +0800 Subject: [PATCH 10/10] Update format --- sdk/resource/container.go | 5 ++--- sdk/resource/resource_test.go | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/sdk/resource/container.go b/sdk/resource/container.go index 49d93951010..e56978adad5 100644 --- a/sdk/resource/container.go +++ b/sdk/resource/container.go @@ -28,15 +28,14 @@ import ( type containerIDProvider func() (string, error) var ( - containerID containerIDProvider = getContainerIDFromCGroup + containerID containerIDProvider = getContainerIDFromCGroup + cgroupContainerIDRe = regexp.MustCompile(`^.*/(?:.*-)?([0-9a-f]+)(?:\.|\s*$)`) ) type cgroupContainerIDDetector struct{} const cgroupPath = "/proc/self/cgroup" -var cgroupContainerIDRe = regexp.MustCompile(`^.*/(?:.*-)?([0-9a-f]+)(?:\.|\s*$)`) - // Detect returns a *Resource that describes the id of the container. // If no container id found, an empty resource will be returned. func (cgroupContainerIDDetector) Detect(ctx context.Context) (*Resource, error) { diff --git a/sdk/resource/resource_test.go b/sdk/resource/resource_test.go index 5fd7a69a32a..fa9b9e4ea05 100644 --- a/sdk/resource/resource_test.go +++ b/sdk/resource/resource_test.go @@ -658,9 +658,8 @@ func TestWithContainerID(t *testing.T) { testCases := []struct { name string containerIDProvider func() (string, error) - - expectedResource map[string]string - expectedErr bool + expectedResource map[string]string + expectedErr bool }{ { name: "get container id",