Skip to content

Commit

Permalink
auto-instrumentation-go
Browse files Browse the repository at this point in the history
Added logic for golang ebpf sidecar auto-instrumentation
  • Loading branch information
andrew-lozoya committed Dec 4, 2023
1 parent 2b0a0cd commit 7005086
Show file tree
Hide file tree
Showing 38 changed files with 1,928 additions and 444 deletions.
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ ARG NEWRELIC_INSTRUMENTATION_JAVA_VERSION
ARG NEWRELIC_INSTRUMENTATION_NODEJS_VERSION
ARG NEWRELIC_INSTRUMENTATION_PYTHON_VERSION
ARG NEWRELIC_INSTRUMENTATION_DOTNET_VERSION
ARG AUTO_INSTRUMENTATION_GO_VERSION
# Build
# the GOARCH has not a default value to allow the binary be built according to the host where the command
# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO
Expand Down
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ NEWRELIC_INSTRUMENTATION_JAVA_VERSION ?= "$(shell grep -v '\#' versions.txt | gr
NEWRELIC_INSTRUMENTATION_NODEJS_VERSION ?= "$(shell grep -v '\#' versions.txt | grep newrelic-instrumentation-nodejs | awk -F= '{print $$2}')"
NEWRELIC_INSTRUMENTATION_PYTHON_VERSION ?= "$(shell grep -v '\#' versions.txt | grep newrelic-instrumentation-python | awk -F= '{print $$2}')"
NEWRELIC_INSTRUMENTATION_DOTNET_VERSION ?= "$(shell grep -v '\#' versions.txt | grep newrelic-instrumentation-dotnet | awk -F= '{print $$2}')"
LD_FLAGS ?= "-X ${VERSION_PKG}.version=${VERSION} -X ${VERSION_PKG}.buildDate=${VERSION_DATE} -X ${VERSION_PKG}.autoInstrumentationJava=${NEWRELIC_INSTRUMENTATION_JAVA_VERSION} -X ${VERSION_PKG}.autoInstrumentationNodeJS=${NEWRELIC_INSTRUMENTATION_NODEJS_VERSION} -X ${VERSION_PKG}.autoInstrumentationPython=${NEWRELIC_INSTRUMENTATION_PYTHON_VERSION} -X ${VERSION_PKG}.autoInstrumentationDotNet=${NEWRELIC_INSTRUMENTATION_DOTNET_VERSION}"
AUTO_INSTRUMENTATION_GO_VERSION ?= "$(shell grep -v '\#' versions.txt | grep autoinstrumentation-go | awk -F= '{print $$2}')"
LD_FLAGS ?= "-X ${VERSION_PKG}.version=${VERSION} -X ${VERSION_PKG}.buildDate=${VERSION_DATE} -X ${VERSION_PKG}.autoInstrumentationJava=${NEWRELIC_INSTRUMENTATION_JAVA_VERSION} -X ${VERSION_PKG}.autoInstrumentationNodeJS=${NEWRELIC_INSTRUMENTATION_NODEJS_VERSION} -X ${VERSION_PKG}.autoInstrumentationPython=${NEWRELIC_INSTRUMENTATION_PYTHON_VERSION} -X ${VERSION_PKG}.autoInstrumentationGo=${AUTO_INSTRUMENTATION_GO_VERSION} -X ${VERSION_PKG}.autoInstrumentationDotNet=${NEWRELIC_INSTRUMENTATION_DOTNET_VERSION}"
ARCH ?= $(shell go env GOARCH)

# Image URL to use all building/pushing image targets
Expand Down Expand Up @@ -310,4 +311,4 @@ $(HELMIFY): $(LOCALBIN)
test -s $(LOCALBIN)/helmify || GOBIN=$(LOCALBIN) go install github.com/arttor/helmify/cmd/helmify@$(HELMIFY_VERSION)

helm: manifests kustomize helmify
$(KUSTOMIZE) build config/default | $(HELMIFY)
$(KUSTOMIZE) build config/default | $(HELMIFY)
84 changes: 83 additions & 1 deletion api/v1alpha1/instrumentation_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package v1alpha1

