1// Copyright 2019, OpenTelemetry Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package stdout
16
17import (
18	"context"
19	"encoding/json"
20	"io"
21	"os"
22
23	export "go.opentelemetry.io/otel/sdk/export/trace"
24)
25
26// Options are the options to be used when initializing a stdout export.
27type Options struct {
28	// Writer is the destination.  If not set, os.Stdout is used.
29	Writer io.Writer
30
31	// PrettyPrint will pretty the json representation of the span,
32	// making it print "pretty". Default is false.
33	PrettyPrint bool
34}
35
36// Exporter is an implementation of trace.Exporter that writes spans to stdout.
37type Exporter struct {
38	pretty       bool
39	outputWriter io.Writer
40}
41
42func NewExporter(o Options) (*Exporter, error) {
43	if o.Writer == nil {
44		o.Writer = os.Stdout
45	}
46	return &Exporter{
47		pretty:       o.PrettyPrint,
48		outputWriter: o.Writer,
49	}, nil
50}
51
52// ExportSpan writes a SpanData in json format to stdout.
53func (e *Exporter) ExportSpan(ctx context.Context, data *export.SpanData) {
54	var jsonSpan []byte
55	var err error
56	if e.pretty {
57		jsonSpan, err = json.MarshalIndent(data, "", "\t")
58	} else {
59		jsonSpan, err = json.Marshal(data)
60	}
61	if err != nil {
62		// ignore writer failures for now
63		_, _ = e.outputWriter.Write([]byte("Error converting spanData to json: " + err.Error()))
64		return
65	}
66	// ignore writer failures for now
67	_, _ = e.outputWriter.Write(append(jsonSpan, byte('\n')))
68}
69