├── .dockerignore ├── .github ├── actions │ └── build-image │ │ └── action.yaml ├── dependabot.yml └── workflows │ ├── ci.yaml │ ├── injector-and-instrumentation-tests.yaml │ └── update-collector-components.yaml ├── .gitignore ├── .golangci.yml ├── .husky └── hooks │ └── pre-push ├── .prettierrc ├── .sonarcloud.properties ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── Makefile ├── NOTICE ├── PROJECT ├── README.md ├── api └── dash0monitoring │ ├── resource_interface.go │ └── v1alpha1 │ ├── dash0monitoring_types.go │ ├── groupversion_info.go │ ├── operator_configuration_types.go │ ├── types_common.go │ └── zz_generated.deepcopy.go ├── cmd └── main.go ├── config ├── certmanager │ ├── certificate.yaml │ ├── kustomization.yaml │ └── kustomizeconfig.yaml ├── crd │ ├── bases │ │ ├── operator.dash0.com_dash0monitorings.yaml │ │ └── operator.dash0.com_dash0operatorconfigurations.yaml │ ├── kustomization.yaml │ ├── kustomizeconfig.yaml │ └── patches │ │ ├── cainjection_in_dash0monitorings.yaml │ │ └── webhook_in_dash0monitorings.yaml ├── default │ ├── kustomization.yaml │ ├── manager_auth_proxy_patch.yaml │ ├── manager_config_patch.yaml │ ├── manager_webhook_patch.yaml │ └── webhookcainjection_patch.yaml ├── manager │ ├── .gitignore │ ├── kustomization.yaml │ └── manager.yaml ├── manifests │ └── kustomization.yaml ├── rbac │ ├── auth_proxy_client_clusterrole.yaml │ ├── auth_proxy_role.yaml │ ├── auth_proxy_role_binding.yaml │ ├── auth_proxy_service.yaml │ ├── dash0_editor_role.yaml │ ├── dash0_viewer_role.yaml │ ├── kustomization.yaml │ ├── leader_election_role.yaml │ ├── leader_election_role_binding.yaml │ ├── role.yaml │ ├── role_binding.yaml │ └── service_account.yaml ├── scorecard │ ├── bases │ │ └── config.yaml │ ├── kustomization.yaml │ └── patches │ │ ├── basic.config.yaml │ │ └── olm.config.yaml └── webhook │ ├── kustomization.yaml │ ├── kustomizeconfig.yaml │ ├── manifests.yaml │ └── service.yaml ├── go.mod ├── go.sum ├── hack └── boilerplate.go.txt ├── helm-chart ├── bin │ └── publish.sh └── dash0-operator │ ├── .helmignore │ ├── Chart.yaml │ ├── LICENSE │ ├── README.md │ ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ └── operator │ │ ├── cluster-role-bindings.yaml │ │ ├── cluster-roles.yaml │ │ ├── custom-resource-definition-monitoring.yaml │ │ ├── custom-resource-definition-operator-configuration.yaml │ │ ├── deployment-and-webhooks.yaml │ │ ├── extra-config-map.yaml │ │ ├── pre-delete-hook.yaml │ │ ├── role-binding.yaml │ │ ├── role.yaml │ │ └── service-account.yaml │ ├── tests │ ├── operator │ │ ├── __snapshot__ │ │ │ ├── cluster-role-bindings_test.yaml.snap │ │ │ ├── cluster-roles_test.yaml.snap │ │ │ ├── custom-resource-definition-monitoring_test.yaml.snap │ │ │ ├── custom-resource-definition-operator-configuration_test.yaml.snap │ │ │ ├── deployment-and-webhooks_test.yaml.snap │ │ │ ├── extra-config-map_test.yaml.snap │ │ │ ├── pre-delete-hook_test.yaml.snap │ │ │ ├── role-binding_test.yaml.snap │ │ │ ├── role_test.yaml.snap │ │ │ └── service-account_test.yaml.snap │ │ ├── cluster-role-bindings_test.yaml │ │ ├── cluster-roles_test.yaml │ │ ├── custom-resource-definition-monitoring_test.yaml │ │ ├── custom-resource-definition-operator-configuration_test.yaml │ │ ├── deployment-and-webhooks_test.yaml │ │ ├── extra-config-map_test.yaml │ │ ├── pre-delete-hook_test.yaml │ │ ├── role-binding_test.yaml │ │ ├── role_test.yaml │ │ └── service-account_test.yaml │ └── update-snapshots.sh │ └── values.yaml ├── images ├── collector │ ├── Dockerfile │ ├── src │ │ ├── builder │ │ │ └── config.yaml │ │ └── image │ │ │ └── entrypoint.sh │ └── update.sh ├── configreloader │ ├── Dockerfile │ └── src │ │ ├── configreloader.go │ │ ├── go.mod │ │ └── go.sum ├── filelogoffsetsync │ ├── Dockerfile │ ├── README.md │ └── src │ │ ├── filelogoffsetsync.go │ │ ├── go.mod │ │ └── go.sum ├── instrumentation │ ├── .dockerignore │ ├── Dockerfile │ ├── Dockerfile-injector-development │ ├── build-and-test-in-dev-container.sh │ ├── build.sh │ ├── copy-instrumentation.sh │ ├── dotnet │ │ ├── download-instrumentation.sh │ │ └── opentelemetry-dotnet-instrumentation-version │ ├── injector-experiments │ │ ├── .gitignore │ │ ├── cleanup.sh │ │ ├── third-party │ │ │ └── .gitignore │ │ ├── zig-to-c │ │ │ ├── 01_simple-values │ │ │ │ ├── Makefile │ │ │ │ ├── app.c │ │ │ │ ├── build.zig │ │ │ │ ├── build.zig.zon │ │ │ │ ├── rebuild-and-run.sh │ │ │ │ ├── root.zig │ │ │ │ └── watch.sh │ │ │ ├── 02_char-ptr-ptr │ │ │ │ ├── Makefile │ │ │ │ ├── app.c │ │ │ │ ├── build.zig │ │ │ │ ├── build.zig.zon │ │ │ │ ├── rebuild-and-run.sh │ │ │ │ ├── root.zig │ │ │ │ └── watch.sh │ │ │ ├── 03_export__environ_stack │ │ │ │ ├── Makefile │ │ │ │ ├── app.c │ │ │ │ ├── build.zig │ │ │ │ ├── build.zig.zon │ │ │ │ ├── rebuild-and-run.sh │ │ │ │ ├── root.zig │ │ │ │ └── watch.sh │ │ │ └── 04_export__environ_allocated │ │ │ │ ├── Makefile │ │ │ │ ├── app.c │ │ │ │ ├── build.zig │ │ │ │ ├── build.zig.zon │ │ │ │ ├── rebuild-and-run.sh │ │ │ │ ├── root.zig │ │ │ │ └── watch.sh │ │ ├── zig-to-jvm │ │ │ └── 01_export__environ │ │ │ │ ├── build.zig │ │ │ │ ├── build.zig.zon │ │ │ │ ├── rebuild-and-run.sh │ │ │ │ ├── root.zig │ │ │ │ └── watch.sh │ │ └── zig-to-nodejs │ │ │ └── 01_export__environ │ │ │ ├── build.zig │ │ │ ├── build.zig.zon │ │ │ ├── rebuild-and-run.sh │ │ │ ├── root.zig │ │ │ ├── script.js │ │ │ └── watch.sh │ ├── injector │ │ ├── .gitignore │ │ ├── README.md │ │ ├── build.zig │ │ ├── build.zig.zon │ │ ├── notes │ │ │ └── readelf │ │ │ │ ├── README.md │ │ │ │ ├── jvm.txt │ │ │ │ ├── nodejs.txt │ │ │ │ └── python.txt │ │ ├── src │ │ │ ├── allocator.zig │ │ │ ├── dash0_injector.exports.map │ │ │ ├── dotnet.zig │ │ │ ├── jvm.zig │ │ │ ├── node_js.zig │ │ │ ├── print.zig │ │ │ ├── print_test.zig │ │ │ ├── resource_attributes.zig │ │ │ ├── resource_attributes_test.zig │ │ │ ├── root.zig │ │ │ ├── test.zig │ │ │ ├── test_util.zig │ │ │ └── types.zig │ │ ├── test │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── app │ │ │ │ └── index.js │ │ │ ├── bin │ │ │ │ └── .gitignore │ │ │ ├── docker │ │ │ │ ├── .gitignore │ │ │ │ └── Dockerfile-test │ │ │ ├── no_environ_symbol │ │ │ │ ├── .gitignore │ │ │ │ ├── Dockerfile-build │ │ │ │ ├── README.md │ │ │ │ ├── go.mod │ │ │ │ ├── go.sum │ │ │ │ └── main.go │ │ │ └── scripts │ │ │ │ ├── build-in-container.sh │ │ │ │ ├── create-inaccessible-sdk-dummy-files.sh │ │ │ │ ├── create-no-sdk-dummy-files.sh │ │ │ │ ├── create-sdk-dummy-files.sh │ │ │ │ ├── default.tests │ │ │ │ ├── run-tests-for-container.sh │ │ │ │ ├── run-tests-within-container.sh │ │ │ │ ├── sdk-cannot-be-accessed.tests │ │ │ │ ├── sdk-does-not-exist.tests │ │ │ │ ├── test-all.sh │ │ │ │ └── util │ │ ├── unit-test-assets │ │ │ ├── dotnet-app-arm64-glibc │ │ │ ├── dotnet-app-arm64-musl │ │ │ ├── dotnet-app-x86_64-glibc │ │ │ ├── dotnet-app-x86_64-musl │ │ │ └── not-an-elf-binary │ │ ├── zig-build.sh │ │ ├── zig-test.sh │ │ └── zig-version │ ├── jvm │ │ ├── .gitignore │ │ ├── .mvn │ │ │ └── wrapper │ │ │ │ └── maven-wrapper.properties │ │ ├── README.md │ │ ├── build │ │ │ └── .gitkeep │ │ ├── mvnw │ │ └── pom.xml │ ├── node.js │ │ ├── .gitignore │ │ ├── build.sh │ │ ├── package-lock.json │ │ └── package.json │ ├── start-injector-dev-container.sh │ └── test │ │ ├── .gitignore │ │ ├── .nvmrc │ │ ├── .prettierrc │ │ ├── README.md │ │ ├── build-time-profiling.ts │ │ ├── c │ │ ├── .dockerignore │ │ ├── .gitignore │ │ ├── Dockerfile │ │ ├── Makefile │ │ ├── base-images │ │ └── test-cases │ │ │ ├── env-api │ │ │ ├── .env │ │ │ └── app.c │ │ │ ├── environ-reallocation │ │ │ ├── .env │ │ │ └── app.c │ │ │ ├── existing-env-var-return-unmodified-secure-getenv │ │ │ ├── .env │ │ │ └── app.c │ │ │ ├── existing-env-var-return-unmodified │ │ │ ├── .env │ │ │ └── app.c │ │ │ ├── non-existing-env-var-return-null │ │ │ ├── .env │ │ │ └── app.c │ │ │ ├── otel-resource-attributes-env-var-already-set │ │ │ ├── .env │ │ │ └── app.c │ │ │ ├── otel-resource-attributes-unset-secure-getenv │ │ │ ├── .env │ │ │ └── app.c │ │ │ └── otel-resource-attributes-unset │ │ │ ├── .env │ │ │ └── app.c │ │ ├── dotnet │ │ ├── .gitignore │ │ ├── Dockerfile │ │ ├── base-images │ │ └── test-cases │ │ │ └── no-op-test │ │ │ ├── .dockerignore │ │ │ ├── .env │ │ │ ├── Program.cs │ │ │ └── app.csproj │ │ ├── eslint.config.js │ │ ├── jvm │ │ ├── Dockerfile │ │ ├── base-images │ │ ├── jvm-test-utils │ │ │ └── src │ │ │ │ └── com │ │ │ │ └── dash0 │ │ │ │ └── injector │ │ │ │ └── testutils │ │ │ │ └── TestUtils.java │ │ └── test-cases │ │ │ ├── .gitignore │ │ │ ├── existing-env-var-return-unmodified │ │ │ ├── .env │ │ │ ├── MANIFEST.MF │ │ │ └── Main.java │ │ │ ├── java-tool-options-otel-resource-attributes-already-set │ │ │ ├── .env │ │ │ ├── MANIFEST.MF │ │ │ └── Main.java │ │ │ ├── java-tool-options-otel-resource-attributes-unset │ │ │ ├── .env │ │ │ ├── MANIFEST.MF │ │ │ ├── Main.java │ │ │ └── system.properties │ │ │ ├── non-existing-env-var-return-null │ │ │ ├── .env │ │ │ ├── MANIFEST.MF │ │ │ └── Main.java │ │ │ └── otel-resource-attributes-env-var-already-set │ │ │ ├── .env │ │ │ ├── MANIFEST.MF │ │ │ └── Main.java │ │ ├── node │ │ ├── Dockerfile │ │ ├── base-images │ │ └── test-cases │ │ │ ├── existing-env-var-return-unmodified │ │ │ ├── .env │ │ │ └── index.js │ │ │ ├── node-options-already-set │ │ │ ├── .env │ │ │ └── index.js │ │ │ ├── node-options-unset │ │ │ ├── .env │ │ │ └── index.js │ │ │ ├── non-existing-env-var-return-undefined │ │ │ ├── .env │ │ │ └── index.js │ │ │ ├── otel-resource-attributes-already-set-but-source-attributes-unset │ │ │ ├── .env │ │ │ └── index.js │ │ │ ├── otel-resource-attributes-already-set │ │ │ ├── .env │ │ │ └── index.js │ │ │ ├── otel-resource-attributes-unset-and-source-attributes-unset │ │ │ ├── .env │ │ │ └── index.js │ │ │ ├── otel-resource-attributes-unset │ │ │ ├── .env │ │ │ └── index.js │ │ │ └── verify-distro-is-loaded │ │ │ ├── .env │ │ │ └── index.js │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── test-all.ts │ │ ├── tsconfig.json │ │ └── util.ts └── pkg │ └── common │ ├── go.mod │ ├── go.sum │ ├── otel.go │ ├── util.go │ └── util_test.go ├── internal ├── collectors │ ├── collector_controller.go │ ├── collector_manager.go │ ├── collector_manager_test.go │ ├── collectors_suite_test.go │ └── otelcolresources │ │ ├── collector_config_maps.go │ │ ├── collector_config_maps_test.go │ │ ├── daemonset.config.yaml.template │ │ ├── deployment.config.yaml.template │ │ ├── desired_state.go │ │ ├── desired_state_test.go │ │ ├── otelcol_resources.go │ │ ├── otelcol_resources_suite_test.go │ │ └── otelcol_resources_test.go ├── controller │ ├── controller_suite_test.go │ ├── monitoring_controller.go │ ├── monitoring_controller_test.go │ ├── operator_configuration_controller.go │ ├── operator_configuration_controller_test.go │ ├── perses_dashboards_controller.go │ ├── perses_dashboards_controller_test.go │ ├── prometheus_rules_controller.go │ ├── prometheus_rules_controller_test.go │ └── third_party_crd_common.go ├── instrumentation │ ├── instrumentable_workloads.go │ ├── instrumentation_suite_test.go │ ├── instrumenter.go │ └── instrumenter_test.go ├── predelete │ ├── operator_pre_delete_handler.go │ ├── operator_pre_delete_handler_test.go │ └── pre_delete_suite_test.go ├── selfmonitoringapiaccess │ ├── otel_init_wait.go │ ├── otel_init_wait_test.go │ ├── self_monitoring_and_api_access.go │ ├── self_monitoring_and_api_access_test.go │ └── selfmonitoringapiaccess_suite_test.go ├── startup │ ├── auto_operator_configuration_handler.go │ ├── auto_operator_configuration_handler_test.go │ ├── instrument_at_startup.go │ ├── operator_manager_startup.go │ ├── operator_manager_startup_test.go │ └── startup_suite_test.go ├── util │ ├── cluster.go │ ├── constants.go │ ├── controller.go │ ├── extraconfig.go │ ├── extraconfig_test.go │ ├── k8s_events.go │ ├── labels.go │ ├── labels_test.go │ ├── leader_election_aware_manager.go │ ├── pointer.go │ ├── pointer_test.go │ ├── retry.go │ ├── types.go │ ├── util_suite_test.go │ ├── workload_types.go │ └── zap │ │ ├── controller_runtime_zap_helper.go │ │ ├── delegating_zap_core.go │ │ ├── delegating_zap_core_test.go │ │ ├── log_bridge_wrapper.go │ │ ├── mru.go │ │ └── mru_test.go ├── webhooks │ ├── attach_dangling_events_test.go │ ├── instrumentation_webhook.go │ ├── instrumentation_webhook_test.go │ ├── monitoring_mutatig_webhook_test.go │ ├── monitoring_mutating_webhook.go │ ├── monitoring_validation_webhook.go │ ├── monitoring_validation_webhook_test.go │ ├── operator_configuration_validation_webhook.go │ ├── operator_configuration_validation_webhook_test.go │ ├── vendored │ │ └── opentelemetry-collector-contrib │ │ │ ├── LICENSE │ │ │ ├── NOTICE │ │ │ ├── internal_ │ │ │ ├── coreinternal │ │ │ │ └── aggregateutil │ │ │ │ │ ├── aggregate.go │ │ │ │ │ └── type.go │ │ │ └── filter │ │ │ │ ├── expr │ │ │ │ └── matcher.go │ │ │ │ └── filterottl │ │ │ │ ├── filter.go │ │ │ │ └── functions.go │ │ │ └── processor │ │ │ └── transformprocessor │ │ │ └── internal_ │ │ │ ├── common │ │ │ ├── config.go │ │ │ ├── functions.go │ │ │ ├── logs.go │ │ │ ├── metrics.go │ │ │ ├── processor.go │ │ │ └── traces.go │ │ │ ├── logs │ │ │ └── functions.go │ │ │ ├── metrics │ │ │ ├── func_aggregate_on_attributes_metrics.go │ │ │ ├── func_agregate_on_attribute_value_metrics.go │ │ │ ├── func_convert_exponential_hist_to_explicit_hist.go │ │ │ ├── func_convert_gauge_to_sum.go │ │ │ ├── func_convert_sum_to_gauge.go │ │ │ ├── func_convert_summary_count_val_to_sum.go │ │ │ ├── func_convert_summary_sum_val_to_sum.go │ │ │ ├── func_copy_metric.go │ │ │ ├── func_extract_count_metric.go │ │ │ ├── func_extract_sum_metric.go │ │ │ ├── func_scale.go │ │ │ └── functions.go │ │ │ └── traces │ │ │ └── functions.go │ └── webhook_suite_test.go └── workloads │ ├── workload_modifier.go │ ├── workload_modifier_test.go │ └── workloads_suite_test.go ├── test-resources ├── .env.template ├── .gitignore ├── bin │ ├── .gitignore │ ├── README.md │ ├── filelog-offset-volume-hostpath-values.yaml │ ├── filelog-offset-volume-pvc-values.yaml │ ├── kubernetes-versions-test.sh │ ├── perses-crd-version-check.sh │ ├── prometheus-crd-version-check.sh │ ├── render-templates.sh │ ├── run-gh-action-locally.sh │ ├── test-cleanup.sh │ ├── test-scenario-01-aum-operator-cr.sh │ ├── test-scenario-02-operator-cr-aum.sh │ ├── test-scenario-03-update-operator.sh │ ├── third-party-crd-version-check-util │ └── util ├── customresources │ ├── dash0monitoring │ │ ├── .gitignore │ │ ├── dash0monitoring-2.yaml.template │ │ ├── dash0monitoring-3.yaml.template │ │ └── dash0monitoring.yaml.template │ ├── dash0operatorconfiguration │ │ ├── .gitignore │ │ ├── dash0operatorconfiguration.otlpsink.yaml.template │ │ ├── dash0operatorconfiguration.secret.yaml.template │ │ └── dash0operatorconfiguration.token.yaml.template │ ├── filelogoffsetpvc │ │ ├── offset-storage-pvc-docker.yaml │ │ └── offset-storage-pvc-kind.yaml │ ├── persesdashboard │ │ └── persesdashboard.yaml │ └── prometheusrule │ │ └── prometheusrule.yaml ├── dotnet │ ├── .dockerignore │ ├── .gitignore │ ├── Dockerfile │ ├── Program.cs │ ├── app.csproj │ ├── daemonset.yaml │ ├── deployment.yaml │ ├── pod.yaml │ ├── replicaset.yaml │ └── statefulset.yaml ├── e2e │ ├── .gitignore │ └── volumes │ │ ├── .gitignore │ │ └── offset-storage │ │ └── .gitignore ├── jvm │ └── spring-boot │ │ ├── .gitattributes │ │ ├── .gitignore │ │ ├── .m2 │ │ ├── .gitignore │ │ ├── repository │ │ │ └── .gitkeep │ │ └── settings.xml │ │ ├── .mvn │ │ └── wrapper │ │ │ └── maven-wrapper.properties │ │ ├── Dockerfile │ │ ├── daemonset.yaml │ │ ├── deployment.yaml │ │ ├── mvnw │ │ ├── pod.yaml │ │ ├── pom.xml │ │ ├── replicaset.yaml │ │ ├── src │ │ ├── main │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── dash0 │ │ │ │ │ └── app_under_test │ │ │ │ │ ├── Application.java │ │ │ │ │ └── Controller.java │ │ │ └── resources │ │ │ │ └── application.properties │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── dash0 │ │ │ └── app_under_test │ │ │ └── ApplicationTests.java │ │ └── statefulset.yaml ├── kind-config.yaml ├── node.js │ └── express │ │ ├── .dockerignore │ │ ├── .gitignore │ │ ├── .nvmrc │ │ ├── .prettierrc │ │ ├── Dockerfile │ │ ├── app.js │ │ ├── build-and-push-to-ghcr.sh │ │ ├── cronjob.yaml │ │ ├── daemonset.opt-out.yaml │ │ ├── daemonset.yaml │ │ ├── deploy.sh │ │ ├── deployment.yaml │ │ ├── job.yaml │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── pod.yaml │ │ ├── replicaset.yaml │ │ ├── statefulset.yaml │ │ └── undeploy.sh ├── otlp-sink │ └── otlp-sink.yaml └── util │ └── otlp-resource-analyzer │ ├── .gitignore │ ├── .nvmrc │ ├── .prettierrc │ ├── analyzer.js │ ├── app.js │ ├── errors.js │ ├── filters │ ├── all_pods.json │ ├── all_resources_with_higher_order_uid.json │ ├── host_name_is_set.json │ ├── host_name_set_to_pod_name.json │ ├── pod_name_but_no_pod_uid.json │ ├── pods_with_higher_order_uid.json │ ├── pods_without_higher_order_uid.json │ └── show_all_resources.json │ ├── index.js │ ├── package-lock.json │ ├── package.json │ ├── public │ └── stylesheets │ │ └── style.css │ ├── routes │ └── index.js │ └── views │ ├── error.pug │ ├── index.pug │ └── layout.pug └── test ├── e2e ├── applications_under_test.go ├── collect_logs_on_fail.go ├── collector.go ├── constants.go ├── container_images.go ├── dash0-api-mock │ ├── Dockerfile │ ├── dash0-api-mock.yaml │ ├── go.mod │ ├── go.sum │ └── main.go ├── dash0_api_mock.go ├── dash0_monitoring_resource.go ├── dash0_operator_configuration_resource.go ├── dash0monitoring.e2e.yaml.template ├── dash0operatorconfiguration.e2e.yaml.template ├── e2e_suite_test.go ├── e2e_test.go ├── events.go ├── k8s_cluster_receiver_metrics.txt ├── kind.go ├── kubeletstats_receiver_metrics.txt ├── labels.go ├── logs.go ├── match_results.go ├── metrics.go ├── metrics_server.go ├── operator.go ├── otlp_sink.go ├── parallel.go ├── persesdashboard.yaml.template ├── prometheus_receiver_metrics.txt ├── prometheusrule.yaml.template ├── run_command.go ├── setup_teardown.go ├── spans.go ├── third_party_resources.go ├── util.go └── verify_instrumentation.go └── util ├── collector.go ├── constants.go ├── crds ├── monitoring.coreos.com_prometheusrules.yaml └── perses.dev_persesdashboards.yaml ├── dummy_clients.go ├── matchers.go ├── monitoring_resource.go ├── operator_configuration_resource.go ├── resources.go ├── testable_workloads.go ├── third_party_resource.go └── verification.go /.dockerignore: -------------------------------------------------------------------------------- 1 | # More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file 2 | # Ignore build and test binaries. 3 | bin/ 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Binaries for programs and plugins 3 | *.exe 4 | *.exe~ 5 | *.dll 6 | *.so 7 | *.o 8 | *.dylib 9 | /bin/* 10 | Dockerfile.cross 11 | 12 | # Test binary, built with `go test -c` 13 | *.test 14 | 15 | # Output of the go coverage tool, specifically when used with LiteIDE 16 | *.out 17 | 18 | # Go workspace file 19 | go.work 20 | 21 | # Kubernetes Generated files - skip generated files, except for vendored files 22 | !vendor/**/zz_generated.* 23 | 24 | # editor and IDE paraphernalia 25 | .idea 26 | .vscode 27 | *.swp 28 | *.swo 29 | *~ 30 | 31 | # Idea run configs 32 | .run 33 | 34 | dash0-operator-values.yaml 35 | -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | run: 2 | deadline: 5m 3 | allow-parallel-runners: true 4 | 5 | issues: 6 | # don't skip warning about doc comments 7 | # don't exclude the default set of lint 8 | exclude-use-default: false 9 | # restore some of the defaults 10 | # (fill in the rest as needed) 11 | exclude-rules: 12 | - path: "api/*" 13 | linters: 14 | - lll 15 | - path: "internal/*" 16 | linters: 17 | - dupl 18 | - lll 19 | linters: 20 | disable-all: true 21 | enable: 22 | - dupl 23 | - copyloopvar 24 | - errcheck 25 | - goconst 26 | - gocyclo 27 | - gofmt 28 | - goimports 29 | - gosimple 30 | - govet 31 | - ineffassign 32 | - lll 33 | - misspell 34 | - nakedret 35 | - prealloc 36 | - staticcheck 37 | - typecheck 38 | - unconvert 39 | - unparam 40 | - unused 41 | exclusions: 42 | paths: 43 | - "internal/webhooks/vendored/*" 44 | linters-settings: 45 | errcheck: 46 | exclude-functions: 47 | - fmt.Fprintf 48 | -------------------------------------------------------------------------------- /.husky/hooks/pre-push: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | cd "$(dirname "${BASH_SOURCE[0]}")"/../.. 5 | 6 | make 7 | make lint 8 | make test 9 | 10 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "avoid", 3 | "quoteProps": "as-needed", 4 | "printWidth": 120, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "all" 8 | } 9 | -------------------------------------------------------------------------------- /.sonarcloud.properties: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | sonar.organization=dash0hq 5 | sonar.projectKey=dash0hq_dash0-operator 6 | 7 | sonar.sources=. 8 | sonar.exclusions=internal/webhooks/vendored/** 9 | sonar.tests=test 10 | sonar.test.inclusions=**/*_test.go,test/** 11 | 12 | # enables disabling Sonar rules 13 | sonar.issue.ignore.multicriteria=g1,j1 14 | 15 | # Do not report the keyword TODO as an issue. 16 | sonar.issue.ignore.multicriteria.g1.ruleKey=go:S1135 17 | sonar.issue.ignore.multicriteria.g1.resourceKey=**/*.go 18 | 19 | # Do not report on JS iteration style. 20 | sonar.issue.ignore.multicriteria.j1.ruleKey=javascript:S4138 21 | sonar.issue.ignore.multicriteria.j1.resourceKey=**/*.js 22 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM --platform=${BUILDPLATFORM} golang:1.24 AS builder 2 | 3 | WORKDIR /workspace 4 | 5 | # copy the Go Modules manifests individually to improve container build caching (see 6 | # go mod download step below) 7 | COPY go.mod go.mod 8 | COPY go.sum go.sum 9 | 10 | # This particular COPY needs to be executed before go mod download since it is referenced by a replace directive 11 | # in go.mod. 12 | COPY images/pkg/common/ images/pkg/common/ 13 | 14 | # download dependencies before building and copying the sources, so that we don't need to re-download as much 15 | # and so that source changes do not invalidate the cached container image build layer 16 | RUN go mod download 17 | 18 | # Copy the go source 19 | COPY cmd/ cmd/ 20 | COPY api/ api/ 21 | COPY internal/ internal/ 22 | 23 | ARG TARGETOS 24 | ARG TARGETARCH 25 | 26 | # Note: By using --platform=${BUILDPLATFORM} in the FROM statement for the build stage, we run the cross-platform 27 | # compilation (specifically, cross-CPU-architecture compilation) for the multi-platform image on the platform/CPU 28 | # architecture of the machine running the docker build, instead of running the build via emulation (QEMU); go build 29 | # takes care of producing the correct binary for the target architecture on its own. 30 | # See https://www.docker.com/blog/faster-multi-platform-builds-dockerfile-cross-compilation-guide/. 31 | RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -v -a -o manager cmd/main.go 32 | 33 | FROM gcr.io/distroless/static:nonroot 34 | WORKDIR / 35 | COPY --from=builder /workspace/manager . 36 | USER 65532:65532 37 | 38 | ENTRYPOINT ["/manager"] 39 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | internal/webhooks/vendored/opentelemetry-collector-contrib contains code originating from 2 | https://github.com/open-telemetry/opentelemetry-collector-contrib, 3 | 4 | which is copyrighted by the OpenTelemetry Authors, 5 | 6 | and licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | -------------------------------------------------------------------------------- /PROJECT: -------------------------------------------------------------------------------- 1 | # Code generated by tool. DO NOT EDIT. 2 | # This file is used to track the info used to scaffold your project 3 | # and allow the plugins properly work. 4 | # More info: https://book.kubebuilder.io/reference/project-config.html 5 | domain: dash0.com 6 | layout: 7 | - go.kubebuilder.io/v4 8 | multigroup: true 9 | plugins: 10 | manifests.sdk.operatorframework.io/v2: {} 11 | scorecard.sdk.operatorframework.io/v2: {} 12 | projectName: dash0-operator 13 | repo: github.com/dash0hq/dash0-operator 14 | resources: 15 | - api: 16 | crdVersion: v1 17 | namespaced: true 18 | controller: true 19 | domain: dash0.com 20 | group: operator 21 | kind: Dash0Monitoring 22 | path: github.com/dash0hq/dash0-operator/api/dash0monitoring/v1alpha1 23 | version: v1alpha1 24 | webhooks: 25 | defaulting: true 26 | webhookVersion: v1 27 | - api: 28 | crdVersion: v1 29 | namespaced: false 30 | controller: true 31 | domain: dash0.com 32 | group: operator 33 | kind: Dash0OperatorConfiguration 34 | path: github.com/dash0hq/dash0-operator/api/dash0monitoring/v1alpha1 35 | version: v1alpha1 36 | version: "3" 37 | -------------------------------------------------------------------------------- /api/dash0monitoring/resource_interface.go: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package dash0monitoring 5 | 6 | import ( 7 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 8 | "k8s.io/apimachinery/pkg/types" 9 | ctrl "sigs.k8s.io/controller-runtime" 10 | "sigs.k8s.io/controller-runtime/pkg/client" 11 | ) 12 | 13 | type Dash0Resource interface { 14 | GetResourceTypeName() string 15 | GetNaturalLanguageResourceTypeName() string 16 | Get() client.Object 17 | GetName() string 18 | GetUID() types.UID 19 | GetCreationTimestamp() metav1.Time 20 | GetReceiver() client.Object 21 | GetListReceiver() client.ObjectList 22 | IsClusterResource() bool 23 | RequestToName(ctrl.Request) string 24 | 25 | IsAvailable() bool 26 | IsDegraded() bool 27 | SetAvailableConditionToUnknown() 28 | EnsureResourceIsMarkedAsAvailable() 29 | EnsureResourceIsMarkedAsDegraded(string, string) 30 | EnsureResourceIsMarkedAsAboutToBeDeleted() 31 | IsMarkedForDeletion() bool 32 | 33 | // Items returns all items from the given ObjectList as an array of client.Object objects. 34 | Items(client.ObjectList) []client.Object 35 | // All returns all items from the given ObjectList as an array of Dash0Resource objects. 36 | All(client.ObjectList) []Dash0Resource 37 | // At returns the item at the given index as a Dash0Resource object. 38 | At(client.ObjectList, int) Dash0Resource 39 | } 40 | -------------------------------------------------------------------------------- /api/dash0monitoring/v1alpha1/groupversion_info.go: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Package v1alpha1 contains API Schema definitions for the operator v1alpha1 API group 5 | // +kubebuilder:object:generate=true 6 | // +groupName=operator.dash0.com 7 | package v1alpha1 8 | 9 | import ( 10 | "k8s.io/apimachinery/pkg/runtime/schema" 11 | "sigs.k8s.io/controller-runtime/pkg/scheme" 12 | ) 13 | 14 | var ( 15 | // GroupVersion is group version used to register these objects 16 | GroupVersion = schema.GroupVersion{Group: "operator.dash0.com", Version: "v1alpha1"} 17 | 18 | // SchemeBuilder is used to add go types to the GroupVersionKind scheme 19 | SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} 20 | 21 | // AddToScheme adds the types in this group-version to the given scheme. 22 | AddToScheme = SchemeBuilder.AddToScheme 23 | ) 24 | -------------------------------------------------------------------------------- /cmd/main.go: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package main 5 | 6 | import ( 7 | // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) 8 | // to ensure that exec-entrypoint and run can make use of them. 9 | _ "k8s.io/client-go/plugin/pkg/client/auth" 10 | 11 | "github.com/dash0hq/dash0-operator/internal/startup" 12 | ) 13 | 14 | func main() { 15 | startup.Start() 16 | } 17 | -------------------------------------------------------------------------------- /config/certmanager/certificate.yaml: -------------------------------------------------------------------------------- 1 | # The following manifests contain a self-signed issuer CR and a certificate CR. 2 | # More document can be found at https://docs.cert-manager.io 3 | # WARNING: Targets CertManager v1.0. Check https://cert-manager.io/docs/installation/upgrading/ for breaking changes. 4 | apiVersion: cert-manager.io/v1 5 | kind: Issuer 6 | metadata: 7 | labels: 8 | app.kubernetes.io/name: certificate 9 | app.kubernetes.io/instance: serving-cert 10 | app.kubernetes.io/component: certificate 11 | app.kubernetes.io/created-by: dash0-operator 12 | app.kubernetes.io/part-of: dash0-operator 13 | app.kubernetes.io/managed-by: kustomize 14 | name: selfsigned-issuer 15 | namespace: system 16 | spec: 17 | selfSigned: {} 18 | --- 19 | apiVersion: cert-manager.io/v1 20 | kind: Certificate 21 | metadata: 22 | labels: 23 | app.kubernetes.io/name: certificate 24 | app.kubernetes.io/instance: serving-cert 25 | app.kubernetes.io/component: certificate 26 | app.kubernetes.io/created-by: dash0-operator 27 | app.kubernetes.io/part-of: dash0-operator 28 | app.kubernetes.io/managed-by: kustomize 29 | name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml 30 | namespace: system 31 | spec: 32 | # SERVICE_NAME and SERVICE_NAMESPACE will be substituted by kustomize 33 | dnsNames: 34 | - SERVICE_NAME.SERVICE_NAMESPACE.svc 35 | - SERVICE_NAME.SERVICE_NAMESPACE.svc.cluster.local 36 | issuerRef: 37 | kind: Issuer 38 | name: selfsigned-issuer 39 | secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize 40 | -------------------------------------------------------------------------------- /config/certmanager/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - certificate.yaml 3 | 4 | configurations: 5 | - kustomizeconfig.yaml 6 | -------------------------------------------------------------------------------- /config/certmanager/kustomizeconfig.yaml: -------------------------------------------------------------------------------- 1 | # This configuration is for teaching kustomize how to update name ref substitution 2 | nameReference: 3 | - kind: Issuer 4 | group: cert-manager.io 5 | fieldSpecs: 6 | - kind: Certificate 7 | group: cert-manager.io 8 | path: spec/issuerRef/name 9 | -------------------------------------------------------------------------------- /config/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # This kustomization.yaml is not intended to be run by itself, 2 | # since it depends on service name and namespace that are out of this kustomize package. 3 | # It should be run by config/default 4 | resources: 5 | - bases/operator.dash0.com_dash0monitorings.yaml 6 | #+kubebuilder:scaffold:crdkustomizeresource 7 | 8 | patches: 9 | # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. 10 | # patches here are for enabling the conversion webhook for each CRD 11 | - path: patches/webhook_in_dash0monitorings.yaml 12 | #+kubebuilder:scaffold:crdkustomizewebhookpatch 13 | 14 | # [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix. 15 | # patches here are for enabling the CA injection for each CRD 16 | - path: patches/cainjection_in_dash0monitorings.yaml 17 | #+kubebuilder:scaffold:crdkustomizecainjectionpatch 18 | 19 | # [WEBHOOK] To enable webhook, uncomment the following section 20 | # the following config is for teaching kustomize how to do kustomization for CRDs. 21 | 22 | configurations: 23 | - kustomizeconfig.yaml 24 | -------------------------------------------------------------------------------- /config/crd/kustomizeconfig.yaml: -------------------------------------------------------------------------------- 1 | # This file is for teaching kustomize how to substitute name and namespace reference in CRD 2 | nameReference: 3 | - kind: Service 4 | version: v1 5 | fieldSpecs: 6 | - kind: CustomResourceDefinition 7 | version: v1 8 | group: apiextensions.k8s.io 9 | path: spec/conversion/webhook/clientConfig/service/name 10 | 11 | namespace: 12 | - kind: CustomResourceDefinition 13 | version: v1 14 | group: apiextensions.k8s.io 15 | path: spec/conversion/webhook/clientConfig/service/namespace 16 | create: false 17 | 18 | varReference: 19 | - path: metadata/annotations 20 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_dash0monitorings.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | cert-manager.io/inject-ca-from: CERTIFICATE_NAMESPACE/CERTIFICATE_NAME 7 | name: dash0monitorings.operator.dash0.com 8 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_dash0monitorings.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables a conversion webhook for the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: dash0monitorings.operator.dash0.com 6 | spec: 7 | conversion: 8 | strategy: Webhook 9 | webhook: 10 | clientConfig: 11 | service: 12 | namespace: system 13 | name: webhook-service 14 | path: /convert 15 | conversionReviewVersions: 16 | - v1 17 | -------------------------------------------------------------------------------- /config/default/manager_auth_proxy_patch.yaml: -------------------------------------------------------------------------------- 1 | # This patch inject a sidecar container which is a HTTP proxy for the 2 | # controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. 3 | apiVersion: apps/v1 4 | kind: Deployment 5 | metadata: 6 | name: controller-manager 7 | namespace: system 8 | spec: 9 | template: 10 | spec: 11 | containers: 12 | - name: kube-rbac-proxy 13 | securityContext: 14 | allowPrivilegeEscalation: false 15 | capabilities: 16 | drop: 17 | - "ALL" 18 | image: quay.io/brancz/kube-rbac-proxy:v0.18.0 19 | args: 20 | - "--secure-listen-address=0.0.0.0:8443" 21 | - "--upstream=http://127.0.0.1:8080/" 22 | - "--logtostderr=true" 23 | - "--v=0" 24 | ports: 25 | - containerPort: 8443 26 | protocol: TCP 27 | name: https 28 | resources: 29 | limits: 30 | cpu: 500m 31 | memory: 128Mi 32 | requests: 33 | cpu: 5m 34 | memory: 64Mi 35 | - name: manager 36 | args: 37 | - "--health-probe-bind-address=:8081" 38 | - "--metrics-bind-address=127.0.0.1:8080" 39 | - "--leader-elect" 40 | -------------------------------------------------------------------------------- /config/default/manager_config_patch.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: controller-manager 5 | namespace: system 6 | spec: 7 | template: 8 | spec: 9 | containers: 10 | - name: manager 11 | -------------------------------------------------------------------------------- /config/default/manager_webhook_patch.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: controller-manager 5 | namespace: system 6 | spec: 7 | template: 8 | spec: 9 | containers: 10 | - name: manager 11 | ports: 12 | - containerPort: 9443 13 | name: webhook-server 14 | protocol: TCP 15 | volumeMounts: 16 | - mountPath: /tmp/k8s-webhook-server/serving-certs 17 | name: cert 18 | readOnly: true 19 | volumes: 20 | - name: cert 21 | secret: 22 | defaultMode: 420 23 | secretName: webhook-server-cert 24 | -------------------------------------------------------------------------------- /config/default/webhookcainjection_patch.yaml: -------------------------------------------------------------------------------- 1 | # This patch add annotation to admission webhook config and 2 | # CERTIFICATE_NAMESPACE and CERTIFICATE_NAME will be substituted by kustomize 3 | apiVersion: admissionregistration.k8s.io/v1 4 | kind: MutatingWebhookConfiguration 5 | metadata: 6 | labels: 7 | app.kubernetes.io/name: mutatingwebhookconfiguration 8 | app.kubernetes.io/instance: mutating-webhook-configuration 9 | app.kubernetes.io/component: webhook 10 | app.kubernetes.io/created-by: dash0-operator 11 | app.kubernetes.io/part-of: dash0-operator 12 | app.kubernetes.io/managed-by: kustomize 13 | name: mutating-webhook-configuration 14 | annotations: 15 | cert-manager.io/inject-ca-from: CERTIFICATE_NAMESPACE/CERTIFICATE_NAME 16 | #--- 17 | #apiVersion: admissionregistration.k8s.io/v1 18 | #kind: ValidatingWebhookConfiguration 19 | #metadata: 20 | # labels: 21 | # app.kubernetes.io/name: validatingwebhookconfiguration 22 | # app.kubernetes.io/instance: validating-webhook-configuration 23 | # app.kubernetes.io/component: webhook 24 | # app.kubernetes.io/created-by: dash0-operator 25 | # app.kubernetes.io/part-of: dash0-operator 26 | # app.kubernetes.io/managed-by: kustomize 27 | # name: validating-webhook-configuration 28 | # annotations: 29 | # cert-manager.io/inject-ca-from: CERTIFICATE_NAMESPACE/CERTIFICATE_NAME 30 | -------------------------------------------------------------------------------- /config/manager/.gitignore: -------------------------------------------------------------------------------- 1 | manager.yaml.backup -------------------------------------------------------------------------------- /config/manager/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - manager.yaml 3 | apiVersion: kustomize.config.k8s.io/v1beta1 4 | kind: Kustomization 5 | images: 6 | - name: controller 7 | newName: dash0-operator-controller 8 | newTag: latest 9 | -------------------------------------------------------------------------------- /config/manifests/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # These resources constitute the fully configured set of manifests 2 | # used to generate the 'manifests/' directory in a bundle. 3 | resources: 4 | - bases/dash0-operator.clusterserviceversion.yaml 5 | - ../default 6 | - ../samples 7 | - ../scorecard 8 | 9 | # [WEBHOOK] To enable webhooks, uncomment all the sections with [WEBHOOK] prefix. 10 | # Do NOT uncomment sections with prefix [CERTMANAGER], as OLM does not support cert-manager. 11 | # These patches remove the unnecessary "cert" volume and its manager container volumeMount. 12 | #patchesJson6902: 13 | #- target: 14 | # group: apps 15 | # version: v1 16 | # kind: Deployment 17 | # name: controller-manager 18 | # namespace: system 19 | # patch: |- 20 | # # Remove the manager container's "cert" volumeMount, since OLM will create and mount a set of certs. 21 | # # Update the indices in this path if adding or removing containers/volumeMounts in the manager's Deployment. 22 | # - op: remove 23 | 24 | # path: /spec/template/spec/containers/0/volumeMounts/0 25 | # # Remove the "cert" volume, since OLM will create and mount a set of certs. 26 | # # Update the indices in this path if adding or removing volumes in the manager's Deployment. 27 | # - op: remove 28 | # path: /spec/template/spec/volumes/0 29 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_client_clusterrole.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | labels: 5 | app.kubernetes.io/name: clusterrole 6 | app.kubernetes.io/instance: metrics-reader 7 | app.kubernetes.io/component: kube-rbac-proxy 8 | app.kubernetes.io/created-by: dash0-operator 9 | app.kubernetes.io/part-of: dash0-operator 10 | app.kubernetes.io/managed-by: kustomize 11 | name: metrics-reader 12 | rules: 13 | - nonResourceURLs: 14 | - "/metrics" 15 | verbs: 16 | - get 17 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | labels: 5 | app.kubernetes.io/name: clusterrole 6 | app.kubernetes.io/instance: proxy-role 7 | app.kubernetes.io/component: kube-rbac-proxy 8 | app.kubernetes.io/created-by: dash0-operator 9 | app.kubernetes.io/part-of: dash0-operator 10 | app.kubernetes.io/managed-by: kustomize 11 | name: proxy-role 12 | rules: 13 | - apiGroups: 14 | - authentication.k8s.io 15 | resources: 16 | - tokenreviews 17 | verbs: 18 | - create 19 | - apiGroups: 20 | - authorization.k8s.io 21 | resources: 22 | - subjectaccessreviews 23 | verbs: 24 | - create 25 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | labels: 5 | app.kubernetes.io/name: clusterrolebinding 6 | app.kubernetes.io/instance: proxy-rolebinding 7 | app.kubernetes.io/component: kube-rbac-proxy 8 | app.kubernetes.io/created-by: dash0-operator 9 | app.kubernetes.io/part-of: dash0-operator 10 | app.kubernetes.io/managed-by: kustomize 11 | name: proxy-rolebinding 12 | roleRef: 13 | apiGroup: rbac.authorization.k8s.io 14 | kind: ClusterRole 15 | name: proxy-role 16 | subjects: 17 | - kind: ServiceAccount 18 | name: controller-manager 19 | namespace: system 20 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | control-plane: controller-manager 6 | app.kubernetes.io/name: service 7 | app.kubernetes.io/instance: controller-manager-metrics-service 8 | app.kubernetes.io/component: kube-rbac-proxy 9 | app.kubernetes.io/created-by: dash0-operator 10 | app.kubernetes.io/part-of: dash0-operator 11 | app.kubernetes.io/managed-by: kustomize 12 | name: controller-manager-metrics-service 13 | namespace: system 14 | spec: 15 | ports: 16 | - name: https 17 | port: 8443 18 | protocol: TCP 19 | targetPort: https 20 | selector: 21 | control-plane: controller-manager 22 | -------------------------------------------------------------------------------- /config/rbac/dash0_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit dash0monitorings. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | labels: 6 | app.kubernetes.io/name: clusterrole 7 | app.kubernetes.io/instance: dash0-editor-role 8 | app.kubernetes.io/component: rbac 9 | app.kubernetes.io/created-by: dash0-operator 10 | app.kubernetes.io/part-of: dash0-operator 11 | app.kubernetes.io/managed-by: kustomize 12 | name: dash0-editor-role 13 | rules: 14 | - apiGroups: 15 | - operator.dash0.com 16 | resources: 17 | - dash0monitorings 18 | verbs: 19 | - create 20 | - delete 21 | - get 22 | - list 23 | - patch 24 | - update 25 | - watch 26 | - apiGroups: 27 | - operator.dash0.com 28 | resources: 29 | - dash0monitorings/status 30 | verbs: 31 | - get 32 | -------------------------------------------------------------------------------- /config/rbac/dash0_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view operator.dash0.com CRs. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | labels: 6 | app.kubernetes.io/name: clusterrole 7 | app.kubernetes.io/instance: dash0-viewer-role 8 | app.kubernetes.io/component: rbac 9 | app.kubernetes.io/created-by: dash0-operator 10 | app.kubernetes.io/part-of: dash0-operator 11 | app.kubernetes.io/managed-by: kustomize 12 | name: dash0-viewer-role 13 | rules: 14 | - apiGroups: 15 | - operator.dash0.com 16 | resources: 17 | - dash0monitorings 18 | - dash0operatorconfigurations 19 | verbs: 20 | - get 21 | - list 22 | - watch 23 | - apiGroups: 24 | - operator.dash0.com 25 | resources: 26 | - dash0monitorings/status 27 | - dash0operatorconfigurations/status 28 | verbs: 29 | - get 30 | -------------------------------------------------------------------------------- /config/rbac/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | # All RBAC will be applied under this service account in 3 | # the deployment namespace. You may comment out this resource 4 | # if your manager will use a service account that exists at 5 | # runtime. Be sure to update RoleBinding and ClusterRoleBinding 6 | # subjects if changing service account names. 7 | - service_account.yaml 8 | - role.yaml 9 | - role_binding.yaml 10 | - leader_election_role.yaml 11 | - leader_election_role_binding.yaml 12 | # Comment the following 4 lines if you want to disable 13 | # the auth proxy (https://github.com/brancz/kube-rbac-proxy) 14 | # which protects your /metrics endpoint. 15 | - auth_proxy_service.yaml 16 | - auth_proxy_role.yaml 17 | - auth_proxy_role_binding.yaml 18 | - auth_proxy_client_clusterrole.yaml 19 | -------------------------------------------------------------------------------- /config/rbac/leader_election_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions to do leader election. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: Role 4 | metadata: 5 | labels: 6 | app.kubernetes.io/name: role 7 | app.kubernetes.io/instance: leader-election-role 8 | app.kubernetes.io/component: rbac 9 | app.kubernetes.io/created-by: dash0-operator 10 | app.kubernetes.io/part-of: dash0-operator 11 | app.kubernetes.io/managed-by: kustomize 12 | name: leader-election-role 13 | rules: 14 | - apiGroups: 15 | - "" 16 | resources: 17 | - configmaps 18 | verbs: 19 | - get 20 | - list 21 | - watch 22 | - create 23 | - update 24 | - patch 25 | - delete 26 | - apiGroups: 27 | - coordination.k8s.io 28 | resources: 29 | - leases 30 | verbs: 31 | - get 32 | - list 33 | - watch 34 | - create 35 | - update 36 | - patch 37 | - delete 38 | - apiGroups: 39 | - "" 40 | resources: 41 | - events 42 | verbs: 43 | - create 44 | - patch 45 | -------------------------------------------------------------------------------- /config/rbac/leader_election_role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | labels: 5 | app.kubernetes.io/name: rolebinding 6 | app.kubernetes.io/instance: leader-election-rolebinding 7 | app.kubernetes.io/component: rbac 8 | app.kubernetes.io/created-by: dash0-operator 9 | app.kubernetes.io/part-of: dash0-operator 10 | app.kubernetes.io/managed-by: kustomize 11 | name: leader-election-rolebinding 12 | roleRef: 13 | apiGroup: rbac.authorization.k8s.io 14 | kind: Role 15 | name: leader-election-role 16 | subjects: 17 | - kind: ServiceAccount 18 | name: controller-manager 19 | namespace: system 20 | -------------------------------------------------------------------------------- /config/rbac/role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | labels: 5 | app.kubernetes.io/name: clusterrolebinding 6 | app.kubernetes.io/instance: manager-rolebinding 7 | app.kubernetes.io/component: rbac 8 | app.kubernetes.io/created-by: dash0-operator 9 | app.kubernetes.io/part-of: dash0-operator 10 | app.kubernetes.io/managed-by: kustomize 11 | name: manager-rolebinding 12 | roleRef: 13 | apiGroup: rbac.authorization.k8s.io 14 | kind: ClusterRole 15 | name: manager-role 16 | subjects: 17 | - kind: ServiceAccount 18 | name: controller-manager 19 | namespace: system 20 | -------------------------------------------------------------------------------- /config/rbac/service_account.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | labels: 5 | app.kubernetes.io/name: serviceaccount 6 | app.kubernetes.io/instance: controller-manager-sa 7 | app.kubernetes.io/component: rbac 8 | app.kubernetes.io/created-by: dash0-operator 9 | app.kubernetes.io/part-of: dash0-operator 10 | app.kubernetes.io/managed-by: kustomize 11 | name: controller-manager 12 | namespace: system 13 | -------------------------------------------------------------------------------- /config/scorecard/bases/config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: scorecard.operatorframework.io/v1alpha3 2 | kind: Configuration 3 | metadata: 4 | name: config 5 | stages: 6 | - parallel: true 7 | tests: [] 8 | -------------------------------------------------------------------------------- /config/scorecard/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - bases/config.yaml 3 | patchesJson6902: 4 | - path: patches/basic.config.yaml 5 | target: 6 | group: scorecard.operatorframework.io 7 | version: v1alpha3 8 | kind: Configuration 9 | name: config 10 | - path: patches/olm.config.yaml 11 | target: 12 | group: scorecard.operatorframework.io 13 | version: v1alpha3 14 | kind: Configuration 15 | name: config 16 | #+kubebuilder:scaffold:patchesJson6902 17 | -------------------------------------------------------------------------------- /config/scorecard/patches/basic.config.yaml: -------------------------------------------------------------------------------- 1 | - op: add 2 | path: /stages/0/tests/- 3 | value: 4 | entrypoint: 5 | - scorecard-test 6 | - basic-check-spec 7 | image: quay.io/operator-framework/scorecard-test:v1.34.1 8 | labels: 9 | suite: basic 10 | test: basic-check-spec-test 11 | -------------------------------------------------------------------------------- /config/scorecard/patches/olm.config.yaml: -------------------------------------------------------------------------------- 1 | - op: add 2 | path: /stages/0/tests/- 3 | value: 4 | entrypoint: 5 | - scorecard-test 6 | - olm-bundle-validation 7 | image: quay.io/operator-framework/scorecard-test:v1.34.1 8 | labels: 9 | suite: olm 10 | test: olm-bundle-validation-test 11 | - op: add 12 | path: /stages/0/tests/- 13 | value: 14 | entrypoint: 15 | - scorecard-test 16 | - olm-crds-have-validation 17 | image: quay.io/operator-framework/scorecard-test:v1.34.1 18 | labels: 19 | suite: olm 20 | test: olm-crds-have-validation-test 21 | - op: add 22 | path: /stages/0/tests/- 23 | value: 24 | entrypoint: 25 | - scorecard-test 26 | - olm-crds-have-resources 27 | image: quay.io/operator-framework/scorecard-test:v1.34.1 28 | labels: 29 | suite: olm 30 | test: olm-crds-have-resources-test 31 | - op: add 32 | path: /stages/0/tests/- 33 | value: 34 | entrypoint: 35 | - scorecard-test 36 | - olm-spec-descriptors 37 | image: quay.io/operator-framework/scorecard-test:v1.34.1 38 | labels: 39 | suite: olm 40 | test: olm-spec-descriptors-test 41 | - op: add 42 | path: /stages/0/tests/- 43 | value: 44 | entrypoint: 45 | - scorecard-test 46 | - olm-status-descriptors 47 | image: quay.io/operator-framework/scorecard-test:v1.34.1 48 | labels: 49 | suite: olm 50 | test: olm-status-descriptors-test 51 | -------------------------------------------------------------------------------- /config/webhook/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - manifests.yaml 3 | - service.yaml 4 | 5 | configurations: 6 | - kustomizeconfig.yaml 7 | -------------------------------------------------------------------------------- /config/webhook/kustomizeconfig.yaml: -------------------------------------------------------------------------------- 1 | # the following config is for teaching kustomize where to look at when substituting nameReference. 2 | # It requires kustomize v2.1.0 or newer to work properly. 3 | nameReference: 4 | - kind: Service 5 | version: v1 6 | fieldSpecs: 7 | - kind: MutatingWebhookConfiguration 8 | group: admissionregistration.k8s.io 9 | path: webhooks/clientConfig/service/name 10 | # - kind: ValidatingWebhookConfiguration 11 | # group: admissionregistration.k8s.io 12 | # path: webhooks/clientConfig/service/name 13 | 14 | namespace: 15 | - kind: MutatingWebhookConfiguration 16 | group: admissionregistration.k8s.io 17 | path: webhooks/clientConfig/service/namespace 18 | create: true 19 | #- kind: ValidatingWebhookConfiguration 20 | # group: admissionregistration.k8s.io 21 | # path: webhooks/clientConfig/service/namespace 22 | # create: true 23 | -------------------------------------------------------------------------------- /config/webhook/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | app.kubernetes.io/name: service 6 | app.kubernetes.io/instance: webhook-service 7 | app.kubernetes.io/component: webhook 8 | app.kubernetes.io/created-by: dash0-operator 9 | app.kubernetes.io/part-of: dash0-operator 10 | app.kubernetes.io/managed-by: kustomize 11 | name: webhook-service 12 | namespace: system 13 | spec: 14 | ports: 15 | - port: 443 16 | protocol: TCP 17 | targetPort: 9443 18 | selector: 19 | control-plane: controller-manager 20 | -------------------------------------------------------------------------------- /hack/boilerplate.go.txt: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 -------------------------------------------------------------------------------- /helm-chart/dash0-operator/.helmignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .gitignore 3 | *.swp 4 | *.bak 5 | *.tmp 6 | *.orig 7 | *~ 8 | tests/ -------------------------------------------------------------------------------- /helm-chart/dash0-operator/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: dash0-operator 3 | version: "0.0.0" # note: will be replaced when building a release 4 | description: The Dash0 Operator makes observability easy for every Kubernetes setup, simply install the operator into your cluster to get OpenTelemetry data flowing from your applications and infrastructure to Dash0. 5 | type: application 6 | keywords: 7 | - OpenTelemetry 8 | - Observability 9 | - Monitoring 10 | - Dash0 11 | - Node.js 12 | - Java 13 | - JVM 14 | - .NET 15 | # - Python 16 | home: https://www.dash0.com/ 17 | sources: 18 | - https://github.com/dash0hq/dash0-operator 19 | maintainers: 20 | - name: Bastian Krol 21 | email: bastian.krol@dash0.com 22 | icon: https://www.dash0.com/shared/logo_colors_128x128.png 23 | appVersion: "0.0.0" # note: will be replaced when building a release 24 | -------------------------------------------------------------------------------- /helm-chart/dash0-operator/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | {{- if .Release.IsInstall }} 2 | The Dash0 operator has been installed successfully from the chart {{ .Chart.Name }}. 3 | {{- else }} 4 | The Dash0 operator has been upgraded successfully from the chart {{ .Chart.Name }}. 5 | {{- end }} 6 | * Helm release name: {{ .Release.Name | quote }} 7 | * Dash0 operator namespace: {{ .Release.Namespace | quote }} 8 | -------------------------------------------------------------------------------- /helm-chart/dash0-operator/templates/operator/cluster-role-bindings.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: {{ template "dash0-operator.chartName" . }}-manager-rolebinding 5 | labels: 6 | app.kubernetes.io/name: dash0-operator 7 | app.kubernetes.io/component: controller 8 | app.kubernetes.io/instance: role-binding 9 | {{- include "dash0-operator.labels" . | nindent 4 }} 10 | roleRef: 11 | apiGroup: rbac.authorization.k8s.io 12 | kind: ClusterRole 13 | name: {{ template "dash0-operator.chartName" . }}-manager-role 14 | subjects: 15 | - kind: ServiceAccount 16 | name: {{ template "dash0-operator.serviceAccountName" . }} 17 | namespace: {{ .Release.Namespace }} 18 | --- 19 | apiVersion: rbac.authorization.k8s.io/v1 20 | kind: ClusterRoleBinding 21 | metadata: 22 | name: {{ template "dash0-operator.chartName" . }}-proxy-rolebinding 23 | labels: 24 | app.kubernetes.io/name: dash0-operator 25 | app.kubernetes.io/component: proxy 26 | app.kubernetes.io/instance: role-binding 27 | {{- include "dash0-operator.labels" . | nindent 4 }} 28 | roleRef: 29 | apiGroup: rbac.authorization.k8s.io 30 | kind: ClusterRole 31 | name: dash0-operator-proxy-role 32 | subjects: 33 | - kind: ServiceAccount 34 | name: {{ template "dash0-operator.serviceAccountName" . }} 35 | namespace: {{ .Release.Namespace }} 36 | -------------------------------------------------------------------------------- /helm-chart/dash0-operator/templates/operator/pre-delete-hook.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: {{ include "dash0-operator.chartName" . }}-pre-delete 5 | namespace: {{ .Release.Namespace }} 6 | labels: 7 | app.kubernetes.io/name: dash0-operator 8 | app.kubernetes.io/component: uninstallation-process 9 | {{- include "dash0-operator.labels" . | nindent 4 }} 10 | dash0.com/enable: "false" 11 | annotations: 12 | "helm.sh/hook": pre-delete 13 | "helm.sh/hook-delete-policy": hook-succeeded 14 | spec: 15 | template: 16 | metadata: 17 | name: {{ .Release.Name }}-pre-delete-job 18 | labels: 19 | app.kubernetes.io/name: dash0-operator 20 | app.kubernetes.io/component: uninstallation-process 21 | app.kubernetes.io/instance: pre-delete-hook 22 | app.kubernetes.io/managed-by: {{ .Release.Service | quote }} 23 | helm.sh/chart: {{ include "dash0-operator.chartNameWithVersion" . }} 24 | spec: 25 | restartPolicy: OnFailure 26 | containers: 27 | - name: pre-delete-job 28 | image: {{ include "dash0-operator.image" . | quote }} 29 | imagePullPolicy: {{ .Values.operator.image.pullPolicy }} 30 | command: 31 | - /manager 32 | - "--uninstrument-all" 33 | {{ include "dash0-operator.restrictiveContainerSecurityContext" . | nindent 10 }} 34 | resources: 35 | {{- toYaml .Values.operator.managerContainerResources | nindent 12 }} 36 | securityContext: 37 | runAsNonRoot: true 38 | serviceAccountName: {{ template "dash0-operator.serviceAccountName" . }} 39 | automountServiceAccountToken: true 40 | backoffLimit: 2 -------------------------------------------------------------------------------- /helm-chart/dash0-operator/templates/operator/role-binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: {{ template "dash0-operator.chartName" . }}-leader-election-rolebinding 5 | namespace: {{ .Release.Namespace }} 6 | labels: 7 | app.kubernetes.io/name: dash0-operator 8 | app.kubernetes.io/component: controller 9 | app.kubernetes.io/instance: leader-election-rolebinding 10 | {{- include "dash0-operator.labels" . | nindent 4 }} 11 | roleRef: 12 | apiGroup: rbac.authorization.k8s.io 13 | kind: Role 14 | name: {{ template "dash0-operator.chartName" . }}-leader-election-role 15 | subjects: 16 | - kind: ServiceAccount 17 | name: {{ template "dash0-operator.serviceAccountName" . }} 18 | namespace: {{ .Release.Namespace }} 19 | -------------------------------------------------------------------------------- /helm-chart/dash0-operator/templates/operator/role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: Role 3 | metadata: 4 | name: {{ template "dash0-operator.chartName" . }}-leader-election-role 5 | namespace: {{ .Release.Namespace }} 6 | labels: 7 | app.kubernetes.io/name: dash0-operator 8 | app.kubernetes.io/component: controller 9 | app.kubernetes.io/instance: leader-election-role 10 | {{- include "dash0-operator.labels" . | nindent 4 }} 11 | rules: 12 | - apiGroups: 13 | - "" 14 | resources: 15 | - configmaps 16 | verbs: 17 | - get 18 | - list 19 | - watch 20 | - create 21 | - update 22 | - patch 23 | - delete 24 | - apiGroups: 25 | - coordination.k8s.io 26 | resources: 27 | - leases 28 | verbs: 29 | - get 30 | - list 31 | - watch 32 | - create 33 | - update 34 | - patch 35 | - delete 36 | - apiGroups: 37 | - "" 38 | resources: 39 | - events 40 | verbs: 41 | - create 42 | - patch 43 | -------------------------------------------------------------------------------- /helm-chart/dash0-operator/templates/operator/service-account.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.operator.serviceAccount.create }} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ template "dash0-operator.serviceAccountName" . }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | app.kubernetes.io/name: dash0-operator 9 | app.kubernetes.io/component: controller 10 | app.kubernetes.io/instance: service-account 11 | {{- include "dash0-operator.labels" . | nindent 4 }} 12 | {{- end }} 13 | -------------------------------------------------------------------------------- /helm-chart/dash0-operator/tests/operator/__snapshot__/cluster-role-bindings_test.yaml.snap: -------------------------------------------------------------------------------- 1 | cluster role bindings should match snapshot: 2 | 1: | 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | kind: ClusterRoleBinding 5 | metadata: 6 | labels: 7 | app.kubernetes.io/component: controller 8 | app.kubernetes.io/instance: role-binding 9 | app.kubernetes.io/managed-by: Helm 10 | app.kubernetes.io/name: dash0-operator 11 | app.kubernetes.io/part-of: dash0-operator 12 | app.kubernetes.io/version: 0.0.0 13 | helm.sh/chart: dash0-operator-0.0.0 14 | name: dash0-operator-manager-rolebinding 15 | roleRef: 16 | apiGroup: rbac.authorization.k8s.io 17 | kind: ClusterRole 18 | name: dash0-operator-manager-role 19 | subjects: 20 | - kind: ServiceAccount 21 | name: dash0-operator-controller 22 | namespace: NAMESPACE 23 | 2: | 24 | apiVersion: rbac.authorization.k8s.io/v1 25 | kind: ClusterRoleBinding 26 | metadata: 27 | labels: 28 | app.kubernetes.io/component: proxy 29 | app.kubernetes.io/instance: role-binding 30 | app.kubernetes.io/managed-by: Helm 31 | app.kubernetes.io/name: dash0-operator 32 | app.kubernetes.io/part-of: dash0-operator 33 | app.kubernetes.io/version: 0.0.0 34 | helm.sh/chart: dash0-operator-0.0.0 35 | name: dash0-operator-proxy-rolebinding 36 | roleRef: 37 | apiGroup: rbac.authorization.k8s.io 38 | kind: ClusterRole 39 | name: dash0-operator-proxy-role 40 | subjects: 41 | - kind: ServiceAccount 42 | name: dash0-operator-controller 43 | namespace: NAMESPACE 44 | -------------------------------------------------------------------------------- /helm-chart/dash0-operator/tests/operator/__snapshot__/role-binding_test.yaml.snap: -------------------------------------------------------------------------------- 1 | leader election role binding should match snapshot: 2 | 1: | 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | kind: RoleBinding 5 | metadata: 6 | labels: 7 | app.kubernetes.io/component: controller 8 | app.kubernetes.io/instance: leader-election-rolebinding 9 | app.kubernetes.io/managed-by: Helm 10 | app.kubernetes.io/name: dash0-operator 11 | app.kubernetes.io/part-of: dash0-operator 12 | app.kubernetes.io/version: 0.0.0 13 | helm.sh/chart: dash0-operator-0.0.0 14 | name: dash0-operator-leader-election-rolebinding 15 | namespace: NAMESPACE 16 | roleRef: 17 | apiGroup: rbac.authorization.k8s.io 18 | kind: Role 19 | name: dash0-operator-leader-election-role 20 | subjects: 21 | - kind: ServiceAccount 22 | name: dash0-operator-controller 23 | namespace: NAMESPACE 24 | -------------------------------------------------------------------------------- /helm-chart/dash0-operator/tests/operator/__snapshot__/role_test.yaml.snap: -------------------------------------------------------------------------------- 1 | leader election role should match snapshot: 2 | 1: | 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | kind: Role 5 | metadata: 6 | labels: 7 | app.kubernetes.io/component: controller 8 | app.kubernetes.io/instance: leader-election-role 9 | app.kubernetes.io/managed-by: Helm 10 | app.kubernetes.io/name: dash0-operator 11 | app.kubernetes.io/part-of: dash0-operator 12 | app.kubernetes.io/version: 0.0.0 13 | helm.sh/chart: dash0-operator-0.0.0 14 | name: dash0-operator-leader-election-role 15 | namespace: NAMESPACE 16 | rules: 17 | - apiGroups: 18 | - "" 19 | resources: 20 | - configmaps 21 | verbs: 22 | - get 23 | - list 24 | - watch 25 | - create 26 | - update 27 | - patch 28 | - delete 29 | - apiGroups: 30 | - coordination.k8s.io 31 | resources: 32 | - leases 33 | verbs: 34 | - get 35 | - list 36 | - watch 37 | - create 38 | - update 39 | - patch 40 | - delete 41 | - apiGroups: 42 | - "" 43 | resources: 44 | - events 45 | verbs: 46 | - create 47 | - patch 48 | -------------------------------------------------------------------------------- /helm-chart/dash0-operator/tests/operator/__snapshot__/service-account_test.yaml.snap: -------------------------------------------------------------------------------- 1 | service account should match snapshot (default settings): 2 | 1: | 3 | apiVersion: v1 4 | kind: ServiceAccount 5 | metadata: 6 | labels: 7 | app.kubernetes.io/component: controller 8 | app.kubernetes.io/instance: service-account 9 | app.kubernetes.io/managed-by: Helm 10 | app.kubernetes.io/name: dash0-operator 11 | app.kubernetes.io/part-of: dash0-operator 12 | app.kubernetes.io/version: 0.0.0 13 | helm.sh/chart: dash0-operator-0.0.0 14 | name: dash0-operator-controller 15 | namespace: NAMESPACE 16 | -------------------------------------------------------------------------------- /helm-chart/dash0-operator/tests/operator/cluster-role-bindings_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test cluster role bindings 2 | templates: 3 | - operator/cluster-role-bindings.yaml 4 | tests: 5 | - it: cluster role bindings should match snapshot 6 | asserts: 7 | - matchSnapshot: {} -------------------------------------------------------------------------------- /helm-chart/dash0-operator/tests/operator/cluster-roles_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test cluster roles 2 | templates: 3 | - operator/cluster-roles.yaml 4 | tests: 5 | - it: cluster roles should match snapshot 6 | asserts: 7 | - matchSnapshot: {} -------------------------------------------------------------------------------- /helm-chart/dash0-operator/tests/operator/custom-resource-definition-monitoring_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test custom resource definition 2 | templates: 3 | - operator/custom-resource-definition-monitoring.yaml 4 | tests: 5 | - it: custom resource definition should match snapshot 6 | asserts: 7 | - matchSnapshot: {} -------------------------------------------------------------------------------- /helm-chart/dash0-operator/tests/operator/custom-resource-definition-operator-configuration_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test custom resource definition 2 | templates: 3 | - operator/custom-resource-definition-operator-configuration.yaml 4 | tests: 5 | - it: custom resource definition should match snapshot 6 | asserts: 7 | - matchSnapshot: {} -------------------------------------------------------------------------------- /helm-chart/dash0-operator/tests/operator/pre-delete-hook_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test pre-delete hook job 2 | templates: 3 | - operator/pre-delete-hook.yaml 4 | tests: 5 | - it: pre-delete hook job should match snapshot 6 | asserts: 7 | - matchSnapshot: {} 8 | 9 | - it: image tag should default to appVersion 10 | chart: 11 | version: 4.5.6 12 | appVersion: 99.100.101 13 | asserts: 14 | - equal: 15 | path: spec.template.spec.containers[0].image 16 | value: ghcr.io/dash0hq/operator-controller:99.100.101 17 | -------------------------------------------------------------------------------- /helm-chart/dash0-operator/tests/operator/role-binding_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test role 2 | templates: 3 | - operator/role-binding.yaml 4 | tests: 5 | - it: leader election role binding should match snapshot 6 | asserts: 7 | - matchSnapshot: {} -------------------------------------------------------------------------------- /helm-chart/dash0-operator/tests/operator/role_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test role 2 | templates: 3 | - operator/role.yaml 4 | tests: 5 | - it: leader election role should match snapshot 6 | asserts: 7 | - matchSnapshot: {} -------------------------------------------------------------------------------- /helm-chart/dash0-operator/tests/operator/service-account_test.yaml: -------------------------------------------------------------------------------- 1 | suite: test role 2 | templates: 3 | - operator/service-account.yaml 4 | tests: 5 | - it: service account should match snapshot (default settings) 6 | asserts: 7 | - matchSnapshot: {} 8 | 9 | - it: should not render service account when disabled 10 | set: 11 | operator.serviceAccount.create: false 12 | asserts: 13 | - hasDocuments: 14 | count: 0 15 | 16 | - it: should render service account with custom settings 17 | set: 18 | operator.serviceAccount.name: custom-service-account-name 19 | asserts: 20 | - equal: 21 | path: metadata.name 22 | value: custom-service-account-name 23 | -------------------------------------------------------------------------------- /helm-chart/dash0-operator/tests/update-snapshots.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | set -euo pipefail 7 | 8 | cd "$(dirname "${BASH_SOURCE[0]}")"/.. 9 | 10 | helm unittest -f 'tests/**/*.yaml' --update-snapshot . -------------------------------------------------------------------------------- /images/collector/Dockerfile: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | FROM --platform=${BUILDPLATFORM} golang:1.24-alpine3.21 AS builder 5 | 6 | RUN apk add --update git make yq && apk cache clean 7 | 8 | COPY src/builder /src/builder 9 | WORKDIR /src 10 | 11 | RUN export builder_version=$(yq '.connectors[0].gomod | match(" v(\d+\.\d+\.\d+)$"; "g") | .captures[0].string' builder/config.yaml) \ 12 | && echo "Using OpenTelemetry collector builder version v${builder_version}." \ 13 | && go install go.opentelemetry.io/collector/cmd/builder@v${builder_version} 14 | 15 | ARG TARGETOS 16 | ARG TARGETARCH 17 | 18 | RUN CGO_ENABLED=0 \ 19 | GOOS=${TARGETOS:-linux} \ 20 | GOARCH=${TARGETARCH} \ 21 | builder --config=builder/config.yaml && \ 22 | chmod u+x /src/dist/dash0-operator-collector 23 | 24 | FROM alpine:3.21.3 25 | COPY src/image/entrypoint.sh /entrypoint.sh 26 | COPY --from=builder /src/dist/dash0-operator-collector otelcol 27 | USER 65532:65532 28 | ENTRYPOINT ["/entrypoint.sh"] 29 | -------------------------------------------------------------------------------- /images/collector/src/image/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | ./otelcol "$@" & 7 | 8 | DASH0_COLLECTOR_PID=$! 9 | 10 | mkdir -p "$(dirname "${DASH0_COLLECTOR_PID_FILE}")" 11 | 12 | printf "%s" "${DASH0_COLLECTOR_PID}" > "${DASH0_COLLECTOR_PID_FILE}" 13 | 14 | printf "Collector pid file created at \"%s\": " "${DASH0_COLLECTOR_PID_FILE}" 15 | cat "${DASH0_COLLECTOR_PID_FILE}" 16 | echo 17 | 18 | wait ${DASH0_COLLECTOR_PID} 19 | -------------------------------------------------------------------------------- /images/configreloader/Dockerfile: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | # Note: This Dockerfile expects dash0-operator/images as the build context. 5 | 6 | FROM --platform=${BUILDPLATFORM} golang:1.24-alpine3.21 AS builder 7 | 8 | WORKDIR /usr/local/go/src/configreloader 9 | 10 | # Copy go.mod and friends and run go mod download separately before starting the container image build, to improve 11 | # container build caching. 12 | COPY configreloader/src/go.mod /usr/local/go/src/configreloader/go.mod 13 | COPY configreloader/src/go.sum /usr/local/go/src/configreloader/go.sum 14 | COPY pkg /usr/local/go/pkg 15 | RUN go mod download 16 | 17 | # now copy the actual go sources and compile them 18 | COPY configreloader/src/*.go /usr/local/go/src/configreloader 19 | 20 | ARG TARGETOS 21 | ARG TARGETARCH 22 | 23 | RUN CGO_ENABLED=0 \ 24 | GOOS=${TARGETOS:-linux} \ 25 | GOARCH=${TARGETARCH} \ 26 | go build \ 27 | -ldflags '-extldflags "-static"' \ 28 | -v \ 29 | configreloader 30 | 31 | FROM --platform=${BUILDPLATFORM} alpine:3.21.3 AS certs 32 | RUN apk --update add ca-certificates && apk cache clean 33 | 34 | FROM scratch 35 | COPY --from=builder /usr/local/go/src/configreloader/configreloader /app/configreloader 36 | COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt 37 | USER 65532:65532 38 | ENTRYPOINT [ "/app/configreloader" ] 39 | -------------------------------------------------------------------------------- /images/filelogoffsetsync/Dockerfile: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | # Note: This Dockerfile expects dash0-operator/images as the build context. 5 | 6 | FROM --platform=${BUILDPLATFORM} golang:1.24-alpine3.21 AS builder 7 | 8 | WORKDIR /usr/local/go/src/filelogoffsetsync 9 | 10 | # Copy go.mod and friends and run go mod download separately before starting the container image build, to improve 11 | # container build caching. 12 | COPY filelogoffsetsync/src/go.mod /usr/local/go/src/filelogoffsetsync/go.mod 13 | COPY filelogoffsetsync/src/go.sum /usr/local/go/src/filelogoffsetsync/go.sum 14 | COPY pkg /usr/local/go/pkg 15 | RUN go mod download 16 | 17 | # now copy the actual go sources and compile them 18 | COPY filelogoffsetsync/src/*.go /usr/local/go/src/filelogoffsetsync 19 | 20 | ARG TARGETOS 21 | ARG TARGETARCH 22 | 23 | RUN CGO_ENABLED=0 \ 24 | GOOS=${TARGETOS:-linux} \ 25 | GOARCH=${TARGETARCH} \ 26 | go build \ 27 | -ldflags '-extldflags "-static"' \ 28 | -v \ 29 | filelogoffsetsync 30 | 31 | FROM --platform=${BUILDPLATFORM} alpine:3.21.3 AS certs 32 | RUN apk --update add ca-certificates && apk cache clean 33 | 34 | FROM scratch 35 | COPY --from=builder /usr/local/go/src/filelogoffsetsync/filelogoffsetsync /app/filelogoffsetsync 36 | COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt 37 | USER 65532:65532 38 | ENTRYPOINT [ "/app/filelogoffsetsync" ] 39 | -------------------------------------------------------------------------------- /images/instrumentation/.dockerignore: -------------------------------------------------------------------------------- 1 | # Note that these ignore instructions need to be valid for a couple of images with different purposes, like the main 2 | # instrumentation image, but also the injector builder image used in injector/test. This is mostly about speeding up 3 | # builds by not invalidating Docker layer caching unnecessarily. The files ending up in the main instrumentation image 4 | # are not controlled by this .dockerignore file, they are carefully controlled by the last stage of the multi-stage 5 | # Dockerfile, which only copies the relevant final artifacts from the various build stages. 6 | injector/test/scripts/* 7 | !injector/test/scripts/run-tests-within-container.sh 8 | !injector/test/scripts/*.tests 9 | injector/.zig-cache 10 | injector/README.md 11 | injector/notes 12 | injector/test/.container_images_to_be_deleted_at_end 13 | injector/test/.containers_to_be_deleted_at_end 14 | injector/test/README.md 15 | injector/test/docker 16 | injector/test/no_environ_symbol 17 | injector/unit-test-assets 18 | injector/zig-*.sh 19 | injector/zig-out 20 | injector-experiments/ 21 | node.js/build.sh 22 | test/ 23 | **/*.swp 24 | **/.DS_Store 25 | -------------------------------------------------------------------------------- /images/instrumentation/build-and-test-in-dev-container.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | set -euo pipefail 7 | 8 | cd "$(dirname "${BASH_SOURCE[0]}")" 9 | 10 | pushd injector > /dev/null 11 | echo building injector 12 | zig build 13 | echo injector build successful 14 | popd > /dev/null 15 | 16 | pushd test/c > /dev/null 17 | make clean 18 | make build 19 | popd > /dev/null 20 | 21 | LD_PRELOAD=injector/dash0_injector.so test/c/test-cases/test/app.o 22 | -------------------------------------------------------------------------------- /images/instrumentation/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | # Note: By default, this script is used neither in the e2e tests nor in the semi-manual test scenarios in 7 | # test-resources/bin, nor in the CI/CD pipeline. It might be outdated. The only use case for this script is when 8 | # you want to build the instrumentation image locally while also using modified sources for the Dash0 Nodes.js distro. 9 | # (See images/instrumenation/node.js/build.sh, USE_LOCAL_SOURCES_FOR_NODEJS_DISTRIBUTION). 10 | 11 | set -euo pipefail 12 | 13 | cd "$(dirname "${BASH_SOURCE[0]}")" 14 | 15 | pushd node.js > /dev/null 16 | ./build.sh 17 | popd > /dev/null 18 | 19 | image_repository=instrumentation 20 | image_version=latest 21 | 22 | if [[ -n "${1:-}" ]]; then 23 | image_repository=$1 24 | fi 25 | if [[ -n "${2:-}" ]]; then 26 | image_version=$2 27 | fi 28 | 29 | docker build . -t "$image_repository":"$image_version" 30 | -------------------------------------------------------------------------------- /images/instrumentation/copy-instrumentation.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | set -eu 7 | 8 | if [ -n "${DASH0_DEBUG:-}" ]; then 9 | set -x 10 | fi 11 | 12 | cd -P -- "$(dirname -- "$0")" 13 | 14 | if [ -z "${DASH0_INSTRUMENTATION_FOLDER_SOURCE:-}" ]; then 15 | DASH0_INSTRUMENTATION_FOLDER_SOURCE=/dash0-init-container 16 | fi 17 | if [ ! -d "${DASH0_INSTRUMENTATION_FOLDER_SOURCE}" ]; then 18 | >&2 echo "[Dash0] Instrumentation source directory ${DASH0_INSTRUMENTATION_FOLDER_SOURCE} does not exist." 19 | exit 1 20 | fi 21 | 22 | if [ -z "${DASH0_INSTRUMENTATION_FOLDER_DESTINATION:-}" ]; then 23 | DASH0_INSTRUMENTATION_FOLDER_DESTINATION=/__dash0__ 24 | fi 25 | 26 | # We deliberately do not create the base directory for $DASH0_INSTRUMENTATION_FOLDER_DESTINATION via mkdir, it needs 27 | # to be an existing mount point provided externally. 28 | cp -R "${DASH0_INSTRUMENTATION_FOLDER_SOURCE}"/* "${DASH0_INSTRUMENTATION_FOLDER_DESTINATION}" 29 | 30 | if [ -n "${DASH0_DEBUG:-}" ]; then 31 | find "${DASH0_INSTRUMENTATION_FOLDER_DESTINATION}" 32 | fi 33 | -------------------------------------------------------------------------------- /images/instrumentation/dotnet/download-instrumentation.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | set -euo noglob 7 | 8 | set -x 9 | 10 | DOWNLOAD_BASE_URL=https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/download 11 | ARTIFACE_BASE_NAME=opentelemetry-dotnet-instrumentation 12 | OS_NAME=linux 13 | 14 | # shellcheck source=images/instrumentation/dotnet/opentelemetry-dotnet-instrumentation-version 15 | . opentelemetry-dotnet-instrumentation-version 16 | 17 | case $(uname -m) in 18 | x86_64) ARCHITECTURE="x64" ;; 19 | aarch64) ARCHITECTURE="arm64" ;; 20 | esac 21 | 22 | case "$ARCHITECTURE" in 23 | "x64"|"arm64") 24 | ;; 25 | *) 26 | echo "Set the architecture type using the ARCHITECTURE environment variable. Supported values: x64, arm64." >&2 27 | exit 1 28 | ;; 29 | esac 30 | 31 | download_and_unzip() { 32 | libc_flavor="$1" 33 | archive_name="$ARTIFACE_BASE_NAME-$OS_NAME-$libc_flavor-$ARCHITECTURE.zip" 34 | archive_url="$DOWNLOAD_BASE_URL/$OPENTELEMETRY_DOTNET_INSTRUMENTATION_VERSION/$archive_name" 35 | curl -sSfL "$archive_url" -O 36 | mkdir "$libc_flavor" 37 | unzip "$archive_name" -d "$libc_flavor" 38 | } 39 | 40 | download_and_unzip musl 41 | download_and_unzip glibc 42 | 43 | set +x 44 | 45 | -------------------------------------------------------------------------------- /images/instrumentation/dotnet/opentelemetry-dotnet-instrumentation-version: -------------------------------------------------------------------------------- 1 | OPENTELEMETRY_DOTNET_INSTRUMENTATION_VERSION=v1.11.0 2 | -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.so 3 | .zig-cache 4 | zig-out 5 | *.log 6 | core 7 | -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | set -euo pipefail 7 | 8 | cd "$(dirname "${BASH_SOURCE[0]}")" 9 | 10 | find . -type d -name .zig-cache -not -path "./third-party/*" -exec rm -rf {} \; 11 | find . -type d -name zig-out -not -path "./third-party/*" -exec rm -rf {} \; 12 | find . -type f -name \*.so -not -path "./third-party/*" -delete 13 | find . -type f -name \*.o -not -path "./third-party/*" -delete 14 | find . -type f -name core -not -path "./third-party/*" -delete 15 | 16 | -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/third-party/.gitignore: -------------------------------------------------------------------------------- 1 | node 2 | jdk 3 | -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-c/01_simple-values/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | ARCH := $(shell uname -m) 5 | SRC_EXT := c 6 | OS := $(shell uname -s) 7 | SHELL := sh 8 | 9 | # -Wl passes options to the linker, i.e. everything after -"Wl," is passed on. 10 | # The ld option -z,undefs allows undefined 11 | CFLAGS ?= \ 12 | -Wall \ 13 | -Werror \ 14 | -Wextra \ 15 | -Wl,-z,undefs,--export-dynamic-symbol=my_char,--export-dynamic-symbol=my_int,--export-dynamic-symbol=my_string,--export-dynamic-symbol=my_nt_kv_str,--export-dynamic-symbol=change_values 16 | 17 | .PHONY: all 18 | all: clean build 19 | 20 | .PHONY: clean 21 | clean: 22 | @rm -f app.o 23 | 24 | .PHONY: build 25 | clean: 26 | build: app.o 27 | 28 | app.o: 29 | $(CC) $(CFLAGS) app.c -o app.o $(DEBUG) $^ 30 | @chmod 755 app.o 31 | 32 | -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-c/01_simple-values/app.c: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #include 5 | #include 6 | 7 | extern int my_char; 8 | extern int my_int; 9 | extern char* my_string; 10 | extern char* my_nt_kv_str; 11 | extern void change_values(); 12 | 13 | void print_nt_kv_str(char* label, char* str) { 14 | printf("app.c: %s: ", label); 15 | bool last_char_was_null = false; 16 | for (int i = 0; true; i++) { 17 | if (str[i] == '\0') { 18 | if (last_char_was_null) { 19 | printf("|NULL|"); 20 | break; 21 | } 22 | last_char_was_null = true; 23 | printf("|NULL|"); 24 | } else { 25 | last_char_was_null = false; 26 | printf("%c", str[i]); 27 | } 28 | } 29 | printf("\n"); 30 | } 31 | 32 | int main() { 33 | printf("app.c: START\n"); 34 | 35 | printf("app.c: my_char (initial): %c\n", my_char); 36 | printf("app.c: my_int (initial): %d\n", my_int); 37 | printf("app.c: my_string (initial): %s\n", my_string); 38 | print_nt_kv_str("my_nt_kv_str (initial)", my_nt_kv_str); 39 | 40 | printf("app.c: calling change_values\n"); 41 | change_values(); 42 | printf("app.c: --------\n"); 43 | 44 | printf("app.c: my_char (after): %c\n", my_char); 45 | printf("app.c: my_int (after): %d\n", my_int); 46 | printf("app.c: my_string (after): %s\n", my_string); 47 | print_nt_kv_str("my_nt_kv_str (after)", my_nt_kv_str); 48 | 49 | printf("app.c: END\n-----------------\n\n"); 50 | } 51 | 52 | -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-c/01_simple-values/build.zig.zon: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | .{ 5 | .name = .symbols, 6 | .version = "0.0.0", 7 | .fingerprint = 0xdf834d856c639076, 8 | .minimum_zig_version = "0.14.0", 9 | .dependencies = .{}, 10 | .paths = .{ 11 | "build.zig", 12 | "build.zig.zon", 13 | "root.zig", 14 | }, 15 | } 16 | -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-c/01_simple-values/rebuild-and-run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | set -euo pipefail 7 | 8 | cd "$(dirname "${BASH_SOURCE[0]}")" 9 | 10 | echo building zig 11 | zig build 12 | echo zig build successful 13 | echo building C 14 | make 15 | echo C build successful 16 | 17 | echo running code 18 | ulimit -c unlimited 19 | LD_PRELOAD=./zig-out/libsymbols.so ./app.o 20 | -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-c/01_simple-values/root.zig: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | const std = @import("std"); 5 | 6 | export const init_array: [1]*const fn () callconv(.C) void linksection(".init_array") = .{&init}; 7 | 8 | export var my_int: c_int = 0; 9 | export var my_char: u8 = 'a'; 10 | export var my_string: [*:0]const u8 = "aaa"; 11 | export var my_nt_kv_str: [*:0]const u8 = "aaa=111\x00bbb=222\x00"; 12 | 13 | fn init() callconv(.C) void { 14 | std.debug.print("root.zig#initEnviron START\n", .{}); 15 | _init() catch @panic("_init failed"); 16 | } 17 | 18 | fn _init() !void { 19 | my_int = 1; 20 | my_char = 'b'; 21 | my_string = "bbb"; 22 | my_nt_kv_str = "ccc=333\x00ddd=444\x00"; 23 | } 24 | 25 | export fn change_values() callconv(.C) void { 26 | std.debug.print("root.zig#change_values\n", .{}); 27 | my_int = 2; 28 | my_char = 'c'; 29 | my_string = "ccc"; 30 | my_nt_kv_str = "eee=555\x00fff=666\x00"; 31 | } 32 | -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-c/01_simple-values/watch.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | set -euo pipefail 7 | 8 | cd "$(dirname "${BASH_SOURCE[0]}")" 9 | 10 | # shellcheck disable=SC2012,SC2035 11 | ls *.c *.zig Makefile *.sh | entr ./rebuild-and-run.sh -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-c/02_char-ptr-ptr/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | ARCH := $(shell uname -m) 5 | SRC_EXT := c 6 | OS := $(shell uname -s) 7 | SHELL := sh 8 | 9 | # -Wl passes options to the linker, i.e. everything after -"Wl," is passed on. 10 | # The ld option -z,undefs allows undefined 11 | CFLAGS ?= \ 12 | -Wall \ 13 | -Werror \ 14 | -Wextra \ 15 | -Wl,-z,undefs,--export-dynamic-symbol=my_environ,--export-dynamic-symbol=change_values 16 | 17 | .PHONY: all 18 | all: clean build 19 | 20 | .PHONY: clean 21 | clean: 22 | @rm -f app.o 23 | 24 | .PHONY: build 25 | clean: 26 | build: app.o 27 | 28 | app.o: 29 | $(CC) $(CFLAGS) app.c -o app.o $(DEBUG) $^ 30 | @chmod 755 app.o 31 | 32 | -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-c/02_char-ptr-ptr/app.c: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #include 5 | 6 | extern char** my_environ; 7 | extern void change_values(); 8 | 9 | void print_char_ptr_of_ptr(char** str_ptr) { 10 | int idx = 0; 11 | for (char **kv_pair = str_ptr; *kv_pair; kv_pair++) { 12 | printf("app.c: my_environ address kv pair %d: '%s'\n", idx, *kv_pair); 13 | idx++; 14 | } 15 | } 16 | 17 | int main() { 18 | printf("app.c: START\n"); 19 | 20 | printf("app.c: my_environ address (initial): %p\n", my_environ); 21 | print_char_ptr_of_ptr(my_environ); 22 | 23 | printf("app.c: calling change_values\n"); 24 | change_values(); 25 | printf("app.c: --------\n"); 26 | 27 | printf("app.c: my_environ address (after): %p\n", my_environ); 28 | print_char_ptr_of_ptr(my_environ); 29 | 30 | printf("app.c: END\n-----------------\n\n"); 31 | } 32 | 33 | -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-c/02_char-ptr-ptr/build.zig.zon: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | .{ 5 | .name = .char_ptr_ptr, 6 | .version = "0.0.0", 7 | .fingerprint = 0x6f769d88e38259c9, 8 | .minimum_zig_version = "0.14.0", 9 | .dependencies = .{}, 10 | .paths = .{ 11 | "build.zig", 12 | "build.zig.zon", 13 | "root.zig", 14 | }, 15 | } 16 | -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-c/02_char-ptr-ptr/rebuild-and-run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | set -euo pipefail 7 | 8 | cd "$(dirname "${BASH_SOURCE[0]}")" 9 | 10 | echo building zig 11 | zig build 12 | echo zig build successful 13 | echo building C 14 | make 15 | echo C build successful 16 | 17 | echo running code 18 | ulimit -c unlimited 19 | LD_PRELOAD=./zig-out/libsymbols.so ./app.o 20 | -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-c/02_char-ptr-ptr/root.zig: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | const std = @import("std"); 5 | 6 | export const init_array: [1]*const fn () callconv(.C) void linksection(".init_array") = .{&init}; 7 | 8 | export var my_environ: [*c]const [*c]const u8 = @as([3][*c]const u8, .{ "VAR1=VALUE1", "VAR2=VALUE2", null })[0..].ptr; 9 | 10 | fn init() callconv(.C) void { 11 | std.debug.print("root.zig#initEnviron START\n", .{}); 12 | _init() catch @panic("_init failed"); 13 | } 14 | 15 | fn _init() !void { 16 | std.debug.print("root.zig#_init my_environ address (before change): {any}\n", .{my_environ}); 17 | 18 | // Note: Adding a final null value is crucial, otherwise C will iterate past the end of the list. The actual length 19 | // of the list that Zig knows about is lost in transfer, C will only react to null terminators to keep individual 20 | // strings apart and to the final double null terminator to know when the list ends. 21 | my_environ = @as([3][*c]const u8, .{ "VAR3=VALUE3", "VAR4=VALUE4", null })[0..].ptr; 22 | std.debug.print("root.zig#_init my_environ address (after change):: {any}\n", .{my_environ}); 23 | } 24 | 25 | export fn change_values() callconv(.C) void { 26 | std.debug.print("root.zig#change_values\n", .{}); 27 | 28 | std.debug.print("root.zig#change_values my_environ address (before change): {any}\n", .{my_environ}); 29 | my_environ = @as([4][*c]const u8, .{ "VAR5=VALUE5", "VAR6=VALUE6", "VAR7=VALUE7", null })[0..].ptr; 30 | std.debug.print("root.zig#change_values my_environ address (after change): {any}\n", .{my_environ}); 31 | } 32 | -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-c/02_char-ptr-ptr/watch.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | set -euo pipefail 7 | 8 | cd "$(dirname "${BASH_SOURCE[0]}")" 9 | 10 | # shellcheck disable=SC2012,SC2035 11 | ls *.c *.zig Makefile *.sh | entr ./rebuild-and-run.sh -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-c/03_export__environ_stack/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | ARCH := $(shell uname -m) 5 | SRC_EXT := c 6 | OS := $(shell uname -s) 7 | SHELL := sh 8 | 9 | # -Wl passes options to the linker, i.e. everything after -"Wl," is passed on. 10 | # The ld option -z,undefs allows undefined 11 | CFLAGS ?= \ 12 | -Wall \ 13 | -Werror \ 14 | -Wextra \ 15 | -g \ 16 | -Wl,-z,undefs,--export-dynamic-symbol=change_values 17 | 18 | .PHONY: all 19 | all: clean build 20 | 21 | .PHONY: clean 22 | clean: 23 | @rm -f app.o 24 | 25 | .PHONY: build 26 | clean: 27 | build: app.o 28 | 29 | app.o: 30 | $(CC) $(CFLAGS) app.c -o app.o $(DEBUG) $^ 31 | @chmod 755 app.o 32 | 33 | -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-c/03_export__environ_stack/build.zig.zon: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | .{ 5 | .name = .export_environ_stack, 6 | .version = "0.0.0", 7 | .fingerprint = 0x3cdd9889681dd7fe, 8 | .minimum_zig_version = "0.14.0", 9 | .dependencies = .{}, 10 | .paths = .{ 11 | "build.zig", 12 | "build.zig.zon", 13 | "root.zig", 14 | }, 15 | } 16 | -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-c/03_export__environ_stack/rebuild-and-run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | set -euo pipefail 7 | 8 | cd "$(dirname "${BASH_SOURCE[0]}")" 9 | 10 | echo building zig 11 | zig build 12 | echo zig build successful 13 | echo building C 14 | make 15 | echo C build successful 16 | 17 | echo running code 18 | ulimit -c unlimited 19 | LD_PRELOAD=./zig-out/libsymbols.so ./app.o 20 | -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-c/03_export__environ_stack/watch.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | set -euo pipefail 7 | 8 | cd "$(dirname "${BASH_SOURCE[0]}")" 9 | 10 | # shellcheck disable=SC2012,SC2035 11 | ls *.c *.zig Makefile *.sh | entr ./rebuild-and-run.sh -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-c/04_export__environ_allocated/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | ARCH := $(shell uname -m) 5 | SRC_EXT := c 6 | OS := $(shell uname -s) 7 | SHELL := sh 8 | 9 | # -Wl passes options to the linker, i.e. everything after -"Wl," is passed on. 10 | # The ld option -z,undefs allows undefined 11 | CFLAGS ?= \ 12 | -Wall \ 13 | -Werror \ 14 | -Wextra \ 15 | -g \ 16 | -Wl,-z,undefs,--export-dynamic-symbol=change_values 17 | 18 | .PHONY: all 19 | all: clean build 20 | 21 | .PHONY: clean 22 | clean: 23 | @rm -f app.o 24 | 25 | .PHONY: build 26 | clean: 27 | build: app.o 28 | 29 | app.o: 30 | $(CC) $(CFLAGS) app.c -o app.o $(DEBUG) $^ 31 | @chmod 755 app.o 32 | 33 | -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-c/04_export__environ_allocated/build.zig.zon: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | .{ 5 | .name = .export_environ_alloc, 6 | .version = "0.0.0", 7 | .fingerprint = 0x19e677767df237ad, 8 | .minimum_zig_version = "0.14.0", 9 | .dependencies = .{}, 10 | .paths = .{ 11 | "build.zig", 12 | "build.zig.zon", 13 | "root.zig", 14 | }, 15 | } 16 | -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-c/04_export__environ_allocated/rebuild-and-run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | set -euo pipefail 7 | 8 | cd "$(dirname "${BASH_SOURCE[0]}")" 9 | 10 | echo building zig 11 | zig build 12 | echo zig build successful 13 | echo building C 14 | make 15 | echo C build successful 16 | 17 | echo running code 18 | ulimit -c unlimited 19 | LD_PRELOAD=./zig-out/libsymbols.so ./app.o 20 | -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-c/04_export__environ_allocated/watch.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | set -euo pipefail 7 | 8 | cd "$(dirname "${BASH_SOURCE[0]}")" 9 | 10 | # shellcheck disable=SC2012,SC2035 11 | ls *.c *.zig Makefile *.sh | entr ./rebuild-and-run.sh -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-jvm/01_export__environ/build.zig.zon: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | .{ 5 | .name = .zig_to_jvm, 6 | .version = "0.0.0", 7 | .fingerprint = 0xea0b47f8e6d58a78, 8 | .minimum_zig_version = "0.14.0", 9 | .dependencies = .{}, 10 | .paths = .{ 11 | "build.zig", 12 | "build.zig.zon", 13 | "root.zig", 14 | }, 15 | } 16 | -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-jvm/01_export__environ/rebuild-and-run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | set -euo pipefail 7 | 8 | cd "$(dirname "${BASH_SOURCE[0]}")" 9 | 10 | jdk_sources=/home/dash0/instrumentation/injector-experiments/third-party/jdk 11 | 12 | # Use installed JDK binaries: 13 | jdk_binaries_java=java 14 | # jdk_binaries_jshell=jshell 15 | 16 | # Use locally built JDK binaries: 17 | # jdk_binaries_java="$jdk_sources"/build/linux-aarch64-server-release/images/jdk/bin/java 18 | # jdk_binaries_jshell="$jdk_sources"/build/linux-aarch64-server-release/images/jdk/bin/jshell 19 | 20 | if [[ "$jdk_binaries_java" =~ "/build/" ]]; then 21 | echo "Using locally built JDK binaries, rebuiding JDK" 22 | pushd "$jdk_sources" > /dev/null 23 | # bash configure 24 | time make images 25 | popd > /dev/null 26 | fi 27 | 28 | echo building zig 29 | zig build 30 | echo zig build successful 31 | 32 | echo starting JVM 33 | ulimit -c unlimited 34 | set -x 35 | LD_PRELOAD=./zig-out/libsymbols.so $jdk_binaries_java -version 36 | -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-jvm/01_export__environ/watch.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | set -euo pipefail 7 | 8 | cd "$(dirname "${BASH_SOURCE[0]}")" 9 | 10 | # shellcheck disable=SC2012,SC2035 11 | ls *.zig *.sh | entr ./rebuild-and-run.sh -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-nodejs/01_export__environ/build.zig.zon: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | .{ 5 | .name = .zig_to_nodejs, 6 | .version = "0.0.0", 7 | .fingerprint = 0xff17a9d52efb1115, 8 | .minimum_zig_version = "0.14.0", 9 | .dependencies = .{}, 10 | .paths = .{ 11 | "build.zig", 12 | "build.zig.zon", 13 | "root.zig", 14 | }, 15 | } 16 | -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-nodejs/01_export__environ/rebuild-and-run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | set -euo pipefail 7 | 8 | cd "$(dirname "${BASH_SOURCE[0]}")" 9 | 10 | node_sources=/home/dash0/instrumentation/injector-experiments/third-party/node 11 | 12 | # Use installed Node.js binary: 13 | node_js=node 14 | 15 | # Use locally built Node.js binary (release build): 16 | # node_js="$node_sources"/out/Release/node 17 | # Use locally built Node.js binary (debug build): 18 | # node_js="$node_sources"/out/Debug/node 19 | 20 | if [[ "$node_js" =~ "/out/" ]]; then 21 | echo "Using locally built Node.js binary, rebuiding Node.js" 22 | pushd "$node_sources" > /dev/null 23 | # ./configure 24 | # ./configure --debug 25 | # Building the whole Node.js code base in the container was somewhat finicky, building with just one parallel job 26 | # (no -j) was abysmally slow, but running with -j4 crashed in linking steps due to out of memory (I believe): 27 | # LINK(target) /home/dash0/instrumentation/injector-experiments/third-party/node/out/Debug/node_mksnapshot 28 | # collect2: fatal error: ld terminated with signal 9 [Killed] 29 | # compilation terminated. 30 | # A good compromise might be to run an initial build with -j4, then finish up with -j2 or without -j. 31 | # Giving the Docker VM more memory might help. 32 | time make -j8 33 | popd > /dev/null 34 | fi 35 | 36 | echo building zig 37 | zig build 38 | echo zig build successful 39 | 40 | echo starting Node.js 41 | ulimit -c unlimited 42 | set -x 43 | LD_PRELOAD=./zig-out/libsymbols.so "$node_js" script.js 44 | -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-nodejs/01_export__environ/script.js: -------------------------------------------------------------------------------- 1 | console.log("accessing individual environment variables:"); 2 | console.log("PATH:", process.env.PATH); 3 | console.log("VAR3:", process.env.VAR3); 4 | console.log("VAR4:", process.env.VAR4); 5 | 6 | console.log("accessing process.env"); 7 | console.log(process.env); 8 | 9 | console.log("writing to process.env"); 10 | process.env.NEW_VAR1 = "new value 1"; 11 | process.env.NEW_VAR2 = "new value 2"; 12 | 13 | console.log("accessing individual environment variables:"); 14 | console.log("PATH:", process.env.PATH); 15 | console.log("VAR3:", process.env.VAR3); 16 | console.log("VAR4:", process.env.VAR4); 17 | console.log("NEW_VAR1:", process.env.NEW_VAR1); 18 | console.log("NEW_VAR2:", process.env.NEW_VAR2); 19 | 20 | console.log("accessing process.env"); 21 | console.log(process.env); 22 | -------------------------------------------------------------------------------- /images/instrumentation/injector-experiments/zig-to-nodejs/01_export__environ/watch.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | set -euo pipefail 7 | 8 | cd "$(dirname "${BASH_SOURCE[0]}")" 9 | 10 | # shellcheck disable=SC2012,SC2035 11 | ls *.zig *.sh | entr ./rebuild-and-run.sh -------------------------------------------------------------------------------- /images/instrumentation/injector/.gitignore: -------------------------------------------------------------------------------- 1 | .zig-cache 2 | zig-out -------------------------------------------------------------------------------- /images/instrumentation/injector/notes/readelf/README.md: -------------------------------------------------------------------------------- 1 | # Readelf Notes 2 | 3 | The output of `readelf` for a couple of relevant executables. 4 | -------------------------------------------------------------------------------- /images/instrumentation/injector/src/allocator.zig: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | const std = @import("std"); 5 | 6 | // We need to allocate memory only to manipulate and return the few environment variables we want to modify. Unmodified 7 | // values are returned as pointers to the original `__environ` memory. 8 | pub const page_allocator: std.mem.Allocator = std.heap.page_allocator; 9 | -------------------------------------------------------------------------------- /images/instrumentation/injector/src/dash0_injector.exports.map: -------------------------------------------------------------------------------- 1 | { 2 | global: 3 | getenv; 4 | local: 5 | *; 6 | }; -------------------------------------------------------------------------------- /images/instrumentation/injector/src/print.zig: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | const std = @import("std"); 5 | 6 | const dash0_injector_debug_env_var_name = "DASH0_INJECTOR_DEBUG"; 7 | const log_prefix = "[Dash0 injector] "; 8 | 9 | var is_debug = false; 10 | 11 | /// Initializes the is_debug flag based on the environment variable DASH0_INJECTOR_DEBUG. 12 | pub fn initDebugFlag() void { 13 | if (std.posix.getenv(dash0_injector_debug_env_var_name)) |is_debug_raw| { 14 | is_debug = std.ascii.eqlIgnoreCase("true", is_debug_raw); 15 | } 16 | } 17 | 18 | pub fn isDebug() bool { 19 | return is_debug; 20 | } 21 | 22 | pub fn printDebug(comptime fmt: []const u8, args: anytype) void { 23 | if (is_debug) { 24 | std.debug.print(log_prefix ++ fmt ++ "\n", args); 25 | } 26 | } 27 | 28 | pub fn printError(comptime fmt: []const u8, args: anytype) void { 29 | std.debug.print(log_prefix ++ fmt ++ "\n", args); 30 | } 31 | 32 | pub fn printMessage(comptime fmt: []const u8, args: anytype) void { 33 | std.debug.print(log_prefix ++ fmt ++ "\n", args); 34 | } 35 | -------------------------------------------------------------------------------- /images/instrumentation/injector/src/print_test.zig: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | const std = @import("std"); 5 | 6 | const print = @import("print.zig"); 7 | const test_util = @import("test_util.zig"); 8 | 9 | const testing = std.testing; 10 | 11 | // Note on having tests embedded in the actual source files versus having them in a separate *_test.zig file: Proper 12 | // pure unit tests are usually directly in the source file of the production function they are testing. More invasive 13 | // tests that need to change the environment variables (for example) should go in a separate file, so we never run the 14 | // risk of even compiling the test mechanism to modify the environment. 15 | 16 | test "initDebugFlag: not set" { 17 | const original_environ = try test_util.clearStdCEnviron(); 18 | defer test_util.resetStdCEnviron(original_environ); 19 | print.initDebugFlag(); 20 | try testing.expect(!print.isDebug()); 21 | } 22 | 23 | test "initDebugFlag: false" { 24 | const original_environ = try test_util.setStdCEnviron(&[1][]const u8{"DASH0_INJECTOR_DEBUG=false"}); 25 | defer test_util.resetStdCEnviron(original_environ); 26 | 27 | print.initDebugFlag(); 28 | try testing.expect(!print.isDebug()); 29 | } 30 | 31 | test "initDebugFlag: true" { 32 | const original_environ = try test_util.setStdCEnviron(&[1][]const u8{"DASH0_INJECTOR_DEBUG=true"}); 33 | defer test_util.resetStdCEnviron(original_environ); 34 | 35 | print.initDebugFlag(); 36 | try testing.expect(print.isDebug()); 37 | } 38 | -------------------------------------------------------------------------------- /images/instrumentation/injector/src/test.zig: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // All files with unit tests need to be referenced here: 5 | pub const alloc = @import("allocator.zig"); 6 | pub const dotnet = @import("dotnet.zig"); 7 | pub const jvm = @import("jvm.zig"); 8 | pub const node_js = @import("node_js.zig"); 9 | pub const print = @import("print.zig"); 10 | pub const print_test = @import("print_test.zig"); 11 | pub const res_attrs = @import("resource_attributes.zig"); 12 | pub const res_attrs_test = @import("resource_attributes_test.zig"); 13 | pub const root = @import("root.zig"); 14 | pub const types = @import("types.zig"); 15 | 16 | // Provide a C-style `char **environ` variable to the linker, to satisfy the 17 | // extern var __environ: [*]u8; 18 | // declaration in `root.zig`. 19 | var ___environ: [100]u8 = [_]u8{0} ** 100; 20 | const ___environ_ptr: *[100]u8 = &___environ; 21 | export var __environ: [*]u8 = ___environ_ptr; 22 | 23 | test { 24 | @import("std").testing.refAllDecls(@This()); 25 | } 26 | -------------------------------------------------------------------------------- /images/instrumentation/injector/src/types.zig: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | pub const NullTerminatedString = [*:0]const u8; 5 | -------------------------------------------------------------------------------- /images/instrumentation/injector/test/.gitignore: -------------------------------------------------------------------------------- 1 | .container_images_to_be_deleted_at_end 2 | -------------------------------------------------------------------------------- /images/instrumentation/injector/test/README.md: -------------------------------------------------------------------------------- 1 | Injector Integration Tests 2 | ========================== 3 | 4 | This directory contains isolated integration tests for the injector code. 5 | The difference to images/instrumentation/test is that the latter tests the whole instrumentation image. 6 | Also, the tests in this folder do not use multi-platform images; instead, an injector binary is build (in a container) 7 | per CPU architecture, and then used for testing. 8 | Note that the Zig source code in images/instrumentation/injector/src also contains Zig unit tests. 9 | 10 | The available test cases for the injector integration tests are listed in the files 11 | `images/instrumentation/injector/test/scripts/*.tests`. 12 | 13 | Usage 14 | ----- 15 | 16 | * `scripts/test-all.sh` to run all tests. 17 | * `ARCHITECTURES=arm64,x86_64 scripts/test-all.sh` to run tests for a subset of CPU architectures. 18 | Can be combined with `LIBC_FLAVORS` and other flags. 19 | * `LIBC_FLAVORS=glibc,musl scripts/test-all.sh` to run tests for a subset of libc flavors. 20 | Can be combined with `ARCHITECTURES` and other flags. 21 | * `TEST_CASES=twice,mapped scripts/test-all.sh` to only run tests cases whose names contain one of the 22 | provided strings. 23 | The test cases are listed in the different `scripts/*.tests` files. 24 | Can be combined with `ARCHITECTURES`, `LIBC_FLAVORS` etc. 25 | * `INSTRUMENTATION_IMAGE=... scripts/test-all.sh` use an existing local or remote instrumentation image. 26 | * `MISSING_ENVIRON_SYMBOL_TESTS=true` also run tests with a binary that does not provide an `__environ` symbol. 27 | These are currently off by default. 28 | 29 | -------------------------------------------------------------------------------- /images/instrumentation/injector/test/app/index.js: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | const process = require('node:process'); 5 | 6 | function echoEnvVar(envVarName) { 7 | const envVarValue = process.env[envVarName]; 8 | if (!envVarValue) { 9 | process.stdout.write(`${envVarName}: -`); 10 | } else { 11 | process.stdout.write(`${envVarName}: ${envVarValue}`); 12 | } 13 | } 14 | 15 | function main() { 16 | const command = process.argv[2]; 17 | if (!command) { 18 | console.error('error: not enough arguments, the command for the app under test needs to be specifed'); 19 | process.exit(1); 20 | } 21 | 22 | switch (command) { 23 | case 'non-existing': 24 | echoEnvVar('DOES_NOT_EXIST'); 25 | break; 26 | case 'existing': 27 | echoEnvVar('TEST_VAR'); 28 | break; 29 | case 'node_options': 30 | echoEnvVar('NODE_OPTIONS'); 31 | break; 32 | case 'node_options_twice': 33 | echoEnvVar('NODE_OPTIONS'); 34 | process.stdout.write('; '); 35 | echoEnvVar('NODE_OPTIONS'); 36 | break; 37 | case 'otel_resource_attributes': 38 | echoEnvVar('OTEL_RESOURCE_ATTRIBUTES'); 39 | break; 40 | case 'java_tool_options': 41 | echoEnvVar('JAVA_TOOL_OPTIONS'); 42 | break; 43 | default: 44 | console.error(`unknown test app command: ${command}`); 45 | process.exit(1); 46 | } 47 | } 48 | 49 | main(); 50 | -------------------------------------------------------------------------------- /images/instrumentation/injector/test/bin/.gitignore: -------------------------------------------------------------------------------- 1 | *.so 2 | -------------------------------------------------------------------------------- /images/instrumentation/injector/test/docker/.gitignore: -------------------------------------------------------------------------------- 1 | Dockerfile-build 2 | -------------------------------------------------------------------------------- /images/instrumentation/injector/test/no_environ_symbol/.gitignore: -------------------------------------------------------------------------------- 1 | noenviron.* 2 | -------------------------------------------------------------------------------- /images/instrumentation/injector/test/no_environ_symbol/Dockerfile-build: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | ARG base_image="golang:1.23.7-bookworm" 5 | FROM --platform=${BUILDPLATFORM} ${base_image} 6 | 7 | WORKDIR /workspace 8 | 9 | COPY go.mod . 10 | COPY go.sum . 11 | 12 | RUN go mod download 13 | 14 | COPY main.go . 15 | 16 | ARG TARGETOS 17 | ARG TARGETARCH 18 | 19 | RUN GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -v -buildmode=pie -ldflags '-s -w' -o noenviron . 20 | 21 | -------------------------------------------------------------------------------- /images/instrumentation/injector/test/no_environ_symbol/README.md: -------------------------------------------------------------------------------- 1 | This Go application reproduces an issue where the injector `LD_PRELOAD` hook would crash executables that do not have 2 | the `__environ` symbol. 3 | This can happen for example for Go applications built with `-buildmode=pie`. 4 | -------------------------------------------------------------------------------- /images/instrumentation/injector/test/no_environ_symbol/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/dash0hq/dash0-operator/images/instrumentation/injector/test/no_environ_symbol 2 | 3 | go 1.23.2 4 | -------------------------------------------------------------------------------- /images/instrumentation/injector/test/no_environ_symbol/go.sum: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dash0hq/dash0-operator/8f9cc021630aadc4f37023b67a8fcbbe1cf2d5c0/images/instrumentation/injector/test/no_environ_symbol/go.sum -------------------------------------------------------------------------------- /images/instrumentation/injector/test/no_environ_symbol/main.go: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | ) 10 | 11 | func main() { 12 | envVarName := "NO_ENVIRON_TEST_VAR" 13 | value, isSet := os.LookupEnv(envVarName) 14 | if !isSet { 15 | fmt.Printf("The environmet variable \"%s\" is not set.\n", envVarName) 16 | os.Exit(0) 17 | } 18 | fmt.Printf("The environmet variable \"%s\" had the value: \"%s\".\n", envVarName, value) 19 | os.Exit(0) 20 | } 21 | -------------------------------------------------------------------------------- /images/instrumentation/injector/test/scripts/create-inaccessible-sdk-dummy-files.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | # Add an inaccessible dummy Dash0 OTel SDKs/distros. 7 | mkdir -p /__dash0__/instrumentation/node.js/node_modules/@dash0hq/opentelemetry 8 | touch /__dash0__/instrumentation/node.js/node_modules/@dash0hq/opentelemetry/index.js 9 | mkdir -p /__dash0__/instrumentation/jvm && touch /__dash0__/instrumentation/jvm/opentelemetry-javaagent.jar 10 | chmod -R 600 /__dash0__/instrumentation 11 | 12 | -------------------------------------------------------------------------------- /images/instrumentation/injector/test/scripts/create-no-sdk-dummy-files.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | echo "not creating and OTel SDK/distro dummy files" 7 | 8 | -------------------------------------------------------------------------------- /images/instrumentation/injector/test/scripts/create-sdk-dummy-files.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | # Add dummy Dash0 OTel SDKs/distros which actually do nothing but make the file check in the injector pass. 7 | mkdir -p /__dash0__/instrumentation/node.js/node_modules/@dash0hq/opentelemetry 8 | touch /__dash0__/instrumentation/node.js/node_modules/@dash0hq/opentelemetry/index.js 9 | mkdir -p /__dash0__/instrumentation/jvm 10 | touch /__dash0__/instrumentation/jvm/opentelemetry-javaagent.jar 11 | 12 | -------------------------------------------------------------------------------- /images/instrumentation/injector/test/scripts/sdk-cannot-be-accessed.tests: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | # NODE_OPTIONS 5 | run_test_case \ 6 | "getenv: does not add NODE_OPTIONS if it the Dash0 Node.js OTel distro is present but cannot be accessed" \ 7 | "app" \ 8 | "node index.js node_options" \ 9 | "NODE_OPTIONS: -" 10 | 11 | # JAVA_TOOL_OPTIONS 12 | run_test_case \ 13 | "getenv: does not add JAVA_TOOL_OPTIONS if it the Java agent is present but cannot be accessed" \ 14 | "app" \ 15 | "node index.js java_tool_options" \ 16 | "JAVA_TOOL_OPTIONS: -" 17 | 18 | -------------------------------------------------------------------------------- /images/instrumentation/injector/test/scripts/sdk-does-not-exist.tests: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | # NODE_OPTIONS 5 | run_test_case \ 6 | "getenv: does not add NODE_OPTIONS if it the Dash0 Node.js OTel distro is not present" \ 7 | "app" \ 8 | "node index.js node_options" \ 9 | "NODE_OPTIONS: -" 10 | run_test_case \ 11 | "getenv: does not modify existing NODE_OPTIONS if it the Dash0 Node.js OTel distro is not present" \ 12 | "app" \ 13 | "node index.js node_options" \ 14 | "NODE_OPTIONS: --no-deprecation" \ 15 | "NODE_OPTIONS=--no-deprecation" 16 | 17 | # JAVA_TOOL_OPTIONS 18 | run_test_case \ 19 | "getenv: does not add JAVA_TOOL_OPTIONS if it the Java agent is not present" \ 20 | "app" \ 21 | "node index.js java_tool_options" \ 22 | "JAVA_TOOL_OPTIONS: -" 23 | run_test_case \ 24 | "getenv: does not modify existing JAVA_TOOL_OPTIONS if it the Java agent is not present" \ 25 | "app" \ 26 | "node index.js java_tool_options" \ 27 | "JAVA_TOOL_OPTIONS: existing-value" \ 28 | "JAVA_TOOL_OPTIONS=existing-value" 29 | 30 | -------------------------------------------------------------------------------- /images/instrumentation/injector/unit-test-assets/dotnet-app-arm64-glibc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dash0hq/dash0-operator/8f9cc021630aadc4f37023b67a8fcbbe1cf2d5c0/images/instrumentation/injector/unit-test-assets/dotnet-app-arm64-glibc -------------------------------------------------------------------------------- /images/instrumentation/injector/unit-test-assets/dotnet-app-arm64-musl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dash0hq/dash0-operator/8f9cc021630aadc4f37023b67a8fcbbe1cf2d5c0/images/instrumentation/injector/unit-test-assets/dotnet-app-arm64-musl -------------------------------------------------------------------------------- /images/instrumentation/injector/unit-test-assets/dotnet-app-x86_64-glibc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dash0hq/dash0-operator/8f9cc021630aadc4f37023b67a8fcbbe1cf2d5c0/images/instrumentation/injector/unit-test-assets/dotnet-app-x86_64-glibc -------------------------------------------------------------------------------- /images/instrumentation/injector/unit-test-assets/dotnet-app-x86_64-musl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dash0hq/dash0-operator/8f9cc021630aadc4f37023b67a8fcbbe1cf2d5c0/images/instrumentation/injector/unit-test-assets/dotnet-app-x86_64-musl -------------------------------------------------------------------------------- /images/instrumentation/injector/unit-test-assets/not-an-elf-binary: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dash0hq/dash0-operator/8f9cc021630aadc4f37023b67a8fcbbe1cf2d5c0/images/instrumentation/injector/unit-test-assets/not-an-elf-binary -------------------------------------------------------------------------------- /images/instrumentation/injector/zig-build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | # A small helper script intended to be used with entr, like so: 7 | # cd images/instrumentation/injector 8 | # fd | entr ./zig-build.sh 9 | # ...to get fast feedback on compile errors when working on the Zig code. 10 | 11 | set -euo pipefail 12 | 13 | cd "$(dirname "${BASH_SOURCE[0]}")" 14 | 15 | if zig build; then 16 | echo "$(date) build successful" 17 | echo 18 | else 19 | echo "$(date) build failed" 20 | echo 21 | fi 22 | -------------------------------------------------------------------------------- /images/instrumentation/injector/zig-test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | # A small helper script intended to be used with entr, like so: 7 | # cd images/instrumentation/injector 8 | # fd | entr ./zig-test.sh 9 | # ...to get fast feedback on test errors when working on the Zig code. 10 | 11 | set -euo pipefail 12 | 13 | cd "$(dirname "${BASH_SOURCE[0]}")" 14 | 15 | if zig build test; then 16 | echo "$(date) tests successful" 17 | echo 18 | else 19 | echo "$(date) tests failed" 20 | echo 21 | fi -------------------------------------------------------------------------------- /images/instrumentation/injector/zig-version: -------------------------------------------------------------------------------- 1 | # See https://dl-cdn.alpinelinux.org/alpine/edge/community, check for zig-*.apk for available versions. 2 | # Keep this in sync with .github/workflows/ci.yaml -> mlugg/setup-zig.with.version. 3 | ZIG_VERSION=0.14.1-r0 4 | -------------------------------------------------------------------------------- /images/instrumentation/jvm/.gitignore: -------------------------------------------------------------------------------- 1 | # Download 2 | build/* 3 | 4 | # Maven 5 | target/ 6 | pom.xml.tag 7 | pom.xml.releaseBackup 8 | pom.xml.versionsBackup 9 | pom.xml.next 10 | release.properties 11 | dependency-reduced-pom.xml 12 | buildNumber.properties 13 | .mvn/timing.properties 14 | .mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /images/instrumentation/jvm/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 20 | -------------------------------------------------------------------------------- /images/instrumentation/jvm/README.md: -------------------------------------------------------------------------------- 1 | # JVM instrumentation 2 | 3 | We currently do not have a Dash0 distro for Java. 4 | Rather, we use the upstream [OpenTelemetry Java agent](https://github.com/open-telemetry/opentelemetry-java-instrumentation). 5 | The version of the OTel Java agent to be used is specified in the [local `pom.xml`](./pom.xml) file. 6 | Maven can download the correct version of the OTel Java agent by running: 7 | 8 | ```shell 9 | ./mvnw dependency:copy-dependencies 10 | ``` -------------------------------------------------------------------------------- /images/instrumentation/jvm/build/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dash0hq/dash0-operator/8f9cc021630aadc4f37023b67a8fcbbe1cf2d5c0/images/instrumentation/jvm/build/.gitkeep -------------------------------------------------------------------------------- /images/instrumentation/jvm/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | com.dash0.instrumentation 6 | otel-javaagent-downloader 7 | 0.0.1-SNAPSHOT 8 | pom 9 | 10 | 11 | io.opentelemetry.javaagent 12 | opentelemetry-javaagent 13 | 2.16.0 14 | 15 | 16 | 17 | 18 | 19 | maven-dependency-plugin 20 | 21 | 22 | install 23 | 24 | copy-dependencies 25 | 26 | 27 | ${project.build.directory} 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /images/instrumentation/node.js/.gitignore: -------------------------------------------------------------------------------- 1 | dash0hq-opentelemetry-*.tgz 2 | -------------------------------------------------------------------------------- /images/instrumentation/node.js/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | cd "$(dirname "${BASH_SOURCE[0]}")" 5 | 6 | if [[ "${USE_LOCAL_SOURCES_FOR_NODEJS_DISTRIBUTION:-}" = "true" ]]; then 7 | echo "Node.js: using the local sources for @dash0hq/opentelemetry" 8 | rm -f dash0hq-opentelemetry-*.tgz 9 | pushd ../../../../opentelemetry-js-distribution > /dev/null 10 | npm pack 11 | popd > /dev/null 12 | cp ../../../../opentelemetry-js-distribution/dash0hq-opentelemetry-*.tgz . 13 | 14 | NPM_CONFIG_UPDATE_NOTIFIER=false \ 15 | npm install \ 16 | --package-lock-only \ 17 | --ignore-scripts \ 18 | --omit=dev \ 19 | --no-audit \ 20 | --no-fund=true \ 21 | dash0hq-opentelemetry-*.tgz 22 | else 23 | rm -f dash0hq-opentelemetry-*.tgz 24 | rm -rf node_modules 25 | fi 26 | -------------------------------------------------------------------------------- /images/instrumentation/node.js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "@dash0hq/opentelemetry": "2.0.5" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /images/instrumentation/start-injector-dev-container.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | set -euo pipefail 7 | 8 | cd "$(dirname "${BASH_SOURCE[0]}")" 9 | 10 | # See https://ziglang.org/download/ for the correct strings for zig_architecture. (Needs to match the architecture part 11 | # of the download URL.) 12 | ARCHITECTURE="${ARCHITECTURE:-arm64}" 13 | if [[ "$ARCHITECTURE" = arm64 ]]; then 14 | docker_platform=linux/arm64 15 | zig_architecture=aarch64 16 | elif [[ "$ARCHITECTURE" = x86_64 ]]; then 17 | docker_platform=linux/amd64 18 | zig_architecture=x86_64 19 | else 20 | echo "The architecture $ARCHITECTURE is not supported." 21 | exit 1 22 | fi 23 | 24 | image_name="dash0-injector-dev-$ARCHITECTURE" 25 | docker rmi -f "$image_name" 2> /dev/null || true 26 | docker build \ 27 | --platform "$docker_platform" \ 28 | --build-arg "zig_architecture=${zig_architecture}" \ 29 | -f Dockerfile-injector-development \ 30 | -t "$image_name" \ 31 | . 32 | 33 | container_name="$image_name" 34 | docker rm -f "$container_name" 2> /dev/null || true 35 | docker run \ 36 | --rm \ 37 | -it \ 38 | --name "$container_name" \ 39 | --volume "$(pwd):/home/dash0/instrumentation" \ 40 | "$image_name" \ 41 | /bin/bash 42 | -------------------------------------------------------------------------------- /images/instrumentation/test/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .containers_to_be_deleted_at_end 3 | .container_images_to_be_deleted_at_end 4 | -------------------------------------------------------------------------------- /images/instrumentation/test/.nvmrc: -------------------------------------------------------------------------------- 1 | 24 2 | -------------------------------------------------------------------------------- /images/instrumentation/test/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "avoid", 3 | "quoteProps": "as-needed", 4 | "printWidth": 120, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "all" 8 | } 9 | -------------------------------------------------------------------------------- /images/instrumentation/test/README.md: -------------------------------------------------------------------------------- 1 | Instumentation Image Integration Tests 2 | ====================================== 3 | 4 | This directory contains integration tests for the instrumentation image. 5 | The difference to images/instrumentation/injector/test is that the latter tests the ld-preload injector in isolation 6 | while the tests in this directory test the complete instrumentation image. 7 | The tests in this directory also cover a wider variety of base images. 8 | 9 | Usage 10 | ----- 11 | 12 | * `npm run test` to run all tests. 13 | * `ARCHITECTURES=arm64,x86_64 npm run test` to run tests for a subset of CPU architectures. 14 | * `RUNTIMES=node,java npm run test` to run tests for a subset of runtimes. 15 | * `RUNTIMES=node,java BASE_IMAGES=node:22-alpine,openjdk:24-jdk-bookworm npm run test` to run tests for a subset of 16 | runtimes and only for a subset of base images. 17 | * `TEST_CASES=existing,otel-resource npm run test` to only run tests cases whose names contain one of the provided 18 | strings. Can be combined with `ARCHITECTURES`, `RUNTIMES` etc. 19 | * Set `PRINT_DOCKER_OUTPUT=true` to always include the output from docker build and docker run. Otherwise the output is 20 | only printed to stdout in case of errors. 21 | -------------------------------------------------------------------------------- /images/instrumentation/test/c/.dockerignore: -------------------------------------------------------------------------------- 1 | *.o 2 | -------------------------------------------------------------------------------- /images/instrumentation/test/c/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | -------------------------------------------------------------------------------- /images/instrumentation/test/c/Dockerfile: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | ARG instrumentation_image=dash0-instrumentation:latest 5 | ARG base_image=alpine:3.21.3 6 | 7 | FROM ${instrumentation_image} AS init 8 | 9 | FROM ${base_image} 10 | 11 | # Need to repeat ARG base_image since build args are cleared by FROM. 12 | ARG base_image 13 | 14 | # test cases where the OTel SDK/distro exists but is not accessible. 15 | RUN case ${base_image} in \ 16 | *alpine*) apk update && apk upgrade --no-cache && apk add --no-cache build-base ;; \ 17 | *) apt-get update && apt-get install -y --no-install-recommends build-essential && apt-get clean; \ 18 | esac 19 | 20 | COPY Makefile . 21 | COPY test-cases /test-cases 22 | 23 | RUN make 24 | 25 | # The following lines emulate the behavior of running the instrumentation image as a Kubernetes init container and 26 | # setting the LD_PRELOAD environment variable via the operator. 27 | COPY --from=init /dash0-init-container/*.so /__dash0__/ 28 | COPY --from=init /dash0-init-container/instrumentation /__dash0__/instrumentation 29 | ENV LD_PRELOAD=/__dash0__/dash0_injector.so -------------------------------------------------------------------------------- /images/instrumentation/test/c/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | ARCH := $(shell uname -m) 5 | CFLAGS ?= -Wall -Werror -Wextra -O2 6 | 7 | TEST_CASES_DIR := test-cases 8 | SRC_EXT := c 9 | 10 | OS := $(shell uname -s) 11 | SHELL := sh 12 | 13 | TEST_SOURCES := $(wildcard $(TEST_CASES_DIR)/**/*.$(SRC_EXT)) 14 | # $(info TEST_SOURCES $(TEST_SOURCES)) 15 | TEST_OBJECTS := $(patsubst %.c,%.o,$(TEST_SOURCES)) 16 | # $(info TEST_OBJECTS $(TEST_OBJECTS)) 17 | TEST_CASE_NAMES := $(sort $(patsubst test-cases/%/,%,$(dir $(TEST_SOURCES)))) 18 | # $(info TEST_CASE_NAMES $(TEST_CASE_NAMES)) 19 | 20 | .PHONY: all 21 | all: clean build 22 | 23 | .PHONY: clean 24 | clean: 25 | @rm -f $(TEST_OBJECTS) 26 | 27 | .PHONY: build 28 | clean: 29 | build: $(TEST_CASE_NAMES) 30 | 31 | $(TEST_CASE_NAMES): 32 | $(CC) $(CFLAGS) $(TEST_CASES_DIR)/$@/app.c -o $(TEST_CASES_DIR)/$@/app.o $(DEBUG) $^ 33 | @chmod 755 $(TEST_CASES_DIR)/$@/app.o 34 | 35 | -------------------------------------------------------------------------------- /images/instrumentation/test/c/base-images: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | alpine:3.21.3 5 | debian:bookworm-slim 6 | -------------------------------------------------------------------------------- /images/instrumentation/test/c/test-cases/env-api/.env: -------------------------------------------------------------------------------- 1 | EXISTING_VAR_1=original-value-1 2 | EXISTING_VAR_2=original-value-2 3 | EXISTING_VAR_3=original-value-3 4 | EXISTING_VAR_4=original-value-4 5 | EXISTING_VAR_5=original-value-5 6 | EXISTING_VAR_6=original-value-6 7 | -------------------------------------------------------------------------------- /images/instrumentation/test/c/test-cases/environ-reallocation/.env: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dash0hq/dash0-operator/8f9cc021630aadc4f37023b67a8fcbbe1cf2d5c0/images/instrumentation/test/c/test-cases/environ-reallocation/.env -------------------------------------------------------------------------------- /images/instrumentation/test/c/test-cases/existing-env-var-return-unmodified-secure-getenv/.env: -------------------------------------------------------------------------------- 1 | AN_ENVIRONMENT_VARIABLE=value 2 | -------------------------------------------------------------------------------- /images/instrumentation/test/c/test-cases/existing-env-var-return-unmodified-secure-getenv/app.c: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #define _GNU_SOURCE 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | int main() { 11 | char* name = "AN_ENVIRONMENT_VARIABLE"; 12 | char* actual = secure_getenv(name); 13 | char* expected = "value"; 14 | if (actual == NULL) { 15 | printf("Unexpected value for the environment variable %s -- expected: %s, was: null\n", name, expected); 16 | return 1; 17 | } 18 | if (strcmp(expected, actual) != 0) { 19 | printf("Unexpected value for the environment variable %s -- expected: %s, was: %s\n", name, expected, actual); 20 | return 1; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /images/instrumentation/test/c/test-cases/existing-env-var-return-unmodified/.env: -------------------------------------------------------------------------------- 1 | AN_ENVIRONMENT_VARIABLE=value 2 | -------------------------------------------------------------------------------- /images/instrumentation/test/c/test-cases/existing-env-var-return-unmodified/app.c: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | int main() { 9 | char* name = "AN_ENVIRONMENT_VARIABLE"; 10 | char* actual = getenv(name); 11 | char* expected = "value"; 12 | if (actual == NULL) { 13 | printf("Unexpected value for the environment variable %s -- expected: %s, was: null\n", name, expected); 14 | return 1; 15 | } 16 | if (strcmp(expected, actual) != 0) { 17 | printf("Unexpected value for the environment variable %s -- expected: %s, was: %s\n", name, expected, actual); 18 | return 1; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /images/instrumentation/test/c/test-cases/non-existing-env-var-return-null/.env: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dash0hq/dash0-operator/8f9cc021630aadc4f37023b67a8fcbbe1cf2d5c0/images/instrumentation/test/c/test-cases/non-existing-env-var-return-null/.env -------------------------------------------------------------------------------- /images/instrumentation/test/c/test-cases/non-existing-env-var-return-null/app.c: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #include 5 | #include 6 | 7 | int main() { 8 | char* name = "DOES_NOT_EXIST"; 9 | char* actual = getenv(name); 10 | if (actual != NULL) { 11 | printf("Unexpected value for the environment variable %s -- expected: null, was: %s\n", name, actual); 12 | return 1; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /images/instrumentation/test/c/test-cases/otel-resource-attributes-env-var-already-set/.env: -------------------------------------------------------------------------------- 1 | DASH0_NAMESPACE_NAME=namespace 2 | DASH0_POD_UID=pod_uid 3 | DASH0_POD_NAME=pod_name 4 | DASH0_CONTAINER_NAME=container_name 5 | OTEL_RESOURCE_ATTRIBUTES=key1=value1,key2=value2 6 | -------------------------------------------------------------------------------- /images/instrumentation/test/c/test-cases/otel-resource-attributes-env-var-already-set/app.c: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | int main() { 9 | char* name = "OTEL_RESOURCE_ATTRIBUTES"; 10 | char* actual = getenv(name); 11 | char* expected = "k8s.namespace.name=namespace,k8s.pod.name=pod_name,k8s.pod.uid=pod_uid,k8s.container.name=container_name,key1=value1,key2=value2"; 12 | if (actual == NULL) { 13 | printf("Unexpected value for the environment variable %s -- expected: %s, was: null\n", name, expected); 14 | return 1; 15 | } 16 | if (strcmp(expected, actual) != 0) { 17 | printf("Unexpected value for the environment variable %s -- expected: %s, was: %s\n", name, expected, actual); 18 | return 1; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /images/instrumentation/test/c/test-cases/otel-resource-attributes-unset-secure-getenv/.env: -------------------------------------------------------------------------------- 1 | DASH0_NAMESPACE_NAME=namespace 2 | DASH0_POD_UID=pod_uid 3 | DASH0_POD_NAME=pod_name 4 | DASH0_CONTAINER_NAME=container_name 5 | -------------------------------------------------------------------------------- /images/instrumentation/test/c/test-cases/otel-resource-attributes-unset-secure-getenv/app.c: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #define _GNU_SOURCE 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | int main() { 11 | // TODO We do not hook into secure_getenv, so this test case currently fails. 12 | // For now, it is disabled by default. 13 | printf("! test case disabled: otel-resource-attributes-unset-secure-getenv\n"); 14 | return 0; 15 | 16 | char* name = "OTEL_RESOURCE_ATTRIBUTES"; 17 | char* actual = secure_getenv(name); 18 | char* expected = "k8s.namespace.name=namespace,k8s.pod.name=pod_name,k8s.pod.uid=pod_uid,k8s.container.name=container_name"; 19 | if (actual == NULL) { 20 | printf("Unexpected value for the environment variable %s -- expected: %s, was: null\n", name, expected); 21 | return 1; 22 | } 23 | if (strcmp(expected, actual) != 0) { 24 | printf("Unexpected value for the environment variable %s -- expected: %s, was: %s\n", name, expected, actual); 25 | return 1; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /images/instrumentation/test/c/test-cases/otel-resource-attributes-unset/.env: -------------------------------------------------------------------------------- 1 | DASH0_NAMESPACE_NAME=namespace 2 | DASH0_POD_UID=pod_uid 3 | DASH0_POD_NAME=pod_name 4 | DASH0_CONTAINER_NAME=container_name 5 | -------------------------------------------------------------------------------- /images/instrumentation/test/c/test-cases/otel-resource-attributes-unset/app.c: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | int main() { 9 | char* name = "OTEL_RESOURCE_ATTRIBUTES"; 10 | char* actual = getenv(name); 11 | char* expected = "k8s.namespace.name=namespace,k8s.pod.name=pod_name,k8s.pod.uid=pod_uid,k8s.container.name=container_name"; 12 | if (actual == NULL) { 13 | printf("Unexpected value for the environment variable %s -- expected: %s, was: null\n", name, expected); 14 | return 1; 15 | } 16 | if (strcmp(expected, actual) != 0) { 17 | printf("Unexpected value for the environment variable %s -- expected: %s, was: %s\n", name, expected, actual); 18 | return 1; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /images/instrumentation/test/dotnet/.gitignore: -------------------------------------------------------------------------------- 1 | obj/ 2 | bin/ 3 | -------------------------------------------------------------------------------- /images/instrumentation/test/dotnet/Dockerfile: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | ARG instrumentation_image=dash0-instrumentation:latest 5 | ARG base_image_build=mcr.microsoft.com/dotnet/sdk:9.0-bookworm-slim 6 | ARG base_image_run=mcr.microsoft.com/dotnet/aspnet:9.0-bookworm-slim 7 | 8 | FROM ${instrumentation_image} AS init 9 | 10 | FROM ${base_image_build} AS build 11 | 12 | COPY test-cases /test-cases 13 | 14 | WORKDIR / 15 | 16 | # run dotnet restore for all test-cases/apps as a separate image layer (speeds up docker build) 17 | RUN for test in /test-cases/*; do \ 18 | cd "/${test}" && \ 19 | dotnet restore \ 20 | ; done 21 | # build all test-cases/apps 22 | RUN for test in /test-cases/*; do \ 23 | cd "/${test}" && \ 24 | dotnet publish -o . \ 25 | ; done 26 | 27 | # build the final image 28 | FROM ${base_image_run} 29 | 30 | COPY --from=build /test-cases /test-cases 31 | 32 | # The following lines emulate the behavior of running the instrumentation image as a Kubernetes init container and 33 | # setting the LD_PRELOAD environment variable via the operator. 34 | COPY --from=init /dash0-init-container/*.so /__dash0__/ 35 | COPY --from=init /dash0-init-container/instrumentation /__dash0__/instrumentation 36 | ENV LD_PRELOAD=/__dash0__/dash0_injector.so 37 | -------------------------------------------------------------------------------- /images/instrumentation/test/dotnet/base-images: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | # See https://mcr.microsoft.com/artifact/mar/dotnet/sdk/about and 5 | # https://mcr.microsoft.com/en-us/artifact/mar/dotnet/sdk/tags to find tags for the build image. 6 | # See https://mcr.microsoft.com/artifact/mar/dotnet/aspnet/about and 7 | # https://mcr.microsoft.com/en-us/artifact/mar/dotnet/aspnet/tags to find tags for the run image. 8 | 9 | # one pair of build and run base images per line 10 | mcr.microsoft.com/dotnet/sdk:9.0-alpine,mcr.microsoft.com/dotnet/aspnet:9.0-alpine 11 | mcr.microsoft.com/dotnet/sdk:9.0-bookworm-slim,mcr.microsoft.com/dotnet/aspnet:9.0-bookworm-slim 12 | -------------------------------------------------------------------------------- /images/instrumentation/test/dotnet/test-cases/no-op-test/.dockerignore: -------------------------------------------------------------------------------- 1 | obj/ 2 | bin/ 3 | -------------------------------------------------------------------------------- /images/instrumentation/test/dotnet/test-cases/no-op-test/.env: -------------------------------------------------------------------------------- 1 | # Enable experimental .NET injection, this feature is currently opt-in. 2 | DASH0_EXPERIMENTAL_DOTNET_INJECTION=true 3 | DASH0_INJECTOR_DEBUG=true 4 | -------------------------------------------------------------------------------- /images/instrumentation/test/dotnet/test-cases/no-op-test/app.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | Exe 4 | net9.0 5 | enable 6 | enable 7 | 8 | -------------------------------------------------------------------------------- /images/instrumentation/test/eslint.config.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | import eslint from '@eslint/js'; 4 | import tseslint from 'typescript-eslint'; 5 | 6 | export default tseslint.config( 7 | // 8 | eslint.configs.recommended, 9 | tseslint.configs.recommended, 10 | { 11 | ignores: ['node/**/*'] 12 | }, 13 | { 14 | rules: { 15 | 'no-case-declarations': 'off' 16 | } 17 | } 18 | ); 19 | -------------------------------------------------------------------------------- /images/instrumentation/test/jvm/Dockerfile: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | ARG instrumentation_image=dash0-instrumentation:latest 5 | ARG base_image=openjdk:24-jdk-bookworm 6 | 7 | FROM ${instrumentation_image} AS init 8 | 9 | FROM ${base_image} 10 | 11 | COPY jvm-test-utils /jvm-test-utils 12 | COPY test-cases /test-cases 13 | 14 | RUN export JAVA_HOME=$(which java | xargs dirname | xargs dirname) 15 | 16 | WORKDIR /jvm-test-utils 17 | RUN javac src/com/dash0/injector/testutils/*.java 18 | 19 | WORKDIR / 20 | RUN for test in /test-cases/*; do \ 21 | cd "/${test}" && \ 22 | cp -R /jvm-test-utils/src/* . && \ 23 | javac \ 24 | -cp /jvm-test-utils/src:"/${test}" \ 25 | Main.java && \ 26 | jar --create --file app.jar --manifest MANIFEST.MF -C . . \ 27 | ; done 28 | 29 | # The following lines emulate the behavior of running the instrumentation image as a Kubernetes init container and 30 | # setting the LD_PRELOAD environment variable via the operator. 31 | COPY --from=init /dash0-init-container/*.so /__dash0__/ 32 | COPY --from=init /dash0-init-container/instrumentation /__dash0__/instrumentation 33 | ENV LD_PRELOAD=/__dash0__/dash0_injector.so 34 | -------------------------------------------------------------------------------- /images/instrumentation/test/jvm/base-images: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | # one base image per line 5 | openjdk:24-jdk-bookworm 6 | openjdk:21-jdk-bookworm 7 | openjdk:17-jdk-bullseye 8 | -------------------------------------------------------------------------------- /images/instrumentation/test/jvm/jvm-test-utils/src/com/dash0/injector/testutils/TestUtils.java: -------------------------------------------------------------------------------- 1 | package com.dash0.injector.testutils; 2 | 3 | public class TestUtils { 4 | 5 | public static void verifyEnvVar(String envVarName, String expected) { 6 | compare(envVarName, "environment variable", expected, System.getenv(envVarName)); 7 | } 8 | 9 | public static void verifyProperty(String propertyName, String expected) { 10 | compare(propertyName, "property", expected, System.getProperty(propertyName)); 11 | } 12 | 13 | public static void compare(String propertyName, String label, String expected, String actual) { 14 | if (expected == null) { 15 | if (actual != null) { 16 | throw new RuntimeException( 17 | String.format( 18 | "Unexpected value for the %s \"%s\" -- expected: null, was: \"%s\"", 19 | label, 20 | propertyName, 21 | actual 22 | )); 23 | } 24 | return; 25 | } 26 | if (!expected.equals(actual)) { 27 | throw new RuntimeException( 28 | String.format( 29 | "Unexpected value for the %s \"%s\" -- expected: \"%s\", was: \"%s\"", 30 | label, 31 | propertyName, 32 | expected, 33 | actual 34 | )); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /images/instrumentation/test/jvm/test-cases/.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | -------------------------------------------------------------------------------- /images/instrumentation/test/jvm/test-cases/existing-env-var-return-unmodified/.env: -------------------------------------------------------------------------------- 1 | AN_ENVIRONMENT_VARIABLE=value 2 | DASH0_NAMESPACE_NAME=namespace 3 | DASH0_POD_UID=pod_uid 4 | DASH0_POD_NAME=pod_name 5 | DASH0_CONTAINER_NAME=container_name 6 | OTEL_LOGS_EXPORTER=none 7 | OTEL_METRICS_EXPORTER=none 8 | OTEL_TRACES_EXPORTER=none 9 | -------------------------------------------------------------------------------- /images/instrumentation/test/jvm/test-cases/existing-env-var-return-unmodified/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: Main 3 | -------------------------------------------------------------------------------- /images/instrumentation/test/jvm/test-cases/existing-env-var-return-unmodified/Main.java: -------------------------------------------------------------------------------- 1 | import static com.dash0.injector.testutils.TestUtils.*; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | verifyEnvVar("AN_ENVIRONMENT_VARIABLE", "value"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /images/instrumentation/test/jvm/test-cases/java-tool-options-otel-resource-attributes-already-set/.env: -------------------------------------------------------------------------------- 1 | DASH0_NAMESPACE_NAME=namespace 2 | DASH0_POD_UID=pod_uid 3 | DASH0_POD_NAME=pod_name 4 | DASH0_CONTAINER_NAME=container_name 5 | OTEL_LOGS_EXPORTER=none 6 | OTEL_METRICS_EXPORTER=none 7 | OTEL_TRACES_EXPORTER=none 8 | JAVA_TOOL_OPTIONS=-Danother.system.property=value -Dotel.resource.attributes=key1=value1,key2=value2 9 | -------------------------------------------------------------------------------- /images/instrumentation/test/jvm/test-cases/java-tool-options-otel-resource-attributes-already-set/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: Main 3 | -------------------------------------------------------------------------------- /images/instrumentation/test/jvm/test-cases/java-tool-options-otel-resource-attributes-already-set/Main.java: -------------------------------------------------------------------------------- 1 | import static com.dash0.injector.testutils.TestUtils.*; 2 | 3 | public class Main { 4 | public static void main(String[] args) { 5 | // Here we just verify that other existing -D properties are not affected by the injector. 6 | verifyProperty("another.system.property", "value"); 7 | 8 | // The injector will merge the existing key-value pairs from -Dotel.resource.attributes with "our" key-value 9 | // pairs. 10 | verifyProperty( 11 | "otel.resource.attributes", 12 | "key1=value1,key2=value2,k8s.namespace.name=namespace,k8s.pod.name=pod_name,k8s.pod.uid=pod_uid,k8s.container.name=container_name" 13 | ); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /images/instrumentation/test/jvm/test-cases/java-tool-options-otel-resource-attributes-unset/.env: -------------------------------------------------------------------------------- 1 | DASH0_NAMESPACE_NAME=namespace 2 | DASH0_POD_UID=pod_uid 3 | DASH0_POD_NAME=pod_name 4 | DASH0_CONTAINER_NAME=container_name 5 | OTEL_LOGS_EXPORTER=none 6 | OTEL_METRICS_EXPORTER=none 7 | OTEL_TRACES_EXPORTER=none 8 | JAVA_TOOL_OPTIONS=-Danother.system.property=value 9 | -------------------------------------------------------------------------------- /images/instrumentation/test/jvm/test-cases/java-tool-options-otel-resource-attributes-unset/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: Main 3 | -------------------------------------------------------------------------------- /images/instrumentation/test/jvm/test-cases/java-tool-options-otel-resource-attributes-unset/Main.java: -------------------------------------------------------------------------------- 1 | import static com.dash0.injector.testutils.TestUtils.*; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | // Here we just verify that other existing -D properties are not affected by the injector. 7 | verifyProperty("another.system.property", "value"); 8 | 9 | // Since -Dotel.resource.attributes is not provided by the application under monitoring, the injector should 10 | // simply supply the resource attributes set by Dash0. 11 | verifyProperty( 12 | "otel.resource.attributes", 13 | "k8s.namespace.name=namespace,k8s.pod.name=pod_name,k8s.pod.uid=pod_uid,k8s.container.name=container_name" 14 | ); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /images/instrumentation/test/jvm/test-cases/java-tool-options-otel-resource-attributes-unset/system.properties: -------------------------------------------------------------------------------- 1 | -Danother.system.property=value 2 | -------------------------------------------------------------------------------- /images/instrumentation/test/jvm/test-cases/non-existing-env-var-return-null/.env: -------------------------------------------------------------------------------- 1 | DASH0_NAMESPACE_NAME=namespace 2 | DASH0_POD_UID=pod_uid 3 | DASH0_POD_NAME=pod_name 4 | DASH0_CONTAINER_NAME=container_name 5 | OTEL_LOGS_EXPORTER=none 6 | OTEL_METRICS_EXPORTER=none 7 | OTEL_TRACES_EXPORTER=none 8 | -------------------------------------------------------------------------------- /images/instrumentation/test/jvm/test-cases/non-existing-env-var-return-null/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: Main 3 | -------------------------------------------------------------------------------- /images/instrumentation/test/jvm/test-cases/non-existing-env-var-return-null/Main.java: -------------------------------------------------------------------------------- 1 | import static com.dash0.injector.testutils.TestUtils.*; 2 | 3 | public class Main { 4 | public static void main(String[] args) { 5 | verifyEnvVar("UNDEFINED_ENVIRONMENT_VARIABLE", null); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /images/instrumentation/test/jvm/test-cases/otel-resource-attributes-env-var-already-set/.env: -------------------------------------------------------------------------------- 1 | DASH0_NAMESPACE_NAME=namespace 2 | DASH0_POD_UID=pod_uid 3 | DASH0_POD_NAME=pod_name 4 | DASH0_CONTAINER_NAME=container_name 5 | OTEL_LOGS_EXPORTER=none 6 | OTEL_METRICS_EXPORTER=none 7 | OTEL_TRACES_EXPORTER=none 8 | OTEL_RESOURCE_ATTRIBUTES=key1=value1,key2=value2 9 | -------------------------------------------------------------------------------- /images/instrumentation/test/jvm/test-cases/otel-resource-attributes-env-var-already-set/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: Main 3 | -------------------------------------------------------------------------------- /images/instrumentation/test/jvm/test-cases/otel-resource-attributes-env-var-already-set/Main.java: -------------------------------------------------------------------------------- 1 | import static com.dash0.injector.testutils.TestUtils.*; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | // The injector will not override the environment variable OTEL_RESOURCE_ATTRIBUTES, but that is ignored by the 7 | // OTel Java SDK anyway. 8 | verifyEnvVar("OTEL_RESOURCE_ATTRIBUTES", "key1=value1,key2=value2"); 9 | 10 | // The injector will inject -Dotel.resource.attributes into JAVA_TOOL_OPTIONS, independent of the 11 | // OTEL_RESOURCE_ATTRIBUTES environment variable. 12 | verifyProperty( 13 | "otel.resource.attributes", 14 | "k8s.namespace.name=namespace,k8s.pod.name=pod_name,k8s.pod.uid=pod_uid,k8s.container.name=container_name" 15 | ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /images/instrumentation/test/node/Dockerfile: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | ARG instrumentation_image=dash0-instrumentation:latest 5 | ARG base_image=node:20.19.0-bookworm 6 | 7 | FROM ${instrumentation_image} AS init 8 | 9 | FROM ${base_image} 10 | 11 | COPY test-cases /test-cases 12 | 13 | # The following lines emulate the behavior of running the instrumentation image as a Kubernetes init container and 14 | # setting the LD_PRELOAD environment variable via the operator. 15 | COPY --from=init /dash0-init-container/*.so /__dash0__/ 16 | COPY --from=init /dash0-init-container/instrumentation /__dash0__/instrumentation 17 | ENV LD_PRELOAD=/__dash0__/dash0_injector.so 18 | 19 | -------------------------------------------------------------------------------- /images/instrumentation/test/node/base-images: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | # one base image per line 5 | node:22-alpine 6 | node:22-bookworm-slim 7 | node:22-bullseye-slim 8 | node:20-alpine 9 | node:20-bookworm-slim 10 | node:18-alpine 11 | node:16-bullseye-slim 12 | -------------------------------------------------------------------------------- /images/instrumentation/test/node/test-cases/existing-env-var-return-unmodified/.env: -------------------------------------------------------------------------------- 1 | AN_ENVIRONMENT_VARIABLE=value 2 | DASH0_OTEL_COLLECTOR_BASE_URL=http://localhost:4318 3 | DASH0_FLUSH_ON_EMPTY_EVENT_LOOP=false 4 | DASH0_DEBUG=true 5 | DASH0_NAMESPACE_NAME=namespace 6 | DASH0_POD_UID=pod_uid 7 | DASH0_POD_NAME=pod_name 8 | DASH0_CONTAINER_NAME=container_name 9 | -------------------------------------------------------------------------------- /images/instrumentation/test/node/test-cases/existing-env-var-return-unmodified/index.js: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | const process = require('node:process'); 5 | 6 | if (process.env['AN_ENVIRONMENT_VARIABLE'] !== 'value') { 7 | console.error(`Unexpected value for AN_ENVIRONMENT_VARIABLE: ${process.env['AN_ENVIRONMENT_VARIABLE']}`); 8 | process.exit(1); 9 | } 10 | -------------------------------------------------------------------------------- /images/instrumentation/test/node/test-cases/node-options-already-set/.env: -------------------------------------------------------------------------------- 1 | NODE_OPTIONS=--no-deprecation 2 | DASH0_OTEL_COLLECTOR_BASE_URL=http://localhost:4318 3 | DASH0_FLUSH_ON_EMPTY_EVENT_LOOP=false 4 | DASH0_DEBUG=true 5 | DASH0_NAMESPACE_NAME=namespace 6 | DASH0_POD_UID=pod_uid 7 | DASH0_POD_NAME=pod_name 8 | DASH0_CONTAINER_NAME=container_name 9 | -------------------------------------------------------------------------------- /images/instrumentation/test/node/test-cases/node-options-already-set/index.js: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | const process = require('node:process'); 5 | 6 | if ( 7 | process.env['NODE_OPTIONS'] !== 8 | '--require /__dash0__/instrumentation/node.js/node_modules/@dash0hq/opentelemetry --no-deprecation' 9 | ) { 10 | console.error(`Unexpected value for NODE_OPTIONS: ${process.env['NODE_OPTIONS']}`); 11 | process.exit(1); 12 | } 13 | -------------------------------------------------------------------------------- /images/instrumentation/test/node/test-cases/node-options-unset/.env: -------------------------------------------------------------------------------- 1 | DASH0_OTEL_COLLECTOR_BASE_URL=http://localhost:4318 2 | DASH0_DEBUG=true 3 | DASH0_FLUSH_ON_EMPTY_EVENT_LOOP=false 4 | DASH0_NAMESPACE_NAME=namespace 5 | DASH0_POD_UID=pod_uid 6 | DASH0_POD_NAME=pod_name 7 | DASH0_CONTAINER_NAME=container_name 8 | -------------------------------------------------------------------------------- /images/instrumentation/test/node/test-cases/node-options-unset/index.js: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | const process = require('node:process'); 5 | 6 | if ( 7 | process.env['NODE_OPTIONS'] !== '--require /__dash0__/instrumentation/node.js/node_modules/@dash0hq/opentelemetry' 8 | ) { 9 | console.error(`Unexpected value for NODE_OPTIONS: ${process.env['NODE_OPTIONS']}`); 10 | process.exit(1); 11 | } 12 | -------------------------------------------------------------------------------- /images/instrumentation/test/node/test-cases/non-existing-env-var-return-undefined/.env: -------------------------------------------------------------------------------- 1 | DASH0_OTEL_COLLECTOR_BASE_URL=http://localhost:4318 2 | DASH0_FLUSH_ON_EMPTY_EVENT_LOOP=false 3 | DASH0_DEBUG=true 4 | DASH0_NAMESPACE_NAME=namespace 5 | DASH0_POD_UID=pod_uid 6 | DASH0_POD_NAME=pod_name 7 | DASH0_CONTAINER_NAME=container_name 8 | -------------------------------------------------------------------------------- /images/instrumentation/test/node/test-cases/non-existing-env-var-return-undefined/index.js: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | const process = require('node:process'); 5 | const envVarName = 'UNDEFINED_ENVIRONMENT_VARIABLE'; 6 | const expectedValue = undefined; 7 | 8 | if (process.env[envVarName] !== expectedValue) { 9 | console.error( 10 | `Unexpected value for ${envVarName}: expected: '${expectedValue}'; actual: '${process.env[envVarName]}'`, 11 | ); 12 | process.exit(1); 13 | } 14 | -------------------------------------------------------------------------------- /images/instrumentation/test/node/test-cases/otel-resource-attributes-already-set-but-source-attributes-unset/.env: -------------------------------------------------------------------------------- 1 | DASH0_OTEL_COLLECTOR_BASE_URL=http://localhost:4318 2 | DASH0_FLUSH_ON_EMPTY_EVENT_LOOP=false 3 | DASH0_DEBUG=true 4 | OTEL_RESOURCE_ATTRIBUTES=key1=value1,key2=value2 5 | -------------------------------------------------------------------------------- /images/instrumentation/test/node/test-cases/otel-resource-attributes-already-set-but-source-attributes-unset/index.js: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | const process = require('node:process'); 5 | const envVarName = 'OTEL_RESOURCE_ATTRIBUTES'; 6 | const expectedValue = 'key1=value1,key2=value2'; 7 | 8 | if (process.env[envVarName] !== expectedValue) { 9 | console.error( 10 | `Unexpected value for ${envVarName}: expected: '${expectedValue}'; actual: '${process.env[envVarName]}'`, 11 | ); 12 | process.exit(1); 13 | } 14 | -------------------------------------------------------------------------------- /images/instrumentation/test/node/test-cases/otel-resource-attributes-already-set/.env: -------------------------------------------------------------------------------- 1 | DASH0_OTEL_COLLECTOR_BASE_URL=http://localhost:4318 2 | DASH0_FLUSH_ON_EMPTY_EVENT_LOOP=false 3 | DASH0_DEBUG=true 4 | DASH0_NAMESPACE_NAME=namespace 5 | DASH0_POD_UID=pod_uid 6 | DASH0_POD_NAME=pod_name 7 | DASH0_CONTAINER_NAME=container_name 8 | OTEL_RESOURCE_ATTRIBUTES=key1=value1,key2=value2 9 | -------------------------------------------------------------------------------- /images/instrumentation/test/node/test-cases/otel-resource-attributes-already-set/index.js: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | const process = require('node:process'); 5 | const envVarName = 'OTEL_RESOURCE_ATTRIBUTES'; 6 | const expectedValue = 7 | 'k8s.namespace.name=namespace,k8s.pod.name=pod_name,k8s.pod.uid=pod_uid,k8s.container.name=container_name,key1=value1,key2=value2'; 8 | 9 | if (process.env[envVarName] !== expectedValue) { 10 | console.error( 11 | `Unexpected value for ${envVarName}: expected: '${expectedValue}'; actual: '${process.env[envVarName]}'`, 12 | ); 13 | process.exit(1); 14 | } 15 | -------------------------------------------------------------------------------- /images/instrumentation/test/node/test-cases/otel-resource-attributes-unset-and-source-attributes-unset/.env: -------------------------------------------------------------------------------- 1 | DASH0_OTEL_COLLECTOR_BASE_URL=http://localhost:4318 2 | DASH0_FLUSH_ON_EMPTY_EVENT_LOOP=false 3 | DASH0_DEBUG=true 4 | -------------------------------------------------------------------------------- /images/instrumentation/test/node/test-cases/otel-resource-attributes-unset-and-source-attributes-unset/index.js: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | const process = require('node:process'); 5 | const envVarName = 'OTEL_RESOURCE_ATTRIBUTES'; 6 | const expectedValue = undefined; 7 | 8 | if (process.env[envVarName] !== expectedValue) { 9 | console.error( 10 | `Unexpected value for ${envVarName}: expected: '${expectedValue}'; actual: '${process.env[envVarName]}'`, 11 | ); 12 | process.exit(1); 13 | } 14 | -------------------------------------------------------------------------------- /images/instrumentation/test/node/test-cases/otel-resource-attributes-unset/.env: -------------------------------------------------------------------------------- 1 | DASH0_OTEL_COLLECTOR_BASE_URL=http://localhost:4318 2 | DASH0_FLUSH_ON_EMPTY_EVENT_LOOP=false 3 | DASH0_DEBUG=true 4 | DASH0_NAMESPACE_NAME=namespace 5 | DASH0_POD_UID=pod_uid 6 | DASH0_POD_NAME=pod_name 7 | DASH0_CONTAINER_NAME=container_name 8 | -------------------------------------------------------------------------------- /images/instrumentation/test/node/test-cases/otel-resource-attributes-unset/index.js: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | const process = require('node:process'); 5 | const envVarName = 'OTEL_RESOURCE_ATTRIBUTES'; 6 | const expectedValue = 7 | 'k8s.namespace.name=namespace,k8s.pod.name=pod_name,k8s.pod.uid=pod_uid,k8s.container.name=container_name'; 8 | 9 | if (process.env[envVarName] !== expectedValue) { 10 | console.error( 11 | `Unexpected value for ${envVarName}: expected: '${expectedValue}'; actual: '${process.env[envVarName]}'`, 12 | ); 13 | process.exit(1); 14 | } 15 | -------------------------------------------------------------------------------- /images/instrumentation/test/node/test-cases/verify-distro-is-loaded/.env: -------------------------------------------------------------------------------- 1 | DASH0_OTEL_COLLECTOR_BASE_URL=http://localhost:4318 2 | DASH0_FLUSH_ON_EMPTY_EVENT_LOOP=false 3 | DASH0_DEBUG=true 4 | DASH0_NAMESPACE_NAME=namespace 5 | DASH0_POD_UID=pod_uid 6 | DASH0_POD_NAME=pod_name 7 | DASH0_CONTAINER_NAME=container_name 8 | NODE_DEBUG=net 9 | -------------------------------------------------------------------------------- /images/instrumentation/test/node/test-cases/verify-distro-is-loaded/index.js: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | const process = require('node:process'); 5 | 6 | const loadedModules = Object.keys(require.cache); 7 | if ( 8 | !loadedModules.includes( 9 | '/__dash0__/instrumentation/node.js/node_modules/@dash0hq/opentelemetry/dist/src/1.x/init.js', 10 | ) && 11 | !loadedModules.includes('/__dash0__/instrumentation/node.js/node_modules/@dash0hq/opentelemetry/dist/src/2.x/init.js') 12 | ) { 13 | console.error(`It looks like the Dash0 Node.js OpenTelemetry distribution has not been loaded.`); 14 | process.exit(1); 15 | } 16 | -------------------------------------------------------------------------------- /images/instrumentation/test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dash0-instrumentation-tests", 3 | "version": "1.0.0", 4 | "description": "TypeScript-based test runner for Dash0 instrumentation images", 5 | "main": "test-all.ts", 6 | "type": "module", 7 | "scripts": { 8 | "lint": "tsc && eslint", 9 | "test": "node --experimental-strip-types test-all.ts", 10 | "dev": "node --experimental-strip-types --watch test-all.ts" 11 | }, 12 | "dependencies": { 13 | "@supercharge/promise-pool": "^3.2.0", 14 | "@types/node": "^22.0.0", 15 | "chalk": "^5.4.1" 16 | }, 17 | "engines": { 18 | "node": ">=24" 19 | }, 20 | "devDependencies": { 21 | "@eslint/js": "^9.27.0", 22 | "eslint": "^9.27.0", 23 | "typescript": "^5.8.3", 24 | "typescript-eslint": "^8.32.1" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /images/instrumentation/test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "module": "ESNext", 5 | "moduleResolution": "Node", 6 | "allowSyntheticDefaultImports": true, 7 | "esModuleInterop": true, 8 | "strict": true, 9 | "skipLibCheck": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "resolveJsonModule": true, 12 | "allowImportingTsExtensions": true, 13 | "noEmit": true 14 | }, 15 | "include": [ 16 | "*.ts" 17 | ] 18 | } -------------------------------------------------------------------------------- /images/pkg/common/util.go: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package common // import "github.com/dash0hq/dash0-operator/images/pkg/common" 5 | 6 | const ( 7 | DefaultErrorMetricAttributeLength = 80 8 | ) 9 | 10 | func TruncateErrorForMetricAttribute(err error) string { 11 | return truncateError(err, DefaultErrorMetricAttributeLength) 12 | } 13 | 14 | func truncateError(err error, maxLength int) string { 15 | if err == nil { 16 | return "nil" 17 | } 18 | return truncateString(err.Error(), maxLength) 19 | } 20 | 21 | func truncateString(s string, length int) string { 22 | if len(s) <= length { 23 | return s 24 | } 25 | return s[:max(0, length)] 26 | } 27 | -------------------------------------------------------------------------------- /internal/startup/instrument_at_startup.go: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package startup 5 | 6 | import ( 7 | "context" 8 | 9 | "sigs.k8s.io/controller-runtime/pkg/log" 10 | "sigs.k8s.io/controller-runtime/pkg/manager" 11 | 12 | "github.com/dash0hq/dash0-operator/internal/instrumentation" 13 | ) 14 | 15 | // InstrumentAtStartupRunnable executes an unconditional apply/update of instrumentation for all workloads in 16 | // Dash0-enabled namespaces, according to the respective settings of the Dash0 monitoring resource in the namespace. 17 | // See godoc comment on Instrumenter#InstrumentAtStartup. 18 | type InstrumentAtStartupRunnable struct { 19 | manager manager.Manager 20 | instrumenter *instrumentation.Instrumenter 21 | } 22 | 23 | func NewInstrumentAtStartupRunnable( 24 | manager manager.Manager, 25 | instrumenter *instrumentation.Instrumenter, 26 | ) *InstrumentAtStartupRunnable { 27 | return &InstrumentAtStartupRunnable{ 28 | manager: manager, 29 | instrumenter: instrumenter, 30 | } 31 | } 32 | 33 | // NeedLeaderElection implements the LeaderElectionRunnable interface, which indicates 34 | // that the InstrumentAtStartupRunnable requires leader election. 35 | func (r *InstrumentAtStartupRunnable) NeedLeaderElection() bool { 36 | return true 37 | } 38 | 39 | // Start runs the instrumentation procedure. 40 | func (r *InstrumentAtStartupRunnable) Start(ctx context.Context) error { 41 | logger := log.FromContext(ctx) 42 | r.instrumenter.Client = r.manager.GetClient() 43 | r.instrumenter.InstrumentAtStartup(ctx, &logger) 44 | return nil 45 | } 46 | -------------------------------------------------------------------------------- /internal/util/cluster.go: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package util 5 | 6 | import ( 7 | "context" 8 | 9 | "github.com/go-logr/logr" 10 | corev1 "k8s.io/api/core/v1" 11 | "sigs.k8s.io/controller-runtime/pkg/client" 12 | ) 13 | 14 | func ReadPseudoClusterUID(ctx context.Context, k8sClient client.Client, logger *logr.Logger) string { 15 | kubeSystemNamespace := &corev1.Namespace{} 16 | if err := k8sClient.Get(ctx, client.ObjectKey{Name: "kube-system"}, kubeSystemNamespace); err != nil { 17 | msg := "unable to get the kube-system namespace uid" 18 | logger.Error(err, msg) 19 | return "unknown" 20 | } 21 | return string(kubeSystemNamespace.UID) 22 | } 23 | -------------------------------------------------------------------------------- /internal/util/constants.go: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package util 5 | 6 | import "fmt" 7 | 8 | type WorkloadModifierActor string 9 | 10 | const ( 11 | AuthorizationHeaderName = "Authorization" 12 | ContentTypeHeaderName = "Content-Type" 13 | AcceptHeaderName = "Accept" 14 | ApplicationJsonMediaType = "application/json" 15 | Dash0DatasetHeaderName = "Dash0-Dataset" 16 | DatasetDefault = "default" 17 | FieldManager = "dash0-operator" 18 | 19 | ActorController WorkloadModifierActor = "controller" 20 | ActorWebhook WorkloadModifierActor = "webhook" 21 | 22 | AppKubernetesIoNameLabel = "app.kubernetes.io/name" 23 | AppKubernetesIoPartOfLabel = "app.kubernetes.io/part-of" 24 | AppKubernetesIoInstanceLabel = "app.kubernetes.io/instance" 25 | AppKubernetesIoComponentLabel = "app.kubernetes.io/component" 26 | AppKubernetesIoManagedByLabel = "app.kubernetes.io/managed-by" 27 | AppKubernetesIoVersionLabel = "app.kubernetes.io/version" 28 | ) 29 | 30 | func RenderAuthorizationHeader(authToken string) string { 31 | return fmt.Sprintf("Bearer %s", authToken) 32 | } 33 | -------------------------------------------------------------------------------- /internal/util/labels_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package util 5 | 6 | import ( 7 | . "github.com/onsi/ginkgo/v2" 8 | . "github.com/onsi/gomega" 9 | ) 10 | 11 | var _ = Describe("labels", func() { 12 | 13 | Describe("converting labels", func() { 14 | It("should leave normal characters untouched", func() { 15 | Expect(ImageNameToLabel("instrumentation")).To(Equal("instrumentation")) 16 | }) 17 | 18 | It("should convert : to _", func() { 19 | Expect(ImageNameToLabel("instrumentation:latest")).To(Equal("instrumentation_latest")) 20 | }) 21 | 22 | It("should convert / to _", func() { 23 | Expect(ImageNameToLabel("ghcr.io/dash0hq/operator-controller:0.3.0")).To(Equal("ghcr.io_dash0hq_operator-controller_0.3.0")) 24 | }) 25 | 26 | It("should convert @ to _", func() { 27 | Expect( 28 | ImageNameToLabel( 29 | "ghcr.io/dash0hq/operator-controller@sha256:123", 30 | ), 31 | ).To( 32 | Equal( 33 | "ghcr.io_dash0hq_operator-controller_sha256_123", 34 | ), 35 | ) 36 | }) 37 | 38 | It("should truncate long image names", func() { 39 | labelFromLongImageName := ImageNameToLabel( 40 | "ghcr.io/dash0hq/operator-controller@sha256:68d83fa12931ba8c085d8804f5a60d0b3df68494903a7a5b6506928e0bcd3c6b", 41 | ) 42 | Expect(labelFromLongImageName).To( 43 | Equal( 44 | "ghcr.io_dash0hq_operator-controller_sha256_68d83fa12931ba8c085d", 45 | ), 46 | ) 47 | Expect(labelFromLongImageName).To(HaveLen(63)) 48 | }) 49 | }) 50 | }) 51 | -------------------------------------------------------------------------------- /internal/util/leader_election_aware_manager.go: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package util 5 | 6 | import ( 7 | "context" 8 | "sync/atomic" 9 | 10 | "sigs.k8s.io/controller-runtime/pkg/log" 11 | ) 12 | 13 | type LeaderElectionAware interface { 14 | IsLeader() bool 15 | } 16 | 17 | // LeaderElectionAwareRunnable serves the purpose of making the operator manager aware whether it is the current leader 18 | // or not. 19 | type LeaderElectionAwareRunnable struct { 20 | isLeader atomic.Bool 21 | } 22 | 23 | func NewLeaderElectionAwareRunnable() *LeaderElectionAwareRunnable { 24 | return &LeaderElectionAwareRunnable{} 25 | } 26 | 27 | // NeedLeaderElection implements the LeaderElectionRunnable interface, which indicates 28 | // that the LeaderElectionAwareRunnable requires leader election. 29 | func (r *LeaderElectionAwareRunnable) NeedLeaderElection() bool { 30 | return true 31 | } 32 | 33 | // Start is the signal from controller-runtime for the runnable that this replica has become leader. 34 | func (r *LeaderElectionAwareRunnable) Start(ctx context.Context) error { 35 | log.FromContext(ctx).Info("This operator manager replica has just become leader.") 36 | r.isLeader.Store(true) 37 | return nil 38 | } 39 | 40 | func (r *LeaderElectionAwareRunnable) IsLeader() bool { 41 | return r.isLeader.Load() 42 | } 43 | -------------------------------------------------------------------------------- /internal/util/pointer.go: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package util 5 | 6 | func ReadBoolPointerWithDefault(pointer *bool, defaultValue bool) bool { 7 | if pointer != nil { 8 | return *pointer 9 | } 10 | return defaultValue 11 | } 12 | 13 | func IsOptOutFlagWithDeprecatedVariantEnabled(deprecatedSetting *bool, newSetting *bool) bool { 14 | deprecateValue := ReadBoolPointerWithDefault(deprecatedSetting, true) 15 | newValue := ReadBoolPointerWithDefault(newSetting, true) 16 | // Opt-out switches default to true if not explicitly set, so if one of the values is false, we know it has 17 | // explicitly been set to false with the purpose of disabling the respective feature. 18 | return deprecateValue && newValue 19 | } 20 | -------------------------------------------------------------------------------- /internal/util/pointer_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package util 5 | 6 | import ( 7 | "k8s.io/utils/ptr" 8 | 9 | . "github.com/onsi/ginkgo/v2" 10 | . "github.com/onsi/gomega" 11 | ) 12 | 13 | var _ = Describe("pointers", func() { 14 | It("ReadBoolPointerWithDefault", func() { 15 | Expect(ReadBoolPointerWithDefault(nil, false)).To(BeFalse()) 16 | Expect(ReadBoolPointerWithDefault(nil, true)).To(BeTrue()) 17 | Expect(ReadBoolPointerWithDefault(ptr.To(false), false)).To(BeFalse()) 18 | Expect(ReadBoolPointerWithDefault(ptr.To(false), true)).To(BeFalse()) 19 | Expect(ReadBoolPointerWithDefault(ptr.To(true), false)).To(BeTrue()) 20 | Expect(ReadBoolPointerWithDefault(ptr.To(true), true)).To(BeTrue()) 21 | }) 22 | 23 | It("IsOptOutFlagWithDeprecatedVariantEnabled", func() { 24 | Expect(IsOptOutFlagWithDeprecatedVariantEnabled(nil, nil)).To(BeTrue()) 25 | Expect(IsOptOutFlagWithDeprecatedVariantEnabled(nil, ptr.To(false))).To(BeFalse()) 26 | Expect(IsOptOutFlagWithDeprecatedVariantEnabled(nil, ptr.To(true))).To(BeTrue()) 27 | Expect(IsOptOutFlagWithDeprecatedVariantEnabled(ptr.To(false), nil)).To(BeFalse()) 28 | Expect(IsOptOutFlagWithDeprecatedVariantEnabled(ptr.To(false), ptr.To(false))).To(BeFalse()) 29 | Expect(IsOptOutFlagWithDeprecatedVariantEnabled(ptr.To(false), ptr.To(true))).To(BeFalse()) 30 | Expect(IsOptOutFlagWithDeprecatedVariantEnabled(ptr.To(true), nil)).To(BeTrue()) 31 | Expect(IsOptOutFlagWithDeprecatedVariantEnabled(ptr.To(true), ptr.To(false))).To(BeFalse()) 32 | Expect(IsOptOutFlagWithDeprecatedVariantEnabled(ptr.To(true), ptr.To(true))).To(BeTrue()) 33 | }) 34 | }) 35 | -------------------------------------------------------------------------------- /internal/util/util_suite_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package util 5 | 6 | import ( 7 | "testing" 8 | 9 | . "github.com/onsi/ginkgo/v2" 10 | . "github.com/onsi/gomega" 11 | ) 12 | 13 | func TestUtil(t *testing.T) { 14 | RegisterFailHandler(Fail) 15 | RunSpecs(t, "Util Suite") 16 | } 17 | -------------------------------------------------------------------------------- /internal/util/zap/log_bridge_wrapper.go: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package zap 5 | 6 | // DelegatingZapCoreWrapper is a wrapper around the root instance of the DelegatingZapCore tree and the global buffer 7 | // for log messages. 8 | type DelegatingZapCoreWrapper struct { 9 | RootDelegatingZapCore *DelegatingZapCore 10 | LogMessageBuffer *Mru[*ZapEntryWithFields] 11 | } 12 | 13 | func NewDelegatingZapCoreWrapper() *DelegatingZapCoreWrapper { 14 | logMessageBuffer := NewMruWithDefaultSizeLimit[*ZapEntryWithFields]() 15 | delegatingZapCore := NewDelegatingZapCore(logMessageBuffer) 16 | return &DelegatingZapCoreWrapper{ 17 | RootDelegatingZapCore: delegatingZapCore, 18 | LogMessageBuffer: logMessageBuffer, 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /internal/util/zap/mru.go: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package zap 5 | 6 | import ( 7 | "sync" 8 | ) 9 | 10 | // Mru is a simple, go-routine safe, ordered, most-recently-used cache. 11 | type Mru[T any] struct { 12 | elements []T 13 | limit int 14 | mu sync.RWMutex 15 | } 16 | 17 | const ( 18 | defaultSizeLimit = 1500 19 | ) 20 | 21 | func NewMruWithDefaultSizeLimit[T any]() *Mru[T] { 22 | return NewMru[T](defaultSizeLimit) 23 | } 24 | 25 | func NewMru[T any](limit int) *Mru[T] { 26 | return &Mru[T]{ 27 | limit: limit, 28 | elements: make([]T, 0), 29 | } 30 | } 31 | 32 | func (mru *Mru[T]) Put(element T) { 33 | mru.mu.Lock() 34 | defer mru.mu.Unlock() 35 | if len(mru.elements) == mru.limit { 36 | mru.elements = mru.elements[1:] 37 | } 38 | mru.elements = append(mru.elements, element) 39 | } 40 | 41 | func (mru *Mru[T]) Take() *T { 42 | mru.mu.Lock() 43 | defer mru.mu.Unlock() 44 | if len(mru.elements) == 0 { 45 | return nil 46 | } 47 | el := mru.elements[0] 48 | mru.elements = mru.elements[1:] 49 | return &el 50 | } 51 | 52 | func (mru *Mru[T]) ForAllAndClear(f func(T)) { 53 | mru.mu.Lock() 54 | defer mru.mu.Unlock() 55 | for _, element := range mru.elements { 56 | f(element) 57 | } 58 | mru.elements = make([]T, 0) 59 | } 60 | 61 | func (mru *Mru[T]) Len() int { 62 | mru.mu.RLock() 63 | defer mru.mu.RUnlock() 64 | return len(mru.elements) 65 | } 66 | 67 | func (mru *Mru[T]) IsEmpty() bool { 68 | mru.mu.RLock() 69 | defer mru.mu.RUnlock() 70 | return len(mru.elements) == 0 71 | } 72 | -------------------------------------------------------------------------------- /internal/webhooks/vendored/opentelemetry-collector-contrib/NOTICE: -------------------------------------------------------------------------------- 1 | This directory contains code originating from 2 | https://github.com/open-telemetry/opentelemetry-collector-contrib, 3 | 4 | which is copyrighted by the OpenTelemetry Authors, 5 | 6 | and licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | -------------------------------------------------------------------------------- /internal/webhooks/vendored/opentelemetry-collector-contrib/processor/transformprocessor/internal_/common/functions.go: -------------------------------------------------------------------------------- 1 | // Copyright The OpenTelemetry Authors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // This is a copy of 5 | // https://raw.githubusercontent.com/open-telemetry/opentelemetry-collector-contrib/refs/tags/v0.126.0/processor/transformprocessor/internal/common/functions.go 6 | 7 | package common 8 | 9 | import ( 10 | "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" 11 | "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottlresource" 12 | "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottlscope" 13 | "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottlfuncs" 14 | ) 15 | 16 | func ResourceFunctions() map[string]ottl.Factory[ottlresource.TransformContext] { 17 | return ottlfuncs.StandardFuncs[ottlresource.TransformContext]() 18 | } 19 | 20 | func ScopeFunctions() map[string]ottl.Factory[ottlscope.TransformContext] { 21 | return ottlfuncs.StandardFuncs[ottlscope.TransformContext]() 22 | } 23 | -------------------------------------------------------------------------------- /internal/webhooks/vendored/opentelemetry-collector-contrib/processor/transformprocessor/internal_/logs/functions.go: -------------------------------------------------------------------------------- 1 | // Copyright The OpenTelemetry Authors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // This is a copy of 5 | // https://raw.githubusercontent.com/open-telemetry/opentelemetry-collector-contrib/refs/tags/v0.126.0/processor/transformprocessor/internal/logs/functions.go 6 | 7 | package logs 8 | 9 | import ( 10 | "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" 11 | "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottllog" 12 | "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottlfuncs" 13 | ) 14 | 15 | func LogFunctions() map[string]ottl.Factory[ottllog.TransformContext] { 16 | // No logs-only functions yet. 17 | return ottlfuncs.StandardFuncs[ottllog.TransformContext]() 18 | } 19 | -------------------------------------------------------------------------------- /internal/webhooks/vendored/opentelemetry-collector-contrib/processor/transformprocessor/internal_/metrics/func_convert_sum_to_gauge.go: -------------------------------------------------------------------------------- 1 | // Copyright The OpenTelemetry Authors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // This is a copy of 5 | // https://raw.githubusercontent.com/open-telemetry/opentelemetry-collector-contrib/refs/tags/v0.126.0/processor/transformprocessor/internal/metrics/func_convert_sum_to_gauge.go 6 | 7 | package metrics 8 | 9 | import ( 10 | "context" 11 | 12 | "go.opentelemetry.io/collector/pdata/pmetric" 13 | 14 | "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" 15 | "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottlmetric" 16 | ) 17 | 18 | func newConvertSumToGaugeFactory() ottl.Factory[ottlmetric.TransformContext] { 19 | return ottl.NewFactory("convert_sum_to_gauge", nil, createConvertSumToGaugeFunction) 20 | } 21 | 22 | func createConvertSumToGaugeFunction(_ ottl.FunctionContext, _ ottl.Arguments) (ottl.ExprFunc[ottlmetric.TransformContext], error) { 23 | return convertSumToGauge() 24 | } 25 | 26 | func convertSumToGauge() (ottl.ExprFunc[ottlmetric.TransformContext], error) { 27 | return func(_ context.Context, tCtx ottlmetric.TransformContext) (any, error) { 28 | metric := tCtx.GetMetric() 29 | if metric.Type() != pmetric.MetricTypeSum { 30 | return nil, nil 31 | } 32 | 33 | dps := metric.Sum().DataPoints() 34 | 35 | // Setting the data type removed all the data points, so we must copy them back to the metric. 36 | dps.MoveAndAppendTo(metric.SetEmptyGauge().DataPoints()) 37 | 38 | return nil, nil 39 | }, nil 40 | } 41 | -------------------------------------------------------------------------------- /internal/webhooks/vendored/opentelemetry-collector-contrib/processor/transformprocessor/internal_/traces/functions.go: -------------------------------------------------------------------------------- 1 | // Copyright The OpenTelemetry Authors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // This is a copy of 5 | // https://raw.githubusercontent.com/open-telemetry/opentelemetry-collector-contrib/refs/tags/v0.126.0/processor/transformprocessor/internal/traces/functions.go 6 | 7 | package traces 8 | 9 | import ( 10 | "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" 11 | "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottlspan" 12 | "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/contexts/ottlspanevent" 13 | "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottlfuncs" 14 | ) 15 | 16 | func SpanFunctions() map[string]ottl.Factory[ottlspan.TransformContext] { 17 | // No trace-only functions yet. 18 | m := ottlfuncs.StandardFuncs[ottlspan.TransformContext]() 19 | isRootSpanFactory := ottlfuncs.NewIsRootSpanFactory() 20 | m[isRootSpanFactory.Name()] = isRootSpanFactory 21 | return m 22 | } 23 | 24 | func SpanEventFunctions() map[string]ottl.Factory[ottlspanevent.TransformContext] { 25 | // No trace-only functions yet. 26 | return ottlfuncs.StandardFuncs[ottlspanevent.TransformContext]() 27 | } 28 | -------------------------------------------------------------------------------- /internal/workloads/workloads_suite_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package workloads 5 | 6 | import ( 7 | "testing" 8 | 9 | . "github.com/onsi/ginkgo/v2" 10 | . "github.com/onsi/gomega" 11 | ) 12 | 13 | func TestWorkloadModifications(t *testing.T) { 14 | RegisterFailHandler(Fail) 15 | RunSpecs(t, "Workload Modifications Suite") 16 | } 17 | -------------------------------------------------------------------------------- /test-resources/.env.template: -------------------------------------------------------------------------------- 1 | # A single kube context name that should be used when running the e2e tests. The e2e test will switch to this context at 2 | # the start of the test suite and switch back to the original context after the tests have finished. 3 | E2E_KUBECTX=docker-desktop 4 | 5 | # Print details about each request sent to the application under test. 6 | # E2E_VERBOSE_HTTP=false 7 | 8 | # A comma separated lists of kube context names that the scripts in test-resources/bin are allowed to talk to. This is a 9 | # safety measure to prevent the local testing accidentally modifying a production cluster. 10 | ALLOWED_KUBECTXS=docker-desktop 11 | 12 | # dev ingress/api 13 | DASH0_INGRESS_ENDPOINT=ingress.eu-west-1.aws.dash0-dev.com:4317 14 | DASH0_API_ENDPOINT=https://api.eu-west-1.aws.dash0-dev.com 15 | 16 | # prod ingress/api 17 | # DASH0_INGRESS_ENDPOINT=ingress.eu-west-1.aws.dash0.com:4317 18 | # DASH0_API_ENDPOINT=https://api.eu-west-1.aws.dash0.com 19 | 20 | # The authorization token for the dash0-operator service account. This is used for the scripts in test-resources/bin, 21 | # if you want to report data from a test-cluster to an actual Dash0 backend. 22 | DASH0_AUTHORIZATION_TOKEN= 23 | -------------------------------------------------------------------------------- /test-resources/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | -------------------------------------------------------------------------------- /test-resources/bin/.gitignore: -------------------------------------------------------------------------------- 1 | extra-values.yaml -------------------------------------------------------------------------------- /test-resources/bin/README.md: -------------------------------------------------------------------------------- 1 | Test Scripts 2 | ============ 3 | 4 | The scripts in this folder are meant for running semi-manual tests. 5 | They deploy the operator and applications under monitoring - this part is automated via scripts. 6 | Whether the instrumentation was successful or not needs to be verified manually. 7 | There is also an extensive suit of fully automated tests in `test/e2e`. 8 | 9 | The section "Semi-Manual Test Scenarios" in CONTRIBUTING.md has more details on the scripts in this folder. 10 | -------------------------------------------------------------------------------- /test-resources/bin/filelog-offset-volume-hostpath-values.yaml: -------------------------------------------------------------------------------- 1 | operator: 2 | collectors: 3 | filelogOffsetSyncStorageVolume: 4 | name: offset-storage 5 | hostPath: 6 | path: /data/dash0-operator/offset-storage 7 | type: DirectoryOrCreate 8 | -------------------------------------------------------------------------------- /test-resources/bin/filelog-offset-volume-pvc-values.yaml: -------------------------------------------------------------------------------- 1 | operator: 2 | collectors: 3 | filelogOffsetSyncStorageVolume: 4 | name: offset-storage 5 | persistentVolumeClaim: 6 | claimName: offset-storage-claim -------------------------------------------------------------------------------- /test-resources/bin/perses-crd-version-check.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | set -euo pipefail 7 | 8 | cd "$(dirname "${BASH_SOURCE[0]}")"/../.. 9 | 10 | source test-resources/bin/third-party-crd-version-check-util 11 | 12 | module_name=github.com/perses/perses-operator 13 | chart_readme=helm-chart/dash0-operator/README.md 14 | unit_test_crd_file=test/util/crds/perses.dev_persesdashboards.yaml 15 | test_resources_util_file=test-resources/bin/util 16 | 17 | get_module_version_from_go_mod "$module_name" 18 | 19 | remote_crd_url="https://raw.githubusercontent.com/perses/perses-operator/refs/tags/v$module_version/config/crd/bases/perses.dev_persesdashboards.yaml" 20 | kubectl_apply="kubectl apply --server-side -f $remote_crd_url" 21 | 22 | check_all 23 | -------------------------------------------------------------------------------- /test-resources/bin/prometheus-crd-version-check.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | set -euo pipefail 7 | 8 | cd "$(dirname "${BASH_SOURCE[0]}")"/../.. 9 | 10 | source test-resources/bin/third-party-crd-version-check-util 11 | 12 | module_name=github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring 13 | chart_readme=helm-chart/dash0-operator/README.md 14 | unit_test_crd_file=test/util/crds/monitoring.coreos.com_prometheusrules.yaml 15 | test_resources_util_file=test-resources/bin/util 16 | 17 | get_module_version_from_go_mod "$module_name" 18 | 19 | remote_crd_url="https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v$module_version/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml" 20 | kubectl_apply="kubectl apply --server-side -f $remote_crd_url" 21 | 22 | check_all 23 | -------------------------------------------------------------------------------- /test-resources/bin/run-gh-action-locally.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | set -euo pipefail 7 | 8 | cd "$(dirname "${BASH_SOURCE[0]}")"/../.. 9 | 10 | command -v act >/dev/null 2>&1 || { 11 | cat <&2 12 | The executable act needs to be installed but it isn't. 13 | See https://nektosact.com/installation/index.html for instructions. 14 | 15 | Aborting. 16 | EOF 17 | exit 1 18 | } 19 | 20 | workflow="${1:-.github/workflows/ci.yaml}" 21 | job="${2:-verify}" 22 | trigger="${3:-push}" 23 | 24 | set -x 25 | act \ 26 | --container-architecture linux/arm64 \ 27 | -W "$workflow" \ 28 | -j "$job" \ 29 | "$trigger" 30 | set +x 31 | 32 | -------------------------------------------------------------------------------- /test-resources/bin/test-scenario-03-update-operator.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | set -euo pipefail 7 | 8 | cd "$(dirname "${BASH_SOURCE[0]}")"/../.. 9 | 10 | target_namespace=${1:-test-namespace} 11 | 12 | source test-resources/bin/util 13 | load_env_file 14 | verify_kubectx 15 | setup_test_environment 16 | 17 | step_counter=1 18 | 19 | echo "STEP $step_counter: rebuild images" 20 | build_all_images 21 | finish_step 22 | 23 | echo "STEP $step_counter: deploy the Dash0 operator using helm" 24 | update_via_helm 25 | finish_step 26 | 27 | -------------------------------------------------------------------------------- /test-resources/customresources/dash0monitoring/.gitignore: -------------------------------------------------------------------------------- 1 | dash0monitoring.yaml 2 | dash0monitoring-2.yaml 3 | dash0monitoring-3.yaml 4 | -------------------------------------------------------------------------------- /test-resources/customresources/dash0monitoring/dash0monitoring-2.yaml.template: -------------------------------------------------------------------------------- 1 | # This resource will be used for the namespace test-namespace-2 if ADDITIONAL_NAMESPACES=true has been provided. 2 | apiVersion: operator.dash0.com/v1alpha1 3 | kind: Dash0Monitoring 4 | metadata: 5 | name: dash0-monitoring-resource 6 | spec: 7 | instrumentWorkloads: $INSTRUMENT_WORKLOADS 8 | logCollection: 9 | enabled: $LOG_COLLECTION 10 | prometheusScraping: 11 | enabled: $PROMETHEUS_SCRAPING_ENABLED 12 | synchronizePersesDashboards: $SYNCHRONIZE_PERSES_DASHBOARDS 13 | synchronizePrometheusRules: $SYNCHRONIZE_PROMETHEUS_RULES 14 | -------------------------------------------------------------------------------- /test-resources/customresources/dash0monitoring/dash0monitoring-3.yaml.template: -------------------------------------------------------------------------------- 1 | # This resource will be used for the namespace test-namespace-3 if ADDITIONAL_NAMESPACES=true has been provided. 2 | apiVersion: operator.dash0.com/v1alpha1 3 | kind: Dash0Monitoring 4 | metadata: 5 | name: dash0-monitoring-resource 6 | spec: 7 | instrumentWorkloads: $INSTRUMENT_WORKLOADS 8 | logCollection: 9 | enabled: $LOG_COLLECTION 10 | prometheusScraping: 11 | enabled: $PROMETHEUS_SCRAPING_ENABLED 12 | synchronizePersesDashboards: $SYNCHRONIZE_PERSES_DASHBOARDS 13 | synchronizePrometheusRules: $SYNCHRONIZE_PROMETHEUS_RULES 14 | -------------------------------------------------------------------------------- /test-resources/customresources/dash0monitoring/dash0monitoring.yaml.template: -------------------------------------------------------------------------------- 1 | # This resource will be deployed to the namespace test-namespace unless DEPLOY_MONITORING_RESOURCE=false has been 2 | # provided. 3 | apiVersion: operator.dash0.com/v1alpha1 4 | kind: Dash0Monitoring 5 | metadata: 6 | name: dash0-monitoring-resource 7 | spec: 8 | instrumentWorkloads: $INSTRUMENT_WORKLOADS 9 | logCollection: 10 | enabled: $LOG_COLLECTION 11 | prometheusScraping: 12 | enabled: $PROMETHEUS_SCRAPING_ENABLED 13 | synchronizePersesDashboards: $SYNCHRONIZE_PERSES_DASHBOARDS 14 | synchronizePrometheusRules: $SYNCHRONIZE_PROMETHEUS_RULES 15 | -------------------------------------------------------------------------------- /test-resources/customresources/dash0operatorconfiguration/.gitignore: -------------------------------------------------------------------------------- 1 | dash0operatorconfiguration.otlpsink.yaml 2 | dash0operatorconfiguration.secret.yaml 3 | dash0operatorconfiguration.token.yaml 4 | -------------------------------------------------------------------------------- /test-resources/customresources/dash0operatorconfiguration/dash0operatorconfiguration.otlpsink.yaml.template: -------------------------------------------------------------------------------- 1 | apiVersion: operator.dash0.com/v1alpha1 2 | kind: Dash0OperatorConfiguration 3 | metadata: 4 | name: dash0-operator-configuration-resource 5 | spec: 6 | export: 7 | dash0: 8 | endpoint: http://otlp-sink.otlp-sink.svc.cluster.local:4317 9 | authorization: 10 | token: dummy-token 11 | selfMonitoring: 12 | enabled: $SELF_MONITORING_ENABLED 13 | kubernetesInfrastructureMetricsCollection: 14 | enabled: $KUBERNETES_INFRASTRUCTURE_METRICS_COLLECTION_ENABLED 15 | collectPodLabelsAndAnnotations: 16 | enabled: $COLLECT_POD_LABELS_AND_ANNOTATIONS_ENABLED 17 | -------------------------------------------------------------------------------- /test-resources/customresources/dash0operatorconfiguration/dash0operatorconfiguration.secret.yaml.template: -------------------------------------------------------------------------------- 1 | apiVersion: operator.dash0.com/v1alpha1 2 | kind: Dash0OperatorConfiguration 3 | metadata: 4 | name: dash0-operator-configuration-resource 5 | spec: 6 | export: 7 | dash0: 8 | endpoint: "$DASH0_INGRESS_ENDPOINT" 9 | authorization: 10 | # Note: without an explicit name and key attribute, the defaults will be used: 11 | # name: dash0-authorization-secret 12 | # key: token 13 | secretRef: {} 14 | apiEndpoint: "$DASH0_API_ENDPOINT" 15 | selfMonitoring: 16 | enabled: $SELF_MONITORING_ENABLED 17 | kubernetesInfrastructureMetricsCollection: 18 | enabled: $KUBERNETES_INFRASTRUCTURE_METRICS_COLLECTION_ENABLED 19 | collectPodLabelsAndAnnotations: 20 | enabled: $COLLECT_POD_LABELS_AND_ANNOTATIONS_ENABLED 21 | -------------------------------------------------------------------------------- /test-resources/customresources/dash0operatorconfiguration/dash0operatorconfiguration.token.yaml.template: -------------------------------------------------------------------------------- 1 | apiVersion: operator.dash0.com/v1alpha1 2 | kind: Dash0OperatorConfiguration 3 | metadata: 4 | name: dash0-operator-configuration-resource 5 | spec: 6 | export: 7 | dash0: 8 | endpoint: "$DASH0_INGRESS_ENDPOINT" 9 | authorization: 10 | token: "$DASH0_AUTHORIZATION_TOKEN" 11 | apiEndpoint: "$DASH0_API_ENDPOINT" 12 | selfMonitoring: 13 | enabled: $SELF_MONITORING_ENABLED 14 | kubernetesInfrastructureMetricsCollection: 15 | enabled: $KUBERNETES_INFRASTRUCTURE_METRICS_COLLECTION_ENABLED 16 | collectPodLabelsAndAnnotations: 17 | enabled: $COLLECT_POD_LABELS_AND_ANNOTATIONS_ENABLED 18 | -------------------------------------------------------------------------------- /test-resources/customresources/filelogoffsetpvc/offset-storage-pvc-docker.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: docker-storage-class 5 | provisioner: docker.io/hostpath 6 | --- 7 | apiVersion: v1 8 | kind: PersistentVolumeClaim 9 | metadata: 10 | name: offset-storage-claim 11 | namespace: operator-namespace 12 | spec: 13 | accessModes: 14 | - ReadWriteOnce 15 | resources: 16 | requests: 17 | storage: 10Mi 18 | storageClassName: docker-storage-class 19 | -------------------------------------------------------------------------------- /test-resources/customresources/filelogoffsetpvc/offset-storage-pvc-kind.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolume 3 | metadata: 4 | name: offset-storage-volume 5 | spec: 6 | storageClassName: standard 7 | accessModes: 8 | - ReadWriteOnce 9 | persistentVolumeReclaimPolicy: Retain 10 | capacity: 11 | storage: 50Mi 12 | hostPath: 13 | path: /offset-storage/ 14 | --- 15 | apiVersion: v1 16 | kind: PersistentVolumeClaim 17 | metadata: 18 | name: offset-storage-claim 19 | namespace: operator-namespace 20 | spec: 21 | volumeName: offset-storage-volume 22 | accessModes: 23 | - ReadWriteOnce 24 | resources: 25 | requests: 26 | storage: 10Mi 27 | -------------------------------------------------------------------------------- /test-resources/dotnet/.dockerignore: -------------------------------------------------------------------------------- 1 | obj/ 2 | bin/ 3 | -------------------------------------------------------------------------------- /test-resources/dotnet/.gitignore: -------------------------------------------------------------------------------- 1 | obj/ 2 | bin/ 3 | -------------------------------------------------------------------------------- /test-resources/dotnet/Dockerfile: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | FROM mcr.microsoft.com/dotnet/sdk:9.0-bookworm-slim AS build 5 | 6 | RUN mkdir /App 7 | WORKDIR /App 8 | COPY . . 9 | 10 | # run dotnet restore as a separate image layer (speeds up docker build) 11 | RUN dotnet restore 12 | # build application 13 | RUN dotnet publish -o . 14 | 15 | # build the final image 16 | FROM mcr.microsoft.com/dotnet/aspnet:9.0-bookworm-slim 17 | 18 | COPY --from=build /App /App 19 | WORKDIR /App/ 20 | ENTRYPOINT [ "./app" ] 21 | -------------------------------------------------------------------------------- /test-resources/dotnet/Program.cs: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | var builder = WebApplication.CreateBuilder(args); 5 | 6 | var port = Environment.GetEnvironmentVariable("PORT") ?? "1407"; 7 | builder.WebHost.UseUrls($"http://0.0.0.0:{port}"); 8 | 9 | var app = builder.Build(); 10 | 11 | app.MapGet("/ready", () => Results.NoContent()); 12 | 13 | app.MapGet("/dash0-k8s-operator-test", (string? id) => 14 | { 15 | if (!string.IsNullOrEmpty(id)) 16 | { 17 | Console.WriteLine($"processing request {id}"); 18 | } 19 | else 20 | { 21 | Console.WriteLine("processing request"); 22 | } 23 | 24 | return new { message = "We make Observability easy for every developer." }; 25 | }); 26 | 27 | app.Run(); 28 | -------------------------------------------------------------------------------- /test-resources/dotnet/app.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net9.0 4 | enable 5 | enable 6 | 7 | 8 | -------------------------------------------------------------------------------- /test-resources/e2e/.gitignore: -------------------------------------------------------------------------------- 1 | logs/ 2 | -------------------------------------------------------------------------------- /test-resources/e2e/volumes/.gitignore: -------------------------------------------------------------------------------- 1 | otlp-sink*/ 2 | -------------------------------------------------------------------------------- /test-resources/e2e/volumes/offset-storage/.gitignore: -------------------------------------------------------------------------------- 1 | * -------------------------------------------------------------------------------- /test-resources/jvm/spring-boot/.gitattributes: -------------------------------------------------------------------------------- 1 | /mvnw text eol=lf 2 | *.cmd text eol=crlf 3 | -------------------------------------------------------------------------------- /test-resources/jvm/spring-boot/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | pom.xml.tag 3 | pom.xml.releaseBackup 4 | pom.xml.versionsBackup 5 | pom.xml.next 6 | release.properties 7 | dependency-reduced-pom.xml 8 | buildNumber.properties 9 | .mvn/timing.properties 10 | .mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /test-resources/jvm/spring-boot/.m2/.gitignore: -------------------------------------------------------------------------------- 1 | repository/* 2 | -------------------------------------------------------------------------------- /test-resources/jvm/spring-boot/.m2/repository/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dash0hq/dash0-operator/8f9cc021630aadc4f37023b67a8fcbbe1cf2d5c0/test-resources/jvm/spring-boot/.m2/repository/.gitkeep -------------------------------------------------------------------------------- /test-resources/jvm/spring-boot/.m2/settings.xml: -------------------------------------------------------------------------------- 1 | 3 | /.m2/repository 4 | 5 | -------------------------------------------------------------------------------- /test-resources/jvm/spring-boot/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 20 | -------------------------------------------------------------------------------- /test-resources/jvm/spring-boot/Dockerfile: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | ARG JDK_VERSION=24 5 | 6 | FROM openjdk:${JDK_VERSION}-jdk-bookworm 7 | 8 | COPY . . 9 | COPY .m2 /m2 10 | 11 | RUN JAVA_HOME=$(which java | xargs dirname | xargs dirname) "./mvnw" "-gs" "/m2/settings.xml" package 12 | 13 | ENTRYPOINT [ "java", "-jar", "/target/app.jar" ] -------------------------------------------------------------------------------- /test-resources/jvm/spring-boot/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 3.5.0 9 | 10 | 11 | com.dash0.app_under_test 12 | app-under-test 13 | 1.0.0-SNAPSHOT 14 | app-under-test 15 | Test App for Dash0 operator 16 | 17 | 17 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-web 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-test 27 | test 28 | 29 | 30 | 31 | app 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-maven-plugin 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /test-resources/jvm/spring-boot/src/main/java/com/dash0/app_under_test/Application.java: -------------------------------------------------------------------------------- 1 | package com.dash0.app_under_test; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | // Use ./mvnw spring-boot:run to run locally without Docker/K8s. 7 | 8 | @SpringBootApplication 9 | public class Application { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(Application.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test-resources/jvm/spring-boot/src/main/java/com/dash0/app_under_test/Controller.java: -------------------------------------------------------------------------------- 1 | package com.dash0.app_under_test; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.fasterxml.jackson.databind.node.ObjectNode; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.HttpStatus; 7 | import org.springframework.http.MediaType; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.ResponseStatus; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | @RestController 13 | public class Controller { 14 | 15 | @Autowired 16 | private ObjectMapper mapper; 17 | 18 | @GetMapping("/ready") 19 | @ResponseStatus(code = HttpStatus.NO_CONTENT) 20 | public void ready() { 21 | } 22 | 23 | @GetMapping(path="/dash0-k8s-operator-test", produces= MediaType.APPLICATION_JSON_VALUE) 24 | public ObjectNode test() { 25 | ObjectNode response = mapper.createObjectNode(); 26 | response.put("message", "We make Observability easy for every developer."); 27 | return response; 28 | } 29 | } -------------------------------------------------------------------------------- /test-resources/jvm/spring-boot/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=dash0-app-under-test-spring-boot 2 | server.port: ${PORT:1307} -------------------------------------------------------------------------------- /test-resources/jvm/spring-boot/src/test/java/com/dash0/app_under_test/ApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.dash0.app_under_test; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class AppUnderTestApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test-resources/node.js/express/.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | node_modules 3 | npm-debug.log 4 | -------------------------------------------------------------------------------- /test-resources/node.js/express/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /test-resources/node.js/express/.nvmrc: -------------------------------------------------------------------------------- 1 | 20 -------------------------------------------------------------------------------- /test-resources/node.js/express/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "avoid", 3 | "quoteProps": "as-needed", 4 | "printWidth": 120, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "all" 8 | } 9 | -------------------------------------------------------------------------------- /test-resources/node.js/express/Dockerfile: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | ARG NODE_VERSION=20.19.0 5 | ARG ALPINE_VERSION=3.21 6 | 7 | FROM node:${NODE_VERSION}-alpine${ALPINE_VERSION} 8 | ENV NODE_ENV=production 9 | WORKDIR /usr/src/app 10 | COPY --chown=node:node package.json . 11 | COPY --chown=node:node package-lock.json . 12 | RUN npm ci --omit=dev 13 | COPY --chown=node:node . . 14 | ENTRYPOINT [ "node", "app.js" ] 15 | -------------------------------------------------------------------------------- /test-resources/node.js/express/build-and-push-to-ghcr.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | set -euo pipefail 7 | 8 | cd "$(dirname "${BASH_SOURCE[0]}")" 9 | 10 | if [[ -z "${GH_PAT:-}" ]]; then 11 | echo "Error: Provide a personal access token (classic) with write_package permission via GH_PAT." 12 | exit 1 13 | fi 14 | if [[ -z "${GH_USER:-}" ]]; then 15 | echo "Error: Provide your Github handle via GH_USER." 16 | exit 1 17 | fi 18 | 19 | echo "$GH_PAT" | docker login ghcr.io -u "$GH_USER" --password-stdin 20 | 21 | # When pushing to ghcr.io, we build for x86_64, not arm. 22 | docker build \ 23 | --platform linux/amd64 \ 24 | . \ 25 | -t ghcr.io/dash0hq/dash0-operator-nodejs-20-express-test-app:latest 26 | 27 | docker push ghcr.io/dash0hq/dash0-operator-nodejs-20-express-test-app:latest 28 | 29 | -------------------------------------------------------------------------------- /test-resources/node.js/express/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dash0-app-under-test-express", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "app.js", 6 | "scripts": { 7 | "start": "node .", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "Bastian Krol ", 11 | "license": "Apache-2.0", 12 | "dependencies": { 13 | "express": "^5.1.0", 14 | "prom-client": "^15.1.3" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test-resources/node.js/express/undeploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | set -euo pipefail 7 | 8 | cd "$(dirname "${BASH_SOURCE[0]}")" 9 | 10 | target_namespace=${1:-test-namespace} 11 | kind=${2:-deployment} 12 | 13 | kubectl delete -n "${target_namespace}" -f "${kind}".yaml --ignore-not-found || true 14 | kubectl delete -f https://kind.sigs.k8s.io/examples/ingress/deploy-ingress-nginx.yaml --ignore-not-found || true 15 | 16 | -------------------------------------------------------------------------------- /test-resources/util/otlp-resource-analyzer/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /test-resources/util/otlp-resource-analyzer/.nvmrc: -------------------------------------------------------------------------------- 1 | 22 2 | -------------------------------------------------------------------------------- /test-resources/util/otlp-resource-analyzer/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "avoid", 3 | "quoteProps": "as-needed", 4 | "printWidth": 120, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "all" 8 | } 9 | -------------------------------------------------------------------------------- /test-resources/util/otlp-resource-analyzer/app.js: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | 'use strict'; 5 | 6 | const path = require('node:path'); 7 | 8 | const bodyParser = require('body-parser'); 9 | const cookieParser = require('cookie-parser'); 10 | const createError = require('http-errors'); 11 | const express = require('express'); 12 | const logger = require('morgan'); 13 | const nocache = require('nocache'); 14 | 15 | const port = parseInt(process.env.PORT || '1302'); 16 | 17 | const indexRouter = require('./routes/index'); 18 | 19 | const app = express(); 20 | 21 | // view engine setup 22 | app.set('views', path.join(__dirname, 'views')); 23 | app.set('view engine', 'pug'); 24 | 25 | app.use(logger('dev')); 26 | app.use(express.json()); 27 | app.use(express.urlencoded({ extended: false })); 28 | app.use(cookieParser()); 29 | app.use(express.static(path.join(__dirname, 'public'))); 30 | app.use('/bootstrap', express.static(__dirname + '/node_modules/bootstrap/dist/css')); 31 | 32 | app.use('/', nocache(), indexRouter.init, indexRouter.router); 33 | 34 | // catch 404 and forward to error handler 35 | app.use(function (req, res, next) { 36 | next(createError(404)); 37 | }); 38 | 39 | // error handler 40 | app.use(function (err, req, res, next) { 41 | // set locals, only providing error in development 42 | res.locals.message = err.message; 43 | res.locals.error = req.app.get('env') === 'development' ? err : {}; 44 | 45 | // render the error page 46 | res.status(err.status || 500); 47 | res.render('error'); 48 | }); 49 | 50 | module.exports = app; 51 | -------------------------------------------------------------------------------- /test-resources/util/otlp-resource-analyzer/errors.js: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | 'use strict'; 5 | 6 | exports.AppError = class AppError extends Error { 7 | constructor(message, status = 400) { 8 | super(message); 9 | this.name = 'AppError'; 10 | this.status = status; 11 | Object.setPrototypeOf(this, AppError.prototype); 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /test-resources/util/otlp-resource-analyzer/filters/all_pods.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "all pods", 3 | "op": "and", 4 | "filters": [ 5 | { "op": "is-set", "key": "k8s.pod.uid" }, 6 | { "op": "is-not-set", "key": "k8s.container.name" }, 7 | { "op": "value-contains-not", "key": "k8s.namespace.name", "regex": "kube-system" } 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /test-resources/util/otlp-resource-analyzer/filters/all_resources_with_higher_order_uid.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "all resources with higher order workload uid", 3 | "op": "or", 4 | "filters": [ 5 | { "op": "is-set", "key": "k8s.cronjob.uid" }, 6 | { "op": "is-set", "key": "k8s.daemonset.uid" }, 7 | { "op": "is-set", "key": "k8s.daemonset.uid" }, 8 | { "op": "is-set", "key": "k8s.deployment.uid" }, 9 | { "op": "is-set", "key": "k8s.job.uid" }, 10 | { "op": "is-set", "key": "k8s.replicaset.uid" }, 11 | { "op": "is-set", "key": "k8s.statefulset.uid" } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /test-resources/util/otlp-resource-analyzer/filters/host_name_is_set.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "host name is set", 3 | "op": "is-set", "key": "host.name" 4 | } 5 | -------------------------------------------------------------------------------- /test-resources/util/otlp-resource-analyzer/filters/host_name_set_to_pod_name.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "host name == pod name", 3 | "op": "or", 4 | "filters": [ 5 | { "op": "value-contains", "key": "host.name", "regex": "daemonset" }, 6 | { "op": "value-contains", "key": "host.name", "regex": "deployment" } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /test-resources/util/otlp-resource-analyzer/filters/pod_name_but_no_pod_uid.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pod name without pod uid", 3 | "op": "and", 4 | "filters": [ 5 | { "op": "is-set", "key": "k8s.pod.name" }, 6 | { "op": "is-not-set", "key": "k8s.pod.uid" } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /test-resources/util/otlp-resource-analyzer/filters/pods_with_higher_order_uid.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pods *with* higher order workload uid", 3 | "op": "and", 4 | "filters": [ 5 | { "op": "is-set", "key": "k8s.pod.uid" }, 6 | { "op": "is-not-set", "key": "k8s.container.name" }, 7 | { "op": "value-contains-not", "key": "k8s.namespace.name", "regex": "kube-system" }, 8 | { 9 | "op": "or", 10 | "filters": [ 11 | { "op": "is-set", "key": "k8s.cronjob.uid" }, 12 | { "op": "is-set", "key": "k8s.daemonset.uid" }, 13 | { "op": "is-set", "key": "k8s.daemonset.uid" }, 14 | { "op": "is-set", "key": "k8s.deployment.uid" }, 15 | { "op": "is-set", "key": "k8s.job.uid" }, 16 | { "op": "is-set", "key": "k8s.replicaset.uid" }, 17 | { "op": "is-set", "key": "k8s.statefulset.uid" } 18 | ] 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /test-resources/util/otlp-resource-analyzer/filters/pods_without_higher_order_uid.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pods *without* higher order workload uid", 3 | "op": "and", 4 | "filters": [ 5 | { "op": "is-set", "key": "k8s.pod.uid" }, 6 | { "op": "is-not-set", "key": "k8s.container.name" }, 7 | { "op": "value-contains-not", "key": "k8s.namespace.name", "regex": "kube-system" }, 8 | { "op": "is-not-set", "key": "k8s.cronjob.uid" }, 9 | { "op": "is-not-set", "key": "k8s.daemonset.uid" }, 10 | { "op": "is-not-set", "key": "k8s.daemonset.uid" }, 11 | { "op": "is-not-set", "key": "k8s.deployment.uid" }, 12 | { "op": "is-not-set", "key": "k8s.job.uid" }, 13 | { "op": "is-not-set", "key": "k8s.replicaset.uid" }, 14 | { "op": "is-not-set", "key": "k8s.statefulset.uid" } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /test-resources/util/otlp-resource-analyzer/filters/show_all_resources.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "show all resources", 3 | "op": "and", 4 | "filters": [] 5 | } 6 | -------------------------------------------------------------------------------- /test-resources/util/otlp-resource-analyzer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "query-otlp-ndjson", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "scripts": { 6 | "start": "NODE_ENV=development DEBUG=* node ." 7 | }, 8 | "author": "Bastian Krol ", 9 | "license": "ISC", 10 | "description": "", 11 | "dependencies": { 12 | "body-parser": "^2.2.0", 13 | "bootstrap": "^5.3.6", 14 | "cookie-parser": "~1.4.7", 15 | "debug": "~4.4.1", 16 | "express": "^5.1.0", 17 | "http-errors": "~2.0.0", 18 | "morgan": "~1.10.0", 19 | "nocache": "^4.0.0", 20 | "prettier": "^3.5.3", 21 | "pug": "3.0.3" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test-resources/util/otlp-resource-analyzer/public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | .error { 2 | color: red; 3 | font-size: larger; 4 | } 5 | -------------------------------------------------------------------------------- /test-resources/util/otlp-resource-analyzer/views/error.pug: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= message 5 | h2= error.status 6 | pre #{error.stack} 7 | -------------------------------------------------------------------------------- /test-resources/util/otlp-resource-analyzer/views/layout.pug: -------------------------------------------------------------------------------- 1 | doctype html 2 | html(lang='en') 3 | head 4 | title= 'OTLP Resource Analyzer' 5 | meta(charset='utf-8') 6 | meta(name='viewport',content='width=device-width, initial-scale=1') 7 | link(rel='stylesheet', type='text/css', href='/bootstrap/bootstrap.css') 8 | link(rel='stylesheet', type='text/css', href='/stylesheets/style.css') 9 | body 10 | div.container 11 | block content 12 | -------------------------------------------------------------------------------- /test/e2e/constants.go: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package e2e 5 | 6 | const ( 7 | applicationUnderTestNamespace = "e2e-application-under-test-namespace" 8 | 9 | runtimeTypeLabelNodeJs = "Node.js" 10 | applicationPathNodeJs = "test-resources/node.js/express" 11 | workloadNameNodeJs = "dash0-operator-nodejs-20-express-test" 12 | 13 | runtimeTypeLabelJvm = "JVM" 14 | applicationPathJvm = "test-resources/jvm/spring-boot" 15 | workloadNameJvm = "dash0-operator-jvm-spring-boot-test" 16 | 17 | runtimeTypeLabelDotnet = ".NET" 18 | applicationPathDotnet = "test-resources/dotnet" 19 | workloadNameDotnet = "dash0-operator-dotnet-test" 20 | ) 21 | -------------------------------------------------------------------------------- /test/e2e/dash0-api-mock/Dockerfile: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | FROM --platform=${BUILDPLATFORM} golang:1.24-alpine3.21 AS builder 5 | 6 | WORKDIR /usr/local/go/dash0_api_mock 7 | 8 | COPY go.mod /usr/local/go/dash0_api_mock/go.mod 9 | COPY go.sum /usr/local/go/dash0_api_mock/go.sum 10 | RUN go mod download 11 | 12 | COPY *.go /usr/local/go/dash0_api_mock 13 | 14 | ARG TARGETOS 15 | ARG TARGETARCH 16 | 17 | RUN CGO_ENABLED=0 \ 18 | GOOS=${TARGETOS:-linux} \ 19 | GOARCH=${TARGETARCH} \ 20 | go build \ 21 | -ldflags '-extldflags "-static"' \ 22 | -v \ 23 | dash0-api-mock 24 | 25 | FROM scratch 26 | COPY --from=builder /usr/local/go/dash0_api_mock/dash0-api-mock /app/dash0-api-mock 27 | USER 65532:65532 28 | ENTRYPOINT [ "/app/dash0-api-mock" ] 29 | -------------------------------------------------------------------------------- /test/e2e/dash0-api-mock/go.mod: -------------------------------------------------------------------------------- 1 | module dash0-api-mock 2 | 3 | go 1.24.1 4 | 5 | require github.com/gin-gonic/gin v1.10.1 6 | 7 | require ( 8 | github.com/bytedance/sonic v1.13.2 // indirect 9 | github.com/bytedance/sonic/loader v0.2.4 // indirect 10 | github.com/cloudwego/base64x v0.1.5 // indirect 11 | github.com/gabriel-vasile/mimetype v1.4.9 // indirect 12 | github.com/gin-contrib/sse v1.1.0 // indirect 13 | github.com/go-playground/locales v0.14.1 // indirect 14 | github.com/go-playground/universal-translator v0.18.1 // indirect 15 | github.com/go-playground/validator/v10 v10.26.0 // indirect 16 | github.com/goccy/go-json v0.10.5 // indirect 17 | github.com/json-iterator/go v1.1.12 // indirect 18 | github.com/klauspost/cpuid/v2 v2.2.10 // indirect 19 | github.com/leodido/go-urn v1.4.0 // indirect 20 | github.com/mattn/go-isatty v0.0.20 // indirect 21 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 22 | github.com/modern-go/reflect2 v1.0.2 // indirect 23 | github.com/pelletier/go-toml/v2 v2.2.4 // indirect 24 | github.com/twitchyliquid64/golang-asm v0.15.1 // indirect 25 | github.com/ugorji/go/codec v1.2.12 // indirect 26 | golang.org/x/arch v0.17.0 // indirect 27 | golang.org/x/crypto v0.38.0 // indirect 28 | golang.org/x/net v0.40.0 // indirect 29 | golang.org/x/sys v0.33.0 // indirect 30 | golang.org/x/text v0.25.0 // indirect 31 | google.golang.org/protobuf v1.36.6 // indirect 32 | gopkg.in/yaml.v3 v3.0.1 // indirect 33 | ) 34 | -------------------------------------------------------------------------------- /test/e2e/dash0monitoring.e2e.yaml.template: -------------------------------------------------------------------------------- 1 | apiVersion: operator.dash0.com/v1alpha1 2 | kind: Dash0Monitoring 3 | metadata: 4 | name: dash0-monitoring-resource-e2e 5 | spec: 6 | instrumentWorkloads: {{ .InstrumentWorkloads }} 7 | {{- if .Endpoint }} 8 | export: 9 | dash0: 10 | endpoint: {{ .Endpoint }} 11 | authorization: 12 | token: {{ .Token }} 13 | {{- end }} 14 | {{- if .Filter }} 15 | filter: 16 | {{- .Filter | indent 4 -}} 17 | {{- end }} 18 | {{- if .Transform }} 19 | transform: 20 | {{- .Transform | indent 4 -}} 21 | {{- end }} -------------------------------------------------------------------------------- /test/e2e/dash0operatorconfiguration.e2e.yaml.template: -------------------------------------------------------------------------------- 1 | apiVersion: operator.dash0.com/v1alpha1 2 | kind: Dash0OperatorConfiguration 3 | metadata: 4 | name: dash0-operator-configuration-resource-e2e 5 | spec: 6 | selfMonitoring: 7 | enabled: {{ .SelfMonitoringEnabled }} 8 | {{- if .Endpoint }} 9 | export: 10 | dash0: 11 | endpoint: {{ .Endpoint }} 12 | authorization: 13 | token: {{ .Token }} 14 | apiEndpoint: {{ .ApiEndpoint }} 15 | {{- end }} 16 | clusterName: {{ .ClusterName }} 17 | -------------------------------------------------------------------------------- /test/e2e/e2e_suite_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package e2e 5 | 6 | import ( 7 | "fmt" 8 | "testing" 9 | 10 | . "github.com/onsi/ginkgo/v2" 11 | . "github.com/onsi/gomega" 12 | ) 13 | 14 | // run e2e tests using the Ginkgo runner. 15 | func TestE2E(t *testing.T) { 16 | RegisterFailHandler(collectPodInfoAndLogsFailWrapper) 17 | _, _ = fmt.Fprint(GinkgoWriter, "Starting dash0-operator suite\n") 18 | RunSpecs(t, "Dash0 operator end-to-end test suite") 19 | } 20 | -------------------------------------------------------------------------------- /test/e2e/k8s_cluster_receiver_metrics.txt: -------------------------------------------------------------------------------- 1 | # extracted from https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/receiver/k8sclusterreceiver/metadata.yaml 2 | k8s.container.cpu_limit 3 | k8s.container.cpu_request 4 | k8s.container.ephemeralstorage_limit 5 | k8s.container.ephemeralstorage_request 6 | k8s.container.memory_limit 7 | k8s.container.memory_request 8 | k8s.container.ready 9 | k8s.container.storage_limit 10 | k8s.container.storage_request 11 | k8s.cronjob.active_jobs 12 | k8s.daemonset.current_scheduled_nodes 13 | k8s.daemonset.desired_scheduled_nodes 14 | k8s.daemonset.misscheduled_nodes 15 | k8s.daemonset.ready_nodes 16 | k8s.deployment.available 17 | k8s.deployment.desired 18 | k8s.hpa.current_replicas 19 | k8s.hpa.desired_replicas 20 | k8s.hpa.max_replicas 21 | k8s.hpa.min_replicas 22 | k8s.job.active_pods 23 | k8s.job.desired_successful_pods 24 | k8s.job.failed_pods 25 | k8s.job.max_parallel_pods 26 | k8s.job.successful_pods 27 | k8s.namespace.phase 28 | k8s.node.condition 29 | k8s.pod.phase 30 | k8s.pod.status_reason 31 | k8s.replication_controller.available 32 | k8s.replication_controller.desired 33 | k8s.resource_quota.hard_limit 34 | k8s.resource_quota.used 35 | k8s.statefulset.current_pods 36 | k8s.statefulset.desired_pods 37 | k8s.statefulset.ready_pods 38 | k8s.statefulset.updated_pods 39 | openshift.appliedclusterquota.limit 40 | openshift.appliedclusterquota.used 41 | openshift.clusterquota.limit 42 | openshift.clusterquota.used 43 | -------------------------------------------------------------------------------- /test/e2e/persesdashboard.yaml.template: -------------------------------------------------------------------------------- 1 | apiVersion: perses.dev/v1alpha1 2 | kind: PersesDashboard 3 | metadata: 4 | name: perses-dashboard-e2e-test 5 | labels: 6 | app.kubernetes.io/name: perses-dashboard-e2e-test 7 | {{- if .Dash0ComEnabled }} 8 | dash0.com/enabled: {{ .Dash0ComEnabled | quote }} 9 | {{- end }} 10 | spec: 11 | duration: 30m 12 | display: 13 | name: E2E Test Dashboard 14 | panels: 15 | fc2f898d-2f49-4090-8c1b-7949da638d66: 16 | kind: Panel 17 | spec: 18 | display: 19 | name: Test Panel 20 | links: [] 21 | plugin: 22 | kind: Markdown 23 | spec: 24 | text: This is a test dashboard. 25 | layouts: 26 | - kind: Grid 27 | spec: 28 | items: 29 | - content: 30 | "$ref": "#/spec/panels/fc2f898d-2f49-4090-8c1b-7949da638d66" 31 | height: 10 32 | width: 24 33 | x: 0 34 | "y": 0 35 | display: 36 | title: Test Group 37 | collapse: 38 | open: true 39 | -------------------------------------------------------------------------------- /test/e2e/prometheus_receiver_metrics.txt: -------------------------------------------------------------------------------- 1 | nodejs_active_handles 2 | nodejs_active_handles_total 3 | nodejs_active_requests_total 4 | nodejs_active_resources 5 | nodejs_eventloop_lag_max_seconds 6 | nodejs_eventloop_lag_mean_seconds 7 | nodejs_eventloop_lag_min_seconds 8 | nodejs_eventloop_lag_p50_seconds 9 | nodejs_eventloop_lag_p90_seconds 10 | nodejs_eventloop_lag_p99_seconds 11 | nodejs_eventloop_lag_seconds 12 | nodejs_eventloop_lag_stddev_seconds 13 | nodejs_external_memory_bytes 14 | nodejs_gc_duration_seconds 15 | nodejs_heap_size_total_bytes 16 | nodejs_heap_size_used_bytes 17 | nodejs_heap_space_size_available_bytes 18 | nodejs_heap_space_size_total_bytes 19 | nodejs_heap_space_size_used_bytes 20 | nodejs_version_info 21 | process_cpu_seconds_total 22 | process_cpu_system_seconds_total 23 | process_cpu_user_seconds_total 24 | process_heap_bytes 25 | process_max_fds 26 | process_open_fds 27 | process_resident_memory_bytes 28 | process_start_time_seconds 29 | process_virtual_memory_bytes 30 | appundertest_testendointrequestcounter 31 | -------------------------------------------------------------------------------- /test/util/dummy_clients.go: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright 2025 Dash0 Inc. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package util 5 | 6 | import ( 7 | "context" 8 | 9 | "github.com/go-logr/logr" 10 | otelmetric "go.opentelemetry.io/otel/metric" 11 | ) 12 | 13 | type DummyAuthTokenClient struct { 14 | SetAuthTokenCalls int 15 | RemoveAuthTokenCalls int 16 | AuthToken string 17 | } 18 | 19 | func (c *DummyAuthTokenClient) SetAuthToken(_ context.Context, authToken string, _ *logr.Logger) { 20 | c.SetAuthTokenCalls++ 21 | c.AuthToken = authToken 22 | } 23 | 24 | func (c *DummyAuthTokenClient) RemoveAuthToken(_ context.Context, _ *logr.Logger) { 25 | c.RemoveAuthTokenCalls++ 26 | c.AuthToken = "" 27 | } 28 | 29 | func (c *DummyAuthTokenClient) Reset() { 30 | c.AuthToken = "" 31 | c.ResetCallCounts() 32 | } 33 | 34 | func (c *DummyAuthTokenClient) ResetCallCounts() { 35 | c.SetAuthTokenCalls = 0 36 | c.RemoveAuthTokenCalls = 0 37 | } 38 | 39 | type DummySelfMonitoringMetricsClient struct { 40 | InitializeSelfMonitoringMetricsCalls int 41 | } 42 | 43 | func (c *DummySelfMonitoringMetricsClient) InitializeSelfMonitoringMetrics( 44 | _ otelmetric.Meter, 45 | _ string, 46 | _ *logr.Logger, 47 | ) { 48 | c.InitializeSelfMonitoringMetricsCalls++ 49 | } 50 | 51 | func (c *DummySelfMonitoringMetricsClient) Reset() { 52 | c.ResetCallCounts() 53 | } 54 | 55 | func (c *DummySelfMonitoringMetricsClient) ResetCallCounts() { 56 | c.InitializeSelfMonitoringMetricsCalls = 0 57 | } 58 | --------------------------------------------------------------------------------