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

[feat] custom user-agent (& expanding OTEL_EXPORTER_OTLP_* env var support) #94

Merged
5 changes: 4 additions & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
pull_request:

jobs:
generate:
generate-and-test:
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
Expand All @@ -24,6 +24,9 @@ jobs:
- name: verify output
run: |
git diff --exit-code || (echo 'generated diff, please run "make generate"' && exit 1)
- name: Run unit tests
run: |
make test
docker-build:
runs-on: ubuntu-latest
steps:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/e2e/k8s/sample-job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ spec:
- name: OTEL_GO_AUTO_TARGET_EXE
value: /sample-app/main
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "test-opentelemetry-collector:4317"
value: "http://test-opentelemetry-collector:4317"
- name: OTEL_SERVICE_NAME
value: "sample-app"
- name: OTEL_PROPAGATORS
Expand Down
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ $(TOOLS)/go-licenses: PACKAGE=github.com/google/go-licenses
.PHONY: tools
tools: $(GOLICENSES)

ALL_GO_MODS := $(shell find . -type f -name 'go.mod' ! -path '$(TOOLS_MOD_DIR)/*' ! -path './LICENSES/*' | sort)
GO_MODS_TO_TEST := $(ALL_GO_MODS:%=test/%)

test: $(GO_MODS_TO_TEST)
robbkidd marked this conversation as resolved.
Show resolved Hide resolved
test/%: GO_MOD=$*
test/%:
cd $(shell dirname $(GO_MOD)) && go test -v ./...

.PHONY: generate
generate: export CFLAGS := $(BPF_INCLUDE)
generate:
Expand Down
8 changes: 4 additions & 4 deletions docs/getting-started/emojivoto-instrumented.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ spec:
- name: OTEL_GO_AUTO_TARGET_EXE
value: /usr/local/bin/emojivoto-emoji-svc
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "jaeger:4317"
value: "http://jaeger:4317"
- name: OTEL_SERVICE_NAME
value: "emojivoto-emoji"
securityContext:
Expand Down Expand Up @@ -143,7 +143,7 @@ spec:
- name: OTEL_GO_AUTO_TARGET_EXE
value: /usr/local/bin/emojivoto-voting-svc
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "jaeger:4317"
value: "http://jaeger:4317"
- name: OTEL_SERVICE_NAME
value: "emojivoto-voting"
securityContext:
Expand Down Expand Up @@ -227,7 +227,7 @@ spec:
- name: OTEL_GO_AUTO_TARGET_EXE
value: /usr/local/bin/emojivoto-web
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "jaeger:4317"
value: "http://jaeger:4317"
- name: OTEL_SERVICE_NAME
value: "emojivoto-web"
securityContext:
Expand All @@ -244,4 +244,4 @@ spec:
emptyDir: {}
- name: kernel-debug
hostPath:
path: /sys/kernel/debug
path: /sys/kernel/debug
6 changes: 5 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,27 @@ require (
github.com/hashicorp/go-version v1.6.0
github.com/pkg/errors v0.9.1
github.com/prometheus/procfs v0.9.0
github.com/stretchr/testify v1.8.2
go.opentelemetry.io/otel v1.14.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0
go.opentelemetry.io/otel/sdk v1.14.0
go.opentelemetry.io/otel/trace v1.14.0
go.uber.org/zap v1.24.0
golang.org/x/arch v0.3.0
golang.org/x/sys v0.7.0
google.golang.org/grpc v1.54.0
gopkg.in/yaml.v3 v3.0.1
)

