vendor: make vendor-update

This commit is contained in:
Aliaksandr Valialkin 2023-01-31 11:03:20 -08:00
parent ac8bc77688
commit 080a3e2396
No known key found for this signature in database
GPG key ID: A72BEC6CD3D0DED1
58 changed files with 3074 additions and 1775 deletions

18
go.mod
View file

@ -25,7 +25,7 @@ require (
github.com/influxdata/influxdb v1.11.0 github.com/influxdata/influxdb v1.11.0
github.com/klauspost/compress v1.15.15 github.com/klauspost/compress v1.15.15
github.com/prometheus/prometheus v0.41.0 github.com/prometheus/prometheus v0.41.0
github.com/urfave/cli/v2 v2.24.1 github.com/urfave/cli/v2 v2.24.2
github.com/valyala/fastjson v1.6.4 github.com/valyala/fastjson v1.6.4
github.com/valyala/fastrand v1.1.0 github.com/valyala/fastrand v1.1.0
github.com/valyala/fasttemplate v1.2.2 github.com/valyala/fasttemplate v1.2.2
@ -35,7 +35,7 @@ require (
golang.org/x/net v0.5.0 golang.org/x/net v0.5.0
golang.org/x/oauth2 v0.4.0 golang.org/x/oauth2 v0.4.0
golang.org/x/sys v0.4.0 golang.org/x/sys v0.4.0
google.golang.org/api v0.108.0 google.golang.org/api v0.109.0
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
) )
@ -47,7 +47,7 @@ require (
github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2 // indirect
github.com/VividCortex/ewma v1.2.0 // indirect github.com/VividCortex/ewma v1.2.0 // indirect
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
github.com/aws/aws-sdk-go v1.44.189 // indirect github.com/aws/aws-sdk-go v1.44.190 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.13.10 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.13.10 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.21 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.21 // indirect
@ -70,7 +70,7 @@ require (
github.com/fatih/color v1.14.1 // indirect github.com/fatih/color v1.14.1 // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/go-kit/log v0.2.1 // indirect github.com/go-kit/log v0.2.1 // indirect
github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect
github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/logr v1.2.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
@ -100,13 +100,13 @@ require (
github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
go.opencensus.io v0.24.0 // indirect go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.37.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.38.0 // indirect
go.opentelemetry.io/otel v1.11.2 // indirect go.opentelemetry.io/otel v1.12.0 // indirect
go.opentelemetry.io/otel/metric v0.34.0 // indirect go.opentelemetry.io/otel/metric v0.35.0 // indirect
go.opentelemetry.io/otel/trace v1.11.2 // indirect go.opentelemetry.io/otel/trace v1.12.0 // indirect
go.uber.org/atomic v1.10.0 // indirect go.uber.org/atomic v1.10.0 // indirect
go.uber.org/goleak v1.2.0 // indirect go.uber.org/goleak v1.2.0 // indirect
golang.org/x/exp v0.0.0-20230127193734-31bee513bff7 // indirect golang.org/x/exp v0.0.0-20230131160201-f062dba9d201 // indirect
golang.org/x/sync v0.1.0 // indirect golang.org/x/sync v0.1.0 // indirect
golang.org/x/text v0.6.0 // indirect golang.org/x/text v0.6.0 // indirect
golang.org/x/time v0.3.0 // indirect golang.org/x/time v0.3.0 // indirect

36
go.sum
View file

@ -87,8 +87,8 @@ github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu
github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/armon/go-metrics v0.3.10 h1:FR+drcQStOe+32sYyJYyZ7FIdgoGGBnwLl+flodp8Uo= github.com/armon/go-metrics v0.3.10 h1:FR+drcQStOe+32sYyJYyZ7FIdgoGGBnwLl+flodp8Uo=
github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
github.com/aws/aws-sdk-go v1.44.189 h1:9PBrjndH1uL5AN8818qI3duhQ4hgkMuLvqkJlg9MRyk= github.com/aws/aws-sdk-go v1.44.190 h1:QC+Pf/Ooj7Waf2obOPZbIQOqr00hy4h54j3ZK9mvHcc=
github.com/aws/aws-sdk-go v1.44.189/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go v1.44.190/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/aws/aws-sdk-go-v2 v1.17.3 h1:shN7NlnVzvDUgPQ+1rLMSxY8OWRNDRYtiqe0p/PgrhY= github.com/aws/aws-sdk-go-v2 v1.17.3 h1:shN7NlnVzvDUgPQ+1rLMSxY8OWRNDRYtiqe0p/PgrhY=
github.com/aws/aws-sdk-go-v2 v1.17.3/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= github.com/aws/aws-sdk-go-v2 v1.17.3/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 h1:dK82zF6kkPeCo8J1e+tGx4JdvDIQzj7ygIoLg8WMuGs= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 h1:dK82zF6kkPeCo8J1e+tGx4JdvDIQzj7ygIoLg8WMuGs=
@ -182,8 +182,8 @@ github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBj
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
@ -419,8 +419,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/urfave/cli/v2 v2.24.1 h1:/QYYr7g0EhwXEML8jO+8OYt5trPnLHS0p3mrgExJ5NU= github.com/urfave/cli/v2 v2.24.2 h1:q1VA+ofZ8SWfEKB9xXHUD4QZaeI9e+ItEqSbfH2JBXk=
github.com/urfave/cli/v2 v2.24.1/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= github.com/urfave/cli/v2 v2.24.2/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus= github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus=
@ -452,14 +452,14 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.37.0 h1:yt2NKzK7Vyo6h0+X8BA4FpreZQTlVEIarnsBP/H5mzs= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.38.0 h1:rTxmym+VN9f6ajzNtITVgyvZrNbpLt3NHr3suLLHLEQ=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.37.0/go.mod h1:+ARmXlUlc51J7sZeCBkBJNdHGySrdOzgzxp6VWRWM1U= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.38.0/go.mod h1:w6xNm+kC506KNs5cknSHal6dtdRnc4uema0uN9GSQc0=
go.opentelemetry.io/otel v1.11.2 h1:YBZcQlsVekzFsFbjygXMOXSs6pialIZxcjfO/mBDmR0= go.opentelemetry.io/otel v1.12.0 h1:IgfC7kqQrRccIKuB7Cl+SRUmsKbEwSGPr0Eu+/ht1SQ=
go.opentelemetry.io/otel v1.11.2/go.mod h1:7p4EUV+AqgdlNV9gL97IgUZiVR3yrFXYo53f9BM3tRI= go.opentelemetry.io/otel v1.12.0/go.mod h1:geaoz0L0r1BEOR81k7/n9W4TCXYCJ7bPO7K374jQHG0=
go.opentelemetry.io/otel/metric v0.34.0 h1:MCPoQxcg/26EuuJwpYN1mZTeCYAUGx8ABxfW07YkjP8= go.opentelemetry.io/otel/metric v0.35.0 h1:aPT5jk/w7F9zW51L7WgRqNKDElBdyRLGuBtI5MX34e8=
go.opentelemetry.io/otel/metric v0.34.0/go.mod h1:ZFuI4yQGNCupurTXCwkeD/zHBt+C2bR7bw5JqUm/AP8= go.opentelemetry.io/otel/metric v0.35.0/go.mod h1:qAcbhaTRFU6uG8QM7dDo7XvFsWcugziq/5YI065TokQ=
go.opentelemetry.io/otel/trace v1.11.2 h1:Xf7hWSF2Glv0DE3MH7fBHvtpSBsjcBUe5MYAmZM/+y0= go.opentelemetry.io/otel/trace v1.12.0 h1:p28in++7Kd0r2d8gSt931O57fdjUyWxkVbESuILAeUc=
go.opentelemetry.io/otel/trace v1.11.2/go.mod h1:4N+yC7QEz7TTsG9BSRLNAa63eg5E06ObSbKPmxQ/pKA= go.opentelemetry.io/otel/trace v1.12.0/go.mod h1:pHlgBynn6s25qJ2szD+Bv+iwKJttjHSI3lUAyf0GNuQ=
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
@ -483,8 +483,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20230127193734-31bee513bff7 h1:pXR8mGh4q8ooBT7HXruL4Xa2IxoL8XZ6lOgXY/0Ryg8= golang.org/x/exp v0.0.0-20230131160201-f062dba9d201 h1:BEABXpNXLEz0WxtA+6CQIz2xkg80e+1zrhWyMcq8VzE=
golang.org/x/exp v0.0.0-20230127193734-31bee513bff7/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/exp v0.0.0-20230131160201-f062dba9d201/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -698,8 +698,8 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/api v0.108.0 h1:WVBc/faN0DkKtR43Q/7+tPny9ZoLZdIiAyG5Q9vFClg= google.golang.org/api v0.109.0 h1:sW9hgHyX497PP5//NUM7nqfV8D0iDfBApqq7sOh1XR8=
google.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= google.golang.org/api v0.109.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 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.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/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=

View file

@ -5,4 +5,4 @@ package aws
const SDKName = "aws-sdk-go" const SDKName = "aws-sdk-go"
// SDKVersion is the version of this SDK // SDKVersion is the version of this SDK
const SDKVersion = "1.44.189" const SDKVersion = "1.44.190"

View file

@ -1,48 +1,82 @@
# Changelog # Changelog
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.5.0] - 2020-01-03 ## [0.6.0] - 2023-01-30
[0.6.0]: https://github.com/go-logfmt/logfmt/compare/v0.5.1...v0.6.0
### Added
- NewDecoderSize by [@alexanderjophus]
## [0.5.1] - 2021-08-18
[0.5.1]: https://github.com/go-logfmt/logfmt/compare/v0.5.0...v0.5.1
### Changed ### Changed
- Update the `go.mod` file for Go 1.17 as described in the [Go 1.17 release
notes](https://golang.org/doc/go1.17#go-command)
## [0.5.0] - 2020-01-03
[0.5.0]: https://github.com/go-logfmt/logfmt/compare/v0.4.0...v0.5.0
### Changed
- Remove the dependency on github.com/kr/logfmt by [@ChrisHines] - Remove the dependency on github.com/kr/logfmt by [@ChrisHines]
- Move fuzz code to github.com/go-logfmt/fuzzlogfmt by [@ChrisHines] - Move fuzz code to github.com/go-logfmt/fuzzlogfmt by [@ChrisHines]
## [0.4.0] - 2018-11-21 ## [0.4.0] - 2018-11-21
[0.4.0]: https://github.com/go-logfmt/logfmt/compare/v0.3.0...v0.4.0
### Added ### Added
- Go module support by [@ChrisHines] - Go module support by [@ChrisHines]
- CHANGELOG by [@ChrisHines] - CHANGELOG by [@ChrisHines]
### Changed ### Changed
- Drop invalid runes from keys instead of returning ErrInvalidKey by [@ChrisHines] - Drop invalid runes from keys instead of returning ErrInvalidKey by [@ChrisHines]
- On panic while printing, attempt to print panic value by [@bboreham] - On panic while printing, attempt to print panic value by [@bboreham]
## [0.3.0] - 2016-11-15 ## [0.3.0] - 2016-11-15
[0.3.0]: https://github.com/go-logfmt/logfmt/compare/v0.2.0...v0.3.0
### Added ### Added
- Pool buffers for quoted strings and byte slices by [@nussjustin] - Pool buffers for quoted strings and byte slices by [@nussjustin]
### Fixed ### Fixed
- Fuzz fix, quote invalid UTF-8 values by [@judwhite] - Fuzz fix, quote invalid UTF-8 values by [@judwhite]
## [0.2.0] - 2016-05-08 ## [0.2.0] - 2016-05-08
[0.2.0]: https://github.com/go-logfmt/logfmt/compare/v0.1.0...v0.2.0
### Added ### Added
- Encoder.EncodeKeyvals by [@ChrisHines] - Encoder.EncodeKeyvals by [@ChrisHines]
## [0.1.0] - 2016-03-28 ## [0.1.0] - 2016-03-28
[0.1.0]: https://github.com/go-logfmt/logfmt/commits/v0.1.0
### Added ### Added
- Encoder by [@ChrisHines] - Encoder by [@ChrisHines]
- Decoder by [@ChrisHines] - Decoder by [@ChrisHines]
- MarshalKeyvals by [@ChrisHines] - MarshalKeyvals by [@ChrisHines]
[0.5.0]: https://github.com/go-logfmt/logfmt/compare/v0.4.0...v0.5.0
[0.4.0]: https://github.com/go-logfmt/logfmt/compare/v0.3.0...v0.4.0
[0.3.0]: https://github.com/go-logfmt/logfmt/compare/v0.2.0...v0.3.0
[0.2.0]: https://github.com/go-logfmt/logfmt/compare/v0.1.0...v0.2.0
[0.1.0]: https://github.com/go-logfmt/logfmt/commits/v0.1.0
[@ChrisHines]: https://github.com/ChrisHines [@ChrisHines]: https://github.com/ChrisHines
[@bboreham]: https://github.com/bboreham [@bboreham]: https://github.com/bboreham
[@judwhite]: https://github.com/judwhite [@judwhite]: https://github.com/judwhite
[@nussjustin]: https://github.com/nussjustin [@nussjustin]: https://github.com/nussjustin
[@alexanderjophus]: https://github.com/alexanderjophus

View file

@ -1,20 +1,25 @@
# logfmt
[![Go Reference](https://pkg.go.dev/badge/github.com/go-logfmt/logfmt.svg)](https://pkg.go.dev/github.com/go-logfmt/logfmt) [![Go Reference](https://pkg.go.dev/badge/github.com/go-logfmt/logfmt.svg)](https://pkg.go.dev/github.com/go-logfmt/logfmt)
[![Go Report Card](https://goreportcard.com/badge/go-logfmt/logfmt)](https://goreportcard.com/report/go-logfmt/logfmt) [![Go Report Card](https://goreportcard.com/badge/go-logfmt/logfmt)](https://goreportcard.com/report/go-logfmt/logfmt)
[![Github Actions](https://github.com/go-logfmt/logfmt/actions/workflows/test.yml/badge.svg)](https://github.com/go-logfmt/logfmt/actions/workflows/test.yml) [![Github Actions](https://github.com/go-logfmt/logfmt/actions/workflows/test.yml/badge.svg)](https://github.com/go-logfmt/logfmt/actions/workflows/test.yml)
[![Coverage Status](https://coveralls.io/repos/github/go-logfmt/logfmt/badge.svg?branch=master)](https://coveralls.io/github/go-logfmt/logfmt?branch=master) [![Coverage Status](https://coveralls.io/repos/github/go-logfmt/logfmt/badge.svg?branch=master)](https://coveralls.io/github/go-logfmt/logfmt?branch=main)
# logfmt
Package logfmt implements utilities to marshal and unmarshal data in the [logfmt Package logfmt implements utilities to marshal and unmarshal data in the [logfmt
format](https://brandur.org/logfmt). It provides an API similar to format][fmt]. It provides an API similar to [encoding/json][json] and
[encoding/json](http://golang.org/pkg/encoding/json/) and [encoding/xml][xml].
[encoding/xml](http://golang.org/pkg/encoding/xml/).
[fmt]: https://brandur.org/logfmt
[json]: https://pkg.go.dev/encoding/json
[xml]: https://pkg.go.dev/encoding/xml
The logfmt format was first documented by Brandur Leach in [this The logfmt format was first documented by Brandur Leach in [this
article](https://brandur.org/logfmt). The format has not been formally article][origin]. The format has not been formally standardized. The most
standardized. The most authoritative public specification to date has been the authoritative public specification to date has been the documentation of a Go
documentation of a Go Language [package](http://godoc.org/github.com/kr/logfmt) Language [package][parser] written by Blake Mizerany and Keith Rarick.
written by Blake Mizerany and Keith Rarick.
[origin]: https://brandur.org/logfmt
[parser]: https://pkg.go.dev/github.com/kr/logfmt
## Goals ## Goals
@ -30,4 +35,7 @@ standard as a goal.
## Versioning ## Versioning
Package logfmt publishes releases via [semver](http://semver.org/) compatible Git tags prefixed with a single 'v'. This project publishes releases according to the Go language guidelines for
[developing and publishing modules][pub].
[pub]: https://go.dev/doc/modules/developing

View file

@ -29,6 +29,23 @@ func NewDecoder(r io.Reader) *Decoder {
return dec return dec
} }
// NewDecoderSize returns a new decoder that reads from r.
//
// The decoder introduces its own buffering and may read data from r beyond
// the logfmt records requested.
// The size argument specifies the size of the initial buffer that the
// Decoder will use to read records from r.
// If a log line is longer than the size argument, the Decoder will return
// a bufio.ErrTooLong error.
func NewDecoderSize(r io.Reader, size int) *Decoder {
scanner := bufio.NewScanner(r)
scanner.Buffer(make([]byte, 0, size), size)
dec := &Decoder{
s: scanner,
}
return dec
}
// ScanRecord advances the Decoder to the next record, which can then be // ScanRecord advances the Decoder to the next record, which can then be
// parsed with the ScanKeyval method. It returns false when decoding stops, // parsed with the ScanKeyval method. It returns false when decoding stops,
// either by reaching the end of the input or an error. After ScanRecord // either by reaching the end of the input or an error. After ScanRecord

View file

@ -1,9 +1,9 @@
# cli # cli
[![GoDoc](https://godoc.org/github.com/urfave/cli?status.svg)](https://pkg.go.dev/github.com/urfave/cli/v2) [![Run Tests](https://github.com/urfave/cli/actions/workflows/cli.yml/badge.svg?branch=v2-maint)](https://github.com/urfave/cli/actions/workflows/cli.yml)
[![codebeat](https://codebeat.co/badges/0a8f30aa-f975-404b-b878-5fab3ae1cc5f)](https://codebeat.co/projects/github-com-urfave-cli) [![Go Reference](https://pkg.go.dev/badge/github.com/urfave/cli/v2.svg)](https://pkg.go.dev/github.com/urfave/cli/v2)
[![Go Report Card](https://goreportcard.com/badge/urfave/cli)](https://goreportcard.com/report/urfave/cli) [![Go Report Card](https://goreportcard.com/badge/github.com/urfave/cli/v2)](https://goreportcard.com/report/github.com/urfave/cli/v2)
[![codecov](https://codecov.io/gh/urfave/cli/branch/main/graph/badge.svg)](https://codecov.io/gh/urfave/cli) [![codecov](https://codecov.io/gh/urfave/cli/branch/v2-maint/graph/badge.svg?token=t9YGWLh05g)](https://app.codecov.io/gh/urfave/cli/tree/v2-maint)
cli is a simple, fast, and fun package for building command line apps in Go. The cli is a simple, fast, and fun package for building command line apps in Go. The
goal is to enable developers to write fast and distributable command line goal is to enable developers to write fast and distributable command line

View file

@ -121,7 +121,8 @@ type App struct {
// Treat all flags as normal arguments if true // Treat all flags as normal arguments if true
SkipFlagParsing bool SkipFlagParsing bool
didSetup bool didSetup bool
separator separatorSpec
rootCommand *Command rootCommand *Command
} }
@ -216,6 +217,16 @@ func (a *App) Setup() {
}) })
} }
if len(a.SliceFlagSeparator) != 0 {
a.separator.customized = true
a.separator.sep = a.SliceFlagSeparator
}
if a.DisableSliceFlagSeparator {
a.separator.customized = true
a.separator.disabled = true
}
var newCommands []*Command var newCommands []*Command
for _, c := range a.Commands { for _, c := range a.Commands {
@ -223,8 +234,8 @@ func (a *App) Setup() {
if c.HelpName != "" { if c.HelpName != "" {
cname = c.HelpName cname = c.HelpName
} }
c.separator = a.separator
c.HelpName = fmt.Sprintf("%s %s", a.HelpName, cname) c.HelpName = fmt.Sprintf("%s %s", a.HelpName, cname)
c.flagCategories = newFlagCategoriesFromFlags(c.Flags) c.flagCategories = newFlagCategoriesFromFlags(c.Flags)
newCommands = append(newCommands, c) newCommands = append(newCommands, c)
} }
@ -250,24 +261,11 @@ func (a *App) Setup() {
} }
sort.Sort(a.categories.(*commandCategories)) sort.Sort(a.categories.(*commandCategories))
a.flagCategories = newFlagCategories() a.flagCategories = newFlagCategoriesFromFlags(a.Flags)
for _, fl := range a.Flags {
if cf, ok := fl.(CategorizableFlag); ok {
if cf.GetCategory() != "" {
a.flagCategories.AddFlag(cf.GetCategory(), cf)
}
}
}
if a.Metadata == nil { if a.Metadata == nil {
a.Metadata = make(map[string]interface{}) a.Metadata = make(map[string]interface{})
} }
if len(a.SliceFlagSeparator) != 0 {
defaultSliceFlagSeparator = a.SliceFlagSeparator
}
disableSliceFlagSeparator = a.DisableSliceFlagSeparator
} }
func (a *App) newRootCommand() *Command { func (a *App) newRootCommand() *Command {
@ -293,11 +291,12 @@ func (a *App) newRootCommand() *Command {
categories: a.categories, categories: a.categories,
SkipFlagParsing: a.SkipFlagParsing, SkipFlagParsing: a.SkipFlagParsing,
isRoot: true, isRoot: true,
separator: a.separator,
} }
} }
func (a *App) newFlagSet() (*flag.FlagSet, error) { func (a *App) newFlagSet() (*flag.FlagSet, error) {
return flagSet(a.Name, a.Flags) return flagSet(a.Name, a.Flags, a.separator)
} }
func (a *App) useShortOptionHandling() bool { func (a *App) useShortOptionHandling() bool {

View file

@ -100,10 +100,23 @@ func newFlagCategories() FlagCategories {
func newFlagCategoriesFromFlags(fs []Flag) FlagCategories { func newFlagCategoriesFromFlags(fs []Flag) FlagCategories {
fc := newFlagCategories() fc := newFlagCategories()
var categorized bool
for _, fl := range fs { for _, fl := range fs {
if cf, ok := fl.(CategorizableFlag); ok { if cf, ok := fl.(CategorizableFlag); ok {
if cf.GetCategory() != "" { if cat := cf.GetCategory(); cat != "" {
fc.AddFlag(cf.GetCategory(), cf) fc.AddFlag(cat, cf)
categorized = true
}
}
}
if categorized == true {
for _, fl := range fs {
if cf, ok := fl.(CategorizableFlag); ok {
if cf.GetCategory() == "" {
fc.AddFlag("", fl)
}
} }
} }
} }

View file

@ -69,6 +69,8 @@ type Command struct {
// if this is a root "special" command // if this is a root "special" command
isRoot bool isRoot bool
separator separatorSpec
} }
type Commands []*Command type Commands []*Command
@ -275,7 +277,7 @@ func (c *Command) Run(cCtx *Context, arguments ...string) (err error) {
} }
func (c *Command) newFlagSet() (*flag.FlagSet, error) { func (c *Command) newFlagSet() (*flag.FlagSet, error) {
return flagSet(c.Name, c.Flags) return flagSet(c.Name, c.Flags, c.separator)
} }
func (c *Command) useShortOptionHandling() bool { func (c *Command) useShortOptionHandling() bool {

View file

@ -20,6 +20,8 @@ flag_types:
skip_interfaces: skip_interfaces:
- fmt.Stringer - fmt.Stringer
struct_fields: struct_fields:
- name: separator
type: separatorSpec
- name: Action - name: Action
type: "func(*Context, []float64) error" type: "func(*Context, []float64) error"
int: int:
@ -33,6 +35,8 @@ flag_types:
skip_interfaces: skip_interfaces:
- fmt.Stringer - fmt.Stringer
struct_fields: struct_fields:
- name: separator
type: separatorSpec
- name: Action - name: Action
type: "func(*Context, []int) error" type: "func(*Context, []int) error"
int64: int64:
@ -46,6 +50,8 @@ flag_types:
skip_interfaces: skip_interfaces:
- fmt.Stringer - fmt.Stringer
struct_fields: struct_fields:
- name: separator
type: separatorSpec
- name: Action - name: Action
type: "func(*Context, []int64) error" type: "func(*Context, []int64) error"
uint: uint:
@ -59,6 +65,8 @@ flag_types:
skip_interfaces: skip_interfaces:
- fmt.Stringer - fmt.Stringer
struct_fields: struct_fields:
- name: separator
type: separatorSpec
- name: Action - name: Action
type: "func(*Context, []uint) error" type: "func(*Context, []uint) error"
uint64: uint64:
@ -72,6 +80,8 @@ flag_types:
skip_interfaces: skip_interfaces:
- fmt.Stringer - fmt.Stringer
struct_fields: struct_fields:
- name: separator
type: separatorSpec
- name: Action - name: Action
type: "func(*Context, []uint64) error" type: "func(*Context, []uint64) error"
string: string:
@ -85,6 +95,8 @@ flag_types:
skip_interfaces: skip_interfaces:
- fmt.Stringer - fmt.Stringer
struct_fields: struct_fields:
- name: separator
type: separatorSpec
- name: TakesFile - name: TakesFile
type: bool type: bool
- name: Action - name: Action

View file

@ -15,7 +15,7 @@ import (
const defaultPlaceholder = "value" const defaultPlaceholder = "value"
var ( const (
defaultSliceFlagSeparator = "," defaultSliceFlagSeparator = ","
disableSliceFlagSeparator = false disableSliceFlagSeparator = false
) )
@ -167,10 +167,13 @@ type Countable interface {
Count() int Count() int
} }
func flagSet(name string, flags []Flag) (*flag.FlagSet, error) { func flagSet(name string, flags []Flag, spec separatorSpec) (*flag.FlagSet, error) {
set := flag.NewFlagSet(name, flag.ContinueOnError) set := flag.NewFlagSet(name, flag.ContinueOnError)
for _, f := range flags { for _, f := range flags {
if c, ok := f.(customizedSeparator); ok {
c.WithSeparatorSpec(spec)
}
if err := f.Apply(set); err != nil { if err := f.Apply(set); err != nil {
return nil, err return nil, err
} }
@ -389,10 +392,28 @@ func flagFromEnvOrFile(envVars []string, filePath string) (value string, fromWhe
return "", "", false return "", "", false
} }
func flagSplitMultiValues(val string) []string { type customizedSeparator interface {
if disableSliceFlagSeparator { WithSeparatorSpec(separatorSpec)
}
type separatorSpec struct {
sep string
disabled bool
customized bool
}
func (s separatorSpec) flagSplitMultiValues(val string) []string {
var (
disabled bool = s.disabled
sep string = s.sep
)
if !s.customized {
disabled = disableSliceFlagSeparator
sep = defaultSliceFlagSeparator
}
if disabled {
return []string{val} return []string{val}
} }
return strings.Split(val, defaultSliceFlagSeparator) return strings.Split(val, sep)
} }

View file

@ -11,6 +11,7 @@ import (
// Float64Slice wraps []float64 to satisfy flag.Value // Float64Slice wraps []float64 to satisfy flag.Value
type Float64Slice struct { type Float64Slice struct {
slice []float64 slice []float64
separator separatorSpec
hasBeenSet bool hasBeenSet bool
} }
@ -29,6 +30,10 @@ func (f *Float64Slice) clone() *Float64Slice {
return n return n
} }
func (f *Float64Slice) WithSeparatorSpec(spec separatorSpec) {
f.separator = spec
}
// Set parses the value into a float64 and appends it to the list of values // Set parses the value into a float64 and appends it to the list of values
func (f *Float64Slice) Set(value string) error { func (f *Float64Slice) Set(value string) error {
if !f.hasBeenSet { if !f.hasBeenSet {
@ -43,7 +48,7 @@ func (f *Float64Slice) Set(value string) error {
return nil return nil
} }
for _, s := range flagSplitMultiValues(value) { for _, s := range f.separator.flagSplitMultiValues(value) {
tmp, err := strconv.ParseFloat(strings.TrimSpace(s), 64) tmp, err := strconv.ParseFloat(strings.TrimSpace(s), 64)
if err != nil { if err != nil {
return err return err
@ -148,11 +153,12 @@ func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error {
setValue = f.Value.clone() setValue = f.Value.clone()
default: default:
setValue = new(Float64Slice) setValue = new(Float64Slice)
setValue.WithSeparatorSpec(f.separator)
} }
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
if val != "" { if val != "" {
for _, s := range flagSplitMultiValues(val) { for _, s := range f.separator.flagSplitMultiValues(val) {
if err := setValue.Set(strings.TrimSpace(s)); err != nil { if err := setValue.Set(strings.TrimSpace(s)); err != nil {
return fmt.Errorf("could not parse %q as float64 slice value from %s for flag %s: %s", val, source, f.Name, err) return fmt.Errorf("could not parse %q as float64 slice value from %s for flag %s: %s", val, source, f.Name, err)
} }
@ -172,6 +178,10 @@ func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error {
return nil return nil
} }
func (f *Float64SliceFlag) WithSeparatorSpec(spec separatorSpec) {
f.separator = spec
}
// Get returns the flags value in the given Context. // Get returns the flags value in the given Context.
func (f *Float64SliceFlag) Get(ctx *Context) []float64 { func (f *Float64SliceFlag) Get(ctx *Context) []float64 {
return ctx.Float64Slice(f.Name) return ctx.Float64Slice(f.Name)

View file

@ -11,6 +11,7 @@ import (
// Int64Slice wraps []int64 to satisfy flag.Value // Int64Slice wraps []int64 to satisfy flag.Value
type Int64Slice struct { type Int64Slice struct {
slice []int64 slice []int64
separator separatorSpec
hasBeenSet bool hasBeenSet bool
} }
@ -29,6 +30,10 @@ func (i *Int64Slice) clone() *Int64Slice {
return n return n
} }
func (i *Int64Slice) WithSeparatorSpec(spec separatorSpec) {
i.separator = spec
}
// Set parses the value into an integer and appends it to the list of values // Set parses the value into an integer and appends it to the list of values
func (i *Int64Slice) Set(value string) error { func (i *Int64Slice) Set(value string) error {
if !i.hasBeenSet { if !i.hasBeenSet {
@ -43,7 +48,7 @@ func (i *Int64Slice) Set(value string) error {
return nil return nil
} }
for _, s := range flagSplitMultiValues(value) { for _, s := range i.separator.flagSplitMultiValues(value) {
tmp, err := strconv.ParseInt(strings.TrimSpace(s), 0, 64) tmp, err := strconv.ParseInt(strings.TrimSpace(s), 0, 64)
if err != nil { if err != nil {
return err return err
@ -149,10 +154,11 @@ func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error {
setValue = f.Value.clone() setValue = f.Value.clone()
default: default:
setValue = new(Int64Slice) setValue = new(Int64Slice)
setValue.WithSeparatorSpec(f.separator)
} }
if val, source, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok && val != "" { if val, source, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok && val != "" {
for _, s := range flagSplitMultiValues(val) { for _, s := range f.separator.flagSplitMultiValues(val) {
if err := setValue.Set(strings.TrimSpace(s)); err != nil { if err := setValue.Set(strings.TrimSpace(s)); err != nil {
return fmt.Errorf("could not parse %q as int64 slice value from %s for flag %s: %s", val, source, f.Name, err) return fmt.Errorf("could not parse %q as int64 slice value from %s for flag %s: %s", val, source, f.Name, err)
} }
@ -171,6 +177,10 @@ func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error {
return nil return nil
} }
func (f *Int64SliceFlag) WithSeparatorSpec(spec separatorSpec) {
f.separator = spec
}
// Get returns the flags value in the given Context. // Get returns the flags value in the given Context.
func (f *Int64SliceFlag) Get(ctx *Context) []int64 { func (f *Int64SliceFlag) Get(ctx *Context) []int64 {
return ctx.Int64Slice(f.Name) return ctx.Int64Slice(f.Name)

View file

@ -11,6 +11,7 @@ import (
// IntSlice wraps []int to satisfy flag.Value // IntSlice wraps []int to satisfy flag.Value
type IntSlice struct { type IntSlice struct {
slice []int slice []int
separator separatorSpec
hasBeenSet bool hasBeenSet bool
} }
@ -40,6 +41,10 @@ func (i *IntSlice) SetInt(value int) {
i.slice = append(i.slice, value) i.slice = append(i.slice, value)
} }
func (i *IntSlice) WithSeparatorSpec(spec separatorSpec) {
i.separator = spec
}
// Set parses the value into an integer and appends it to the list of values // Set parses the value into an integer and appends it to the list of values
func (i *IntSlice) Set(value string) error { func (i *IntSlice) Set(value string) error {
if !i.hasBeenSet { if !i.hasBeenSet {
@ -54,7 +59,7 @@ func (i *IntSlice) Set(value string) error {
return nil return nil
} }
for _, s := range flagSplitMultiValues(value) { for _, s := range i.separator.flagSplitMultiValues(value) {
tmp, err := strconv.ParseInt(strings.TrimSpace(s), 0, 64) tmp, err := strconv.ParseInt(strings.TrimSpace(s), 0, 64)
if err != nil { if err != nil {
return err return err
@ -160,10 +165,11 @@ func (f *IntSliceFlag) Apply(set *flag.FlagSet) error {
setValue = f.Value.clone() setValue = f.Value.clone()
default: default:
setValue = new(IntSlice) setValue = new(IntSlice)
setValue.WithSeparatorSpec(f.separator)
} }
if val, source, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok && val != "" { if val, source, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok && val != "" {
for _, s := range flagSplitMultiValues(val) { for _, s := range f.separator.flagSplitMultiValues(val) {
if err := setValue.Set(strings.TrimSpace(s)); err != nil { if err := setValue.Set(strings.TrimSpace(s)); err != nil {
return fmt.Errorf("could not parse %q as int slice value from %s for flag %s: %s", val, source, f.Name, err) return fmt.Errorf("could not parse %q as int slice value from %s for flag %s: %s", val, source, f.Name, err)
} }
@ -182,6 +188,10 @@ func (f *IntSliceFlag) Apply(set *flag.FlagSet) error {
return nil return nil
} }
func (f *IntSliceFlag) WithSeparatorSpec(spec separatorSpec) {
f.separator = spec
}
// Get returns the flags value in the given Context. // Get returns the flags value in the given Context.
func (f *IntSliceFlag) Get(ctx *Context) []int { func (f *IntSliceFlag) Get(ctx *Context) []int {
return ctx.IntSlice(f.Name) return ctx.IntSlice(f.Name)

View file

@ -11,6 +11,7 @@ import (
// StringSlice wraps a []string to satisfy flag.Value // StringSlice wraps a []string to satisfy flag.Value
type StringSlice struct { type StringSlice struct {
slice []string slice []string
separator separatorSpec
hasBeenSet bool hasBeenSet bool
} }
@ -43,13 +44,17 @@ func (s *StringSlice) Set(value string) error {
return nil return nil
} }
for _, t := range flagSplitMultiValues(value) { for _, t := range s.separator.flagSplitMultiValues(value) {
s.slice = append(s.slice, t) s.slice = append(s.slice, t)
} }
return nil return nil
} }
func (s *StringSlice) WithSeparatorSpec(spec separatorSpec) {
s.separator = spec
}
// String returns a readable representation of this value (for usage defaults) // String returns a readable representation of this value (for usage defaults)
func (s *StringSlice) String() string { func (s *StringSlice) String() string {
return fmt.Sprintf("%s", s.slice) return fmt.Sprintf("%s", s.slice)
@ -141,10 +146,11 @@ func (f *StringSliceFlag) Apply(set *flag.FlagSet) error {
setValue = f.Value.clone() setValue = f.Value.clone()
default: default:
setValue = new(StringSlice) setValue = new(StringSlice)
setValue.WithSeparatorSpec(f.separator)
} }
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
for _, s := range flagSplitMultiValues(val) { for _, s := range f.separator.flagSplitMultiValues(val) {
if err := setValue.Set(strings.TrimSpace(s)); err != nil { if err := setValue.Set(strings.TrimSpace(s)); err != nil {
return fmt.Errorf("could not parse %q as string value from %s for flag %s: %s", val, source, f.Name, err) return fmt.Errorf("could not parse %q as string value from %s for flag %s: %s", val, source, f.Name, err)
} }
@ -163,6 +169,10 @@ func (f *StringSliceFlag) Apply(set *flag.FlagSet) error {
return nil return nil
} }
func (f *StringSliceFlag) WithSeparatorSpec(spec separatorSpec) {
f.separator = spec
}
// Get returns the flags value in the given Context. // Get returns the flags value in the given Context.
func (f *StringSliceFlag) Get(ctx *Context) []string { func (f *StringSliceFlag) Get(ctx *Context) []string {
return ctx.StringSlice(f.Name) return ctx.StringSlice(f.Name)

View file

@ -11,6 +11,7 @@ import (
// Uint64Slice wraps []int64 to satisfy flag.Value // Uint64Slice wraps []int64 to satisfy flag.Value
type Uint64Slice struct { type Uint64Slice struct {
slice []uint64 slice []uint64
separator separatorSpec
hasBeenSet bool hasBeenSet bool
} }
@ -43,7 +44,7 @@ func (i *Uint64Slice) Set(value string) error {
return nil return nil
} }
for _, s := range flagSplitMultiValues(value) { for _, s := range i.separator.flagSplitMultiValues(value) {
tmp, err := strconv.ParseUint(strings.TrimSpace(s), 0, 64) tmp, err := strconv.ParseUint(strings.TrimSpace(s), 0, 64)
if err != nil { if err != nil {
return err return err
@ -55,6 +56,10 @@ func (i *Uint64Slice) Set(value string) error {
return nil return nil
} }
func (i *Uint64Slice) WithSeparatorSpec(spec separatorSpec) {
i.separator = spec
}
// String returns a readable representation of this value (for usage defaults) // String returns a readable representation of this value (for usage defaults)
func (i *Uint64Slice) String() string { func (i *Uint64Slice) String() string {
v := i.slice v := i.slice
@ -153,10 +158,11 @@ func (f *Uint64SliceFlag) Apply(set *flag.FlagSet) error {
setValue = f.Value.clone() setValue = f.Value.clone()
default: default:
setValue = new(Uint64Slice) setValue = new(Uint64Slice)
setValue.WithSeparatorSpec(f.separator)
} }
if val, source, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok && val != "" { if val, source, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok && val != "" {
for _, s := range flagSplitMultiValues(val) { for _, s := range f.separator.flagSplitMultiValues(val) {
if err := setValue.Set(strings.TrimSpace(s)); err != nil { if err := setValue.Set(strings.TrimSpace(s)); err != nil {
return fmt.Errorf("could not parse %q as uint64 slice value from %s for flag %s: %s", val, source, f.Name, err) return fmt.Errorf("could not parse %q as uint64 slice value from %s for flag %s: %s", val, source, f.Name, err)
} }
@ -175,6 +181,10 @@ func (f *Uint64SliceFlag) Apply(set *flag.FlagSet) error {
return nil return nil
} }
func (f *Uint64SliceFlag) WithSeparatorSpec(spec separatorSpec) {
f.separator = spec
}
// Get returns the flags value in the given Context. // Get returns the flags value in the given Context.
func (f *Uint64SliceFlag) Get(ctx *Context) []uint64 { func (f *Uint64SliceFlag) Get(ctx *Context) []uint64 {
return ctx.Uint64Slice(f.Name) return ctx.Uint64Slice(f.Name)

View file

@ -11,6 +11,7 @@ import (
// UintSlice wraps []int to satisfy flag.Value // UintSlice wraps []int to satisfy flag.Value
type UintSlice struct { type UintSlice struct {
slice []uint slice []uint
separator separatorSpec
hasBeenSet bool hasBeenSet bool
} }
@ -54,7 +55,7 @@ func (i *UintSlice) Set(value string) error {
return nil return nil
} }
for _, s := range flagSplitMultiValues(value) { for _, s := range i.separator.flagSplitMultiValues(value) {
tmp, err := strconv.ParseUint(strings.TrimSpace(s), 0, 32) tmp, err := strconv.ParseUint(strings.TrimSpace(s), 0, 32)
if err != nil { if err != nil {
return err return err
@ -66,6 +67,10 @@ func (i *UintSlice) Set(value string) error {
return nil return nil
} }
func (i *UintSlice) WithSeparatorSpec(spec separatorSpec) {
i.separator = spec
}
// String returns a readable representation of this value (for usage defaults) // String returns a readable representation of this value (for usage defaults)
func (i *UintSlice) String() string { func (i *UintSlice) String() string {
v := i.slice v := i.slice
@ -164,10 +169,11 @@ func (f *UintSliceFlag) Apply(set *flag.FlagSet) error {
setValue = f.Value.clone() setValue = f.Value.clone()
default: default:
setValue = new(UintSlice) setValue = new(UintSlice)
setValue.WithSeparatorSpec(f.separator)
} }
if val, source, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok && val != "" { if val, source, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok && val != "" {
for _, s := range flagSplitMultiValues(val) { for _, s := range f.separator.flagSplitMultiValues(val) {
if err := setValue.Set(strings.TrimSpace(s)); err != nil { if err := setValue.Set(strings.TrimSpace(s)); err != nil {
return fmt.Errorf("could not parse %q as uint slice value from %s for flag %s: %s", val, source, f.Name, err) return fmt.Errorf("could not parse %q as uint slice value from %s for flag %s: %s", val, source, f.Name, err)
} }
@ -186,6 +192,10 @@ func (f *UintSliceFlag) Apply(set *flag.FlagSet) error {
return nil return nil
} }
func (f *UintSliceFlag) WithSeparatorSpec(spec separatorSpec) {
f.separator = spec
}
// Get returns the flags value in the given Context. // Get returns the flags value in the given Context.
func (f *UintSliceFlag) Get(ctx *Context) []uint { func (f *UintSliceFlag) Get(ctx *Context) []uint {
return ctx.UintSlice(f.Name) return ctx.UintSlice(f.Name)

View file

@ -1038,6 +1038,8 @@ func (f *Float64Slice) String() string
func (f *Float64Slice) Value() []float64 func (f *Float64Slice) Value() []float64
Value returns the slice of float64s set by this flag Value returns the slice of float64s set by this flag
func (f *Float64Slice) WithSeparatorSpec(spec separatorSpec)
type Float64SliceFlag struct { type Float64SliceFlag struct {
Name string Name string
@ -1113,6 +1115,8 @@ func (f *Float64SliceFlag) String() string
func (f *Float64SliceFlag) TakesValue() bool func (f *Float64SliceFlag) TakesValue() bool
TakesValue returns true if the flag takes a value, otherwise false TakesValue returns true if the flag takes a value, otherwise false
func (f *Float64SliceFlag) WithSeparatorSpec(spec separatorSpec)
type Generic interface { type Generic interface {
Set(value string) error Set(value string) error
String() string String() string
@ -1279,6 +1283,8 @@ func (i *Int64Slice) String() string
func (i *Int64Slice) Value() []int64 func (i *Int64Slice) Value() []int64
Value returns the slice of ints set by this flag Value returns the slice of ints set by this flag
func (i *Int64Slice) WithSeparatorSpec(spec separatorSpec)
type Int64SliceFlag struct { type Int64SliceFlag struct {
Name string Name string
@ -1354,6 +1360,8 @@ func (f *Int64SliceFlag) String() string
func (f *Int64SliceFlag) TakesValue() bool func (f *Int64SliceFlag) TakesValue() bool
TakesValue returns true of the flag takes a value, otherwise false TakesValue returns true of the flag takes a value, otherwise false
func (f *Int64SliceFlag) WithSeparatorSpec(spec separatorSpec)
type IntFlag struct { type IntFlag struct {
Name string Name string
@ -1449,6 +1457,8 @@ func (i *IntSlice) String() string
func (i *IntSlice) Value() []int func (i *IntSlice) Value() []int
Value returns the slice of ints set by this flag Value returns the slice of ints set by this flag
func (i *IntSlice) WithSeparatorSpec(spec separatorSpec)
type IntSliceFlag struct { type IntSliceFlag struct {
Name string Name string
@ -1524,6 +1534,8 @@ func (f *IntSliceFlag) String() string
func (f *IntSliceFlag) TakesValue() bool func (f *IntSliceFlag) TakesValue() bool
TakesValue returns true of the flag takes a value, otherwise false TakesValue returns true of the flag takes a value, otherwise false
func (f *IntSliceFlag) WithSeparatorSpec(spec separatorSpec)
type InvalidFlagAccessFunc func(*Context, string) type InvalidFlagAccessFunc func(*Context, string)
InvalidFlagAccessFunc is executed when an invalid flag is accessed from the InvalidFlagAccessFunc is executed when an invalid flag is accessed from the
context. context.
@ -1792,6 +1804,8 @@ func (s *StringSlice) String() string
func (s *StringSlice) Value() []string func (s *StringSlice) Value() []string
Value returns the slice of strings set by this flag Value returns the slice of strings set by this flag
func (s *StringSlice) WithSeparatorSpec(spec separatorSpec)
type StringSliceFlag struct { type StringSliceFlag struct {
Name string Name string
@ -1869,6 +1883,8 @@ func (f *StringSliceFlag) String() string
func (f *StringSliceFlag) TakesValue() bool func (f *StringSliceFlag) TakesValue() bool
TakesValue returns true of the flag takes a value, otherwise false TakesValue returns true of the flag takes a value, otherwise false
func (f *StringSliceFlag) WithSeparatorSpec(spec separatorSpec)
type SuggestCommandFunc func(commands []*Command, provided string) string type SuggestCommandFunc func(commands []*Command, provided string) string
type SuggestFlagFunc func(flags []Flag, provided string, hideHelp bool) string type SuggestFlagFunc func(flags []Flag, provided string, hideHelp bool) string
@ -2063,6 +2079,8 @@ func (i *Uint64Slice) String() string
func (i *Uint64Slice) Value() []uint64 func (i *Uint64Slice) Value() []uint64
Value returns the slice of ints set by this flag Value returns the slice of ints set by this flag
func (i *Uint64Slice) WithSeparatorSpec(spec separatorSpec)
type Uint64SliceFlag struct { type Uint64SliceFlag struct {
Name string Name string
@ -2129,6 +2147,8 @@ func (f *Uint64SliceFlag) String() string
func (f *Uint64SliceFlag) TakesValue() bool func (f *Uint64SliceFlag) TakesValue() bool
TakesValue returns true of the flag takes a value, otherwise false TakesValue returns true of the flag takes a value, otherwise false
func (f *Uint64SliceFlag) WithSeparatorSpec(spec separatorSpec)
type UintFlag struct { type UintFlag struct {
Name string Name string
@ -2224,6 +2244,8 @@ func (i *UintSlice) String() string
func (i *UintSlice) Value() []uint func (i *UintSlice) Value() []uint
Value returns the slice of ints set by this flag Value returns the slice of ints set by this flag
func (i *UintSlice) WithSeparatorSpec(spec separatorSpec)
type UintSliceFlag struct { type UintSliceFlag struct {
Name string Name string
@ -2290,6 +2312,8 @@ func (f *UintSliceFlag) String() string
func (f *UintSliceFlag) TakesValue() bool func (f *UintSliceFlag) TakesValue() bool
TakesValue returns true of the flag takes a value, otherwise false TakesValue returns true of the flag takes a value, otherwise false
func (f *UintSliceFlag) WithSeparatorSpec(spec separatorSpec)
type VisibleFlag interface { type VisibleFlag interface {
Flag Flag

View file

@ -25,6 +25,8 @@ type Float64SliceFlag struct {
defaultValue *Float64Slice defaultValue *Float64Slice
separator separatorSpec
Action func(*Context, []float64) error Action func(*Context, []float64) error
} }
@ -120,6 +122,8 @@ type Int64SliceFlag struct {
defaultValue *Int64Slice defaultValue *Int64Slice
separator separatorSpec
Action func(*Context, []int64) error Action func(*Context, []int64) error
} }
@ -164,6 +168,8 @@ type IntSliceFlag struct {
defaultValue *IntSlice defaultValue *IntSlice
separator separatorSpec
Action func(*Context, []int) error Action func(*Context, []int) error
} }
@ -259,6 +265,8 @@ type StringSliceFlag struct {
defaultValue *StringSlice defaultValue *StringSlice
separator separatorSpec
TakesFile bool TakesFile bool
Action func(*Context, []string) error Action func(*Context, []string) error
@ -358,6 +366,8 @@ type Uint64SliceFlag struct {
defaultValue *Uint64Slice defaultValue *Uint64Slice
separator separatorSpec
Action func(*Context, []uint64) error Action func(*Context, []uint64) error
} }
@ -402,6 +412,8 @@ type UintSliceFlag struct {
defaultValue *UintSlice defaultValue *UintSlice
separator separatorSpec
Action func(*Context, []uint) error Action func(*Context, []uint) error
} }

View file

@ -33,6 +33,7 @@ const (
// config represents the configuration options available for the http.Handler // config represents the configuration options available for the http.Handler
// and http.Transport types. // and http.Transport types.
type config struct { type config struct {
ServerName string
Tracer trace.Tracer Tracer trace.Tracer
Meter metric.Meter Meter metric.Meter
Propagators propagation.TextMapPropagator Propagators propagation.TextMapPropagator
@ -198,3 +199,11 @@ func WithClientTrace(f func(context.Context) *httptrace.ClientTrace) Option {
c.ClientTrace = f c.ClientTrace = f
}) })
} }
// WithServerName returns an Option that sets the name of the (virtual) server
// handling requests.
func WithServerName(server string) Option {
return optionFunc(func(c *config) {
c.ServerName = server
})
}

View file

@ -24,10 +24,10 @@ import (
"go.opentelemetry.io/otel" "go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/instrument/syncfloat64" "go.opentelemetry.io/otel/metric/instrument"
"go.opentelemetry.io/otel/metric/instrument/syncint64"
"go.opentelemetry.io/otel/propagation" "go.opentelemetry.io/otel/propagation"
semconv "go.opentelemetry.io/otel/semconv/v1.12.0" semconv "go.opentelemetry.io/otel/semconv/v1.17.0"
"go.opentelemetry.io/otel/semconv/v1.17.0/httpconv"
"go.opentelemetry.io/otel/trace" "go.opentelemetry.io/otel/trace"
) )
@ -39,6 +39,7 @@ var _ http.Handler = &Handler{}
// to the span using the attribute.Keys defined in this package. // to the span using the attribute.Keys defined in this package.
type Handler struct { type Handler struct {
operation string operation string
server string
handler http.Handler handler http.Handler
tracer trace.Tracer tracer trace.Tracer
@ -49,8 +50,8 @@ type Handler struct {
writeEvent bool writeEvent bool
filters []Filter filters []Filter
spanNameFormatter func(string, *http.Request) string spanNameFormatter func(string, *http.Request) string
counters map[string]syncint64.Counter counters map[string]instrument.Int64Counter
valueRecorders map[string]syncfloat64.Histogram valueRecorders map[string]instrument.Float64Histogram
publicEndpoint bool publicEndpoint bool
publicEndpointFn func(*http.Request) bool publicEndpointFn func(*http.Request) bool
} }
@ -90,6 +91,7 @@ func (h *Handler) configure(c *config) {
h.spanNameFormatter = c.SpanNameFormatter h.spanNameFormatter = c.SpanNameFormatter
h.publicEndpoint = c.PublicEndpoint h.publicEndpoint = c.PublicEndpoint
h.publicEndpointFn = c.PublicEndpointFn h.publicEndpointFn = c.PublicEndpointFn
h.server = c.ServerName
} }
func handleErr(err error) { func handleErr(err error) {
@ -99,16 +101,16 @@ func handleErr(err error) {
} }
func (h *Handler) createMeasures() { func (h *Handler) createMeasures() {
h.counters = make(map[string]syncint64.Counter) h.counters = make(map[string]instrument.Int64Counter)
h.valueRecorders = make(map[string]syncfloat64.Histogram) h.valueRecorders = make(map[string]instrument.Float64Histogram)
requestBytesCounter, err := h.meter.SyncInt64().Counter(RequestContentLength) requestBytesCounter, err := h.meter.Int64Counter(RequestContentLength)
handleErr(err) handleErr(err)
responseBytesCounter, err := h.meter.SyncInt64().Counter(ResponseContentLength) responseBytesCounter, err := h.meter.Int64Counter(ResponseContentLength)
handleErr(err) handleErr(err)
serverLatencyMeasure, err := h.meter.SyncFloat64().Histogram(ServerLatency) serverLatencyMeasure, err := h.meter.Float64Histogram(ServerLatency)
handleErr(err) handleErr(err)
h.counters[RequestContentLength] = requestBytesCounter h.counters[RequestContentLength] = requestBytesCounter
@ -128,7 +130,14 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
ctx := h.propagators.Extract(r.Context(), propagation.HeaderCarrier(r.Header)) ctx := h.propagators.Extract(r.Context(), propagation.HeaderCarrier(r.Header))
opts := h.spanStartOptions opts := []trace.SpanStartOption{
trace.WithAttributes(httpconv.ServerRequest(h.server, r)...),
}
if h.server != "" {
hostAttr := semconv.NetHostNameKey.String(h.server)
opts = append(opts, trace.WithAttributes(hostAttr))
}
opts = append(opts, h.spanStartOptions...)
if h.publicEndpoint || (h.publicEndpointFn != nil && h.publicEndpointFn(r.WithContext(ctx))) { if h.publicEndpoint || (h.publicEndpointFn != nil && h.publicEndpointFn(r.WithContext(ctx))) {
opts = append(opts, trace.WithNewRoot()) opts = append(opts, trace.WithNewRoot())
// Linking incoming span context if any for public endpoint. // Linking incoming span context if any for public endpoint.
@ -137,12 +146,6 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
} }
opts = append([]trace.SpanStartOption{
trace.WithAttributes(semconv.NetAttributesFromHTTPRequest("tcp", r)...),
trace.WithAttributes(semconv.EndUserAttributesFromHTTPRequest(r)...),
trace.WithAttributes(semconv.HTTPServerAttributesFromHTTPRequest(h.operation, "", r)...),
}, opts...) // start with the configured options
tracer := h.tracer tracer := h.tracer
if tracer == nil { if tracer == nil {
@ -212,7 +215,10 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
setAfterServeAttributes(span, bw.read, rww.written, rww.statusCode, bw.err, rww.err) setAfterServeAttributes(span, bw.read, rww.written, rww.statusCode, bw.err, rww.err)
// Add metrics // Add metrics
attributes := append(labeler.Get(), semconv.HTTPServerMetricAttributesFromHTTPRequest(h.operation, r)...) attributes := append(labeler.Get(), httpconv.ServerRequest(h.server, r)...)
if rww.statusCode > 0 {
attributes = append(attributes, semconv.HTTPStatusCodeKey.Int(rww.statusCode))
}
h.counters[RequestContentLength].Add(ctx, bw.read, attributes...) h.counters[RequestContentLength].Add(ctx, bw.read, attributes...)
h.counters[ResponseContentLength].Add(ctx, rww.written, attributes...) h.counters[ResponseContentLength].Add(ctx, rww.written, attributes...)
@ -236,8 +242,10 @@ func setAfterServeAttributes(span trace.Span, read, wrote int64, statusCode int,
if wrote > 0 { if wrote > 0 {
attributes = append(attributes, WroteBytesKey.Int64(wrote)) attributes = append(attributes, WroteBytesKey.Int64(wrote))
} }
attributes = append(attributes, semconv.HTTPAttributesFromHTTPStatusCode(statusCode)...) if statusCode > 0 {
span.SetStatus(semconv.SpanStatusFromHTTPStatusCodeAndSpanKind(statusCode, trace.SpanKindServer)) attributes = append(attributes, semconv.HTTPStatusCodeKey.Int(statusCode))
}
span.SetStatus(httpconv.ServerStatus(statusCode))
if werr != nil && werr != io.EOF { if werr != nil && werr != io.EOF {
attributes = append(attributes, WriteErrorKey.String(werr.Error())) attributes = append(attributes, WriteErrorKey.String(werr.Error()))

View file

@ -23,7 +23,7 @@ import (
"go.opentelemetry.io/otel" "go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/propagation" "go.opentelemetry.io/otel/propagation"
semconv "go.opentelemetry.io/otel/semconv/v1.12.0" "go.opentelemetry.io/otel/semconv/v1.17.0/httpconv"
"go.opentelemetry.io/otel/trace" "go.opentelemetry.io/otel/trace"
) )
@ -110,7 +110,7 @@ func (t *Transport) RoundTrip(r *http.Request) (*http.Response, error) {
} }
r = r.WithContext(ctx) r = r.WithContext(ctx)
span.SetAttributes(semconv.HTTPClientAttributesFromHTTPRequest(r)...) span.SetAttributes(httpconv.ClientRequest(r)...)
t.propagators.Inject(ctx, propagation.HeaderCarrier(r.Header)) t.propagators.Inject(ctx, propagation.HeaderCarrier(r.Header))
res, err := t.rt.RoundTrip(r) res, err := t.rt.RoundTrip(r)
@ -121,8 +121,8 @@ func (t *Transport) RoundTrip(r *http.Request) (*http.Response, error) {
return res, err return res, err
} }
span.SetAttributes(semconv.HTTPAttributesFromHTTPStatusCode(res.StatusCode)...) span.SetAttributes(httpconv.ClientResponse(res)...)
span.SetStatus(semconv.SpanStatusFromHTTPStatusCode(res.StatusCode)) span.SetStatus(httpconv.ClientStatus(res.StatusCode))
res.Body = newWrappedBody(span, res.Body) res.Body = newWrappedBody(span, res.Body)
return res, err return res, err

View file

@ -16,7 +16,7 @@ package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http
// Version is the current release version of the otelhttp instrumentation. // Version is the current release version of the otelhttp instrumentation.
func Version() string { func Version() string {
return "0.37.0" return "0.38.0"
// This string is updated by the pre_release.sh script during release // This string is updated by the pre_release.sh script during release
} }

View file

@ -1,3 +1,4 @@
http://localhost http://localhost
http://jaeger-collector http://jaeger-collector
https://github.com/open-telemetry/opentelemetry-go/milestone/ https://github.com/open-telemetry/opentelemetry-go/milestone/
https://github.com/open-telemetry/opentelemetry-go/projects

View file

@ -8,6 +8,139 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
## [Unreleased] ## [Unreleased]
## [1.12.0/0.35.0] 2023-01-28
### Added
- The `WithInt64Callback` option to `go.opentelemetry.io/otel/metric/instrument`.
This options is used to configure `int64` Observer callbacks during their creation. (#3507)
- The `WithFloat64Callback` option to `go.opentelemetry.io/otel/metric/instrument`.
This options is used to configure `float64` Observer callbacks during their creation. (#3507)
- The `Producer` interface and `Reader.RegisterProducer(Producer)` to `go.opentelemetry.io/otel/sdk/metric`.
These additions are used to enable external metric Producers. (#3524)
- The `Callback` function type to `go.opentelemetry.io/otel/metric`.
This new named function type is registered with a `Meter`. (#3564)
- The `go.opentelemetry.io/otel/semconv/v1.13.0` package.
The package contains semantic conventions from the `v1.13.0` version of the OpenTelemetry specification. (#3499)
- The `EndUserAttributesFromHTTPRequest` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is merged into `ClientRequest` and `ServerRequest` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`.
- The `HTTPAttributesFromHTTPStatusCode` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is merged into `ClientResponse` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`.
- The `HTTPClientAttributesFromHTTPRequest` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is replaced by `ClientRequest` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`.
- The `HTTPServerAttributesFromHTTPRequest` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is replaced by `ServerRequest` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`.
- The `HTTPServerMetricAttributesFromHTTPRequest` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is replaced by `ServerRequest` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`.
- The `NetAttributesFromHTTPRequest` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is split into `Transport` in `go.opentelemetry.io/otel/semconv/v1.13.0/netconv` and `ClientRequest` or `ServerRequest` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`.
- The `SpanStatusFromHTTPStatusCode` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is replaced by `ClientStatus` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`.
- The `SpanStatusFromHTTPStatusCodeAndSpanKind` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is split into `ClientStatus` and `ServerStatus` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`.
- The `Client` function is included in `go.opentelemetry.io/otel/semconv/v1.13.0/netconv` to generate attributes for a `net.Conn`.
- The `Server` function is included in `go.opentelemetry.io/otel/semconv/v1.13.0/netconv` to generate attributes for a `net.Listener`.
- The `go.opentelemetry.io/otel/semconv/v1.14.0` package.
The package contains semantic conventions from the `v1.14.0` version of the OpenTelemetry specification. (#3566)
- The `go.opentelemetry.io/otel/semconv/v1.15.0` package.
The package contains semantic conventions from the `v1.15.0` version of the OpenTelemetry specification. (#3578)
- The `go.opentelemetry.io/otel/semconv/v1.16.0` package.
The package contains semantic conventions from the `v1.16.0` version of the OpenTelemetry specification. (#3579)
- Metric instruments to `go.opentelemetry.io/otel/metric/instrument`.
These instruments are use as replacements of the depreacted `go.opentelemetry.io/otel/metric/instrument/{asyncfloat64,asyncint64,syncfloat64,syncint64}` packages.(#3575, #3586)
- `Float64ObservableCounter` replaces the `asyncfloat64.Counter`
- `Float64ObservableUpDownCounter` replaces the `asyncfloat64.UpDownCounter`
- `Float64ObservableGauge` replaces the `asyncfloat64.Gauge`
- `Int64ObservableCounter` replaces the `asyncint64.Counter`
- `Int64ObservableUpDownCounter` replaces the `asyncint64.UpDownCounter`
- `Int64ObservableGauge` replaces the `asyncint64.Gauge`
- `Float64Counter` replaces the `syncfloat64.Counter`
- `Float64UpDownCounter` replaces the `syncfloat64.UpDownCounter`
- `Float64Histogram` replaces the `syncfloat64.Histogram`
- `Int64Counter` replaces the `syncint64.Counter`
- `Int64UpDownCounter` replaces the `syncint64.UpDownCounter`
- `Int64Histogram` replaces the `syncint64.Histogram`
- `NewTracerProvider` to `go.opentelemetry.io/otel/bridge/opentracing`.
This is used to create `WrapperTracer` instances from a `TracerProvider`. (#3116)
- The `Extrema` type to `go.opentelemetry.io/otel/sdk/metric/metricdata`.
This type is used to represent min/max values and still be able to distinguish unset and zero values. (#3487)
- The `go.opentelemetry.io/otel/semconv/v1.17.0` package.
The package contains semantic conventions from the `v1.17.0` version of the OpenTelemetry specification. (#3599)
### Changed
- Jaeger and Zipkin exporter use `github.com/go-logr/logr` as the logging interface, and add the `WithLogr` option. (#3497, #3500)
- Instrument configuration in `go.opentelemetry.io/otel/metric/instrument` is split into specific options and confguration based on the instrument type. (#3507)
- Use the added `Int64Option` type to configure instruments from `go.opentelemetry.io/otel/metric/instrument/syncint64`.
- Use the added `Float64Option` type to configure instruments from `go.opentelemetry.io/otel/metric/instrument/syncfloat64`.
- Use the added `Int64ObserverOption` type to configure instruments from `go.opentelemetry.io/otel/metric/instrument/asyncint64`.
- Use the added `Float64ObserverOption` type to configure instruments from `go.opentelemetry.io/otel/metric/instrument/asyncfloat64`.
- Return a `Registration` from the `RegisterCallback` method of a `Meter` in the `go.opentelemetry.io/otel/metric` package.
This `Registration` can be used to unregister callbacks. (#3522)
- Global error handler uses an atomic value instead of a mutex. (#3543)
- Add `NewMetricProducer` to `go.opentelemetry.io/otel/bridge/opencensus`, which can be used to pass OpenCensus metrics to an OpenTelemetry Reader. (#3541)
- Global logger uses an atomic value instead of a mutex. (#3545)
- The `Shutdown` method of the `"go.opentelemetry.io/otel/sdk/trace".TracerProvider` releases all computational resources when called the first time. (#3551)
- The `Sampler` returned from `TraceIDRatioBased` `go.opentelemetry.io/otel/sdk/trace` now uses the rightmost bits for sampling decisions.
This fixes random sampling when using ID generators like `xray.IDGenerator` and increasing parity with other language implementations. (#3557)
- Errors from `go.opentelemetry.io/otel/exporters/otlp/otlptrace` exporters are wrapped in erros identifying their signal name.
Existing users of the exporters attempting to identify specific errors will need to use `errors.Unwrap()` to get the underlying error. (#3516)
- Exporters from `go.opentelemetry.io/otel/exporters/otlp` will print the final retryable error message when attempts to retry time out. (#3514)
- The instrument kind names in `go.opentelemetry.io/otel/sdk/metric` are updated to match the API. (#3562)
- `InstrumentKindSyncCounter` is renamed to `InstrumentKindCounter`
- `InstrumentKindSyncUpDownCounter` is renamed to `InstrumentKindUpDownCounter`
- `InstrumentKindSyncHistogram` is renamed to `InstrumentKindHistogram`
- `InstrumentKindAsyncCounter` is renamed to `InstrumentKindObservableCounter`
- `InstrumentKindAsyncUpDownCounter` is renamed to `InstrumentKindObservableUpDownCounter`
- `InstrumentKindAsyncGauge` is renamed to `InstrumentKindObservableGauge`
- The `RegisterCallback` method of the `Meter` in `go.opentelemetry.io/otel/metric` changed.
- The named `Callback` replaces the inline function parameter. (#3564)
- `Callback` is required to return an error. (#3576)
- `Callback` accepts the added `Observer` parameter added.
This new parameter is used by `Callback` implementations to observe values for asynchronous instruments instead of calling the `Observe` method of the instrument directly. (#3584)
- The slice of `instrument.Asynchronous` is now passed as a variadic argument. (#3587)
- The exporter from `go.opentelemetry.io/otel/exporters/zipkin` is updated to use the `v1.16.0` version of semantic conventions.
This means it no longer uses the removed `net.peer.ip` or `http.host` attributes to determine the remote endpoint.
Instead it uses the `net.sock.peer` attributes. (#3581)
- The `Min` and `Max` fields of the `HistogramDataPoint` in `go.opentelemetry.io/otel/sdk/metric/metricdata` are now defined with the added `Extrema` type instead of a `*float64`. (#3487)
### Fixed
- Asynchronous instruments that use sum aggregators and attribute filters correctly add values from equivalent attribute sets that have been filtered. (#3439, #3549)
- The `RegisterCallback` method of the `Meter` from `go.opentelemetry.io/otel/sdk/metric` only registers a callback for instruments created by that meter.
Trying to register a callback with instruments from a different meter will result in an error being returned. (#3584)
### Deprecated
- The `NewMetricExporter` in `go.opentelemetry.io/otel/bridge/opencensus` is deprecated.
Use `NewMetricProducer` instead. (#3541)
- The `go.opentelemetry.io/otel/metric/instrument/asyncfloat64` package is deprecated.
Use the instruments from `go.opentelemetry.io/otel/metric/instrument` instead. (#3575)
- The `go.opentelemetry.io/otel/metric/instrument/asyncint64` package is deprecated.
Use the instruments from `go.opentelemetry.io/otel/metric/instrument` instead. (#3575)
- The `go.opentelemetry.io/otel/metric/instrument/syncfloat64` package is deprecated.
Use the instruments from `go.opentelemetry.io/otel/metric/instrument` instead. (#3575)
- The `go.opentelemetry.io/otel/metric/instrument/syncint64` package is deprecated.
Use the instruments from `go.opentelemetry.io/otel/metric/instrument` instead. (#3575)
- The `NewWrappedTracerProvider` in `go.opentelemetry.io/otel/bridge/opentracing` is now deprecated.
Use `NewTracerProvider` instead. (#3116)
### Removed
- The deprecated `go.opentelemetry.io/otel/sdk/metric/view` package is removed. (#3520)
- The `InstrumentProvider` from `go.opentelemetry.io/otel/sdk/metric/asyncint64` is removed.
Use the new creation methods of the `Meter` in `go.opentelemetry.io/otel/sdk/metric` instead. (#3530)
- The `Counter` method is replaced by `Meter.Int64ObservableCounter`
- The `UpDownCounter` method is replaced by `Meter.Int64ObservableUpDownCounter`
- The `Gauge` method is replaced by `Meter.Int64ObservableGauge`
- The `InstrumentProvider` from `go.opentelemetry.io/otel/sdk/metric/asyncfloat64` is removed.
Use the new creation methods of the `Meter` in `go.opentelemetry.io/otel/sdk/metric` instead. (#3530)
- The `Counter` method is replaced by `Meter.Float64ObservableCounter`
- The `UpDownCounter` method is replaced by `Meter.Float64ObservableUpDownCounter`
- The `Gauge` method is replaced by `Meter.Float64ObservableGauge`
- The `InstrumentProvider` from `go.opentelemetry.io/otel/sdk/metric/syncint64` is removed.
Use the new creation methods of the `Meter` in `go.opentelemetry.io/otel/sdk/metric` instead. (#3530)
- The `Counter` method is replaced by `Meter.Int64Counter`
- The `UpDownCounter` method is replaced by `Meter.Int64UpDownCounter`
- The `Histogram` method is replaced by `Meter.Int64Histogram`
- The `InstrumentProvider` from `go.opentelemetry.io/otel/sdk/metric/syncfloat64` is removed.
Use the new creation methods of the `Meter` in `go.opentelemetry.io/otel/sdk/metric` instead. (#3530)
- The `Counter` method is replaced by `Meter.Float64Counter`
- The `UpDownCounter` method is replaced by `Meter.Float64UpDownCounter`
- The `Histogram` method is replaced by `Meter.Float64Histogram`
## [1.11.2/0.34.0] 2022-12-05 ## [1.11.2/0.34.0] 2022-12-05
### Added ### Added
@ -58,7 +191,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Prevent duplicate Prometheus description, unit, and type. (#3469) - Prevent duplicate Prometheus description, unit, and type. (#3469)
- Prevents panic when using incorrect `attribute.Value.As[Type]Slice()`. (#3489) - Prevents panic when using incorrect `attribute.Value.As[Type]Slice()`. (#3489)
## Removed ### Removed
- The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric.Client` interface is removed. (#3486) - The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric.Client` interface is removed. (#3486)
- The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric.New` function is removed. Use the `otlpmetric[http|grpc].New` directly. (#3486) - The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric.New` function is removed. Use the `otlpmetric[http|grpc].New` directly. (#3486)
@ -2087,7 +2220,8 @@ It contains api and sdk for trace and meter.
- CircleCI build CI manifest files. - CircleCI build CI manifest files.
- CODEOWNERS file to track owners of this project. - CODEOWNERS file to track owners of this project.
[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.11.2...HEAD [Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.12.0...HEAD
[1.12.0/0.35.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.12.0
[1.11.2/0.34.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.11.2 [1.11.2/0.34.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.11.2
[1.11.1/0.33.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.11.1 [1.11.1/0.33.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.11.1
[1.11.0/0.32.3]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.11.0 [1.11.0/0.32.3]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.11.0

View file

@ -208,11 +208,11 @@ check-clean-work-tree:
SEMCONVPKG ?= "semconv/" SEMCONVPKG ?= "semconv/"
.PHONY: semconv-generate .PHONY: semconv-generate
semconv-generate: | $(SEMCONVGEN) $(SEMCONVKIT) semconv-generate: | $(SEMCONVGEN) $(SEMCONVKIT)
@[ "$(TAG)" ] || ( echo "TAG unset: missing opentelemetry specification tag"; exit 1 ) [ "$(TAG)" ] || ( echo "TAG unset: missing opentelemetry specification tag"; exit 1 )
@[ "$(OTEL_SPEC_REPO)" ] || ( echo "OTEL_SPEC_REPO unset: missing path to opentelemetry specification repo"; exit 1 ) [ "$(OTEL_SPEC_REPO)" ] || ( echo "OTEL_SPEC_REPO unset: missing path to opentelemetry specification repo"; exit 1 )
@$(SEMCONVGEN) -i "$(OTEL_SPEC_REPO)/semantic_conventions/trace" -t "$(SEMCONVPKG)/template.j2" -s "$(TAG)" $(SEMCONVGEN) -i "$(OTEL_SPEC_REPO)/semantic_conventions/." --only=span -p conventionType=trace -p conventionType=trace -f trace.go -t "$(SEMCONVPKG)/template.j2" -s "$(TAG)"
@$(SEMCONVGEN) -i "$(OTEL_SPEC_REPO)/semantic_conventions/resource" -t "$(SEMCONVPKG)/template.j2" -s "$(TAG)" $(SEMCONVGEN) -i "$(OTEL_SPEC_REPO)/semantic_conventions/." --only=resource -p conventionType=resource -p conventionType=resource -f resource.go -t "$(SEMCONVPKG)/template.j2" -s "$(TAG)"
@$(SEMCONVKIT) -output "$(SEMCONVPKG)/$(TAG)" -tag "$(TAG)" $(SEMCONVKIT) -output "$(SEMCONVPKG)/$(TAG)" -tag "$(TAG)"
.PHONY: prerelease .PHONY: prerelease
prerelease: | $(MULTIMOD) prerelease: | $(MULTIMOD)

View file

@ -6,20 +6,25 @@ New versions of the [OpenTelemetry specification] mean new versions of the `semc
The `semconv-generate` make target is used for this. The `semconv-generate` make target is used for this.
1. Checkout a local copy of the [OpenTelemetry specification] to the desired release tag. 1. Checkout a local copy of the [OpenTelemetry specification] to the desired release tag.
2. Run the `make semconv-generate ...` target from this repository. 2. Pull the latest `otel/semconvgen` image: `docker pull otel/semconvgen:latest`
3. Run the `make semconv-generate ...` target from this repository.
For example, For example,
```sh ```sh
export TAG="v1.7.0" # Change to the release version you are generating. export TAG="v1.13.0" # Change to the release version you are generating.
export OTEL_SPEC_REPO="/absolute/path/to/opentelemetry-specification" export OTEL_SPEC_REPO="/absolute/path/to/opentelemetry-specification"
git -C "$OTEL_SPEC_REPO" checkout "tags/$TAG" git -C "$OTEL_SPEC_REPO" checkout "tags/$TAG" -b "$TAG"
docker pull otel/semconvgen:latest
make semconv-generate # Uses the exported TAG and OTEL_SPEC_REPO. make semconv-generate # Uses the exported TAG and OTEL_SPEC_REPO.
``` ```
This should create a new sub-package of [`semconv`](./semconv). This should create a new sub-package of [`semconv`](./semconv).
Ensure things look correct before submitting a pull request to include the addition. Ensure things look correct before submitting a pull request to include the addition.
**Note**, the generation code was changed to generate versions >= 1.13.
To generate versions prior to this, checkout the old release of this repository (i.e. [2fe8861](https://github.com/open-telemetry/opentelemetry-go/commit/2fe8861a24e20088c065b116089862caf9e3cd8b)).
## Pre-Release ## Pre-Release
First, decide which module sets will be released and update their versions First, decide which module sets will be released and update their versions

View file

@ -17,7 +17,8 @@ package otel // import "go.opentelemetry.io/otel"
import ( import (
"log" "log"
"os" "os"
"sync" "sync/atomic"
"unsafe"
) )
var ( var (
@ -34,28 +35,26 @@ var (
) )
type delegator struct { type delegator struct {
lock *sync.RWMutex delegate unsafe.Pointer
eh ErrorHandler
} }
func (d *delegator) Handle(err error) { func (d *delegator) Handle(err error) {
d.lock.RLock() d.getDelegate().Handle(err)
defer d.lock.RUnlock() }
d.eh.Handle(err)
func (d *delegator) getDelegate() ErrorHandler {
return *(*ErrorHandler)(atomic.LoadPointer(&d.delegate))
} }
// setDelegate sets the ErrorHandler delegate. // setDelegate sets the ErrorHandler delegate.
func (d *delegator) setDelegate(eh ErrorHandler) { func (d *delegator) setDelegate(eh ErrorHandler) {
d.lock.Lock() atomic.StorePointer(&d.delegate, unsafe.Pointer(&eh))
defer d.lock.Unlock()
d.eh = eh
} }
func defaultErrorHandler() *delegator { func defaultErrorHandler() *delegator {
return &delegator{ d := &delegator{}
lock: &sync.RWMutex{}, d.setDelegate(&errLogger{l: log.New(os.Stderr, "", log.LstdFlags)})
eh: &errLogger{l: log.New(os.Stderr, "", log.LstdFlags)}, return d
}
} }
// errLogger logs errors if no delegate is set, otherwise they are delegated. // errLogger logs errors if no delegate is set, otherwise they are delegated.

View file

@ -17,7 +17,8 @@ package global // import "go.opentelemetry.io/otel/internal/global"
import ( import (
"log" "log"
"os" "os"
"sync" "sync/atomic"
"unsafe"
"github.com/go-logr/logr" "github.com/go-logr/logr"
"github.com/go-logr/stdr" "github.com/go-logr/stdr"
@ -27,37 +28,36 @@ import (
// //
// The default logger uses stdr which is backed by the standard `log.Logger` // The default logger uses stdr which is backed by the standard `log.Logger`
// interface. This logger will only show messages at the Error Level. // interface. This logger will only show messages at the Error Level.
var globalLogger logr.Logger = stdr.New(log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile)) var globalLogger unsafe.Pointer
var globalLoggerLock = &sync.RWMutex{}
func init() {
SetLogger(stdr.New(log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile)))
}
// SetLogger overrides the globalLogger with l. // SetLogger overrides the globalLogger with l.
// //
// To see Info messages use a logger with `l.V(1).Enabled() == true` // To see Info messages use a logger with `l.V(1).Enabled() == true`
// To see Debug messages use a logger with `l.V(5).Enabled() == true`. // To see Debug messages use a logger with `l.V(5).Enabled() == true`.
func SetLogger(l logr.Logger) { func SetLogger(l logr.Logger) {
globalLoggerLock.Lock() atomic.StorePointer(&globalLogger, unsafe.Pointer(&l))
defer globalLoggerLock.Unlock() }
globalLogger = l
func getLogger() logr.Logger {
return *(*logr.Logger)(atomic.LoadPointer(&globalLogger))
} }
// Info prints messages about the general state of the API or SDK. // Info prints messages about the general state of the API or SDK.
// This should usually be less then 5 messages a minute. // This should usually be less then 5 messages a minute.
func Info(msg string, keysAndValues ...interface{}) { func Info(msg string, keysAndValues ...interface{}) {
globalLoggerLock.RLock() getLogger().V(1).Info(msg, keysAndValues...)
defer globalLoggerLock.RUnlock()
globalLogger.V(1).Info(msg, keysAndValues...)
} }
// Error prints messages about exceptional states of the API or SDK. // Error prints messages about exceptional states of the API or SDK.
func Error(err error, msg string, keysAndValues ...interface{}) { func Error(err error, msg string, keysAndValues ...interface{}) {
globalLoggerLock.RLock() getLogger().Error(err, msg, keysAndValues...)
defer globalLoggerLock.RUnlock()
globalLogger.Error(err, msg, keysAndValues...)
} }
// Debug prints messages about all internal changes in the API or SDK. // Debug prints messages about all internal changes in the API or SDK.
func Debug(msg string, keysAndValues ...interface{}) { func Debug(msg string, keysAndValues ...interface{}) {
globalLoggerLock.RLock() getLogger().V(5).Info(msg, keysAndValues...)
defer globalLoggerLock.RUnlock()
globalLogger.V(5).Info(msg, keysAndValues...)
} }

View file

@ -0,0 +1,131 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package instrument // import "go.opentelemetry.io/otel/metric/instrument"
import (
"context"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric/unit"
)
// Float64Observable describes a set of instruments used asynchronously to
// record float64 measurements once per collection cycle. Observations of
// these instruments are only made within a callback.
//
// Warning: methods may be added to this interface in minor releases.
type Float64Observable interface {
Asynchronous
float64Observable()
}
// Float64ObservableCounter is an instrument used to asynchronously record
// increasing float64 measurements once per collection cycle. Observations are
// only made within a callback for this instrument. The value observed is
// assumed the to be the cumulative sum of the count.
//
// Warning: methods may be added to this interface in minor releases.
type Float64ObservableCounter interface{ Float64Observable }
// Float64ObservableUpDownCounter is an instrument used to asynchronously
// record float64 measurements once per collection cycle. Observations are only
// made within a callback for this instrument. The value observed is assumed
// the to be the cumulative sum of the count.
//
// Warning: methods may be added to this interface in minor releases.
type Float64ObservableUpDownCounter interface{ Float64Observable }
// Float64ObservableGauge is an instrument used to asynchronously record
// instantaneous float64 measurements once per collection cycle. Observations
// are only made within a callback for this instrument.
//
// Warning: methods may be added to this interface in minor releases.
type Float64ObservableGauge interface{ Float64Observable }
// Float64Observer is a recorder of float64 measurements.
//
// Warning: methods may be added to this interface in minor releases.
type Float64Observer interface {
Observe(value float64, attributes ...attribute.KeyValue)
}
// Float64Callback is a function registered with a Meter that makes
// observations for a Float64Observerable instrument it is registered with.
// Calls to the Float64Observer record measurement values for the
// Float64Observable.
//
// The function needs to complete in a finite amount of time and the deadline
// of the passed context is expected to be honored.
//
// The function needs to make unique observations across all registered
// Float64Callbacks. Meaning, it should not report measurements with the same
// attributes as another Float64Callbacks also registered for the same
// instrument.
//
// The function needs to be concurrent safe.
type Float64Callback func(context.Context, Float64Observer) error
// Float64ObserverConfig contains options for Asynchronous instruments that
// observe float64 values.
type Float64ObserverConfig struct {
description string
unit unit.Unit
callbacks []Float64Callback
}
// NewFloat64ObserverConfig returns a new Float64ObserverConfig with all opts
// applied.
func NewFloat64ObserverConfig(opts ...Float64ObserverOption) Float64ObserverConfig {
var config Float64ObserverConfig
for _, o := range opts {
config = o.applyFloat64Observer(config)
}
return config
}
// Description returns the Config description.
func (c Float64ObserverConfig) Description() string {
return c.description
}
// Unit returns the Config unit.
func (c Float64ObserverConfig) Unit() unit.Unit {
return c.unit
}
// Callbacks returns the Config callbacks.
func (c Float64ObserverConfig) Callbacks() []Float64Callback {
return c.callbacks
}
// Float64ObserverOption applies options to float64 Observer instruments.
type Float64ObserverOption interface {
applyFloat64Observer(Float64ObserverConfig) Float64ObserverConfig
}
type float64ObserverOptionFunc func(Float64ObserverConfig) Float64ObserverConfig
func (fn float64ObserverOptionFunc) applyFloat64Observer(cfg Float64ObserverConfig) Float64ObserverConfig {
return fn(cfg)
}
// WithFloat64Callback adds callback to be called for an instrument.
func WithFloat64Callback(callback Float64Callback) Float64ObserverOption {
return float64ObserverOptionFunc(func(cfg Float64ObserverConfig) Float64ObserverConfig {
cfg.callbacks = append(cfg.callbacks, callback)
return cfg
})
}

View file

@ -1,80 +0,0 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package asyncfloat64 // import "go.opentelemetry.io/otel/metric/instrument/asyncfloat64"
import (
"context"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric/instrument"
)
// InstrumentProvider provides access to individual instruments.
//
// Warning: methods may be added to this interface in minor releases.
type InstrumentProvider interface {
// Counter creates an instrument for recording increasing values.
Counter(name string, opts ...instrument.Option) (Counter, error)
// UpDownCounter creates an instrument for recording changes of a value.
UpDownCounter(name string, opts ...instrument.Option) (UpDownCounter, error)
// Gauge creates an instrument for recording the current value.
Gauge(name string, opts ...instrument.Option) (Gauge, error)
}
// Counter is an instrument that records increasing values.
//
// Warning: methods may be added to this interface in minor releases.
type Counter interface {
// Observe records the state of the instrument to be x. Implementations
// will assume x to be the cumulative sum of the count.
//
// It is only valid to call this within a callback. If called outside of the
// registered callback it should have no effect on the instrument, and an
// error will be reported via the error handler.
Observe(ctx context.Context, x float64, attrs ...attribute.KeyValue)
instrument.Asynchronous
}
// UpDownCounter is an instrument that records increasing or decreasing values.
//
// Warning: methods may be added to this interface in minor releases.
type UpDownCounter interface {
// Observe records the state of the instrument to be x. Implementations
// will assume x to be the cumulative sum of the count.
//
// It is only valid to call this within a callback. If called outside of the
// registered callback it should have no effect on the instrument, and an
// error will be reported via the error handler.
Observe(ctx context.Context, x float64, attrs ...attribute.KeyValue)
instrument.Asynchronous
}
// Gauge is an instrument that records independent readings.
//
// Warning: methods may be added to this interface in minor releases.
type Gauge interface {
// Observe records the state of the instrument to be x.
//
// It is only valid to call this within a callback. If called outside of the
// registered callback it should have no effect on the instrument, and an
// error will be reported via the error handler.
Observe(ctx context.Context, x float64, attrs ...attribute.KeyValue)
instrument.Asynchronous
}

View file

@ -0,0 +1,131 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package instrument // import "go.opentelemetry.io/otel/metric/instrument"
import (
"context"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric/unit"
)
// Int64Observable describes a set of instruments used asynchronously to record
// int64 measurements once per collection cycle. Observations of these
// instruments are only made within a callback.
//
// Warning: methods may be added to this interface in minor releases.
type Int64Observable interface {
Asynchronous
int64Observable()
}
// Int64ObservableCounter is an instrument used to asynchronously record
// increasing int64 measurements once per collection cycle. Observations are
// only made within a callback for this instrument. The value observed is
// assumed the to be the cumulative sum of the count.
//
// Warning: methods may be added to this interface in minor releases.
type Int64ObservableCounter interface{ Int64Observable }
// Int64ObservableUpDownCounter is an instrument used to asynchronously record
// int64 measurements once per collection cycle. Observations are only made
// within a callback for this instrument. The value observed is assumed the to
// be the cumulative sum of the count.
//
// Warning: methods may be added to this interface in minor releases.
type Int64ObservableUpDownCounter interface{ Int64Observable }
// Int64ObservableGauge is an instrument used to asynchronously record
// instantaneous int64 measurements once per collection cycle. Observations are
// only made within a callback for this instrument.
//
// Warning: methods may be added to this interface in minor releases.
type Int64ObservableGauge interface{ Int64Observable }
// Int64Observer is a recorder of int64 measurements.
//
// Warning: methods may be added to this interface in minor releases.
type Int64Observer interface {
Observe(value int64, attributes ...attribute.KeyValue)
}
// Int64Callback is a function registered with a Meter that makes
// observations for a Int64Observerable instrument it is registered with.
// Calls to the Int64Observer record measurement values for the
// Int64Observable.
//
// The function needs to complete in a finite amount of time and the deadline
// of the passed context is expected to be honored.
//
// The function needs to make unique observations across all registered
// Int64Callback. Meaning, it should not report measurements with the same
// attributes as another Int64Callbacks also registered for the same
// instrument.
//
// The function needs to be concurrent safe.
type Int64Callback func(context.Context, Int64Observer) error
// Int64ObserverConfig contains options for Asynchronous instruments that
// observe int64 values.
type Int64ObserverConfig struct {
description string
unit unit.Unit
callbacks []Int64Callback
}
// NewInt64ObserverConfig returns a new Int64ObserverConfig with all opts
// applied.
func NewInt64ObserverConfig(opts ...Int64ObserverOption) Int64ObserverConfig {
var config Int64ObserverConfig
for _, o := range opts {
config = o.applyInt64Observer(config)
}
return config
}
// Description returns the Config description.
func (c Int64ObserverConfig) Description() string {
return c.description
}
// Unit returns the Config unit.
func (c Int64ObserverConfig) Unit() unit.Unit {
return c.unit
}
// Callbacks returns the Config callbacks.
func (c Int64ObserverConfig) Callbacks() []Int64Callback {
return c.callbacks
}
// Int64ObserverOption applies options to int64 Observer instruments.
type Int64ObserverOption interface {
applyInt64Observer(Int64ObserverConfig) Int64ObserverConfig
}
type int64ObserverOptionFunc func(Int64ObserverConfig) Int64ObserverConfig
func (fn int64ObserverOptionFunc) applyInt64Observer(cfg Int64ObserverConfig) Int64ObserverConfig {
return fn(cfg)
}
// WithInt64Callback adds callback to be called for an instrument.
func WithInt64Callback(callback Int64Callback) Int64ObserverOption {
return int64ObserverOptionFunc(func(cfg Int64ObserverConfig) Int64ObserverConfig {
cfg.callbacks = append(cfg.callbacks, callback)
return cfg
})
}

View file

@ -1,80 +0,0 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package asyncint64 // import "go.opentelemetry.io/otel/metric/instrument/asyncint64"
import (
"context"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric/instrument"
)
// InstrumentProvider provides access to individual instruments.
//
// Warning: methods may be added to this interface in minor releases.
type InstrumentProvider interface {
// Counter creates an instrument for recording increasing values.
Counter(name string, opts ...instrument.Option) (Counter, error)
// UpDownCounter creates an instrument for recording changes of a value.
UpDownCounter(name string, opts ...instrument.Option) (UpDownCounter, error)
// Gauge creates an instrument for recording the current value.
Gauge(name string, opts ...instrument.Option) (Gauge, error)
}
// Counter is an instrument that records increasing values.
//
// Warning: methods may be added to this interface in minor releases.
type Counter interface {
// Observe records the state of the instrument to be x. Implementations
// will assume x to be the cumulative sum of the count.
//
// It is only valid to call this within a callback. If called outside of the
// registered callback it should have no effect on the instrument, and an
// error will be reported via the error handler.
Observe(ctx context.Context, x int64, attrs ...attribute.KeyValue)
instrument.Asynchronous
}
// UpDownCounter is an instrument that records increasing or decreasing values.
//
// Warning: methods may be added to this interface in minor releases.
type UpDownCounter interface {
// Observe records the state of the instrument to be x. Implementations
// will assume x to be the cumulative sum of the count.
//
// It is only valid to call this within a callback. If called outside of the
// registered callback it should have no effect on the instrument, and an
// error will be reported via the error handler.
Observe(ctx context.Context, x int64, attrs ...attribute.KeyValue)
instrument.Asynchronous
}
// Gauge is an instrument that records independent readings.
//
// Warning: methods may be added to this interface in minor releases.
type Gauge interface {
// Observe records the state of the instrument to be x.
//
// It is only valid to call this within a callback. If called outside of the
// registered callback it should have no effect on the instrument, and an
// error will be reported via the error handler.
Observe(ctx context.Context, x int64, attrs ...attribute.KeyValue)
instrument.Asynchronous
}

View file

@ -1,69 +0,0 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package instrument // import "go.opentelemetry.io/otel/metric/instrument"
import "go.opentelemetry.io/otel/metric/unit"
// Config contains options for metric instrument descriptors.
type Config struct {
description string
unit unit.Unit
}
// Description describes the instrument in human-readable terms.
func (cfg Config) Description() string {
return cfg.description
}
// Unit describes the measurement unit for an instrument.
func (cfg Config) Unit() unit.Unit {
return cfg.unit
}
// Option is an interface for applying metric instrument options.
type Option interface {
applyInstrument(Config) Config
}
// NewConfig creates a new Config and applies all the given options.
func NewConfig(opts ...Option) Config {
var config Config
for _, o := range opts {
config = o.applyInstrument(config)
}
return config
}
type optionFunc func(Config) Config
func (fn optionFunc) applyInstrument(cfg Config) Config {
return fn(cfg)
}
// WithDescription applies provided description.
func WithDescription(desc string) Option {
return optionFunc(func(cfg Config) Config {
cfg.description = desc
return cfg
})
}
// WithUnit applies provided unit.
func WithUnit(u unit.Unit) Option {
return optionFunc(func(cfg Config) Config {
cfg.unit = u
return cfg
})
}

View file

@ -14,6 +14,8 @@
package instrument // import "go.opentelemetry.io/otel/metric/instrument" package instrument // import "go.opentelemetry.io/otel/metric/instrument"
import "go.opentelemetry.io/otel/metric/unit"
// Asynchronous instruments are instruments that are updated within a Callback. // Asynchronous instruments are instruments that are updated within a Callback.
// If an instrument is observed outside of it's callback it should be an error. // If an instrument is observed outside of it's callback it should be an error.
// //
@ -28,3 +30,61 @@ type Asynchronous interface {
type Synchronous interface { type Synchronous interface {
synchronous() synchronous()
} }
// Option applies options to all instruments.
type Option interface {
Float64ObserverOption
Int64ObserverOption
Float64Option
Int64Option
}
type descOpt string
func (o descOpt) applyFloat64(c Float64Config) Float64Config {
c.description = string(o)
return c
}
func (o descOpt) applyInt64(c Int64Config) Int64Config {
c.description = string(o)
return c
}
func (o descOpt) applyFloat64Observer(c Float64ObserverConfig) Float64ObserverConfig {
c.description = string(o)
return c
}
func (o descOpt) applyInt64Observer(c Int64ObserverConfig) Int64ObserverConfig {
c.description = string(o)
return c
}
// WithDescription sets the instrument description.
func WithDescription(desc string) Option { return descOpt(desc) }
type unitOpt unit.Unit
func (o unitOpt) applyFloat64(c Float64Config) Float64Config {
c.unit = unit.Unit(o)
return c
}
func (o unitOpt) applyInt64(c Int64Config) Int64Config {
c.unit = unit.Unit(o)
return c
}
func (o unitOpt) applyFloat64Observer(c Float64ObserverConfig) Float64ObserverConfig {
c.unit = unit.Unit(o)
return c
}
func (o unitOpt) applyInt64Observer(c Int64ObserverConfig) Int64ObserverConfig {
c.unit = unit.Unit(o)
return c
}
// WithUnit sets the instrument unit.
func WithUnit(u unit.Unit) Option { return unitOpt(u) }

View file

@ -0,0 +1,86 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package instrument // import "go.opentelemetry.io/otel/metric/instrument"
import (
"context"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric/unit"
)
// Float64Counter is an instrument that records increasing float64 values.
//
// Warning: methods may be added to this interface in minor releases.
type Float64Counter interface {
// Add records a change to the counter.
Add(ctx context.Context, incr float64, attrs ...attribute.KeyValue)
Synchronous
}
// Float64UpDownCounter is an instrument that records increasing or decreasing
// float64 values.
//
// Warning: methods may be added to this interface in minor releases.
type Float64UpDownCounter interface {
// Add records a change to the counter.
Add(ctx context.Context, incr float64, attrs ...attribute.KeyValue)
Synchronous
}
// Float64Histogram is an instrument that records a distribution of float64
// values.
//
// Warning: methods may be added to this interface in minor releases.
type Float64Histogram interface {
// Record adds an additional value to the distribution.
Record(ctx context.Context, incr float64, attrs ...attribute.KeyValue)
Synchronous
}
// Float64Config contains options for Asynchronous instruments that
// observe float64 values.
type Float64Config struct {
description string
unit unit.Unit
}
// Float64Config contains options for Synchronous instruments that record
// float64 values.
func NewFloat64Config(opts ...Float64Option) Float64Config {
var config Float64Config
for _, o := range opts {
config = o.applyFloat64(config)
}
return config
}
// Description returns the Config description.
func (c Float64Config) Description() string {
return c.description
}
// Unit returns the Config unit.
func (c Float64Config) Unit() unit.Unit {
return c.unit
}
// Float64Option applies options to synchronous float64 instruments.
type Float64Option interface {
applyFloat64(Float64Config) Float64Config
}

View file

@ -1,64 +0,0 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package syncfloat64 // import "go.opentelemetry.io/otel/metric/instrument/syncfloat64"
import (
"context"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric/instrument"
)
// InstrumentProvider provides access to individual instruments.
//
// Warning: methods may be added to this interface in minor releases.
type InstrumentProvider interface {
// Counter creates an instrument for recording increasing values.
Counter(name string, opts ...instrument.Option) (Counter, error)
// UpDownCounter creates an instrument for recording changes of a value.
UpDownCounter(name string, opts ...instrument.Option) (UpDownCounter, error)
// Histogram creates an instrument for recording a distribution of values.
Histogram(name string, opts ...instrument.Option) (Histogram, error)
}
// Counter is an instrument that records increasing values.
//
// Warning: methods may be added to this interface in minor releases.
type Counter interface {
// Add records a change to the counter.
Add(ctx context.Context, incr float64, attrs ...attribute.KeyValue)
instrument.Synchronous
}
// UpDownCounter is an instrument that records increasing or decreasing values.
//
// Warning: methods may be added to this interface in minor releases.
type UpDownCounter interface {
// Add records a change to the counter.
Add(ctx context.Context, incr float64, attrs ...attribute.KeyValue)
instrument.Synchronous
}
// Histogram is an instrument that records a distribution of values.
//
// Warning: methods may be added to this interface in minor releases.
type Histogram interface {
// Record adds an additional value to the distribution.
Record(ctx context.Context, incr float64, attrs ...attribute.KeyValue)
instrument.Synchronous
}

View file

@ -12,53 +12,75 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package syncint64 // import "go.opentelemetry.io/otel/metric/instrument/syncint64" package instrument // import "go.opentelemetry.io/otel/metric/instrument"
import ( import (
"context" "context"
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric/instrument" "go.opentelemetry.io/otel/metric/unit"
) )
// InstrumentProvider provides access to individual instruments. // Int64Counter is an instrument that records increasing int64 values.
// //
// Warning: methods may be added to this interface in minor releases. // Warning: methods may be added to this interface in minor releases.
type InstrumentProvider interface { type Int64Counter interface {
// Counter creates an instrument for recording increasing values.
Counter(name string, opts ...instrument.Option) (Counter, error)
// UpDownCounter creates an instrument for recording changes of a value.
UpDownCounter(name string, opts ...instrument.Option) (UpDownCounter, error)
// Histogram creates an instrument for recording a distribution of values.
Histogram(name string, opts ...instrument.Option) (Histogram, error)
}
// Counter is an instrument that records increasing values.
//
// Warning: methods may be added to this interface in minor releases.
type Counter interface {
// Add records a change to the counter. // Add records a change to the counter.
Add(ctx context.Context, incr int64, attrs ...attribute.KeyValue) Add(ctx context.Context, incr int64, attrs ...attribute.KeyValue)
instrument.Synchronous Synchronous
} }
// UpDownCounter is an instrument that records increasing or decreasing values. // Int64UpDownCounter is an instrument that records increasing or decreasing
// int64 values.
// //
// Warning: methods may be added to this interface in minor releases. // Warning: methods may be added to this interface in minor releases.
type UpDownCounter interface { type Int64UpDownCounter interface {
// Add records a change to the counter. // Add records a change to the counter.
Add(ctx context.Context, incr int64, attrs ...attribute.KeyValue) Add(ctx context.Context, incr int64, attrs ...attribute.KeyValue)
instrument.Synchronous Synchronous
} }
// Histogram is an instrument that records a distribution of values. // Int64Histogram is an instrument that records a distribution of int64
// values.
// //
// Warning: methods may be added to this interface in minor releases. // Warning: methods may be added to this interface in minor releases.
type Histogram interface { type Int64Histogram interface {
// Record adds an additional value to the distribution. // Record adds an additional value to the distribution.
Record(ctx context.Context, incr int64, attrs ...attribute.KeyValue) Record(ctx context.Context, incr int64, attrs ...attribute.KeyValue)
instrument.Synchronous Synchronous
}
// Int64Config contains options for Synchronous instruments that record int64
// values.
type Int64Config struct {
description string
unit unit.Unit
}
// NewInt64Config returns a new Int64Config with all opts
// applied.
func NewInt64Config(opts ...Int64Option) Int64Config {
var config Int64Config
for _, o := range opts {
config = o.applyInt64(config)
}
return config
}
// Description returns the Config description.
func (c Int64Config) Description() string {
return c.description
}
// Unit returns the Config unit.
func (c Int64Config) Unit() unit.Unit {
return c.unit
}
// Int64Option applies options to synchronous int64 instruments.
type Int64Option interface {
applyInt64(Int64Config) Int64Config
} }

View file

@ -22,23 +22,27 @@ import (
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/instrument" "go.opentelemetry.io/otel/metric/instrument"
"go.opentelemetry.io/otel/metric/instrument/asyncfloat64"
"go.opentelemetry.io/otel/metric/instrument/asyncint64"
"go.opentelemetry.io/otel/metric/instrument/syncfloat64"
"go.opentelemetry.io/otel/metric/instrument/syncint64"
) )
type afCounter struct { // unwrapper unwraps to return the underlying instrument implementation.
name string type unwrapper interface {
opts []instrument.Option Unwrap() instrument.Asynchronous
delegate atomic.Value //asyncfloat64.Counter
instrument.Asynchronous
} }
type afCounter struct {
instrument.Float64Observable
name string
opts []instrument.Float64ObserverOption
delegate atomic.Value //instrument.Float64ObservableCounter
}
var _ unwrapper = (*afCounter)(nil)
var _ instrument.Float64ObservableCounter = (*afCounter)(nil)
func (i *afCounter) setDelegate(m metric.Meter) { func (i *afCounter) setDelegate(m metric.Meter) {
ctr, err := m.AsyncFloat64().Counter(i.name, i.opts...) ctr, err := m.Float64ObservableCounter(i.name, i.opts...)
if err != nil { if err != nil {
otel.Handle(err) otel.Handle(err)
return return
@ -46,30 +50,27 @@ func (i *afCounter) setDelegate(m metric.Meter) {
i.delegate.Store(ctr) i.delegate.Store(ctr)
} }
func (i *afCounter) Observe(ctx context.Context, x float64, attrs ...attribute.KeyValue) { func (i *afCounter) Unwrap() instrument.Asynchronous {
if ctr := i.delegate.Load(); ctr != nil { if ctr := i.delegate.Load(); ctr != nil {
ctr.(asyncfloat64.Counter).Observe(ctx, x, attrs...) return ctr.(instrument.Float64ObservableCounter)
}
}
func (i *afCounter) unwrap() instrument.Asynchronous {
if ctr := i.delegate.Load(); ctr != nil {
return ctr.(asyncfloat64.Counter)
} }
return nil return nil
} }
type afUpDownCounter struct { type afUpDownCounter struct {
instrument.Float64Observable
name string name string
opts []instrument.Option opts []instrument.Float64ObserverOption
delegate atomic.Value //asyncfloat64.UpDownCounter delegate atomic.Value //instrument.Float64ObservableUpDownCounter
instrument.Asynchronous
} }
var _ unwrapper = (*afUpDownCounter)(nil)
var _ instrument.Float64ObservableUpDownCounter = (*afUpDownCounter)(nil)
func (i *afUpDownCounter) setDelegate(m metric.Meter) { func (i *afUpDownCounter) setDelegate(m metric.Meter) {
ctr, err := m.AsyncFloat64().UpDownCounter(i.name, i.opts...) ctr, err := m.Float64ObservableUpDownCounter(i.name, i.opts...)
if err != nil { if err != nil {
otel.Handle(err) otel.Handle(err)
return return
@ -77,30 +78,27 @@ func (i *afUpDownCounter) setDelegate(m metric.Meter) {
i.delegate.Store(ctr) i.delegate.Store(ctr)
} }
func (i *afUpDownCounter) Observe(ctx context.Context, x float64, attrs ...attribute.KeyValue) { func (i *afUpDownCounter) Unwrap() instrument.Asynchronous {
if ctr := i.delegate.Load(); ctr != nil { if ctr := i.delegate.Load(); ctr != nil {
ctr.(asyncfloat64.UpDownCounter).Observe(ctx, x, attrs...) return ctr.(instrument.Float64ObservableUpDownCounter)
}
}
func (i *afUpDownCounter) unwrap() instrument.Asynchronous {
if ctr := i.delegate.Load(); ctr != nil {
return ctr.(asyncfloat64.UpDownCounter)
} }
return nil return nil
} }
type afGauge struct { type afGauge struct {
instrument.Float64Observable
name string name string
opts []instrument.Option opts []instrument.Float64ObserverOption
delegate atomic.Value //asyncfloat64.Gauge delegate atomic.Value //instrument.Float64ObservableGauge
instrument.Asynchronous
} }
var _ unwrapper = (*afGauge)(nil)
var _ instrument.Float64ObservableGauge = (*afGauge)(nil)
func (i *afGauge) setDelegate(m metric.Meter) { func (i *afGauge) setDelegate(m metric.Meter) {
ctr, err := m.AsyncFloat64().Gauge(i.name, i.opts...) ctr, err := m.Float64ObservableGauge(i.name, i.opts...)
if err != nil { if err != nil {
otel.Handle(err) otel.Handle(err)
return return
@ -108,30 +106,27 @@ func (i *afGauge) setDelegate(m metric.Meter) {
i.delegate.Store(ctr) i.delegate.Store(ctr)
} }
func (i *afGauge) Observe(ctx context.Context, x float64, attrs ...attribute.KeyValue) { func (i *afGauge) Unwrap() instrument.Asynchronous {
if ctr := i.delegate.Load(); ctr != nil { if ctr := i.delegate.Load(); ctr != nil {
ctr.(asyncfloat64.Gauge).Observe(ctx, x, attrs...) return ctr.(instrument.Float64ObservableGauge)
}
}
func (i *afGauge) unwrap() instrument.Asynchronous {
if ctr := i.delegate.Load(); ctr != nil {
return ctr.(asyncfloat64.Gauge)
} }
return nil return nil
} }
type aiCounter struct { type aiCounter struct {
instrument.Int64Observable
name string name string
opts []instrument.Option opts []instrument.Int64ObserverOption
delegate atomic.Value //asyncint64.Counter delegate atomic.Value //instrument.Int64ObservableCounter
instrument.Asynchronous
} }
var _ unwrapper = (*aiCounter)(nil)
var _ instrument.Int64ObservableCounter = (*aiCounter)(nil)
func (i *aiCounter) setDelegate(m metric.Meter) { func (i *aiCounter) setDelegate(m metric.Meter) {
ctr, err := m.AsyncInt64().Counter(i.name, i.opts...) ctr, err := m.Int64ObservableCounter(i.name, i.opts...)
if err != nil { if err != nil {
otel.Handle(err) otel.Handle(err)
return return
@ -139,30 +134,27 @@ func (i *aiCounter) setDelegate(m metric.Meter) {
i.delegate.Store(ctr) i.delegate.Store(ctr)
} }
func (i *aiCounter) Observe(ctx context.Context, x int64, attrs ...attribute.KeyValue) { func (i *aiCounter) Unwrap() instrument.Asynchronous {
if ctr := i.delegate.Load(); ctr != nil { if ctr := i.delegate.Load(); ctr != nil {
ctr.(asyncint64.Counter).Observe(ctx, x, attrs...) return ctr.(instrument.Int64ObservableCounter)
}
}
func (i *aiCounter) unwrap() instrument.Asynchronous {
if ctr := i.delegate.Load(); ctr != nil {
return ctr.(asyncint64.Counter)
} }
return nil return nil
} }
type aiUpDownCounter struct { type aiUpDownCounter struct {
instrument.Int64Observable
name string name string
opts []instrument.Option opts []instrument.Int64ObserverOption
delegate atomic.Value //asyncint64.UpDownCounter delegate atomic.Value //instrument.Int64ObservableUpDownCounter
instrument.Asynchronous
} }
var _ unwrapper = (*aiUpDownCounter)(nil)
var _ instrument.Int64ObservableUpDownCounter = (*aiUpDownCounter)(nil)
func (i *aiUpDownCounter) setDelegate(m metric.Meter) { func (i *aiUpDownCounter) setDelegate(m metric.Meter) {
ctr, err := m.AsyncInt64().UpDownCounter(i.name, i.opts...) ctr, err := m.Int64ObservableUpDownCounter(i.name, i.opts...)
if err != nil { if err != nil {
otel.Handle(err) otel.Handle(err)
return return
@ -170,30 +162,27 @@ func (i *aiUpDownCounter) setDelegate(m metric.Meter) {
i.delegate.Store(ctr) i.delegate.Store(ctr)
} }
func (i *aiUpDownCounter) Observe(ctx context.Context, x int64, attrs ...attribute.KeyValue) { func (i *aiUpDownCounter) Unwrap() instrument.Asynchronous {
if ctr := i.delegate.Load(); ctr != nil { if ctr := i.delegate.Load(); ctr != nil {
ctr.(asyncint64.UpDownCounter).Observe(ctx, x, attrs...) return ctr.(instrument.Int64ObservableUpDownCounter)
}
}
func (i *aiUpDownCounter) unwrap() instrument.Asynchronous {
if ctr := i.delegate.Load(); ctr != nil {
return ctr.(asyncint64.UpDownCounter)
} }
return nil return nil
} }
type aiGauge struct { type aiGauge struct {
instrument.Int64Observable
name string name string
opts []instrument.Option opts []instrument.Int64ObserverOption
delegate atomic.Value //asyncint64.Gauge delegate atomic.Value //instrument.Int64ObservableGauge
instrument.Asynchronous
} }
var _ unwrapper = (*aiGauge)(nil)
var _ instrument.Int64ObservableGauge = (*aiGauge)(nil)
func (i *aiGauge) setDelegate(m metric.Meter) { func (i *aiGauge) setDelegate(m metric.Meter) {
ctr, err := m.AsyncInt64().Gauge(i.name, i.opts...) ctr, err := m.Int64ObservableGauge(i.name, i.opts...)
if err != nil { if err != nil {
otel.Handle(err) otel.Handle(err)
return return
@ -201,15 +190,9 @@ func (i *aiGauge) setDelegate(m metric.Meter) {
i.delegate.Store(ctr) i.delegate.Store(ctr)
} }
func (i *aiGauge) Observe(ctx context.Context, x int64, attrs ...attribute.KeyValue) { func (i *aiGauge) Unwrap() instrument.Asynchronous {
if ctr := i.delegate.Load(); ctr != nil { if ctr := i.delegate.Load(); ctr != nil {
ctr.(asyncint64.Gauge).Observe(ctx, x, attrs...) return ctr.(instrument.Int64ObservableGauge)
}
}
func (i *aiGauge) unwrap() instrument.Asynchronous {
if ctr := i.delegate.Load(); ctr != nil {
return ctr.(asyncint64.Gauge)
} }
return nil return nil
} }
@ -217,15 +200,17 @@ func (i *aiGauge) unwrap() instrument.Asynchronous {
// Sync Instruments. // Sync Instruments.
type sfCounter struct { type sfCounter struct {
name string name string
opts []instrument.Option opts []instrument.Float64Option
delegate atomic.Value //syncfloat64.Counter delegate atomic.Value //instrument.Float64Counter
instrument.Synchronous instrument.Synchronous
} }
var _ instrument.Float64Counter = (*sfCounter)(nil)
func (i *sfCounter) setDelegate(m metric.Meter) { func (i *sfCounter) setDelegate(m metric.Meter) {
ctr, err := m.SyncFloat64().Counter(i.name, i.opts...) ctr, err := m.Float64Counter(i.name, i.opts...)
if err != nil { if err != nil {
otel.Handle(err) otel.Handle(err)
return return
@ -235,21 +220,23 @@ func (i *sfCounter) setDelegate(m metric.Meter) {
func (i *sfCounter) Add(ctx context.Context, incr float64, attrs ...attribute.KeyValue) { func (i *sfCounter) Add(ctx context.Context, incr float64, attrs ...attribute.KeyValue) {
if ctr := i.delegate.Load(); ctr != nil { if ctr := i.delegate.Load(); ctr != nil {
ctr.(syncfloat64.Counter).Add(ctx, incr, attrs...) ctr.(instrument.Float64Counter).Add(ctx, incr, attrs...)
} }
} }
type sfUpDownCounter struct { type sfUpDownCounter struct {
name string name string
opts []instrument.Option opts []instrument.Float64Option
delegate atomic.Value //syncfloat64.UpDownCounter delegate atomic.Value //instrument.Float64UpDownCounter
instrument.Synchronous instrument.Synchronous
} }
var _ instrument.Float64UpDownCounter = (*sfUpDownCounter)(nil)
func (i *sfUpDownCounter) setDelegate(m metric.Meter) { func (i *sfUpDownCounter) setDelegate(m metric.Meter) {
ctr, err := m.SyncFloat64().UpDownCounter(i.name, i.opts...) ctr, err := m.Float64UpDownCounter(i.name, i.opts...)
if err != nil { if err != nil {
otel.Handle(err) otel.Handle(err)
return return
@ -259,21 +246,23 @@ func (i *sfUpDownCounter) setDelegate(m metric.Meter) {
func (i *sfUpDownCounter) Add(ctx context.Context, incr float64, attrs ...attribute.KeyValue) { func (i *sfUpDownCounter) Add(ctx context.Context, incr float64, attrs ...attribute.KeyValue) {
if ctr := i.delegate.Load(); ctr != nil { if ctr := i.delegate.Load(); ctr != nil {
ctr.(syncfloat64.UpDownCounter).Add(ctx, incr, attrs...) ctr.(instrument.Float64UpDownCounter).Add(ctx, incr, attrs...)
} }
} }
type sfHistogram struct { type sfHistogram struct {
name string name string
opts []instrument.Option opts []instrument.Float64Option
delegate atomic.Value //syncfloat64.Histogram delegate atomic.Value //instrument.Float64Histogram
instrument.Synchronous instrument.Synchronous
} }
var _ instrument.Float64Histogram = (*sfHistogram)(nil)
func (i *sfHistogram) setDelegate(m metric.Meter) { func (i *sfHistogram) setDelegate(m metric.Meter) {
ctr, err := m.SyncFloat64().Histogram(i.name, i.opts...) ctr, err := m.Float64Histogram(i.name, i.opts...)
if err != nil { if err != nil {
otel.Handle(err) otel.Handle(err)
return return
@ -283,21 +272,23 @@ func (i *sfHistogram) setDelegate(m metric.Meter) {
func (i *sfHistogram) Record(ctx context.Context, x float64, attrs ...attribute.KeyValue) { func (i *sfHistogram) Record(ctx context.Context, x float64, attrs ...attribute.KeyValue) {
if ctr := i.delegate.Load(); ctr != nil { if ctr := i.delegate.Load(); ctr != nil {
ctr.(syncfloat64.Histogram).Record(ctx, x, attrs...) ctr.(instrument.Float64Histogram).Record(ctx, x, attrs...)
} }
} }
type siCounter struct { type siCounter struct {
name string name string
opts []instrument.Option opts []instrument.Int64Option
delegate atomic.Value //syncint64.Counter delegate atomic.Value //instrument.Int64Counter
instrument.Synchronous instrument.Synchronous
} }
var _ instrument.Int64Counter = (*siCounter)(nil)
func (i *siCounter) setDelegate(m metric.Meter) { func (i *siCounter) setDelegate(m metric.Meter) {
ctr, err := m.SyncInt64().Counter(i.name, i.opts...) ctr, err := m.Int64Counter(i.name, i.opts...)
if err != nil { if err != nil {
otel.Handle(err) otel.Handle(err)
return return
@ -307,21 +298,23 @@ func (i *siCounter) setDelegate(m metric.Meter) {
func (i *siCounter) Add(ctx context.Context, x int64, attrs ...attribute.KeyValue) { func (i *siCounter) Add(ctx context.Context, x int64, attrs ...attribute.KeyValue) {
if ctr := i.delegate.Load(); ctr != nil { if ctr := i.delegate.Load(); ctr != nil {
ctr.(syncint64.Counter).Add(ctx, x, attrs...) ctr.(instrument.Int64Counter).Add(ctx, x, attrs...)
} }
} }
type siUpDownCounter struct { type siUpDownCounter struct {
name string name string
opts []instrument.Option opts []instrument.Int64Option
delegate atomic.Value //syncint64.UpDownCounter delegate atomic.Value //instrument.Int64UpDownCounter
instrument.Synchronous instrument.Synchronous
} }
var _ instrument.Int64UpDownCounter = (*siUpDownCounter)(nil)
func (i *siUpDownCounter) setDelegate(m metric.Meter) { func (i *siUpDownCounter) setDelegate(m metric.Meter) {
ctr, err := m.SyncInt64().UpDownCounter(i.name, i.opts...) ctr, err := m.Int64UpDownCounter(i.name, i.opts...)
if err != nil { if err != nil {
otel.Handle(err) otel.Handle(err)
return return
@ -331,21 +324,23 @@ func (i *siUpDownCounter) setDelegate(m metric.Meter) {
func (i *siUpDownCounter) Add(ctx context.Context, x int64, attrs ...attribute.KeyValue) { func (i *siUpDownCounter) Add(ctx context.Context, x int64, attrs ...attribute.KeyValue) {
if ctr := i.delegate.Load(); ctr != nil { if ctr := i.delegate.Load(); ctr != nil {
ctr.(syncint64.UpDownCounter).Add(ctx, x, attrs...) ctr.(instrument.Int64UpDownCounter).Add(ctx, x, attrs...)
} }
} }
type siHistogram struct { type siHistogram struct {
name string name string
opts []instrument.Option opts []instrument.Int64Option
delegate atomic.Value //syncint64.Histogram delegate atomic.Value //instrument.Int64Histogram
instrument.Synchronous instrument.Synchronous
} }
var _ instrument.Int64Histogram = (*siHistogram)(nil)
func (i *siHistogram) setDelegate(m metric.Meter) { func (i *siHistogram) setDelegate(m metric.Meter) {
ctr, err := m.SyncInt64().Histogram(i.name, i.opts...) ctr, err := m.Int64Histogram(i.name, i.opts...)
if err != nil { if err != nil {
otel.Handle(err) otel.Handle(err)
return return
@ -355,6 +350,6 @@ func (i *siHistogram) setDelegate(m metric.Meter) {
func (i *siHistogram) Record(ctx context.Context, x int64, attrs ...attribute.KeyValue) { func (i *siHistogram) Record(ctx context.Context, x int64, attrs ...attribute.KeyValue) {
if ctr := i.delegate.Load(); ctr != nil { if ctr := i.delegate.Load(); ctr != nil {
ctr.(syncint64.Histogram).Record(ctx, x, attrs...) ctr.(instrument.Int64Histogram).Record(ctx, x, attrs...)
} }
} }

View file

@ -15,17 +15,13 @@
package global // import "go.opentelemetry.io/otel/metric/internal/global" package global // import "go.opentelemetry.io/otel/metric/internal/global"
import ( import (
"context" "container/list"
"sync" "sync"
"sync/atomic" "sync/atomic"
"go.opentelemetry.io/otel" "go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/instrument" "go.opentelemetry.io/otel/metric/instrument"
"go.opentelemetry.io/otel/metric/instrument/asyncfloat64"
"go.opentelemetry.io/otel/metric/instrument/asyncint64"
"go.opentelemetry.io/otel/metric/instrument/syncfloat64"
"go.opentelemetry.io/otel/metric/instrument/syncint64"
) )
// meterProvider is a placeholder for a configured SDK MeterProvider. // meterProvider is a placeholder for a configured SDK MeterProvider.
@ -109,7 +105,8 @@ type meter struct {
mtx sync.Mutex mtx sync.Mutex
instruments []delegatedInstrument instruments []delegatedInstrument
callbacks []delegatedCallback
registry list.List
delegate atomic.Value // metric.Meter delegate atomic.Value // metric.Meter
} }
@ -135,52 +132,167 @@ func (m *meter) setDelegate(provider metric.MeterProvider) {
inst.setDelegate(meter) inst.setDelegate(meter)
} }
for _, callback := range m.callbacks { for e := m.registry.Front(); e != nil; e = e.Next() {
callback.setDelegate(meter) r := e.Value.(*registration)
r.setDelegate(meter)
m.registry.Remove(e)
} }
m.instruments = nil m.instruments = nil
m.callbacks = nil m.registry.Init()
} }
// AsyncInt64 is the namespace for the Asynchronous Integer instruments. func (m *meter) Int64Counter(name string, options ...instrument.Int64Option) (instrument.Int64Counter, error) {
//
// To Observe data with instruments it must be registered in a callback.
func (m *meter) AsyncInt64() asyncint64.InstrumentProvider {
if del, ok := m.delegate.Load().(metric.Meter); ok { if del, ok := m.delegate.Load().(metric.Meter); ok {
return del.AsyncInt64() return del.Int64Counter(name, options...)
} }
return (*aiInstProvider)(m) m.mtx.Lock()
defer m.mtx.Unlock()
i := &siCounter{name: name, opts: options}
m.instruments = append(m.instruments, i)
return i, nil
} }
// AsyncFloat64 is the namespace for the Asynchronous Float instruments. func (m *meter) Int64UpDownCounter(name string, options ...instrument.Int64Option) (instrument.Int64UpDownCounter, error) {
//
// To Observe data with instruments it must be registered in a callback.
func (m *meter) AsyncFloat64() asyncfloat64.InstrumentProvider {
if del, ok := m.delegate.Load().(metric.Meter); ok { if del, ok := m.delegate.Load().(metric.Meter); ok {
return del.AsyncFloat64() return del.Int64UpDownCounter(name, options...)
} }
return (*afInstProvider)(m) m.mtx.Lock()
defer m.mtx.Unlock()
i := &siUpDownCounter{name: name, opts: options}
m.instruments = append(m.instruments, i)
return i, nil
}
func (m *meter) Int64Histogram(name string, options ...instrument.Int64Option) (instrument.Int64Histogram, error) {
if del, ok := m.delegate.Load().(metric.Meter); ok {
return del.Int64Histogram(name, options...)
}
m.mtx.Lock()
defer m.mtx.Unlock()
i := &siHistogram{name: name, opts: options}
m.instruments = append(m.instruments, i)
return i, nil
}
func (m *meter) Int64ObservableCounter(name string, options ...instrument.Int64ObserverOption) (instrument.Int64ObservableCounter, error) {
if del, ok := m.delegate.Load().(metric.Meter); ok {
return del.Int64ObservableCounter(name, options...)
}
m.mtx.Lock()
defer m.mtx.Unlock()
i := &aiCounter{name: name, opts: options}
m.instruments = append(m.instruments, i)
return i, nil
}
func (m *meter) Int64ObservableUpDownCounter(name string, options ...instrument.Int64ObserverOption) (instrument.Int64ObservableUpDownCounter, error) {
if del, ok := m.delegate.Load().(metric.Meter); ok {
return del.Int64ObservableUpDownCounter(name, options...)
}
m.mtx.Lock()
defer m.mtx.Unlock()
i := &aiUpDownCounter{name: name, opts: options}
m.instruments = append(m.instruments, i)
return i, nil
}
func (m *meter) Int64ObservableGauge(name string, options ...instrument.Int64ObserverOption) (instrument.Int64ObservableGauge, error) {
if del, ok := m.delegate.Load().(metric.Meter); ok {
return del.Int64ObservableGauge(name, options...)
}
m.mtx.Lock()
defer m.mtx.Unlock()
i := &aiGauge{name: name, opts: options}
m.instruments = append(m.instruments, i)
return i, nil
}
func (m *meter) Float64Counter(name string, options ...instrument.Float64Option) (instrument.Float64Counter, error) {
if del, ok := m.delegate.Load().(metric.Meter); ok {
return del.Float64Counter(name, options...)
}
m.mtx.Lock()
defer m.mtx.Unlock()
i := &sfCounter{name: name, opts: options}
m.instruments = append(m.instruments, i)
return i, nil
}
func (m *meter) Float64UpDownCounter(name string, options ...instrument.Float64Option) (instrument.Float64UpDownCounter, error) {
if del, ok := m.delegate.Load().(metric.Meter); ok {
return del.Float64UpDownCounter(name, options...)
}
m.mtx.Lock()
defer m.mtx.Unlock()
i := &sfUpDownCounter{name: name, opts: options}
m.instruments = append(m.instruments, i)
return i, nil
}
func (m *meter) Float64Histogram(name string, options ...instrument.Float64Option) (instrument.Float64Histogram, error) {
if del, ok := m.delegate.Load().(metric.Meter); ok {
return del.Float64Histogram(name, options...)
}
m.mtx.Lock()
defer m.mtx.Unlock()
i := &sfHistogram{name: name, opts: options}
m.instruments = append(m.instruments, i)
return i, nil
}
func (m *meter) Float64ObservableCounter(name string, options ...instrument.Float64ObserverOption) (instrument.Float64ObservableCounter, error) {
if del, ok := m.delegate.Load().(metric.Meter); ok {
return del.Float64ObservableCounter(name, options...)
}
m.mtx.Lock()
defer m.mtx.Unlock()
i := &afCounter{name: name, opts: options}
m.instruments = append(m.instruments, i)
return i, nil
}
func (m *meter) Float64ObservableUpDownCounter(name string, options ...instrument.Float64ObserverOption) (instrument.Float64ObservableUpDownCounter, error) {
if del, ok := m.delegate.Load().(metric.Meter); ok {
return del.Float64ObservableUpDownCounter(name, options...)
}
m.mtx.Lock()
defer m.mtx.Unlock()
i := &afUpDownCounter{name: name, opts: options}
m.instruments = append(m.instruments, i)
return i, nil
}
func (m *meter) Float64ObservableGauge(name string, options ...instrument.Float64ObserverOption) (instrument.Float64ObservableGauge, error) {
if del, ok := m.delegate.Load().(metric.Meter); ok {
return del.Float64ObservableGauge(name, options...)
}
m.mtx.Lock()
defer m.mtx.Unlock()
i := &afGauge{name: name, opts: options}
m.instruments = append(m.instruments, i)
return i, nil
} }
// RegisterCallback captures the function that will be called during Collect. // RegisterCallback captures the function that will be called during Collect.
// func (m *meter) RegisterCallback(f metric.Callback, insts ...instrument.Asynchronous) (metric.Registration, error) {
// It is only valid to call Observe within the scope of the passed function,
// and only on the instruments that were registered with this call.
func (m *meter) RegisterCallback(insts []instrument.Asynchronous, function func(context.Context)) error {
if del, ok := m.delegate.Load().(metric.Meter); ok { if del, ok := m.delegate.Load().(metric.Meter); ok {
insts = unwrapInstruments(insts) insts = unwrapInstruments(insts)
return del.RegisterCallback(insts, function) return del.RegisterCallback(f, insts...)
} }
m.mtx.Lock() m.mtx.Lock()
defer m.mtx.Unlock() defer m.mtx.Unlock()
m.callbacks = append(m.callbacks, delegatedCallback{
instruments: insts,
function: function,
})
return nil reg := &registration{instruments: insts, function: f}
e := m.registry.PushBack(reg)
reg.unreg = func() error {
m.mtx.Lock()
_ = m.registry.Remove(e)
m.mtx.Unlock()
return nil
}
return reg, nil
} }
type wrapped interface { type wrapped interface {
@ -201,147 +313,42 @@ func unwrapInstruments(instruments []instrument.Asynchronous) []instrument.Async
return out return out
} }
// SyncInt64 is the namespace for the Synchronous Integer instruments. type registration struct {
func (m *meter) SyncInt64() syncint64.InstrumentProvider {
if del, ok := m.delegate.Load().(metric.Meter); ok {
return del.SyncInt64()
}
return (*siInstProvider)(m)
}
// SyncFloat64 is the namespace for the Synchronous Float instruments.
func (m *meter) SyncFloat64() syncfloat64.InstrumentProvider {
if del, ok := m.delegate.Load().(metric.Meter); ok {
return del.SyncFloat64()
}
return (*sfInstProvider)(m)
}
type delegatedCallback struct {
instruments []instrument.Asynchronous instruments []instrument.Asynchronous
function func(context.Context) function metric.Callback
unreg func() error
unregMu sync.Mutex
} }
func (c *delegatedCallback) setDelegate(m metric.Meter) { func (c *registration) setDelegate(m metric.Meter) {
insts := unwrapInstruments(c.instruments) insts := unwrapInstruments(c.instruments)
err := m.RegisterCallback(insts, c.function)
c.unregMu.Lock()
defer c.unregMu.Unlock()
if c.unreg == nil {
// Unregister already called.
return
}
reg, err := m.RegisterCallback(c.function, insts...)
if err != nil { if err != nil {
otel.Handle(err) otel.Handle(err)
} }
c.unreg = reg.Unregister
} }
type afInstProvider meter func (c *registration) Unregister() error {
c.unregMu.Lock()
defer c.unregMu.Unlock()
if c.unreg == nil {
// Unregister already called.
return nil
}
// Counter creates an instrument for recording increasing values. var err error
func (ip *afInstProvider) Counter(name string, opts ...instrument.Option) (asyncfloat64.Counter, error) { err, c.unreg = c.unreg(), nil
ip.mtx.Lock() return err
defer ip.mtx.Unlock()
ctr := &afCounter{name: name, opts: opts}
ip.instruments = append(ip.instruments, ctr)
return ctr, nil
}
// UpDownCounter creates an instrument for recording changes of a value.
func (ip *afInstProvider) UpDownCounter(name string, opts ...instrument.Option) (asyncfloat64.UpDownCounter, error) {
ip.mtx.Lock()
defer ip.mtx.Unlock()
ctr := &afUpDownCounter{name: name, opts: opts}
ip.instruments = append(ip.instruments, ctr)
return ctr, nil
}
// Gauge creates an instrument for recording the current value.
func (ip *afInstProvider) Gauge(name string, opts ...instrument.Option) (asyncfloat64.Gauge, error) {
ip.mtx.Lock()
defer ip.mtx.Unlock()
ctr := &afGauge{name: name, opts: opts}
ip.instruments = append(ip.instruments, ctr)
return ctr, nil
}
type aiInstProvider meter
// Counter creates an instrument for recording increasing values.
func (ip *aiInstProvider) Counter(name string, opts ...instrument.Option) (asyncint64.Counter, error) {
ip.mtx.Lock()
defer ip.mtx.Unlock()
ctr := &aiCounter{name: name, opts: opts}
ip.instruments = append(ip.instruments, ctr)
return ctr, nil
}
// UpDownCounter creates an instrument for recording changes of a value.
func (ip *aiInstProvider) UpDownCounter(name string, opts ...instrument.Option) (asyncint64.UpDownCounter, error) {
ip.mtx.Lock()
defer ip.mtx.Unlock()
ctr := &aiUpDownCounter{name: name, opts: opts}
ip.instruments = append(ip.instruments, ctr)
return ctr, nil
}
// Gauge creates an instrument for recording the current value.
func (ip *aiInstProvider) Gauge(name string, opts ...instrument.Option) (asyncint64.Gauge, error) {
ip.mtx.Lock()
defer ip.mtx.Unlock()
ctr := &aiGauge{name: name, opts: opts}
ip.instruments = append(ip.instruments, ctr)
return ctr, nil
}
type sfInstProvider meter
// Counter creates an instrument for recording increasing values.
func (ip *sfInstProvider) Counter(name string, opts ...instrument.Option) (syncfloat64.Counter, error) {
ip.mtx.Lock()
defer ip.mtx.Unlock()
ctr := &sfCounter{name: name, opts: opts}
ip.instruments = append(ip.instruments, ctr)
return ctr, nil
}
// UpDownCounter creates an instrument for recording changes of a value.
func (ip *sfInstProvider) UpDownCounter(name string, opts ...instrument.Option) (syncfloat64.UpDownCounter, error) {
ip.mtx.Lock()
defer ip.mtx.Unlock()
ctr := &sfUpDownCounter{name: name, opts: opts}
ip.instruments = append(ip.instruments, ctr)
return ctr, nil
}
// Histogram creates an instrument for recording a distribution of values.
func (ip *sfInstProvider) Histogram(name string, opts ...instrument.Option) (syncfloat64.Histogram, error) {
ip.mtx.Lock()
defer ip.mtx.Unlock()
ctr := &sfHistogram{name: name, opts: opts}
ip.instruments = append(ip.instruments, ctr)
return ctr, nil
}
type siInstProvider meter
// Counter creates an instrument for recording increasing values.
func (ip *siInstProvider) Counter(name string, opts ...instrument.Option) (syncint64.Counter, error) {
ip.mtx.Lock()
defer ip.mtx.Unlock()
ctr := &siCounter{name: name, opts: opts}
ip.instruments = append(ip.instruments, ctr)
return ctr, nil
}
// UpDownCounter creates an instrument for recording changes of a value.
func (ip *siInstProvider) UpDownCounter(name string, opts ...instrument.Option) (syncint64.UpDownCounter, error) {
ip.mtx.Lock()
defer ip.mtx.Unlock()
ctr := &siUpDownCounter{name: name, opts: opts}
ip.instruments = append(ip.instruments, ctr)
return ctr, nil
}
// Histogram creates an instrument for recording a distribution of values.
func (ip *siInstProvider) Histogram(name string, opts ...instrument.Option) (syncint64.Histogram, error) {
ip.mtx.Lock()
defer ip.mtx.Unlock()
ctr := &siHistogram{name: name, opts: opts}
ip.instruments = append(ip.instruments, ctr)
return ctr, nil
} }

View file

@ -17,11 +17,8 @@ package metric // import "go.opentelemetry.io/otel/metric"
import ( import (
"context" "context"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric/instrument" "go.opentelemetry.io/otel/metric/instrument"
"go.opentelemetry.io/otel/metric/instrument/asyncfloat64"
"go.opentelemetry.io/otel/metric/instrument/asyncint64"
"go.opentelemetry.io/otel/metric/instrument/syncfloat64"
"go.opentelemetry.io/otel/metric/instrument/syncint64"
) )
// MeterProvider provides access to named Meter instances, for instrumenting // MeterProvider provides access to named Meter instances, for instrumenting
@ -41,24 +38,101 @@ type MeterProvider interface {
// //
// Warning: methods may be added to this interface in minor releases. // Warning: methods may be added to this interface in minor releases.
type Meter interface { type Meter interface {
// AsyncInt64 is the namespace for the Asynchronous Integer instruments. // Int64Counter returns a new instrument identified by name and configured
// // with options. The instrument is used to synchronously record increasing
// To Observe data with instruments it must be registered in a callback. // int64 measurements during a computational operation.
AsyncInt64() asyncint64.InstrumentProvider Int64Counter(name string, options ...instrument.Int64Option) (instrument.Int64Counter, error)
// Int64UpDownCounter returns a new instrument identified by name and
// configured with options. The instrument is used to synchronously record
// int64 measurements during a computational operation.
Int64UpDownCounter(name string, options ...instrument.Int64Option) (instrument.Int64UpDownCounter, error)
// Int64Histogram returns a new instrument identified by name and
// configured with options. The instrument is used to synchronously record
// the distribution of int64 measurements during a computational operation.
Int64Histogram(name string, options ...instrument.Int64Option) (instrument.Int64Histogram, error)
// Int64ObservableCounter returns a new instrument identified by name and
// configured with options. The instrument is used to asynchronously record
// increasing int64 measurements once per a measurement collection cycle.
Int64ObservableCounter(name string, options ...instrument.Int64ObserverOption) (instrument.Int64ObservableCounter, error)
// Int64ObservableUpDownCounter returns a new instrument identified by name
// and configured with options. The instrument is used to asynchronously
// record int64 measurements once per a measurement collection cycle.
Int64ObservableUpDownCounter(name string, options ...instrument.Int64ObserverOption) (instrument.Int64ObservableUpDownCounter, error)
// Int64ObservableGauge returns a new instrument identified by name and
// configured with options. The instrument is used to asynchronously record
// instantaneous int64 measurements once per a measurement collection
// cycle.
Int64ObservableGauge(name string, options ...instrument.Int64ObserverOption) (instrument.Int64ObservableGauge, error)
// AsyncFloat64 is the namespace for the Asynchronous Float instruments // Float64Counter returns a new instrument identified by name and
// // configured with options. The instrument is used to synchronously record
// To Observe data with instruments it must be registered in a callback. // increasing float64 measurements during a computational operation.
AsyncFloat64() asyncfloat64.InstrumentProvider Float64Counter(name string, options ...instrument.Float64Option) (instrument.Float64Counter, error)
// Float64UpDownCounter returns a new instrument identified by name and
// configured with options. The instrument is used to synchronously record
// float64 measurements during a computational operation.
Float64UpDownCounter(name string, options ...instrument.Float64Option) (instrument.Float64UpDownCounter, error)
// Float64Histogram returns a new instrument identified by name and
// configured with options. The instrument is used to synchronously record
// the distribution of float64 measurements during a computational
// operation.
Float64Histogram(name string, options ...instrument.Float64Option) (instrument.Float64Histogram, error)
// Float64ObservableCounter returns a new instrument identified by name and
// configured with options. The instrument is used to asynchronously record
// increasing float64 measurements once per a measurement collection cycle.
Float64ObservableCounter(name string, options ...instrument.Float64ObserverOption) (instrument.Float64ObservableCounter, error)
// Float64ObservableUpDownCounter returns a new instrument identified by
// name and configured with options. The instrument is used to
// asynchronously record float64 measurements once per a measurement
// collection cycle.
Float64ObservableUpDownCounter(name string, options ...instrument.Float64ObserverOption) (instrument.Float64ObservableUpDownCounter, error)
// Float64ObservableGauge returns a new instrument identified by name and
// configured with options. The instrument is used to asynchronously record
// instantaneous float64 measurements once per a measurement collection
// cycle.
Float64ObservableGauge(name string, options ...instrument.Float64ObserverOption) (instrument.Float64ObservableGauge, error)
// RegisterCallback captures the function that will be called during Collect. // RegisterCallback registers f to be called during the collection of a
// measurement cycle.
// //
// It is only valid to call Observe within the scope of the passed function, // If Unregister of the returned Registration is called, f needs to be
// and only on the instruments that were registered with this call. // unregistered and not called during collection.
RegisterCallback(insts []instrument.Asynchronous, function func(context.Context)) error //
// The instruments f is registered with are the only instruments that f may
// SyncInt64 is the namespace for the Synchronous Integer instruments // observe values for.
SyncInt64() syncint64.InstrumentProvider //
// SyncFloat64 is the namespace for the Synchronous Float instruments // If no instruments are passed, f should not be registered nor called
SyncFloat64() syncfloat64.InstrumentProvider // during collection.
RegisterCallback(f Callback, instruments ...instrument.Asynchronous) (Registration, error)
}
// Callback is a function registered with a Meter that makes observations for
// the set of instruments it is registered with. The Observer parameter is used
// to record measurment observations for these instruments.
//
// The function needs to complete in a finite amount of time and the deadline
// of the passed context is expected to be honored.
//
// The function needs to make unique observations across all registered
// Callbacks. Meaning, it should not report measurements for an instrument with
// the same attributes as another Callback will report.
//
// The function needs to be concurrent safe.
type Callback func(context.Context, Observer) error
// Observer records measurements for multiple instruments in a Callback.
type Observer interface {
// ObserveFloat64 records the float64 value with attributes for obsrv.
ObserveFloat64(obsrv instrument.Float64Observable, value float64, attributes ...attribute.KeyValue)
// ObserveInt64 records the int64 value with attributes for obsrv.
ObserveInt64(obsrv instrument.Int64Observable, value int64, attributes ...attribute.KeyValue)
}
// Registration is an token representing the unique registration of a callback
// for a set of instruments with a Meter.
type Registration interface {
// Unregister removes the callback registration from a Meter.
//
// This method needs to be idempotent and concurrent safe.
Unregister() error
} }

View file

@ -19,10 +19,6 @@ import (
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric/instrument" "go.opentelemetry.io/otel/metric/instrument"
"go.opentelemetry.io/otel/metric/instrument/asyncfloat64"
"go.opentelemetry.io/otel/metric/instrument/asyncint64"
"go.opentelemetry.io/otel/metric/instrument/syncfloat64"
"go.opentelemetry.io/otel/metric/instrument/syncint64"
) )
// NewNoopMeterProvider creates a MeterProvider that does not record any metrics. // NewNoopMeterProvider creates a MeterProvider that does not record any metrics.
@ -43,104 +39,126 @@ func NewNoopMeter() Meter {
type noopMeter struct{} type noopMeter struct{}
// AsyncInt64 creates an instrument that does not record any metrics. func (noopMeter) Int64Counter(string, ...instrument.Int64Option) (instrument.Int64Counter, error) {
func (noopMeter) AsyncInt64() asyncint64.InstrumentProvider { return nonrecordingSyncInt64Instrument{}, nil
return nonrecordingAsyncInt64Instrument{}
} }
// AsyncFloat64 creates an instrument that does not record any metrics. func (noopMeter) Int64UpDownCounter(string, ...instrument.Int64Option) (instrument.Int64UpDownCounter, error) {
func (noopMeter) AsyncFloat64() asyncfloat64.InstrumentProvider { return nonrecordingSyncInt64Instrument{}, nil
return nonrecordingAsyncFloat64Instrument{}
} }
// SyncInt64 creates an instrument that does not record any metrics. func (noopMeter) Int64Histogram(string, ...instrument.Int64Option) (instrument.Int64Histogram, error) {
func (noopMeter) SyncInt64() syncint64.InstrumentProvider { return nonrecordingSyncInt64Instrument{}, nil
return nonrecordingSyncInt64Instrument{}
} }
// SyncFloat64 creates an instrument that does not record any metrics. func (noopMeter) Int64ObservableCounter(string, ...instrument.Int64ObserverOption) (instrument.Int64ObservableCounter, error) {
func (noopMeter) SyncFloat64() syncfloat64.InstrumentProvider { return nonrecordingAsyncInt64Instrument{}, nil
return nonrecordingSyncFloat64Instrument{} }
func (noopMeter) Int64ObservableUpDownCounter(string, ...instrument.Int64ObserverOption) (instrument.Int64ObservableUpDownCounter, error) {
return nonrecordingAsyncInt64Instrument{}, nil
}
func (noopMeter) Int64ObservableGauge(string, ...instrument.Int64ObserverOption) (instrument.Int64ObservableGauge, error) {
return nonrecordingAsyncInt64Instrument{}, nil
}
func (noopMeter) Float64Counter(string, ...instrument.Float64Option) (instrument.Float64Counter, error) {
return nonrecordingSyncFloat64Instrument{}, nil
}
func (noopMeter) Float64UpDownCounter(string, ...instrument.Float64Option) (instrument.Float64UpDownCounter, error) {
return nonrecordingSyncFloat64Instrument{}, nil
}
func (noopMeter) Float64Histogram(string, ...instrument.Float64Option) (instrument.Float64Histogram, error) {
return nonrecordingSyncFloat64Instrument{}, nil
}
func (noopMeter) Float64ObservableCounter(string, ...instrument.Float64ObserverOption) (instrument.Float64ObservableCounter, error) {
return nonrecordingAsyncFloat64Instrument{}, nil
}
func (noopMeter) Float64ObservableUpDownCounter(string, ...instrument.Float64ObserverOption) (instrument.Float64ObservableUpDownCounter, error) {
return nonrecordingAsyncFloat64Instrument{}, nil
}
func (noopMeter) Float64ObservableGauge(string, ...instrument.Float64ObserverOption) (instrument.Float64ObservableGauge, error) {
return nonrecordingAsyncFloat64Instrument{}, nil
} }
// RegisterCallback creates a register callback that does not record any metrics. // RegisterCallback creates a register callback that does not record any metrics.
func (noopMeter) RegisterCallback([]instrument.Asynchronous, func(context.Context)) error { func (noopMeter) RegisterCallback(Callback, ...instrument.Asynchronous) (Registration, error) {
return nil return noopReg{}, nil
} }
type noopReg struct{}
func (noopReg) Unregister() error { return nil }
type nonrecordingAsyncFloat64Instrument struct { type nonrecordingAsyncFloat64Instrument struct {
instrument.Asynchronous instrument.Float64Observable
} }
var ( var (
_ asyncfloat64.InstrumentProvider = nonrecordingAsyncFloat64Instrument{} _ instrument.Float64ObservableCounter = nonrecordingAsyncFloat64Instrument{}
_ asyncfloat64.Counter = nonrecordingAsyncFloat64Instrument{} _ instrument.Float64ObservableUpDownCounter = nonrecordingAsyncFloat64Instrument{}
_ asyncfloat64.UpDownCounter = nonrecordingAsyncFloat64Instrument{} _ instrument.Float64ObservableGauge = nonrecordingAsyncFloat64Instrument{}
_ asyncfloat64.Gauge = nonrecordingAsyncFloat64Instrument{}
) )
func (n nonrecordingAsyncFloat64Instrument) Counter(string, ...instrument.Option) (asyncfloat64.Counter, error) { func (n nonrecordingAsyncFloat64Instrument) Counter(string, ...instrument.Float64ObserverOption) (instrument.Float64ObservableCounter, error) {
return n, nil return n, nil
} }
func (n nonrecordingAsyncFloat64Instrument) UpDownCounter(string, ...instrument.Option) (asyncfloat64.UpDownCounter, error) { func (n nonrecordingAsyncFloat64Instrument) UpDownCounter(string, ...instrument.Float64ObserverOption) (instrument.Float64ObservableUpDownCounter, error) {
return n, nil return n, nil
} }
func (n nonrecordingAsyncFloat64Instrument) Gauge(string, ...instrument.Option) (asyncfloat64.Gauge, error) { func (n nonrecordingAsyncFloat64Instrument) Gauge(string, ...instrument.Float64ObserverOption) (instrument.Float64ObservableGauge, error) {
return n, nil return n, nil
} }
func (nonrecordingAsyncFloat64Instrument) Observe(context.Context, float64, ...attribute.KeyValue) {
}
type nonrecordingAsyncInt64Instrument struct { type nonrecordingAsyncInt64Instrument struct {
instrument.Asynchronous instrument.Int64Observable
} }
var ( var (
_ asyncint64.InstrumentProvider = nonrecordingAsyncInt64Instrument{} _ instrument.Int64ObservableCounter = nonrecordingAsyncInt64Instrument{}
_ asyncint64.Counter = nonrecordingAsyncInt64Instrument{} _ instrument.Int64ObservableUpDownCounter = nonrecordingAsyncInt64Instrument{}
_ asyncint64.UpDownCounter = nonrecordingAsyncInt64Instrument{} _ instrument.Int64ObservableGauge = nonrecordingAsyncInt64Instrument{}
_ asyncint64.Gauge = nonrecordingAsyncInt64Instrument{}
) )
func (n nonrecordingAsyncInt64Instrument) Counter(string, ...instrument.Option) (asyncint64.Counter, error) { func (n nonrecordingAsyncInt64Instrument) Counter(string, ...instrument.Int64ObserverOption) (instrument.Int64ObservableCounter, error) {
return n, nil return n, nil
} }
func (n nonrecordingAsyncInt64Instrument) UpDownCounter(string, ...instrument.Option) (asyncint64.UpDownCounter, error) { func (n nonrecordingAsyncInt64Instrument) UpDownCounter(string, ...instrument.Int64ObserverOption) (instrument.Int64ObservableUpDownCounter, error) {
return n, nil return n, nil
} }
func (n nonrecordingAsyncInt64Instrument) Gauge(string, ...instrument.Option) (asyncint64.Gauge, error) { func (n nonrecordingAsyncInt64Instrument) Gauge(string, ...instrument.Int64ObserverOption) (instrument.Int64ObservableGauge, error) {
return n, nil return n, nil
} }
func (nonrecordingAsyncInt64Instrument) Observe(context.Context, int64, ...attribute.KeyValue) {
}
type nonrecordingSyncFloat64Instrument struct { type nonrecordingSyncFloat64Instrument struct {
instrument.Synchronous instrument.Synchronous
} }
var ( var (
_ syncfloat64.InstrumentProvider = nonrecordingSyncFloat64Instrument{} _ instrument.Float64Counter = nonrecordingSyncFloat64Instrument{}
_ syncfloat64.Counter = nonrecordingSyncFloat64Instrument{} _ instrument.Float64UpDownCounter = nonrecordingSyncFloat64Instrument{}
_ syncfloat64.UpDownCounter = nonrecordingSyncFloat64Instrument{} _ instrument.Float64Histogram = nonrecordingSyncFloat64Instrument{}
_ syncfloat64.Histogram = nonrecordingSyncFloat64Instrument{}
) )
func (n nonrecordingSyncFloat64Instrument) Counter(string, ...instrument.Option) (syncfloat64.Counter, error) { func (n nonrecordingSyncFloat64Instrument) Counter(string, ...instrument.Float64Option) (instrument.Float64Counter, error) {
return n, nil return n, nil
} }
func (n nonrecordingSyncFloat64Instrument) UpDownCounter(string, ...instrument.Option) (syncfloat64.UpDownCounter, error) { func (n nonrecordingSyncFloat64Instrument) UpDownCounter(string, ...instrument.Float64Option) (instrument.Float64UpDownCounter, error) {
return n, nil return n, nil
} }
func (n nonrecordingSyncFloat64Instrument) Histogram(string, ...instrument.Option) (syncfloat64.Histogram, error) { func (n nonrecordingSyncFloat64Instrument) Histogram(string, ...instrument.Float64Option) (instrument.Float64Histogram, error) {
return n, nil return n, nil
} }
@ -157,21 +175,20 @@ type nonrecordingSyncInt64Instrument struct {
} }
var ( var (
_ syncint64.InstrumentProvider = nonrecordingSyncInt64Instrument{} _ instrument.Int64Counter = nonrecordingSyncInt64Instrument{}
_ syncint64.Counter = nonrecordingSyncInt64Instrument{} _ instrument.Int64UpDownCounter = nonrecordingSyncInt64Instrument{}
_ syncint64.UpDownCounter = nonrecordingSyncInt64Instrument{} _ instrument.Int64Histogram = nonrecordingSyncInt64Instrument{}
_ syncint64.Histogram = nonrecordingSyncInt64Instrument{}
) )
func (n nonrecordingSyncInt64Instrument) Counter(string, ...instrument.Option) (syncint64.Counter, error) { func (n nonrecordingSyncInt64Instrument) Counter(string, ...instrument.Int64Option) (instrument.Int64Counter, error) {
return n, nil return n, nil
} }
func (n nonrecordingSyncInt64Instrument) UpDownCounter(string, ...instrument.Option) (syncint64.UpDownCounter, error) { func (n nonrecordingSyncInt64Instrument) UpDownCounter(string, ...instrument.Int64Option) (instrument.Int64UpDownCounter, error) {
return n, nil return n, nil
} }
func (n nonrecordingSyncInt64Instrument) Histogram(string, ...instrument.Option) (syncint64.Histogram, error) { func (n nonrecordingSyncInt64Instrument) Histogram(string, ...instrument.Int64Option) (instrument.Int64Histogram, error) {
return n, nil return n, nil
} }

View file

@ -1,336 +0,0 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package internal // import "go.opentelemetry.io/otel/semconv/internal"
import (
"fmt"
"net"
"net/http"
"strconv"
"strings"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/trace"
)
// SemanticConventions are the semantic convention values defined for a
// version of the OpenTelemetry specification.
type SemanticConventions struct {
EnduserIDKey attribute.Key
HTTPClientIPKey attribute.Key
HTTPFlavorKey attribute.Key
HTTPHostKey attribute.Key
HTTPMethodKey attribute.Key
HTTPRequestContentLengthKey attribute.Key
HTTPRouteKey attribute.Key
HTTPSchemeHTTP attribute.KeyValue
HTTPSchemeHTTPS attribute.KeyValue
HTTPServerNameKey attribute.Key
HTTPStatusCodeKey attribute.Key
HTTPTargetKey attribute.Key
HTTPURLKey attribute.Key
HTTPUserAgentKey attribute.Key
NetHostIPKey attribute.Key
NetHostNameKey attribute.Key
NetHostPortKey attribute.Key
NetPeerIPKey attribute.Key
NetPeerNameKey attribute.Key
NetPeerPortKey attribute.Key
NetTransportIP attribute.KeyValue
NetTransportOther attribute.KeyValue
NetTransportTCP attribute.KeyValue
NetTransportUDP attribute.KeyValue
NetTransportUnix attribute.KeyValue
}
// NetAttributesFromHTTPRequest generates attributes of the net
// namespace as specified by the OpenTelemetry specification for a
// span. The network parameter is a string that net.Dial function
// from standard library can understand.
func (sc *SemanticConventions) NetAttributesFromHTTPRequest(network string, request *http.Request) []attribute.KeyValue {
attrs := []attribute.KeyValue{}
switch network {
case "tcp", "tcp4", "tcp6":
attrs = append(attrs, sc.NetTransportTCP)
case "udp", "udp4", "udp6":
attrs = append(attrs, sc.NetTransportUDP)
case "ip", "ip4", "ip6":
attrs = append(attrs, sc.NetTransportIP)
case "unix", "unixgram", "unixpacket":
attrs = append(attrs, sc.NetTransportUnix)
default:
attrs = append(attrs, sc.NetTransportOther)
}
peerIP, peerName, peerPort := hostIPNamePort(request.RemoteAddr)
if peerIP != "" {
attrs = append(attrs, sc.NetPeerIPKey.String(peerIP))
}
if peerName != "" {
attrs = append(attrs, sc.NetPeerNameKey.String(peerName))
}
if peerPort != 0 {
attrs = append(attrs, sc.NetPeerPortKey.Int(peerPort))
}
hostIP, hostName, hostPort := "", "", 0
for _, someHost := range []string{request.Host, request.Header.Get("Host"), request.URL.Host} {
hostIP, hostName, hostPort = hostIPNamePort(someHost)
if hostIP != "" || hostName != "" || hostPort != 0 {
break
}
}
if hostIP != "" {
attrs = append(attrs, sc.NetHostIPKey.String(hostIP))
}
if hostName != "" {
attrs = append(attrs, sc.NetHostNameKey.String(hostName))
}
if hostPort != 0 {
attrs = append(attrs, sc.NetHostPortKey.Int(hostPort))
}
return attrs
}
// hostIPNamePort extracts the IP address, name and (optional) port from hostWithPort.
// It handles both IPv4 and IPv6 addresses. If the host portion is not recognized
// as a valid IPv4 or IPv6 address, the `ip` result will be empty and the
// host portion will instead be returned in `name`.
func hostIPNamePort(hostWithPort string) (ip string, name string, port int) {
var (
hostPart, portPart string
parsedPort uint64
err error
)
if hostPart, portPart, err = net.SplitHostPort(hostWithPort); err != nil {
hostPart, portPart = hostWithPort, ""
}
if parsedIP := net.ParseIP(hostPart); parsedIP != nil {
ip = parsedIP.String()
} else {
name = hostPart
}
if parsedPort, err = strconv.ParseUint(portPart, 10, 16); err == nil {
port = int(parsedPort)
}
return
}
// EndUserAttributesFromHTTPRequest generates attributes of the
// enduser namespace as specified by the OpenTelemetry specification
// for a span.
func (sc *SemanticConventions) EndUserAttributesFromHTTPRequest(request *http.Request) []attribute.KeyValue {
if username, _, ok := request.BasicAuth(); ok {
return []attribute.KeyValue{sc.EnduserIDKey.String(username)}
}
return nil
}
// HTTPClientAttributesFromHTTPRequest generates attributes of the
// http namespace as specified by the OpenTelemetry specification for
// a span on the client side.
func (sc *SemanticConventions) HTTPClientAttributesFromHTTPRequest(request *http.Request) []attribute.KeyValue {
attrs := []attribute.KeyValue{}
// remove any username/password info that may be in the URL
// before adding it to the attributes
userinfo := request.URL.User
request.URL.User = nil
attrs = append(attrs, sc.HTTPURLKey.String(request.URL.String()))
// restore any username/password info that was removed
request.URL.User = userinfo
return append(attrs, sc.httpCommonAttributesFromHTTPRequest(request)...)
}
func (sc *SemanticConventions) httpCommonAttributesFromHTTPRequest(request *http.Request) []attribute.KeyValue {
attrs := []attribute.KeyValue{}
if ua := request.UserAgent(); ua != "" {
attrs = append(attrs, sc.HTTPUserAgentKey.String(ua))
}
if request.ContentLength > 0 {
attrs = append(attrs, sc.HTTPRequestContentLengthKey.Int64(request.ContentLength))
}
return append(attrs, sc.httpBasicAttributesFromHTTPRequest(request)...)
}
func (sc *SemanticConventions) httpBasicAttributesFromHTTPRequest(request *http.Request) []attribute.KeyValue {
// as these attributes are used by HTTPServerMetricAttributesFromHTTPRequest, they should be low-cardinality
attrs := []attribute.KeyValue{}
if request.TLS != nil {
attrs = append(attrs, sc.HTTPSchemeHTTPS)
} else {
attrs = append(attrs, sc.HTTPSchemeHTTP)
}
if request.Host != "" {
attrs = append(attrs, sc.HTTPHostKey.String(request.Host))
} else if request.URL != nil && request.URL.Host != "" {
attrs = append(attrs, sc.HTTPHostKey.String(request.URL.Host))
}
flavor := ""
if request.ProtoMajor == 1 {
flavor = fmt.Sprintf("1.%d", request.ProtoMinor)
} else if request.ProtoMajor == 2 {
flavor = "2"
}
if flavor != "" {
attrs = append(attrs, sc.HTTPFlavorKey.String(flavor))
}
if request.Method != "" {
attrs = append(attrs, sc.HTTPMethodKey.String(request.Method))
} else {
attrs = append(attrs, sc.HTTPMethodKey.String(http.MethodGet))
}
return attrs
}
// HTTPServerMetricAttributesFromHTTPRequest generates low-cardinality attributes
// to be used with server-side HTTP metrics.
func (sc *SemanticConventions) HTTPServerMetricAttributesFromHTTPRequest(serverName string, request *http.Request) []attribute.KeyValue {
attrs := []attribute.KeyValue{}
if serverName != "" {
attrs = append(attrs, sc.HTTPServerNameKey.String(serverName))
}
return append(attrs, sc.httpBasicAttributesFromHTTPRequest(request)...)
}
// HTTPServerAttributesFromHTTPRequest generates attributes of the
// http namespace as specified by the OpenTelemetry specification for
// a span on the server side. Currently, only basic authentication is
// supported.
func (sc *SemanticConventions) HTTPServerAttributesFromHTTPRequest(serverName, route string, request *http.Request) []attribute.KeyValue {
attrs := []attribute.KeyValue{
sc.HTTPTargetKey.String(request.RequestURI),
}
if serverName != "" {
attrs = append(attrs, sc.HTTPServerNameKey.String(serverName))
}
if route != "" {
attrs = append(attrs, sc.HTTPRouteKey.String(route))
}
if values, ok := request.Header["X-Forwarded-For"]; ok && len(values) > 0 {
if addresses := strings.SplitN(values[0], ",", 2); len(addresses) > 0 {
attrs = append(attrs, sc.HTTPClientIPKey.String(addresses[0]))
}
}
return append(attrs, sc.httpCommonAttributesFromHTTPRequest(request)...)
}
// HTTPAttributesFromHTTPStatusCode generates attributes of the http
// namespace as specified by the OpenTelemetry specification for a
// span.
func (sc *SemanticConventions) HTTPAttributesFromHTTPStatusCode(code int) []attribute.KeyValue {
attrs := []attribute.KeyValue{
sc.HTTPStatusCodeKey.Int(code),
}
return attrs
}
type codeRange struct {
fromInclusive int
toInclusive int
}
func (r codeRange) contains(code int) bool {
return r.fromInclusive <= code && code <= r.toInclusive
}
var validRangesPerCategory = map[int][]codeRange{
1: {
{http.StatusContinue, http.StatusEarlyHints},
},
2: {
{http.StatusOK, http.StatusAlreadyReported},
{http.StatusIMUsed, http.StatusIMUsed},
},
3: {
{http.StatusMultipleChoices, http.StatusUseProxy},
{http.StatusTemporaryRedirect, http.StatusPermanentRedirect},
},
4: {
{http.StatusBadRequest, http.StatusTeapot}, // yes, teapot is so useful…
{http.StatusMisdirectedRequest, http.StatusUpgradeRequired},
{http.StatusPreconditionRequired, http.StatusTooManyRequests},
{http.StatusRequestHeaderFieldsTooLarge, http.StatusRequestHeaderFieldsTooLarge},
{http.StatusUnavailableForLegalReasons, http.StatusUnavailableForLegalReasons},
},
5: {
{http.StatusInternalServerError, http.StatusLoopDetected},
{http.StatusNotExtended, http.StatusNetworkAuthenticationRequired},
},
}
// SpanStatusFromHTTPStatusCode generates a status code and a message
// as specified by the OpenTelemetry specification for a span.
func SpanStatusFromHTTPStatusCode(code int) (codes.Code, string) {
spanCode, valid := validateHTTPStatusCode(code)
if !valid {
return spanCode, fmt.Sprintf("Invalid HTTP status code %d", code)
}
return spanCode, ""
}
// SpanStatusFromHTTPStatusCodeAndSpanKind generates a status code and a message
// as specified by the OpenTelemetry specification for a span.
// Exclude 4xx for SERVER to set the appropriate status.
func SpanStatusFromHTTPStatusCodeAndSpanKind(code int, spanKind trace.SpanKind) (codes.Code, string) {
spanCode, valid := validateHTTPStatusCode(code)
if !valid {
return spanCode, fmt.Sprintf("Invalid HTTP status code %d", code)
}
category := code / 100
if spanKind == trace.SpanKindServer && category == 4 {
return codes.Unset, ""
}
return spanCode, ""
}
// validateHTTPStatusCode validates the HTTP status code and returns
// corresponding span status code. If the `code` is not a valid HTTP status
// code, returns span status Error and false.
func validateHTTPStatusCode(code int) (codes.Code, bool) {
category := code / 100
ranges, ok := validRangesPerCategory[category]
if !ok {
return codes.Error, false
}
ok = false
for _, crange := range ranges {
ok = crange.contains(code)
if ok {
break
}
}
if !ok {
return codes.Error, false
}
if category > 0 && category < 4 {
return codes.Unset, true
}
return codes.Error, true
}

View file

@ -0,0 +1,405 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package internal // import "go.opentelemetry.io/otel/semconv/internal/v2"
import (
"fmt"
"net/http"
"strings"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
)
// HTTPConv are the HTTP semantic convention attributes defined for a version
// of the OpenTelemetry specification.
type HTTPConv struct {
NetConv *NetConv
EnduserIDKey attribute.Key
HTTPClientIPKey attribute.Key
HTTPFlavorKey attribute.Key
HTTPMethodKey attribute.Key
HTTPRequestContentLengthKey attribute.Key
HTTPResponseContentLengthKey attribute.Key
HTTPRouteKey attribute.Key
HTTPSchemeHTTP attribute.KeyValue
HTTPSchemeHTTPS attribute.KeyValue
HTTPStatusCodeKey attribute.Key
HTTPTargetKey attribute.Key
HTTPURLKey attribute.Key
HTTPUserAgentKey attribute.Key
}
// ClientResponse returns attributes for an HTTP response received by a client
// from a server. The following attributes are returned if the related values
// are defined in resp: "http.status.code", "http.response_content_length".
//
// This does not add all OpenTelemetry required attributes for an HTTP event,
// it assumes ClientRequest was used to create the span with a complete set of
// attributes. If a complete set of attributes can be generated using the
// request contained in resp. For example:
//
// append(ClientResponse(resp), ClientRequest(resp.Request)...)
func (c *HTTPConv) ClientResponse(resp *http.Response) []attribute.KeyValue {
var n int
if resp.StatusCode > 0 {
n++
}
if resp.ContentLength > 0 {
n++
}
attrs := make([]attribute.KeyValue, 0, n)
if resp.StatusCode > 0 {
attrs = append(attrs, c.HTTPStatusCodeKey.Int(resp.StatusCode))
}
if resp.ContentLength > 0 {
attrs = append(attrs, c.HTTPResponseContentLengthKey.Int(int(resp.ContentLength)))
}
return attrs
}
// ClientRequest returns attributes for an HTTP request made by a client. The
// following attributes are always returned: "http.url", "http.flavor",
// "http.method", "net.peer.name". The following attributes are returned if the
// related values are defined in req: "net.peer.port", "http.user_agent",
// "http.request_content_length", "enduser.id".
func (c *HTTPConv) ClientRequest(req *http.Request) []attribute.KeyValue {
n := 3 // URL, peer name, proto, and method.
var h string
if req.URL != nil {
h = req.URL.Host
}
peer, p := firstHostPort(h, req.Header.Get("Host"))
port := requiredHTTPPort(req.URL != nil && req.URL.Scheme == "https", p)
if port > 0 {
n++
}
useragent := req.UserAgent()
if useragent != "" {
n++
}
if req.ContentLength > 0 {
n++
}
userID, _, hasUserID := req.BasicAuth()
if hasUserID {
n++
}
attrs := make([]attribute.KeyValue, 0, n)
attrs = append(attrs, c.method(req.Method))
attrs = append(attrs, c.proto(req.Proto))
var u string
if req.URL != nil {
// Remove any username/password info that may be in the URL.
userinfo := req.URL.User
req.URL.User = nil
u = req.URL.String()
// Restore any username/password info that was removed.
req.URL.User = userinfo
}
attrs = append(attrs, c.HTTPURLKey.String(u))
attrs = append(attrs, c.NetConv.PeerName(peer))
if port > 0 {
attrs = append(attrs, c.NetConv.PeerPort(port))
}
if useragent != "" {
attrs = append(attrs, c.HTTPUserAgentKey.String(useragent))
}
if l := req.ContentLength; l > 0 {
attrs = append(attrs, c.HTTPRequestContentLengthKey.Int64(l))
}
if hasUserID {
attrs = append(attrs, c.EnduserIDKey.String(userID))
}
return attrs
}
// ServerRequest returns attributes for an HTTP request received by a server.
//
// The server must be the primary server name if it is known. For example this
// would be the ServerName directive
// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache
// server, and the server_name directive
// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an
// nginx server. More generically, the primary server name would be the host
// header value that matches the default virtual host of an HTTP server. It
// should include the host identifier and if a port is used to route to the
// server that port identifier should be included as an appropriate port
// suffix.
//
// If the primary server name is not known, server should be an empty string.
// The req Host will be used to determine the server instead.
//
// The following attributes are always returned: "http.method", "http.scheme",
// "http.flavor", "http.target", "net.host.name". The following attributes are
// returned if they related values are defined in req: "net.host.port",
// "net.sock.peer.addr", "net.sock.peer.port", "http.user_agent", "enduser.id",
// "http.client_ip".
func (c *HTTPConv) ServerRequest(server string, req *http.Request) []attribute.KeyValue {
n := 5 // Method, scheme, target, proto, and host name.
var host string
var p int
if server == "" {
host, p = splitHostPort(req.Host)
} else {
// Prioritize the primary server name.
host, p = splitHostPort(server)
if p < 0 {
_, p = splitHostPort(req.Host)
}
}
hostPort := requiredHTTPPort(req.TLS != nil, p)
if hostPort > 0 {
n++
}
peer, peerPort := splitHostPort(req.RemoteAddr)
if peer != "" {
n++
if peerPort > 0 {
n++
}
}
useragent := req.UserAgent()
if useragent != "" {
n++
}
userID, _, hasUserID := req.BasicAuth()
if hasUserID {
n++
}
clientIP := serverClientIP(req.Header.Get("X-Forwarded-For"))
if clientIP != "" {
n++
}
attrs := make([]attribute.KeyValue, 0, n)
attrs = append(attrs, c.method(req.Method))
attrs = append(attrs, c.scheme(req.TLS != nil))
attrs = append(attrs, c.proto(req.Proto))
attrs = append(attrs, c.NetConv.HostName(host))
if req.URL != nil {
attrs = append(attrs, c.HTTPTargetKey.String(req.URL.RequestURI()))
} else {
// This should never occur if the request was generated by the net/http
// package. Fail gracefully, if it does though.
attrs = append(attrs, c.HTTPTargetKey.String(req.RequestURI))
}
if hostPort > 0 {
attrs = append(attrs, c.NetConv.HostPort(hostPort))
}
if peer != "" {
// The Go HTTP server sets RemoteAddr to "IP:port", this will not be a
// file-path that would be interpreted with a sock family.
attrs = append(attrs, c.NetConv.SockPeerAddr(peer))
if peerPort > 0 {
attrs = append(attrs, c.NetConv.SockPeerPort(peerPort))
}
}
if useragent != "" {
attrs = append(attrs, c.HTTPUserAgentKey.String(useragent))
}
if hasUserID {
attrs = append(attrs, c.EnduserIDKey.String(userID))
}
if clientIP != "" {
attrs = append(attrs, c.HTTPClientIPKey.String(clientIP))
}
return attrs
}
func (c *HTTPConv) method(method string) attribute.KeyValue {
if method == "" {
return c.HTTPMethodKey.String(http.MethodGet)
}
return c.HTTPMethodKey.String(method)
}
func (c *HTTPConv) scheme(https bool) attribute.KeyValue { // nolint:revive
if https {
return c.HTTPSchemeHTTPS
}
return c.HTTPSchemeHTTP
}
func (c *HTTPConv) proto(proto string) attribute.KeyValue {
switch proto {
case "HTTP/1.0":
return c.HTTPFlavorKey.String("1.0")
case "HTTP/1.1":
return c.HTTPFlavorKey.String("1.1")
case "HTTP/2":
return c.HTTPFlavorKey.String("2.0")
case "HTTP/3":
return c.HTTPFlavorKey.String("3.0")
default:
return c.HTTPFlavorKey.String(proto)
}
}
func serverClientIP(xForwardedFor string) string {
if idx := strings.Index(xForwardedFor, ","); idx >= 0 {
xForwardedFor = xForwardedFor[:idx]
}
return xForwardedFor
}
func requiredHTTPPort(https bool, port int) int { // nolint:revive
if https {
if port > 0 && port != 443 {
return port
}
} else {
if port > 0 && port != 80 {
return port
}
}
return -1
}
// Return the request host and port from the first non-empty source.
func firstHostPort(source ...string) (host string, port int) {
for _, hostport := range source {
host, port = splitHostPort(hostport)
if host != "" || port > 0 {
break
}
}
return
}
// RequestHeader returns the contents of h as OpenTelemetry attributes.
func (c *HTTPConv) RequestHeader(h http.Header) []attribute.KeyValue {
return c.header("http.request.header", h)
}
// ResponseHeader returns the contents of h as OpenTelemetry attributes.
func (c *HTTPConv) ResponseHeader(h http.Header) []attribute.KeyValue {
return c.header("http.response.header", h)
}
func (c *HTTPConv) header(prefix string, h http.Header) []attribute.KeyValue {
key := func(k string) attribute.Key {
k = strings.ToLower(k)
k = strings.ReplaceAll(k, "-", "_")
k = fmt.Sprintf("%s.%s", prefix, k)
return attribute.Key(k)
}
attrs := make([]attribute.KeyValue, 0, len(h))
for k, v := range h {
attrs = append(attrs, key(k).StringSlice(v))
}
return attrs
}
// ClientStatus returns a span status code and message for an HTTP status code
// value received by a client.
func (c *HTTPConv) ClientStatus(code int) (codes.Code, string) {
stat, valid := validateHTTPStatusCode(code)
if !valid {
return stat, fmt.Sprintf("Invalid HTTP status code %d", code)
}
return stat, ""
}
// ServerStatus returns a span status code and message for an HTTP status code
// value returned by a server. Status codes in the 400-499 range are not
// returned as errors.
func (c *HTTPConv) ServerStatus(code int) (codes.Code, string) {
stat, valid := validateHTTPStatusCode(code)
if !valid {
return stat, fmt.Sprintf("Invalid HTTP status code %d", code)
}
if code/100 == 4 {
return codes.Unset, ""
}
return stat, ""
}
type codeRange struct {
fromInclusive int
toInclusive int
}
func (r codeRange) contains(code int) bool {
return r.fromInclusive <= code && code <= r.toInclusive
}
var validRangesPerCategory = map[int][]codeRange{
1: {
{http.StatusContinue, http.StatusEarlyHints},
},
2: {
{http.StatusOK, http.StatusAlreadyReported},
{http.StatusIMUsed, http.StatusIMUsed},
},
3: {
{http.StatusMultipleChoices, http.StatusUseProxy},
{http.StatusTemporaryRedirect, http.StatusPermanentRedirect},
},
4: {
{http.StatusBadRequest, http.StatusTeapot}, // yes, teapot is so useful…
{http.StatusMisdirectedRequest, http.StatusUpgradeRequired},
{http.StatusPreconditionRequired, http.StatusTooManyRequests},
{http.StatusRequestHeaderFieldsTooLarge, http.StatusRequestHeaderFieldsTooLarge},
{http.StatusUnavailableForLegalReasons, http.StatusUnavailableForLegalReasons},
},
5: {
{http.StatusInternalServerError, http.StatusLoopDetected},
{http.StatusNotExtended, http.StatusNetworkAuthenticationRequired},
},
}
// validateHTTPStatusCode validates the HTTP status code and returns
// corresponding span status code. If the `code` is not a valid HTTP status
// code, returns span status Error and false.
func validateHTTPStatusCode(code int) (codes.Code, bool) {
category := code / 100
ranges, ok := validRangesPerCategory[category]
if !ok {
return codes.Error, false
}
ok = false
for _, crange := range ranges {
ok = crange.contains(code)
if ok {
break
}
}
if !ok {
return codes.Error, false
}
if category > 0 && category < 4 {
return codes.Unset, true
}
return codes.Error, true
}

View file

@ -0,0 +1,324 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package internal // import "go.opentelemetry.io/otel/semconv/internal/v2"
import (
"net"
"strconv"
"strings"
"go.opentelemetry.io/otel/attribute"
)
// NetConv are the network semantic convention attributes defined for a version
// of the OpenTelemetry specification.
type NetConv struct {
NetHostNameKey attribute.Key
NetHostPortKey attribute.Key
NetPeerNameKey attribute.Key
NetPeerPortKey attribute.Key
NetSockFamilyKey attribute.Key
NetSockPeerAddrKey attribute.Key
NetSockPeerPortKey attribute.Key
NetSockHostAddrKey attribute.Key
NetSockHostPortKey attribute.Key
NetTransportOther attribute.KeyValue
NetTransportTCP attribute.KeyValue
NetTransportUDP attribute.KeyValue
NetTransportInProc attribute.KeyValue
}
func (c *NetConv) Transport(network string) attribute.KeyValue {
switch network {
case "tcp", "tcp4", "tcp6":
return c.NetTransportTCP
case "udp", "udp4", "udp6":
return c.NetTransportUDP
case "unix", "unixgram", "unixpacket":
return c.NetTransportInProc
default:
// "ip:*", "ip4:*", and "ip6:*" all are considered other.
return c.NetTransportOther
}
}
// Host returns attributes for a network host address.
func (c *NetConv) Host(address string) []attribute.KeyValue {
h, p := splitHostPort(address)
var n int
if h != "" {
n++
if p > 0 {
n++
}
}
if n == 0 {
return nil
}
attrs := make([]attribute.KeyValue, 0, n)
attrs = append(attrs, c.HostName(h))
if p > 0 {
attrs = append(attrs, c.HostPort(int(p)))
}
return attrs
}
// Server returns attributes for a network listener listening at address. See
// net.Listen for information about acceptable address values, address should
// be the same as the one used to create ln. If ln is nil, only network host
// attributes will be returned that describe address. Otherwise, the socket
// level information about ln will also be included.
func (c *NetConv) Server(address string, ln net.Listener) []attribute.KeyValue {
if ln == nil {
return c.Host(address)
}
lAddr := ln.Addr()
if lAddr == nil {
return c.Host(address)
}
hostName, hostPort := splitHostPort(address)
sockHostAddr, sockHostPort := splitHostPort(lAddr.String())
network := lAddr.Network()
sockFamily := family(network, sockHostAddr)
n := nonZeroStr(hostName, network, sockHostAddr, sockFamily)
n += positiveInt(hostPort, sockHostPort)
attr := make([]attribute.KeyValue, 0, n)
if hostName != "" {
attr = append(attr, c.HostName(hostName))
if hostPort > 0 {
// Only if net.host.name is set should net.host.port be.
attr = append(attr, c.HostPort(hostPort))
}
}
if network != "" {
attr = append(attr, c.Transport(network))
}
if sockFamily != "" {
attr = append(attr, c.NetSockFamilyKey.String(sockFamily))
}
if sockHostAddr != "" {
attr = append(attr, c.NetSockHostAddrKey.String(sockHostAddr))
if sockHostPort > 0 {
// Only if net.sock.host.addr is set should net.sock.host.port be.
attr = append(attr, c.NetSockHostPortKey.Int(sockHostPort))
}
}
return attr
}
func (c *NetConv) HostName(name string) attribute.KeyValue {
return c.NetHostNameKey.String(name)
}
func (c *NetConv) HostPort(port int) attribute.KeyValue {
return c.NetHostPortKey.Int(port)
}
// Client returns attributes for a client network connection to address. See
// net.Dial for information about acceptable address values, address should be
// the same as the one used to create conn. If conn is nil, only network peer
// attributes will be returned that describe address. Otherwise, the socket
// level information about conn will also be included.
func (c *NetConv) Client(address string, conn net.Conn) []attribute.KeyValue {
if conn == nil {
return c.Peer(address)
}
lAddr, rAddr := conn.LocalAddr(), conn.RemoteAddr()
var network string
switch {
case lAddr != nil:
network = lAddr.Network()
case rAddr != nil:
network = rAddr.Network()
default:
return c.Peer(address)
}
peerName, peerPort := splitHostPort(address)
var (
sockFamily string
sockPeerAddr string
sockPeerPort int
sockHostAddr string
sockHostPort int
)
if lAddr != nil {
sockHostAddr, sockHostPort = splitHostPort(lAddr.String())
}
if rAddr != nil {
sockPeerAddr, sockPeerPort = splitHostPort(rAddr.String())
}
switch {
case sockHostAddr != "":
sockFamily = family(network, sockHostAddr)
case sockPeerAddr != "":
sockFamily = family(network, sockPeerAddr)
}
n := nonZeroStr(peerName, network, sockPeerAddr, sockHostAddr, sockFamily)
n += positiveInt(peerPort, sockPeerPort, sockHostPort)
attr := make([]attribute.KeyValue, 0, n)
if peerName != "" {
attr = append(attr, c.PeerName(peerName))
if peerPort > 0 {
// Only if net.peer.name is set should net.peer.port be.
attr = append(attr, c.PeerPort(peerPort))
}
}
if network != "" {
attr = append(attr, c.Transport(network))
}
if sockFamily != "" {
attr = append(attr, c.NetSockFamilyKey.String(sockFamily))
}
if sockPeerAddr != "" {
attr = append(attr, c.NetSockPeerAddrKey.String(sockPeerAddr))
if sockPeerPort > 0 {
// Only if net.sock.peer.addr is set should net.sock.peer.port be.
attr = append(attr, c.NetSockPeerPortKey.Int(sockPeerPort))
}
}
if sockHostAddr != "" {
attr = append(attr, c.NetSockHostAddrKey.String(sockHostAddr))
if sockHostPort > 0 {
// Only if net.sock.host.addr is set should net.sock.host.port be.
attr = append(attr, c.NetSockHostPortKey.Int(sockHostPort))
}
}
return attr
}
func family(network, address string) string {
switch network {
case "unix", "unixgram", "unixpacket":
return "unix"
default:
if ip := net.ParseIP(address); ip != nil {
if ip.To4() == nil {
return "inet6"
}
return "inet"
}
}
return ""
}
func nonZeroStr(strs ...string) int {
var n int
for _, str := range strs {
if str != "" {
n++
}
}
return n
}
func positiveInt(ints ...int) int {
var n int
for _, i := range ints {
if i > 0 {
n++
}
}
return n
}
// Peer returns attributes for a network peer address.
func (c *NetConv) Peer(address string) []attribute.KeyValue {
h, p := splitHostPort(address)
var n int
if h != "" {
n++
if p > 0 {
n++
}
}
if n == 0 {
return nil
}
attrs := make([]attribute.KeyValue, 0, n)
attrs = append(attrs, c.PeerName(h))
if p > 0 {
attrs = append(attrs, c.PeerPort(int(p)))
}
return attrs
}
func (c *NetConv) PeerName(name string) attribute.KeyValue {
return c.NetPeerNameKey.String(name)
}
func (c *NetConv) PeerPort(port int) attribute.KeyValue {
return c.NetPeerPortKey.Int(port)
}
func (c *NetConv) SockPeerAddr(addr string) attribute.KeyValue {
return c.NetSockPeerAddrKey.String(addr)
}
func (c *NetConv) SockPeerPort(port int) attribute.KeyValue {
return c.NetSockPeerPortKey.Int(port)
}
// splitHostPort splits a network address hostport of the form "host",
// "host%zone", "[host]", "[host%zone], "host:port", "host%zone:port",
// "[host]:port", "[host%zone]:port", or ":port" into host or host%zone and
// port.
//
// An empty host is returned if it is not provided or unparsable. A negative
// port is returned if it is not provided or unparsable.
func splitHostPort(hostport string) (host string, port int) {
port = -1
if strings.HasPrefix(hostport, "[") {
addrEnd := strings.LastIndex(hostport, "]")
if addrEnd < 0 {
// Invalid hostport.
return
}
if i := strings.LastIndex(hostport[addrEnd:], ":"); i < 0 {
host = hostport[1:addrEnd]
return
}
} else {
if i := strings.LastIndex(hostport, ":"); i < 0 {
host = hostport
return
}
}
host, pStr, err := net.SplitHostPort(hostport)
if err != nil {
return
}
p, err := strconv.ParseUint(pStr, 10, 16)
if err != nil {
return
}
return host, int(p)
}

View file

@ -1,114 +0,0 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package semconv // import "go.opentelemetry.io/otel/semconv/v1.12.0"
import (
"net/http"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/semconv/internal"
"go.opentelemetry.io/otel/trace"
)
// HTTP scheme attributes.
var (
HTTPSchemeHTTP = HTTPSchemeKey.String("http")
HTTPSchemeHTTPS = HTTPSchemeKey.String("https")
)
var sc = &internal.SemanticConventions{
EnduserIDKey: EnduserIDKey,
HTTPClientIPKey: HTTPClientIPKey,
HTTPFlavorKey: HTTPFlavorKey,
HTTPHostKey: HTTPHostKey,
HTTPMethodKey: HTTPMethodKey,
HTTPRequestContentLengthKey: HTTPRequestContentLengthKey,
HTTPRouteKey: HTTPRouteKey,
HTTPSchemeHTTP: HTTPSchemeHTTP,
HTTPSchemeHTTPS: HTTPSchemeHTTPS,
HTTPServerNameKey: HTTPServerNameKey,
HTTPStatusCodeKey: HTTPStatusCodeKey,
HTTPTargetKey: HTTPTargetKey,
HTTPURLKey: HTTPURLKey,
HTTPUserAgentKey: HTTPUserAgentKey,
NetHostIPKey: NetHostIPKey,
NetHostNameKey: NetHostNameKey,
NetHostPortKey: NetHostPortKey,
NetPeerIPKey: NetPeerIPKey,
NetPeerNameKey: NetPeerNameKey,
NetPeerPortKey: NetPeerPortKey,
NetTransportIP: NetTransportIP,
NetTransportOther: NetTransportOther,
NetTransportTCP: NetTransportTCP,
NetTransportUDP: NetTransportUDP,
NetTransportUnix: NetTransportUnix,
}
// NetAttributesFromHTTPRequest generates attributes of the net
// namespace as specified by the OpenTelemetry specification for a
// span. The network parameter is a string that net.Dial function
// from standard library can understand.
func NetAttributesFromHTTPRequest(network string, request *http.Request) []attribute.KeyValue {
return sc.NetAttributesFromHTTPRequest(network, request)
}
// EndUserAttributesFromHTTPRequest generates attributes of the
// enduser namespace as specified by the OpenTelemetry specification
// for a span.
func EndUserAttributesFromHTTPRequest(request *http.Request) []attribute.KeyValue {
return sc.EndUserAttributesFromHTTPRequest(request)
}
// HTTPClientAttributesFromHTTPRequest generates attributes of the
// http namespace as specified by the OpenTelemetry specification for
// a span on the client side.
func HTTPClientAttributesFromHTTPRequest(request *http.Request) []attribute.KeyValue {
return sc.HTTPClientAttributesFromHTTPRequest(request)
}
// HTTPServerMetricAttributesFromHTTPRequest generates low-cardinality attributes
// to be used with server-side HTTP metrics.
func HTTPServerMetricAttributesFromHTTPRequest(serverName string, request *http.Request) []attribute.KeyValue {
return sc.HTTPServerMetricAttributesFromHTTPRequest(serverName, request)
}
// HTTPServerAttributesFromHTTPRequest generates attributes of the
// http namespace as specified by the OpenTelemetry specification for
// a span on the server side. Currently, only basic authentication is
// supported.
func HTTPServerAttributesFromHTTPRequest(serverName, route string, request *http.Request) []attribute.KeyValue {
return sc.HTTPServerAttributesFromHTTPRequest(serverName, route, request)
}
// HTTPAttributesFromHTTPStatusCode generates attributes of the http
// namespace as specified by the OpenTelemetry specification for a
// span.
func HTTPAttributesFromHTTPStatusCode(code int) []attribute.KeyValue {
return sc.HTTPAttributesFromHTTPStatusCode(code)
}
// SpanStatusFromHTTPStatusCode generates a status code and a message
// as specified by the OpenTelemetry specification for a span.
func SpanStatusFromHTTPStatusCode(code int) (codes.Code, string) {
return internal.SpanStatusFromHTTPStatusCode(code)
}
// SpanStatusFromHTTPStatusCodeAndSpanKind generates a status code and a message
// as specified by the OpenTelemetry specification for a span.
// Exclude 4xx for SERVER to set the appropriate status.
func SpanStatusFromHTTPStatusCodeAndSpanKind(code int, spanKind trace.SpanKind) (codes.Code, string) {
return internal.SpanStatusFromHTTPStatusCodeAndSpanKind(code, spanKind)
}

View file

@ -16,5 +16,5 @@
// //
// OpenTelemetry semantic conventions are agreed standardized naming // OpenTelemetry semantic conventions are agreed standardized naming
// patterns for OpenTelemetry things. This package represents the conventions // patterns for OpenTelemetry things. This package represents the conventions
// as of the v1.12.0 version of the OpenTelemetry specification. // as of the v1.17.0 version of the OpenTelemetry specification.
package semconv // import "go.opentelemetry.io/otel/semconv/v1.12.0" package semconv // import "go.opentelemetry.io/otel/semconv/v1.17.0"

View file

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package semconv // import "go.opentelemetry.io/otel/semconv/v1.12.0" package semconv // import "go.opentelemetry.io/otel/semconv/v1.17.0"
const ( const (
// ExceptionEventName is the name of the Span event representing an exception. // ExceptionEventName is the name of the Span event representing an exception.

View file

@ -0,0 +1,21 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package semconv // import "go.opentelemetry.io/otel/semconv/v1.17.0"
// HTTP scheme attributes.
var (
HTTPSchemeHTTP = HTTPSchemeKey.String("http")
HTTPSchemeHTTPS = HTTPSchemeKey.String("https")
)

View file

@ -0,0 +1,150 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package httpconv provides OpenTelemetry semantic convetions for the net/http
// package from the standard library.
package httpconv // import "go.opentelemetry.io/otel/semconv/v1.17.0/httpconv"
import (
"net/http"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/semconv/internal/v2"
semconv "go.opentelemetry.io/otel/semconv/v1.17.0"
)
var (
nc = &internal.NetConv{
NetHostNameKey: semconv.NetHostNameKey,
NetHostPortKey: semconv.NetHostPortKey,
NetPeerNameKey: semconv.NetPeerNameKey,
NetPeerPortKey: semconv.NetPeerPortKey,
NetSockPeerAddrKey: semconv.NetSockPeerAddrKey,
NetSockPeerPortKey: semconv.NetSockPeerPortKey,
NetTransportOther: semconv.NetTransportOther,
NetTransportTCP: semconv.NetTransportTCP,
NetTransportUDP: semconv.NetTransportUDP,
NetTransportInProc: semconv.NetTransportInProc,
}
hc = &internal.HTTPConv{
NetConv: nc,
EnduserIDKey: semconv.EnduserIDKey,
HTTPClientIPKey: semconv.HTTPClientIPKey,
HTTPFlavorKey: semconv.HTTPFlavorKey,
HTTPMethodKey: semconv.HTTPMethodKey,
HTTPRequestContentLengthKey: semconv.HTTPRequestContentLengthKey,
HTTPResponseContentLengthKey: semconv.HTTPResponseContentLengthKey,
HTTPRouteKey: semconv.HTTPRouteKey,
HTTPSchemeHTTP: semconv.HTTPSchemeHTTP,
HTTPSchemeHTTPS: semconv.HTTPSchemeHTTPS,
HTTPStatusCodeKey: semconv.HTTPStatusCodeKey,
HTTPTargetKey: semconv.HTTPTargetKey,
HTTPURLKey: semconv.HTTPURLKey,
HTTPUserAgentKey: semconv.HTTPUserAgentKey,
}
)
// ClientResponse returns attributes for an HTTP response received by a client
// from a server. It will return the following attributes if the related values
// are defined in resp: "http.status.code", "http.response_content_length".
//
// This does not add all OpenTelemetry required attributes for an HTTP event,
// it assumes ClientRequest was used to create the span with a complete set of
// attributes. If a complete set of attributes can be generated using the
// request contained in resp. For example:
//
// append(ClientResponse(resp), ClientRequest(resp.Request)...)
func ClientResponse(resp *http.Response) []attribute.KeyValue {
return hc.ClientResponse(resp)
}
// ClientRequest returns attributes for an HTTP request made by a client. The
// following attributes are always returned: "http.url", "http.flavor",
// "http.method", "net.peer.name". The following attributes are returned if the
// related values are defined in req: "net.peer.port", "http.user_agent",
// "http.request_content_length", "enduser.id".
func ClientRequest(req *http.Request) []attribute.KeyValue {
return hc.ClientRequest(req)
}
// ClientStatus returns a span status code and message for an HTTP status code
// value received by a client.
func ClientStatus(code int) (codes.Code, string) {
return hc.ClientStatus(code)
}
// ServerRequest returns attributes for an HTTP request received by a server.
//
// The server must be the primary server name if it is known. For example this
// would be the ServerName directive
// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache
// server, and the server_name directive
// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an
// nginx server. More generically, the primary server name would be the host
// header value that matches the default virtual host of an HTTP server. It
// should include the host identifier and if a port is used to route to the
// server that port identifier should be included as an appropriate port
// suffix.
//
// If the primary server name is not known, server should be an empty string.
// The req Host will be used to determine the server instead.
//
// The following attributes are always returned: "http.method", "http.scheme",
// "http.flavor", "http.target", "net.host.name". The following attributes are
// returned if they related values are defined in req: "net.host.port",
// "net.sock.peer.addr", "net.sock.peer.port", "http.user_agent", "enduser.id",
// "http.client_ip".
func ServerRequest(server string, req *http.Request) []attribute.KeyValue {
return hc.ServerRequest(server, req)
}
// ServerStatus returns a span status code and message for an HTTP status code
// value returned by a server. Status codes in the 400-499 range are not
// returned as errors.
func ServerStatus(code int) (codes.Code, string) {
return hc.ServerStatus(code)
}
// RequestHeader returns the contents of h as attributes.
//
// Instrumentation should require an explicit configuration of which headers to
// captured and then prune what they pass here. Including all headers can be a
// security risk - explicit configuration helps avoid leaking sensitive
// information.
//
// The User-Agent header is already captured in the http.user_agent attribute
// from ClientRequest and ServerRequest. Instrumentation may provide an option
// to capture that header here even though it is not recommended. Otherwise,
// instrumentation should filter that out of what is passed.
func RequestHeader(h http.Header) []attribute.KeyValue {
return hc.RequestHeader(h)
}
// ResponseHeader returns the contents of h as attributes.
//
// Instrumentation should require an explicit configuration of which headers to
// captured and then prune what they pass here. Including all headers can be a
// security risk - explicit configuration helps avoid leaking sensitive
// information.
//
// The User-Agent header is already captured in the http.user_agent attribute
// from ClientRequest and ServerRequest. Instrumentation may provide an option
// to capture that header here even though it is not recommended. Otherwise,
// instrumentation should filter that out of what is passed.
func ResponseHeader(h http.Header) []attribute.KeyValue {
return hc.ResponseHeader(h)
}

View file

@ -14,7 +14,7 @@
// Code generated from semantic convention specification. DO NOT EDIT. // Code generated from semantic convention specification. DO NOT EDIT.
package semconv // import "go.opentelemetry.io/otel/semconv/v1.12.0" package semconv // import "go.opentelemetry.io/otel/semconv/v1.17.0"
import "go.opentelemetry.io/otel/attribute" import "go.opentelemetry.io/otel/attribute"
@ -23,35 +23,45 @@ const (
// Array of brand name and version separated by a space // Array of brand name and version separated by a space
// //
// Type: string[] // Type: string[]
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: ' Not A;Brand 99', 'Chromium 99', 'Chrome 99' // Examples: ' Not A;Brand 99', 'Chromium 99', 'Chrome 99'
// Note: This value is intended to be taken from the [UA client hints // Note: This value is intended to be taken from the [UA client hints
// API](https://wicg.github.io/ua-client-hints/#interface) // API](https://wicg.github.io/ua-client-hints/#interface)
// (navigator.userAgentData.brands). // (`navigator.userAgentData.brands`).
BrowserBrandsKey = attribute.Key("browser.brands") BrowserBrandsKey = attribute.Key("browser.brands")
// The platform on which the browser is running // The platform on which the browser is running
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'Windows', 'macOS', 'Android' // Examples: 'Windows', 'macOS', 'Android'
// Note: This value is intended to be taken from the [UA client hints // Note: This value is intended to be taken from the [UA client hints
// API](https://wicg.github.io/ua-client-hints/#interface) // API](https://wicg.github.io/ua-client-hints/#interface)
// (navigator.userAgentData.platform). If unavailable, the legacy // (`navigator.userAgentData.platform`). If unavailable, the legacy
// `navigator.platform` API SHOULD NOT be used instead and this attribute SHOULD // `navigator.platform` API SHOULD NOT be used instead and this attribute SHOULD
// be left unset in order for the values to be consistent. // be left unset in order for the values to be consistent.
// The list of possible values is defined in the [W3C User-Agent Client Hints // The list of possible values is defined in the [W3C User-Agent Client Hints
// specification](https://wicg.github.io/ua-client-hints/#sec-ch-ua-platform). // specification](https://wicg.github.io/ua-client-hints/#sec-ch-ua-platform).
// Note that some (but not all) of these values can overlap with values in the // Note that some (but not all) of these values can overlap with values in the
// [os.type and os.name attributes](./os.md). However, for consistency, the values // [`os.type` and `os.name` attributes](./os.md). However, for consistency, the
// in the `browser.platform` attribute should capture the exact value that the // values in the `browser.platform` attribute should capture the exact value that
// user agent provides. // the user agent provides.
BrowserPlatformKey = attribute.Key("browser.platform") BrowserPlatformKey = attribute.Key("browser.platform")
// A boolean that is true if the browser is running on a mobile device
//
// Type: boolean
// RequirementLevel: Optional
// Stability: stable
// Note: This value is intended to be taken from the [UA client hints
// API](https://wicg.github.io/ua-client-hints/#interface)
// (`navigator.userAgentData.mobile`). If unavailable, this attribute SHOULD be
// left unset.
BrowserMobileKey = attribute.Key("browser.mobile")
// Full user-agent string provided by the browser // Full user-agent string provided by the browser
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 // Examples: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36
// (KHTML, ' // (KHTML, '
@ -61,6 +71,15 @@ const (
// Agent Client Hints API. To retrieve the value, the legacy `navigator.userAgent` // Agent Client Hints API. To retrieve the value, the legacy `navigator.userAgent`
// API can be used. // API can be used.
BrowserUserAgentKey = attribute.Key("browser.user_agent") BrowserUserAgentKey = attribute.Key("browser.user_agent")
// Preferred language of the user using the browser
//
// Type: string
// RequirementLevel: Optional
// Stability: stable
// Examples: 'en', 'en-US', 'fr', 'fr-FR'
// Note: This value is intended to be taken from the Navigator API
// `navigator.language`.
BrowserLanguageKey = attribute.Key("browser.language")
) )
// A cloud environment (e.g. GCP, Azure, AWS) // A cloud environment (e.g. GCP, Azure, AWS)
@ -68,20 +87,20 @@ const (
// Name of the cloud provider. // Name of the cloud provider.
// //
// Type: Enum // Type: Enum
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
CloudProviderKey = attribute.Key("cloud.provider") CloudProviderKey = attribute.Key("cloud.provider")
// The cloud account ID the resource is assigned to. // The cloud account ID the resource is assigned to.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: '111111111111', 'opentelemetry' // Examples: '111111111111', 'opentelemetry'
CloudAccountIDKey = attribute.Key("cloud.account.id") CloudAccountIDKey = attribute.Key("cloud.account.id")
// The geographical region the resource is running. // The geographical region the resource is running.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'us-central1', 'us-east-1' // Examples: 'us-central1', 'us-east-1'
// Note: Refer to your provider's docs to see the available regions, for example // Note: Refer to your provider's docs to see the available regions, for example
@ -97,7 +116,7 @@ const (
// is running. // is running.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'us-east-1c' // Examples: 'us-east-1c'
// Note: Availability zones are called "zones" on Alibaba Cloud and Google Cloud. // Note: Availability zones are called "zones" on Alibaba Cloud and Google Cloud.
@ -105,7 +124,7 @@ const (
// The cloud platform in use. // The cloud platform in use.
// //
// Type: Enum // Type: Enum
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Note: The prefix of the service SHOULD match the one specified in // Note: The prefix of the service SHOULD match the one specified in
// `cloud.provider`. // `cloud.provider`.
@ -121,6 +140,8 @@ var (
CloudProviderAzure = CloudProviderKey.String("azure") CloudProviderAzure = CloudProviderKey.String("azure")
// Google Cloud Platform // Google Cloud Platform
CloudProviderGCP = CloudProviderKey.String("gcp") CloudProviderGCP = CloudProviderKey.String("gcp")
// IBM Cloud
CloudProviderIbmCloud = CloudProviderKey.String("ibm_cloud")
// Tencent Cloud // Tencent Cloud
CloudProviderTencentCloud = CloudProviderKey.String("tencent_cloud") CloudProviderTencentCloud = CloudProviderKey.String("tencent_cloud")
) )
@ -130,6 +151,8 @@ var (
CloudPlatformAlibabaCloudECS = CloudPlatformKey.String("alibaba_cloud_ecs") CloudPlatformAlibabaCloudECS = CloudPlatformKey.String("alibaba_cloud_ecs")
// Alibaba Cloud Function Compute // Alibaba Cloud Function Compute
CloudPlatformAlibabaCloudFc = CloudPlatformKey.String("alibaba_cloud_fc") CloudPlatformAlibabaCloudFc = CloudPlatformKey.String("alibaba_cloud_fc")
// Red Hat OpenShift on Alibaba Cloud
CloudPlatformAlibabaCloudOpenshift = CloudPlatformKey.String("alibaba_cloud_openshift")
// AWS Elastic Compute Cloud // AWS Elastic Compute Cloud
CloudPlatformAWSEC2 = CloudPlatformKey.String("aws_ec2") CloudPlatformAWSEC2 = CloudPlatformKey.String("aws_ec2")
// AWS Elastic Container Service // AWS Elastic Container Service
@ -142,6 +165,8 @@ var (
CloudPlatformAWSElasticBeanstalk = CloudPlatformKey.String("aws_elastic_beanstalk") CloudPlatformAWSElasticBeanstalk = CloudPlatformKey.String("aws_elastic_beanstalk")
// AWS App Runner // AWS App Runner
CloudPlatformAWSAppRunner = CloudPlatformKey.String("aws_app_runner") CloudPlatformAWSAppRunner = CloudPlatformKey.String("aws_app_runner")
// Red Hat OpenShift on AWS (ROSA)
CloudPlatformAWSOpenshift = CloudPlatformKey.String("aws_openshift")
// Azure Virtual Machines // Azure Virtual Machines
CloudPlatformAzureVM = CloudPlatformKey.String("azure_vm") CloudPlatformAzureVM = CloudPlatformKey.String("azure_vm")
// Azure Container Instances // Azure Container Instances
@ -152,6 +177,8 @@ var (
CloudPlatformAzureFunctions = CloudPlatformKey.String("azure_functions") CloudPlatformAzureFunctions = CloudPlatformKey.String("azure_functions")
// Azure App Service // Azure App Service
CloudPlatformAzureAppService = CloudPlatformKey.String("azure_app_service") CloudPlatformAzureAppService = CloudPlatformKey.String("azure_app_service")
// Azure Red Hat OpenShift
CloudPlatformAzureOpenshift = CloudPlatformKey.String("azure_openshift")
// Google Cloud Compute Engine (GCE) // Google Cloud Compute Engine (GCE)
CloudPlatformGCPComputeEngine = CloudPlatformKey.String("gcp_compute_engine") CloudPlatformGCPComputeEngine = CloudPlatformKey.String("gcp_compute_engine")
// Google Cloud Run // Google Cloud Run
@ -162,6 +189,10 @@ var (
CloudPlatformGCPCloudFunctions = CloudPlatformKey.String("gcp_cloud_functions") CloudPlatformGCPCloudFunctions = CloudPlatformKey.String("gcp_cloud_functions")
// Google Cloud App Engine (GAE) // Google Cloud App Engine (GAE)
CloudPlatformGCPAppEngine = CloudPlatformKey.String("gcp_app_engine") CloudPlatformGCPAppEngine = CloudPlatformKey.String("gcp_app_engine")
// Red Hat OpenShift on Google Cloud
CloudPlatformGoogleCloudOpenshift = CloudPlatformKey.String("google_cloud_openshift")
// Red Hat OpenShift on IBM Cloud
CloudPlatformIbmCloudOpenshift = CloudPlatformKey.String("ibm_cloud_openshift")
// Tencent Cloud Cloud Virtual Machine (CVM) // Tencent Cloud Cloud Virtual Machine (CVM)
CloudPlatformTencentCloudCvm = CloudPlatformKey.String("tencent_cloud_cvm") CloudPlatformTencentCloudCvm = CloudPlatformKey.String("tencent_cloud_cvm")
// Tencent Cloud Elastic Kubernetes Service (EKS) // Tencent Cloud Elastic Kubernetes Service (EKS)
@ -176,7 +207,7 @@ const (
// amazon.com/AmazonECS/latest/developerguide/ECS_instances.html). // amazon.com/AmazonECS/latest/developerguide/ECS_instances.html).
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'arn:aws:ecs:us- // Examples: 'arn:aws:ecs:us-
// west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9' // west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9'
@ -185,7 +216,7 @@ const (
// perguide/clusters.html). // perguide/clusters.html).
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster' // Examples: 'arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster'
AWSECSClusterARNKey = attribute.Key("aws.ecs.cluster.arn") AWSECSClusterARNKey = attribute.Key("aws.ecs.cluster.arn")
@ -193,14 +224,14 @@ const (
// aunch_types.html) for an ECS task. // aunch_types.html) for an ECS task.
// //
// Type: Enum // Type: Enum
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
AWSECSLaunchtypeKey = attribute.Key("aws.ecs.launchtype") AWSECSLaunchtypeKey = attribute.Key("aws.ecs.launchtype")
// The ARN of an [ECS task definition](https://docs.aws.amazon.com/AmazonECS/lates // The ARN of an [ECS task definition](https://docs.aws.amazon.com/AmazonECS/lates
// t/developerguide/task_definitions.html). // t/developerguide/task_definitions.html).
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'arn:aws:ecs:us- // Examples: 'arn:aws:ecs:us-
// west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b' // west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b'
@ -208,14 +239,14 @@ const (
// The task definition family this task definition is a member of. // The task definition family this task definition is a member of.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'opentelemetry-family' // Examples: 'opentelemetry-family'
AWSECSTaskFamilyKey = attribute.Key("aws.ecs.task.family") AWSECSTaskFamilyKey = attribute.Key("aws.ecs.task.family")
// The revision for this task definition. // The revision for this task definition.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: '8', '26' // Examples: '8', '26'
AWSECSTaskRevisionKey = attribute.Key("aws.ecs.task.revision") AWSECSTaskRevisionKey = attribute.Key("aws.ecs.task.revision")
@ -233,7 +264,7 @@ const (
// The ARN of an EKS cluster. // The ARN of an EKS cluster.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster' // Examples: 'arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster'
AWSEKSClusterARNKey = attribute.Key("aws.eks.cluster.arn") AWSEKSClusterARNKey = attribute.Key("aws.eks.cluster.arn")
@ -244,7 +275,7 @@ const (
// The name(s) of the AWS log group(s) an application is writing to. // The name(s) of the AWS log group(s) an application is writing to.
// //
// Type: string[] // Type: string[]
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: '/aws/lambda/my-function', 'opentelemetry-service' // Examples: '/aws/lambda/my-function', 'opentelemetry-service'
// Note: Multiple log groups must be supported for cases like multi-container // Note: Multiple log groups must be supported for cases like multi-container
@ -254,7 +285,7 @@ const (
// The Amazon Resource Name(s) (ARN) of the AWS log group(s). // The Amazon Resource Name(s) (ARN) of the AWS log group(s).
// //
// Type: string[] // Type: string[]
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*' // Examples: 'arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*'
// Note: See the [log group ARN format // Note: See the [log group ARN format
@ -264,14 +295,14 @@ const (
// The name(s) of the AWS log stream(s) an application is writing to. // The name(s) of the AWS log stream(s) an application is writing to.
// //
// Type: string[] // Type: string[]
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'logs/main/10838bed-421f-43ef-870a-f43feacbbb5b' // Examples: 'logs/main/10838bed-421f-43ef-870a-f43feacbbb5b'
AWSLogStreamNamesKey = attribute.Key("aws.log.stream.names") AWSLogStreamNamesKey = attribute.Key("aws.log.stream.names")
// The ARN(s) of the AWS log stream(s). // The ARN(s) of the AWS log stream(s).
// //
// Type: string[] // Type: string[]
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log- // Examples: 'arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-
// stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b' // stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b'
@ -288,7 +319,7 @@ const (
// Container name used by container runtime. // Container name used by container runtime.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'opentelemetry-autoconf' // Examples: 'opentelemetry-autoconf'
ContainerNameKey = attribute.Key("container.name") ContainerNameKey = attribute.Key("container.name")
@ -297,28 +328,28 @@ const (
// identification). The UUID might be abbreviated. // identification). The UUID might be abbreviated.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'a3bf90e006b2' // Examples: 'a3bf90e006b2'
ContainerIDKey = attribute.Key("container.id") ContainerIDKey = attribute.Key("container.id")
// The container runtime managing this container. // The container runtime managing this container.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'docker', 'containerd', 'rkt' // Examples: 'docker', 'containerd', 'rkt'
ContainerRuntimeKey = attribute.Key("container.runtime") ContainerRuntimeKey = attribute.Key("container.runtime")
// Name of the image the container was built on. // Name of the image the container was built on.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'gcr.io/opentelemetry/operator' // Examples: 'gcr.io/opentelemetry/operator'
ContainerImageNameKey = attribute.Key("container.image.name") ContainerImageNameKey = attribute.Key("container.image.name")
// Container image tag. // Container image tag.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: '0.1' // Examples: '0.1'
ContainerImageTagKey = attribute.Key("container.image.tag") ContainerImageTagKey = attribute.Key("container.image.tag")
@ -331,7 +362,7 @@ const (
// deployment tier). // deployment tier).
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'staging', 'production' // Examples: 'staging', 'production'
DeploymentEnvironmentKey = attribute.Key("deployment.environment") DeploymentEnvironmentKey = attribute.Key("deployment.environment")
@ -342,7 +373,7 @@ const (
// A unique identifier representing the device // A unique identifier representing the device
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: '2ab2916d-a51f-4ac8-80ee-45ac31a28092' // Examples: '2ab2916d-a51f-4ac8-80ee-45ac31a28092'
// Note: The device identifier MUST only be defined using the values outlined // Note: The device identifier MUST only be defined using the values outlined
@ -360,7 +391,7 @@ const (
// The model identifier for the device // The model identifier for the device
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'iPhone3,4', 'SM-G920F' // Examples: 'iPhone3,4', 'SM-G920F'
// Note: It's recommended this value represents a machine readable version of the // Note: It's recommended this value represents a machine readable version of the
@ -370,7 +401,7 @@ const (
// The marketing name for the device model // The marketing name for the device model
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'iPhone 6s Plus', 'Samsung Galaxy S6' // Examples: 'iPhone 6s Plus', 'Samsung Galaxy S6'
// Note: It's recommended this value represents a human readable version of the // Note: It's recommended this value represents a human readable version of the
@ -379,7 +410,7 @@ const (
// The name of the device manufacturer // The name of the device manufacturer
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'Apple', 'Samsung' // Examples: 'Apple', 'Samsung'
// Note: The Android OS provides this field via // Note: The Android OS provides this field via
@ -393,7 +424,7 @@ const (
// The name of the single function that this runtime instance executes. // The name of the single function that this runtime instance executes.
// //
// Type: string // Type: string
// Required: Always // RequirementLevel: Required
// Stability: stable // Stability: stable
// Examples: 'my-function', 'myazurefunctionapp/some-function-name' // Examples: 'my-function', 'myazurefunctionapp/some-function-name'
// Note: This is the name of the function as configured/deployed on the FaaS // Note: This is the name of the function as configured/deployed on the FaaS
@ -417,7 +448,7 @@ const (
// The unique ID of the single function that this runtime instance executes. // The unique ID of the single function that this runtime instance executes.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'arn:aws:lambda:us-west-2:123456789012:function:my-function' // Examples: 'arn:aws:lambda:us-west-2:123456789012:function:my-function'
// Note: On some cloud providers, it may not be possible to determine the full ID // Note: On some cloud providers, it may not be possible to determine the full ID
@ -449,7 +480,7 @@ const (
// The immutable version of the function being executed. // The immutable version of the function being executed.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: '26', 'pinkfroid-00002' // Examples: '26', 'pinkfroid-00002'
// Note: Depending on the cloud provider and platform, use: // Note: Depending on the cloud provider and platform, use:
@ -471,7 +502,7 @@ const (
// other invocations to the same function/function version. // other invocations to the same function/function version.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: '2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de' // Examples: '2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de'
// Note: * **AWS Lambda:** Use the (full) log stream name. // Note: * **AWS Lambda:** Use the (full) log stream name.
@ -479,7 +510,7 @@ const (
// The amount of memory available to the serverless function in MiB. // The amount of memory available to the serverless function in MiB.
// //
// Type: int // Type: int
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 128 // Examples: 128
// Note: It's recommended to set this attribute since e.g. too little memory can // Note: It's recommended to set this attribute since e.g. too little memory can
@ -492,46 +523,47 @@ const (
// A host is defined as a general computing instance. // A host is defined as a general computing instance.
const ( const (
// Unique host ID. For Cloud, this must be the instance_id assigned by the cloud // Unique host ID. For Cloud, this must be the instance_id assigned by the cloud
// provider. // provider. For non-containerized Linux systems, the `machine-id` located in
// `/etc/machine-id` or `/var/lib/dbus/machine-id` may be used.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'opentelemetry-test' // Examples: 'fdbf79e8af94cb7f9e8df36789187052'
HostIDKey = attribute.Key("host.id") HostIDKey = attribute.Key("host.id")
// Name of the host. On Unix systems, it may contain what the hostname command // Name of the host. On Unix systems, it may contain what the hostname command
// returns, or the fully qualified hostname, or another name specified by the // returns, or the fully qualified hostname, or another name specified by the
// user. // user.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'opentelemetry-test' // Examples: 'opentelemetry-test'
HostNameKey = attribute.Key("host.name") HostNameKey = attribute.Key("host.name")
// Type of host. For Cloud, this must be the machine type. // Type of host. For Cloud, this must be the machine type.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'n1-standard-1' // Examples: 'n1-standard-1'
HostTypeKey = attribute.Key("host.type") HostTypeKey = attribute.Key("host.type")
// The CPU architecture the host system is running on. // The CPU architecture the host system is running on.
// //
// Type: Enum // Type: Enum
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
HostArchKey = attribute.Key("host.arch") HostArchKey = attribute.Key("host.arch")
// Name of the VM image or OS install the host was instantiated from. // Name of the VM image or OS install the host was instantiated from.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'infra-ami-eks-worker-node-7d4ec78312', 'CentOS-8-x86_64-1905' // Examples: 'infra-ami-eks-worker-node-7d4ec78312', 'CentOS-8-x86_64-1905'
HostImageNameKey = attribute.Key("host.image.name") HostImageNameKey = attribute.Key("host.image.name")
// VM image ID. For Cloud, this value is from the provider. // VM image ID. For Cloud, this value is from the provider.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'ami-07b06b442921831e5' // Examples: 'ami-07b06b442921831e5'
HostImageIDKey = attribute.Key("host.image.id") HostImageIDKey = attribute.Key("host.image.id")
@ -539,7 +571,7 @@ const (
// Attributes](README.md#version-attributes). // Attributes](README.md#version-attributes).
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: '0.1' // Examples: '0.1'
HostImageVersionKey = attribute.Key("host.image.version") HostImageVersionKey = attribute.Key("host.image.version")
@ -569,7 +601,7 @@ const (
// The name of the cluster. // The name of the cluster.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'opentelemetry-cluster' // Examples: 'opentelemetry-cluster'
K8SClusterNameKey = attribute.Key("k8s.cluster.name") K8SClusterNameKey = attribute.Key("k8s.cluster.name")
@ -580,14 +612,14 @@ const (
// The name of the Node. // The name of the Node.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'node-1' // Examples: 'node-1'
K8SNodeNameKey = attribute.Key("k8s.node.name") K8SNodeNameKey = attribute.Key("k8s.node.name")
// The UID of the Node. // The UID of the Node.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: '1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2' // Examples: '1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2'
K8SNodeUIDKey = attribute.Key("k8s.node.uid") K8SNodeUIDKey = attribute.Key("k8s.node.uid")
@ -598,7 +630,7 @@ const (
// The name of the namespace that the pod is running in. // The name of the namespace that the pod is running in.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'default' // Examples: 'default'
K8SNamespaceNameKey = attribute.Key("k8s.namespace.name") K8SNamespaceNameKey = attribute.Key("k8s.namespace.name")
@ -609,14 +641,14 @@ const (
// The UID of the Pod. // The UID of the Pod.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
K8SPodUIDKey = attribute.Key("k8s.pod.uid") K8SPodUIDKey = attribute.Key("k8s.pod.uid")
// The name of the Pod. // The name of the Pod.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'opentelemetry-pod-autoconf' // Examples: 'opentelemetry-pod-autoconf'
K8SPodNameKey = attribute.Key("k8s.pod.name") K8SPodNameKey = attribute.Key("k8s.pod.name")
@ -629,7 +661,7 @@ const (
// (`container.name`). // (`container.name`).
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'redis' // Examples: 'redis'
K8SContainerNameKey = attribute.Key("k8s.container.name") K8SContainerNameKey = attribute.Key("k8s.container.name")
@ -637,7 +669,7 @@ const (
// identify a particular container (running or stopped) within a container spec. // identify a particular container (running or stopped) within a container spec.
// //
// Type: int // Type: int
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 0, 2 // Examples: 0, 2
K8SContainerRestartCountKey = attribute.Key("k8s.container.restart_count") K8SContainerRestartCountKey = attribute.Key("k8s.container.restart_count")
@ -648,14 +680,14 @@ const (
// The UID of the ReplicaSet. // The UID of the ReplicaSet.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
K8SReplicaSetUIDKey = attribute.Key("k8s.replicaset.uid") K8SReplicaSetUIDKey = attribute.Key("k8s.replicaset.uid")
// The name of the ReplicaSet. // The name of the ReplicaSet.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'opentelemetry' // Examples: 'opentelemetry'
K8SReplicaSetNameKey = attribute.Key("k8s.replicaset.name") K8SReplicaSetNameKey = attribute.Key("k8s.replicaset.name")
@ -666,14 +698,14 @@ const (
// The UID of the Deployment. // The UID of the Deployment.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
K8SDeploymentUIDKey = attribute.Key("k8s.deployment.uid") K8SDeploymentUIDKey = attribute.Key("k8s.deployment.uid")
// The name of the Deployment. // The name of the Deployment.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'opentelemetry' // Examples: 'opentelemetry'
K8SDeploymentNameKey = attribute.Key("k8s.deployment.name") K8SDeploymentNameKey = attribute.Key("k8s.deployment.name")
@ -684,14 +716,14 @@ const (
// The UID of the StatefulSet. // The UID of the StatefulSet.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
K8SStatefulSetUIDKey = attribute.Key("k8s.statefulset.uid") K8SStatefulSetUIDKey = attribute.Key("k8s.statefulset.uid")
// The name of the StatefulSet. // The name of the StatefulSet.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'opentelemetry' // Examples: 'opentelemetry'
K8SStatefulSetNameKey = attribute.Key("k8s.statefulset.name") K8SStatefulSetNameKey = attribute.Key("k8s.statefulset.name")
@ -702,14 +734,14 @@ const (
// The UID of the DaemonSet. // The UID of the DaemonSet.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
K8SDaemonSetUIDKey = attribute.Key("k8s.daemonset.uid") K8SDaemonSetUIDKey = attribute.Key("k8s.daemonset.uid")
// The name of the DaemonSet. // The name of the DaemonSet.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'opentelemetry' // Examples: 'opentelemetry'
K8SDaemonSetNameKey = attribute.Key("k8s.daemonset.name") K8SDaemonSetNameKey = attribute.Key("k8s.daemonset.name")
@ -720,14 +752,14 @@ const (
// The UID of the Job. // The UID of the Job.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
K8SJobUIDKey = attribute.Key("k8s.job.uid") K8SJobUIDKey = attribute.Key("k8s.job.uid")
// The name of the Job. // The name of the Job.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'opentelemetry' // Examples: 'opentelemetry'
K8SJobNameKey = attribute.Key("k8s.job.name") K8SJobNameKey = attribute.Key("k8s.job.name")
@ -738,14 +770,14 @@ const (
// The UID of the CronJob. // The UID of the CronJob.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
K8SCronJobUIDKey = attribute.Key("k8s.cronjob.uid") K8SCronJobUIDKey = attribute.Key("k8s.cronjob.uid")
// The name of the CronJob. // The name of the CronJob.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'opentelemetry' // Examples: 'opentelemetry'
K8SCronJobNameKey = attribute.Key("k8s.cronjob.name") K8SCronJobNameKey = attribute.Key("k8s.cronjob.name")
@ -756,21 +788,21 @@ const (
// The operating system type. // The operating system type.
// //
// Type: Enum // Type: Enum
// Required: Always // RequirementLevel: Required
// Stability: stable // Stability: stable
OSTypeKey = attribute.Key("os.type") OSTypeKey = attribute.Key("os.type")
// Human readable (not intended to be parsed) OS version information, like e.g. // Human readable (not intended to be parsed) OS version information, like e.g.
// reported by `ver` or `lsb_release -a` commands. // reported by `ver` or `lsb_release -a` commands.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'Microsoft Windows [Version 10.0.18363.778]', 'Ubuntu 18.04.1 LTS' // Examples: 'Microsoft Windows [Version 10.0.18363.778]', 'Ubuntu 18.04.1 LTS'
OSDescriptionKey = attribute.Key("os.description") OSDescriptionKey = attribute.Key("os.description")
// Human readable operating system name. // Human readable operating system name.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'iOS', 'Android', 'Ubuntu' // Examples: 'iOS', 'Android', 'Ubuntu'
OSNameKey = attribute.Key("os.name") OSNameKey = attribute.Key("os.name")
@ -778,7 +810,7 @@ const (
// Attributes](../../resource/semantic_conventions/README.md#version-attributes). // Attributes](../../resource/semantic_conventions/README.md#version-attributes).
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: '14.2.1', '18.04.1' // Examples: '14.2.1', '18.04.1'
OSVersionKey = attribute.Key("os.version") OSVersionKey = attribute.Key("os.version")
@ -814,16 +846,23 @@ const (
// Process identifier (PID). // Process identifier (PID).
// //
// Type: int // Type: int
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 1234 // Examples: 1234
ProcessPIDKey = attribute.Key("process.pid") ProcessPIDKey = attribute.Key("process.pid")
// Parent Process identifier (PID).
//
// Type: int
// RequirementLevel: Optional
// Stability: stable
// Examples: 111
ProcessParentPIDKey = attribute.Key("process.parent_pid")
// The name of the process executable. On Linux based systems, can be set to the // The name of the process executable. On Linux based systems, can be set to the
// `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of // `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of
// `GetProcessImageFileNameW`. // `GetProcessImageFileNameW`.
// //
// Type: string // Type: string
// Required: See below // RequirementLevel: ConditionallyRequired (See alternative attributes below.)
// Stability: stable // Stability: stable
// Examples: 'otelcol' // Examples: 'otelcol'
ProcessExecutableNameKey = attribute.Key("process.executable.name") ProcessExecutableNameKey = attribute.Key("process.executable.name")
@ -832,7 +871,7 @@ const (
// `GetProcessImageFileNameW`. // `GetProcessImageFileNameW`.
// //
// Type: string // Type: string
// Required: See below // RequirementLevel: ConditionallyRequired (See alternative attributes below.)
// Stability: stable // Stability: stable
// Examples: '/usr/bin/cmd/otelcol' // Examples: '/usr/bin/cmd/otelcol'
ProcessExecutablePathKey = attribute.Key("process.executable.path") ProcessExecutablePathKey = attribute.Key("process.executable.path")
@ -841,7 +880,7 @@ const (
// can be set to the first parameter extracted from `GetCommandLineW`. // can be set to the first parameter extracted from `GetCommandLineW`.
// //
// Type: string // Type: string
// Required: See below // RequirementLevel: ConditionallyRequired (See alternative attributes below.)
// Stability: stable // Stability: stable
// Examples: 'cmd/otelcol' // Examples: 'cmd/otelcol'
ProcessCommandKey = attribute.Key("process.command") ProcessCommandKey = attribute.Key("process.command")
@ -851,7 +890,7 @@ const (
// `process.command_args` instead. // `process.command_args` instead.
// //
// Type: string // Type: string
// Required: See below // RequirementLevel: ConditionallyRequired (See alternative attributes below.)
// Stability: stable // Stability: stable
// Examples: 'C:\\cmd\\otecol --config="my directory\\config.yaml"' // Examples: 'C:\\cmd\\otecol --config="my directory\\config.yaml"'
ProcessCommandLineKey = attribute.Key("process.command_line") ProcessCommandLineKey = attribute.Key("process.command_line")
@ -862,14 +901,14 @@ const (
// the full argv vector passed to `main`. // the full argv vector passed to `main`.
// //
// Type: string[] // Type: string[]
// Required: See below // RequirementLevel: ConditionallyRequired (See alternative attributes below.)
// Stability: stable // Stability: stable
// Examples: 'cmd/otecol', '--config=config.yaml' // Examples: 'cmd/otecol', '--config=config.yaml'
ProcessCommandArgsKey = attribute.Key("process.command_args") ProcessCommandArgsKey = attribute.Key("process.command_args")
// The username of the user that owns the process. // The username of the user that owns the process.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'root' // Examples: 'root'
ProcessOwnerKey = attribute.Key("process.owner") ProcessOwnerKey = attribute.Key("process.owner")
@ -881,7 +920,7 @@ const (
// SHOULD be the name of the compiler. // SHOULD be the name of the compiler.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'OpenJDK Runtime Environment' // Examples: 'OpenJDK Runtime Environment'
ProcessRuntimeNameKey = attribute.Key("process.runtime.name") ProcessRuntimeNameKey = attribute.Key("process.runtime.name")
@ -889,7 +928,7 @@ const (
// modification. // modification.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: '14.0.2' // Examples: '14.0.2'
ProcessRuntimeVersionKey = attribute.Key("process.runtime.version") ProcessRuntimeVersionKey = attribute.Key("process.runtime.version")
@ -897,7 +936,7 @@ const (
// specific vendor customization of the runtime environment. // specific vendor customization of the runtime environment.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0' // Examples: 'Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0'
ProcessRuntimeDescriptionKey = attribute.Key("process.runtime.description") ProcessRuntimeDescriptionKey = attribute.Key("process.runtime.description")
@ -908,7 +947,7 @@ const (
// Logical name of the service. // Logical name of the service.
// //
// Type: string // Type: string
// Required: Always // RequirementLevel: Required
// Stability: stable // Stability: stable
// Examples: 'shoppingcart' // Examples: 'shoppingcart'
// Note: MUST be the same for all instances of horizontally scaled services. If // Note: MUST be the same for all instances of horizontally scaled services. If
@ -920,7 +959,7 @@ const (
// A namespace for `service.name`. // A namespace for `service.name`.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'Shop' // Examples: 'Shop'
// Note: A string value having a meaning that helps to distinguish a group of // Note: A string value having a meaning that helps to distinguish a group of
@ -934,7 +973,7 @@ const (
// The string ID of the service instance. // The string ID of the service instance.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: '627cc493-f310-47de-96bd-71410b7dec09' // Examples: '627cc493-f310-47de-96bd-71410b7dec09'
// Note: MUST be unique for each instance of the same // Note: MUST be unique for each instance of the same
@ -953,7 +992,7 @@ const (
// The version string of the service API or implementation. // The version string of the service API or implementation.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: '2.0.0' // Examples: '2.0.0'
ServiceVersionKey = attribute.Key("service.version") ServiceVersionKey = attribute.Key("service.version")
@ -964,27 +1003,27 @@ const (
// The name of the telemetry SDK as defined above. // The name of the telemetry SDK as defined above.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'opentelemetry' // Examples: 'opentelemetry'
TelemetrySDKNameKey = attribute.Key("telemetry.sdk.name") TelemetrySDKNameKey = attribute.Key("telemetry.sdk.name")
// The language of the telemetry SDK. // The language of the telemetry SDK.
// //
// Type: Enum // Type: Enum
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
TelemetrySDKLanguageKey = attribute.Key("telemetry.sdk.language") TelemetrySDKLanguageKey = attribute.Key("telemetry.sdk.language")
// The version string of the telemetry SDK. // The version string of the telemetry SDK.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: '1.2.3' // Examples: '1.2.3'
TelemetrySDKVersionKey = attribute.Key("telemetry.sdk.version") TelemetrySDKVersionKey = attribute.Key("telemetry.sdk.version")
// The version string of the auto instrumentation agent, if used. // The version string of the auto instrumentation agent, if used.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: '1.2.3' // Examples: '1.2.3'
TelemetryAutoVersionKey = attribute.Key("telemetry.auto.version") TelemetryAutoVersionKey = attribute.Key("telemetry.auto.version")
@ -1020,14 +1059,14 @@ const (
// The name of the web engine. // The name of the web engine.
// //
// Type: string // Type: string
// Required: Always // RequirementLevel: Required
// Stability: stable // Stability: stable
// Examples: 'WildFly' // Examples: 'WildFly'
WebEngineNameKey = attribute.Key("webengine.name") WebEngineNameKey = attribute.Key("webengine.name")
// The version of the web engine. // The version of the web engine.
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: '21.0.0' // Examples: '21.0.0'
WebEngineVersionKey = attribute.Key("webengine.version") WebEngineVersionKey = attribute.Key("webengine.version")
@ -1035,8 +1074,45 @@ const (
// information). // information).
// //
// Type: string // Type: string
// Required: No // RequirementLevel: Optional
// Stability: stable // Stability: stable
// Examples: 'WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) - 2.2.2.Final' // Examples: 'WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) - 2.2.2.Final'
WebEngineDescriptionKey = attribute.Key("webengine.description") WebEngineDescriptionKey = attribute.Key("webengine.description")
) )
// Attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts.
const (
// The name of the instrumentation scope - (`InstrumentationScope.Name` in OTLP).
//
// Type: string
// RequirementLevel: Optional
// Stability: stable
// Examples: 'io.opentelemetry.contrib.mongodb'
OtelScopeNameKey = attribute.Key("otel.scope.name")
// The version of the instrumentation scope - (`InstrumentationScope.Version` in
// OTLP).
//
// Type: string
// RequirementLevel: Optional
// Stability: stable
// Examples: '1.0.0'
OtelScopeVersionKey = attribute.Key("otel.scope.version")
)
// Span attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts.
const (
// Deprecated, use the `otel.scope.name` attribute.
//
// Type: string
// RequirementLevel: Optional
// Stability: deprecated
// Examples: 'io.opentelemetry.contrib.mongodb'
OtelLibraryNameKey = attribute.Key("otel.library.name")
// Deprecated, use the `otel.scope.version` attribute.
//
// Type: string
// RequirementLevel: Optional
// Stability: deprecated
// Examples: '1.0.0'
OtelLibraryVersionKey = attribute.Key("otel.library.version")
)

View file

@ -12,9 +12,9 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package semconv // import "go.opentelemetry.io/otel/semconv/v1.12.0" package semconv // import "go.opentelemetry.io/otel/semconv/v1.17.0"
// SchemaURL is the schema URL that matches the version of the semantic conventions // SchemaURL is the schema URL that matches the version of the semantic conventions
// that this package defines. Semconv packages starting from v1.4.0 must declare // that this package defines. Semconv packages starting from v1.4.0 must declare
// non-empty schema URL in the form https://opentelemetry.io/schemas/<version> // non-empty schema URL in the form https://opentelemetry.io/schemas/<version>
const SchemaURL = "https://opentelemetry.io/schemas/1.12.0" const SchemaURL = "https://opentelemetry.io/schemas/1.17.0"

View file

@ -16,5 +16,5 @@ package otel // import "go.opentelemetry.io/otel"
// Version is the current release version of OpenTelemetry in use. // Version is the current release version of OpenTelemetry in use.
func Version() string { func Version() string {
return "1.11.2" return "1.12.0"
} }

View file

@ -14,7 +14,7 @@
module-sets: module-sets:
stable-v1: stable-v1:
version: v1.11.2 version: v1.12.0
modules: modules:
- go.opentelemetry.io/otel - go.opentelemetry.io/otel
- go.opentelemetry.io/otel/bridge/opentracing - go.opentelemetry.io/otel/bridge/opentracing
@ -34,7 +34,7 @@ module-sets:
- go.opentelemetry.io/otel/trace - go.opentelemetry.io/otel/trace
- go.opentelemetry.io/otel/sdk - go.opentelemetry.io/otel/sdk
experimental-metrics: experimental-metrics:
version: v0.34.0 version: v0.35.0
modules: modules:
- go.opentelemetry.io/otel/example/opencensus - go.opentelemetry.io/otel/example/opencensus
- go.opentelemetry.io/otel/example/prometheus - go.opentelemetry.io/otel/example/prometheus

View file

@ -5,4 +5,4 @@
package internal package internal
// Version is the current tagged release of the library. // Version is the current tagged release of the library.
const Version = "0.108.0" const Version = "0.109.0"

27
vendor/modules.txt vendored
View file

@ -80,7 +80,7 @@ github.com/VividCortex/ewma
# github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 # github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137
## explicit; go 1.15 ## explicit; go 1.15
github.com/alecthomas/units github.com/alecthomas/units
# github.com/aws/aws-sdk-go v1.44.189 # github.com/aws/aws-sdk-go v1.44.190
## explicit; go 1.11 ## explicit; go 1.11
github.com/aws/aws-sdk-go/aws github.com/aws/aws-sdk-go/aws
github.com/aws/aws-sdk-go/aws/awserr github.com/aws/aws-sdk-go/aws/awserr
@ -268,7 +268,7 @@ github.com/felixge/httpsnoop
## explicit; go 1.17 ## explicit; go 1.17
github.com/go-kit/log github.com/go-kit/log
github.com/go-kit/log/level github.com/go-kit/log/level
# github.com/go-logfmt/logfmt v0.5.1 # github.com/go-logfmt/logfmt v0.6.0
## explicit; go 1.17 ## explicit; go 1.17
github.com/go-logfmt/logfmt github.com/go-logfmt/logfmt
# github.com/go-logr/logr v1.2.3 # github.com/go-logr/logr v1.2.3
@ -441,7 +441,7 @@ github.com/russross/blackfriday/v2
## explicit; go 1.13 ## explicit; go 1.13
github.com/stretchr/testify/assert github.com/stretchr/testify/assert
github.com/stretchr/testify/require github.com/stretchr/testify/require
# github.com/urfave/cli/v2 v2.24.1 # github.com/urfave/cli/v2 v2.24.2
## explicit; go 1.18 ## explicit; go 1.18
github.com/urfave/cli/v2 github.com/urfave/cli/v2
# github.com/valyala/bytebufferpool v1.0.0 # github.com/valyala/bytebufferpool v1.0.0
@ -488,10 +488,10 @@ go.opencensus.io/trace
go.opencensus.io/trace/internal go.opencensus.io/trace/internal
go.opencensus.io/trace/propagation go.opencensus.io/trace/propagation
go.opencensus.io/trace/tracestate go.opencensus.io/trace/tracestate
# go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.37.0 # go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.38.0
## explicit; go 1.18 ## explicit; go 1.18
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp
# go.opentelemetry.io/otel v1.11.2 # go.opentelemetry.io/otel v1.12.0
## explicit; go 1.18 ## explicit; go 1.18
go.opentelemetry.io/otel go.opentelemetry.io/otel
go.opentelemetry.io/otel/attribute go.opentelemetry.io/otel/attribute
@ -502,20 +502,17 @@ go.opentelemetry.io/otel/internal/attribute
go.opentelemetry.io/otel/internal/baggage go.opentelemetry.io/otel/internal/baggage
go.opentelemetry.io/otel/internal/global go.opentelemetry.io/otel/internal/global
go.opentelemetry.io/otel/propagation go.opentelemetry.io/otel/propagation
go.opentelemetry.io/otel/semconv/internal go.opentelemetry.io/otel/semconv/internal/v2
go.opentelemetry.io/otel/semconv/v1.12.0 go.opentelemetry.io/otel/semconv/v1.17.0
# go.opentelemetry.io/otel/metric v0.34.0 go.opentelemetry.io/otel/semconv/v1.17.0/httpconv
# go.opentelemetry.io/otel/metric v0.35.0
## explicit; go 1.18 ## explicit; go 1.18
go.opentelemetry.io/otel/metric go.opentelemetry.io/otel/metric
go.opentelemetry.io/otel/metric/global go.opentelemetry.io/otel/metric/global
go.opentelemetry.io/otel/metric/instrument go.opentelemetry.io/otel/metric/instrument
go.opentelemetry.io/otel/metric/instrument/asyncfloat64
go.opentelemetry.io/otel/metric/instrument/asyncint64
go.opentelemetry.io/otel/metric/instrument/syncfloat64
go.opentelemetry.io/otel/metric/instrument/syncint64
go.opentelemetry.io/otel/metric/internal/global go.opentelemetry.io/otel/metric/internal/global
go.opentelemetry.io/otel/metric/unit go.opentelemetry.io/otel/metric/unit
# go.opentelemetry.io/otel/trace v1.11.2 # go.opentelemetry.io/otel/trace v1.12.0
## explicit; go 1.18 ## explicit; go 1.18
go.opentelemetry.io/otel/trace go.opentelemetry.io/otel/trace
# go.uber.org/atomic v1.10.0 # go.uber.org/atomic v1.10.0
@ -525,7 +522,7 @@ go.uber.org/atomic
## explicit; go 1.18 ## explicit; go 1.18
go.uber.org/goleak go.uber.org/goleak
go.uber.org/goleak/internal/stack go.uber.org/goleak/internal/stack
# golang.org/x/exp v0.0.0-20230127193734-31bee513bff7 # golang.org/x/exp v0.0.0-20230131160201-f062dba9d201
## explicit; go 1.18 ## explicit; go 1.18
golang.org/x/exp/constraints golang.org/x/exp/constraints
golang.org/x/exp/slices golang.org/x/exp/slices
@ -572,7 +569,7 @@ golang.org/x/time/rate
## explicit; go 1.17 ## explicit; go 1.17
golang.org/x/xerrors golang.org/x/xerrors
golang.org/x/xerrors/internal golang.org/x/xerrors/internal
# google.golang.org/api v0.108.0 # google.golang.org/api v0.109.0
## explicit; go 1.19 ## explicit; go 1.19
google.golang.org/api/googleapi google.golang.org/api/googleapi
google.golang.org/api/googleapi/transport google.golang.org/api/googleapi/transport