diff --git a/.chloggen/pprof_port.yaml b/.chloggen/pprof_port.yaml new file mode 100644 index 0000000000000..26c6ad461b7fb --- /dev/null +++ b/.chloggen/pprof_port.yaml @@ -0,0 +1,27 @@ +# Use this changelog template to create an entry for release notes. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. receiver/filelog) +component: receiver/pprof + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Read pprof data from HTTP remote endpoints or the collector itself + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [38260] + +# (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: + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# 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: [] diff --git a/receiver/pprofreceiver/README.md b/receiver/pprofreceiver/README.md index 11bdd685d879e..0d0d03dcaced7 100644 --- a/receiver/pprofreceiver/README.md +++ b/receiver/pprofreceiver/README.md @@ -1,7 +1,7 @@ # Pprof Receiver -The Pprof Receiver collects profiles from files specified with a glob pattern. +The Pprof Receiver collects profiles from files specified with a glob pattern, from a remote endpoint or the running collector. | Status | | @@ -19,6 +19,10 @@ The Pprof Receiver collects profiles from files specified with a glob pattern. - `include` (required): The glob path for files to watch - `collection_interval` (default = `1m`): The interval at which metrics are emitted by this receiver. - `initial_delay` (default = `1s`): defines how long this receiver waits before starting. +- `block_profile_fraction` (default = `1`): (self scraper only) Fraction of blocking events that are profiled. + A value <= 0 disables profiling. See https://golang.org/pkg/runtime/#SetBlockProfileRate for details. +- `mutex_profile_fraction` (default = `1`): (self scraper only) Fraction of mutex contention events that are profiled. + A value <= 0 disables profiling. See https://golang.org/pkg/runtime/#SetMutexProfileFraction for details. ### Example @@ -29,3 +33,10 @@ receivers: collection_interval: 10s initial_delay: 1s ``` + +Collector with remote endpoint: +```yaml +receivers: + pprof: + endpoint: "http://localhost:6060/debug/pprof/profile?seconds=1" +``` \ No newline at end of file diff --git a/receiver/pprofreceiver/config.go b/receiver/pprofreceiver/config.go index c67549bedde66..6aec409cc0f9d 100644 --- a/receiver/pprofreceiver/config.go +++ b/receiver/pprofreceiver/config.go @@ -4,13 +4,36 @@ package pprofreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/pprofreceiver" import ( + "errors" + + "go.opentelemetry.io/collector/config/confighttp" "go.opentelemetry.io/collector/scraper/scraperhelper" ) // Config defines the configuration for the pprof receiver. type Config struct { scraperhelper.ControllerConfig `mapstructure:",squash"` + confighttp.ClientConfig `mapstructure:",squash"` // Include is the glob pattern for pprof files to scrape. Include string `mapstructure:"include"` + + // Self-scraper only: + // Fraction of blocking events that are profiled. A value <= 0 disables + // profiling. See https://golang.org/pkg/runtime/#SetBlockProfileRate for details. + BlockProfileFraction int `mapstructure:"block_profile_fraction"` + + // Self-scraper only: + // Fraction of mutex contention events that are profiled. A value <= 0 + // disables profiling. See https://golang.org/pkg/runtime/#SetMutexProfileFraction + // for details. + MutexProfileFraction int `mapstructure:"mutex_profile_fraction"` +} + +func (c *Config) Validate() error { + if c.Include != "" && c.Endpoint != "" { + return errors.New("either include or endpoint must be specified") + } + + return nil } diff --git a/receiver/pprofreceiver/config.schema.yaml b/receiver/pprofreceiver/config.schema.yaml index 66066abefe00d..5b58d027d80a0 100644 --- a/receiver/pprofreceiver/config.schema.yaml +++ b/receiver/pprofreceiver/config.schema.yaml @@ -1,8 +1,15 @@ description: Config defines the configuration for the pprof receiver. type: object properties: + block_profile_fraction: + description: 'Self-scraper only: Fraction of blocking events that are profiled. A value <= 0 disables profiling. See https://golang.org/pkg/runtime/#SetBlockProfileRate for details.' + type: integer include: description: Include is the glob pattern for pprof files to scrape. type: string + mutex_profile_fraction: + description: 'Self-scraper only: Fraction of mutex contention events that are profiled. A value <= 0 disables profiling. See https://golang.org/pkg/runtime/#SetMutexProfileFraction for details.' + type: integer allOf: - $ref: go.opentelemetry.io/collector/scraper/scraperhelper.controller_config + - $ref: go.opentelemetry.io/collector/config/confighttp.client_config diff --git a/receiver/pprofreceiver/factory.go b/receiver/pprofreceiver/factory.go index 202785a133c2f..c52638765425e 100644 --- a/receiver/pprofreceiver/factory.go +++ b/receiver/pprofreceiver/factory.go @@ -31,8 +31,10 @@ func createDefaultConfig() component.Config { scraperCfg.CollectionInterval = 10 * time.Second return &Config{ - ControllerConfig: scraperCfg, - Include: "", + ControllerConfig: scraperCfg, + Include: "", + BlockProfileFraction: 1, + MutexProfileFraction: 1, } } @@ -48,12 +50,11 @@ func createProfilesReceiver( metadata.Type, func() component.Config { return &Config{} }, xscraper.WithProfiles(func(_ context.Context, set scraper.Settings, _ component.Config) (xscraper.Profiles, error) { - ps := newScraper(rCfg, receiver.Settings{ + return newScraper(rCfg, receiver.Settings{ ID: set.ID, TelemetrySettings: set.TelemetrySettings, BuildInfo: settings.BuildInfo, }) - return xscraper.NewProfiles(ps.scrape, xscraper.WithStart(ps.start)) }, metadata.ProfilesStability), ) diff --git a/receiver/pprofreceiver/go.mod b/receiver/pprofreceiver/go.mod index 4c2c39044e48d..5293fb063d472 100644 --- a/receiver/pprofreceiver/go.mod +++ b/receiver/pprofreceiver/go.mod @@ -9,6 +9,7 @@ require ( github.com/stretchr/testify v1.11.1 go.opentelemetry.io/collector/component v1.53.1-0.20260312104527-c74f90fe3922 go.opentelemetry.io/collector/component/componenttest v0.147.1-0.20260312104527-c74f90fe3922 + go.opentelemetry.io/collector/config/confighttp v0.147.1-0.20260312104527-c74f90fe3922 go.opentelemetry.io/collector/confmap v1.53.1-0.20260312104527-c74f90fe3922 go.opentelemetry.io/collector/consumer/consumertest v0.147.1-0.20260312104527-c74f90fe3922 go.opentelemetry.io/collector/consumer/xconsumer v0.147.1-0.20260312104527-c74f90fe3922 @@ -28,13 +29,19 @@ require ( require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect + github.com/golang/snappy v1.0.0 // indirect + github.com/google/go-tpm v0.9.8 // indirect github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/go-version v1.8.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.18.4 // indirect github.com/klauspost/cpuid/v2 v2.2.10 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect @@ -43,24 +50,41 @@ require ( github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect + github.com/pierrec/lz4/v4 v4.1.26 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/rs/cors v1.11.1 // indirect github.com/zeebo/xxh3 v1.1.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/collector/client v1.53.1-0.20260312104527-c74f90fe3922 // indirect + go.opentelemetry.io/collector/config/configauth v1.53.1-0.20260312104527-c74f90fe3922 // indirect + go.opentelemetry.io/collector/config/configcompression v1.53.1-0.20260312104527-c74f90fe3922 // indirect + go.opentelemetry.io/collector/config/configmiddleware v1.53.1-0.20260312104527-c74f90fe3922 // indirect + go.opentelemetry.io/collector/config/confignet v1.53.1-0.20260312104527-c74f90fe3922 // indirect + go.opentelemetry.io/collector/config/configopaque v1.53.1-0.20260312104527-c74f90fe3922 // indirect + go.opentelemetry.io/collector/config/configoptional v1.53.1-0.20260312104527-c74f90fe3922 // indirect + go.opentelemetry.io/collector/config/configtls v1.53.1-0.20260312104527-c74f90fe3922 // indirect + go.opentelemetry.io/collector/confmap/xconfmap v0.147.1-0.20260312104527-c74f90fe3922 // indirect go.opentelemetry.io/collector/consumer v1.53.1-0.20260312104527-c74f90fe3922 // indirect go.opentelemetry.io/collector/consumer/consumererror v0.147.1-0.20260312104527-c74f90fe3922 // indirect + go.opentelemetry.io/collector/extension/extensionauth v1.53.1-0.20260312104527-c74f90fe3922 // indirect + go.opentelemetry.io/collector/extension/extensionmiddleware v0.147.1-0.20260312104527-c74f90fe3922 // indirect go.opentelemetry.io/collector/featuregate v1.53.1-0.20260312104527-c74f90fe3922 // indirect go.opentelemetry.io/collector/internal/componentalias v0.147.1-0.20260312104527-c74f90fe3922 // indirect go.opentelemetry.io/collector/pdata v1.53.1-0.20260312104527-c74f90fe3922 // indirect go.opentelemetry.io/collector/pipeline v1.53.1-0.20260312104527-c74f90fe3922 // indirect go.opentelemetry.io/collector/pipeline/xpipeline v0.147.1-0.20260312104527-c74f90fe3922 // indirect go.opentelemetry.io/collector/receiver/receiverhelper v0.147.1-0.20260312104527-c74f90fe3922 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 // indirect go.opentelemetry.io/otel v1.42.0 // indirect go.opentelemetry.io/otel/metric v1.42.0 // indirect go.opentelemetry.io/otel/sdk v1.42.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.42.0 // indirect go.opentelemetry.io/otel/trace v1.42.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/crypto v0.48.0 // indirect + golang.org/x/net v0.51.0 // indirect golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect google.golang.org/grpc v1.79.2 // indirect google.golang.org/protobuf v1.36.11 // indirect diff --git a/receiver/pprofreceiver/go.sum b/receiver/pprofreceiver/go.sum index 61d7ae9fea022..c3f312cb46bc7 100644 --- a/receiver/pprofreceiver/go.sum +++ b/receiver/pprofreceiver/go.sum @@ -5,6 +5,12 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f h1:RJ+BDPLSHQO7cSjKBqjPJSbi1qfk9WcsjQDtZiw3dZw= +github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f/go.mod h1:VHbbch/X4roIY22jL1s3qRbZhCiRIgUAF/PdSUcx2io= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -16,8 +22,14 @@ github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= +github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= +github.com/google/go-tpm v0.9.8/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= +github.com/google/go-tpm-tools v0.4.7 h1:J3ycC8umYxM9A4eF73EofRZu4BxY0jjQnUnkhIBbvws= +github.com/google/go-tpm-tools v0.4.7/go.mod h1:gSyXTZHe3fgbzb6WEGd90QucmsnT1SRdlye82gH8QjQ= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20260111202518-71be6bfdd440 h1:oKBqR+eQXiIM7X8K1JEg9aoTEePLq/c6Awe484abOuA= github.com/google/pprof v0.0.0-20260111202518-71be6bfdd440/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI= @@ -27,6 +39,8 @@ github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bP github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= +github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= @@ -49,10 +63,14 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pierrec/lz4/v4 v4.1.26 h1:GrpZw1gZttORinvzBdXPUXATeqlJjqUG/D87TKMnhjY= +github.com/pierrec/lz4/v4 v4.1.26/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= +github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= @@ -63,12 +81,32 @@ github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/collector/client v1.53.1-0.20260312104527-c74f90fe3922 h1:O66uf+AmWAR1a9JlpfqVQGAHxpN/vpfKgcCiqXiWN8o= +go.opentelemetry.io/collector/client v1.53.1-0.20260312104527-c74f90fe3922/go.mod h1:7Tyz93uX4Ur65ApO/EAwk/3aRnNJSwSKWmnHSnHj4eM= go.opentelemetry.io/collector/component v1.53.1-0.20260312104527-c74f90fe3922 h1:02e6qduDLPdDkOUX+JXYdGOkAusuonBzHQoI5aNuodE= go.opentelemetry.io/collector/component v1.53.1-0.20260312104527-c74f90fe3922/go.mod h1:/tgJRfWsks4wZYdOxDx9BfXcsl2svmYlkExicqwhkQw= go.opentelemetry.io/collector/component/componenttest v0.147.1-0.20260312104527-c74f90fe3922 h1:XTPGcYrnxSnH+qghHUsEY8dQ1bJVOmn596gbsubPbCQ= go.opentelemetry.io/collector/component/componenttest v0.147.1-0.20260312104527-c74f90fe3922/go.mod h1:M2qQ6T9mbYlFho/RwVkNqel4f+1i0yhi7yPYK+QMOGs= +go.opentelemetry.io/collector/config/configauth v1.53.1-0.20260312104527-c74f90fe3922 h1:7axhsRPHxDoOb8AW2Lm0RtrblrbdKWGPjxOBJWFdl/Y= +go.opentelemetry.io/collector/config/configauth v1.53.1-0.20260312104527-c74f90fe3922/go.mod h1:/yo6MswmtsYor2DboulI+BYIdjVhiHIa1vcbyBOURfE= +go.opentelemetry.io/collector/config/configcompression v1.53.1-0.20260312104527-c74f90fe3922 h1:BMnz7TiubyYZpTtmnfZHa8FnlF+lwrdAVnWjZfKMj4k= +go.opentelemetry.io/collector/config/configcompression v1.53.1-0.20260312104527-c74f90fe3922/go.mod h1:SEcE2uFLHHPc/Vi8WCkW5MhOMUwaT321HBdZ3P8x8D0= +go.opentelemetry.io/collector/config/confighttp v0.147.1-0.20260312104527-c74f90fe3922 h1:OO52upvp3fN+WfpdJMBr4ltaHDAMjNB4UGj7VYVLJKI= +go.opentelemetry.io/collector/config/confighttp v0.147.1-0.20260312104527-c74f90fe3922/go.mod h1:72wu6ubiPvaG12VQ1aoPL04WUfRjfWsX5+tLHFYdRqg= +go.opentelemetry.io/collector/config/configmiddleware v1.53.1-0.20260312104527-c74f90fe3922 h1:XQwabBabE4XhY/uKlfoxOPM/QAugSJ36kRrXw1e9iI8= +go.opentelemetry.io/collector/config/configmiddleware v1.53.1-0.20260312104527-c74f90fe3922/go.mod h1:Mwb270V8W84NIvxJ9C7xUMLth4tU85IAdJL7JTj4uVs= +go.opentelemetry.io/collector/config/confignet v1.53.1-0.20260312104527-c74f90fe3922 h1:DQBU1D91gMCg6uFbSk30Ar8VBo/Of5f7seRZCpzNDRg= +go.opentelemetry.io/collector/config/confignet v1.53.1-0.20260312104527-c74f90fe3922/go.mod h1:okpHzgIUQW9ga1P9PXzUsggmG1woR1rYsfZGDWKAC6c= +go.opentelemetry.io/collector/config/configopaque v1.53.1-0.20260312104527-c74f90fe3922 h1:5/1V6qHo+fQnZpBlY9zYDoVfNMmxF9UaSClygMa2/hg= +go.opentelemetry.io/collector/config/configopaque v1.53.1-0.20260312104527-c74f90fe3922/go.mod h1:xVXG7rnOGHCzgCL3gKcQmSGdq1Y2AxxF+c/6eiPiI2A= +go.opentelemetry.io/collector/config/configoptional v1.53.1-0.20260312104527-c74f90fe3922 h1:EOZfLqL6Mg0CZaNyBOYAhJ/ib04IXcmngvm9OIp/sxk= +go.opentelemetry.io/collector/config/configoptional v1.53.1-0.20260312104527-c74f90fe3922/go.mod h1:dE/hkuZuV6RB6n4D7aCzQX+MOIyd3DpuIeASZD+B7w8= +go.opentelemetry.io/collector/config/configtls v1.53.1-0.20260312104527-c74f90fe3922 h1:WVzSTBMIHiwE6p8DZXdEGUN70sFNzd5jEvx+tRnlEzA= +go.opentelemetry.io/collector/config/configtls v1.53.1-0.20260312104527-c74f90fe3922/go.mod h1:CocDbAhxm+EBY1tWmaduNmzGbHVtrkdB/cTrR8haukU= go.opentelemetry.io/collector/confmap v1.53.1-0.20260312104527-c74f90fe3922 h1:YIXh0ZJx37Brlrt+Po8X47cXlFQVEO1J7VkfQG+0Ou4= go.opentelemetry.io/collector/confmap v1.53.1-0.20260312104527-c74f90fe3922/go.mod h1:fandgkechnNLI0FctZVJY6NGzuTqazyztUN3weshGYY= +go.opentelemetry.io/collector/confmap/xconfmap v0.147.1-0.20260312104527-c74f90fe3922 h1:z4vBVd7DnBp9STIXYwYAHJpW3/TOVP9UEjq+6KONNCs= +go.opentelemetry.io/collector/confmap/xconfmap v0.147.1-0.20260312104527-c74f90fe3922/go.mod h1:Y8DOF+GcT/2dR6LYJRCfAyntJLQaKjVGdkuHl9zLaLg= go.opentelemetry.io/collector/consumer v1.53.1-0.20260312104527-c74f90fe3922 h1:chbeZv6vk4wvk5L0FKm8/77YWEtkMSghcKb6pVSYWEA= go.opentelemetry.io/collector/consumer v1.53.1-0.20260312104527-c74f90fe3922/go.mod h1:f5U6ibd+XpC5eOSeEYhERAQJ2a5bp1d2RzW3MFddMDM= go.opentelemetry.io/collector/consumer/consumererror v0.147.1-0.20260312104527-c74f90fe3922 h1:PFUhcsJhN4ssBQjP/gYTKtbn5vYVO325igt8eQ6LbBI= @@ -77,6 +115,16 @@ go.opentelemetry.io/collector/consumer/consumertest v0.147.1-0.20260312104527-c7 go.opentelemetry.io/collector/consumer/consumertest v0.147.1-0.20260312104527-c74f90fe3922/go.mod h1:QWGFRmeYNbKaseDTNT3a2iGDmjl+DCZnLzMP7Rjj0JM= go.opentelemetry.io/collector/consumer/xconsumer v0.147.1-0.20260312104527-c74f90fe3922 h1:zvwakBvjvSGAAmjj8oiCWw6LHgWwr2U8SHnsKMTNrmY= go.opentelemetry.io/collector/consumer/xconsumer v0.147.1-0.20260312104527-c74f90fe3922/go.mod h1:mtwh1VsUoGjxwdmXEzjbswH7KAGByJNCIMHmhqwXeK0= +go.opentelemetry.io/collector/extension v1.53.0 h1:rgg0zQe6zHPF2okbnoEA7UQ2Tyw12lwU1ToQTfxvp6M= +go.opentelemetry.io/collector/extension v1.53.0/go.mod h1:UawW4sBNV+TIXgz1GR+UtnMQYb8AfFbhEdKoKTYyf7M= +go.opentelemetry.io/collector/extension/extensionauth v1.53.1-0.20260312104527-c74f90fe3922 h1:MuMO5nintheftXs8MT3hxoikIjv32JmMVOl5ymX6UIc= +go.opentelemetry.io/collector/extension/extensionauth v1.53.1-0.20260312104527-c74f90fe3922/go.mod h1:5SXF5D0r+uhrHU50xCXAnJ1HNmSDDuXamD+fZdcYRLs= +go.opentelemetry.io/collector/extension/extensionauth/extensionauthtest v0.147.0 h1:VK8OeyWTtT9bkbCTSRIOM0wmvXamMm4eeWuszkc+1uc= +go.opentelemetry.io/collector/extension/extensionauth/extensionauthtest v0.147.0/go.mod h1:qi8SUTVdd+3FqTY5oaNaagoS/xR/Mj0xVmoHe6Z4S9k= +go.opentelemetry.io/collector/extension/extensionmiddleware v0.147.1-0.20260312104527-c74f90fe3922 h1:lu1lRfB4NcrVaAAYhOS+xPqnEw9hiHB39B0eaBl+GTg= +go.opentelemetry.io/collector/extension/extensionmiddleware v0.147.1-0.20260312104527-c74f90fe3922/go.mod h1:ySiHSkCzMcgphWdZiGYIPrFgaEGO2tPY3D0MipGsYpo= +go.opentelemetry.io/collector/extension/extensionmiddleware/extensionmiddlewaretest v0.147.0 h1:QsuUpmBwAZHOLdFC+j6EzL43G1EmGvBqz9JlJv4Bovc= +go.opentelemetry.io/collector/extension/extensionmiddleware/extensionmiddlewaretest v0.147.0/go.mod h1:rXkQ/Kw+UD3IovJQb8pXKoA8ZU7rm0nfwylsHzeF05A= go.opentelemetry.io/collector/featuregate v1.53.1-0.20260312104527-c74f90fe3922 h1:ZCfYa0H43+as7y6WeeUrIOJSwfuoSgogu+dmaeHxD5U= go.opentelemetry.io/collector/featuregate v1.53.1-0.20260312104527-c74f90fe3922/go.mod h1:PS7zY/zaCb28EqciePVwRHVhc3oKortTFXsi3I6ee4g= go.opentelemetry.io/collector/internal/componentalias v0.147.1-0.20260312104527-c74f90fe3922 h1:Mt5Ybbp2854fsvKvaic6n5BGXmi1EPvoXmE+ZjMfLKQ= @@ -109,6 +157,8 @@ go.opentelemetry.io/collector/scraper/scraperhelper/xscraperhelper v0.147.1-0.20 go.opentelemetry.io/collector/scraper/scraperhelper/xscraperhelper v0.147.1-0.20260312104527-c74f90fe3922/go.mod h1:DakNkzT2m8qLkN6UjlZ74zmNbhV71IcrElZyWsebEp4= go.opentelemetry.io/collector/scraper/xscraper v0.147.1-0.20260312104527-c74f90fe3922 h1:5m0cpaPtDFwD3ine0BN+NBdspcRqzt6uzqzoj9Yv0eU= go.opentelemetry.io/collector/scraper/xscraper v0.147.1-0.20260312104527-c74f90fe3922/go.mod h1:FTWCHe0cNIpkZKApJbzSN67MjB6wPfgWMYw5OxQc/Vo= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:OyrsyzuttWTSur2qN/Lm0m2a8yqyIjUVBZcxFPuXq2o= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg= go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= @@ -133,12 +183,16 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= google.golang.org/grpc v1.79.2 h1:fRMD94s2tITpyJGtBBn7MkMseNpOZU8ZxgC3MMBaXRU= diff --git a/receiver/pprofreceiver/internal/file_scraper.go b/receiver/pprofreceiver/internal/file_scraper.go new file mode 100644 index 0000000000000..571855f263bc7 --- /dev/null +++ b/receiver/pprofreceiver/internal/file_scraper.go @@ -0,0 +1,63 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package internal // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/pprofreceiver/internal" + +import ( + "context" + "fmt" + "os" + + "github.com/bmatcuk/doublestar/v4" + "github.com/google/pprof/profile" + "go.opentelemetry.io/collector/pdata/pprofile" + "go.opentelemetry.io/collector/scraper/scrapererror" + "go.uber.org/multierr" + "go.uber.org/zap" + + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/pprof" +) + +type FileScraper struct { + Include string + Logger *zap.Logger +} + +func (fs FileScraper) Scrape(_ context.Context) (pprofile.Profiles, error) { + matches, err := doublestar.FilepathGlob(fs.Include) + if err != nil { + return pprofile.NewProfiles(), err + } + + var scrapeErrors []error + result := pprofile.NewProfiles() + + for _, match := range matches { + reader, err := os.Open(match) + if err != nil { + scrapeErrors = append(scrapeErrors, fmt.Errorf("failed to open file %s: %w", match, err)) + continue + } + + pprofProfile, err := profile.Parse(reader) + reader.Close() + if err != nil { + scrapeErrors = append(scrapeErrors, fmt.Errorf("failed to parse pprof data from %s: %w", match, err)) + continue + } + + profiles, err := pprof.ConvertPprofToProfiles(pprofProfile) + if err != nil { + scrapeErrors = append(scrapeErrors, fmt.Errorf("failed to convert pprof to profiles from %s: %w", match, err)) + continue + } + + profiles.ResourceProfiles().MoveAndAppendTo(result.ResourceProfiles()) + fs.Logger.Debug("Successfully scraped pprof file", zap.String("file", match)) + } + + if len(scrapeErrors) > 0 { + return result, scrapererror.NewPartialScrapeError(multierr.Combine(scrapeErrors...), len(scrapeErrors)) + } + return result, nil +} diff --git a/receiver/pprofreceiver/internal/http_scraper.go b/receiver/pprofreceiver/internal/http_scraper.go new file mode 100644 index 0000000000000..780505a5ab5a0 --- /dev/null +++ b/receiver/pprofreceiver/internal/http_scraper.go @@ -0,0 +1,60 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package internal // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/pprofreceiver/internal" + +import ( + "context" + "fmt" + "net/http" + + "github.com/google/pprof/profile" + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config/confighttp" + "go.opentelemetry.io/collector/pdata/pprofile" + "go.opentelemetry.io/collector/scraper/xscraper" + "go.uber.org/zap" + + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/pprof" +) + +var _ xscraper.Profiles = &HTTPClientScraper{} + +type HTTPClientScraper struct { + ClientConfig confighttp.ClientConfig + Settings component.TelemetrySettings + client *http.Client +} + +func (hcs *HTTPClientScraper) Start(ctx context.Context, host component.Host) error { + httpClient, err := hcs.ClientConfig.ToClient(ctx, host.GetExtensions(), hcs.Settings) + hcs.client = httpClient + return err +} + +func (hcs *HTTPClientScraper) Shutdown(_ context.Context) error { + if hcs.client != nil { + hcs.client.CloseIdleConnections() + hcs.client = nil + } + return nil +} + +func (hcs *HTTPClientScraper) ScrapeProfiles(_ context.Context) (pprofile.Profiles, error) { + resp, err := hcs.client.Get(hcs.ClientConfig.Endpoint) + if err != nil { + hcs.Settings.Logger.Error("error requesting profile", zap.Error(err), zap.String("endpoint", hcs.ClientConfig.Endpoint)) + return pprofile.Profiles{}, err + } + + pprofProfile, err := profile.Parse(resp.Body) + if err != nil { + return pprofile.Profiles{}, fmt.Errorf("failed to parse pprof data: %w", err) + } + + profiles, err := pprof.ConvertPprofToProfiles(pprofProfile) + if err != nil { + return pprofile.Profiles{}, fmt.Errorf("failed to convert pprof to profiles: %w", err) + } + return *profiles, err +} diff --git a/receiver/pprofreceiver/internal/http_scraper_test.go b/receiver/pprofreceiver/internal/http_scraper_test.go new file mode 100644 index 0000000000000..1b50fbfb9983e --- /dev/null +++ b/receiver/pprofreceiver/internal/http_scraper_test.go @@ -0,0 +1,50 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package internal + +import ( + "context" + "errors" + "fmt" + "net" + "net/http" + "net/http/pprof" + "testing" + "time" + + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/config/confighttp" +) + +func TestHttpScraper(t *testing.T) { + listener, err := net.Listen("tcp", "127.0.0.1:0") + require.NoError(t, err) + server := http.Server{ + Handler: pprof.Handler("goroutine"), + ReadHeaderTimeout: 10 * time.Second, + } + go func() { + if err2 := server.Serve(listener); !errors.Is(err2, http.ErrServerClosed) { + panic(err2) + } + }() + t.Cleanup(func() { + ctx := context.WithoutCancel(t.Context()) + require.NoError(t, server.Shutdown(ctx)) + }) + + s := HTTPClientScraper{ + ClientConfig: confighttp.NewDefaultClientConfig(), + } + s.ClientConfig.Endpoint = fmt.Sprintf("http://%s/debug/pprof/", listener.Addr().String()) + err = s.Start(t.Context(), componenttest.NewNopHost()) + require.NoError(t, err) + defer func() { + require.NoError(t, s.Shutdown(t.Context())) + }() + p, err := s.ScrapeProfiles(t.Context()) + require.NoError(t, err) + require.NotEqual(t, 0, p.ProfileCount()) +} diff --git a/receiver/pprofreceiver/internal/self_scraper.go b/receiver/pprofreceiver/internal/self_scraper.go new file mode 100644 index 0000000000000..1c7858a6398cb --- /dev/null +++ b/receiver/pprofreceiver/internal/self_scraper.go @@ -0,0 +1,60 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package internal // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/pprofreceiver/internal" + +import ( + "bufio" + "bytes" + "context" + "runtime" + "runtime/pprof" + + "github.com/google/pprof/profile" + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/pdata/pprofile" + "go.opentelemetry.io/collector/scraper/xscraper" + + translator "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/pprof" +) + +var _ xscraper.Profiles = &SelfScraper{} + +type SelfScraper struct { + BlockProfileFraction int + MutexProfileFraction int + buf *bytes.Buffer + writer *bufio.Writer +} + +func (hcs *SelfScraper) Start(_ context.Context, _ component.Host) error { + runtime.SetBlockProfileRate(hcs.BlockProfileFraction) + runtime.SetMutexProfileFraction(hcs.MutexProfileFraction) + hcs.buf = bytes.NewBuffer(make([]byte, 0, 8096)) + hcs.writer = bufio.NewWriter(hcs.buf) + err := pprof.StartCPUProfile(hcs.writer) + return err +} + +func (*SelfScraper) Shutdown(_ context.Context) error { + pprof.StopCPUProfile() + return nil +} + +func (hcs *SelfScraper) ScrapeProfiles(_ context.Context) (pprofile.Profiles, error) { + pprof.StopCPUProfile() + _ = hcs.writer.Flush() + pprofProfile, parseErr := profile.Parse(hcs.buf) + hcs.buf.Reset() + if parseErr == nil { + p, err := translator.ConvertPprofToProfiles(pprofProfile) + _ = pprof.StartCPUProfile(hcs.writer) + if p == nil { + return pprofile.Profiles{}, err + } + return *p, err + } + + _ = pprof.StartCPUProfile(hcs.writer) + return pprofile.Profiles{}, parseErr +} diff --git a/receiver/pprofreceiver/internal/self_scraper_test.go b/receiver/pprofreceiver/internal/self_scraper_test.go new file mode 100644 index 0000000000000..5e4c7beee0bbd --- /dev/null +++ b/receiver/pprofreceiver/internal/self_scraper_test.go @@ -0,0 +1,26 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package internal + +import ( + "testing" + + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/component/componenttest" +) + +func TestScrapeSelf(t *testing.T) { + s := SelfScraper{ + BlockProfileFraction: 1, + MutexProfileFraction: 1, + } + err := s.Start(t.Context(), componenttest.NewNopHost()) + require.NoError(t, err) + defer func() { + require.NoError(t, s.Shutdown(t.Context())) + }() + p, err := s.ScrapeProfiles(t.Context()) + require.NoError(t, err) + require.NotEqual(t, 0, p.ProfileCount()) +} diff --git a/receiver/pprofreceiver/metadata.yaml b/receiver/pprofreceiver/metadata.yaml index 63492707b90de..c44d4247acc4a 100644 --- a/receiver/pprofreceiver/metadata.yaml +++ b/receiver/pprofreceiver/metadata.yaml @@ -2,7 +2,7 @@ display_name: Pprof Receiver type: pprof description: | - The Pprof Receiver collects profiles from files specified with a glob pattern. + The Pprof Receiver collects profiles from files specified with a glob pattern, from a remote endpoint or the running collector. status: class: receiver diff --git a/receiver/pprofreceiver/receiver.go b/receiver/pprofreceiver/receiver.go index 9ad47ab00804f..ded77dc1f6d5e 100644 --- a/receiver/pprofreceiver/receiver.go +++ b/receiver/pprofreceiver/receiver.go @@ -4,75 +4,30 @@ package pprofreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/pprofreceiver" import ( - "context" - "fmt" - "os" - - "github.com/bmatcuk/doublestar/v4" - "github.com/google/pprof/profile" - "go.opentelemetry.io/collector/component" - "go.opentelemetry.io/collector/pdata/pprofile" "go.opentelemetry.io/collector/receiver" - "go.opentelemetry.io/collector/scraper/scrapererror" - "go.uber.org/multierr" - "go.uber.org/zap" + "go.opentelemetry.io/collector/scraper/xscraper" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/pprof" + "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/pprofreceiver/internal" ) -type pprofScraper struct { - logger *zap.Logger - config *Config - settings component.TelemetrySettings -} - -func newScraper(cfg *Config, settings receiver.Settings) *pprofScraper { - return &pprofScraper{ - logger: settings.Logger, - settings: settings.TelemetrySettings, - config: cfg, - } -} - -func (*pprofScraper) start(_ context.Context, _ component.Host) error { - return nil -} - -func (s *pprofScraper) scrape(_ context.Context) (pprofile.Profiles, error) { - matches, err := doublestar.FilepathGlob(s.config.Include) - if err != nil { - return pprofile.NewProfiles(), err - } - - var scrapeErrors []error - result := pprofile.NewProfiles() - - for _, match := range matches { - reader, err := os.Open(match) - if err != nil { - scrapeErrors = append(scrapeErrors, fmt.Errorf("failed to open file %s: %w", match, err)) - continue - } - - pprofProfile, err := profile.Parse(reader) - reader.Close() - if err != nil { - scrapeErrors = append(scrapeErrors, fmt.Errorf("failed to parse pprof data from %s: %w", match, err)) - continue +func newScraper(cfg *Config, settings receiver.Settings) (xscraper.Profiles, error) { + if cfg.Include != "" { + fs := internal.FileScraper{ + Logger: settings.Logger, + Include: cfg.Include, } - - profiles, err := pprof.ConvertPprofToProfiles(pprofProfile) - if err != nil { - scrapeErrors = append(scrapeErrors, fmt.Errorf("failed to convert pprof to profiles from %s: %w", match, err)) - continue + return xscraper.NewProfiles(fs.Scrape) + } + if cfg.Endpoint != "" { + httpScraper := &internal.HTTPClientScraper{ + ClientConfig: cfg.ClientConfig, + Settings: settings.TelemetrySettings, } - - profiles.ResourceProfiles().MoveAndAppendTo(result.ResourceProfiles()) - s.logger.Debug("Successfully scraped pprof file", zap.String("file", match)) + return httpScraper, nil } - if len(scrapeErrors) > 0 { - return result, scrapererror.NewPartialScrapeError(multierr.Combine(scrapeErrors...), len(scrapeErrors)) - } - return result, nil + return &internal.SelfScraper{ + BlockProfileFraction: cfg.BlockProfileFraction, + MutexProfileFraction: cfg.MutexProfileFraction, + }, nil }