Skip to content

Commit 0f32efc

Browse files
authored
Trace sdk (#65)
* trace sdk initial commit. * fix imports and comments. * remove tracestate * split trace.go * add attribute over limit test. * add comments and restructure span.go and tracer.go * refactor MessageEvent * defer unlock * some more cleanup in span.go * rename *MessageEvent* to *Event* * cleanup comments in trace_test.go * fix typos. * return full string ID for traceID and spanID.
1 parent ed3b26b commit 0f32efc

28 files changed

+2082
-10
lines changed

api/core/span_context.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,13 @@ func (sc SpanContext) HasSpanID() bool {
5353
}
5454

5555
func (sc SpanContext) SpanIDString() string {
56-
p := fmt.Sprintf("%.16x", sc.SpanID)
57-
return p[0:3] + ".." + p[13:16]
56+
return fmt.Sprintf("%.16x", sc.SpanID)
5857
}
5958

6059
func (sc SpanContext) TraceIDString() string {
6160
p1 := fmt.Sprintf("%.16x", sc.TraceID.High)
6261
p2 := fmt.Sprintf("%.16x", sc.TraceID.Low)
63-
return p1[0:3] + ".." + p2[13:16]
62+
return p1 + p2
6463
}
6564

6665
func (sc SpanContext) IsSampled() bool {

api/core/span_context_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,11 @@ func TestSpanIDString(t *testing.T) {
8888
{
8989
name: "fourtytwo",
9090
sc: SpanContext{SpanID: uint64(42)},
91-
want: `000..02a`,
91+
want: `000000000000002a`,
9292
}, {
9393
name: "empty",
9494
sc: SpanContext{},
95-
want: `000..000`,
95+
want: `0000000000000000`,
9696
},
9797
} {
9898
t.Run(testcase.name, func(t *testing.T) {
@@ -119,11 +119,11 @@ func TestTraceIDString(t *testing.T) {
119119
Low: uint64(42),
120120
},
121121
},
122-
want: `000..02a`,
122+
want: `000000000000002a000000000000002a`,
123123
}, {
124124
name: "empty",
125125
sc: SpanContext{TraceID: TraceID{}},
126-
want: `000..000`,
126+
want: `00000000000000000000000000000000`,
127127
},
128128
} {
129129
t.Run(testcase.name, func(t *testing.T) {

go.mod

+4-3
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,21 @@ go 1.12
55
require (
66
github.com/gogo/protobuf v1.2.1 // indirect
77
github.com/golang/mock v1.2.0 // indirect
8-
github.com/golang/protobuf v1.3.1 // indirect
8+
github.com/golang/protobuf v1.3.1
99
github.com/golangci/golangci-lint v1.17.1
1010
github.com/google/go-cmp v0.3.0
11+
github.com/hashicorp/golang-lru v0.5.1
1112
github.com/lightstep/tracecontext.go v0.0.0-20181129014701-1757c391b1ac
1213
github.com/onsi/ginkgo v1.8.0 // indirect
1314
github.com/onsi/gomega v1.5.0 // indirect
1415
github.com/pkg/errors v0.8.1 // indirect
1516
github.com/sirupsen/logrus v1.2.0 // indirect
1617
github.com/spf13/cobra v0.0.5 // indirect
1718
github.com/stretchr/testify v1.3.0 // indirect
19+
go.opencensus.io v0.22.0
1820
golang.org/x/crypto v0.0.0-20190424203555-c05e17bb3b2d // indirect
19-
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 // indirect
21+
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980
2022
golang.org/x/sys v0.0.0-20190614160838-b47fdc937951 // indirect
21-
golang.org/x/text v0.3.2 // indirect
2223
golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd
2324
google.golang.org/appengine v1.4.0 // indirect
2425
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873 // indirect

go.sum

+10
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
112112
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
113113
github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3 h1:JVnpOZS+qxli+rgVl98ILOXVNbW+kb5wcxeGx8ShUIw=
114114
github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
115+
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
116+
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
115117
github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce h1:xdsDDbiBDQTKASoGEZ+pEmF1OnWuu8AQ9I8iNbHNeno=
116118
github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
117119
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
@@ -233,6 +235,10 @@ github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk
233235
github.com/valyala/quicktemplate v1.1.1/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4=
234236
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
235237
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
238+
go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4=
239+
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
240+
go.opentelemetry.io v0.0.0-20190715214921-eed647d11f57 h1:5uH+S26G3/t2aU82KLk7vvytwkFoH7ynSIrSQo5CxSI=
241+
go.opentelemetry.io v0.0.0-20190715214921-eed647d11f57/go.mod h1:7pfucu8MX8izd4pjPRY2kCQQMtFi4DWT/IV7KA3sjOQ=
236242
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
237243
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
238244
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@@ -262,6 +268,7 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
262268
golang.org/x/net v0.0.0-20190313220215-9f648a60d977 h1:actzWV6iWn3GLqN8dZjzsB+CLt+gaV2+wsxroxiQI8I=
263269
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
264270
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
271+
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
265272
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU=
266273
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
267274
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -283,6 +290,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
283290
golang.org/x/sys v0.0.0-20190312061237-fead79001313 h1:pczuHS43Cp2ktBEEmLwScxgjWsBSzdaQiKzUyf3DTTc=
284291
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
285292
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
293+
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
286294
golang.org/x/sys v0.0.0-20190614160838-b47fdc937951 h1:ZUgGZ7PSkne6oY+VgAvayrB16owfm9/DKAtgWubzgzU=
287295
golang.org/x/sys v0.0.0-20190614160838-b47fdc937951/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
288296
golang.org/x/text v0.0.0-20170915090833-1cbadb444a80/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -310,9 +318,11 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl
310318
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
311319
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
312320
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
321+
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
313322
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873 h1:nfPFGzJkUDX6uBmpN/pSw7MbOAWegH5QDQuoXFHedLg=
314323
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
315324
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
325+
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
316326
google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8=
317327
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
318328
gopkg.in/airbrake/gobrake.v2 v2.0.9 h1:7z2uVWwn7oVeeugY1DtlPAy5H+KYgB1KeKTnqjNatLo=

sdk/README.md

Whitespace-only changes.

sdk/internal/internal.go

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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+
15+
package internal // import "go.opentelemetry.io/sdk/internal"
16+
17+
import (
18+
"fmt"
19+
"time"
20+
21+
opentelemetry "go.opentelemetry.io/sdk"
22+
)
23+
24+
// UserAgent is the user agent to be added to the outgoing
25+
// requests from the exporters.
26+
var UserAgent = fmt.Sprintf("opentelemetry-go/%s", opentelemetry.Version())
27+
28+
// MonotonicEndTime returns the end time at present
29+
// but offset from start, monotonically.
30+
//
31+
// The monotonic clock is used in subtractions hence
32+
// the duration since start added back to start gives
33+
// end as a monotonic time.
34+
// See https://golang.org/pkg/time/#hdr-Monotonic_Clocks
35+
func MonotonicEndTime(start time.Time) time.Time {
36+
return start.Add(time.Since(start))
37+
}

sdk/internal/sanitize.go

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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+
15+
package internal
16+
17+
import (
18+
"strings"
19+
"unicode"
20+
)
21+
22+
const labelKeySizeLimit = 100
23+
24+
// Sanitize returns a string that is trunacated to 100 characters if it's too
25+
// long, and replaces non-alphanumeric characters to underscores.
26+
func Sanitize(s string) string {
27+
if len(s) == 0 {
28+
return s
29+
}
30+
if len(s) > labelKeySizeLimit {
31+
s = s[:labelKeySizeLimit]
32+
}
33+
s = strings.Map(sanitizeRune, s)
34+
if unicode.IsDigit(rune(s[0])) {
35+
s = "key_" + s
36+
}
37+
if s[0] == '_' {
38+
s = "key" + s
39+
}
40+
return s
41+
}
42+
43+
// converts anything that is not a letter or digit to an underscore
44+
func sanitizeRune(r rune) rune {
45+
if unicode.IsLetter(r) || unicode.IsDigit(r) {
46+
return r
47+
}
48+
// Everything else turns into an underscore
49+
return '_'
50+
}

sdk/internal/sanitize_test.go

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
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+
15+
package internal
16+
17+
import (
18+
"strings"
19+
"testing"
20+
)
21+
22+
func TestSanitize(t *testing.T) {
23+
tests := []struct {
24+
name string
25+
input string
26+
want string
27+
}{
28+
{
29+
name: "trunacate long string",
30+
input: strings.Repeat("a", 101),
31+
want: strings.Repeat("a", 100),
32+
},
33+
{
34+
name: "replace character",
35+
input: "test/key-1",
36+
want: "test_key_1",
37+
},
38+
{
39+
name: "add prefix if starting with digit",
40+
input: "0123456789",
41+
want: "key_0123456789",
42+
},
43+
{
44+
name: "add prefix if starting with _",
45+
input: "_0123456789",
46+
want: "key_0123456789",
47+
},
48+
{
49+
name: "starts with _ after sanitization",
50+
input: "/0123456789",
51+
want: "key_0123456789",
52+
},
53+
{
54+
name: "valid input",
55+
input: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789",
56+
want: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789",
57+
},
58+
}
59+
60+
for _, tt := range tests {
61+
t.Run(tt.name, func(t *testing.T) {
62+
if got, want := Sanitize(tt.input), tt.want; got != want {
63+
t.Errorf("sanitize() = %q; want %q", got, want)
64+
}
65+
})
66+
}
67+
}

sdk/opentelemetry.go

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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+
15+
// Package opentelemetry contains Go support for OpenTelemetry.
16+
package opentelemetry // import "go.opentelemetry.io/sdk"
17+
18+
// Version is the current release version of OpenTelemetry in use.
19+
func Version() string {
20+
return "0.1.0"
21+
}

sdk/trace/basetypes.go

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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+
15+
package trace
16+
17+
import (
18+
"time"
19+
20+
"go.opentelemetry.io/api/core"
21+
apievent "go.opentelemetry.io/api/event"
22+
)
23+
24+
// event is used to describe an event with a message string and set of
25+
// attributes.
26+
type event struct {
27+
msg string
28+
attributes []core.KeyValue
29+
time time.Time
30+
}
31+
32+
var _ apievent.Event = &event{}
33+
34+
func (me *event) Message() string {
35+
return me.msg
36+
}
37+
38+
func (me *event) Attributes() []core.KeyValue {
39+
return me.attributes
40+
}

0 commit comments

Comments
 (0)