diff --git a/go.mod b/go.mod index f7f6f843f3..adf2f5c301 100644 --- a/go.mod +++ b/go.mod @@ -15,17 +15,25 @@ require ( github.com/google/go-cmp v0.5.5 github.com/google/uuid v1.1.2 github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 + github.com/hashicorp/go-uuid v1.0.1 // indirect github.com/nats-io/nats-streaming-server v0.17.0 github.com/nats-io/stan.go v0.6.0 github.com/networkservicemesh/api v0.0.0-20210617173100-f34297145219 github.com/open-policy-agent/opa v0.16.1 - github.com/opentracing/opentracing-go v1.1.0 + github.com/opentracing/opentracing-go v1.2.0 github.com/pkg/errors v0.9.1 github.com/sirupsen/logrus v1.7.0 github.com/spiffe/go-spiffe/v2 v2.0.0-alpha.4.0.20200528145730-dc11d0c74e85 github.com/stretchr/testify v1.7.0 - github.com/uber/jaeger-client-go v2.21.1+incompatible + github.com/uber/jaeger-client-go v2.25.0+incompatible github.com/uber/jaeger-lib v2.4.0+incompatible // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0 + go.opentelemetry.io/otel v0.20.0 + go.opentelemetry.io/otel/exporters/otlp v0.20.0 + go.opentelemetry.io/otel/metric v0.20.0 + go.opentelemetry.io/otel/sdk v0.20.0 + go.opentelemetry.io/otel/sdk/metric v0.20.0 + go.opentelemetry.io/otel/trace v0.20.0 go.uber.org/atomic v1.7.0 go.uber.org/goleak v1.1.10 golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect @@ -33,6 +41,6 @@ require ( golang.org/x/sys v0.0.0-20210603125802-9665404d3644 // indirect golang.org/x/tools v0.1.2 // indirect gonum.org/v1/gonum v0.6.2 - google.golang.org/grpc v1.35.0 + google.golang.org/grpc v1.37.0 google.golang.org/protobuf v1.26.0 ) diff --git a/go.sum b/go.sum index 73cb0deafb..36b618307b 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,6 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0 h1:eOI3/cP2VTU6uZLDYAoic+eyzzB9YyGmJ7eIjl8rOPg= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/HdrHistogram/hdrhistogram-go v1.0.1 h1:GX8GAYDuhlFQnI2fRDHQhTlkHMz8bEn0jTI6LJU0mpw= @@ -7,8 +9,10 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE github.com/OneOfOne/xxhash v1.2.3 h1:wS8NNaIgtzapuArKIAjsyXtEN/IUjQkbw90xszUdS40= github.com/OneOfOne/xxhash v1.2.3/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 h1:EFSB7Zo9Eg91v7MJPVsifUysc/wPdN+NOnVe6bWbdBM= github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= +github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -38,6 +42,7 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -68,6 +73,7 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= @@ -84,6 +90,8 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3 github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v0.0.0-20181024020800-521ea7b17d02/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= @@ -94,8 +102,9 @@ github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjh github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/raft v1.1.1 h1:HJr7UE1x/JrJSc9Oy6aDBHtNHUUBHjcQjTgvUVihoZs= @@ -141,8 +150,8 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/open-policy-agent/opa v0.16.1 h1:BDADmi1Xl08aPcubaYgSEU0lJ/zrWDwmFMRXVPX856c= github.com/open-policy-agent/opa v0.16.1/go.mod h1:P0xUE/GQAAgnvV537GzA0Ikw4+icPELRT327QJPkaKY= -github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/peterh/liner v0.0.0-20170211195444-bf27d3ba8e1d/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= @@ -164,6 +173,7 @@ github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLk github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= @@ -173,6 +183,7 @@ github.com/spf13/pflag v0.0.0-20181024212040-082b515c9490/go.mod h1:DYY7MBk1bdzu github.com/spiffe/go-spiffe/v2 v2.0.0-alpha.4.0.20200528145730-dc11d0c74e85 h1:+Rnw8UZdRsA7AMJZKApyDtXM6209d+ABW4oMHtOsXoU= github.com/spiffe/go-spiffe/v2 v2.0.0-alpha.4.0.20200528145730-dc11d0c74e85/go.mod h1:Z6jOEo3L49OpNaK5JTIOig6K9HJhwH6cb78MF5mothQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -182,8 +193,8 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/uber/jaeger-client-go v2.21.1+incompatible h1:oozboeZmWz+tyh3VZttJWlF3K73mHgbokieceqKccLo= -github.com/uber/jaeger-client-go v2.21.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-client-go v2.25.0+incompatible h1:IxcNZ7WRY1Y3G4poYlx24szfsn/3LvK9QHCq9oQw8+U= +github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.0+incompatible h1:fY7QsGQWiCt8pajv4r7JEvmATdCVaWxXbjwyYwsNaLQ= github.com/uber/jaeger-lib v2.4.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/yashtewari/glob-intersection v0.0.0-20180916065949-5c77d914dd0b h1:vVRagRXf67ESqAb72hG2C/ZwI8NtJF2u2V76EsuOHGY= @@ -193,6 +204,28 @@ github.com/zeebo/errs v1.2.2 h1:5NFypMTuSdoySVTqlNs1dEoU21QVamMQJxW/Fii5O7g= github.com/zeebo/errs v1.2.2/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.opentelemetry.io/contrib v0.20.0 h1:ubFQUn0VCZ0gPwIoJfBJVpeBlyRMxu8Mm/huKWYd9p0= +go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0 h1:sO4WKdPAudZGKPcpZT4MJn6JaDmpyLrMPDGGyA1SttE= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= +go.opentelemetry.io/otel v0.20.0 h1:eaP0Fqu7SXHwvjiqDq83zImeehOHX8doTvU9AwXON8g= +go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= +go.opentelemetry.io/otel/exporters/otlp v0.20.0 h1:PTNgq9MRmQqqJY0REVbZFvwkYOA85vbdQU/nVfxDyqg= +go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= +go.opentelemetry.io/otel/metric v0.20.0 h1:4kzhXFP+btKm4jwxpjIqjs41A7MakRFUS86bqLHTIw8= +go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= +go.opentelemetry.io/otel/oteltest v0.20.0 h1:HiITxCawalo5vQzdHfKeZurV8x7ljcqAgiWzF6Vaeaw= +go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= +go.opentelemetry.io/otel/sdk v0.20.0 h1:JsxtGXd06J8jrnya7fdI/U/MR6yXA5DtbZy+qoHQlr8= +go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= +go.opentelemetry.io/otel/sdk/export/metric v0.20.0 h1:c5VRjxCXdQlx1HjzwGdQHzZaVI82b5EbBgOu2ljD92g= +go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE= +go.opentelemetry.io/otel/sdk/metric v0.20.0 h1:7ao1wpzHRVKf0OQ7GIxiQJA6X7DLX9o14gmVon7mMK8= +go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= +go.opentelemetry.io/otel/trace v0.20.0 h1:1DL6EXUdcg95gukhuRRvLDO/4X5THh/5dIV52lqtnbw= +go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= +go.opentelemetry.io/proto/otlp v0.7.0 h1:rwOQPCuKAKmwGKq2aVNnYIibI6wnV7EvzgfTCzcdGg8= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= @@ -201,6 +234,7 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200206161412-a0c6ece9d31a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -219,17 +253,22 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r 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-20181201002055-351d144fa1fc/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-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/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-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -242,6 +281,7 @@ golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -278,10 +318,12 @@ gonum.org/v1/gonum v0.6.2/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.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-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -291,8 +333,10 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.35.0 h1:TwIQcH3es+MojMVojxxfQ3l3OF2KzlRxML2xZq0kRo8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0 h1:uSZWeQJX5j11bIQ4AJoj+McDBo29cY1MCoC1wO3ts+c= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -313,8 +357,9 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/square/go-jose.v2 v2.4.1 h1:H0TmLt7/KmzlrDOpa1F+zr0Tk90PbJYBfsVUmRLrf9Y= gopkg.in/square/go-jose.v2 v2.4.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3 h1:fvjTMHxHEw/mxHbtzPi3JCcKXQRAnQTBRo6YCJSVHKI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/pkg/networkservice/chains/nsmgr/server.go b/pkg/networkservice/chains/nsmgr/server.go index b85d47004e..dd83840db8 100644 --- a/pkg/networkservice/chains/nsmgr/server.go +++ b/pkg/networkservice/chains/nsmgr/server.go @@ -43,6 +43,7 @@ import ( "github.com/networkservicemesh/sdk/pkg/networkservice/common/interpose" "github.com/networkservicemesh/sdk/pkg/networkservice/common/mechanisms/recvfd" "github.com/networkservicemesh/sdk/pkg/networkservice/common/mechanisms/sendfd" + "github.com/networkservicemesh/sdk/pkg/networkservice/common/metrics" "github.com/networkservicemesh/sdk/pkg/networkservice/common/roundrobin" "github.com/networkservicemesh/sdk/pkg/networkservice/core/adapters" "github.com/networkservicemesh/sdk/pkg/registry" @@ -191,6 +192,7 @@ func NewServer(ctx context.Context, tokenGenerator token.GeneratorFunc, options roundrobin.NewServer(), excludedprefixes.NewServer(ctx), recvfd.NewServer(), // Receive any files passed + metrics.NewServer(), interpose.NewServer(&interposeRegistryServer), filtermechanisms.NewServer(&urlsRegistryServer), heal.NewServer(ctx, diff --git a/pkg/networkservice/common/metrics/server.go b/pkg/networkservice/common/metrics/server.go new file mode 100644 index 0000000000..77f9cae6f6 --- /dev/null +++ b/pkg/networkservice/common/metrics/server.go @@ -0,0 +1,74 @@ +// Copyright (c) 2021 Doc.ai and/or its affiliates. +// +// SPDX-License-Identifier: Apache-2.0 +// +// 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 metrics provides a chain element that sends metrics to collector +package metrics + +import ( + "context" + + "github.com/golang/protobuf/ptypes/empty" + "github.com/networkservicemesh/api/pkg/api/networkservice" + + "github.com/networkservicemesh/sdk/pkg/networkservice/core/next" + "github.com/networkservicemesh/sdk/pkg/tools/opentelemetry/meterhelper" +) + +type metricServer struct { + helpers map[string]meterhelper.MeterHelper +} + +// NewServer returns a new metric server chain element +func NewServer() networkservice.NetworkServiceServer { + return &metricServer{ + helpers: make(map[string]meterhelper.MeterHelper), + } +} + +func (t *metricServer) Request(ctx context.Context, request *networkservice.NetworkServiceRequest) (*networkservice.Connection, error) { + conn, err := next.Server(ctx).Request(ctx, request) + if err != nil { + return nil, err + } + + t.writeMetrics(ctx, conn.GetPath()) + return conn, nil +} + +func (t *metricServer) Close(ctx context.Context, conn *networkservice.Connection) (*empty.Empty, error) { + _, err := next.Server(ctx).Close(ctx, conn) + if err != nil { + return nil, err + } + + t.writeMetrics(ctx, conn.GetPath()) + return &empty.Empty{}, nil +} + +func (t *metricServer) writeMetrics(ctx context.Context, path *networkservice.Path) { + if path != nil { + for _, pathSegment := range path.GetPathSegments() { + if pathSegment.Metrics == nil { + continue + } + _, ok := t.helpers[pathSegment.Id] + if !ok { + t.helpers[pathSegment.Id] = meterhelper.NewMeterHelper(pathSegment.Name, path.GetPathSegments()[0].Id) + } + t.helpers[pathSegment.Id].WriteMetrics(ctx, pathSegment.Metrics) + } + } +} diff --git a/pkg/tools/jaeger/jaeger.go b/pkg/tools/jaeger/jaeger.go index c62e7744e1..1e926beeff 100644 --- a/pkg/tools/jaeger/jaeger.go +++ b/pkg/tools/jaeger/jaeger.go @@ -24,38 +24,14 @@ import ( "fmt" "io" "os" - "strconv" - - "github.com/networkservicemesh/sdk/pkg/tools/log" "github.com/opentracing/opentracing-go" "github.com/uber/jaeger-client-go" "github.com/uber/jaeger-client-go/config" -) -const ( - opentracingEnv = "TRACER_ENABLED" - opentracingDefault = true + "github.com/networkservicemesh/sdk/pkg/tools/log" ) -// IsOpentracingEnabled returns true if opentracing enabled -func IsOpentracingEnabled() bool { - val, err := readEnvBool(opentracingEnv, opentracingDefault) - if err == nil { - return val - } - return opentracingDefault -} - -func readEnvBool(env string, value bool) (bool, error) { - str := os.Getenv(env) - if str == "" { - return value, nil - } - - return strconv.ParseBool(str) -} - type emptyCloser struct { } @@ -66,7 +42,7 @@ func (*emptyCloser) Close() error { // InitJaeger - returns an instance of Jaeger Tracer that samples 100% of traces and logs all spans to stdout. func InitJaeger(ctx context.Context, service string) io.Closer { - if !IsOpentracingEnabled() { + if !log.IsOpentracingEnabled() { return &emptyCloser{} } if opentracing.IsGlobalTracerRegistered() { diff --git a/pkg/tools/log/logger.go b/pkg/tools/log/logger.go index 54a6291f72..24900dd47f 100644 --- a/pkg/tools/log/logger.go +++ b/pkg/tools/log/logger.go @@ -19,6 +19,7 @@ package log import ( "context" + "os" ) type contextKeyType string @@ -26,8 +27,33 @@ type contextKeyType string const ( logKey contextKeyType = "Logger" logFieldsKey contextKeyType = "LoggerFields" + + telemetryEnv = "TELEMETRY" + telemetryOT = "opentracing" + telemetryOTel = "opentelemetry" + + // Opentracing enabled by default + telemetryDefault = telemetryOT ) +// IsOpentracingEnabled returns true if opentracing enabled +func IsOpentracingEnabled() bool { + return telemetryOT == getTelemetryEnv() +} + +// IsOpentelemetryEnabled returns true if opentelemetry enabled +func IsOpentelemetryEnabled() bool { + return telemetryOTel == getTelemetryEnv() +} + +func getTelemetryEnv() string { + val := os.Getenv(telemetryEnv) + if val == "" { + return telemetryDefault + } + return val +} + var ( isTracingEnabled = false ) diff --git a/pkg/tools/log/logruslogger/logruslogger.go b/pkg/tools/log/logruslogger/logruslogger.go index 3f7608734c..1dc1c986c1 100644 --- a/pkg/tools/log/logruslogger/logruslogger.go +++ b/pkg/tools/log/logruslogger/logruslogger.go @@ -26,11 +26,11 @@ import ( "sync" "github.com/google/uuid" - "github.com/opentracing/opentracing-go" "github.com/sirupsen/logrus" "google.golang.org/grpc/metadata" "github.com/networkservicemesh/sdk/pkg/tools/log" + "github.com/networkservicemesh/sdk/pkg/tools/log/spanlogger" ) type loggerKeyType string @@ -93,15 +93,17 @@ func fromContext(ctx context.Context) *traceCtxInfo { type logrusLogger struct { entry *logrus.Entry - span opentracing.Span + span spanlogger.Span info *traceCtxInfo operation string } func (s *logrusLogger) getSpan() string { - spanStr := fmt.Sprintf("%v", s.span) - if len(spanStr) > 0 && spanStr != "{}" && s.span != nil { - return fmt.Sprintf(" span=%v", spanStr) + if s.span != nil { + spanStr := s.span.ToString() + if len(spanStr) > 0 && spanStr != "{}" { + return fmt.Sprintf(" span=%v", spanStr) + } } return "" } @@ -194,7 +196,7 @@ func New(ctx context.Context) log.Logger { // FromSpan - creates a new logruslogger from context, operation and span // and returns context with it, logger, and a function to defer -func FromSpan(ctx context.Context, span opentracing.Span, operation string) (context.Context, log.Logger, func()) { +func FromSpan(ctx context.Context, span spanlogger.Span, operation string) (context.Context, log.Logger, func()) { entry := logrus.WithFields(log.Fields(ctx)) var info *traceCtxInfo diff --git a/pkg/tools/log/spanlogger/span.go b/pkg/tools/log/spanlogger/span.go new file mode 100644 index 0000000000..cefbdd9fcc --- /dev/null +++ b/pkg/tools/log/spanlogger/span.go @@ -0,0 +1,133 @@ +// Copyright (c) 2021 Doc.ai and/or its affiliates. +// +// SPDX-License-Identifier: Apache-2.0 +// +// 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 spanlogger + +import ( + "context" + "fmt" + + "github.com/opentracing/opentracing-go" + opentracinglog "github.com/opentracing/opentracing-go/log" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + opentelemetry "go.opentelemetry.io/otel/trace" + + opentelemetrynsm "github.com/networkservicemesh/sdk/pkg/tools/opentelemetry" +) + +// Span - unified interface for opentracing/opentelemetry spans +type Span interface { + Log(level, format string, v ...interface{}) + LogObject(k, v interface{}) + WithField(k, v interface{}) Span + Finish() + + ToString() string +} + +// Opentracing span +type otSpan struct { + span opentracing.Span +} + +func (otsp *otSpan) Log(level, format string, v ...interface{}) { + otsp.span.LogFields( + opentracinglog.String("event", level), + opentracinglog.String("message", fmt.Sprintf(format, v...)), + ) +} + +func (otsp *otSpan) LogObject(k, v interface{}) { + otsp.span.LogFields(opentracinglog.Object(k.(string), v)) +} + +func (otsp *otSpan) WithField(k, v interface{}) Span { + otsp.span = otsp.span.SetTag(k.(string), v) + return otsp +} + +func (otsp *otSpan) ToString() string { + if spanStr := fmt.Sprintf("%v", otsp.span); spanStr != "{}" { + return spanStr + } + return "" +} + +func (otsp *otSpan) Finish() { + otsp.span.Finish() +} + +func newOTSpan(ctx context.Context, operationName string, additionalFields map[string]interface{}) (c context.Context, s Span) { + span, ctx := opentracing.StartSpanFromContext(ctx, operationName) + for k, v := range additionalFields { + span = span.SetTag(k, v) + } + return ctx, &otSpan{span: span} +} + +// Opentelemetry span +type otelSpan struct { + span opentelemetry.Span +} + +func (otelsp *otelSpan) Log(level, format string, v ...interface{}) { + otelsp.span.AddEvent( + "", + opentelemetry.WithAttributes([]attribute.KeyValue{ + attribute.String("event", level), + attribute.String("message", fmt.Sprintf(format, v...)), + }...), + ) +} + +func (otelsp *otelSpan) LogObject(k, v interface{}) { + otelsp.span.AddEvent( + "", + opentelemetry.WithAttributes([]attribute.KeyValue{ + attribute.String(fmt.Sprintf("%v", k), fmt.Sprintf("%v", v)), + }...), + ) +} + +func (otelsp *otelSpan) WithField(k, v interface{}) Span { + otelsp.span.SetAttributes(attribute.Any(k.(string), v)) + return otelsp +} + +func (otelsp *otelSpan) ToString() string { + if spanID := otelsp.span.SpanContext().SpanID(); spanID.IsValid() { + return spanID.String() + } + return "" +} + +func (otelsp *otelSpan) Finish() { + otelsp.span.End() +} + +func newOTELSpan(ctx context.Context, operationName string, additionalFields map[string]interface{}) (c context.Context, s Span) { + var add []attribute.KeyValue + + for k, v := range additionalFields { + add = append(add, attribute.Any(k, v)) + } + + ctx, span := otel.Tracer(opentelemetrynsm.InstrumentationName).Start(ctx, operationName) + span.SetAttributes(add...) + + return ctx, &otelSpan{span: span} +} diff --git a/pkg/tools/log/spanlogger/spanlogger.go b/pkg/tools/log/spanlogger/spanlogger.go index a92746f165..7aaa0b2d13 100644 --- a/pkg/tools/log/spanlogger/spanlogger.go +++ b/pkg/tools/log/spanlogger/spanlogger.go @@ -25,10 +25,6 @@ import ( "strings" "sync" - "github.com/opentracing/opentracing-go" - opentracinglog "github.com/opentracing/opentracing-go/log" - - "github.com/networkservicemesh/sdk/pkg/tools/jaeger" "github.com/networkservicemesh/sdk/pkg/tools/log" ) @@ -39,9 +35,8 @@ const ( // spanlogger - provides a way to log via opentracing spans type spanLogger struct { - span opentracing.Span - entries map[interface{}]interface{} - lock sync.RWMutex + span Span + lock sync.RWMutex } func (s *spanLogger) Info(v ...interface{}) { @@ -105,11 +100,7 @@ func (s *spanLogger) Object(k, v interface{}) { } else { msg = fmt.Sprint(v) } - - s.span.LogFields(opentracinglog.Object(k.(string), limitString(msg))) - for k, v := range s.entries { - s.span.LogKV(k, v) - } + s.span.LogObject(k, msg) } } } @@ -118,16 +109,13 @@ func (s *spanLogger) WithField(key, value interface{}) log.Logger { s.lock.RLock() defer s.lock.RUnlock() - data := make(map[interface{}]interface{}, len(s.entries)+1) - for k, v := range s.entries { - data[k] = v - } - data[key] = value - newlog := &spanLogger{ - span: s.span, - entries: data, + if s.span != nil { + newlog := &spanLogger{ + span: s.span.WithField(key, value), + } + return newlog } - return newlog + return s } func (s *spanLogger) log(level string, v ...interface{}) { @@ -140,23 +128,21 @@ func (s *spanLogger) logf(level, format string, v ...interface{}) { if s.span != nil { if v != nil { - s.span.LogFields(opentracinglog.String("event", level), opentracinglog.String("message", fmt.Sprintf(format, v...))) - for k, v := range s.entries { - s.span.LogKV(k, v) - } + s.span.Log(level, format, v...) } } } // FromContext - creates a new spanLogger from context and operation -func FromContext(ctx context.Context, operation string) (context.Context, log.Logger, opentracing.Span, func()) { - var span opentracing.Span - if jaeger.IsOpentracingEnabled() { - span, ctx = opentracing.StartSpanFromContext(ctx, operation) +func FromContext(ctx context.Context, operation string) (context.Context, log.Logger, Span, func()) { + var span Span + if log.IsOpentracingEnabled() { + ctx, span = newOTSpan(ctx, operation, log.Fields(ctx)) + } else if log.IsOpentelemetryEnabled() { + ctx, span = newOTELSpan(ctx, operation, log.Fields(ctx)) } newLog := &spanLogger{ - span: span, - entries: make(map[interface{}]interface{}), + span: span, } return ctx, newLog, span, func() { newLog.finish() } } diff --git a/pkg/tools/opentelemetry/meterhelper/meter_helper.go b/pkg/tools/opentelemetry/meterhelper/meter_helper.go new file mode 100644 index 0000000000..31ac7fdb17 --- /dev/null +++ b/pkg/tools/opentelemetry/meterhelper/meter_helper.go @@ -0,0 +1,74 @@ +// Copyright (c) 2021 Doc.ai and/or its affiliates. +// +// SPDX-License-Identifier: Apache-2.0 +// +// 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 meterhelper provides a set of utilities to assist in working with opentelemetry metrics +package meterhelper + +import ( + "context" + "strconv" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/metric/global" + + "github.com/networkservicemesh/sdk/pkg/tools/log" + "github.com/networkservicemesh/sdk/pkg/tools/opentelemetry" +) + +// MeterHelper - wrap opentelemetry Meter to simplify workflow +type MeterHelper interface { + WriteMetrics(ctx context.Context, metrics map[string]string) +} + +type meterHelper struct { + prefix string + connLabel attribute.KeyValue + meter metric.Meter + recorderMap map[string]metric.Int64ValueRecorder +} + +// NewMeterHelper - constructs a meter helper from segmentName and connectionID. +func NewMeterHelper(segmentName, connectionID string) MeterHelper { + meter := global.Meter(opentelemetry.InstrumentationName) + return &meterHelper{ + prefix: segmentName + "_", + connLabel: attribute.String("connection", connectionID), + meter: meter, + recorderMap: make(map[string]metric.Int64ValueRecorder), + } +} + +func (m *meterHelper) WriteMetrics(ctx context.Context, metrics map[string]string) { + if metrics == nil || !log.IsOpentelemetryEnabled() { + return + } + + for metricName, metricValue := range metrics { + /* Works with integers only */ + recVal, err := strconv.ParseInt(metricValue, 10, 64) + if err != nil { + continue + } + _, ok := m.recorderMap[metricName] + if !ok { + m.recorderMap[metricName] = metric.Must(m.meter).NewInt64ValueRecorder( + m.prefix + metricName, + ) + } + m.recorderMap[metricName].Record(ctx, recVal, m.connLabel) + } +} diff --git a/pkg/tools/opentelemetry/opentelemetry.go b/pkg/tools/opentelemetry/opentelemetry.go new file mode 100644 index 0000000000..71ef6009d5 --- /dev/null +++ b/pkg/tools/opentelemetry/opentelemetry.go @@ -0,0 +1,146 @@ +// Copyright (c) 2021 Doc.ai and/or its affiliates. +// +// SPDX-License-Identifier: Apache-2.0 +// +// 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 opentelemetry provides a set of utilities for assisting with telemetry data +package opentelemetry + +import ( + "context" + "io" + "time" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/exporters/otlp" + "go.opentelemetry.io/otel/exporters/otlp/otlpgrpc" + "go.opentelemetry.io/otel/metric/global" + controller "go.opentelemetry.io/otel/sdk/metric/controller/basic" + processor "go.opentelemetry.io/otel/sdk/metric/processor/basic" + "go.opentelemetry.io/otel/sdk/metric/selector/simple" + "go.opentelemetry.io/otel/sdk/resource" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + "go.opentelemetry.io/otel/semconv" + + "github.com/networkservicemesh/sdk/pkg/tools/log" +) + +const ( + // InstrumentationName - denotes the library that provides the instrumentation + InstrumentationName = "NSM" +) + +type opentelemetry struct { + io.Closer + + ctx context.Context + + controller *controller.Controller + tracerProvider *sdktrace.TracerProvider + exporter *otlp.Exporter +} + +func (o *opentelemetry) Close() error { + if o.controller != nil { + if err := o.controller.Stop(o.ctx); err != nil { + log.FromContext(o.ctx).Errorf("failed to shutdown controller: %v", err) + } + } + if o.tracerProvider != nil { + if err := o.tracerProvider.Shutdown(o.ctx); err != nil { + log.FromContext(o.ctx).Errorf("failed to shutdown provider: %v", err) + } + } + if o.exporter != nil { + if err := o.controller.Stop(o.ctx); err != nil { + log.FromContext(o.ctx).Errorf("failed to stop exporter: %v", err) + } + } + return nil +} + +// Init - creates opentelemetry trace and metrics providers +func Init(ctx context.Context, service, otelAddr string) io.Closer { + opentel := &opentelemetry{} + if !log.IsOpentelemetryEnabled() { + return opentel + } + + opentel.ctx = ctx + + driverOptions := []otlpgrpc.Option{ + otlpgrpc.WithInsecure(), + } + if otelAddr != "" { + driverOptions = append(driverOptions, otlpgrpc.WithEndpoint(otelAddr)) + } + metricsDriver := otlpgrpc.NewDriver(driverOptions...) + tracesDriver := otlpgrpc.NewDriver(driverOptions...) + driver := otlp.NewSplitDriver( + otlp.SplitConfig{ + ForMetrics: metricsDriver, + ForTraces: tracesDriver, + }, + ) + + exp, err := otlp.NewExporter(ctx, driver) + if err != nil { + log.FromContext(ctx).Errorf("%v", err) + return opentel + } + opentel.exporter = exp + + res, err := resource.New(ctx, + resource.WithAttributes( + // the service name used to display traces in backends + semconv.ServiceNameKey.String(service), + ), + ) + if err != nil { + log.FromContext(ctx).Errorf("%v", err) + return opentel + } + + /* Create tracer provider */ + tracerProvider := sdktrace.NewTracerProvider( + sdktrace.WithSampler(sdktrace.AlwaysSample()), + sdktrace.WithResource(res), + sdktrace.WithBatcher( + exp, + // add following two options to ensure flush + sdktrace.WithBatchTimeout(5*time.Second), + sdktrace.WithMaxExportBatchSize(10), + ), + ) + otel.SetTracerProvider(tracerProvider) + opentel.tracerProvider = tracerProvider + + /* Create meter provider */ + cont := controller.New( + processor.New( + simple.NewWithExactDistribution(), + exp, + ), + controller.WithExporter(exp), + ) + global.SetMeterProvider(cont.MeterProvider()) + + if err := cont.Start(ctx); err != nil { + log.FromContext(ctx).Errorf("%v", err) + return opentel + } + opentel.controller = cont + + return opentel +} diff --git a/pkg/tools/sandbox/builder.go b/pkg/tools/sandbox/builder.go index b01c03ab27..8ae994304b 100644 --- a/pkg/tools/sandbox/builder.go +++ b/pkg/tools/sandbox/builder.go @@ -45,8 +45,8 @@ import ( "github.com/networkservicemesh/sdk/pkg/registry/common/dnsresolve" "github.com/networkservicemesh/sdk/pkg/tools/grpcutils" "github.com/networkservicemesh/sdk/pkg/tools/log" - "github.com/networkservicemesh/sdk/pkg/tools/opentracing" "github.com/networkservicemesh/sdk/pkg/tools/token" + "github.com/networkservicemesh/sdk/pkg/tools/tracing" ) // Builder implements builder pattern for building NSM Domain @@ -375,7 +375,7 @@ func (b *Builder) newNSMgr(ctx context.Context, address string, registryURL *url } func serve(ctx context.Context, u *url.URL, register func(server *grpc.Server)) { - server := grpc.NewServer(opentracing.WithTracing()...) + server := grpc.NewServer(tracing.WithTracing()...) register(server) errCh := grpcutils.ListenAndServe(ctx, u, server) go func() { diff --git a/pkg/tools/sandbox/utils.go b/pkg/tools/sandbox/utils.go index 84f67ad6e6..1300e6cec2 100644 --- a/pkg/tools/sandbox/utils.go +++ b/pkg/tools/sandbox/utils.go @@ -25,8 +25,8 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials" - "github.com/networkservicemesh/sdk/pkg/tools/opentracing" "github.com/networkservicemesh/sdk/pkg/tools/token" + "github.com/networkservicemesh/sdk/pkg/tools/tracing" ) const ( @@ -96,5 +96,5 @@ func DefaultDialOptions(genTokenFunc token.GeneratorFunc) []grpc.DialOption { grpcfd.WithChainUnaryInterceptor(), WithInsecureRPCCredentials(), WithInsecureStreamRPCCredentials(), - }, opentracing.WithTracingDial()...) + }, tracing.WithTracingDial()...) } diff --git a/pkg/tools/opentracing/grpcoptions.go b/pkg/tools/tracing/grpcoptions.go similarity index 57% rename from pkg/tools/opentracing/grpcoptions.go rename to pkg/tools/tracing/grpcoptions.go index 7eddaa3e17..3cbb08c04d 100644 --- a/pkg/tools/opentracing/grpcoptions.go +++ b/pkg/tools/tracing/grpcoptions.go @@ -16,23 +16,26 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package opentracing provides a set of utilities to assist in working with opentracing -package opentracing +// Package tracing provides a set of utilities to assist in working with opentracing and opentelemetry +package tracing import ( "context" - "github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc" - "github.com/opentracing/opentracing-go" + "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" + "go.opentelemetry.io/otel" "google.golang.org/grpc" "google.golang.org/protobuf/proto" - "github.com/networkservicemesh/sdk/pkg/tools/jaeger" + "github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc" + "github.com/opentracing/opentracing-go" + + "github.com/networkservicemesh/sdk/pkg/tools/log" ) -// WithTracing - returns array of grpc.ServerOption that should be passed to grpc.Dial to enable opentracing +// WithTracing - returns array of grpc.ServerOption that should be passed to grpc.Dial to enable opentracing/opentelemetry tracing func WithTracing() []grpc.ServerOption { - if jaeger.IsOpentracingEnabled() { + if log.IsOpentracingEnabled() { interceptor := func( ctx context.Context, req interface{}, @@ -47,15 +50,30 @@ func WithTracing() []grpc.ServerOption { grpc.ChainStreamInterceptor( otgrpc.OpenTracingStreamServerInterceptor(opentracing.GlobalTracer())), } + } else if log.IsOpentelemetryEnabled() { + interceptor := func( + ctx context.Context, + req interface{}, + info *grpc.UnaryServerInfo, + handler grpc.UnaryHandler, + ) (resp interface{}, err error) { + return otelgrpc.UnaryServerInterceptor(otelgrpc.WithTracerProvider(otel.GetTracerProvider()))(ctx, proto.Clone(req.(proto.Message)), info, handler) + } + return []grpc.ServerOption{ + grpc.ChainUnaryInterceptor( + interceptor), + grpc.ChainStreamInterceptor( + otelgrpc.StreamServerInterceptor(otelgrpc.WithTracerProvider(otel.GetTracerProvider()))), + } } return []grpc.ServerOption{ grpc.EmptyServerOption{}, } } -// WithTracingDial returns array of grpc.DialOption that should be passed to grpc.Dial to enable opentracing +// WithTracingDial returns array of grpc.DialOption that should be passed to grpc.Dial to enable opentracing/opentelemetry tracing func WithTracingDial() []grpc.DialOption { - if jaeger.IsOpentracingEnabled() { + if log.IsOpentracingEnabled() { interceptor := func( ctx context.Context, method string, @@ -72,6 +90,23 @@ func WithTracingDial() []grpc.DialOption { grpc.WithChainStreamInterceptor( otgrpc.OpenTracingStreamClientInterceptor(opentracing.GlobalTracer())), } + } else if log.IsOpentelemetryEnabled() { + interceptor := func( + ctx context.Context, + method string, + req, reply interface{}, + cc *grpc.ClientConn, + invoker grpc.UnaryInvoker, + opts ...grpc.CallOption, + ) error { + return otelgrpc.UnaryClientInterceptor(otelgrpc.WithTracerProvider(otel.GetTracerProvider()))(ctx, method, proto.Clone(req.(proto.Message)), reply, cc, invoker, opts...) + } + return []grpc.DialOption{ + grpc.WithChainUnaryInterceptor( + interceptor), + grpc.WithChainStreamInterceptor( + otelgrpc.StreamClientInterceptor(otelgrpc.WithTracerProvider(otel.GetTracerProvider()))), + } } return []grpc.DialOption{ grpc.EmptyDialOption{},