From f621e0599713e3bdb89b8ed84379734ccd6df88e Mon Sep 17 00:00:00 2001 From: Mitali Salvi <44349099+mitali-salvi@users.noreply.github.com> Date: Thu, 11 Jul 2024 12:23:47 -0400 Subject: [PATCH 1/7] Adding support for nodejs instrumentation (#191) --- Dockerfile | 3 +- Makefile | 3 +- main.go | 10 ++++- pkg/instrumentation/auto/config.go | 3 ++ pkg/instrumentation/auto/config_test.go | 9 ++++ pkg/instrumentation/defaultinstrumentation.go | 32 ++++++++++++--- .../defaultinstrumentation_test.go | 41 ++++++++++++++++++- pkg/instrumentation/podmutator_test.go | 22 +++++++++- versions.txt | 2 + 9 files changed, 114 insertions(+), 11 deletions(-) diff --git a/Dockerfile b/Dockerfile index 22c723c25..c65c8ed8c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,11 +26,12 @@ ARG VERSION_DATE ARG AGENT_VERSION ARG AUTO_INSTRUMENTATION_JAVA_VERSION ARG AUTO_INSTRUMENTATION_PYTHON_VERSION +ARG AUTO_INSTRUMENTATION_NODEJS_VERSION ARG DCMG_EXPORTER_VERSION ARG NEURON_MONITOR_VERSION # Build -RUN CGO_ENABLED=0 GOOS=linux GO111MODULE=on go build -ldflags="-X ${VERSION_PKG}.version=${VERSION} -X ${VERSION_PKG}.buildDate=${VERSION_DATE} -X ${VERSION_PKG}.agent=${AGENT_VERSION} -X ${VERSION_PKG}.autoInstrumentationJava=${AUTO_INSTRUMENTATION_JAVA_VERSION} -X ${VERSION_PKG}.autoInstrumentationPython=${AUTO_INSTRUMENTATION_PYTHON_VERSION} -X ${VERSION_PKG}.dcgmExporter=${DCMG_EXPORTER_VERSION} -X ${VERSION_PKG}.neuronMonitor=${NEURON_MONITOR_VERSION}" -a -o manager main.go +RUN CGO_ENABLED=0 GOOS=linux GO111MODULE=on go build -ldflags="-X ${VERSION_PKG}.version=${VERSION} -X ${VERSION_PKG}.buildDate=${VERSION_DATE} -X ${VERSION_PKG}.agent=${AGENT_VERSION} -X ${VERSION_PKG}.autoInstrumentationJava=${AUTO_INSTRUMENTATION_JAVA_VERSION} -X ${VERSION_PKG}.autoInstrumentationPython=${AUTO_INSTRUMENTATION_PYTHON_VERSION} -X ${VERSION_PKG}.autoInstrumentationNodeJS=${AUTO_INSTRUMENTATION_NODEJS_VERSION} -X ${VERSION_PKG}.dcgmExporter=${DCMG_EXPORTER_VERSION} -X ${VERSION_PKG}.neuronMonitor=${NEURON_MONITOR_VERSION}" -a -o manager main.go # Use distroless as minimal base image to package the manager binary # Refer to https://github.com/GoogleContainerTools/distroless for more details diff --git a/Makefile b/Makefile index c839e739f..db3bf91fb 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ VERSION_PKG ?= "github.com/aws/amazon-cloudwatch-agent-operator/internal/version AGENT_VERSION ?= "$(shell grep -v '\#' versions.txt | grep cloudwatch-agent | awk -F= '{print $$2}')" AUTO_INSTRUMENTATION_JAVA_VERSION ?= "$(shell grep -v '\#' versions.txt | grep aws-otel-java-instrumentation | awk -F= '{print $$2}')" AUTO_INSTRUMENTATION_PYTHON_VERSION ?= "$(shell grep -v '\#' versions.txt | grep aws-otel-python-instrumentation | awk -F= '{print $$2}')" +AUTO_INSTRUMENTATION_NODEJS_VERSION ?= "$(shell grep -v '\#' versions.txt | grep aws-otel-nodejs-instrumentation | awk -F= '{print $$2}')" DCGM_EXPORTER_VERSION ?= "$(shell grep -v '\#' versions.txt | grep dcgm-exporter | awk -F= '{print $$2}')" NEURON_MONITOR_VERSION ?= "$(shell grep -v '\#' versions.txt | grep neuron-monitor | awk -F= '{print $$2}')" @@ -153,7 +154,7 @@ generate: controller-gen api-docs # buildx is used to ensure same results for arm based systems (m1/2 chips) .PHONY: container container: - docker buildx build --load --platform linux/${ARCH} -t ${IMG} --build-arg VERSION_PKG=${VERSION_PKG} --build-arg VERSION=${VERSION} --build-arg VERSION_DATE=${VERSION_DATE} --build-arg AGENT_VERSION=${AGENT_VERSION} --build-arg AUTO_INSTRUMENTATION_JAVA_VERSION=${AUTO_INSTRUMENTATION_JAVA_VERSION} --build-arg AUTO_INSTRUMENTATION_PYTHON_VERSION=${AUTO_INSTRUMENTATION_PYTHON_VERSION} --build-arg DCGM_EXPORTER_VERSION=${DCGM_EXPORTER_VERSION} --build-arg NEURON_MONITOR_VERSION=${NEURON_MONITOR_VERSION} . + docker buildx build --load --platform linux/${ARCH} -t ${IMG} --build-arg VERSION_PKG=${VERSION_PKG} --build-arg VERSION=${VERSION} --build-arg VERSION_DATE=${VERSION_DATE} --build-arg AGENT_VERSION=${AGENT_VERSION} --build-arg AUTO_INSTRUMENTATION_JAVA_VERSION=${AUTO_INSTRUMENTATION_JAVA_VERSION} --build-arg AUTO_INSTRUMENTATION_PYTHON_VERSION=${AUTO_INSTRUMENTATION_PYTHON_VERSION} --build-arg AUTO_INSTRUMENTATION_NODEJS_VERSION=${AUTO_INSTRUMENTATION_NODEJS_VERSION} --build-arg DCGM_EXPORTER_VERSION=${DCGM_EXPORTER_VERSION} --build-arg NEURON_MONITOR_VERSION=${NEURON_MONITOR_VERSION} . # Push the container image, used only for local dev purposes .PHONY: container-push diff --git a/main.go b/main.go index 34b1909ab..bc3a6700f 100644 --- a/main.go +++ b/main.go @@ -48,6 +48,8 @@ const ( cloudwatchAgentImageRepository = "public.ecr.aws/cloudwatch-agent/cloudwatch-agent" autoInstrumentationJavaImageRepository = "public.ecr.aws/aws-observability/adot-autoinstrumentation-java" autoInstrumentationPythonImageRepository = "public.ecr.aws/aws-observability/adot-autoinstrumentation-python" + //TODO: Update with the latest release of ADOT SDK for NodeJS + autoInstrumentationNodeJSImageRepository = "ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-nodejs" dcgmExporterImageRepository = "nvcr.io/nvidia/k8s/dcgm-exporter" neuronMonitorImageRepository = "public.ecr.aws/neuron" ) @@ -98,6 +100,7 @@ func main() { agentImage string autoInstrumentationJava string autoInstrumentationPython string + autoInstrumentationNodeJS string autoAnnotationConfigStr string webhookPort int tlsOpt tlsConfig @@ -111,14 +114,16 @@ func main() { stringFlagOrEnv(&agentImage, "agent-image", "RELATED_IMAGE_COLLECTOR", fmt.Sprintf("%s:%s", cloudwatchAgentImageRepository, v.AmazonCloudWatchAgent), "The default CloudWatch Agent image. This image is used when no image is specified in the CustomResource.") stringFlagOrEnv(&autoInstrumentationJava, "auto-instrumentation-java-image", "RELATED_IMAGE_AUTO_INSTRUMENTATION_JAVA", fmt.Sprintf("%s:%s", autoInstrumentationJavaImageRepository, v.AutoInstrumentationJava), "The default OpenTelemetry Java instrumentation image. This image is used when no image is specified in the CustomResource.") stringFlagOrEnv(&autoInstrumentationPython, "auto-instrumentation-python-image", "RELATED_IMAGE_AUTO_INSTRUMENTATION_PYTHON", fmt.Sprintf("%s:%s", autoInstrumentationPythonImageRepository, v.AutoInstrumentationPython), "The default OpenTelemetry Python instrumentation image. This image is used when no image is specified in the CustomResource.") + stringFlagOrEnv(&autoInstrumentationNodeJS, "auto-instrumentation-nodejs-image", "RELATED_IMAGE_AUTO_INSTRUMENTATION_NODEJS", fmt.Sprintf("%s:%s", autoInstrumentationNodeJSImageRepository, v.AutoInstrumentationNodeJS), "The default OpenTelemetry NodeJS instrumentation image. This image is used when no image is specified in the CustomResource.") stringFlagOrEnv(&autoAnnotationConfigStr, "auto-annotation-config", "AUTO_ANNOTATION_CONFIG", "", "The configuration for auto-annotation.") stringFlagOrEnv(&dcgmExporterImage, "dcgm-exporter-image", "RELATED_IMAGE_DCGM_EXPORTER", fmt.Sprintf("%s:%s", dcgmExporterImageRepository, v.DcgmExporter), "The default DCGM Exporter image. This image is used when no image is specified in the CustomResource.") stringFlagOrEnv(&neuronMonitorImage, "neuron-monitor-image", "RELATED_IMAGE_NEURON_MONITOR", fmt.Sprintf("%s:%s", neuronMonitorImageRepository, v.NeuronMonitor), "The default Neuron monitor image. This image is used when no image is specified in the CustomResource.") pflag.Parse() - // set java instrumentation java image in environment variable to be used for default instrumentation + // set supported languages instrumentation images in environment variable to be used for default instrumentation os.Setenv("AUTO_INSTRUMENTATION_JAVA", autoInstrumentationJava) os.Setenv("AUTO_INSTRUMENTATION_PYTHON", autoInstrumentationPython) + os.Setenv("AUTO_INSTRUMENTATION_NODEJS", autoInstrumentationNodeJS) logger := zap.New(zap.UseFlagOptions(&opts)) ctrl.SetLogger(logger) @@ -128,6 +133,7 @@ func main() { "cloudwatch-agent", agentImage, "auto-instrumentation-java", autoInstrumentationJava, "auto-instrumentation-python", autoInstrumentationPython, + "auto-instrumentation-nodejs", autoInstrumentationNodeJS, "dcgm-exporter", dcgmExporterImage, "neuron-monitor", neuronMonitorImage, "build-date", v.BuildDate, @@ -142,6 +148,7 @@ func main() { config.WithCollectorImage(agentImage), config.WithAutoInstrumentationJavaImage(autoInstrumentationJava), config.WithAutoInstrumentationPythonImage(autoInstrumentationPython), + config.WithAutoInstrumentationNodeJSImage(autoInstrumentationNodeJS), config.WithDcgmExporterImage(dcgmExporterImage), config.WithNeuronMonitorImage(neuronMonitorImage), ) @@ -238,6 +245,7 @@ func main() { instrumentation.NewTypeSet( instrumentation.TypeJava, instrumentation.TypePython, + instrumentation.TypeNodeJS, ), ) mgr.GetWebhookServer().Register("/mutate-v1-workload", &webhook.Admission{ diff --git a/pkg/instrumentation/auto/config.go b/pkg/instrumentation/auto/config.go index c6c4b46de..23d1e81ac 100644 --- a/pkg/instrumentation/auto/config.go +++ b/pkg/instrumentation/auto/config.go @@ -10,6 +10,7 @@ import "github.com/aws/amazon-cloudwatch-agent-operator/pkg/instrumentation" type AnnotationConfig struct { Java AnnotationResources `json:"java"` Python AnnotationResources `json:"python"` + NodeJS AnnotationResources `json:"nodejs"` } func (c AnnotationConfig) getResources(instType instrumentation.Type) AnnotationResources { @@ -18,6 +19,8 @@ func (c AnnotationConfig) getResources(instType instrumentation.Type) Annotation return c.Java case instrumentation.TypePython: return c.Python + case instrumentation.TypeNodeJS: + return c.NodeJS default: return AnnotationResources{} } diff --git a/pkg/instrumentation/auto/config_test.go b/pkg/instrumentation/auto/config_test.go index d6aa8187e..c5600f883 100644 --- a/pkg/instrumentation/auto/config_test.go +++ b/pkg/instrumentation/auto/config_test.go @@ -25,6 +25,12 @@ func TestConfig(t *testing.T) { DaemonSets: []string{"ds2"}, StatefulSets: []string{"ss2"}, }, + NodeJS: AnnotationResources{ + Namespaces: []string{"n3"}, + Deployments: []string{"d3"}, + DaemonSets: []string{"ds3"}, + StatefulSets: []string{"ss3"}, + }, } assert.Equal(t, cfg.Java, cfg.getResources(instrumentation.TypeJava)) assert.Equal(t, []string{"n1"}, getNamespaces(cfg.Java)) @@ -32,5 +38,8 @@ func TestConfig(t *testing.T) { assert.Equal(t, cfg.Python, cfg.getResources(instrumentation.TypePython)) assert.Equal(t, []string{"ds2"}, getDaemonSets(cfg.Python)) assert.Equal(t, []string{"ss2"}, getStatefulSets(cfg.Python)) + assert.Equal(t, cfg.Python, cfg.getResources(instrumentation.TypeNodeJS)) + assert.Equal(t, []string{"ds3"}, getDaemonSets(cfg.NodeJS)) + assert.Equal(t, []string{"ss3"}, getStatefulSets(cfg.NodeJS)) assert.Equal(t, AnnotationResources{}, cfg.getResources("invalidType")) } diff --git a/pkg/instrumentation/defaultinstrumentation.go b/pkg/instrumentation/defaultinstrumentation.go index ccd73ff6b..bbf1cbff6 100644 --- a/pkg/instrumentation/defaultinstrumentation.go +++ b/pkg/instrumentation/defaultinstrumentation.go @@ -15,10 +15,10 @@ import ( ) const ( - defaultAPIVersion = "cloudwatch.aws.amazon.com/v1alpha1" - defaultInstrumenation = "java-instrumentation" - defaultNamespace = "default" - defaultKind = "Instrumentation" + defaultAPIVersion = "cloudwatch.aws.amazon.com/v1alpha1" + defaultInstrumentation = "java-instrumentation" + defaultNamespace = "default" + defaultKind = "Instrumentation" httpPrefix = "http://" httpsPrefix = "https://" @@ -33,6 +33,10 @@ func getDefaultInstrumentation(agentConfig *adapters.CwaConfig) (*v1alpha1.Instr if !ok { return nil, errors.New("unable to determine python instrumentation image") } + nodeJSInstrumentationImage, ok := os.LookupEnv("AUTO_INSTRUMENTATION_NODEJS") + if !ok { + return nil, errors.New("unable to determine nodejs instrumentation image") + } // set protocol by checking cloudwatch agent config for tls setting exporterPrefix := httpPrefix @@ -50,7 +54,7 @@ func getDefaultInstrumentation(agentConfig *adapters.CwaConfig) (*v1alpha1.Instr Kind: defaultKind, }, ObjectMeta: metav1.ObjectMeta{ - Name: defaultInstrumenation, + Name: defaultInstrumentation, Namespace: defaultNamespace, }, Spec: v1alpha1.InstrumentationSpec{ @@ -92,6 +96,24 @@ func getDefaultInstrumentation(agentConfig *adapters.CwaConfig) (*v1alpha1.Instr {Name: "OTEL_LOGS_EXPORTER", Value: "none"}, }, }, + //TODO: temporary environment variables. Update with the latest values from the ADOT SDK for NodeJS + NodeJS: v1alpha1.NodeJS{ + Image: nodeJSInstrumentationImage, + Env: []corev1.EnvVar{ + {Name: "OTEL_AWS_APP_SIGNALS_ENABLED", Value: "true"}, //TODO: remove in favor of new name once safe + {Name: "OTEL_AWS_APPLICATION_SIGNALS_ENABLED", Value: "true"}, + {Name: "OTEL_TRACES_SAMPLER_ARG", Value: "endpoint=http://cloudwatch-agent.amazon-cloudwatch:2000"}, + {Name: "OTEL_TRACES_SAMPLER", Value: "xray"}, + {Name: "OTEL_EXPORTER_OTLP_PROTOCOL", Value: "http/protobuf"}, + {Name: "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", Value: exporterPrefix + "cloudwatch-agent.amazon-cloudwatch:4316/v1/traces"}, + {Name: "OTEL_AWS_APP_SIGNALS_EXPORTER_ENDPOINT", Value: exporterPrefix + "cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, //TODO: remove in favor of new name once safe + {Name: "OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT", Value: exporterPrefix + "cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, + {Name: "OTEL_METRICS_EXPORTER", Value: "none"}, + {Name: "OTEL_NODEJS_DISTRO", Value: "aws_distro"}, + {Name: "OTEL_NODEJS_CONFIGURATOR", Value: "aws_configurator"}, + {Name: "OTEL_LOGS_EXPORTER", Value: "none"}, + }, + }, }, }, nil } diff --git a/pkg/instrumentation/defaultinstrumentation_test.go b/pkg/instrumentation/defaultinstrumentation_test.go index a3fe0b807..5d8de7470 100644 --- a/pkg/instrumentation/defaultinstrumentation_test.go +++ b/pkg/instrumentation/defaultinstrumentation_test.go @@ -18,6 +18,7 @@ import ( func Test_getDefaultInstrumentation(t *testing.T) { os.Setenv("AUTO_INSTRUMENTATION_JAVA", defaultJavaInstrumentationImage) os.Setenv("AUTO_INSTRUMENTATION_PYTHON", defaultPythonInstrumentationImage) + os.Setenv("AUTO_INSTRUMENTATION_NODEJS", defaultNodeJSInstrumentationImage) httpInst := &v1alpha1.Instrumentation{ Status: v1alpha1.InstrumentationStatus{}, @@ -26,7 +27,7 @@ func Test_getDefaultInstrumentation(t *testing.T) { Kind: defaultKind, }, ObjectMeta: metav1.ObjectMeta{ - Name: defaultInstrumenation, + Name: defaultInstrumentation, Namespace: defaultNamespace, }, Spec: v1alpha1.InstrumentationSpec{ @@ -68,6 +69,24 @@ func Test_getDefaultInstrumentation(t *testing.T) { {Name: "OTEL_LOGS_EXPORTER", Value: "none"}, }, }, + //TODO: temporary environment variables. Update with the latest values from the ADOT SDK for NodeJS + NodeJS: v1alpha1.NodeJS{ + Image: defaultNodeJSInstrumentationImage, + Env: []corev1.EnvVar{ + {Name: "OTEL_AWS_APP_SIGNALS_ENABLED", Value: "true"}, //TODO: remove in favor of new name once safe + {Name: "OTEL_AWS_APPLICATION_SIGNALS_ENABLED", Value: "true"}, + {Name: "OTEL_TRACES_SAMPLER_ARG", Value: "endpoint=http://cloudwatch-agent.amazon-cloudwatch:2000"}, + {Name: "OTEL_TRACES_SAMPLER", Value: "xray"}, + {Name: "OTEL_EXPORTER_OTLP_PROTOCOL", Value: "http/protobuf"}, + {Name: "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", Value: "http://cloudwatch-agent.amazon-cloudwatch:4316/v1/traces"}, + {Name: "OTEL_AWS_APP_SIGNALS_EXPORTER_ENDPOINT", Value: "http://cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, //TODO: remove in favor of new name once safe + {Name: "OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT", Value: "http://cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, + {Name: "OTEL_METRICS_EXPORTER", Value: "none"}, + {Name: "OTEL_NODEJS_DISTRO", Value: "aws_distro"}, + {Name: "OTEL_NODEJS_CONFIGURATOR", Value: "aws_configurator"}, + {Name: "OTEL_LOGS_EXPORTER", Value: "none"}, + }, + }, }, } httpsInst := &v1alpha1.Instrumentation{ @@ -77,7 +96,7 @@ func Test_getDefaultInstrumentation(t *testing.T) { Kind: defaultKind, }, ObjectMeta: metav1.ObjectMeta{ - Name: defaultInstrumenation, + Name: defaultInstrumentation, Namespace: defaultNamespace, }, Spec: v1alpha1.InstrumentationSpec{ @@ -119,6 +138,24 @@ func Test_getDefaultInstrumentation(t *testing.T) { {Name: "OTEL_LOGS_EXPORTER", Value: "none"}, }, }, + //TODO: temporary environment variables. Update with the latest values from the ADOT SDK for NodeJS + NodeJS: v1alpha1.NodeJS{ + Image: defaultNodeJSInstrumentationImage, + Env: []corev1.EnvVar{ + {Name: "OTEL_AWS_APP_SIGNALS_ENABLED", Value: "true"}, //TODO: remove in favor of new name once safe + {Name: "OTEL_AWS_APPLICATION_SIGNALS_ENABLED", Value: "true"}, + {Name: "OTEL_TRACES_SAMPLER_ARG", Value: "endpoint=http://cloudwatch-agent.amazon-cloudwatch:2000"}, + {Name: "OTEL_TRACES_SAMPLER", Value: "xray"}, + {Name: "OTEL_EXPORTER_OTLP_PROTOCOL", Value: "http/protobuf"}, + {Name: "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", Value: "https://cloudwatch-agent.amazon-cloudwatch:4316/v1/traces"}, + {Name: "OTEL_AWS_APP_SIGNALS_EXPORTER_ENDPOINT", Value: "https://cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, //TODO: remove in favor of new name once safe + {Name: "OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT", Value: "https://cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, + {Name: "OTEL_METRICS_EXPORTER", Value: "none"}, + {Name: "OTEL_NODEJS_DISTRO", Value: "aws_distro"}, + {Name: "OTEL_NODEJS_CONFIGURATOR", Value: "aws_configurator"}, + {Name: "OTEL_LOGS_EXPORTER", Value: "none"}, + }, + }, }, } diff --git a/pkg/instrumentation/podmutator_test.go b/pkg/instrumentation/podmutator_test.go index d2070f62c..5dc88cd79 100644 --- a/pkg/instrumentation/podmutator_test.go +++ b/pkg/instrumentation/podmutator_test.go @@ -25,11 +25,13 @@ import ( const ( defaultJavaInstrumentationImage = "test.registry/adot-autoinstrumentation-java:test-tag" defaultPythonInstrumentationImage = "test.registry/adot-autoinstrumentation-python:test-tag" + defaultNodeJSInstrumentationImage = "test.registry/adot-autoinstrumentation-nodejs:test-tag" ) func TestGetInstrumentationInstanceFromNameSpaceDefault(t *testing.T) { os.Setenv("AUTO_INSTRUMENTATION_JAVA", defaultJavaInstrumentationImage) os.Setenv("AUTO_INSTRUMENTATION_PYTHON", defaultPythonInstrumentationImage) + os.Setenv("AUTO_INSTRUMENTATION_NODEJS", defaultNodeJSInstrumentationImage) defaultInst := &v1alpha1.Instrumentation{ Status: v1alpha1.InstrumentationStatus{}, @@ -38,7 +40,7 @@ func TestGetInstrumentationInstanceFromNameSpaceDefault(t *testing.T) { Kind: defaultKind, }, ObjectMeta: metav1.ObjectMeta{ - Name: defaultInstrumenation, + Name: defaultInstrumentation, Namespace: defaultNamespace, }, Spec: v1alpha1.InstrumentationSpec{ @@ -80,6 +82,24 @@ func TestGetInstrumentationInstanceFromNameSpaceDefault(t *testing.T) { {Name: "OTEL_LOGS_EXPORTER", Value: "none"}, }, }, + //TODO: temporary environment variables. Update with the latest values from the ADOT SDK for NodeJS + NodeJS: v1alpha1.NodeJS{ + Image: defaultNodeJSInstrumentationImage, + Env: []corev1.EnvVar{ + {Name: "OTEL_AWS_APP_SIGNALS_ENABLED", Value: "true"}, //TODO: remove in favor of new name once safe + {Name: "OTEL_AWS_APPLICATION_SIGNALS_ENABLED", Value: "true"}, + {Name: "OTEL_TRACES_SAMPLER_ARG", Value: "endpoint=http://cloudwatch-agent.amazon-cloudwatch:2000"}, + {Name: "OTEL_TRACES_SAMPLER", Value: "xray"}, + {Name: "OTEL_EXPORTER_OTLP_PROTOCOL", Value: "http/protobuf"}, + {Name: "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", Value: "http://cloudwatch-agent.amazon-cloudwatch:4316/v1/traces"}, + {Name: "OTEL_AWS_APP_SIGNALS_EXPORTER_ENDPOINT", Value: "http://cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, //TODO: remove in favor of new name once safe + {Name: "OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT", Value: "http://cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, + {Name: "OTEL_METRICS_EXPORTER", Value: "none"}, + {Name: "OTEL_NODEJS_DISTRO", Value: "aws_distro"}, + {Name: "OTEL_NODEJS_CONFIGURATOR", Value: "aws_configurator"}, + {Name: "OTEL_LOGS_EXPORTER", Value: "none"}, + }, + }, }, } namespace := corev1.Namespace{ diff --git a/versions.txt b/versions.txt index 07a1cd739..392076b5d 100644 --- a/versions.txt +++ b/versions.txt @@ -7,6 +7,8 @@ operator=1.4.1 # Represents the current release of ADOT language instrumentation. aws-otel-java-instrumentation=v1.32.2 aws-otel-python-instrumentation=v0.2.0 +# TODO - Update with the latest release of ADOT SDK +aws-otel-nodejs-instrumentation=0.51.0 dcgm-exporter=3.3.3-3.3.1-ubuntu22.04 neuron-monitor=1.0.0 \ No newline at end of file From 0483af675d0a273d1579b7f1eff4143b146c6b08 Mon Sep 17 00:00:00 2001 From: Paramadon Date: Thu, 22 Aug 2024 09:57:36 -0400 Subject: [PATCH 2/7] adding nodejs-instrumentation --- main.go | 2 +- pkg/instrumentation/defaultinstrumentation.go | 2 -- pkg/instrumentation/defaultinstrumentation_test.go | 4 ---- pkg/instrumentation/podmutator_test.go | 2 -- versions.txt | 2 +- 5 files changed, 2 insertions(+), 10 deletions(-) diff --git a/main.go b/main.go index bc3a6700f..2b8d06c12 100644 --- a/main.go +++ b/main.go @@ -49,7 +49,7 @@ const ( autoInstrumentationJavaImageRepository = "public.ecr.aws/aws-observability/adot-autoinstrumentation-java" autoInstrumentationPythonImageRepository = "public.ecr.aws/aws-observability/adot-autoinstrumentation-python" //TODO: Update with the latest release of ADOT SDK for NodeJS - autoInstrumentationNodeJSImageRepository = "ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-nodejs" + autoInstrumentationNodeJSImageRepository = "637423224110.dkr.ecr.us-east-1.amazonaws.com/aws-observability/adot-autoinstrumentation-node-staging" dcgmExporterImageRepository = "nvcr.io/nvidia/k8s/dcgm-exporter" neuronMonitorImageRepository = "public.ecr.aws/neuron" ) diff --git a/pkg/instrumentation/defaultinstrumentation.go b/pkg/instrumentation/defaultinstrumentation.go index bbf1cbff6..a511c2d1b 100644 --- a/pkg/instrumentation/defaultinstrumentation.go +++ b/pkg/instrumentation/defaultinstrumentation.go @@ -109,8 +109,6 @@ func getDefaultInstrumentation(agentConfig *adapters.CwaConfig) (*v1alpha1.Instr {Name: "OTEL_AWS_APP_SIGNALS_EXPORTER_ENDPOINT", Value: exporterPrefix + "cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, //TODO: remove in favor of new name once safe {Name: "OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT", Value: exporterPrefix + "cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, {Name: "OTEL_METRICS_EXPORTER", Value: "none"}, - {Name: "OTEL_NODEJS_DISTRO", Value: "aws_distro"}, - {Name: "OTEL_NODEJS_CONFIGURATOR", Value: "aws_configurator"}, {Name: "OTEL_LOGS_EXPORTER", Value: "none"}, }, }, diff --git a/pkg/instrumentation/defaultinstrumentation_test.go b/pkg/instrumentation/defaultinstrumentation_test.go index 5d8de7470..9c5f39380 100644 --- a/pkg/instrumentation/defaultinstrumentation_test.go +++ b/pkg/instrumentation/defaultinstrumentation_test.go @@ -82,8 +82,6 @@ func Test_getDefaultInstrumentation(t *testing.T) { {Name: "OTEL_AWS_APP_SIGNALS_EXPORTER_ENDPOINT", Value: "http://cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, //TODO: remove in favor of new name once safe {Name: "OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT", Value: "http://cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, {Name: "OTEL_METRICS_EXPORTER", Value: "none"}, - {Name: "OTEL_NODEJS_DISTRO", Value: "aws_distro"}, - {Name: "OTEL_NODEJS_CONFIGURATOR", Value: "aws_configurator"}, {Name: "OTEL_LOGS_EXPORTER", Value: "none"}, }, }, @@ -151,8 +149,6 @@ func Test_getDefaultInstrumentation(t *testing.T) { {Name: "OTEL_AWS_APP_SIGNALS_EXPORTER_ENDPOINT", Value: "https://cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, //TODO: remove in favor of new name once safe {Name: "OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT", Value: "https://cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, {Name: "OTEL_METRICS_EXPORTER", Value: "none"}, - {Name: "OTEL_NODEJS_DISTRO", Value: "aws_distro"}, - {Name: "OTEL_NODEJS_CONFIGURATOR", Value: "aws_configurator"}, {Name: "OTEL_LOGS_EXPORTER", Value: "none"}, }, }, diff --git a/pkg/instrumentation/podmutator_test.go b/pkg/instrumentation/podmutator_test.go index 5dc88cd79..b066edd1b 100644 --- a/pkg/instrumentation/podmutator_test.go +++ b/pkg/instrumentation/podmutator_test.go @@ -95,8 +95,6 @@ func TestGetInstrumentationInstanceFromNameSpaceDefault(t *testing.T) { {Name: "OTEL_AWS_APP_SIGNALS_EXPORTER_ENDPOINT", Value: "http://cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, //TODO: remove in favor of new name once safe {Name: "OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT", Value: "http://cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, {Name: "OTEL_METRICS_EXPORTER", Value: "none"}, - {Name: "OTEL_NODEJS_DISTRO", Value: "aws_distro"}, - {Name: "OTEL_NODEJS_CONFIGURATOR", Value: "aws_configurator"}, {Name: "OTEL_LOGS_EXPORTER", Value: "none"}, }, }, diff --git a/versions.txt b/versions.txt index 392076b5d..c5fd064c4 100644 --- a/versions.txt +++ b/versions.txt @@ -8,7 +8,7 @@ operator=1.4.1 aws-otel-java-instrumentation=v1.32.2 aws-otel-python-instrumentation=v0.2.0 # TODO - Update with the latest release of ADOT SDK -aws-otel-nodejs-instrumentation=0.51.0 +aws-otel-nodejs-instrumentation=latest dcgm-exporter=3.3.3-3.3.1-ubuntu22.04 neuron-monitor=1.0.0 \ No newline at end of file From fcd2242d49d599a2aeed300b4086de90422b8e8f Mon Sep 17 00:00:00 2001 From: Paramadon Date: Thu, 22 Aug 2024 12:43:00 -0400 Subject: [PATCH 3/7] removing unnecessary env vars --- pkg/instrumentation/defaultinstrumentation.go | 2 -- pkg/instrumentation/defaultinstrumentation_test.go | 6 ------ pkg/instrumentation/podmutator_test.go | 2 -- 3 files changed, 10 deletions(-) diff --git a/pkg/instrumentation/defaultinstrumentation.go b/pkg/instrumentation/defaultinstrumentation.go index a511c2d1b..e5f591879 100644 --- a/pkg/instrumentation/defaultinstrumentation.go +++ b/pkg/instrumentation/defaultinstrumentation.go @@ -100,13 +100,11 @@ func getDefaultInstrumentation(agentConfig *adapters.CwaConfig) (*v1alpha1.Instr NodeJS: v1alpha1.NodeJS{ Image: nodeJSInstrumentationImage, Env: []corev1.EnvVar{ - {Name: "OTEL_AWS_APP_SIGNALS_ENABLED", Value: "true"}, //TODO: remove in favor of new name once safe {Name: "OTEL_AWS_APPLICATION_SIGNALS_ENABLED", Value: "true"}, {Name: "OTEL_TRACES_SAMPLER_ARG", Value: "endpoint=http://cloudwatch-agent.amazon-cloudwatch:2000"}, {Name: "OTEL_TRACES_SAMPLER", Value: "xray"}, {Name: "OTEL_EXPORTER_OTLP_PROTOCOL", Value: "http/protobuf"}, {Name: "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", Value: exporterPrefix + "cloudwatch-agent.amazon-cloudwatch:4316/v1/traces"}, - {Name: "OTEL_AWS_APP_SIGNALS_EXPORTER_ENDPOINT", Value: exporterPrefix + "cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, //TODO: remove in favor of new name once safe {Name: "OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT", Value: exporterPrefix + "cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, {Name: "OTEL_METRICS_EXPORTER", Value: "none"}, {Name: "OTEL_LOGS_EXPORTER", Value: "none"}, diff --git a/pkg/instrumentation/defaultinstrumentation_test.go b/pkg/instrumentation/defaultinstrumentation_test.go index 9c5f39380..f732bdcb1 100644 --- a/pkg/instrumentation/defaultinstrumentation_test.go +++ b/pkg/instrumentation/defaultinstrumentation_test.go @@ -40,7 +40,6 @@ func Test_getDefaultInstrumentation(t *testing.T) { Java: v1alpha1.Java{ Image: defaultJavaInstrumentationImage, Env: []corev1.EnvVar{ - {Name: "OTEL_AWS_APP_SIGNALS_ENABLED", Value: "true"}, //TODO: remove in favor of new name once safe {Name: "OTEL_AWS_APPLICATION_SIGNALS_ENABLED", Value: "true"}, {Name: "OTEL_TRACES_SAMPLER_ARG", Value: "endpoint=http://cloudwatch-agent.amazon-cloudwatch:2000"}, {Name: "OTEL_TRACES_SAMPLER", Value: "xray"}, @@ -55,7 +54,6 @@ func Test_getDefaultInstrumentation(t *testing.T) { Python: v1alpha1.Python{ Image: defaultPythonInstrumentationImage, Env: []corev1.EnvVar{ - {Name: "OTEL_AWS_APP_SIGNALS_ENABLED", Value: "true"}, //TODO: remove in favor of new name once safe {Name: "OTEL_AWS_APPLICATION_SIGNALS_ENABLED", Value: "true"}, {Name: "OTEL_TRACES_SAMPLER_ARG", Value: "endpoint=http://cloudwatch-agent.amazon-cloudwatch:2000"}, {Name: "OTEL_TRACES_SAMPLER", Value: "xray"}, @@ -73,13 +71,11 @@ func Test_getDefaultInstrumentation(t *testing.T) { NodeJS: v1alpha1.NodeJS{ Image: defaultNodeJSInstrumentationImage, Env: []corev1.EnvVar{ - {Name: "OTEL_AWS_APP_SIGNALS_ENABLED", Value: "true"}, //TODO: remove in favor of new name once safe {Name: "OTEL_AWS_APPLICATION_SIGNALS_ENABLED", Value: "true"}, {Name: "OTEL_TRACES_SAMPLER_ARG", Value: "endpoint=http://cloudwatch-agent.amazon-cloudwatch:2000"}, {Name: "OTEL_TRACES_SAMPLER", Value: "xray"}, {Name: "OTEL_EXPORTER_OTLP_PROTOCOL", Value: "http/protobuf"}, {Name: "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", Value: "http://cloudwatch-agent.amazon-cloudwatch:4316/v1/traces"}, - {Name: "OTEL_AWS_APP_SIGNALS_EXPORTER_ENDPOINT", Value: "http://cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, //TODO: remove in favor of new name once safe {Name: "OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT", Value: "http://cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, {Name: "OTEL_METRICS_EXPORTER", Value: "none"}, {Name: "OTEL_LOGS_EXPORTER", Value: "none"}, @@ -140,13 +136,11 @@ func Test_getDefaultInstrumentation(t *testing.T) { NodeJS: v1alpha1.NodeJS{ Image: defaultNodeJSInstrumentationImage, Env: []corev1.EnvVar{ - {Name: "OTEL_AWS_APP_SIGNALS_ENABLED", Value: "true"}, //TODO: remove in favor of new name once safe {Name: "OTEL_AWS_APPLICATION_SIGNALS_ENABLED", Value: "true"}, {Name: "OTEL_TRACES_SAMPLER_ARG", Value: "endpoint=http://cloudwatch-agent.amazon-cloudwatch:2000"}, {Name: "OTEL_TRACES_SAMPLER", Value: "xray"}, {Name: "OTEL_EXPORTER_OTLP_PROTOCOL", Value: "http/protobuf"}, {Name: "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", Value: "https://cloudwatch-agent.amazon-cloudwatch:4316/v1/traces"}, - {Name: "OTEL_AWS_APP_SIGNALS_EXPORTER_ENDPOINT", Value: "https://cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, //TODO: remove in favor of new name once safe {Name: "OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT", Value: "https://cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, {Name: "OTEL_METRICS_EXPORTER", Value: "none"}, {Name: "OTEL_LOGS_EXPORTER", Value: "none"}, diff --git a/pkg/instrumentation/podmutator_test.go b/pkg/instrumentation/podmutator_test.go index b066edd1b..95f458f29 100644 --- a/pkg/instrumentation/podmutator_test.go +++ b/pkg/instrumentation/podmutator_test.go @@ -86,13 +86,11 @@ func TestGetInstrumentationInstanceFromNameSpaceDefault(t *testing.T) { NodeJS: v1alpha1.NodeJS{ Image: defaultNodeJSInstrumentationImage, Env: []corev1.EnvVar{ - {Name: "OTEL_AWS_APP_SIGNALS_ENABLED", Value: "true"}, //TODO: remove in favor of new name once safe {Name: "OTEL_AWS_APPLICATION_SIGNALS_ENABLED", Value: "true"}, {Name: "OTEL_TRACES_SAMPLER_ARG", Value: "endpoint=http://cloudwatch-agent.amazon-cloudwatch:2000"}, {Name: "OTEL_TRACES_SAMPLER", Value: "xray"}, {Name: "OTEL_EXPORTER_OTLP_PROTOCOL", Value: "http/protobuf"}, {Name: "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", Value: "http://cloudwatch-agent.amazon-cloudwatch:4316/v1/traces"}, - {Name: "OTEL_AWS_APP_SIGNALS_EXPORTER_ENDPOINT", Value: "http://cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, //TODO: remove in favor of new name once safe {Name: "OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT", Value: "http://cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, {Name: "OTEL_METRICS_EXPORTER", Value: "none"}, {Name: "OTEL_LOGS_EXPORTER", Value: "none"}, From 603c358db520f30c9ac18917946b0111c1edadbe Mon Sep 17 00:00:00 2001 From: Paramadon Date: Thu, 22 Aug 2024 13:21:16 -0400 Subject: [PATCH 4/7] fixing merge conflicts --- pkg/instrumentation/auto/config.go | 6 ------ pkg/instrumentation/auto/config_test.go | 12 ++++++------ pkg/instrumentation/defaultinstrumentation.go | 4 +--- pkg/instrumentation/defaultinstrumentation_test.go | 5 +---- pkg/instrumentation/podmutator_test.go | 13 +------------ 5 files changed, 9 insertions(+), 31 deletions(-) diff --git a/pkg/instrumentation/auto/config.go b/pkg/instrumentation/auto/config.go index d455b3bb7..eaf371a7b 100644 --- a/pkg/instrumentation/auto/config.go +++ b/pkg/instrumentation/auto/config.go @@ -10,11 +10,8 @@ import "github.com/aws/amazon-cloudwatch-agent-operator/pkg/instrumentation" type AnnotationConfig struct { Java AnnotationResources `json:"java"` Python AnnotationResources `json:"python"` -<<<<<<< HEAD NodeJS AnnotationResources `json:"nodejs"` -======= DotNet AnnotationResources `json:"dotnet"` ->>>>>>> 099460aea6622b73557017a14b5c46e1b10de680 } func (c AnnotationConfig) getResources(instType instrumentation.Type) AnnotationResources { @@ -23,13 +20,10 @@ func (c AnnotationConfig) getResources(instType instrumentation.Type) Annotation return c.Java case instrumentation.TypePython: return c.Python -<<<<<<< HEAD case instrumentation.TypeNodeJS: return c.NodeJS -======= case instrumentation.TypeDotNet: return c.DotNet ->>>>>>> 099460aea6622b73557017a14b5c46e1b10de680 default: return AnnotationResources{} } diff --git a/pkg/instrumentation/auto/config_test.go b/pkg/instrumentation/auto/config_test.go index edb73ab03..3c183d19f 100644 --- a/pkg/instrumentation/auto/config_test.go +++ b/pkg/instrumentation/auto/config_test.go @@ -25,31 +25,31 @@ func TestConfig(t *testing.T) { DaemonSets: []string{"ds2"}, StatefulSets: []string{"ss2"}, }, -<<<<<<< HEAD NodeJS: AnnotationResources{ -======= + Namespaces: []string{"n3"}, + Deployments: []string{"d3"}, + DaemonSets: []string{"ds3"}, + StatefulSets: []string{"ss3"}, + }, DotNet: AnnotationResources{ ->>>>>>> 099460aea6622b73557017a14b5c46e1b10de680 Namespaces: []string{"n3"}, Deployments: []string{"d3"}, DaemonSets: []string{"ds3"}, StatefulSets: []string{"ss3"}, }, } + assert.Equal(t, cfg.Java, cfg.getResources(instrumentation.TypeJava)) assert.Equal(t, []string{"n1"}, getNamespaces(cfg.Java)) assert.Equal(t, []string{"d1"}, getDeployments(cfg.Java)) assert.Equal(t, cfg.Python, cfg.getResources(instrumentation.TypePython)) assert.Equal(t, []string{"ds2"}, getDaemonSets(cfg.Python)) assert.Equal(t, []string{"ss2"}, getStatefulSets(cfg.Python)) -<<<<<<< HEAD assert.Equal(t, cfg.Python, cfg.getResources(instrumentation.TypeNodeJS)) assert.Equal(t, []string{"ds3"}, getDaemonSets(cfg.NodeJS)) assert.Equal(t, []string{"ss3"}, getStatefulSets(cfg.NodeJS)) -======= assert.Equal(t, cfg.DotNet, cfg.getResources(instrumentation.TypeDotNet)) assert.Equal(t, []string{"ds3"}, getDaemonSets(cfg.DotNet)) assert.Equal(t, []string{"ss3"}, getStatefulSets(cfg.DotNet)) ->>>>>>> 099460aea6622b73557017a14b5c46e1b10de680 assert.Equal(t, AnnotationResources{}, cfg.getResources("invalidType")) } diff --git a/pkg/instrumentation/defaultinstrumentation.go b/pkg/instrumentation/defaultinstrumentation.go index 0b7d9b8c0..5f56b3bb3 100644 --- a/pkg/instrumentation/defaultinstrumentation.go +++ b/pkg/instrumentation/defaultinstrumentation.go @@ -58,11 +58,10 @@ func getDefaultInstrumentation(agentConfig *adapters.CwaConfig, isWindowsPod boo if !ok { return nil, errors.New("unable to determine python instrumentation image") } -<<<<<<< HEAD nodeJSInstrumentationImage, ok := os.LookupEnv("AUTO_INSTRUMENTATION_NODEJS") if !ok { return nil, errors.New("unable to determine nodejs instrumentation image") -======= + } dotNetInstrumentationImage, ok := os.LookupEnv("AUTO_INSTRUMENTATION_DOTNET") if !ok { return nil, errors.New("unable to determine dotnet instrumentation image") @@ -73,7 +72,6 @@ func getDefaultInstrumentation(agentConfig *adapters.CwaConfig, isWindowsPod boo // Windows pods use the headless service endpoint due to limitations with the agent on host network mode // https://kubernetes.io/docs/concepts/services-networking/windows-networking/#limitations cloudwatchAgentServiceEndpoint = "cloudwatch-agent-windows-headless.amazon-cloudwatch.svc.cluster.local" ->>>>>>> 099460aea6622b73557017a14b5c46e1b10de680 } // set protocol by checking cloudwatch agent config for tls setting diff --git a/pkg/instrumentation/defaultinstrumentation_test.go b/pkg/instrumentation/defaultinstrumentation_test.go index eeb65481b..5f8bebf58 100644 --- a/pkg/instrumentation/defaultinstrumentation_test.go +++ b/pkg/instrumentation/defaultinstrumentation_test.go @@ -20,9 +20,7 @@ import ( func Test_getDefaultInstrumentationLinux(t *testing.T) { os.Setenv("AUTO_INSTRUMENTATION_JAVA", defaultJavaInstrumentationImage) os.Setenv("AUTO_INSTRUMENTATION_PYTHON", defaultPythonInstrumentationImage) -<<<<<<< HEAD os.Setenv("AUTO_INSTRUMENTATION_NODEJS", defaultNodeJSInstrumentationImage) -======= os.Setenv("AUTO_INSTRUMENTATION_DOTNET", defaultDotNetInstrumentationImage) os.Setenv("AUTO_INSTRUMENTATION_JAVA_CPU_LIMIT", "500m") os.Setenv("AUTO_INSTRUMENTATION_JAVA_MEM_LIMIT", "64Mi") @@ -36,7 +34,6 @@ func Test_getDefaultInstrumentationLinux(t *testing.T) { os.Setenv("AUTO_INSTRUMENTATION_DOTNET_MEM_LIMIT", "128Mi") os.Setenv("AUTO_INSTRUMENTATION_DOTNET_CPU_REQUEST", "50m") os.Setenv("AUTO_INSTRUMENTATION_DOTNET_MEM_REQUEST", "128Mi") ->>>>>>> 099460aea6622b73557017a14b5c46e1b10de680 httpInst := &v1alpha1.Instrumentation{ Status: v1alpha1.InstrumentationStatus{}, @@ -342,7 +339,7 @@ func Test_getDefaultInstrumentationWindows(t *testing.T) { Kind: defaultKind, }, ObjectMeta: metav1.ObjectMeta{ - Name: defaultInstrumenation, + Name: defaultInstrumentation, Namespace: defaultNamespace, }, Spec: v1alpha1.InstrumentationSpec{ diff --git a/pkg/instrumentation/podmutator_test.go b/pkg/instrumentation/podmutator_test.go index c0512e384..8e7ab1c45 100644 --- a/pkg/instrumentation/podmutator_test.go +++ b/pkg/instrumentation/podmutator_test.go @@ -19,15 +19,14 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/fake" "github.com/aws/amazon-cloudwatch-agent-operator/apis/v1alpha1" - "github.com/aws/amazon-cloudwatch-agent-operator/internal/manifests/collector/adapters" "github.com/aws/amazon-cloudwatch-agent-operator/pkg/featuregate" ) const ( defaultJavaInstrumentationImage = "test.registry/adot-autoinstrumentation-java:test-tag" defaultPythonInstrumentationImage = "test.registry/adot-autoinstrumentation-python:test-tag" -<<<<<<< HEAD defaultNodeJSInstrumentationImage = "test.registry/adot-autoinstrumentation-nodejs:test-tag" + defaultDotNetInstrumentationImage = "test.registry/adot-autoinstrumentation-dotnet:test-tag" ) func TestGetInstrumentationInstanceFromNameSpaceDefault(t *testing.T) { @@ -84,7 +83,6 @@ func TestGetInstrumentationInstanceFromNameSpaceDefault(t *testing.T) { {Name: "OTEL_LOGS_EXPORTER", Value: "none"}, }, }, - //TODO: temporary environment variables. Update with the latest values from the ADOT SDK for NodeJS NodeJS: v1alpha1.NodeJS{ Image: defaultNodeJSInstrumentationImage, Env: []corev1.EnvVar{ @@ -100,14 +98,6 @@ func TestGetInstrumentationInstanceFromNameSpaceDefault(t *testing.T) { }, }, } -======= - defaultDotNetInstrumentationImage = "test.registry/adot-autoinstrumentation-dotnet:test-tag" -) - -func TestGetInstrumentationInstanceFromNameSpaceDefault(t *testing.T) { - defaultInst, _ := getDefaultInstrumentation(&adapters.CwaConfig{}, false) - ->>>>>>> 099460aea6622b73557017a14b5c46e1b10de680 namespace := corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: "default-namespace", @@ -125,7 +115,6 @@ func TestGetInstrumentationInstanceFromNameSpaceDefault(t *testing.T) { assert.Nil(t, err) assert.Equal(t, defaultInst, instrumentation) - } func TestMutatePod(t *testing.T) { From fd36a9075ee28f5d0d35f75a1e8fca209d562580 Mon Sep 17 00:00:00 2001 From: Paramadon Date: Thu, 22 Aug 2024 13:31:37 -0400 Subject: [PATCH 5/7] fixing merge conflict tests --- .../defaultinstrumentation_test.go | 4 +- pkg/instrumentation/podmutator_test.go | 66 +------------------ 2 files changed, 5 insertions(+), 65 deletions(-) diff --git a/pkg/instrumentation/defaultinstrumentation_test.go b/pkg/instrumentation/defaultinstrumentation_test.go index 5f8bebf58..3e51814ca 100644 --- a/pkg/instrumentation/defaultinstrumentation_test.go +++ b/pkg/instrumentation/defaultinstrumentation_test.go @@ -55,6 +55,7 @@ func Test_getDefaultInstrumentationLinux(t *testing.T) { Java: v1alpha1.Java{ Image: defaultJavaInstrumentationImage, Env: []corev1.EnvVar{ + {Name: "OTEL_AWS_APP_SIGNALS_ENABLED", Value: "true"}, //TODO: remove in favor of new name once safe {Name: "OTEL_AWS_APPLICATION_SIGNALS_ENABLED", Value: "true"}, {Name: "OTEL_TRACES_SAMPLER_ARG", Value: "endpoint=http://cloudwatch-agent.amazon-cloudwatch:2000"}, {Name: "OTEL_TRACES_SAMPLER", Value: "xray"}, @@ -79,6 +80,7 @@ func Test_getDefaultInstrumentationLinux(t *testing.T) { Python: v1alpha1.Python{ Image: defaultPythonInstrumentationImage, Env: []corev1.EnvVar{ + {Name: "OTEL_AWS_APP_SIGNALS_ENABLED", Value: "true"}, //TODO: remove in favor of new name once safe {Name: "OTEL_AWS_APPLICATION_SIGNALS_ENABLED", Value: "true"}, {Name: "OTEL_TRACES_SAMPLER_ARG", Value: "endpoint=http://cloudwatch-agent.amazon-cloudwatch:2000"}, {Name: "OTEL_TRACES_SAMPLER", Value: "xray"}, @@ -437,7 +439,7 @@ func Test_getDefaultInstrumentationWindows(t *testing.T) { Kind: defaultKind, }, ObjectMeta: metav1.ObjectMeta{ - Name: defaultInstrumenation, + Name: defaultInstrumentation, Namespace: defaultNamespace, }, Spec: v1alpha1.InstrumentationSpec{ diff --git a/pkg/instrumentation/podmutator_test.go b/pkg/instrumentation/podmutator_test.go index 8e7ab1c45..d22a28175 100644 --- a/pkg/instrumentation/podmutator_test.go +++ b/pkg/instrumentation/podmutator_test.go @@ -6,6 +6,7 @@ package instrumentation import ( "context" "fmt" + "github.com/aws/amazon-cloudwatch-agent-operator/internal/manifests/collector/adapters" "os" "testing" @@ -34,70 +35,7 @@ func TestGetInstrumentationInstanceFromNameSpaceDefault(t *testing.T) { os.Setenv("AUTO_INSTRUMENTATION_PYTHON", defaultPythonInstrumentationImage) os.Setenv("AUTO_INSTRUMENTATION_NODEJS", defaultNodeJSInstrumentationImage) - defaultInst := &v1alpha1.Instrumentation{ - Status: v1alpha1.InstrumentationStatus{}, - TypeMeta: metav1.TypeMeta{ - APIVersion: defaultAPIVersion, - Kind: defaultKind, - }, - ObjectMeta: metav1.ObjectMeta{ - Name: defaultInstrumentation, - Namespace: defaultNamespace, - }, - Spec: v1alpha1.InstrumentationSpec{ - Propagators: []v1alpha1.Propagator{ - v1alpha1.TraceContext, - v1alpha1.Baggage, - v1alpha1.B3, - v1alpha1.XRay, - }, - Java: v1alpha1.Java{ - Image: defaultJavaInstrumentationImage, - Env: []corev1.EnvVar{ - {Name: "OTEL_AWS_APP_SIGNALS_ENABLED", Value: "true"}, //TODO: remove in favor of new name once safe - {Name: "OTEL_AWS_APPLICATION_SIGNALS_ENABLED", Value: "true"}, - {Name: "OTEL_TRACES_SAMPLER_ARG", Value: "endpoint=http://cloudwatch-agent.amazon-cloudwatch:2000"}, - {Name: "OTEL_TRACES_SAMPLER", Value: "xray"}, - {Name: "OTEL_EXPORTER_OTLP_PROTOCOL", Value: "http/protobuf"}, - {Name: "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", Value: "http://cloudwatch-agent.amazon-cloudwatch:4316/v1/traces"}, - {Name: "OTEL_AWS_APP_SIGNALS_EXPORTER_ENDPOINT", Value: "http://cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, //TODO: remove in favor of new name once safe - {Name: "OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT", Value: "http://cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, - {Name: "OTEL_METRICS_EXPORTER", Value: "none"}, - {Name: "OTEL_LOGS_EXPORTER", Value: "none"}, - }, - }, - Python: v1alpha1.Python{ - Image: defaultPythonInstrumentationImage, - Env: []corev1.EnvVar{ - {Name: "OTEL_AWS_APP_SIGNALS_ENABLED", Value: "true"}, //TODO: remove in favor of new name once safe - {Name: "OTEL_AWS_APPLICATION_SIGNALS_ENABLED", Value: "true"}, - {Name: "OTEL_TRACES_SAMPLER_ARG", Value: "endpoint=http://cloudwatch-agent.amazon-cloudwatch:2000"}, - {Name: "OTEL_TRACES_SAMPLER", Value: "xray"}, - {Name: "OTEL_EXPORTER_OTLP_PROTOCOL", Value: "http/protobuf"}, - {Name: "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", Value: "http://cloudwatch-agent.amazon-cloudwatch:4316/v1/traces"}, - {Name: "OTEL_AWS_APP_SIGNALS_EXPORTER_ENDPOINT", Value: "http://cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, //TODO: remove in favor of new name once safe - {Name: "OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT", Value: "http://cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, - {Name: "OTEL_METRICS_EXPORTER", Value: "none"}, - {Name: "OTEL_PYTHON_DISTRO", Value: "aws_distro"}, - {Name: "OTEL_PYTHON_CONFIGURATOR", Value: "aws_configurator"}, - {Name: "OTEL_LOGS_EXPORTER", Value: "none"}, - }, - }, - NodeJS: v1alpha1.NodeJS{ - Image: defaultNodeJSInstrumentationImage, - Env: []corev1.EnvVar{ - {Name: "OTEL_AWS_APPLICATION_SIGNALS_ENABLED", Value: "true"}, - {Name: "OTEL_TRACES_SAMPLER_ARG", Value: "endpoint=http://cloudwatch-agent.amazon-cloudwatch:2000"}, - {Name: "OTEL_TRACES_SAMPLER", Value: "xray"}, - {Name: "OTEL_EXPORTER_OTLP_PROTOCOL", Value: "http/protobuf"}, - {Name: "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", Value: "http://cloudwatch-agent.amazon-cloudwatch:4316/v1/traces"}, - {Name: "OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT", Value: "http://cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, - {Name: "OTEL_METRICS_EXPORTER", Value: "none"}, - {Name: "OTEL_LOGS_EXPORTER", Value: "none"}, - }, - }, - }, - } + defaultInst, _ := getDefaultInstrumentation(&adapters.CwaConfig{}, false) namespace := corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: "default-namespace", From eeadc15764b8c8d423f3dcd9816d3ce9abf2d5bc Mon Sep 17 00:00:00 2001 From: Paramadon Date: Thu, 22 Aug 2024 15:32:59 -0400 Subject: [PATCH 6/7] fixing unit tests --- pkg/instrumentation/auto/config_test.go | 2 +- pkg/instrumentation/defaultinstrumentation.go | 7 ++- .../defaultinstrumentation_test.go | 46 +++++++++++++++---- pkg/instrumentation/podmutator_test.go | 3 +- 4 files changed, 44 insertions(+), 14 deletions(-) diff --git a/pkg/instrumentation/auto/config_test.go b/pkg/instrumentation/auto/config_test.go index 3c183d19f..68e5c8a7e 100644 --- a/pkg/instrumentation/auto/config_test.go +++ b/pkg/instrumentation/auto/config_test.go @@ -45,7 +45,7 @@ func TestConfig(t *testing.T) { assert.Equal(t, cfg.Python, cfg.getResources(instrumentation.TypePython)) assert.Equal(t, []string{"ds2"}, getDaemonSets(cfg.Python)) assert.Equal(t, []string{"ss2"}, getStatefulSets(cfg.Python)) - assert.Equal(t, cfg.Python, cfg.getResources(instrumentation.TypeNodeJS)) + assert.Equal(t, cfg.NodeJS, cfg.getResources(instrumentation.TypeNodeJS)) assert.Equal(t, []string{"ds3"}, getDaemonSets(cfg.NodeJS)) assert.Equal(t, []string{"ss3"}, getStatefulSets(cfg.NodeJS)) assert.Equal(t, cfg.DotNet, cfg.getResources(instrumentation.TypeDotNet)) diff --git a/pkg/instrumentation/defaultinstrumentation.go b/pkg/instrumentation/defaultinstrumentation.go index 5f56b3bb3..fcc7f2a1c 100644 --- a/pkg/instrumentation/defaultinstrumentation.go +++ b/pkg/instrumentation/defaultinstrumentation.go @@ -161,16 +161,15 @@ func getDefaultInstrumentation(agentConfig *adapters.CwaConfig, isWindowsPod boo Requests: getInstrumentationConfigForResource(dotNet, request), }, }, - //TODO: temporary environment variables. Update with the latest values from the ADOT SDK for NodeJS NodeJS: v1alpha1.NodeJS{ Image: nodeJSInstrumentationImage, Env: []corev1.EnvVar{ {Name: "OTEL_AWS_APPLICATION_SIGNALS_ENABLED", Value: "true"}, - {Name: "OTEL_TRACES_SAMPLER_ARG", Value: "endpoint=http://cloudwatch-agent.amazon-cloudwatch:2000"}, + {Name: "OTEL_TRACES_SAMPLER_ARG", Value: fmt.Sprintf("endpoint=%s://%s:2000", exporterPrefix, cloudwatchAgentServiceEndpoint)}, {Name: "OTEL_TRACES_SAMPLER", Value: "xray"}, {Name: "OTEL_EXPORTER_OTLP_PROTOCOL", Value: "http/protobuf"}, - {Name: "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", Value: exporterPrefix + "cloudwatch-agent.amazon-cloudwatch:4316/v1/traces"}, - {Name: "OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT", Value: exporterPrefix + "cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics"}, + {Name: "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", Value: fmt.Sprintf("%s://%s:4316/v1/traces", exporterPrefix, cloudwatchAgentServiceEndpoint)}, + {Name: "OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT", Value: fmt.Sprintf("%s://%s:4316/v1/metrics", exporterPrefix, cloudwatchAgentServiceEndpoint)}, {Name: "OTEL_METRICS_EXPORTER", Value: "none"}, {Name: "OTEL_LOGS_EXPORTER", Value: "none"}, }, diff --git a/pkg/instrumentation/defaultinstrumentation_test.go b/pkg/instrumentation/defaultinstrumentation_test.go index 3e51814ca..20034f4a8 100644 --- a/pkg/instrumentation/defaultinstrumentation_test.go +++ b/pkg/instrumentation/defaultinstrumentation_test.go @@ -4,10 +4,12 @@ package instrumentation import ( + "fmt" "os" - "reflect" "testing" + "github.com/google/go-cmp/cmp" + "k8s.io/apimachinery/pkg/api/resource" corev1 "k8s.io/api/core/v1" @@ -131,7 +133,6 @@ func Test_getDefaultInstrumentationLinux(t *testing.T) { }, }, }, - //TODO: temporary environment variables. Update with the latest values from the ADOT SDK for NodeJS NodeJS: v1alpha1.NodeJS{ Image: defaultNodeJSInstrumentationImage, Env: []corev1.EnvVar{ @@ -243,12 +244,11 @@ func Test_getDefaultInstrumentationLinux(t *testing.T) { }, }, }, - //TODO: temporary environment variables. Update with the latest values from the ADOT SDK for NodeJS NodeJS: v1alpha1.NodeJS{ Image: defaultNodeJSInstrumentationImage, Env: []corev1.EnvVar{ {Name: "OTEL_AWS_APPLICATION_SIGNALS_ENABLED", Value: "true"}, - {Name: "OTEL_TRACES_SAMPLER_ARG", Value: "endpoint=http://cloudwatch-agent.amazon-cloudwatch:2000"}, + {Name: "OTEL_TRACES_SAMPLER_ARG", Value: "endpoint=https://cloudwatch-agent.amazon-cloudwatch:2000"}, {Name: "OTEL_TRACES_SAMPLER", Value: "xray"}, {Name: "OTEL_EXPORTER_OTLP_PROTOCOL", Value: "http/protobuf"}, {Name: "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", Value: "https://cloudwatch-agent.amazon-cloudwatch:4316/v1/traces"}, @@ -310,17 +310,19 @@ func Test_getDefaultInstrumentationLinux(t *testing.T) { t.Errorf("getDefaultInstrumentation() error = %v, wantErr %v", err, tt.wantErr) return } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("getDefaultInstrumentation() got = %v, want %v", got, tt.want) + if diff := cmp.Diff(tt.want, got); diff != "" { + t.Errorf("getDefaultInstrumentation() mismatch (-want +got):\n%s", diff) } }) } + } func Test_getDefaultInstrumentationWindows(t *testing.T) { os.Setenv("AUTO_INSTRUMENTATION_JAVA", defaultJavaInstrumentationImage) os.Setenv("AUTO_INSTRUMENTATION_PYTHON", defaultPythonInstrumentationImage) os.Setenv("AUTO_INSTRUMENTATION_DOTNET", defaultDotNetInstrumentationImage) + os.Setenv("AUTO_INSTRUMENTATION_NODEJS", defaultNodeJSInstrumentationImage) os.Setenv("AUTO_INSTRUMENTATION_JAVA_CPU_LIMIT", "500m") os.Setenv("AUTO_INSTRUMENTATION_JAVA_MEM_LIMIT", "64Mi") os.Setenv("AUTO_INSTRUMENTATION_JAVA_CPU_REQUEST", "50m") @@ -430,6 +432,19 @@ func Test_getDefaultInstrumentationWindows(t *testing.T) { }, }, }, + NodeJS: v1alpha1.NodeJS{ + Image: defaultNodeJSInstrumentationImage, + Env: []corev1.EnvVar{ + {Name: "OTEL_AWS_APPLICATION_SIGNALS_ENABLED", Value: "true"}, + {Name: "OTEL_TRACES_SAMPLER_ARG", Value: "endpoint=http://cloudwatch-agent-windows-headless.amazon-cloudwatch.svc.cluster.local:2000"}, + {Name: "OTEL_TRACES_SAMPLER", Value: "xray"}, + {Name: "OTEL_EXPORTER_OTLP_PROTOCOL", Value: "http/protobuf"}, + {Name: "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", Value: "http://cloudwatch-agent-windows-headless.amazon-cloudwatch.svc.cluster.local:4316/v1/traces"}, + {Name: "OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT", Value: "http://cloudwatch-agent-windows-headless.amazon-cloudwatch.svc.cluster.local:4316/v1/metrics"}, + {Name: "OTEL_METRICS_EXPORTER", Value: "none"}, + {Name: "OTEL_LOGS_EXPORTER", Value: "none"}, + }, + }, }, } httpsInst := &v1alpha1.Instrumentation{ @@ -528,6 +543,19 @@ func Test_getDefaultInstrumentationWindows(t *testing.T) { }, }, }, + NodeJS: v1alpha1.NodeJS{ + Image: defaultNodeJSInstrumentationImage, + Env: []corev1.EnvVar{ + {Name: "OTEL_AWS_APPLICATION_SIGNALS_ENABLED", Value: "true"}, + {Name: "OTEL_TRACES_SAMPLER_ARG", Value: "endpoint=https://cloudwatch-agent-windows-headless.amazon-cloudwatch.svc.cluster.local:2000"}, + {Name: "OTEL_TRACES_SAMPLER", Value: "xray"}, + {Name: "OTEL_EXPORTER_OTLP_PROTOCOL", Value: "http/protobuf"}, + {Name: "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", Value: "https://cloudwatch-agent-windows-headless.amazon-cloudwatch.svc.cluster.local:4316/v1/traces"}, + {Name: "OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT", Value: "https://cloudwatch-agent-windows-headless.amazon-cloudwatch.svc.cluster.local:4316/v1/metrics"}, + {Name: "OTEL_METRICS_EXPORTER", Value: "none"}, + {Name: "OTEL_LOGS_EXPORTER", Value: "none"}, + }, + }, }, } @@ -577,12 +605,14 @@ func Test_getDefaultInstrumentationWindows(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := getDefaultInstrumentation(tt.args.agentConfig, true) + fmt.Println(got) + fmt.Println("___------__---__") if (err != nil) != tt.wantErr { t.Errorf("getDefaultInstrumentation() error = %v, wantErr %v", err, tt.wantErr) return } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("getDefaultInstrumentation() got = %v, want %v", got, tt.want) + if diff := cmp.Diff(tt.want, got); diff != "" { + t.Errorf("getDefaultInstrumentation() mismatch (-want +got):\n%s", diff) } }) } diff --git a/pkg/instrumentation/podmutator_test.go b/pkg/instrumentation/podmutator_test.go index d22a28175..06f7f2361 100644 --- a/pkg/instrumentation/podmutator_test.go +++ b/pkg/instrumentation/podmutator_test.go @@ -6,10 +6,11 @@ package instrumentation import ( "context" "fmt" - "github.com/aws/amazon-cloudwatch-agent-operator/internal/manifests/collector/adapters" "os" "testing" + "github.com/aws/amazon-cloudwatch-agent-operator/internal/manifests/collector/adapters" + "github.com/go-logr/logr" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" From 4ed3e3b27295a1801d48622b653f114aa5ccded4 Mon Sep 17 00:00:00 2001 From: Paramadon Date: Fri, 23 Aug 2024 10:41:30 -0400 Subject: [PATCH 7/7] changing back nodejs image --- .../workflows/operator-integration-test.yml | 28 +++++++++++ .../validate_annotation_daemonset_test.go | 32 ++++++++++++- .../validate_annotation_methods.go | 6 ++- .../validate_annotations_deployment_test.go | 43 ++++++++++++++++- .../validate_annotations_namespace_test.go | 46 ++++++++++++++++++- .../validate_annotations_statefulset_test.go | 39 +++++++++++++++- ..._instrumentation_nodejs_env_variables.json | 11 +++++ .../nodejs/sample-deployment-nodejs.yaml | 20 ++++++++ main.go | 3 +- versions.txt | 2 +- 10 files changed, 222 insertions(+), 8 deletions(-) create mode 100644 integration-tests/nodejs/default_instrumentation_nodejs_env_variables.json create mode 100644 integration-tests/nodejs/sample-deployment-nodejs.yaml diff --git a/.github/workflows/operator-integration-test.yml b/.github/workflows/operator-integration-test.yml index 463e9d0c3..6027f21fe 100644 --- a/.github/workflows/operator-integration-test.yml +++ b/.github/workflows/operator-integration-test.yml @@ -127,6 +127,24 @@ jobs: go run integration-tests/manifests/cmd/validate_instrumentation_vars.go default integration-tests/manifests/cmd/ns_instrumentation_env_variables.json kubectl delete instrumentation sample-instrumentation + - name: Test for default instrumentation resources for nodejs + run: | + cat integration-tests/nodejs/sample-deployment-nodejs.yaml + kubectl apply -f integration-tests/nodejs/sample-deployment-nodejs.yaml + sleep 5 + kubectl wait --for=condition=Available deployment/nginx -n default + kubectl get pods -A + kubectl describe pods -n default + go run integration-tests/manifests/cmd/validate_instrumentation_vars.go default integration-tests/nodejs/default_instrumentation_nodejs_env_variables.json + + - name: Test for defined instrumentation resources for nodejs + run: | + kubectl apply -f integration-tests/manifests/sample-instrumentation.yaml + kubectl delete pods --all -n default + sleep 5 + kubectl wait --for=condition=Ready pod --all -n default + go run integration-tests/manifests/cmd/validate_instrumentation_vars.go default integration-tests/manifests/cmd/ns_instrumentation_env_variables.json + kubectl delete instrumentation sample-instrumentation - name: Test for default instrumentation resources for all languages run: | @@ -195,6 +213,8 @@ jobs: sleep 5 go test -v -run TestDotNetOnlyDeployment ./integration-tests/manifests/annotations -timeout 30m sleep 5 + go test -v -run TestNodeJSOnlyDeployment ./integration-tests/manifests/annotations -timeout 30m + sleep 5 go test -v -run TestAnnotationsOnMultipleResources ./integration-tests/manifests/annotations -timeout 30m DaemonsetAnnotationsTest: @@ -245,6 +265,8 @@ jobs: sleep 5 go test -v -run TestDotNetOnlyDaemonSet ./integration-tests/manifests/annotations -timeout 30m sleep 5 + go test -v -run TestNodeJSOnlyDaemonSet ./integration-tests/manifests/annotations -timeout 30m + sleep 5 go test -v -run TestAutoAnnotationForManualAnnotationRemoval ./integration-tests/manifests/annotations -timeout 30m StatefulsetAnnotationsTest: @@ -293,6 +315,10 @@ jobs: sleep 5 go test -v -run TestPythonOnlyStatefulSet ./integration-tests/manifests/annotations -timeout 30m sleep 5 + go test -v -run TestDotNetOnlyStatefulSet ./integration-tests/manifests/annotations -timeout 30m + sleep 5 + go test -v -run TestNodeJSOnlyStatefulSet ./integration-tests/manifests/annotations -timeout 30m + sleep 5 go test -v -run TestOnlyNonAnnotatedAppsShouldBeRestarted ./integration-tests/manifests/annotations -timeout 30m @@ -342,4 +368,6 @@ jobs: sleep 5 go test -v -run TestDotNetOnlyNamespace ./integration-tests/manifests/annotations -timeout 30m sleep 5 + go test -v -run TestNodeJSOnlyNamespace ./integration-tests/manifests/annotations -timeout 30m + sleep 5 go test -v -run TestAlreadyAutoAnnotatedResourceShouldNotRestart ./integration-tests/manifests/annotations -timeout 30m diff --git a/integration-tests/manifests/annotations/validate_annotation_daemonset_test.go b/integration-tests/manifests/annotations/validate_annotation_daemonset_test.go index bacbb22c4..5aae96ee0 100644 --- a/integration-tests/manifests/annotations/validate_annotation_daemonset_test.go +++ b/integration-tests/manifests/annotations/validate_annotation_daemonset_test.go @@ -42,6 +42,12 @@ func TestAllLanguagesDaemonSet(t *testing.T) { Deployments: []string{""}, StatefulSets: []string{""}, }, + NodeJS: auto.AnnotationResources{ + Namespaces: []string{""}, + DaemonSets: []string{filepath.Join(uniqueNamespace, daemonSetName)}, + Deployments: []string{""}, + StatefulSets: []string{""}, + }, } jsonStr, err := json.Marshal(annotationConfig) if err != nil { @@ -51,7 +57,7 @@ func TestAllLanguagesDaemonSet(t *testing.T) { startTime := time.Now() updateTheOperator(t, clientSet, string(jsonStr)) - if err := checkResourceAnnotations(t, clientSet, "daemonset", uniqueNamespace, daemonSetName, sampleDaemonsetYamlRelPath, startTime, []string{injectJavaAnnotation, autoAnnotateJavaAnnotation, injectPythonAnnotation, autoAnnotatePythonAnnotation, injectDotNetAnnotation, autoAnnotateDotNetAnnotation}, false); err != nil { + if err := checkResourceAnnotations(t, clientSet, "daemonset", uniqueNamespace, daemonSetName, sampleDaemonsetYamlRelPath, startTime, []string{injectJavaAnnotation, autoAnnotateJavaAnnotation, injectPythonAnnotation, autoAnnotatePythonAnnotation, injectDotNetAnnotation, autoAnnotateDotNetAnnotation, injectNodeJSAnnotation, autoAnnotateNodeJSAnnotation}, false); err != nil { t.Fatalf("Failed annotation check: %s", err.Error()) } @@ -156,3 +162,27 @@ func TestDotNetOnlyDaemonSet(t *testing.T) { } } +func TestNodeJSOnlyDaemonSet(t *testing.T) { + clientSet := setupTest(t) + randomNumber, err := rand.Int(rand.Reader, big.NewInt(9000)) + if err != nil { + panic(err) + } + randomNumber.Add(randomNumber, big.NewInt(1000)) //adding a hash to namespace + uniqueNamespace := fmt.Sprintf("daemonset-namespace-nodejs-only-%d", randomNumber) + annotationConfig := auto.AnnotationConfig{ + NodeJS: auto.AnnotationResources{ + DaemonSets: []string{filepath.Join(uniqueNamespace, daemonSetName)}, + }, + } + jsonStr, err := json.Marshal(annotationConfig) + if err != nil { + t.Error("Error:", err) + } + startTime := time.Now() + updateTheOperator(t, clientSet, string(jsonStr)) + + if err := checkResourceAnnotations(t, clientSet, "daemonset", uniqueNamespace, daemonSetName, sampleDaemonsetYamlRelPath, startTime, []string{injectNodeJSAnnotation, autoAnnotateNodeJSAnnotation}, false); err != nil { + t.Fatalf("Failed annotation check: %s", err.Error()) + } +} diff --git a/integration-tests/manifests/annotations/validate_annotation_methods.go b/integration-tests/manifests/annotations/validate_annotation_methods.go index 4acb6eb5c..cdebf6afc 100644 --- a/integration-tests/manifests/annotations/validate_annotation_methods.go +++ b/integration-tests/manifests/annotations/validate_annotation_methods.go @@ -35,6 +35,9 @@ const ( injectDotNetAnnotation = "instrumentation.opentelemetry.io/inject-dotnet" autoAnnotateDotNetAnnotation = "cloudwatch.aws.amazon.com/auto-annotate-dotnet" + injectNodeJSAnnotation = "instrumentation.opentelemetry.io/inject-nodejs" + autoAnnotateNodeJSAnnotation = "cloudwatch.aws.amazon.com/auto-annotate-nodejs" + deploymentName = "sample-deployment" nginxDeploymentName = "nginx" statefulSetName = "sample-statefulset" @@ -175,8 +178,9 @@ func checkNameSpaceAnnotations(t *testing.T, clientSet *kubernetes.Clientset, ex fmt.Println("There was an error getting namespace, ", err) return false } + for _, annotation := range expectedAnnotations { - fmt.Printf("\n This is the annotation: %v and its status %v, namespace name: %v, \n", annotation, ns.Status, ns.Name) + fmt.Printf("\n This is the annotation: %v and its status %v, namespace name: %v, \n", ns.ObjectMeta.Annotations, ns.Status, ns.Name) if ns.ObjectMeta.Annotations[annotation] != "true" { time.Sleep(timeBetweenRetries) correct = false diff --git a/integration-tests/manifests/annotations/validate_annotations_deployment_test.go b/integration-tests/manifests/annotations/validate_annotations_deployment_test.go index 8c0a91cea..6c84bbbae 100644 --- a/integration-tests/manifests/annotations/validate_annotations_deployment_test.go +++ b/integration-tests/manifests/annotations/validate_annotations_deployment_test.go @@ -44,6 +44,12 @@ func TestAllLanguagesDeployment(t *testing.T) { Deployments: []string{filepath.Join(uniqueNamespace, deploymentName)}, StatefulSets: []string{""}, }, + NodeJS: auto.AnnotationResources{ + Namespaces: []string{""}, + DaemonSets: []string{""}, + Deployments: []string{filepath.Join(uniqueNamespace, deploymentName)}, + StatefulSets: []string{""}, + }, } jsonStr, err := json.Marshal(annotationConfig) assert.Nil(t, err) @@ -51,7 +57,7 @@ func TestAllLanguagesDeployment(t *testing.T) { startTime := time.Now() updateTheOperator(t, clientSet, string(jsonStr)) - if err := checkResourceAnnotations(t, clientSet, "deployment", uniqueNamespace, deploymentName, sampleDeploymentYamlNameRelPath, startTime, []string{injectJavaAnnotation, autoAnnotateJavaAnnotation, injectPythonAnnotation, autoAnnotatePythonAnnotation, injectDotNetAnnotation, autoAnnotateDotNetAnnotation}, false); err != nil { + if err := checkResourceAnnotations(t, clientSet, "deployment", uniqueNamespace, deploymentName, sampleDeploymentYamlNameRelPath, startTime, []string{injectJavaAnnotation, autoAnnotateJavaAnnotation, injectPythonAnnotation, autoAnnotatePythonAnnotation, injectDotNetAnnotation, autoAnnotateDotNetAnnotation, injectNodeJSAnnotation, autoAnnotateNodeJSAnnotation}, false); err != nil { t.Fatalf("Failed annotation check: %s", err.Error()) } @@ -167,3 +173,38 @@ func TestDotNetOnlyDeployment(t *testing.T) { } } + +func TestNodeJSOnlyDeployment(t *testing.T) { + + clientSet := setupTest(t) + randomNumber, err := rand.Int(rand.Reader, big.NewInt(9000)) + if err != nil { + panic(err) + } + randomNumber.Add(randomNumber, big.NewInt(1000)) //adding a hash to namespace + uniqueNamespace := fmt.Sprintf("deployment-namespace-nodejs-only-%d", randomNumber) + + annotationConfig := auto.AnnotationConfig{ + NodeJS: auto.AnnotationResources{ + Namespaces: []string{""}, + DaemonSets: []string{""}, + Deployments: []string{filepath.Join(uniqueNamespace, deploymentName)}, + StatefulSets: []string{""}, + }, + } + jsonStr, err := json.Marshal(annotationConfig) + if err != nil { + t.Error("Error:", err) + } + + startTime := time.Now() + updateTheOperator(t, clientSet, string(jsonStr)) + if err != nil { + t.Errorf("Failed to get deployment app: %s", err.Error()) + } + + if err := checkResourceAnnotations(t, clientSet, "deployment", uniqueNamespace, deploymentName, sampleDeploymentYamlNameRelPath, startTime, []string{injectNodeJSAnnotation, autoAnnotateNodeJSAnnotation}, false); err != nil { + t.Fatalf("Failed annotation check: %s", err.Error()) + } + +} diff --git a/integration-tests/manifests/annotations/validate_annotations_namespace_test.go b/integration-tests/manifests/annotations/validate_annotations_namespace_test.go index 4f8e97316..520e37066 100644 --- a/integration-tests/manifests/annotations/validate_annotations_namespace_test.go +++ b/integration-tests/manifests/annotations/validate_annotations_namespace_test.go @@ -50,6 +50,12 @@ func TestAllLanguagesNamespace(t *testing.T) { Deployments: []string{""}, StatefulSets: []string{""}, }, + NodeJS: auto.AnnotationResources{ + Namespaces: []string{uniqueNamespace}, + DaemonSets: []string{""}, + Deployments: []string{""}, + StatefulSets: []string{""}, + }, } jsonStr, err := json.Marshal(annotationConfig) if err != nil { @@ -58,7 +64,7 @@ func TestAllLanguagesNamespace(t *testing.T) { startTime := time.Now() updateTheOperator(t, clientSet, string(jsonStr)) - if !checkNameSpaceAnnotations(t, clientSet, []string{injectJavaAnnotation, autoAnnotateJavaAnnotation, injectPythonAnnotation, autoAnnotatePythonAnnotation, injectDotNetAnnotation, autoAnnotateDotNetAnnotation}, uniqueNamespace, startTime) { + if !checkNameSpaceAnnotations(t, clientSet, []string{injectJavaAnnotation, autoAnnotateJavaAnnotation, injectPythonAnnotation, autoAnnotatePythonAnnotation, injectDotNetAnnotation, autoAnnotateDotNetAnnotation, injectNodeJSAnnotation, autoAnnotateNodeJSAnnotation}, uniqueNamespace, startTime) { t.Error("Missing Languages annotations") } } @@ -184,6 +190,44 @@ func TestDotNetOnlyNamespace(t *testing.T) { } } +func TestNodeJSOnlyNamespace(t *testing.T) { + + clientSet := setupTest(t) + randomNumber, err := rand.Int(rand.Reader, big.NewInt(9000)) + if err != nil { + panic(err) + } + randomNumber.Add(randomNumber, big.NewInt(1000)) //adding a hash to namespace + uniqueNamespace := fmt.Sprintf("namespace-nodejs-only-%d", randomNumber) + if err := createNamespace(clientSet, uniqueNamespace); err != nil { + t.Fatalf("Failed to create/apply resoures on namespace: %v", err) + } + + defer func() { + if err := deleteNamespace(clientSet, uniqueNamespace); err != nil { + t.Fatalf("Failed to delete namespace: %v", err) + } + }() + + annotationConfig := auto.AnnotationConfig{ + DotNet: auto.AnnotationResources{ + Namespaces: []string{uniqueNamespace}, + }, + } + jsonStr, err := json.Marshal(annotationConfig) + if err != nil { + t.Error("Error:", err) + } + + startTime := time.Now() + + updateTheOperator(t, clientSet, string(jsonStr)) + + if !checkNameSpaceAnnotations(t, clientSet, []string{injectNodeJSAnnotation, autoAnnotateNodeJSAnnotation}, uniqueNamespace, startTime) { + t.Error("Missing nodejs annotations") + } +} + // Multiple resources on the same namespace should all get annotations func TestAnnotationsOnMultipleResources(t *testing.T) { diff --git a/integration-tests/manifests/annotations/validate_annotations_statefulset_test.go b/integration-tests/manifests/annotations/validate_annotations_statefulset_test.go index 3e25f34e9..4f8ccea04 100644 --- a/integration-tests/manifests/annotations/validate_annotations_statefulset_test.go +++ b/integration-tests/manifests/annotations/validate_annotations_statefulset_test.go @@ -42,6 +42,12 @@ func TestAllLanguagesStatefulSet(t *testing.T) { Deployments: []string{""}, StatefulSets: []string{filepath.Join(uniqueNamespace, statefulSetName)}, }, + NodeJS: auto.AnnotationResources{ + Namespaces: []string{""}, + DaemonSets: []string{""}, + Deployments: []string{""}, + StatefulSets: []string{filepath.Join(uniqueNamespace, statefulSetName)}, + }, } jsonStr, err := json.Marshal(annotationConfig) if err != nil { @@ -49,7 +55,7 @@ func TestAllLanguagesStatefulSet(t *testing.T) { } startTime := time.Now() updateTheOperator(t, clientSet, string(jsonStr)) - if err := checkResourceAnnotations(t, clientSet, "statefulset", uniqueNamespace, statefulSetName, sampleStatefulsetYamlNameRelPath, startTime, []string{injectJavaAnnotation, autoAnnotateJavaAnnotation, injectPythonAnnotation, autoAnnotatePythonAnnotation, injectDotNetAnnotation, autoAnnotateDotNetAnnotation}, false); err != nil { + if err := checkResourceAnnotations(t, clientSet, "statefulset", uniqueNamespace, statefulSetName, sampleStatefulsetYamlNameRelPath, startTime, []string{injectJavaAnnotation, autoAnnotateJavaAnnotation, injectPythonAnnotation, autoAnnotatePythonAnnotation, injectDotNetAnnotation, autoAnnotateDotNetAnnotation, injectNodeJSAnnotation, autoAnnotateNodeJSAnnotation}, false); err != nil { t.Fatalf("Failed annotation check: %s", err.Error()) } } @@ -150,7 +156,36 @@ func TestDotNetOnlyStatefulSet(t *testing.T) { startTime := time.Now() updateTheOperator(t, clientSet, string(jsonStr)) - if err := checkResourceAnnotations(t, clientSet, "statefulset", uniqueNamespace, statefulSetName, sampleStatefulsetYamlNameRelPath, startTime, []string{injectPythonAnnotation, autoAnnotatePythonAnnotation, injectDotNetAnnotation, autoAnnotateDotNetAnnotation}, false); err != nil { + if err := checkResourceAnnotations(t, clientSet, "statefulset", uniqueNamespace, statefulSetName, sampleStatefulsetYamlNameRelPath, startTime, []string{injectDotNetAnnotation, autoAnnotateDotNetAnnotation}, false); err != nil { + t.Fatalf("Failed annotation check: %s", err.Error()) + } +} +func TestNodeJSOnlyStatefulSet(t *testing.T) { + + clientSet := setupTest(t) + randomNumber, err := rand.Int(rand.Reader, big.NewInt(9000)) + if err != nil { + panic(err) + } + randomNumber.Add(randomNumber, big.NewInt(1000)) //adding a hash to namespace + uniqueNamespace := fmt.Sprintf("statefulset-namespace-nodejs-only-%d", randomNumber) + annotationConfig := auto.AnnotationConfig{ + NodeJS: auto.AnnotationResources{ + Namespaces: []string{""}, + DaemonSets: []string{""}, + Deployments: []string{""}, + StatefulSets: []string{filepath.Join(uniqueNamespace, statefulSetName)}, + }, + } + jsonStr, err := json.Marshal(annotationConfig) + if err != nil { + t.Error("Error:", err) + } + + startTime := time.Now() + updateTheOperator(t, clientSet, string(jsonStr)) + + if err := checkResourceAnnotations(t, clientSet, "statefulset", uniqueNamespace, statefulSetName, sampleStatefulsetYamlNameRelPath, startTime, []string{injectNodeJSAnnotation, autoAnnotateNodeJSAnnotation}, false); err != nil { t.Fatalf("Failed annotation check: %s", err.Error()) } } diff --git a/integration-tests/nodejs/default_instrumentation_nodejs_env_variables.json b/integration-tests/nodejs/default_instrumentation_nodejs_env_variables.json new file mode 100644 index 000000000..a075b8eed --- /dev/null +++ b/integration-tests/nodejs/default_instrumentation_nodejs_env_variables.json @@ -0,0 +1,11 @@ + +{ +"OTEL_AWS_APPLICATION_SIGNALS_ENABLED": "true", +"OTEL_TRACES_SAMPLER_ARG" : "endpoint=http://cloudwatch-agent.amazon-cloudwatch:2000", +"OTEL_TRACES_SAMPLER": "xray", +"OTEL_EXPORTER_OTLP_PROTOCOL": "http/protobuf", +"OTEL_EXPORTER_OTLP_TRACES_ENDPOINT" : "http://cloudwatch-agent.amazon-cloudwatch:4316/v1/traces", +"OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT": "http://cloudwatch-agent.amazon-cloudwatch:4316/v1/metrics", +"OTEL_METRICS_EXPORTER": "none", +"OTEL_LOGS_EXPORTER": "none" +} \ No newline at end of file diff --git a/integration-tests/nodejs/sample-deployment-nodejs.yaml b/integration-tests/nodejs/sample-deployment-nodejs.yaml new file mode 100644 index 000000000..a5d57aa32 --- /dev/null +++ b/integration-tests/nodejs/sample-deployment-nodejs.yaml @@ -0,0 +1,20 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx +spec: + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + annotations: + instrumentation.opentelemetry.io/inject-nodejs: "true" + spec: + containers: + - name: nginx + image: nginx:1.14.2 + restartPolicy: Always +status: {} \ No newline at end of file diff --git a/main.go b/main.go index 847b30536..4ee5e8d84 100644 --- a/main.go +++ b/main.go @@ -50,7 +50,7 @@ const ( autoInstrumentationPythonImageRepository = "public.ecr.aws/aws-observability/adot-autoinstrumentation-python" autoInstrumentationDotNetImageRepository = "ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-dotnet" - autoInstrumentationNodeJSImageRepository = "637423224110.dkr.ecr.us-east-1.amazonaws.com/aws-observability/adot-autoinstrumentation-node-staging" + autoInstrumentationNodeJSImageRepository = "ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-nodejs" dcgmExporterImageRepository = "nvcr.io/nvidia/k8s/dcgm-exporter" neuronMonitorImageRepository = "public.ecr.aws/neuron" ) @@ -167,6 +167,7 @@ func main() { os.Setenv("AUTO_INSTRUMENTATION_JAVA", autoInstrumentationJava) os.Setenv("AUTO_INSTRUMENTATION_PYTHON", autoInstrumentationPython) os.Setenv("AUTO_INSTRUMENTATION_DOTNET", autoInstrumentationDotNet) + os.Setenv("AUTO_INSTRUMENTATION_DOTNET", autoInstrumentationNodeJS) logger := zap.New(zap.UseFlagOptions(&opts)) ctrl.SetLogger(logger) diff --git a/versions.txt b/versions.txt index 1c651db30..e88a78b5e 100644 --- a/versions.txt +++ b/versions.txt @@ -7,7 +7,7 @@ operator=1.4.1 # Represents the current release of ADOT language instrumentation. aws-otel-java-instrumentation=v1.32.2 aws-otel-python-instrumentation=v0.2.0 -aws-otel-nodejs-instrumentation=latest +aws-otel-nodejs-instrumentation=0.51.0 # This needs to be updated with the latest release of ADOT SDK aws-otel-dotnet-instrumentation=1.6.0