Repository: open-telemetry/opentelemetry-go-contrib (go)

Issue:
Rename `go.opentelemetry.io/contrib/processors/baggage/baggagetrace`
- The `go.opentelemetry.io/contrib/processors/baggage/baggagetrace` package sits on the `go.opentelemetry.io/contrib/processors/*` prefix. This package prefix will need to be used for log processors as well.
- The `baggagetrace` package name is not descriptive of the functionality it provides. A name indicating the package provides a `SpanProcessor` that will copy baggage values into a span should be used instead.

### Proposal

1. Copy the package to a new package under the new `processors/span` directory
  - Use `processors/span` and not `processors/trace` as this is for a `SpanProcessor`
2. Rename the package to one of:
  - `go.opentelemetry.io/contrib/processors/span/bagcp`
  - `go.opentelemetry.io/contrib/processors/span/bagcopy`
  - `go.opentelemetry.io/contrib/processors/span/baggagecp`
  - `go.opentelemetry.io/contrib/processors/span/baggagecopy`
3. Deprecate `go.opentelemetry.io/contrib/processors/baggage/baggagetrace` in favor of the new package.

Pull request description:
Replace and deprecate `baggagetrace`
Resolve #5808 

- Move current version of `go.opentelemetry.io/contrib/processors/baggage/baggagetrace` to `go.opentelemetry.io/contrib/processors/baggagecopy`
- Rename `baggagecopy.New` to `baggagecopy.NewSpanProcessor` to allow for future processors
- Restore `go.opentelemetry.io/contrib/processors/baggage/baggagetrace` to its last released version (v0.0.1)
  - This excludes dependency upgrades
