1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-11-25 22:41:46 +02:00

Remove experimental/streaming globals, add streaming example (#135)

* Remove globals from exp/streaming

* basic example

* Build the streaming example

* Update README.md for running streaming example

* Remove observer package

* Move observer to exporter

* Fix

* Re-run make circle-ci
This commit is contained in:
Joshua MacDonald
2019-09-23 14:39:10 -07:00
committed by GitHub
parent 83935b2558
commit a3ae50d8bc
34 changed files with 534 additions and 593 deletions

1
.gitignore vendored
View File

@@ -7,3 +7,4 @@ coverage.*
/example/basic/basic /example/basic/basic
/example/http/client/client /example/http/client/client
/example/http/server/server /example/http/server/server
/experimental/streaming/example/basic/basic

View File

@@ -3,7 +3,8 @@ ALL_PKGS := $(shell go list ./...)
EXAMPLES := \ EXAMPLES := \
./example/basic \ ./example/basic \
./example/http/client \ ./example/http/client \
./example/http/server ./example/http/server \
./experimental/streaming/example/basic
# All source code and documents. Used in spell check. # All source code and documents. Used in spell check.
ALL_DOCS := $(shell find . -name '*.md' -type f | sort) ALL_DOCS := $(shell find . -name '*.md' -type f | sort)

View File

@@ -4,23 +4,17 @@
[![Docs](https://godoc.org/go.opentelemetry.io?status.svg)](http://godoc.org/go.opentelemetry.io) [![Docs](https://godoc.org/go.opentelemetry.io?status.svg)](http://godoc.org/go.opentelemetry.io)
[![Go Report Card](https://goreportcard.com/badge/go.opentelemetry.io)](https://goreportcard.com/report/go.opentelemetry.io) [![Go Report Card](https://goreportcard.com/badge/go.opentelemetry.io)](https://goreportcard.com/report/go.opentelemetry.io)
This is a prototype *intended to be modified* into the opentelemetry-go implementation. The `api` directory here should be used as a starting point to introduce a new OpenTelemetry exporter, whereas the existing `exporter/observer` streaming model should be help verify the api The Go [OpenTelemetry](https://opentelemetry.io/) client.
To run the examples, first build the stderr tracer plugin (requires Linux or OS X): ## TODO
TODO
## Experimental streaming SDK
The `experimental/streaming` directory contains an experimental SDK
that supports a low-level exporter.
```console
(cd ./experimental/streaming/exporter/stdout/plugin && make)
(cd ./experimental/streaming/exporter/spanlog/plugin && make)
``` ```
go run experimental/streaming/example/basic/main.go
Then set the `OPENTELEMETRY_LIB` environment variable to the .so file in that directory, e.g.,
```console
OPENTELEMETRY_LIB=./experimental/streaming/exporter/stderr/plugin/stderr.so go run ./example/http/server/server.go
```
and
```console
OPENTELEMETRY_LIB=./experimental/streaming/exporter/spanlog/plugin/spanlog.so go run ./example/http/client/client.go
``` ```

View File

@@ -24,7 +24,7 @@ func GlobalMeter() Meter {
if t := global.Load(); t != nil { if t := global.Load(); t != nil {
return t.(Meter) return t.(Meter)
} }
return noopMeter{} return NoopMeter{}
} }
// SetGlobalMeter sets provided meter as a global meter. // SetGlobalMeter sets provided meter as a global meter.

View File

@@ -6,15 +6,15 @@ import (
"go.opentelemetry.io/api/core" "go.opentelemetry.io/api/core"
) )
type noopMeter struct{} type NoopMeter struct{}
type noopMetric struct{} type noopMetric struct{}
var _ Meter = noopMeter{} var _ Meter = NoopMeter{}
var _ Float64Gauge = noopMetric{} var _ Float64Gauge = noopMetric{}
func (noopMeter) GetFloat64Gauge(ctx context.Context, gauge *Float64GaugeHandle, labels ...core.KeyValue) Float64Gauge { func (NoopMeter) GetFloat64Gauge(ctx context.Context, gauge *Float64GaugeHandle, labels ...core.KeyValue) Float64Gauge {
return noopMetric{} return noopMetric{}
} }

View File

@@ -0,0 +1,7 @@
module github.com/open-telemetry/opentelemetry-go/experimental/streaming/example/basic
go 1.12
replace go.opentelemetry.io => ../../../..
require go.opentelemetry.io v0.0.0-00010101000000-000000000000

View File

@@ -0,0 +1,201 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/OpenPeeDeeP/depguard v0.0.0-20180806142446-a69c782687b2/go.mod h1:7/4sitnI9YlQgTLLk734QlzXT8DuHVnAyztLplQjk+o=
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.6.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/go-critic/go-critic v0.0.0-20181204210945-1df300866540/go.mod h1:+sE8vrLDS2M0pZkBk0wy6+nLdKexVDrl/jBqQOTDThA=
github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTDqfpXvXAN0sXM=
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4=
github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ=
github.com/go-toolsmith/astequal v0.0.0-20180903214952-dcb477bfacd6/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY=
github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY=
github.com/go-toolsmith/astfmt v0.0.0-20180903215011-8f8ee99c3086/go.mod h1:mP93XdblcopXwlyN4X4uodxXQhldPGZbcEJIimQHrkg=
github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw=
github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU=
github.com/go-toolsmith/astp v0.0.0-20180903215135-0af7e3c24f30/go.mod h1:SV2ur98SGypH1UjcPpCatrV5hPazG6+IfNHbkDXBRrk=
github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI=
github.com/go-toolsmith/pkgload v0.0.0-20181119091011-e9e65178eee8/go.mod h1:WoMrjiy4zvdS+Bg6z9jZH82QXwkcgCBX6nOfnmdaHks=
github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc=
github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8=
github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.0.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4=
github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk=
github.com/golangci/errcheck v0.0.0-20181003203344-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0=
github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8=
github.com/golangci/go-tools v0.0.0-20180109140146-af6baa5dc196/go.mod h1:unzUULGw35sjyOYjUt0jMTXqHlZPpPc6e+xfO4cd6mM=
github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3/go.mod h1:JXrF4TWy4tXYn62/9x8Wm/K/dm06p8tCKwFRDPZG/1o=
github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee/go.mod h1:ozx7R9SIwqmqf5pRP90DhR2Oay2UIjGuKheCBCNwAYU=
github.com/golangci/gofmt v0.0.0-20181105071733-0b8337e80d98/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU=
github.com/golangci/golangci-lint v1.17.1/go.mod h1:+5sJSl2h3aly+fpmL2meSP8CaSKua2E4Twi9LPy7b1g=
github.com/golangci/gosec v0.0.0-20180901114220-66fb7fc33547/go.mod h1:0qUabqiIQgfmlAmulqxyiGkkyF6/tOGSnY2cnPVwrzU=
github.com/golangci/ineffassign v0.0.0-20180808204949-42439a7714cc/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU=
github.com/golangci/lint-1 v0.0.0-20180610141402-ee948d087217/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg=
github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o=
github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA=
github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21/go.mod h1:tf5+bzsHdTM0bsB7+8mt0GUMvjCgwLpTapNZHU8AajI=
github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4=
github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/kisielk/gotool v0.0.0-20161130080628-0de1eaf82fa3/go.mod h1:jxZFDH7ILpTPQTk+E2s+z4CUas9lVNjIuKR4c5/zKgM=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/magiconair/properties v1.7.6/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk=
github.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mozilla/tls-observatory v0.0.0-20180409132520-8791a200eb40/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
github.com/nbutton23/zxcvbn-go v0.0.0-20160627004424-a22cb81b2ecd/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
github.com/nbutton23/zxcvbn-go v0.0.0-20171102151520-eafdab6b0663/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/pelletier/go-toml v1.1.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI=
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE=
github.com/spf13/afero v1.1.0/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg=
github.com/spf13/cobra v0.0.2/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.0.2/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/timakin/bodyclose v0.0.0-20190407043127-4a873e97b2bb/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s=
github.com/valyala/quicktemplate v1.1.1/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20170915142106-8351a756f30f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20171026204733-164713f0dfce/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20170915090833-1cbadb444a80/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20170915040203-e531a2a1c15f/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190121143147-24cd39ecf745/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873 h1:nfPFGzJkUDX6uBmpN/pSw7MbOAWegH5QDQuoXFHedLg=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.22.1 h1:/7cs52RnTJmD43s3uxzlq2U7nqVTd/37viQwMrMNlOM=
google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
mvdan.cc/unparam v0.0.0-20190124213536-fbb59629db34/go.mod h1:H6SUd1XjIs+qQCyskXg5OFSrilMRUkD8ePJpHKDPaeY=
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=

View File

@@ -0,0 +1,95 @@
// Copyright 2019, 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 main
import (
"context"
"go.opentelemetry.io/api/key"
"go.opentelemetry.io/api/metric"
"go.opentelemetry.io/api/stats"
"go.opentelemetry.io/api/tag"
"go.opentelemetry.io/api/trace"
"go.opentelemetry.io/experimental/streaming/exporter/spanlog"
"go.opentelemetry.io/experimental/streaming/sdk"
)
var (
streaming = sdk.New(spanlog.New()).
WithComponent("example").
WithResources(
key.New("whatevs").String("yesss"),
)
tracer trace.Tracer = streaming
meter metric.Meter = metric.NoopMeter{}
fooKey = key.New("ex.com/foo")
barKey = key.New("ex.com/bar")
lemonsKey = key.New("ex.com/lemons")
anotherKey = key.New("ex.com/another")
oneMetric = metric.NewFloat64Gauge("ex.com/one",
metric.WithKeys(fooKey, barKey, lemonsKey),
metric.WithDescription("A gauge set to 1.0"),
)
measureTwo = stats.NewMeasure("ex.com/two")
)
func main() {
ctx := context.Background()
ctx = tag.NewContext(ctx,
tag.Insert(fooKey.String("foo1")),
tag.Insert(barKey.String("bar1")),
)
gauge := meter.GetFloat64Gauge(
ctx,
oneMetric,
lemonsKey.Int(10),
)
err := tracer.WithSpan(ctx, "operation", func(ctx context.Context) error {
trace.CurrentSpan(ctx).AddEvent(ctx, "Nice operation!", key.New("bogons").Int(100))
trace.CurrentSpan(ctx).SetAttributes(anotherKey.String("yes"))
gauge.Set(ctx, 1)
return tracer.WithSpan(
ctx,
"Sub operation...",
func(ctx context.Context) error {
trace.CurrentSpan(ctx).SetAttribute(lemonsKey.String("five"))
trace.CurrentSpan(ctx).AddEvent(ctx, "Sub span event")
stats.Record(ctx, measureTwo.M(1.3))
return nil
},
)
})
if err != nil {
panic(err)
}
// TODO: How to flush?
// loader.Flush()
}

View File

@@ -18,21 +18,21 @@ import (
"sync" "sync"
"sync/atomic" "sync/atomic"
"go.opentelemetry.io/experimental/streaming/exporter/observer" "go.opentelemetry.io/experimental/streaming/exporter"
) )
type Buffer struct { type Buffer struct {
observers []observer.Observer observers []exporter.Observer
events chan observer.Event events chan exporter.Event
dropped uint64 dropped uint64
wait sync.WaitGroup wait sync.WaitGroup
close chan struct{} close chan struct{}
} }
func NewBuffer(size int, observers ...observer.Observer) *Buffer { func NewBuffer(size int, observers ...exporter.Observer) *Buffer {
b := &Buffer{ b := &Buffer{
observers: observers, observers: observers,
events: make(chan observer.Event, size), events: make(chan exporter.Event, size),
close: make(chan struct{}), close: make(chan struct{}),
} }
b.wait.Add(1) b.wait.Add(1)
@@ -40,7 +40,7 @@ func NewBuffer(size int, observers ...observer.Observer) *Buffer {
return b return b
} }
func (b *Buffer) Observe(data observer.Event) { func (b *Buffer) Observe(data exporter.Event) {
select { select {
case b.events <- data: case b.events <- data:
default: default:

View File

@@ -1,6 +1,6 @@
// Code generated by "stringer -type=EventType"; DO NOT EDIT. // Code generated by "stringer -type=EventType"; DO NOT EDIT.
package observer package exporter
import "strconv" import "strconv"

View File

@@ -0,0 +1,114 @@
package exporter
import (
"context"
"sync/atomic"
"time"
"google.golang.org/grpc/codes"
"go.opentelemetry.io/api/core"
"go.opentelemetry.io/api/stats"
"go.opentelemetry.io/api/tag"
)
type EventType int
type EventID uint64
type ScopeID struct {
EventID
core.SpanContext
}
type Event struct {
// Automatic fields
Sequence EventID // Auto-filled
Time time.Time // Auto-filled
// Type, Scope, Context
Type EventType // All events
Scope ScopeID // All events
Context context.Context // core.FromContext() and scope.Active()
// Arguments (type-specific)
Attribute core.KeyValue // SET_ATTRIBUTE
Attributes []core.KeyValue // SET_ATTRIBUTES
Mutator tag.Mutator // SET_ATTRIBUTE
Mutators []tag.Mutator // SET_ATTRIBUTES
Recovered interface{} // FINISH_SPAN
Status codes.Code // SET_STATUS
// Values
String string // START_SPAN, EVENT, SET_NAME, ...
Float64 float64
Parent ScopeID // START_SPAN
Stats []stats.Measurement
Stat stats.Measurement
}
type Observer interface {
Observe(data Event)
}
//go:generate stringer -type=EventType
const (
INVALID EventType = iota
START_SPAN
FINISH_SPAN
ADD_EVENT
ADD_EVENTF
NEW_SCOPE
NEW_MEASURE
NEW_METRIC
MODIFY_ATTR
RECORD_STATS
SET_STATUS
SET_NAME
)
type Exporter struct {
sequence uint64
observers []Observer
}
func NewExporter(observers ...Observer) *Exporter {
return &Exporter{
observers: observers,
}
}
func (e *Exporter) NextEventID() EventID {
return EventID(atomic.AddUint64(&e.sequence, 1))
}
func (e *Exporter) Record(event Event) EventID {
if event.Sequence == 0 {
event.Sequence = e.NextEventID()
}
if event.Time.IsZero() {
event.Time = time.Now()
}
for _, observer := range e.observers {
observer.Observe(event)
}
return event.Sequence
}
func (e *Exporter) Foreach(f func(Observer)) {
for _, observer := range e.observers {
f(observer)
}
}
func (e *Exporter) NewScope(parent ScopeID, attributes ...core.KeyValue) ScopeID {
eventID := e.Record(Event{
Type: NEW_SCOPE,
Scope: parent,
Attributes: attributes,
})
return ScopeID{
EventID: eventID,
SpanContext: parent.SpanContext,
}
}

View File

@@ -1,15 +0,0 @@
// Copyright 2019, 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 loader // import "go.opentelemetry.io/experimental/streaming/exporter/loader"

View File

@@ -1,56 +0,0 @@
// Copyright 2019, 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 loader
import (
"fmt"
"os"
"plugin"
"time"
"go.opentelemetry.io/experimental/streaming/exporter/observer"
)
// TODO add buffer support directly, eliminate stdout
func init() {
pluginName := os.Getenv("OPENTELEMETRY_LIB")
if pluginName == "" {
return
}
sharedObj, err := plugin.Open(pluginName)
if err != nil {
fmt.Println("Open failed", pluginName, err)
return
}
obsPlugin, err := sharedObj.Lookup("Observer")
if err != nil {
fmt.Println("Observer not found", pluginName, err)
return
}
f, ok := obsPlugin.(func() observer.Observer)
if !ok {
fmt.Printf("Observer not valid\n")
return
}
observer.RegisterObserver(f())
}
func Flush() {
// TODO implement for exporter/{stdout,stderr,buffer}
time.Sleep(1 * time.Second)
}

View File

@@ -1,15 +0,0 @@
// Copyright 2019, 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 observer // import "go.opentelemetry.io/experimental/streaming/exporter/observer"

View File

@@ -1,163 +0,0 @@
// Copyright 2019, 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 observer
import (
"context"
"sync"
"sync/atomic"
"time"
"google.golang.org/grpc/codes"
"go.opentelemetry.io/api/core"
"go.opentelemetry.io/api/stats"
"go.opentelemetry.io/api/tag"
)
type EventType int
type EventID uint64
type ScopeID struct {
EventID
core.SpanContext
}
type Event struct {
// Automatic fields
Sequence EventID // Auto-filled
Time time.Time // Auto-filled
// Type, Scope, Context
Type EventType // All events
Scope ScopeID // All events
Context context.Context // core.FromContext() and scope.Active()
// Arguments (type-specific)
Attribute core.KeyValue // SET_ATTRIBUTE
Attributes []core.KeyValue // SET_ATTRIBUTES
Mutator tag.Mutator // SET_ATTRIBUTE
Mutators []tag.Mutator // SET_ATTRIBUTES
Recovered interface{} // FINISH_SPAN
Status codes.Code // SET_STATUS
// Values
String string // START_SPAN, EVENT, SET_NAME, ...
Float64 float64
Parent ScopeID // START_SPAN
Stats []stats.Measurement
Stat stats.Measurement
}
type Observer interface {
Observe(data Event)
}
type observersMap map[Observer]struct{}
//go:generate stringer -type=EventType
const (
// TODO: rename these NOUN_VERB
INVALID EventType = iota
START_SPAN
FINISH_SPAN
ADD_EVENT
ADD_EVENTF
NEW_SCOPE
NEW_MEASURE
NEW_METRIC
MODIFY_ATTR
RECORD_STATS
SET_STATUS
SET_NAME
)
var (
observerMu sync.Mutex
observers atomic.Value
sequenceNum uint64
)
func NextEventID() EventID {
return EventID(atomic.AddUint64(&sequenceNum, 1))
}
// RegisterObserver adds to the list of Observers that will receive sampled
// trace spans.
//
// Binaries can register observers, libraries shouldn't register observers.
func RegisterObserver(e Observer) {
observerMu.Lock()
new := make(observersMap)
if old, ok := observers.Load().(observersMap); ok {
for k, v := range old {
new[k] = v
}
}
new[e] = struct{}{}
observers.Store(new)
observerMu.Unlock()
}
// UnregisterObserver removes from the list of Observers the Observer that was
// registered with the given name.
func UnregisterObserver(e Observer) {
observerMu.Lock()
new := make(observersMap)
if old, ok := observers.Load().(observersMap); ok {
for k, v := range old {
new[k] = v
}
}
delete(new, e)
observers.Store(new)
observerMu.Unlock()
}
func Record(event Event) EventID {
if event.Sequence == 0 {
event.Sequence = NextEventID()
}
if event.Time.IsZero() {
event.Time = time.Now()
}
observers, _ := observers.Load().(observersMap)
for observer := range observers {
observer.Observe(event)
}
return event.Sequence
}
func Foreach(f func(Observer)) {
observers, _ := observers.Load().(observersMap)
for observer := range observers {
f(observer)
}
}
func NewScope(parent ScopeID, attributes ...core.KeyValue) ScopeID {
eventID := Record(Event{
Type: NEW_SCOPE,
Scope: parent,
Attributes: attributes,
})
return ScopeID{
EventID: eventID,
SpanContext: parent.SpanContext,
}
}

View File

@@ -24,7 +24,7 @@ import (
"go.opentelemetry.io/api/core" "go.opentelemetry.io/api/core"
"go.opentelemetry.io/api/stats" "go.opentelemetry.io/api/stats"
"go.opentelemetry.io/api/tag" "go.opentelemetry.io/api/tag"
"go.opentelemetry.io/experimental/streaming/exporter/observer" "go.opentelemetry.io/experimental/streaming/exporter"
) )
type Reader interface { type Reader interface {
@@ -36,7 +36,7 @@ type EventType int
type Event struct { type Event struct {
Type EventType Type EventType
Time time.Time Time time.Time
Sequence observer.EventID Sequence exporter.EventID
SpanContext core.SpanContext SpanContext core.SpanContext
Tags tag.Map Tags tag.Map
Attributes tag.Map Attributes tag.Map
@@ -90,7 +90,7 @@ type readerMetric struct {
type readerScope struct { type readerScope struct {
span *readerSpan span *readerSpan
parent observer.EventID parent exporter.EventID
attributes tag.Map attributes tag.Map
} }
@@ -109,18 +109,18 @@ const (
// necessary state needed by a reader to process events in memory. // necessary state needed by a reader to process events in memory.
// Practically, this means tracking live metric handles and scope // Practically, this means tracking live metric handles and scope
// attribute sets. // attribute sets.
func NewReaderObserver(readers ...Reader) observer.Observer { func NewReaderObserver(readers ...Reader) exporter.Observer {
return &readerObserver{ return &readerObserver{
readers: readers, readers: readers,
} }
} }
func (ro *readerObserver) Observe(event observer.Event) { func (ro *readerObserver) Observe(event exporter.Event) {
// TODO this should check for out-of-order events and buffer. // TODO this should check for out-of-order events and buffer.
ro.orderedObserve(event) ro.orderedObserve(event)
} }
func (ro *readerObserver) orderedObserve(event observer.Event) { func (ro *readerObserver) orderedObserve(event exporter.Event) {
read := Event{ read := Event{
Time: event.Time, Time: event.Time,
Sequence: event.Sequence, Sequence: event.Sequence,
@@ -133,7 +133,7 @@ func (ro *readerObserver) orderedObserve(event observer.Event) {
} }
switch event.Type { switch event.Type {
case observer.START_SPAN: case exporter.START_SPAN:
// Save the span context tags, initial attributes, start time, and name. // Save the span context tags, initial attributes, start time, and name.
span := &readerSpan{ span := &readerSpan{
name: event.String, name: event.String,
@@ -170,7 +170,7 @@ func (ro *readerObserver) orderedObserve(event observer.Event) {
ro.scopes.Store(event.Sequence, span) ro.scopes.Store(event.Sequence, span)
case observer.FINISH_SPAN: case exporter.FINISH_SPAN:
attrs, span := ro.readScope(event.Scope) attrs, span := ro.readScope(event.Scope)
if span == nil { if span == nil {
panic(fmt.Sprint("span not found", event.Scope)) panic(fmt.Sprint("span not found", event.Scope))
@@ -186,7 +186,7 @@ func (ro *readerObserver) orderedObserve(event observer.Event) {
// TODO: recovered // TODO: recovered
case observer.NEW_SCOPE, observer.MODIFY_ATTR: case exporter.NEW_SCOPE, exporter.MODIFY_ATTR:
var span *readerSpan var span *readerSpan
var m tag.Map var m tag.Map
@@ -223,7 +223,7 @@ func (ro *readerObserver) orderedObserve(event observer.Event) {
ro.scopes.Store(event.Sequence, sc) ro.scopes.Store(event.Sequence, sc)
if event.Type == observer.NEW_SCOPE { if event.Type == exporter.NEW_SCOPE {
return return
} }
@@ -235,14 +235,14 @@ func (ro *readerObserver) orderedObserve(event observer.Event) {
read.Tags = span.startTags read.Tags = span.startTags
} }
case observer.NEW_MEASURE: case exporter.NEW_MEASURE:
measure := &readerMeasure{ measure := &readerMeasure{
name: event.String, name: event.String,
} }
ro.measures.Store(event.Sequence, measure) ro.measures.Store(event.Sequence, measure)
return return
case observer.NEW_METRIC: case exporter.NEW_METRIC:
measureI, has := ro.measures.Load(event.Scope.EventID) measureI, has := ro.measures.Load(event.Scope.EventID)
if !has { if !has {
panic("metric measure not found") panic("metric measure not found")
@@ -253,7 +253,7 @@ func (ro *readerObserver) orderedObserve(event observer.Event) {
ro.metrics.Store(event.Sequence, metric) ro.metrics.Store(event.Sequence, metric)
return return
case observer.ADD_EVENT: case exporter.ADD_EVENT:
read.Type = ADD_EVENT read.Type = ADD_EVENT
read.Message = event.String read.Message = event.String
@@ -265,7 +265,7 @@ func (ro *readerObserver) orderedObserve(event observer.Event) {
read.SpanContext = span.spanContext read.SpanContext = span.spanContext
} }
case observer.RECORD_STATS: case exporter.RECORD_STATS:
read.Type = RECORD_STATS read.Type = RECORD_STATS
_, span := ro.readScope(event.Scope) _, span := ro.readScope(event.Scope)
@@ -279,7 +279,7 @@ func (ro *readerObserver) orderedObserve(event observer.Event) {
ro.addMeasurement(&read, event.Stat) ro.addMeasurement(&read, event.Stat)
} }
case observer.SET_STATUS: case exporter.SET_STATUS:
read.Type = SET_STATUS read.Type = SET_STATUS
read.Status = event.Status read.Status = event.Status
_, span := ro.readScope(event.Scope) _, span := ro.readScope(event.Scope)
@@ -288,7 +288,7 @@ func (ro *readerObserver) orderedObserve(event observer.Event) {
read.SpanContext = span.spanContext read.SpanContext = span.spanContext
} }
case observer.SET_NAME: case exporter.SET_NAME:
read.Type = SET_NAME read.Type = SET_NAME
read.Name = event.String read.Name = event.String
@@ -300,7 +300,7 @@ func (ro *readerObserver) orderedObserve(event observer.Event) {
reader.Read(read) reader.Read(read)
} }
if event.Type == observer.FINISH_SPAN { if event.Type == exporter.FINISH_SPAN {
ro.cleanupSpan(event.Scope.EventID) ro.cleanupSpan(event.Scope.EventID)
} }
} }
@@ -319,7 +319,7 @@ func (ro *readerObserver) readMeasureScope(m stats.Measure) (tag.Map, *readerSpa
return tag.NewEmptyMap(), nil return tag.NewEmptyMap(), nil
} }
func (ro *readerObserver) readScope(id observer.ScopeID) (tag.Map, *readerSpan) { func (ro *readerObserver) readScope(id exporter.ScopeID) (tag.Map, *readerSpan) {
if id.EventID == 0 { if id.EventID == 0 {
return tag.NewEmptyMap(), nil return tag.NewEmptyMap(), nil
} }
@@ -335,7 +335,7 @@ func (ro *readerObserver) readScope(id observer.ScopeID) (tag.Map, *readerSpan)
return tag.NewEmptyMap(), nil return tag.NewEmptyMap(), nil
} }
func (ro *readerObserver) cleanupSpan(id observer.EventID) { func (ro *readerObserver) cleanupSpan(id exporter.EventID) {
for id != 0 { for id != 0 {
ev, has := ro.scopes.Load(id) ev, has := ro.scopes.Load(id)
if !has { if !has {

View File

@@ -16,7 +16,7 @@ package spandata
import ( import (
"go.opentelemetry.io/api/core" "go.opentelemetry.io/api/core"
"go.opentelemetry.io/experimental/streaming/exporter/observer" "go.opentelemetry.io/experimental/streaming/exporter"
"go.opentelemetry.io/experimental/streaming/exporter/reader" "go.opentelemetry.io/experimental/streaming/exporter/reader"
) )
@@ -33,7 +33,7 @@ type spanReader struct {
readers []Reader readers []Reader
} }
func NewReaderObserver(readers ...Reader) observer.Observer { func NewReaderObserver(readers ...Reader) exporter.Observer {
return reader.NewReaderObserver(&spanReader{ return reader.NewReaderObserver(&spanReader{
spans: map[core.SpanContext]*Span{}, spans: map[core.SpanContext]*Span{},
readers: readers, readers: readers,

View File

@@ -1,30 +0,0 @@
// Copyright 2019, 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 install // import "go.opentelemetry.io/experimental/streaming/exporter/spanlog/install"
import (
"go.opentelemetry.io/experimental/streaming/exporter/observer"
"go.opentelemetry.io/experimental/streaming/exporter/spanlog"
)
// Use this import:
//
// import _ "go.opentelemetry.io/experimental/streaming/exporter/spanlog/install"
//
// to include the spanlog exporter by default.
func init() {
observer.RegisterObserver(spanlog.New())
}

View File

@@ -1,4 +0,0 @@
.PHONY: module
module:
go build -buildmode=plugin -o spanlog.so package.go

View File

@@ -1,32 +0,0 @@
// Copyright 2019, 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 main // import "go.opentelemetry.io/experimental/streaming/exporter/spanlog/plugin"
import (
"go.opentelemetry.io/experimental/streaming/exporter/observer"
"go.opentelemetry.io/experimental/streaming/exporter/spanlog"
)
var (
spanlogObs = spanlog.New()
)
func Observer() observer.Observer {
return spanlogObs
}
func main() {
_ = Observer()
}

View File

@@ -18,14 +18,14 @@ import (
"os" "os"
"strings" "strings"
"go.opentelemetry.io/experimental/streaming/exporter/observer" "go.opentelemetry.io/experimental/streaming/exporter"
"go.opentelemetry.io/experimental/streaming/exporter/spandata" "go.opentelemetry.io/experimental/streaming/exporter/spandata"
"go.opentelemetry.io/experimental/streaming/exporter/spandata/format" "go.opentelemetry.io/experimental/streaming/exporter/spandata/format"
) )
type spanLog struct{} type spanLog struct{}
func New() observer.Observer { func New() exporter.Observer {
return spandata.NewReaderObserver(&spanLog{}) return spandata.NewReaderObserver(&spanLog{})
} }

View File

@@ -1,30 +0,0 @@
// Copyright 2019, 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 install // import "go.opentelemetry.io/experimental/streaming/exporter/stderr/install"
import (
"go.opentelemetry.io/experimental/streaming/exporter/observer"
"go.opentelemetry.io/experimental/streaming/exporter/stderr"
)
// Use this import:
//
// import _ "go.opentelemetry.io/experimental/streaming/exporter/stderr/install"
//
// to include the stderr exporter by default.
func init() {
observer.RegisterObserver(stderr.New())
}

View File

@@ -1,4 +0,0 @@
.PHONY: module
module:
go build -buildmode=plugin -o stderr.so package.go

View File

@@ -1,32 +0,0 @@
// Copyright 2019, 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 main // "go.opentelemetry.io/experimental/streaming/exporter/stderr/plugin"
import (
"go.opentelemetry.io/experimental/streaming/exporter/observer"
"go.opentelemetry.io/experimental/streaming/exporter/stderr"
)
var (
stderrObs = stderr.New()
)
func Observer() observer.Observer {
return stderrObs
}
func main() {
_ = Observer()
}

View File

@@ -17,14 +17,14 @@ package stderr // import "go.opentelemetry.io/experimental/streaming/exporter/st
import ( import (
"os" "os"
"go.opentelemetry.io/experimental/streaming/exporter/observer" "go.opentelemetry.io/experimental/streaming/exporter"
"go.opentelemetry.io/experimental/streaming/exporter/reader" "go.opentelemetry.io/experimental/streaming/exporter/reader"
"go.opentelemetry.io/experimental/streaming/exporter/reader/format" "go.opentelemetry.io/experimental/streaming/exporter/reader/format"
) )
type stderrLog struct{} type stderrLog struct{}
func New() observer.Observer { func New() exporter.Observer {
return reader.NewReaderObserver(&stderrLog{}) return reader.NewReaderObserver(&stderrLog{})
} }

View File

@@ -1,30 +0,0 @@
// Copyright 2019, 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 install // import "go.opentelemetry.io/experimental/streaming/exporter/stdout/install"
import (
"go.opentelemetry.io/experimental/streaming/exporter/observer"
"go.opentelemetry.io/experimental/streaming/exporter/stdout"
)
// Use this import:
//
// import _ "go.opentelemetry.io/experimental/streaming/exporter/stdout/install"
//
// to include the stderr exporter by default.
func init() {
observer.RegisterObserver(stdout.New())
}

View File

@@ -1,4 +0,0 @@
.PHONY: module
module:
go build -buildmode=plugin -o stdout.so package.go

View File

@@ -1,32 +0,0 @@
// Copyright 2019, 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 main // import "go.opentelemetry.io/experimental/streaming/exporter/stdout/plugin"
import (
"go.opentelemetry.io/experimental/streaming/exporter/observer"
"go.opentelemetry.io/experimental/streaming/exporter/stdout"
)
var (
stdoutObs = stdout.New()
)
func Observer() observer.Observer {
return stdoutObs
}
func main() {
_ = Observer()
}

View File

@@ -17,14 +17,14 @@ package stdout // import "go.opentelemetry.io/experimental/streaming/exporter/st
import ( import (
"os" "os"
"go.opentelemetry.io/experimental/streaming/exporter/observer" "go.opentelemetry.io/experimental/streaming/exporter"
"go.opentelemetry.io/experimental/streaming/exporter/reader" "go.opentelemetry.io/experimental/streaming/exporter/reader"
"go.opentelemetry.io/experimental/streaming/exporter/reader/format" "go.opentelemetry.io/experimental/streaming/exporter/reader/format"
) )
type stdoutLog struct{} type stdoutLog struct{}
func New() observer.Observer { func New() exporter.Observer {
return reader.NewReaderObserver(&stdoutLog{}) return reader.NewReaderObserver(&stdoutLog{})
} }

View File

@@ -14,45 +14,28 @@
package internal // import "go.opentelemetry.io/experimental/streaming/sdk/internal" package internal // import "go.opentelemetry.io/experimental/streaming/sdk/internal"
import ( import "go.opentelemetry.io/experimental/streaming/exporter"
"go.opentelemetry.io/experimental/streaming/exporter/observer"
)
type eventsMap map[observer.EventType][]observer.Event type eventsMap map[exporter.EventType][]exporter.Event
type TestObserver struct { type TestObserver struct {
events eventsMap events eventsMap
} }
var _ observer.Observer = &TestObserver{} var _ exporter.Observer = &TestObserver{}
func NewRegisteredObserver() *TestObserver { func NewTestObserver() *TestObserver {
o := &TestObserver{} return &TestObserver{}
observer.RegisterObserver(o)
return o
} }
func (o *TestObserver) Unregister() { func (o *TestObserver) Observe(e exporter.Event) {
observer.UnregisterObserver(o)
}
func (o *TestObserver) Observe(e observer.Event) {
if o.events == nil { if o.events == nil {
o.events = make(eventsMap) o.events = make(eventsMap)
} }
o.events[e.Type] = append(o.events[e.Type], e) o.events[e.Type] = append(o.events[e.Type], e)
} }
func (o *TestObserver) Clear() { func (o *TestObserver) Events(eType exporter.EventType) []exporter.Event {
o.events = nil
}
func (o *TestObserver) ClearAndUnregister() {
o.Clear()
o.Unregister()
}
func (o *TestObserver) Events(eType observer.EventType) []observer.Event {
if o.events == nil { if o.events == nil {
return nil return nil
} }

View File

@@ -1,9 +0,0 @@
package sdk
import (
"go.opentelemetry.io/api/trace"
)
func init() {
trace.SetGlobalTracer(New())
}

View File

@@ -22,13 +22,13 @@ import (
"go.opentelemetry.io/api/core" "go.opentelemetry.io/api/core"
"go.opentelemetry.io/api/tag" "go.opentelemetry.io/api/tag"
apitrace "go.opentelemetry.io/api/trace" "go.opentelemetry.io/api/trace"
"go.opentelemetry.io/experimental/streaming/exporter/observer" "go.opentelemetry.io/experimental/streaming/exporter"
) )
type span struct { type span struct {
tracer *tracer tracer *tracer
initial observer.ScopeID initial exporter.ScopeID
} }
// SpancContext returns span context of the span. Return SpanContext is usable // SpancContext returns span context of the span. Return SpanContext is usable
@@ -44,58 +44,58 @@ func (sp *span) IsRecordingEvents() bool {
// SetStatus sets the status of the span. // SetStatus sets the status of the span.
func (sp *span) SetStatus(status codes.Code) { func (sp *span) SetStatus(status codes.Code) {
observer.Record(observer.Event{ sp.tracer.exporter.Record(exporter.Event{
Type: observer.SET_STATUS, Type: exporter.SET_STATUS,
Scope: sp.ScopeID(), Scope: sp.ScopeID(),
Status: status, Status: status,
}) })
} }
func (sp *span) ScopeID() observer.ScopeID { func (sp *span) ScopeID() exporter.ScopeID {
return sp.initial return sp.initial
} }
func (sp *span) SetAttribute(attribute core.KeyValue) { func (sp *span) SetAttribute(attribute core.KeyValue) {
observer.Record(observer.Event{ sp.tracer.exporter.Record(exporter.Event{
Type: observer.MODIFY_ATTR, Type: exporter.MODIFY_ATTR,
Scope: sp.ScopeID(), Scope: sp.ScopeID(),
Attribute: attribute, Attribute: attribute,
}) })
} }
func (sp *span) SetAttributes(attributes ...core.KeyValue) { func (sp *span) SetAttributes(attributes ...core.KeyValue) {
observer.Record(observer.Event{ sp.tracer.exporter.Record(exporter.Event{
Type: observer.MODIFY_ATTR, Type: exporter.MODIFY_ATTR,
Scope: sp.ScopeID(), Scope: sp.ScopeID(),
Attributes: attributes, Attributes: attributes,
}) })
} }
func (sp *span) ModifyAttribute(mutator tag.Mutator) { func (sp *span) ModifyAttribute(mutator tag.Mutator) {
observer.Record(observer.Event{ sp.tracer.exporter.Record(exporter.Event{
Type: observer.MODIFY_ATTR, Type: exporter.MODIFY_ATTR,
Scope: sp.ScopeID(), Scope: sp.ScopeID(),
Mutator: mutator, Mutator: mutator,
}) })
} }
func (sp *span) ModifyAttributes(mutators ...tag.Mutator) { func (sp *span) ModifyAttributes(mutators ...tag.Mutator) {
observer.Record(observer.Event{ sp.tracer.exporter.Record(exporter.Event{
Type: observer.MODIFY_ATTR, Type: exporter.MODIFY_ATTR,
Scope: sp.ScopeID(), Scope: sp.ScopeID(),
Mutators: mutators, Mutators: mutators,
}) })
} }
func (sp *span) Finish(options ...apitrace.FinishOption) { func (sp *span) Finish(options ...trace.FinishOption) {
recovered := recover() recovered := recover()
opts := apitrace.FinishOptions{} opts := trace.FinishOptions{}
for _, opt := range options { for _, opt := range options {
opt(&opts) opt(&opts)
} }
observer.Record(observer.Event{ sp.tracer.exporter.Record(exporter.Event{
Time: opts.FinishTime, Time: opts.FinishTime,
Type: observer.FINISH_SPAN, Type: exporter.FINISH_SPAN,
Scope: sp.ScopeID(), Scope: sp.ScopeID(),
Recovered: recovered, Recovered: recovered,
}) })
@@ -104,7 +104,7 @@ func (sp *span) Finish(options ...apitrace.FinishOption) {
} }
} }
func (sp *span) Tracer() apitrace.Tracer { func (sp *span) Tracer() trace.Tracer {
return sp.tracer return sp.tracer
} }
@@ -113,9 +113,9 @@ func (sp *span) AddEvent(ctx context.Context, msg string, attrs ...core.KeyValue
} }
func (sp *span) addEventWithTime(ctx context.Context, timestamp time.Time, msg string, attrs ...core.KeyValue) { func (sp *span) addEventWithTime(ctx context.Context, timestamp time.Time, msg string, attrs ...core.KeyValue) {
observer.Record(observer.Event{ sp.tracer.exporter.Record(exporter.Event{
Time: timestamp, Time: timestamp,
Type: observer.ADD_EVENT, Type: exporter.ADD_EVENT,
String: msg, String: msg,
Attributes: attrs, Attributes: attrs,
Context: ctx, Context: ctx,
@@ -123,13 +123,13 @@ func (sp *span) addEventWithTime(ctx context.Context, timestamp time.Time, msg s
} }
func (sp *span) SetName(name string) { func (sp *span) SetName(name string) {
observer.Record(observer.Event{ sp.tracer.exporter.Record(exporter.Event{
Type: observer.SET_NAME, Type: exporter.SET_NAME,
String: name, String: name,
}) })
} }
func (sp *span) AddLink(link apitrace.Link) { func (sp *span) AddLink(link trace.Link) {
} }
func (sp *span) Link(sc core.SpanContext, attrs ...core.KeyValue) { func (sp *span) Link(sc core.SpanContext, attrs ...core.KeyValue) {

View File

@@ -26,17 +26,16 @@ import (
"go.opentelemetry.io/api/key" "go.opentelemetry.io/api/key"
"go.opentelemetry.io/api/trace" "go.opentelemetry.io/api/trace"
"go.opentelemetry.io/experimental/streaming/exporter/observer" "go.opentelemetry.io/experimental/streaming/exporter"
"go.opentelemetry.io/experimental/streaming/sdk/internal" "go.opentelemetry.io/experimental/streaming/sdk/internal"
) )
func TestEvents(t *testing.T) { func TestEvents(t *testing.T) {
_ = New().WithSpan(context.Background(), "test", func(ctx context.Context) error { obs := internal.NewTestObserver()
_ = New(obs).WithSpan(context.Background(), "test", func(ctx context.Context) error {
type test1Type struct{} type test1Type struct{}
type test2Type struct{} type test2Type struct{}
span := trace.CurrentSpan(ctx) span := trace.CurrentSpan(ctx)
obs := internal.NewRegisteredObserver()
defer obs.ClearAndUnregister()
k1v1 := key.New("k1").String("v1") k1v1 := key.New("k1").String("v1")
k2v2 := key.New("k2").String("v2") k2v2 := key.New("k2").String("v2")
k3v3 := key.New("k3").String("v3") k3v3 := key.New("k3").String("v3")
@@ -45,7 +44,7 @@ func TestEvents(t *testing.T) {
ctx2 := context.WithValue(ctx1, test2Type{}, "foo") ctx2 := context.WithValue(ctx1, test2Type{}, "foo")
span.AddEvent(ctx2, "testing", k2v2, k3v3) span.AddEvent(ctx2, "testing", k2v2, k3v3)
got := obs.Events(observer.ADD_EVENT) got := obs.Events(exporter.ADD_EVENT)
for idx := range got { for idx := range got {
if got[idx].Time.IsZero() { if got[idx].Time.IsZero() {
t.Errorf("Event %d has zero timestamp", idx) t.Errorf("Event %d has zero timestamp", idx)
@@ -55,14 +54,14 @@ func TestEvents(t *testing.T) {
if len(got) != 2 { if len(got) != 2 {
t.Errorf("Expected two events, got %d", len(got)) t.Errorf("Expected two events, got %d", len(got))
} }
want := []observer.Event{ want := []exporter.Event{
{ {
Type: observer.ADD_EVENT, Type: exporter.ADD_EVENT,
String: "one two three", String: "one two three",
Attributes: []core.KeyValue{k1v1}, Attributes: []core.KeyValue{k1v1},
}, },
{ {
Type: observer.ADD_EVENT, Type: exporter.ADD_EVENT,
String: "testing", String: "testing",
Attributes: []core.KeyValue{k2v2, k3v3}, Attributes: []core.KeyValue{k2v2, k3v3},
}, },
@@ -80,27 +79,26 @@ func TestEvents(t *testing.T) {
func TestCustomStartEndTime(t *testing.T) { func TestCustomStartEndTime(t *testing.T) {
startTime := time.Date(2019, time.August, 27, 14, 42, 0, 0, time.UTC) startTime := time.Date(2019, time.August, 27, 14, 42, 0, 0, time.UTC)
endTime := startTime.Add(time.Second * 20) endTime := startTime.Add(time.Second * 20)
tracer := New() obs := internal.NewTestObserver()
obs := internal.NewRegisteredObserver() tracer := New(obs)
defer obs.ClearAndUnregister()
_, span := tracer.Start( _, span := tracer.Start(
context.Background(), context.Background(),
"testspan", "testspan",
trace.WithStartTime(startTime), trace.WithStartTime(startTime),
) )
span.Finish(trace.WithFinishTime(endTime)) span.Finish(trace.WithFinishTime(endTime))
want := []observer.Event{ want := []exporter.Event{
{ {
Type: observer.START_SPAN, Type: exporter.START_SPAN,
Time: startTime, Time: startTime,
String: "testspan", String: "testspan",
}, },
{ {
Type: observer.FINISH_SPAN, Type: exporter.FINISH_SPAN,
Time: endTime, Time: endTime,
}, },
} }
got := append(obs.Events(observer.START_SPAN), obs.Events(observer.FINISH_SPAN)...) got := append(obs.Events(exporter.START_SPAN), obs.Events(exporter.FINISH_SPAN)...)
diffEvents(t, got, want, "Scope") diffEvents(t, got, want, "Scope")
} }
@@ -129,7 +127,7 @@ func checkContext(t *testing.T, ctx context.Context, key, wantValue interface{})
return true return true
} }
func diffEvents(t *testing.T, got, want []observer.Event, extraIgnoredFields ...string) bool { func diffEvents(t *testing.T, got, want []exporter.Event, extraIgnoredFields ...string) bool {
ignoredPaths := map[string]struct{}{ ignoredPaths := map[string]struct{}{
"Sequence": struct{}{}, "Sequence": struct{}{},
"Context": struct{}{}, "Context": struct{}{},

View File

@@ -21,12 +21,12 @@ import (
"go.opentelemetry.io/api/core" "go.opentelemetry.io/api/core"
"go.opentelemetry.io/api/key" "go.opentelemetry.io/api/key"
"go.opentelemetry.io/api/trace" "go.opentelemetry.io/api/trace"
apitrace "go.opentelemetry.io/api/trace" "go.opentelemetry.io/experimental/streaming/exporter"
"go.opentelemetry.io/experimental/streaming/exporter/observer"
) )
type tracer struct { type tracer struct {
resources observer.EventID exporter *exporter.Exporter
resources exporter.EventID
} }
var ( var (
@@ -39,24 +39,27 @@ var (
MessageKey = key.New("message") MessageKey = key.New("message")
) )
func New() trace.Tracer { func New(observers ...exporter.Observer) trace.Tracer {
return &tracer{} return &tracer{
exporter: exporter.NewExporter(observers...),
}
} }
func (t *tracer) WithResources(attributes ...core.KeyValue) apitrace.Tracer { func (t *tracer) WithResources(attributes ...core.KeyValue) trace.Tracer {
s := observer.NewScope(observer.ScopeID{ s := t.exporter.NewScope(exporter.ScopeID{
EventID: t.resources, EventID: t.resources,
}, attributes...) }, attributes...)
return &tracer{ return &tracer{
exporter: t.exporter,
resources: s.EventID, resources: s.EventID,
} }
} }
func (t *tracer) WithComponent(name string) apitrace.Tracer { func (t *tracer) WithComponent(name string) trace.Tracer {
return t.WithResources(ComponentKey.String(name)) return t.WithResources(ComponentKey.String(name))
} }
func (t *tracer) WithService(name string) apitrace.Tracer { func (t *tracer) WithService(name string) trace.Tracer {
return t.WithResources(ServiceKey.String(name)) return t.WithResources(ServiceKey.String(name))
} }
@@ -74,23 +77,23 @@ func (t *tracer) WithSpan(ctx context.Context, name string, body func(context.Co
return nil return nil
} }
func (t *tracer) Start(ctx context.Context, name string, opts ...apitrace.SpanOption) (context.Context, apitrace.Span) { func (t *tracer) Start(ctx context.Context, name string, opts ...trace.SpanOption) (context.Context, trace.Span) {
var child core.SpanContext var child core.SpanContext
child.SpanID = rand.Uint64() child.SpanID = rand.Uint64()
o := &apitrace.SpanOptions{} o := &trace.SpanOptions{}
for _, opt := range opts { for _, opt := range opts {
opt(o) opt(o)
} }
var parentScope observer.ScopeID var parentScope exporter.ScopeID
if o.Reference.HasTraceID() { if o.Reference.HasTraceID() {
parentScope.SpanContext = o.Reference.SpanContext parentScope.SpanContext = o.Reference.SpanContext
} else { } else {
parentScope.SpanContext = apitrace.CurrentSpan(ctx).SpanContext() parentScope.SpanContext = trace.CurrentSpan(ctx).SpanContext()
} }
if parentScope.HasTraceID() { if parentScope.HasTraceID() {
@@ -102,19 +105,19 @@ func (t *tracer) Start(ctx context.Context, name string, opts ...apitrace.SpanOp
child.TraceID.Low = rand.Uint64() child.TraceID.Low = rand.Uint64()
} }
childScope := observer.ScopeID{ childScope := exporter.ScopeID{
SpanContext: child, SpanContext: child,
EventID: t.resources, EventID: t.resources,
} }
span := &span{ span := &span{
tracer: t, tracer: t,
initial: observer.ScopeID{ initial: exporter.ScopeID{
SpanContext: child, SpanContext: child,
EventID: observer.Record(observer.Event{ EventID: t.exporter.Record(exporter.Event{
Time: o.StartTime, Time: o.StartTime,
Type: observer.START_SPAN, Type: exporter.START_SPAN,
Scope: observer.NewScope(childScope, o.Attributes...), Scope: t.exporter.NewScope(childScope, o.Attributes...),
Context: ctx, Context: ctx,
Parent: parentScope, Parent: parentScope,
String: name, String: name,