import (
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

Expand All @@ -26,7 +27,27 @@ type InstrumentationSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file

// Env defines agent specific env vars
// Exporter defines exporter configuration.
// +optional
Exporter `json:"exporter,omitempty"`

// Resource defines the configuration for the resource attributes, as defined by the OpenTelemetry specification.
// +optional
Resource Resource `json:"resource,omitempty"`

// Propagators defines inter-process context propagation configuration.
// Values in this list will be set in the OTEL_PROPAGATORS env var.
// Enum=tracecontext;none
// +optional
Propagators []Propagator `json:"propagators,omitempty"`

// Sampler defines sampling configuration.
// +optional
Sampler `json:"sampler,omitempty"`

// Env defines common env vars. There are four layers for env vars' definitions and
// the precedence order is: `original container env vars` > `language specific env vars` > `common env vars` > `instrument spec configs' vars`.
// If the former var had been defined, then the other vars would be ignored.
// +optional
Env []corev1.EnvVar `json:"env,omitempty"`

Expand All @@ -45,6 +66,47 @@ type InstrumentationSpec struct {
// DotNet defines configuration for DotNet auto-instrumentation.
// +optional
DotNet DotNet `json:"dotnet,omitempty"`

// Go defines configuration for Go auto-instrumentation.
// When using Go auto-instrumentation you must provide a value for the OTEL_GO_AUTO_TARGET_EXE env var via the
// Instrumentation env vars or via the instrumentation.opentelemetry.io/otel-go-auto-target-exe pod annotation.
// Failure to set this value causes instrumentation injection to abort, leaving the original pod unchanged.
// +optional
Go Go `json:"go,omitempty"`
}

type Resource struct {
// Attributes defines attributes that are added to the resource.
// For example environment: dev
// +optional
Attributes map[string]string `json:"resourceAttributes,omitempty"`

// AddK8sUIDAttributes defines whether K8s UID attributes should be collected (e.g. k8s.deployment.uid).
// +optional
AddK8sUIDAttributes bool `json:"addK8sUIDAttributes,omitempty"`
}

// Exporter defines OTLP exporter configuration.
type Exporter struct {
// Endpoint is address of the collector with OTLP endpoint.
// +optional
Endpoint string `json:"endpoint,omitempty"`
}

// Sampler defines sampling configuration.
type Sampler struct {
// Type defines sampler type.
// The value will be set in the OTEL_TRACES_SAMPLER env var.
// The value can be for instance parentbased_always_on, parentbased_always_off, parentbased_traceidratio...
// +optional
Type SamplerType `json:"type,omitempty"`

// Argument defines sampler argument.
// The value depends on the sampler type.
// For instance for parentbased_traceidratio sampler type it is a number in range [0..1] e.g. 0.25.
// The value will be set in the OTEL_TRACES_SAMPLER_ARG env var.
// +optional
Argument string `json:"argument,omitempty"`
}

// Java defines Java agent and instrumentation configuration.
Expand Down Expand Up @@ -94,6 +156,26 @@ type DotNet struct {
Env []corev1.EnvVar `json:"env,omitempty"`
}

type Go struct {
// Image is a container image with Go SDK and auto-instrumentation.
// +optional
Image string `json:"image,omitempty"`

// VolumeSizeLimit defines size limit for volume used for auto-instrumentation.
// The default size is 200Mi.
VolumeSizeLimit *resource.Quantity `json:"volumeLimitSize,omitempty"`

// Env defines Go specific env vars. There are four layers for env vars' definitions and
// the precedence order is: `original container env vars` > `language specific env vars` > `common env vars` > `instrument spec configs' vars`.
// If the former var had been defined, then the other vars would be ignored.
// +optional
Env []corev1.EnvVar `json:"env,omitempty"`

// Resources describes the compute resource requirements.
// +optional
Resources corev1.ResourceRequirements `json:"resourceRequirements,omitempty"`
}

// InstrumentationStatus defines the observed state of Instrumentation
type InstrumentationStatus struct {
}
Expand Down
16 changes: 13 additions & 3 deletions api/v1alpha1/instrumentation_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ const (
AnnotationDefaultAutoInstrumentationNodeJS = "instrumentation.newrelic.com/default-auto-instrumentation-nodejs-image"
AnnotationDefaultAutoInstrumentationPython = "instrumentation.newrelic.com/default-auto-instrumentation-python-image"
AnnotationDefaultAutoInstrumentationDotNet = "instrumentation.newrelic.com/default-auto-instrumentation-dotnet-image"
envPrefix = "NEW_RELIC_"
AnnotationDefaultAutoInstrumentationGo = "instrumentation.newrelic.com/default-auto-instrumentation-go-image"
envNewRelicPrefix = "NEW_RELIC_"
envOtelPrefix = "OTEL_"
)

// log is for logging in this package.
Expand Down Expand Up @@ -78,6 +80,11 @@ func (r *Instrumentation) Default() {
r.Spec.DotNet.Image = val
}
}
if r.Spec.Go.Image == "" {
if val, ok := r.Annotations[AnnotationDefaultAutoInstrumentationGo]; ok {
r.Spec.Go.Image = val
}
}
}

