Skip to content

Commit

Permalink
Add EntityEmitterProvider
Browse files Browse the repository at this point in the history
  • Loading branch information
tigrannajaryan committed Feb 14, 2024
1 parent 0b099b2 commit 89e6818
Show file tree
Hide file tree
Showing 10 changed files with 562 additions and 31 deletions.
47 changes: 47 additions & 0 deletions entity.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package otel // import "go.opentelemetry.io/otel"

import (
"go.opentelemetry.io/otel/entity"
"go.opentelemetry.io/otel/internal/global"
)

// EntityEmitter creates a named entityEmitter that implements EntityEmitter interface.
// If the name is an empty string then provider uses default name.
//
// This is short for GetEntityEmitterProvider().EntityEmitter(name, opts...)
func EntityEmitter(name string, opts ...entity.EntityEmitterOption) entity.EntityEmitter {
return GetEntityEmitterProvider().EntityEmitter(name, opts...)
}

// GetEntityEmitterProvider returns the registered global entity provider.
// If none is registered then an instance of NoopEntityEmitterProvider is returned.
//
// Use the entity provider to create a named entityEmitter. E.g.
//
// entityEmitter := otel.GetEntityEmitterProvider().EntityEmitter("example.com/foo")
//
// or
//
// entityEmitter := otel.EntityEmitter("example.com/foo")
func GetEntityEmitterProvider() entity.EntityEmitterProvider {
return global.EntityEmitterProvider()
}

// SetEntityEmitterProvider registers `tp` as the global entity provider.
func SetEntityEmitterProvider(tp entity.EntityEmitterProvider) {
global.SetEntityEmitterProvider(tp)
}
95 changes: 95 additions & 0 deletions entity/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package entity // import "go.opentelemetry.io/otel/entity"

import (
"go.opentelemetry.io/otel/attribute"
)

// EntityEmitterConfig is a group of options for a EntityEmitter.
type EntityEmitterConfig struct {
instrumentationVersion string
// Schema URL of the telemetry emitted by the EntityEmitter.
schemaURL string
attrs attribute.Set
}

// InstrumentationVersion returns the version of the library providing instrumentation.
func (t *EntityEmitterConfig) InstrumentationVersion() string {
return t.instrumentationVersion
}

// InstrumentationAttributes returns the attributes associated with the library
// providing instrumentation.
func (t *EntityEmitterConfig) InstrumentationAttributes() attribute.Set {
return t.attrs
}

// SchemaURL returns the Schema URL of the telemetry emitted by the EntityEmitter.
func (t *EntityEmitterConfig) SchemaURL() string {
return t.schemaURL
}

// NewEntityEmitterConfig applies all the options to a returned EntityEmitterConfig.
func NewEntityEmitterConfig(options ...EntityEmitterOption) EntityEmitterConfig {
var config EntityEmitterConfig
for _, option := range options {
config = option.apply(config)
}
return config
}

// EntityEmitterOption applies an option to a EntityEmitterConfig.
type EntityEmitterOption interface {
apply(EntityEmitterConfig) EntityEmitterConfig
}

type entityEmitterOptionFunc func(EntityEmitterConfig) EntityEmitterConfig

func (fn entityEmitterOptionFunc) apply(cfg EntityEmitterConfig) EntityEmitterConfig {
return fn(cfg)
}

// WithInstrumentationVersion sets the instrumentation version.
func WithInstrumentationVersion(version string) EntityEmitterOption {
return entityEmitterOptionFunc(
func(cfg EntityEmitterConfig) EntityEmitterConfig {
cfg.instrumentationVersion = version
return cfg
},
)
}

// WithInstrumentationAttributes sets the instrumentation attributes.
//
// The passed attributes will be de-duplicated.
func WithInstrumentationAttributes(attr ...attribute.KeyValue) EntityEmitterOption {
return entityEmitterOptionFunc(
func(config EntityEmitterConfig) EntityEmitterConfig {
config.attrs = attribute.NewSet(attr...)
return config
},
)
}

