Skip to content
Merged
30 changes: 30 additions & 0 deletions protocols/encoding/decoder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// 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 encoding

// MetricsDecoder decodes bytes into pdata.
type MetricsDecoder interface {
DecodeMetrics(bytes []byte) (interface{}, error)
}

// TracesDecoder decodes bytes into pdata.
type TracesDecoder interface {
DecodeTraces(bytes []byte) (interface{}, error)
}

// LogsDecoder decodes bytes into pdata.
type LogsDecoder interface {
DecodeLogs(bytes []byte) (interface{}, error)
}
30 changes: 30 additions & 0 deletions protocols/encoding/encoder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// 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 encoding

// MetricsEncoder encodes pdata into bytes.
type MetricsEncoder interface {
EncodeMetrics(model interface{}) ([]byte, error)
}

// TracesEncoder encodes pdata into bytes.
type TracesEncoder interface {
EncodeTraces(model interface{}) ([]byte, error)
}

// LogsEncoder encodes pdata into bytes.
type LogsEncoder interface {
EncodeLogs(model interface{}) ([]byte, error)
}
39 changes: 39 additions & 0 deletions protocols/encoding/encoding.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// 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 encoding

import "fmt"

// Type is the encoding format that a model is serialized to.
type Type string

const (
Protobuf Type = "protobuf"
JSON Type = "json"
Thrift Type = "thrift"
)

func (e Type) String() string {
return string(e)
}

// ErrUnavailableEncoding is returned when the requested encoding is not present.
type ErrUnavailableEncoding struct {
Encoding Type
}

func (e *ErrUnavailableEncoding) Error() string {
return fmt.Sprintf("unsupported encoding %q", e.Encoding)
}
53 changes: 53 additions & 0 deletions protocols/models/models.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// 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 models

import (
"fmt"
"go.opentelemetry.io/collector/consumer/pdata"
)

type MetricsModelTranslator interface {
// MetricsFromModel converts a data model of another protocol into pdata.
MetricsFromModel(src interface{}) (pdata.Metrics, error)
// MetricsToModel converts pdata to data model.
MetricsToModel(md pdata.Metrics, out interface{}) error
}

type TracesModelTranslator interface {
// TracesFromModel converts a data model of another protocol into pdata.
TracesFromModel(src interface{}) (pdata.Traces, error)
// TracesToModel converts pdata to data model.
TracesToModel(md pdata.Traces, out interface{}) error

Type() interface{}
}

type LogsModelTranslator interface {
// LogsFromModel converts a data model of another protocol into pdata.
LogsFromModel(src interface{}) (pdata.Logs, error)
// LogsToModel converts pdata to data model.
LogsToModel(md pdata.Logs, out interface{}) error
}

// ErrIncompatibleType details a type conversion error during translation.
type ErrIncompatibleType struct {
Model interface{}
// TODO: maybe do expected vs. actual?
}

func (i *ErrIncompatibleType) Error() string {
return fmt.Sprintf("model type %T is incompatible", i.Model)
}
57 changes: 57 additions & 0 deletions protocols/protocols.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// 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 protocols

import (
"go.opentelemetry.io/collector/consumer/pdata"
"go.opentelemetry.io/collector/protocols/encoding"
"go.opentelemetry.io/collector/protocols/models"
"go.opentelemetry.io/collector/protocols/zipkinv2"
)

type Transcoder struct {
models.TracesModelTranslator
encoding.TracesEncoder
encoding.TracesDecoder
}

func (t *Transcoder) UnmarshalTraces(data []byte) (pdata.Traces, error) {
model, err := t.DecodeTraces(data)
if err != nil {
return pdata.NewTraces(), err
}
return t.TracesFromModel(model)
}

func (t *Transcoder) MarshalTraces(td pdata.Traces) ([]byte, error) {
out := t.Type()
if err := t.TracesToModel(td, &out); err != nil {
return nil, err
}
return t.EncodeTraces(out)
}

func test() {
translator := &zipkinv2.Model{ParseStringTags: false}
encodingDecoding := &zipkinv2.Encoder{
Encoding: encoding.JSON,
}

tc := &Transcoder{
TracesModelTranslator: translator,
TracesEncoder: encodingDecoding,
TracesDecoder: encodingDecoding,
}
}
66 changes: 66 additions & 0 deletions protocols/zipkinv2/encoding.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// 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 zipkinv2

import (
"encoding/json"

zipkinmodel "github.com/openzipkin/zipkin-go/model"
"github.com/openzipkin/zipkin-go/proto/zipkin_proto3"

"go.opentelemetry.io/collector/protocols/encoding"
"go.opentelemetry.io/collector/protocols/models"
)

var (
_ encoding.TracesEncoder = (*Encoder)(nil)
_ encoding.TracesDecoder = (*Encoder)(nil)
)

type Encoder struct {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

map[encoding.Type]Encoder

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's possible but will require some helpers. Let's punt on it for now though as it doesn't impact the external API so can be easily tidied up later.

// Encoding is the format Zipkin is serialized to.
Encoding encoding.Type
}

func (z *Encoder) DecodeTraces(bytes []byte) (interface{}, error) {
switch z.Encoding {
case encoding.Protobuf:
return zipkin_proto3.ParseSpans(bytes, false)
case encoding.JSON:
var spans []*zipkinmodel.SpanModel
if err := json.Unmarshal(bytes, &spans); err != nil {
return nil, err
}
return spans, nil
default:
return nil, &encoding.ErrUnavailableEncoding{Encoding: z.Encoding}
}
}

func (z *Encoder) EncodeTraces(model interface{}) ([]byte, error) {
spans, ok := model.([]*zipkinmodel.SpanModel)
if !ok {
return nil, &models.ErrIncompatibleType{Model: spans}
}

switch z.Encoding {
// TODO
// case protocols.Protobuf:
case encoding.JSON:
return json.Marshal(spans)
default:
return nil, &encoding.ErrUnavailableEncoding{Encoding: z.Encoding}
}
}
54 changes: 54 additions & 0 deletions protocols/zipkinv2/models.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 zipkinv2

import (
zipkinmodel "github.com/openzipkin/zipkin-go/model"

"go.opentelemetry.io/collector/consumer/pdata"
"go.opentelemetry.io/collector/protocols/models"
"go.opentelemetry.io/collector/translator/trace/zipkin"
)

var (
_ models.TracesModelTranslator = (*Model)(nil)
)

type Model struct {
// ParseStringTags is true if string tags should be automatically converted to numbers.
ParseStringTags bool
}

func (z *Model) Type() interface{} {
return []*zipkinmodel.SpanModel{}
}

func (z *Model) TracesFromModel(src interface{}) (pdata.Traces, error) {
if model, ok := src.([]*zipkinmodel.SpanModel); ok {
return zipkin.V2SpansToInternalTraces(model, z.ParseStringTags)
}
return pdata.NewTraces(), &models.ErrIncompatibleType{Model: src}
}

func (z *Model) TracesToModel(td pdata.Traces, out interface{}) error {
if model, ok := out.(*[]*zipkinmodel.SpanModel); ok {
sm, err := zipkin.InternalTracesToZipkinSpans(td)
if err != nil {
return err
}
*model = sm
}
return &models.ErrIncompatibleType{Model: out}
}