// +kubebuilder:webhook:verbs=create;update,path=/validate-newrelic-com-v1alpha1-instrumentation,mutating=false,failurePolicy=fail,groups=newrelic.com,resources=instrumentations,versions=v1alpha1,name=vinstrumentationcreateupdate.kb.io,sideEffects=none,admissionReviewVersions=v1
Expand Down Expand Up @@ -121,14 +128,17 @@ func (r *Instrumentation) validate() error {
if err := r.validateEnv(r.Spec.DotNet.Env); err != nil {
return err
}
if err := r.validateEnv(r.Spec.Go.Env); err != nil {
return err
}

return nil
}

func (r *Instrumentation) validateEnv(envs []corev1.EnvVar) error {
for _, env := range envs {
if !strings.HasPrefix(env.Name, envPrefix) {
return fmt.Errorf("env name should start with \"NEW_RELIC_\": %s", env.Name)
if !strings.HasPrefix(env.Name, envNewRelicPrefix) && !strings.HasPrefix(env.Name, envOtelPrefix) {
return fmt.Errorf("env name should start with \"NEW_RELIC_\" or \"OTEL_\": %s", env.Name)
}
}
return nil
Expand Down
28 changes: 28 additions & 0 deletions api/v1alpha1/propagators.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// 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 v1alpha1

type (
// Propagator represents the propagation type.
// +kubebuilder:validation:Enum=tracecontext;none
Propagator string
)

const (
// TraceContext represents W3C Trace Context.
TraceContext Propagator = "tracecontext"
// None represents automatically configured propagator.
None Propagator = "none"
)
36 changes: 36 additions & 0 deletions api/v1alpha1/samplers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// 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 v1alpha1

type (
// SamplerType represents sampler type.
// +kubebuilder:validation:Enum=always_on;always_off;traceidratio;parentbased_always_on;parentbased_always_off;parentbased_traceidratio
SamplerType string
)

const (
// AlwaysOn represents AlwaysOnSampler.
AlwaysOn SamplerType = "always_on"
// AlwaysOff represents AlwaysOffSampler.
AlwaysOff SamplerType = "always_off"
// TraceIDRatio represents TraceIdRatioBased.
TraceIDRatio SamplerType = "traceidratio"
// ParentBasedAlwaysOn represents ParentBased(root=AlwaysOnSampler).
ParentBasedAlwaysOn SamplerType = "parentbased_always_on"
// ParentBasedAlwaysOff represents ParentBased(root=AlwaysOffSampler).
ParentBasedAlwaysOff SamplerType = "parentbased_always_off"
// ParentBasedTraceIDRatio represents ParentBased(root=TraceIdRatioBased).
ParentBasedTraceIDRatio SamplerType = "parentbased_traceidratio"
)
89 changes: 89 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion autoinstrumentation/dotnet/version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
10.20.0
10.20.0
2 changes: 1 addition & 1 deletion autoinstrumentation/java/version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8.7.0
8.7.0
2 changes: 1 addition & 1 deletion autoinstrumentation/python/requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
newrelic==9.2.0
newrelic==9.2.0
Loading

0 comments on commit 7005086

Please sign in to comment.