// WithSchemaURL sets the schema URL for the EntityEmitter.
func WithSchemaURL(schemaURL string) EntityEmitterOption {
return entityEmitterOptionFunc(
func(cfg EntityEmitterConfig) EntityEmitterConfig {
cfg.schemaURL = schemaURL
return cfg
},
)
}
56 changes: 56 additions & 0 deletions entity/embedded/embedded.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package embedded provides interfaces embedded within the [OpenTelemetry
// entity API].
//
// Implementers of the [OpenTelemetry entity API] can embed the relevant type
// from this package into their implementation directly. Doing so will result
// in a compilation error for users when the [OpenTelemetry entity API] is
// extended (which is something that can happen without a major version bump of
// the API package).
//
// [OpenTelemetry entity API]: https://pkg.go.dev/go.opentelemetry.io/otel/entity
package embedded // import "go.opentelemetry.io/otel/entity/embedded"

// EntityEmitterProvider is embedded in
// [go.opentelemetry.io/otel/entity.EntityEmitterProvider].
//
// Embed this interface in your implementation of the
// [go.opentelemetry.io/otel/entity.EntityEmitterProvider] if you want users to
// experience a compilation error, signaling they need to update to your latest
// implementation, when the [go.opentelemetry.io/otel/entity.EntityEmitterProvider]
// interface is extended (which is something that can happen without a major
// version bump of the API package).
type EntityEmitterProvider interface{ entityEmitterProvider() }

// EntityEmitter is embedded in [go.opentelemetry.io/otel/entity.EntityEmitter].
//
// Embed this interface in your implementation of the
// [go.opentelemetry.io/otel/entity.EntityEmitter] if you want users to experience a
// compilation error, signaling they need to update to your latest
// implementation, when the [go.opentelemetry.io/otel/entity.EntityEmitter] interface
// is extended (which is something that can happen without a major version bump
// of the API package).
type EntityEmitter interface{ entityEmitter() }

// Entity is embedded in [go.opentelemetry.io/otel/entity.Entity].
//
// Embed this interface in your implementation of the
// [go.opentelemetry.io/otel/entity.Entity] if you want users to experience a
// compilation error, signaling they need to update to your latest
// implementation, when the [go.opentelemetry.io/otel/entity.Entity] interface is
// extended (which is something that can happen without a major version bump of
// the API package).
type Entity interface{ entity() }
99 changes: 99 additions & 0 deletions entity/entity.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package entity // import "go.opentelemetry.io/otel/entity"

import (
"go.opentelemetry.io/otel/entity/embedded"
)

// EntityEmitter is the creator of Spans.
//
// Warning: Methods may be added to this interface in minor releases. See
// package documentation on API implementation for information on how to set
// default behavior for unimplemented methods.
type EntityEmitter interface {
// Users of the interface can ignore this. This embedded type is only used
// by implementations of this interface. See the "API Implementations"
// section of the package documentation for more information.
embedded.EntityEmitter

// Start creates a span and a context.Context containing the newly-created span.
//
// If the context.Context provided in `ctx` contains a Span then the newly-created
// Span will be a child of that span, otherwise it will be a root span. This behavior
// can be overridden by providing `WithNewRoot()` as a SpanOption, causing the
// newly-created Span to be a root span even if `ctx` contains a Span.
//
// When creating a Span it is recommended to provide all known span attributes using
// the `WithAttributes()` SpanOption as samplers will only have access to the
// attributes provided when a Span is created.
//
// Any Span that is created MUST also be ended. This is the responsibility of the user.
// Implementations of this API may leak memory or other resources if Spans are not ended.
//Start(ctx context.Context, spanName string, opts ...SpanStartOption) (context.Context, Span)
}

// EntityEmitterProvider provides EntityEmitters that are used by instrumentation code to
// entity computational workflows.
//
// A EntityEmitterProvider is the collection destination of all Spans from EntityEmitters it
// provides, it represents a unique telemetry collection pipeline. How that
// pipeline is defined, meaning how those Spans are collected, processed, and
// where they are exported, depends on its implementation. Instrumentation
// authors do not need to define this implementation, rather just use the
// provided EntityEmitters to instrument code.
//
// Commonly, instrumentation code will accept a EntityEmitterProvider implementation
// at runtime from its users or it can simply use the globally registered one
// (see https://pkg.go.dev/go.opentelemetry.io/otel#GetEntityEmitterProvider).
//
// Warning: Methods may be added to this interface in minor releases. See
// package documentation on API implementation for information on how to set
// default behavior for unimplemented methods.
type EntityEmitterProvider interface {
// Users of the interface can ignore this. This embedded type is only used
// by implementations of this interface. See the "API Implementations"
// section of the package documentation for more information.
embedded.EntityEmitterProvider

// EntityEmitter returns a unique EntityEmitter scoped to be used by instrumentation code
// to entity computational workflows. The scope and identity of that
// instrumentation code is uniquely defined by the name and options passed.
//
// The passed name needs to uniquely identify instrumentation code.
// Therefore, it is recommended that name is the Go package name of the
// library providing instrumentation (note: not the code being
// instrumented). Instrumentation libraries can have multiple versions,
// therefore, the WithInstrumentationVersion option should be used to
// distinguish these different codebases. Additionally, instrumentation
// libraries may sometimes use entitys to communicate different domains of
// workflow data (i.e. using spans to communicate workflow events only). If
// this is the case, the WithScopeAttributes option should be used to
// uniquely identify EntityEmitters that handle the different domains of workflow
// data.
//
// If the same name and options are passed multiple times, the same EntityEmitter
// will be returned (it is up to the implementation if this will be the
// same underlying instance of that EntityEmitter or not). It is not necessary to
// call this multiple times with the same name and options to get an
// up-to-date EntityEmitter. All implementations will ensure any EntityEmitterProvider
// configuration changes are propagated to all provided EntityEmitters.
//
// If name is empty, then an implementation defined default name will be
// used instead.
//
// This method is safe to call concurrently.
EntityEmitter(name string, options ...EntityEmitterOption) EntityEmitter
}
Loading

0 comments on commit 89e6818

Please sign in to comment.