Files
eae5b0e346 [receiver/otlp] Fix profiles receiver reporting its samples as spans (#15090)
<!--Ex. Fixing a bug - Describe the bug and how this fixes the issue.
Ex. Adding a feature - Explain what this achieves.-->
#### Description

The profiles receiver erroneously reported all of its samples as traces
when emitting metrics. This means that no profiles receiver metrics were
reported, instead being attributed to spans.


<!-- Issue number if applicable -->
#### Link to tracking issue
Fixes #15089.

<!--Describe what testing was performed and which tests were added.-->
#### Testing

- Automatic testing of metrics, following the traces example above

Co-authored-by: Alex Boten <[email protected]>
2026-04-21 23:48:34 +00:00

57 lines
2.0 KiB
Go

// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
package profiles // import "go.opentelemetry.io/collector/receiver/otlpreceiver/internal/profiles"
import (
"context"
"go.opentelemetry.io/collector/consumer/xconsumer"
"go.opentelemetry.io/collector/pdata/pprofile/pprofileotlp"
"go.opentelemetry.io/collector/receiver/otlpreceiver/internal/errors"
"go.opentelemetry.io/collector/receiver/receiverhelper"
)
const dataFormatProtobuf = "protobuf"
// Receiver is the type used to handle spans from OpenTelemetry exporters.
type Receiver struct {
pprofileotlp.UnimplementedGRPCServer
nextConsumer xconsumer.Profiles
obsreport *receiverhelper.ObsReport
}
// New creates a new Receiver reference.
func New(nextConsumer xconsumer.Profiles, obsreport *receiverhelper.ObsReport) *Receiver {
return &Receiver{
nextConsumer: nextConsumer,
obsreport: obsreport,
}
}
// Export implements the service Export profiles func.
func (r *Receiver) Export(ctx context.Context, req pprofileotlp.ExportRequest) (pprofileotlp.ExportResponse, error) {
td := req.Profiles()
// We need to ensure that it propagates the receiver name as a tag
numSamples := td.SampleCount()
if numSamples == 0 {
return pprofileotlp.NewExportResponse(), nil
}
ctx = r.obsreport.StartProfilesOp(ctx)
err := r.nextConsumer.ConsumeProfiles(ctx, td)
r.obsreport.EndProfilesOp(ctx, dataFormatProtobuf, numSamples, err)
// Use appropriate status codes for permanent/non-permanent errors
// If we return the error straightaway, then the grpc implementation will set status code to Unknown
// Refer: https://github.com/grpc/grpc-go/blob/v1.59.0/server.go#L1345
// So, convert the error to appropriate grpc status and return the error
// NonPermanent errors will be converted to codes.Unavailable (equivalent to HTTP 503)
// Permanent errors will be converted to codes.InvalidArgument (equivalent to HTTP 400)
if err != nil {
return pprofileotlp.NewExportResponse(), errors.GetStatusFromError(err)
}
return pprofileotlp.NewExportResponse(), nil
}