require (
github.com/cenkalti/backoff/v4 v4.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0 // indirect
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
Expand Down
7 changes: 7 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,16 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down Expand Up @@ -454,6 +459,7 @@ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
google.golang.org/protobuf v1.28.1/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=
Expand All @@ -462,6 +468,7 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
Expand Down
38 changes: 20 additions & 18 deletions pkg/opentelemetry/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ import (
"fmt"
"os"
"runtime"
"strings"
"time"

"github.com/prometheus/procfs"
"go.opentelemetry.io/auto"
"go.opentelemetry.io/auto/pkg/instrumentors/events"
"go.opentelemetry.io/auto/pkg/log"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
"go.opentelemetry.io/otel/sdk/resource"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
Expand All @@ -34,10 +37,20 @@ import (
)

const (
otelEndpointEnvVar = "OTEL_EXPORTER_OTLP_ENDPOINT"
otelServiceNameEnvVar = "OTEL_SERVICE_NAME"
)

var (
// Controller-local reference to the auto-instrumentation release version.
releaseVersion = auto.Version()
// Start of this auto-instrumentation's exporter User-Agent header, e.g. ""OTel-Go-Auto-Instrumentation/1.2.3"
baseUserAgent = fmt.Sprintf("OTel-Go-Auto-Instrumentation/%s", releaseVersion)
// Information about the runtime environment for inclusion in User-Agent, e.g. "go/1.18.2 (linux/amd64)"
runtimeInfo = fmt.Sprintf("%s (%s/%s)", strings.Replace(runtime.Version(), "go", "go/", 1), runtime.GOOS, runtime.GOARCH)
// Combined User-Agent identifying this auto-instrumentation and its runtime environment, see RFC7231 for format considerations.
autoinstUserAgent = fmt.Sprintf("%s %s", baseUserAgent, runtimeInfo)
robbkidd marked this conversation as resolved.
Show resolved Hide resolved
)

type Controller struct {
tracerProvider trace.TracerProvider
tracersMap map[string]trace.Tracer
Expand Down Expand Up @@ -83,11 +96,6 @@ func (c *Controller) convertTime(t int64) time.Time {
}

func NewController() (*Controller, error) {
endpoint, exists := os.LookupEnv(otelEndpointEnvVar)
if !exists {
return nil, fmt.Errorf("%s env var must be set", otelEndpointEnvVar)
}

serviceName, exists := os.LookupEnv(otelServiceNameEnvVar)
if !exists {
return nil, fmt.Errorf("%s env var must be set", otelServiceNameEnvVar)
Expand All @@ -98,26 +106,20 @@ func NewController() (*Controller, error) {
resource.WithAttributes(
semconv.ServiceNameKey.String(serviceName),
semconv.TelemetrySDKLanguageGo,
semconv.TelemetryAutoVersionKey.String(releaseVersion),
),
)
if err != nil {
return nil, err
}

log.Logger.V(0).Info("Establishing connection to OpenTelemetry collector ...")
timeoutContext, cancel := context.WithTimeout(ctx, time.Second*10)
defer cancel()
conn, err := grpc.DialContext(timeoutContext, endpoint, grpc.WithInsecure(), grpc.WithBlock())
if err != nil {
log.Logger.Error(err, "unable to connect to OpenTelemetry collector", "addr", endpoint)
return nil, err
}

traceExporter, err := otlptracegrpc.New(ctx,
otlptracegrpc.WithGRPCConn(conn),
log.Logger.V(0).Info("Establishing connection to OTLP receiver ...")
otlpTraceClient := otlptracegrpc.NewClient(
robbkidd marked this conversation as resolved.
Show resolved Hide resolved
otlptracegrpc.WithDialOption(grpc.WithUserAgent(autoinstUserAgent)),
)

traceExporter, err := otlptrace.New(ctx, otlpTraceClient)
if err != nil {
log.Logger.Error(err, "unable to connect to OTLP endpoint")
return nil, err
}

Expand Down
27 changes: 27 additions & 0 deletions pkg/opentelemetry/controller_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// 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 opentelemetry

import (
"fmt"
"testing"

"github.com/stretchr/testify/assert"
"go.opentelemetry.io/auto"
)

func TestUserAgent(t *testing.T) {
assert.Contains(t, autoinstUserAgent, fmt.Sprintf("OTel-Go-Auto-Instrumentation/%s", auto.Version()))
}
6 changes: 6 additions & 0 deletions test/e2e/gorillamux/traces.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
"stringValue": "sample-app"
}
},
{
"key": "telemetry.auto.version",
"value": {
"stringValue": "v0.1.0-alpha"
MrAlias marked this conversation as resolved.
Show resolved Hide resolved
}
},
{
"key": "telemetry.sdk.language",
"value": {
Expand Down
6 changes: 6 additions & 0 deletions test/e2e/nethttp/traces.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
"stringValue": "sample-app"
}
},
{
"key": "telemetry.auto.version",
"value": {
"stringValue": "v0.1.0-alpha"
}
},
{
"key": "telemetry.sdk.language",
"value": {
Expand Down
20 changes: 20 additions & 0 deletions version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// 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 auto

// Go autoinstrumentation release version
robbkidd marked this conversation as resolved.
Show resolved Hide resolved
func Version() string {
return "v0.1.0-alpha"
}
54 changes: 54 additions & 0 deletions version_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// 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 auto

import (
"io/ioutil"
"regexp"
"testing"

"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
)

// regex taken from https://github.com/Masterminds/semver/tree/v3.1.1
var versionRegex = regexp.MustCompile(`^v?([0-9]+)(\.[0-9]+)?(\.[0-9]+)?` +
`(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` +
`(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?$`)

func TestVersionSemver(t *testing.T) {
v := Version()
assert.NotNil(t, versionRegex.FindStringSubmatch(v), "version is not semver: %s", v)
}

func TestVersionMatchesYaml(t *testing.T) {
versionYaml, err := ioutil.ReadFile("versions.yaml")
if err != nil {
t.Fatalf("Couldn't read versions.yaml file: %e", err)
return
}

var versionInfo map[string]interface{}

err = yaml.Unmarshal(versionYaml, &versionInfo)
if err != nil {
t.Fatalf("Couldn't parse version.yaml: %e", err)
return
}

// incredibad, but it's where the intended version is declared at the moment
expectedVersion := versionInfo["module-sets"].(map[string]interface{})["alpha"].(map[string]interface{})["version"]
assert.Equal(t, expectedVersion, Version(), "Build version should match versions.yaml.")
}