Skip to content

Commit

Permalink
Begin adding entity exporter
Browse files Browse the repository at this point in the history
  • Loading branch information
tigrannajaryan committed Feb 15, 2024
1 parent 89e6818 commit ebf4054
Show file tree
Hide file tree
Showing 11 changed files with 1,363 additions and 0 deletions.
18 changes: 18 additions & 0 deletions entity/entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,27 @@
package entity // import "go.opentelemetry.io/otel/entity"

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

type Entity interface {
embedded.Entity

// IsRecording returns the recording state of the Span. It will return
// true if the Span is active and events can be recorded.
IsRecording() bool

// SetAttributes sets kv as attributes of the Span. If a key from kv
// already exists for an attribute of the Span it will be overwritten with
// the value contained in kv.
SetAttributes(kv ...attribute.KeyValue)

// TracerProvider returns a TracerProvider that can be used to generate
// additional Spans on the same telemetry pipeline as the current Span.
EntityEmitterProvider() EntityEmitterProvider
}

// EntityEmitter is the creator of Spans.
//
// Warning: Methods may be added to this interface in minor releases. See
Expand Down
54 changes: 54 additions & 0 deletions exporters/otlp/otlpentity/clients.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// 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 otlpentity // import "go.opentelemetry.io/otel/exporters/otlp/otlpentity"

import (
"context"

entitiespb "go.opentelemetry.io/proto/otlp/entities/v1"
)

// Client manages connections to the collector, handles the
// transformation of data into wire format, and the transmission of that
// data to the collector.
type Client interface {
// DO NOT CHANGE: any modification will not be backwards compatible and
// must never be done outside of a new major release.

// Start should establish connection(s) to endpoint(s). It is
// called just once by the exporter, so the implementation
// does not need to worry about idempotence and locking.
Start(ctx context.Context) error
// DO NOT CHANGE: any modification will not be backwards compatible and
// must never be done outside of a new major release.

// Stop should close the connections. The function is called
// only once by the exporter, so the implementation does not
// need to worry about idempotence, but it may be called
// concurrently with UploadEntitys, so proper
// locking is required. The function serves as a
// synchronization point - after the function returns, the
// process of closing connections is assumed to be finished.
Stop(ctx context.Context) error
// DO NOT CHANGE: any modification will not be backwards compatible and
// must never be done outside of a new major release.

// UploadEntitys should transform the passed entitys to the wire
// format and send it to the collector. May be called
// concurrently.
UploadEntities(ctx context.Context, entities []*entitiespb.ScopeEntities) error
// DO NOT CHANGE: any modification will not be backwards compatible and
// must never be done outside of a new major release.
}
120 changes: 120 additions & 0 deletions exporters/otlp/otlpentity/exporter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// 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 otlpentity // import "go.opentelemetry.io/otel/exporters/otlp/otlpentity"

import (
"context"
"errors"
"fmt"
"sync"

"go.opentelemetry.io/otel/exporters/otlp/otlpentity/internal/entitytransform"
"go.opentelemetry.io/otel/sdk/resource"
)

var errAlreadyStarted = errors.New("already started")

// Exporter exports entity data in the OTLP wire format.
type Exporter struct {
client Client

mu sync.RWMutex
started bool

startOnce sync.Once
stopOnce sync.Once
}

// ExportSpans exports a batch of spans.
func (e *Exporter) ExportEntities(ctx context.Context, entities []resource.ReadOnlyEntity) error {
protoSpans := entitytransform.Entities(entities)
if len(protoSpans) == 0 {
return nil
}

err := e.client.UploadEntities(ctx, protoSpans)
if err != nil {
return fmt.Errorf("entitys export: %w", err)
}
return nil
}

// Start establishes a connection to the receiving endpoint.
func (e *Exporter) Start(ctx context.Context) error {
err := errAlreadyStarted
e.startOnce.Do(
func() {
e.mu.Lock()
e.started = true
e.mu.Unlock()
err = e.client.Start(ctx)
},
)

return err
}

// Shutdown flushes all exports and closes all connections to the receiving endpoint.
func (e *Exporter) Shutdown(ctx context.Context) error {
e.mu.RLock()
started := e.started
e.mu.RUnlock()

if !started {
return nil
}

var err error

e.stopOnce.Do(
func() {
err = e.client.Stop(ctx)
e.mu.Lock()
e.started = false
e.mu.Unlock()
},
)

return err
}

var _ resource.EntityExporter = (*Exporter)(nil)

// New constructs a new Exporter and starts it.
func New(ctx context.Context, client Client) (*Exporter, error) {
exp := NewUnstarted(client)
if err := exp.Start(ctx); err != nil {
return nil, err
}
return exp, nil
}

// NewUnstarted constructs a new Exporter and does not start it.
func NewUnstarted(client Client) *Exporter {
return &Exporter{
client: client,
}
}

// MarshalLog is the marshaling function used by the logging system to represent this Exporter.
func (e *Exporter) MarshalLog() interface{} {
return struct {
Type string
Client Client
}{
Type: "otlpentity",
Client: e.client,
}
}
28 changes: 28 additions & 0 deletions exporters/otlp/otlpentity/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module go.opentelemetry.io/otel/exporters/otlp/otlpentity

go 1.20

require (
go.opentelemetry.io/otel v1.23.1
go.opentelemetry.io/otel/sdk v1.23.1
go.opentelemetry.io/proto/otlp v1.1.0
)

require (
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
go.opentelemetry.io/otel/metric v1.23.1 // indirect
go.opentelemetry.io/otel/trace v1.23.0-rc.1 // indirect
golang.org/x/sys v0.16.0 // indirect
google.golang.org/protobuf v1.32.0 // indirect
)

replace go.opentelemetry.io/otel => ../../..

replace go.opentelemetry.io/otel/sdk => ../../../sdk

replace go.opentelemetry.io/otel/trace => ../../../trace

replace go.opentelemetry.io/otel/metric => ../../../metric

replace go.opentelemetry.io/proto/otlp => ../../../../opentelemetry-proto-go/otlp/
14 changes: 14 additions & 0 deletions exporters/otlp/otlpentity/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Loading

0 comments on commit ebf4054

Please sign in to comment.