英文:
Propagate OpenTelemetry context through Google PubSub using Go
问题
使用Go语言,我该如何通过Google PubSub传播OpenTelemetry上下文?
英文:
Using Go, how can I propagate the OpenTelemetry context
through Google PubSub
?
答案1
得分: 1
为了实现这一点,我实现了TextMapCarrier
接口
// TextMapCarrier是TextMapPropagator使用的存储介质。
type TextMapCarrier interface {
Get(key string) string
Set(key string, value string)
Keys() []string
}
最终的代码如下:
package whatever
import (
"cloud.google.com/go/pubsub"
"context"
"go.opentelemetry.io/otel"
)
const pubsubAttribPrefix = "whatever"
// PubsubMessageCarrier从pubsub.Message中注入和提取跟踪信息。
type PubsubMessageCarrier struct {
msg *pubsub.Message
}
// NewPubsubMessageCarrier创建一个新的PubsubMessageCarrier。
func NewPubsubMessageCarrier(msg *pubsub.Message) PubsubMessageCarrier {
return PubsubMessageCarrier{msg: msg}
}
// Get检索给定键的单个值。
func (c PubsubMessageCarrier) Get(key string) string {
return c.msg.Attributes[pubsubAttribPrefix+"_"+key]
}
// Set设置一个属性。
func (c PubsubMessageCarrier) Set(key, val string) {
c.msg.Attributes[pubsubAttribPrefix+"_"+key] = val
}
// Keys返回载体中所有键的切片。
func (c PubsubMessageCarrier) Keys() []string {
i := 0
out := make([]string, len(c.msg.Attributes))
for k := range c.msg.Attributes {
out[i] = k
i++
}
return out
}
func PubSubMessageInjectContext(ctx context.Context, msg *pubsub.Message) {
otel.GetTextMapPropagator().Inject(ctx, NewPubsubMessageCarrier(msg))
}
func PubSubMessageExtractContext(ctx context.Context, msg *pubsub.Message) context.Context {
return otel.GetTextMapPropagator().Extract(ctx, NewPubsubMessageCarrier(msg))
}
现在只需将最新的context
和PubSub
消息传递给PubSubMessageInjectContext
函数。这将向消息中注入数据。
在接收到的消息中,将新的context
与接收到的message
一起传递,以提取数据。然后使用输出的context
创建一个新的span
。
注意,这并没有提供需要添加到指定span的属性,比如semconv.MessagingDestinationKindTopic
。
尽管基本功能已经实现,但这还没有经过实战测试。
英文:
To accomplish that I implemented the TextMapCarrier
interface
// TextMapCarrier is the storage medium used by a TextMapPropagator.
type TextMapCarrier interface {
Get(key string) string
Set(key string, value string)
Keys() []string
}
The final code is:
package whatever
import (
"cloud.google.com/go/pubsub"
"context"
"go.opentelemetry.io/otel"
)
const pubsubAttribPrefix = "whatever"
// PubsubMessageCarrier injects and extracts traces from a pubsub.Message.
type PubsubMessageCarrier struct {
msg *pubsub.Message
}
// NewPubsubMessageCarrier creates a new PubsubMessageCarrier.
func NewPubsubMessageCarrier(msg *pubsub.Message) PubsubMessageCarrier {
return PubsubMessageCarrier{msg: msg}
}
// Get retrieves a single value for a given key.
func (c PubsubMessageCarrier) Get(key string) string {
return c.msg.Attributes[pubsubAttribPrefix+"_"+key]
}
// Set sets an attribute.
func (c PubsubMessageCarrier) Set(key, val string) {
c.msg.Attributes[pubsubAttribPrefix+"_"+key] = val
}
// Keys returns a slice of all keys in the carrier.
func (c PubsubMessageCarrier) Keys() []string {
i := 0
out := make([]string, len(c.msg.Attributes))
for k := range c.msg.Attributes {
out[i] = k
i++
}
return out
}
func PubSubMessageInjectContext(ctx context.Context, msg *pubsub.Message) {
otel.GetTextMapPropagator().Inject(ctx, NewPubsubMessageCarrier(msg))
}
func PubSubMessageExtractContext(ctx context.Context, msg *pubsub.Message) context.Context {
return otel.GetTextMapPropagator().Extract(ctx, NewPubsubMessageCarrier(msg))
}
So all that is left is to feed the latest context
from the span
and the PubSub
message to PubSubMessageInjectContext
. This will inject the data to the message.
On the other side feed the new context
with the received message
to extract the data. And use the output context
to create a new span
.
Note, this does not provide attributes that need to be added to the designated span. like semconv.MessagingDestinationKindTopic
It still not battle tested though the basics are here
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论