diff --git a/.chloggen/ebpf-profiler.yaml b/.chloggen/ebpf-profiler.yaml new file mode 100644 index 0000000..67fe343 --- /dev/null +++ b/.chloggen/ebpf-profiler.yaml @@ -0,0 +1,25 @@ +# Use this changelog template to create an entry for release notes. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: new_component + +# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver) +component: otelcol-ebpf-profiler + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Introduce eBPF Profiler Distribution + +# One or more tracking issues or pull requests related to the change +issues: [908] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: + +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [user] diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 8416fb0..cf3f00e 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -6,9 +6,9 @@ # # Learn about membership in OpenTelemetry community: # https://github.com/open-telemetry/community/blob/main/community-membership.md -# # -# Learn about CODEOWNERS file format: +# +# Learn about CODEOWNERS file format: # https://help.github.com/en/articles/about-code-owners # @@ -18,4 +18,4 @@ /distributions/otelcol-otlp/manifest.yaml @open-telemetry/collector-releases-approvers @open-telemetry/collector-approvers /distributions/otelcol-contrib/manifest.yaml @open-telemetry/collector-releases-approvers @open-telemetry/collector-contrib-approvers /distributions/otelcol-k8s/manifest.yaml @open-telemetry/collector-releases-approvers @open-telemetry/helm-approvers @open-telemetry/operator-approvers - +/distributions/otelcol-ebpf-profiler @open-telemetry/collector-releases-approvers @open-telemetry/ebpf-profiler-approvers diff --git a/.github/workflows/ci-goreleaser-ebpf-profiler.yaml b/.github/workflows/ci-goreleaser-ebpf-profiler.yaml new file mode 100644 index 0000000..2249278 --- /dev/null +++ b/.github/workflows/ci-goreleaser-ebpf-profiler.yaml @@ -0,0 +1,37 @@ +name: CI - eBPF Profiler - GoReleaser + +on: + merge_group: + push: + branches: [main] + paths: + - "distributions/otelcol-ebpf-profiler/**" + - "cmd/**" + - ".github/**" + - "scripts/**" + - "Makefile" + - "go.mod" + - "go.sum" + pull_request: + branches: [main] + paths: + - "distributions/otelcol-ebpf-profiler/**" + - "cmd/**" + - ".github/**" + - "scripts/**" + - "Makefile" + - "go.mod" + - "go.sum" + +jobs: + check-goreleaser: + name: CI - eBPF Profiler - GoReleaser + uses: ./.github/workflows/base-ci-goreleaser.yaml + with: + distribution: otelcol-ebpf-profiler + config_file: ebpf-profiler-config.yaml + docker_run_options: '--privileged --pid=host -v /sys/kernel/debug/:/sys/kernel/debug/:ro' + otelcol_run_options: '--feature-gates=service.profilesSupport' + goos: '[ "linux" ]' + goarch: '[ "amd64" ]' + secrets: inherit diff --git a/.github/workflows/scripts/bump-versions.sh b/.github/workflows/scripts/bump-versions.sh index e2f5375..6792423 100755 --- a/.github/workflows/scripts/bump-versions.sh +++ b/.github/workflows/scripts/bump-versions.sh @@ -1,8 +1,8 @@ #!/bin/bash set -e # This script reads current versions and takes optional next versions, and updates the -# version in the specified files. If next version is not provided, it will infer the -# next semantic version (e.g. v0.110.0 -> v0.111.0 or v1.16.0 -> v1.17.0) based on the +# version in the specified files. If next version is not provided, it will infer the +# next semantic version (e.g. v0.110.0 -> v0.111.0 or v1.16.0 -> v1.17.0) based on the # current version(s) read in. # List of files to update @@ -11,6 +11,7 @@ manifest_files=( "distributions/otelcol/manifest.yaml" "distributions/otelcol-k8s/manifest.yaml" "distributions/otelcol-otlp/manifest.yaml" + "distributions/otelcol-ebpf-profiler/manifest.yaml" ) # Function to display usage @@ -202,7 +203,7 @@ create_pr() { gh pr create --title "[chore] Prepare release $next_version" \ --body "This PR updates the version from $current_version to $next_version" \ - --base main --head "$branch_name" --draft + --base main --head "$branch_name" --draft } # TODO: Once Collector 1.0 is released, we can consider removing the diff --git a/Makefile b/Makefile index efbf02b..7128d75 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ TOOLS_BIN_NAMES := $(addprefix $(TOOLS_BIN_DIR)/, $(notdir $(shell echo $(TOOLS_ CHLOGGEN := $(TOOLS_BIN_DIR)/chloggen CHLOGGEN_CONFIG := .chloggen/config.yaml -DISTRIBUTIONS ?= "otelcol,otelcol-contrib,otelcol-k8s,otelcol-otlp" +DISTRIBUTIONS ?= "otelcol,otelcol-contrib,otelcol-k8s,otelcol-otlp,otelcol-ebpf-profiler" ci: check build check: ensure-goreleaser-up-to-date validate-components diff --git a/README.md b/README.md index e775841..24e7d3f 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ Current list of distributions: - [OpenTelemetry Collector Contrib (also known as "otelcol-contrib")](./distributions/otelcol-contrib) - [OpenTelemetry Collector for Kubernetes (also known as "otelcol-k8s")](./distributions/otelcol-k8s) - [OpenTelemetry Collector OTLP (also known as "otelcol-otlp")](./distributions/otelcol-otlp) +- [OpenTelemetry Collector eBPF Profiler (also known as "otelcol-ebpf-profiler")](./distributions/otelcol-ebpf-profiler) ## Community diff --git a/cmd/goreleaser/internal/configure.go b/cmd/goreleaser/internal/configure.go index 15618ad..2e25705 100644 --- a/cmd/goreleaser/internal/configure.go +++ b/cmd/goreleaser/internal/configure.go @@ -29,14 +29,15 @@ import ( ) const ( - armArch = "arm" - coreDistro = "otelcol" - contribDistro = "otelcol-contrib" - k8sDistro = "otelcol-k8s" - otlpDistro = "otelcol-otlp" - ghcr = "ghcr.io/open-telemetry/opentelemetry-collector-releases" - binaryNamePrefix = "otelcol" - imageNamePrefix = "opentelemetry-collector" + armArch = "arm" + coreDistro = "otelcol" + contribDistro = "otelcol-contrib" + k8sDistro = "otelcol-k8s" + otlpDistro = "otelcol-otlp" + ebpfProfilerDistro = "otelcol-ebpf-profiler" + ghcr = "ghcr.io/open-telemetry/opentelemetry-collector-releases" + binaryNamePrefix = "otelcol" + imageNamePrefix = "opentelemetry-collector" ) var ( @@ -45,6 +46,7 @@ var ( winContainerArchs = []string{"amd64"} darwinArchs = []string{"amd64", "arm64"} k8sArchs = []string{"amd64", "arm64", "ppc64le", "s390x"} + ebpfProfilerArchs = []string{"amd64"} imageRepos = []string{ghcr} @@ -141,6 +143,22 @@ var ( newContainerImageManifests(d.name, "linux", k8sArchs, containerImageOptions{}), ) }).WithDefaultArchives().WithDefaultChecksum().WithDefaultSigns().WithDefaultDockerSigns().WithDefaultSBOMs().Build() + + // ebpf-profiler distro + ebpfProfilerDist = newDistributionBuilder(ebpfProfilerDistro).WithConfigFunc(func(d *distribution) { + d.buildConfigs = []buildConfig{ + &fullBuildConfig{targetOS: "linux", targetArch: ebpfProfilerArchs}, + } + d.containerImages = slices.Concat( + newContainerImages(d.name, "linux", ebpfProfilerArchs, containerImageOptions{}), + ) + d.containerImageManifests = slices.Concat( + newContainerImageManifests(d.name, "linux", ebpfProfilerArchs, containerImageOptions{}), + ) + d.enableCgo = true + d.ldFlags = "-extldflags=-static" + d.goTags = "osusergo,netgo" + }).WithDefaultArchives().WithDefaultChecksum().WithDefaultSigns().WithDefaultDockerSigns().WithDefaultSBOMs().Build() ) type buildConfig interface { @@ -610,6 +628,8 @@ func BuildDist(dist string, onlyBuild bool) config.Project { return otlpDist.BuildProject() case k8sDistro: return k8sDist.BuildProject() + case ebpfProfilerDistro: + return ebpfProfilerDist.BuildProject() case contribDistro: if onlyBuild { return contribBuildOnlyDist.BuildProject() diff --git a/distributions/otelcol-ebpf-profiler/.goreleaser.yaml b/distributions/otelcol-ebpf-profiler/.goreleaser.yaml new file mode 100644 index 0000000..9b7a304 --- /dev/null +++ b/distributions/otelcol-ebpf-profiler/.goreleaser.yaml @@ -0,0 +1,78 @@ +version: 2 +project_name: opentelemetry-collector-releases +env: + - COSIGN_YES=true + - LD_FLAGS=-extldflags=-static + - BUILD_FLAGS=-trimpath + - GO_TAGS=osusergo,netgo +release: + replace_existing_artifacts: true +builds: + - id: otelcol-ebpf-profiler-linux + goos: + - linux + goarch: + - amd64 + dir: _build + binary: otelcol-ebpf-profiler + ldflags: + - '{{ .Env.LD_FLAGS }}' + flags: + - '{{ .Env.BUILD_FLAGS }}' +archives: + - id: otelcol-ebpf-profiler + builds: + - otelcol-ebpf-profiler-linux + name_template: '{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}' +checksum: + name_template: '{{ .ProjectName }}_otelcol-ebpf-profiler_checksums.txt' +dockers: + - goos: linux + goarch: amd64 + dockerfile: Dockerfile + image_templates: + - ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector-ebpf-profiler:{{ .Version }}-amd64 + - ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector-ebpf-profiler:latest-amd64 + build_flag_templates: + - --pull + - --platform=linux/amd64 + - --label=org.opencontainers.image.created={{.Date}} + - --label=org.opencontainers.image.name={{.ProjectName}} + - --label=org.opencontainers.image.revision={{.FullCommit}} + - --label=org.opencontainers.image.version={{.Version}} + - --label=org.opencontainers.image.source={{.GitURL}} + - --label=org.opencontainers.image.licenses=Apache-2.0 + use: buildx +docker_manifests: + - name_template: ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector-ebpf-profiler:{{ .Version }} + image_templates: + - ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector-ebpf-profiler:{{ .Version }}-amd64 + - name_template: ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector-ebpf-profiler:latest + image_templates: + - ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector-ebpf-profiler:latest-amd64 +signs: + - cmd: cosign + args: + - sign-blob + - --output-signature + - ${artifact}.sig + - --output-certificate + - ${artifact}.pem + - ${artifact} + signature: ${artifact}.sig + artifacts: all + certificate: ${artifact}.pem +docker_signs: + - args: + - sign + - ${artifact} + artifacts: all +sboms: + - id: archive + artifacts: archive + - id: package + artifacts: package +monorepo: + tag_prefix: v +partial: + by: target diff --git a/distributions/otelcol-ebpf-profiler/Dockerfile b/distributions/otelcol-ebpf-profiler/Dockerfile new file mode 100644 index 0000000..458eb34 --- /dev/null +++ b/distributions/otelcol-ebpf-profiler/Dockerfile @@ -0,0 +1,4 @@ +FROM golang:1.23.8 + +COPY --chmod=755 otelcol-ebpf-profiler /otelcol-ebpf-profiler +ENTRYPOINT ["/otelcol-ebpf-profiler"] diff --git a/distributions/otelcol-ebpf-profiler/README.md b/distributions/otelcol-ebpf-profiler/README.md new file mode 100644 index 0000000..bf298da --- /dev/null +++ b/distributions/otelcol-ebpf-profiler/README.md @@ -0,0 +1,36 @@ +# OpenTelemetry Collector eBPF Profiling Distribution + +This distribution is made specifically to be used as a node agent to gather +profiles on all processes running on the system. + +It contains the [eBPF profiler +receiver](https://github.com/open-telemetry/opentelemetry-ebpf-profiler) as +well as a subset of components from [OpenTelemetry Collector +Core](https://github.com/open-telemetry/opentelemetry-collector) and +[OpenTelemetry Collector +Contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib). + +## Requirements + +### CGO + +The use of the foreign language interface to bring in dependencies requires to +set CGO for the eBPF profiler. +To utilize a foreign language interface for incorporating dependencies into the +eBPF profiler, it is essential to configure and enable CGO. + +In order to enable CGO, we need a libc on the container. +We use glibc, and the distribution is tested against v2.39. + +## Components + +The full list of components is available in the [manifest](manifest.yaml). + +### Rules for Component Inclusion + +- Only includes components from Contrib and Core, except for the ebpf-profiler receiver. +- Only components that are Alpha or higher. +- All processors, connectors, and extensions must facilitate the collection and processing of data that is generated by the eBPF profiler. +- All components must be vendor-neutral. +- Only exporters that use OTLP are allowed. + - To facilitate troubleshooting, the nop, debug, and file exporters are exceptions. diff --git a/distributions/otelcol-ebpf-profiler/manifest.yaml b/distributions/otelcol-ebpf-profiler/manifest.yaml new file mode 100644 index 0000000..1b38c2f --- /dev/null +++ b/distributions/otelcol-ebpf-profiler/manifest.yaml @@ -0,0 +1,36 @@ +dist: + module: github.com/open-telemetry/opentelemetry-collector-releases/ebpf-profiler + name: otelcol-ebpf-profiler + description: OpenTelemetry Collector for eBPF Profiling + version: 0.123.1 + output_path: ./_build + +exporters: + - gomod: go.opentelemetry.io/collector/exporter/debugexporter v0.123.0 + - gomod: go.opentelemetry.io/collector/exporter/nopexporter v0.123.0 + - gomod: go.opentelemetry.io/collector/exporter/otlpexporter v0.123.0 + - gomod: go.opentelemetry.io/collector/exporter/otlphttpexporter v0.123.0 + - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/exporter/fileexporter v0.123.0 + +processors: + - gomod: go.opentelemetry.io/collector/processor/batchprocessor v0.123.0 + - gomod: go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.123.0 + - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/processor/k8sattributesprocessor v0.123.0 + - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor v0.123.0 + - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourceprocessor v0.123.0 + +receivers: + - gomod: go.opentelemetry.io/ebpf-profiler v0.0.0-20250408174414-ead430a15d49 + import: go.opentelemetry.io/ebpf-profiler/collector + +providers: + - gomod: go.opentelemetry.io/collector/confmap/provider/envprovider v1.29.0 + - gomod: go.opentelemetry.io/collector/confmap/provider/fileprovider v1.29.0 + - gomod: go.opentelemetry.io/collector/confmap/provider/httpprovider v1.29.0 + - gomod: go.opentelemetry.io/collector/confmap/provider/httpsprovider v1.29.0 + - gomod: go.opentelemetry.io/collector/confmap/provider/yamlprovider v1.29.0 + +# When adding a replace, add a comment before it to document why it's needed and when it can be removed +replaces: + # see https://github.com/openshift/api/pull/1515 + - github.com/openshift/api => github.com/openshift/api v0.0.0-20230726162818-81f778f3b3ec diff --git a/scripts/validate-components.sh b/scripts/validate-components.sh index da64c1c..1a8f6d6 100755 --- a/scripts/validate-components.sh +++ b/scripts/validate-components.sh @@ -5,7 +5,7 @@ # This script verifies that all components declared in manifest.yaml files are # defined in the builder-config.yaml from the opentelemetry-collector-contrib -# repository, ensuring they were built and tested successfully. +# repository, or ebpf-profiler, ensuring they were built and tested successfully. set -euo pipefail @@ -35,6 +35,8 @@ valid_components="$( | awk '{print $1}' \ | sort -u )" +valid_components+=' +go.opentelemetry.io/ebpf-profiler' if [[ -z "$valid_components" ]]; then echo "Error: No valid 'gomod' entries found in builder-config.yaml!" diff --git a/tests/docker-tests/ebpf-profiler-config.yaml b/tests/docker-tests/ebpf-profiler-config.yaml new file mode 100644 index 0000000..c71c904 --- /dev/null +++ b/tests/docker-tests/ebpf-profiler-config.yaml @@ -0,0 +1,14 @@ +receivers: + profiling: + SamplesPerSecond: 19 + +exporters: + otlphttp: + endpoint: "http://0.0.0.0:4317" + +service: + pipelines: + profiles: + receivers: [profiling] + processors: [] + exporters: [otlphttp]