### Getting Started with the Bridge Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/bridge/opentracing/README.md This snippet shows how to install and set up the OpenTelemetry/OpenTracing bridge, configuring an OpenTelemetry TracerProvider and creating a bridge tracer. ```APIDOC ## Getting started with the OpenTelemetry/OpenTracing Bridge ### Description This section guides you through installing and initializing the OpenTelemetry/OpenTracing bridge. It assumes you have an OpenTelemetry `TracerProvider` configured. ### Installation ```bash go get go.opentelemetry.io/otel/bridge/opentracing ``` ### Setup ```go import ( "go.opentelemetry.io/otel" otelBridge "go.opentelemetry.io/otel/bridge/opentracing" ) func main() { // Assume tracerProvider is already configured for OpenTelemetry // var tracerProvider trace.TracerProvider // Get an OpenTelemetry tracer otelTracer := tracerProvider.Tracer("tracer_name") // Create a bridge tracer and a wrapper TracerProvider bridgeTracer, wrapperTracerProvider := otelBridge.NewTracerPair(otelTracer) // Set the wrapperTracerProvider as the global OpenTelemetry TracerProvider // This ensures that other instrumentations will use the bridge by default. otel.SetTracerProvider(wrapperTracerProvider) // Now you can use bridgeTracer as your OpenTracing tracer. } ``` ``` -------------------------------- ### Install and Run Local Go Doc Site Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md Installs and runs a local Go documentation site. Ensure you have Go installed and configured. ```sh go install golang.org/x/pkgsite/cmd/pkgsite@latest pkgsite ``` -------------------------------- ### Get opentelemetry-go Project Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md Use 'go get' to download the opentelemetry-go project source code. This command may produce warnings about build constraints, which can be ignored. ```sh go get -d go.opentelemetry.io/otel ``` -------------------------------- ### Explicit SDK Component Initialization in Go Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md Use this pattern to encapsulate instrumentation setup within a constructor function. This ensures clear ownership and scope, avoiding implicit side effects. It requires importing necessary OpenTelemetry packages. ```go import ( "errors" semconv "go.opentelemetry.io/otel/semconv/v1.42.0" "go.opentelemetry.io/otel/semconv/v1.42.0/otelconv" ) type SDKComponent struct { inst *instrumentation } func NewSDKComponent(config Config) (*SDKComponent, error) { inst, err := newInstrumentation() if err != nil { return nil, err } return &SDKComponent{inst: inst}, nil } type instrumentation struct { inflight otelconv.SDKComponentInflight exported otelconv.SDKComponentExported } func newInstrumentation() (*instrumentation, error) { if !x.Observability.Enabled() { return nil, nil } meter := otel.GetMeterProvider().Meter( "", metric.WithInstrumentationVersion(sdk.Version()), metric.WithSchemaURL(semconv.SchemaURL), ) inst := &instrumentation{} var err, e error inst.inflight, e = otelconv.NewSDKComponentInflight(meter) err = errors.Join(err, e) inst.exported, e = otelconv.NewSDKComponentExported(meter) err = errors.Join(err, e) return inst, err } ``` -------------------------------- ### Deterministic Testing Setup in Go Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md Isolate state for deterministic testing by restoring global variables after tests. Use t.Setenv for environment variables and reset counters. ```go func TestObservability(t *testing.T) { // Restore state after test to ensure this does not affect other tests. prev := otel.GetMeterProvider() t.Cleanup(func() { otel.SetMeterProvider(prev) }) // Isolate the meter provider for deterministic testing reader := metric.NewManualReader() meterProvider := metric.NewMeterProvider(metric.WithReader(reader)) otel.SetMeterProvider(meterProvider) // Use t.Setenv to ensure environment variable is restored after test. t.Setenv("OTEL_GO_X_OBSERVABILITY", "true") // Reset component ID counter to ensure deterministic component names. componentIDCounter.Store(0) /* ... test code ... */ } ``` -------------------------------- ### Experimental Option Function Example Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md Demonstrates how to implement an experimental option function for API or SDK use. The option embeds a stable type and includes an Experimental() method to prevent panics. The SDK can use type assertions to access experimental functionality. ```go type myOption struct { // Embed the stable option type. metric.InstrumentOption value string } // Experimental prevents the API from panicking when the option is used. func (o myOption) Experimental() {} // The SDK can use type assertions to use this function. func (o myOption) Value() string { return o.value } func WithMyOption(value string) metric.InstrumentOption { return myOption{value: value} } ``` -------------------------------- ### Initialize OpenTracing Bridge Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/bridge/opentracing/README.md Configures the OpenTelemetry bridge to allow OpenTracing tracers to interoperate with an OpenTelemetry TracerProvider. This setup ensures that instrumentation using the global tracer provider utilizes the bridge. ```go import ( "go.opentelemetry.io/otel" otelBridge "go.opentelemetry.io/otel/bridge/opentracing" ) func main() { otelTracer := tracerProvider.Tracer("tracer_name") bridgeTracer, wrapperTracerProvider := otelBridge.NewTracerPair(otelTracer) otel.SetTracerProvider(wrapperTracerProvider) } ``` -------------------------------- ### Instantiation with Options Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md Illustrates how to instantiate a type using a variadic slice of Option arguments, allowing for flexible configuration during creation. ```go func NewT(options ...Option) T {…} ``` -------------------------------- ### Handle Overlapping Configurations with Interfaces Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md Demonstrates a strategy for managing overlapping configurations between different types (e.g., Dog and Bird) by using common and type-specific Option interfaces. ```go // config holds options for all animals. type config struct { Weight float64 Color string MaxAltitude float64 } // DogOption apply Dog specific options. type DogOption interface { applyDog(config) config } // BirdOption apply Bird specific options. type BirdOption interface { applyBird(config) config } // Option apply options for all animals. type Option interface { BirdOption DogOption } type weightOption float64 func (o weightOption) applyDog(c config) config { c.Weight = float64(o) return c } func (o weightOption) applyBird(c config) config { c.Weight = float64(o) return c } func WithWeight(w float64) Option { return weightOption(w) } type furColorOption string func (o furColorOption) applyDog(c config) config { c.Color = string(o) return c } func WithFurColor(c string) DogOption { return furColorOption(c) } type maxAltitudeOption float64 func (o maxAltitudeOption) applyBird(c config) config { c.MaxAltitude = float64(o) return c } func WithMaxAltitude(a float64) BirdOption { return maxAltitudeOption(a) } func NewDog(name string, o ...DogOption) Dog {…} func NewBird(name string, o ...BirdOption) Bird {…} ``` -------------------------------- ### Record Severity Accessors Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/log/DESIGN.md Provides methods to get and set the SeverityNumber field of a LogRecord. ```go func (r *Record) Severity() Severity func (r *Record) SetSeverity(s Severity) ``` -------------------------------- ### Record ObservedTimestamp Accessors Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/log/DESIGN.md Provides methods to get and set the ObservedTimestamp field of a LogRecord. ```go func (r *Record) ObservedTimestamp() time.Time func (r *Record) SetObservedTimestamp(t time.Time) ``` -------------------------------- ### Create New Configuration Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md Creates a configured struct by applying a variable number of options. This function sets default values, applies options, and performs validation. ```go // newConfig returns an appropriately configured config. func newConfig(options ...Option) config { // Set default values for config. config := config{/* […] */} for _, option := range options { config = option.apply(config) } // Perform any validation here. return config } ``` -------------------------------- ### Record EventName Accessors Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/log/DESIGN.md Provides methods to get and set the EventName field of a LogRecord. ```go func (r *Record) EventName() string func (r *Record) SetEventName(s string) ``` -------------------------------- ### Implement Functional Option Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md Demonstrates the functional options pattern where an option is implemented as a function. This is flexible for complex configurations. ```go type optionFunc func(config) config func (fn optionFunc) apply(c config) config { return fn(c) } // WithMyType sets t as MyType. func WithMyType(t MyType) Option { return optionFunc(func(c config) config { c.MyType = t return c }) } ``` -------------------------------- ### Record Timestamp Accessors Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/log/DESIGN.md Provides methods to get and set the Timestamp field of a LogRecord. ```go func (r *Record) Timestamp() time.Time func (r *Record) SetTimestamp(t time.Time) ``` -------------------------------- ### Get Number of Attributes in Record Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/log/DESIGN.md This method returns the count of attributes associated with a log record, useful for preallocating slices when converting records. ```go func (r *Record) AttributesLen() int ``` -------------------------------- ### Get GPG Key ID Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/RELEASING.md Command to list secret GPG keys and their IDs. The key ID is required for signing release artifacts. ```terminal gpg --list-secret-keys --keyid-format=long ``` -------------------------------- ### Enable Self-Observability Metrics Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/x/README.md Enable the experimental self-observability metrics feature by setting the OTEL_GO_X_OBSERVABILITY environment variable to 'true'. ```console export OTEL_GO_X_OBSERVABILITY=true ``` -------------------------------- ### Access Body in Record Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/log/DESIGN.md Use these methods to get or set the Body field of a log record. The body represents the main content of the log message. ```go func (r *Record) Body() attribute.Value func (r *Record) SetBody(v attribute.Value) ``` -------------------------------- ### Develop and Push Changes Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md Create a new branch, make your code modifications, update the changelog, run pre-commit checks, stage changes, commit, and push to your fork. ```sh git checkout -b # edit files # update changelog make precommit git add -p git commit git push ``` -------------------------------- ### Access SeverityText in Record Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/log/DESIGN.md Use these methods to get or set the SeverityText field of a log record. This field provides a human-readable representation of the log's severity. ```go func (r *Record) SeverityText() string func (r *Record) SetSeverityText(s string) ``` -------------------------------- ### Parse OpenTelemetry Schema File in Go Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/schema/README.md Demonstrates how to load an OpenTelemetry schema from a file using the schema package. It shows error handling and how to use the parsed schema object. This requires importing the specific versioned schema package. ```go import schema "go.opentelemetry.io/otel/schema/v1.1" // Load the schema from a file in v1.1.x file format. func loadSchemaFromFile() error { telSchema, err := schema.ParseFile("schema-file.yaml") if err != nil { return err } // Use telSchema struct here. return nil } ``` ```go import ( s ``` -------------------------------- ### Implement Declared Type Option Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md Shows how to implement an option for a specific declared type. This is useful for options that take a value of a particular type. ```go type myTypeOption struct { MyType MyType } func (o myTypeOption) apply(c config) config { c.MyType = o.MyType return c } // WithMyType sets T to have include MyType. func WithMyType(t MyType) Option { return myTypeOption{t} } ``` -------------------------------- ### Propagate OpenTracing Context to OpenTelemetry Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/bridge/opentracing/README.md Demonstrates how to wrap an existing OpenTracing span into a context that is recognized by both OpenTracing and OpenTelemetry instrumentation. This is necessary for proper trace propagation. ```go ctxWithOTSpan := opentracing.ContextWithSpan(ctx, otSpan) ctxWithOTAndOTelSpan := bridgeTracer.ContextWithSpanHook(ctxWithOTSpan, otSpan) ``` -------------------------------- ### Enable Metric Export Batching Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/sdk/metric/internal/x/README.md Set the OTEL_GO_X_METRIC_EXPORT_BATCH_SIZE environment variable to a positive integer to enable batching of metrics before export. This controls the maximum number of data points per batch. ```console export OTEL_GO_X_METRIC_EXPORT_BATCH_SIZE=200 ``` -------------------------------- ### Component Type Identification in Go Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md Use the fully qualified package path as the component type for stable identification when a component is not a well-known type. ```go componentType := "go.opentelemetry.io/otel/sdk/trace.Span" ``` -------------------------------- ### Proper Error Handling in Go Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md Return errors to the caller when initialization fails. Use partially initialized objects if they are still usable. ```go func newInstrumentation() (*instrumentation, error) { if !x.Observability.Enabled() { return nil, nil } m := otel.GetMeterProvider().Meter(/* initialize meter */) counter, err := otelconv.NewSDKComponentCounter(m) // Use the partially initialized counter if available. i := &instrumentation{counter: counter} // Return any error to the caller. return i, err } ``` -------------------------------- ### Create Pre-Release Branch with Make Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/RELEASING.md This command uses the 'prerelease' make target to create a new branch for release changes. It requires specifying the module set to be released. ```bash make prerelease MODSET= ``` -------------------------------- ### Implement Boolean Option (False Default) Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md Provides an implementation for a boolean option that defaults to false. Use this when the option should be off by default and enabled via a `With*` function. ```go type defaultFalseOption bool func (o defaultFalseOption) apply(c config) config { c.Bool = bool(o) return c } // WithOption sets a T to have an option included. func WithOption() Option { return defaultFalseOption(true) } ``` -------------------------------- ### Verify Pre-Release Changes Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/RELEASING.md Compares the current branch with the newly created pre-release branch to verify that all module versions have been updated correctly to the new tag. ```bash git diff ...prerelease__ ``` -------------------------------- ### Clone opentelemetry-go Repository Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md Alternatively, use 'git clone' to directly clone the opentelemetry-go repository from GitHub. Note that this method does not use the 'go.opentelemetry.io/otel' redirector name. ```sh git clone https://github.com/open-telemetry/opentelemetry-go ``` -------------------------------- ### Clone the opentelemetry-go repository Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md Use this command to clone the official Go repository for OpenTelemetry. ```shell git clone https://github.com/open-telemetry/opentelemetry-go.git ``` -------------------------------- ### Implement Boolean Option (True Default) Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md Provides an implementation for a boolean option that defaults to true. Use this when the option should be on by default and disabled via a `Without*` function. ```go type defaultTrueOption bool func (o defaultTrueOption) apply(c config) config { c.Bool = bool(o) return c } // WithoutOption sets a T to have Bool option excluded. func WithoutOption() Option { return defaultTrueOption(false) } ``` -------------------------------- ### Update Semantic Convention Imports in Go Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/RELEASING.md Demonstrates the transition of import paths for semconv modules when upgrading to a new semantic convention version. Ensure all references in the codebase are updated to the new version path. ```go // Before semconv "go.opentelemetry.io/otel/semconv/v1.37.0" "go.opentelemetry.io/otel/semconv/v1.37.0/otelconv" // After semconv "go.opentelemetry.io/otel/semconv/v1.39.0" "go.opentelemetry.io/otel/semconv/v1.39.0/otelconv" ``` -------------------------------- ### Benchmarking Instrumentation Performance in Go Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md Provides a benchmark function to measure the performance of span exporting under different observability enabled/disabled scenarios. This helps in identifying performance regressions and optimizing instrumentation. ```go func BenchmarkExportSpans(b *testing.B) { scenarios := []struct { name string obsEnabled bool }{ {"ObsDisabled", false}, {"ObsEnabled", true}, } for _, scenario := range scenarios { b.Run(scenario.name, func(b *testing.B) { b.Setenv( "OTEL_GO_X_OBSERVABILITY", strconv.FormatBool(scenario.obsEnabled), ) exporter := NewExporter() spans := generateTestSpans(100) b.ResetTimer() b.ReportAllocs() for i := 0; i < b.N; i++ { _ = exporter.ExportSpans(context.Background(), spans) } }) } } ``` -------------------------------- ### Enable Observability Features Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md Check if observability features are enabled via the OTEL_GO_X_OBSERVABILITY environment variable. This pattern is used for experimental features. ```go import "go.opentelemetry.io/otel/*/internal/x" if x.Observability.Enabled() { // Initialize observability metrics } ``` -------------------------------- ### Avoid Implicit Observability Initialization in Go Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md This pattern is discouraged as it relies on implicit side effects for initialization. Initialization logic should be explicit and managed within constructor functions. ```go // ❌ Avoid this pattern. func (c *Component) initObservability() { // Initialize observability metrics if !x.Observability.Enabled() { return } // Initialize observability metrics c.inst = &instrumentation {/* ... */} } ``` -------------------------------- ### Sign Release Artifacts with GPG Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/RELEASING.md Signs the release archives (.tar.gz and .zip) using a specified GPG key. Environment variables for version and key ID are required. ```bash export VERSION="" export KEY_ID="" gpg --local-user $KEY_ID --armor --detach-sign opentelemetry-go-$VERSION.tar.gz gpg --local-user $KEY_ID --armor --detach-sign opentelemetry-go-$VERSION.zip ``` -------------------------------- ### Interop from OpenTracing to OpenTelemetry Context Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/bridge/opentracing/README.md Demonstrates how to ensure OpenTracing spans are correctly recognized and propagated within the OpenTelemetry context. ```APIDOC ## Interop from OpenTracing to OpenTelemetry Context ### Description To ensure OpenTracing spans are properly integrated into the OpenTelemetry context for propagation (both internally and externally), you must explicitly use the `BridgeTracer` when creating your OpenTracing spans. ### Context Propagation When you start an OpenTracing Span, you need to make the OpenTelemetry system aware of it. Use the `BridgeTracer.ContextWithSpanHook` method for this purpose. ```go import ( opentracing "github.com/opentracing/opentracing-go" ``` -------------------------------- ### Define New Interface for Added Functionality Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md When an existing stable interface cannot be modified, add new functionality by defining a separate interface. This allows consumers to check for and use the new capabilities. ```go type Exporter interface { Export() } ``` ```go type Closer interface { Close() } ``` -------------------------------- ### Configure LogRecord Attribute Count Limit Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/sdk/log/DESIGN.md Use `WithAttributeCountLimit` to set the maximum number of attributes allowed in a LogRecord. This option can be configured via environment variables. ```go func WithAttributeCountLimit(limit int) LoggerProviderOption ``` -------------------------------- ### Add Release Tags with Make Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/RELEASING.md This command uses the 'add-tags' make target to create Git tags for the release. It requires specifying the module set and optionally the commit hash if HEAD is not the correct commit. ```bash make add-tags MODSET= COMMIT= ``` -------------------------------- ### LoggerProvider Interface with LoggerConfig Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/log/DESIGN.md A proposed LoggerProvider interface that would accept a LoggerConfig for acquiring loggers. This design was not adopted because it differed from the Trace and Metrics API patterns, and logger acquisition performance is less critical than log emission performance. ```go type LoggerProvider interface{ embedded.LoggerProvider Logger(name string, config LoggerConfig) } ``` -------------------------------- ### Logger Interface with RecordOption Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/log/DESIGN.md An initial design idea for the Logger interface that accepted variadic RecordOptions. This approach was rejected in favor of passing a Record directly to reduce heap allocations and simplify API usage. ```go type Logger interface{ embedded.Logger Emit(ctx context.Context, options ...RecordOption) } ``` -------------------------------- ### Add Fork as Remote Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md After cloning the repository, add your GitHub fork as a new remote using the provided command, replacing placeholders with your fork and username. ```sh git remote add git@github.com:/opentelemetry-go ``` -------------------------------- ### Attribute and Option Allocation Management with sync.Pool in Go Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md Utilizes `sync.Pool` to manage attribute slices and measurement options, minimizing allocations during measurement calls with dynamic attributes. This is crucial for performance when attributes are frequently added. ```go var ( attrPool = sync.Pool{ New: func() any { // Pre-allocate common capacity knowCap := 8 // Adjust based on expected usage s := make([]attribute.KeyValue, 0, knownCap) // Return a pointer to avoid extra allocation on Put(). return &s }, } addOptPool = &sync.Pool{ New: func() any { const n = 1 // WithAttributeSet o := make([]metric.AddOption, 0, n) // Return a pointer to avoid extra allocation on Put(). return &o }, } ) func (i *instrumentation) record(ctx context.Context, value int64, baseAttrs ...attribute.KeyValue) { if !i.counter.Enabled(ctx) { return } attrs := attrPool.Get().(*[]attribute.KeyValue) defer func() { clear(*attrs) // Clear references to strings/etc to let GC collect them. *attrs = (*attrs)[:0] // Reset. attrPool.Put(attrs) }() *attrs = append(*attrs, baseAttrs...) // Add any dynamic attributes. *attrs = append(*attrs, semconv.OTelComponentName("exporter-1")) addOpt := addOptPool.Get().(*[]metric.AddOption) defer func() { clear(*addOpt) *addOpt = (*addOpt)[:0] addOptPool.Put(addOpt) }() set := attribute.NewSet(*attrs...) *addOpt = append(*addOpt, metric.WithAttributeSet(set)) i.counter.Add(ctx, value, *addOpt...) } ``` -------------------------------- ### Generate Unique Component Names in Go Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md Use an atomic counter to generate unique, stable component names. Format the name using the component type and a unique ID. ```go // Unique 0-based ID counter for component instances. var componentIDCounter atomic.Int64 // nextID returns the next unique ID for a component. func nextID() int64 { return componentIDCounter.Add(1) - 1 } // componentName returns a unique name for the component instance. func componentName() attribute.KeyValue { id := nextID() name := fmt.Sprintf("%s/%d", componentType, id) return semconv.OTelComponentName(name) } ``` -------------------------------- ### Generate Semantic Conventions via Makefile Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/RELEASING.md Uses the semconv-generate make target to create new semantic convention packages based on a specified tag. Requires the TAG environment variable to be set to the desired version. ```bash export TAG="v1.30.0" make semconv-generate ``` -------------------------------- ### Type Assertion for New Interface Functionality Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md Demonstrates how to check if an object implementing an existing interface also satisfies a newly defined interface, enabling the use of additional methods. ```go func caller(e Exporter) { /* ... */ if c, ok := e.(Closer); ok { c.Close() } /* ... */ } ``` -------------------------------- ### Context Propagation in Go Exporter Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md Use the provided context for observability measurements within the ExportSpans method. Record span export status based on the operation's success or failure. ```go func (e *Exporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan) error { // Use the provided context for observability measurements if e.inst.Enabled(ctx) { e.inst.recordSpanExportStarted(ctx, len(spans)) } err := e.doExport(ctx, spans) if e.inst.Enabled(ctx) { if err != nil { e.inst.recordSpanExportFailed(ctx, len(spans), err) } else { e.inst.recordSpanExportSucceeded(ctx, len(spans)) } } return err } ``` -------------------------------- ### Avoid Unconditional Span Export Overhead in Go Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md This pattern demonstrates an anti-pattern where span recording occurs regardless of whether observability is enabled, leading to unnecessary overhead. Always check if instrumentation is enabled before performing expensive operations. ```go // ❌ Avoid this pattern. func (e *Exporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan) error { attrs := expensiveOperation() e.inst.recordSpanInflight(ctx, int64(len(spans)), attrs...) // Export spans... } func (i *instrumentation) recordSpanInflight(ctx context.Context, count int64, attrs ...attribute.KeyValue) { if i == nil || i.inflight == nil || !i.inflight.Enabled(ctx) { return } i.inflight.Add(ctx, count, metric.WithAttributes(attrs...)) } ``` -------------------------------- ### Configure LogRecord Attribute Value Length Limit Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/sdk/log/DESIGN.md Use `WithAttributeValueLengthLimit` to set the maximum length for attribute values in a LogRecord. This option can be configured via environment variables. ```go func WithAttributeValueLengthLimit(limit int) LoggerProviderOption ``` -------------------------------- ### Push Tags to Upstream Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/RELEASING.md Pushes the newly created Git tags to the upstream remote repository. This command should be run for each tag, including those for submodules. ```bash git push upstream git push upstream ... ``` -------------------------------- ### Define Option Interface Source: https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md Defines the core Option interface with an unexported apply method to ensure it's not used externally and remains sealed. ```go type Option interface { apply(config) config } ```