- Deprecate `go.opentelemetry.io/contrib/processors/baggage/baggagetrace`

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e5ef17eb9..96efc69e0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
 - Add log support for the autoexport package. (#5733)
 - Add support for disabling the old runtime metrics using the `OTEL_GO_X_DEPRECATED_RUNTIME_METRICS=false` environment variable. (#5747)
 - Add support for signal-specific protocols environment variables (`OTEL_EXPORTER_OTLP_TRACES_PROTOCOL`, `OTEL_EXPORTER_OTLP_LOGS_PROTOCOL`, `OTEL_EXPORTER_OTLP_METRICS_PROTOCOL`) in `go.opentelemetry.io/contrib/exporters/autoexport`. (#5816)
+- The `go.opentelemetry.io/contrib/processors/baggagecopy` module.
+  This module is a replacment of `go.opentelemetry.io/contrib/processors/baggage/baggagetrace`. (#5824)
 
 ### Fixed
 
@@ -24,7 +26,6 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
 - Use `c.FullPath()` method to set `http.route` attribute in `go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin`. (#5734)
 - The double setup in `go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace/example` that caused duplicate traces. (#5564)
 - Out-of-bounds panic in case of invalid span ID in `go.opentelemetry.io/contrib/propagators/b3`. (#5754)
-- Do not panic if a zero-value `SpanProcessor` is used from `go.opentelemetry.io/contrib/processors/baggage/baggagetrace`. (#5811)
 
 ### Deprecated
 
@@ -36,6 +37,12 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
   If you would like to become a Code Owner of this module and prevent it from being removed, see [#5552]. (#5646)
 - The `go.opentelemetry.io/contrib/samplers/aws/xray` package is deprecated.
   If you would like to become a Code Owner of this module and prevent it from being removed, see [#5554]. (#5647)
+- The `go.opentelemetry.io/contrib/processors/baggage/baggagetrace` package is deprecated.
+  Use the added `go.opentelemetry.io/contrib/processors/baggagecopy` package instead. (#5824)
+  - Use `baggagecopy.NewSpanProcessor` as a replacement for `baggagetrace.New`.
+    - `NewSpanProcessor` accepts a `Fitler` function type that selects which baggage members are added to a span.
+    - `NewSpanProcessor` returns a `*baggagecopy.SpanProcessor` instead of a `trace.SpanProcessor` interface.
+      The returned type still implements the interface.
 
 [#5550]: https://github.com/open-telemetry/opentelemetry-go-contrib/issues/5550
 [#5551]: https://github.com/open-telemetry/opentelemetry-go-contrib/issues/5551
@@ -47,10 +54,6 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
 - Improve performance of `go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc` with the usage of `WithAttributeSet()` instead of `WithAttribute()`. (#5664)
 - Improve performance of `go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp` with the usage of `WithAttributeSet()` instead of `WithAttribute()`. (#5664)
 - Update `go.opentelemetry.io/contrib/config` to latest released configuration schema which introduces breaking changes where `Attributes` is now a `map[string]interface{}`. (#5758)
-- Rename `BaggageKeyPredicate` to `Filter` in `go.opentelemetry.io/contrib/processors/baggage/baggagetrace`. (#5809)
-- Return `*SpanProcessor` from `"go.opentelemetry.io/contrib/processors/baggage/baggagetrace".New` instead of the `trace.SpanProcessor` interface. (#5810)
-- The `Filter` in `go.opentelemetry.io/contrib/processors/baggage/baggagetrace` now accepts a `baggage.Member` as a parameter instead of a string. (#5813)
-- Rename `AllowAllBaggageKeys` to `AllowAllMembers` in `go.opentelemetry.io/contrib/processors/baggage/baggagetrace`. (#5813)
 
 ## [1.27.0/0.52.0/0.21.0/0.7.0/0.2.0] - 2024-05-21
 
@@ -84,8 +87,6 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
   This parameter is used as a replacement of `WithInstrumentationScope` to specify the name of the logger backing the returned `Handler`. (#5588)
 - Upgrade all dependencies of `go.opentelemetry.io/otel/semconv/v1.24.0` to `go.opentelemetry.io/otel/semconv/v1.25.0`. (#5605)
 
-- Update the span processor in `go.opentelemetry.io/contrib/processors/baggage/baggagetrace` to require a baggage key predicate. (#5619)
-
 ### Removed
 
 - The `WithInstrumentationScope` option function in `go.opentelemetry.io/contrib/bridges/otelslog` is removed.
diff --git a/processors/baggage/baggagetrace/doc.go b/processors/baggage/baggagetrace/doc.go
index c18ff060b..96b8d8cc4 100644
--- a/processors/baggage/baggagetrace/doc.go
+++ b/processors/baggage/baggagetrace/doc.go
@@ -1,27 +1,7 @@
 // Copyright The OpenTelemetry Authors
 // SPDX-License-Identifier: Apache-2.0
 
-// Package baggagetrace is an OpenTelemetry [Span Processor] that reads key/values
-// stored in [Baggage] in the starting span's parent context and adds them as
-// attributes to the span.
+// Package baggagetrace implements a baggage span processor.
 //
-// Keys and values added to Baggage will appear on all subsequent child spans for
-// a trace within this service and will be propagated to external services via
-// propagation headers.
-// If the external services also have a Baggage span processor, the keys and
-// values will appear in those child spans as well.
-//
-// Do not put sensitive information in Baggage.
-//
-// # Usage
-//
-// Add the span processor when configuring the tracer provider.
-//
-// The convenience function [AllowAllBaggageKeys] is provided to
-// allow all baggage keys to be copied to the span. Alternatively, you can
-// provide a custom baggage key predicate to select which baggage keys you want
-// to copy.
-//
-// [Span Processor]: https://opentelemetry.io/docs/specs/otel/trace/sdk/#span-processor
-// [Baggage]: https://opentelemetry.io/docs/specs/otel/api/baggage
+// Deprecated: Use go.opentelemetry.io/contrib/processors/baggagecopy instead.
 package baggagetrace // import "go.opentelemetry.io/contrib/processors/baggage/baggagetrace"
diff --git a/processors/baggage/baggagetrace/go.mod b/processors/baggage/baggagetrace/go.mod
index 5b660a220..32a9f6958 100644
--- a/processors/baggage/baggagetrace/go.mod
+++ b/processors/baggage/baggagetrace/go.mod
@@ -1,9 +1,11 @@
+// Deprecated: Use go.opentelemetry.io/contrib/processors/baggagecopy instead.
 module go.opentelemetry.io/contrib/processors/baggage/baggagetrace
 
 go 1.21
 
 require (
 	github.com/stretchr/testify v1.9.0
+	go.opentelemetry.io/contrib/processors/baggagecopy v0.0.0-00010101000000-000000000000
 	go.opentelemetry.io/otel v1.27.0
 	go.opentelemetry.io/otel/sdk v1.27.0
 )
@@ -18,3 +20,5 @@ require (
 	golang.org/x/sys v0.21.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 )
+
+replace go.opentelemetry.io/contrib/processors/baggagecopy => ../../baggagecopy
diff --git a/processors/baggage/baggagetrace/processor.go b/processors/baggage/baggagetrace/processor.go
index 77dc5c4da..8eabac0c7 100644
--- a/processors/baggage/baggagetrace/processor.go
+++ b/processors/baggage/baggagetrace/processor.go
@@ -7,48 +7,29 @@ import (
 	"context"
 
 	"go.opentelemetry.io/otel/attribute"
-	"go.opentelemetry.io/otel/baggage"
+	otelbaggage "go.opentelemetry.io/otel/baggage"
 	"go.opentelemetry.io/otel/sdk/trace"
-)
-
-// Filter returns true if the baggage member should be added to a span.
-type Filter func(member baggage.Member) bool
 
-// AllowAllMembers allows all baggage members to be added to a span.
-var AllowAllMembers Filter = func(baggage.Member) bool { return true }
+	"go.opentelemetry.io/contrib/processors/baggagecopy"
+)
 
-// SpanProcessor is a [trace.SpanProcessor] implementation that adds baggage
-// members onto a span as attributes.
-type SpanProcessor struct {
-	filter Filter
-}
+// SpanProcessor is a processing pipeline for spans in the trace signal.
+type SpanProcessor struct{}
 
 var _ trace.SpanProcessor = (*SpanProcessor)(nil)
 
-// New returns a new [SpanProcessor].
+// New returns a new SpanProcessor.
 //
 // The Baggage span processor duplicates onto a span the attributes found
 // in Baggage in the parent context at the moment the span is started.
-// The passed filter determines which baggage members are added to the span.
-//
-// If filter is nil, all baggage members will be added.
-func New(filter Filter) *SpanProcessor {
-	return &SpanProcessor{
-		filter: filter,
-	}
+func New() trace.SpanProcessor {
+	return baggagecopy.NewSpanProcessor(baggagecopy.AllowAllMembers)
 }
 
 // OnStart is called when a span is started and adds span attributes for baggage contents.
 func (processor SpanProcessor) OnStart(ctx context.Context, span trace.ReadWriteSpan) {
-	filter := processor.filter
-	if filter == nil {
-		filter = AllowAllMembers
-	}
-
-	for _, member := range baggage.FromContext(ctx).Members() {
-		if filter(member) {
-			span.SetAttributes(attribute.String(member.Key(), member.Value()))
-		}
+	for _, entry := range otelbaggage.FromContext(ctx).Members() {
+		span.SetAttributes(attribute.String(entry.Key(), entry.Value()))
 	}
 }
 
diff --git a/processors/baggagecopy/doc.go b/processors/baggagecopy/doc.go
new file mode 100644
index 000000000..854879441
--- /dev/null
+++ b/processors/baggagecopy/doc.go
@@ -0,0 +1,27 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+// Package baggagecopy is an OpenTelemetry [Span Processor] that reads key/values
+// stored in [Baggage] in the starting span's parent context and adds them as
+// attributes to the span.
+//
+// Keys and values added to Baggage will appear on all subsequent child spans for
+// a trace within this service and will be propagated to external services via
+// propagation headers.
+// If the external services also have a Baggage span processor, the keys and
+// values will appear in those child spans as well.
+//
+// Do not put sensitive information in Baggage.
+//
+// # Usage
+//
+// Add the span processor when configuring the tracer provider.
+//
+// The convenience function [AllowAllBaggageKeys] is provided to
+// allow all baggage keys to be copied to the span. Alternatively, you can
+// provide a custom baggage key predicate to select which baggage keys you want
+// to copy.
+//
+// [Span Processor]: https://opentelemetry.io/docs/specs/otel/trace/sdk/#span-processor
+// [Baggage]: https://opentelemetry.io/docs/specs/otel/api/baggage
+package baggagecopy // import "go.opentelemetry.io/contrib/processors/baggagecopy"
diff --git a/processors/baggagecopy/go.mod b/processors/baggagecopy/go.mod
new file mode 100644
index 000000000..a592a67f4
--- /dev/null
+++ b/processors/baggagecopy/go.mod
@@ -0,0 +1,20 @@
+module go.opentelemetry.io/contrib/processors/baggagecopy
+
+go 1.21
+
+require (
+	github.com/stretchr/testify v1.9.0
+	go.opentelemetry.io/otel v1.27.0
+	go.opentelemetry.io/otel/sdk v1.27.0
+)
+
+require (
+	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/go-logr/logr v1.4.2 // indirect
+	github.com/go-logr/stdr v1.2.2 // indirect
+	github.com/pmezard/go-difflib v1.0.0 // indirect
+	go.opentelemetry.io/otel/metric v1.27.0 // indirect
+	go.opentelemetry.io/otel/trace v1.27.0 // indirect
+	golang.org/x/sys v0.21.0 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
+)
diff --git a/processors/baggagecopy/go.sum b/processors/baggagecopy/go.sum
new file mode 100644
index 000000000..2f8d594db
--- /dev/null
+++ b/processors/baggagecopy/go.sum
@@ -0,0 +1,27 @@
+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/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
+github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+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/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg=
+go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ=
+go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik=
+go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak=
+go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kTWmI=
+go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A=
+go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw=
+go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4=
+golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
+golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/processors/baggagecopy/processor.go b/processors/baggagecopy/processor.go
new file mode 100644
index 000000000..040483cad
--- /dev/null
+++ b/processors/baggagecopy/processor.go
@@ -0,0 +1,63 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package baggagecopy // import "go.opentelemetry.io/contrib/processors/baggagecopy"
+
+import (
+	"context"
+
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/baggage"
+	"go.opentelemetry.io/otel/sdk/trace"
+)
+
+// Filter returns true if the baggage member should be added to a span.
+type Filter func(member baggage.Member) bool
+
+// AllowAllMembers allows all baggage members to be added to a span.
+var AllowAllMembers Filter = func(baggage.Member) bool { return true }
+
+// SpanProcessor is a [trace.SpanProcessor] implementation that adds baggage
+// members onto a span as attributes.
+type SpanProcessor struct {
+	filter Filter
+}
+
+var _ trace.SpanProcessor = (*SpanProcessor)(nil)
+
+// NewSpanProcessor returns a new [SpanProcessor].
+//
+// The Baggage span processor duplicates onto a span the attributes found
+// in Baggage in the parent context at the moment the span is started.
+// The passed filter determines which baggage members are added to the span.
+//
+// If filter is nil, all baggage members will be added.
+func NewSpanProcessor(filter Filter) *SpanProcessor {
+	return &SpanProcessor{
+		filter: filter,
+	}
+}
+
+// OnStart is called when a span is started and adds span attributes for baggage contents.
+func (processor SpanProcessor) OnStart(ctx context.Context, span trace.ReadWriteSpan) {
+	filter := processor.filter
+	if filter == nil {
+		filter = AllowAllMembers
+	}
+
+	for _, member := range baggage.FromContext(ctx).Members() {
+		if filter(member) {
+			span.SetAttributes(attribute.String(member.Key(), member.Value()))
+		}
+	}
+}
+
+// OnEnd is called when span is finished and is a no-op for this processor.
+func (processor SpanProcessor) OnEnd(s trace.ReadOnlySpan) {}
+
+// Shutdown is called when the SDK shuts down and is a no-op for this processor.
+func (processor SpanProcessor) Shutdown(context.Context) error { return nil }
+
+// ForceFlush exports all ended spans to the configured Exporter that have not yet
+// been exported and is a no-op for this processor.
+func (processor SpanProcessor) ForceFlush(context.Context) error { return nil }
diff --git a/versions.yaml b/versions.yaml
index 26e0311c7..b5a77a1e8 100644
--- a/versions.yaml
+++ b/versions.yaml
@@ -82,6 +82,7 @@ module-sets:
     version: v0.0.1
     modules:
       - go.opentelemetry.io/contrib/processors/baggage/baggagetrace
+      - go.opentelemetry.io/contrib/processors/baggagecopy
   experimental-detectors:
     version: v0.0.1
     modules:


Test patch:
diff --git a/processors/baggage/baggagetrace/processor_test.go b/processors/baggage/baggagetrace/processor_test.go
index bd680c038..3b50bcf3e 100644
--- a/processors/baggage/baggagetrace/processor_test.go
+++ b/processors/baggage/baggagetrace/processor_test.go
@@ -5,17 +5,14 @@ package baggagetrace
 
 import (
 	"context"
-	"regexp"
-	"strings"
 	"testing"
 
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 
 	"go.opentelemetry.io/otel/attribute"
-	"go.opentelemetry.io/otel/baggage"
+	otelbaggage "go.opentelemetry.io/otel/baggage"
 	"go.opentelemetry.io/otel/sdk/trace"
-	"go.opentelemetry.io/otel/sdk/trace/tracetest"
 )
 
 var _ trace.SpanExporter = &testExporter{}
@@ -36,72 +33,19 @@ func NewTestExporter() *testExporter {
 	return &testExporter{}
 }
 
-func TestSpanProcessorAppendsAllBaggageAttributes(t *testing.T) {
-	b, _ := baggage.New()
-	b = addEntryToBaggage(t, b, "baggage.test", "baggage value")
-	ctx := baggage.ContextWithBaggage(context.Background(), b)
-
-	// create trace provider with baggage processor and test exporter
-	exporter := NewTestExporter()
-	tp := trace.NewTracerProvider(
-		trace.WithSpanProcessor(New(AllowAllMembers)),
-		trace.WithSpanProcessor(trace.NewSimpleSpanProcessor(exporter)),
-	)
-
-	// create tracer and start/end span
-	tracer := tp.Tracer("test")
-	_, span := tracer.Start(ctx, "test")
-	span.End()
-
-	require.Len(t, exporter.spans, 1)
-	require.Len(t, exporter.spans[0].Attributes(), 1)
-
-	want := []attribute.KeyValue{attribute.String("baggage.test", "baggage value")}
-	require.Equal(t, want, exporter.spans[0].Attributes())
-}
-
-func TestSpanProcessorAppendsBaggageAttributesWithHaPrefixPredicate(t *testing.T) {
-	b, _ := baggage.New()
-	b = addEntryToBaggage(t, b, "baggage.test", "baggage value")
-	ctx := baggage.ContextWithBaggage(context.Background(), b)
-
-	baggageKeyPredicate := func(m baggage.Member) bool {
-		return strings.HasPrefix(m.Key(), "baggage.")
-	}
-
-	// create trace provider with baggage processor and test exporter
-	exporter := NewTestExporter()
-	tp := trace.NewTracerProvider(
-		trace.WithSpanProcessor(New(baggageKeyPredicate)),
-		trace.WithSpanProcessor(trace.NewSimpleSpanProcessor(exporter)),
-	)
-
-	// create tracer and start/end span
-	tracer := tp.Tracer("test")
-	_, span := tracer.Start(ctx, "test")
-	span.End()
-
-	require.Len(t, exporter.spans, 1)
-	require.Len(t, exporter.spans[0].Attributes(), 1)
-
-	want := []attribute.KeyValue{attribute.String("baggage.test", "baggage value")}
-	require.Equal(t, want, exporter.spans[0].Attributes())
-}
-
-func TestSpanProcessorAppendsBaggageAttributesWithRegexPredicate(t *testing.T) {
-	b, _ := baggage.New()
-	b = addEntryToBaggage(t, b, "baggage.test", "baggage value")
-	ctx := baggage.ContextWithBaggage(context.Background(), b)
-
-	expr := regexp.MustCompile(`^baggage\..*`)
-	baggageKeyPredicate := func(m baggage.Member) bool {
-		return expr.MatchString(m.Key())
-	}
+func TestSpanProcessorAppendsBaggageAttributes(t *testing.T) {
+	suitcase, err := otelbaggage.New()
+	require.NoError(t, err)
+	packingCube, err := otelbaggage.NewMemberRaw("baggage.test", "baggage value")
+	require.NoError(t, err)
+	suitcase, err = suitcase.SetMember(packingCube)
+	require.NoError(t, err)
+	ctx := otelbaggage.ContextWithBaggage(context.Background(), suitcase)
 
 	// create trace provider with baggage processor and test exporter
 	exporter := NewTestExporter()
 	tp := trace.NewTracerProvider(
-		trace.WithSpanProcessor(New(baggageKeyPredicate)),
+		trace.WithSpanProcessor(New()),
 		trace.WithSpanProcessor(trace.NewSimpleSpanProcessor(exporter)),
 	)
 
@@ -110,71 +54,9 @@ func TestSpanProcessorAppendsBaggageAttributesWithRegexPredicate(t *testing.T) {
 	_, span := tracer.Start(ctx, "test")
 	span.End()
 
-	require.Len(t, exporter.spans, 1)
-	require.Len(t, exporter.spans[0].Attributes(), 1)
+	assert.Len(t, exporter.spans, 1)
+	assert.Len(t, exporter.spans[0].Attributes(), 1)
 
 	want := []attribute.KeyValue{attribute.String("baggage.test", "baggage value")}
-	require.Equal(t, want, exporter.spans[0].Attributes())
+	assert.Equal(t, want, exporter.spans[0].Attributes())
 }
-
-func TestOnlyAddsBaggageEntriesThatMatchPredicate(t *testing.T) {
-	b, _ := baggage.New()
-	b = addEntryToBaggage(t, b, "baggage.test", "baggage value")
-	b = addEntryToBaggage(t, b, "foo", "bar")
-	ctx := baggage.ContextWithBaggage(context.Background(), b)
-
-	baggageKeyPredicate := func(m baggage.Member) bool {
-		return m.Key() == "baggage.test"
-	}
-
-	// create trace provider with baggage processor and test exporter
-	exporter := NewTestExporter()
-	tp := trace.NewTracerProvider(
-		trace.WithSpanProcessor(New(baggageKeyPredicate)),
-		trace.WithSpanProcessor(trace.NewSimpleSpanProcessor(exporter)),
-	)
-
-	// create tracer and start/end span
-	tracer := tp.Tracer("test")
-	_, span := tracer.Start(ctx, "test")
-	span.End()
-
-	require.Len(t, exporter.spans, 1)
-	require.Len(t, exporter.spans[0].Attributes(), 1)
-
-	want := attribute.String("baggage.test", "baggage value")
-	require.Equal(t, want, exporter.spans[0].Attributes()[0])
-}
-
-func addEntryToBaggage(t *testing.T, b baggage.Baggage, key, value string) baggage.Baggage {
-	member, err := baggage.NewMemberRaw(key, value)
-	require.NoError(t, err)
-	b, err = b.SetMember(member)
-	require.NoError(t, err)
-	return b
-}
-
-func TestZeroSpanProcessorNoPanic(t *testing.T) {
-	sp := new(SpanProcessor)
-
-	m, err := baggage.NewMember("key", "val")
-	require.NoError(t, err)
-	b, err := baggage.New(m)
-	require.NoError(t, err)
-
-	ctx := baggage.ContextWithBaggage(context.Background(), b)
-	roS := (tracetest.SpanStub{}).Snapshot()
-	rwS := rwSpan{}
-	assert.NotPanics(t, func() {
-		sp.OnStart(ctx, rwS)
-		sp.OnEnd(roS)
-		_ = sp.ForceFlush(ctx)
-		_ = sp.Shutdown(ctx)
-	})
-}
-
-type rwSpan struct {
-	trace.ReadWriteSpan
-}
-
-func (s rwSpan) SetAttributes(kv ...attribute.KeyValue) {}
diff --git a/processors/baggage/baggagetrace/example_test.go b/processors/baggagecopy/example_test.go
similarity index 74%
rename from processors/baggage/baggagetrace/example_test.go
rename to processors/baggagecopy/example_test.go
index a86418416..a05d71f5b 100644
--- a/processors/baggage/baggagetrace/example_test.go
+++ b/processors/baggagecopy/example_test.go
@@ -1,27 +1,27 @@
 // Copyright The OpenTelemetry Authors
 // SPDX-License-Identifier: Apache-2.0
 
-package baggagetrace_test
+package baggagecopy_test
 
 import (
 	"regexp"
 	"strings"
 
-	"go.opentelemetry.io/contrib/processors/baggage/baggagetrace"
+	"go.opentelemetry.io/contrib/processors/baggagecopy"
 	"go.opentelemetry.io/otel/baggage"
 	"go.opentelemetry.io/otel/sdk/trace"
 )
 
 func ExampleNew_allKeys() {
 	trace.NewTracerProvider(
-		trace.WithSpanProcessor(baggagetrace.New(baggagetrace.AllowAllMembers)),
+		trace.WithSpanProcessor(baggagecopy.NewSpanProcessor(baggagecopy.AllowAllMembers)),
 	)
 }
 
 func ExampleNew_keysWithPrefix() {
 	trace.NewTracerProvider(
 		trace.WithSpanProcessor(
-			baggagetrace.New(
+			baggagecopy.NewSpanProcessor(
 				func(m baggage.Member) bool {
 					return strings.HasPrefix(m.Key(), "my-key")
 				},
@@ -34,7 +34,7 @@ func ExampleNew_keysMatchingRegex() {
 	expr := regexp.MustCompile(`^key.+`)
 	trace.NewTracerProvider(
 		trace.WithSpanProcessor(
-			baggagetrace.New(
+			baggagecopy.NewSpanProcessor(
 				func(m baggage.Member) bool {
 					return expr.MatchString(m.Key())
 				},
diff --git a/processors/baggagecopy/processor_test.go b/processors/baggagecopy/processor_test.go
new file mode 100644
index 000000000..b6656ca4c
--- /dev/null
+++ b/processors/baggagecopy/processor_test.go
@@ -0,0 +1,180 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package baggagecopy
+
+import (
+	"context"
+	"regexp"
+	"strings"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/baggage"
+	"go.opentelemetry.io/otel/sdk/trace"
+	"go.opentelemetry.io/otel/sdk/trace/tracetest"
+)
+
+var _ trace.SpanExporter = &testExporter{}
+
+type testExporter struct {
+	spans []trace.ReadOnlySpan
+}
+
+func (e *testExporter) Start(ctx context.Context) error    { return nil }
+func (e *testExporter) Shutdown(ctx context.Context) error { return nil }
+
+func (e *testExporter) ExportSpans(ctx context.Context, ss []trace.ReadOnlySpan) error {
+	e.spans = append(e.spans, ss...)
+	return nil
+}
+
+func NewTestExporter() *testExporter {
+	return &testExporter{}
+}
+
+func TestSpanProcessorAppendsAllBaggageAttributes(t *testing.T) {
+	b, _ := baggage.New()
+	b = addEntryToBaggage(t, b, "baggage.test", "baggage value")
+	ctx := baggage.ContextWithBaggage(context.Background(), b)
+
+	// create trace provider with baggage processor and test exporter
+	exporter := NewTestExporter()
+	tp := trace.NewTracerProvider(
+		trace.WithSpanProcessor(NewSpanProcessor(AllowAllMembers)),
+		trace.WithSpanProcessor(trace.NewSimpleSpanProcessor(exporter)),
+	)
+
+	// create tracer and start/end span
+	tracer := tp.Tracer("test")
+	_, span := tracer.Start(ctx, "test")
+	span.End()
+
+	require.Len(t, exporter.spans, 1)
+	require.Len(t, exporter.spans[0].Attributes(), 1)
+
+	want := []attribute.KeyValue{attribute.String("baggage.test", "baggage value")}
+	require.Equal(t, want, exporter.spans[0].Attributes())
+}
+
+func TestSpanProcessorAppendsBaggageAttributesWithHaPrefixPredicate(t *testing.T) {
+	b, _ := baggage.New()
+	b = addEntryToBaggage(t, b, "baggage.test", "baggage value")
+	ctx := baggage.ContextWithBaggage(context.Background(), b)
+
+	baggageKeyPredicate := func(m baggage.Member) bool {
+		return strings.HasPrefix(m.Key(), "baggage.")
+	}
+
+	// create trace provider with baggage processor and test exporter
+	exporter := NewTestExporter()
+	tp := trace.NewTracerProvider(
+		trace.WithSpanProcessor(NewSpanProcessor(baggageKeyPredicate)),
+		trace.WithSpanProcessor(trace.NewSimpleSpanProcessor(exporter)),
+	)
+
+	// create tracer and start/end span
+	tracer := tp.Tracer("test")
+	_, span := tracer.Start(ctx, "test")
+	span.End()
+
+	require.Len(t, exporter.spans, 1)
+	require.Len(t, exporter.spans[0].Attributes(), 1)
+
+	want := []attribute.KeyValue{attribute.String("baggage.test", "baggage value")}
+	require.Equal(t, want, exporter.spans[0].Attributes())
+}
+
+func TestSpanProcessorAppendsBaggageAttributesWithRegexPredicate(t *testing.T) {
+	b, _ := baggage.New()
+	b = addEntryToBaggage(t, b, "baggage.test", "baggage value")
+	ctx := baggage.ContextWithBaggage(context.Background(), b)
+
+	expr := regexp.MustCompile(`^baggage\..*`)
+	baggageKeyPredicate := func(m baggage.Member) bool {
+		return expr.MatchString(m.Key())
+	}
+
+	// create trace provider with baggage processor and test exporter
+	exporter := NewTestExporter()
+	tp := trace.NewTracerProvider(
+		trace.WithSpanProcessor(NewSpanProcessor(baggageKeyPredicate)),
+		trace.WithSpanProcessor(trace.NewSimpleSpanProcessor(exporter)),
+	)
+
+	// create tracer and start/end span
+	tracer := tp.Tracer("test")
+	_, span := tracer.Start(ctx, "test")
+	span.End()
+
+	require.Len(t, exporter.spans, 1)
+	require.Len(t, exporter.spans[0].Attributes(), 1)
+
+	want := []attribute.KeyValue{attribute.String("baggage.test", "baggage value")}
+	require.Equal(t, want, exporter.spans[0].Attributes())
+}
+
+func TestOnlyAddsBaggageEntriesThatMatchPredicate(t *testing.T) {
+	b, _ := baggage.New()
+	b = addEntryToBaggage(t, b, "baggage.test", "baggage value")
+	b = addEntryToBaggage(t, b, "foo", "bar")
+	ctx := baggage.ContextWithBaggage(context.Background(), b)
+
+	baggageKeyPredicate := func(m baggage.Member) bool {
+		return m.Key() == "baggage.test"
+	}
+
+	// create trace provider with baggage processor and test exporter
+	exporter := NewTestExporter()
+	tp := trace.NewTracerProvider(
+		trace.WithSpanProcessor(NewSpanProcessor(baggageKeyPredicate)),
+		trace.WithSpanProcessor(trace.NewSimpleSpanProcessor(exporter)),
+	)
+
+	// create tracer and start/end span
+	tracer := tp.Tracer("test")
+	_, span := tracer.Start(ctx, "test")
+	span.End()
+
+	require.Len(t, exporter.spans, 1)
+	require.Len(t, exporter.spans[0].Attributes(), 1)
+
+	want := attribute.String("baggage.test", "baggage value")
+	require.Equal(t, want, exporter.spans[0].Attributes()[0])
+}
+
+func addEntryToBaggage(t *testing.T, b baggage.Baggage, key, value string) baggage.Baggage {
+	member, err := baggage.NewMemberRaw(key, value)
+	require.NoError(t, err)
+	b, err = b.SetMember(member)
+	require.NoError(t, err)
+	return b
+}
+
+func TestZeroSpanProcessorNoPanic(t *testing.T) {
+	sp := new(SpanProcessor)
+
+	m, err := baggage.NewMember("key", "val")
+	require.NoError(t, err)
+	b, err := baggage.New(m)
+	require.NoError(t, err)
+
+	ctx := baggage.ContextWithBaggage(context.Background(), b)
+	roS := (tracetest.SpanStub{}).Snapshot()
+	rwS := rwSpan{}
+	assert.NotPanics(t, func() {
+		sp.OnStart(ctx, rwS)
+		sp.OnEnd(roS)
+		_ = sp.ForceFlush(ctx)
+		_ = sp.Shutdown(ctx)
+	})
+}
+
+type rwSpan struct {
+	trace.ReadWriteSpan
+}
+
+func (s rwSpan) SetAttributes(kv ...attribute.KeyValue) {}