在AWS控制台中看不到手动创建的嵌套AWS XRay子段

huangapple go评论72阅读模式
英文:

Not seeing manually created nested AWS XRay subsegments in AWS console

问题

我正在尝试为在AWS ECS上运行的Go编写的提供REST API的Web服务器进行仪器化。目前我在VSCode中以调试模式运行服务器,正在进行一个概念验证,以显示不同端点的跟踪,并将主要函数作为子段。我已经在我们的中间件中对路由器进行了仪器化,代码如下:

h = xray.Handler(xray.NewFixedSegmentNamer("myappname"), h)

然后,在各个处理程序函数中通过传递请求上下文来对函数调用进行仪器化,代码如下:

_, subSeg := xray.BeginSubsegment(ctx, "get-user")

calculateUsefulInfo(ctx)

subSeg.Close(nil)

然后,calculateUsefulInfo()函数可以调用其他函数,并传递上下文(ctx),在内部使用不同的子段名称执行相同的操作(另一个BeginSubsegment+subSeg.Close)。

我已经在AWS上运行了XRay守护程序,并具有适当的权限,我可以在AWS控制台中看到跟踪。然而,我只能看到一层嵌套。

我在AWS上启用了100%的采样率。我在本地模式下运行XRay守护程序,并进行了开发级别的日志记录。你有什么想法,我可能漏掉了什么?

英文:

I'm trying to instrument a web server written in Go that provides REST API, that runs in a container on AWS ECS. I'm running the server in Debug in VSCode for now, working on a proof of concept that would show traces for the different endpoints, with major functions as subsegments. I've instrumented the router in our middleware like this:

h = xray.Handler(xray.NewFixedSegmentNamer("myappname"), h)

And function calls made from the various handler functions are instrumented by passing the request context in, then having this:

_, subSeg := xray.BeginSubsegment(ctx, "get-user")

calculateUsefulInfo(ctx)

subSeg.Close(nil)

Then that calculateUsefulInfo() function can call other functions, passing along the context (ctx) and internally doing the same thing (another BeginSubsegment+subSeg.Close) with a different subsegment name.

I have the AWS XRay daemon running, with appropriate permissions, and I see the traces appear in the AWS console. However, I only see one level of nesting.

在AWS控制台中看不到手动创建的嵌套AWS XRay子段

I turned on 100% sampling in AWS. I'm running the XRay daemon in local mode, dev-level logging. Any idea what I'm missing here?

答案1

得分: 1

父段存储在上下文中,因此如果您只将顶级上下文传递给其他函数,它只会为该父段生成段。

要实现所需的嵌套级别,您必须使用xray.BeginSubsegment提供的context。此上下文包含一个可以追溯到父段的新段。

嵌套段的示例:

package main

import (
	"net"
	"net/http"
	"time"

	"github.com/aws/aws-xray-sdk-go/xray"
	"github.com/davecgh/go-spew/spew"
)

type ConsoleEmitter struct {
}

func (c *ConsoleEmitter) Emit(seg *xray.Segment) {
	spew.Dump(seg)
}

func (c *ConsoleEmitter) RefreshEmitterWithAddress(raddr *net.UDPAddr) {
	return
}

var _ xray.Emitter = (*ConsoleEmitter)(nil)

func init() {
	xray.Configure(xray.Config{
		DaemonAddr:     "127.0.0.1:2000", // 默认值
		ServiceVersion: "1.2.3",
		// 控制台发射器用于在本地查看跟踪的层次结构
		// 而无需使用xray守护程序
		Emitter: &ConsoleEmitter{},
	})
}

func main() {
	http.Handle("/", xray.Handler(xray.NewFixedSegmentNamer("myApp"), http.HandlerFunc(top)))
	http.ListenAndServe(":7000", nil)
}

func top(w http.ResponseWriter, r *http.Request) {
	// 使用xray提供的上下文进行嵌套层次结构
	ctx, subSeg := xray.BeginSubsegment(r.Context(), "top")
	_, childSeg := xray.BeginSubsegment(ctx, "top-sleep")
	time.Sleep(time.Millisecond * 50)
	childSeg.Close(nil)
	middle(w, r)
	subSeg.Close(nil)
}

func middle(w http.ResponseWriter, r *http.Request) {
	ctx, subSeg := xray.BeginSubsegment(r.Context(), "middle")
	_, childSeg := xray.BeginSubsegment(ctx, "middle-sleep")
	time.Sleep(time.Millisecond * 100)
	childSeg.Close(nil)
	bottom(w, r)
	subSeg.Close(nil)
}

func bottom(w http.ResponseWriter, r *http.Request) {
	_, subSeg := xray.BeginSubsegment(r.Context(), "bottom")
	w.Write([]byte("Hello!"))
	subSeg.Close(nil)
}

英文:

The parent segment is stored in the context, so if you are only passing in the top level context to the other functions, it will only generate segments for that parent.

To achieve your desired nesting level you have to use the context provided by xray.BeginSubsegment. This context contains a new segment that can be traced back to the parent.

Example with nested segments:

package main

import (
	"net"
	"net/http"
	"time"

	"github.com/aws/aws-xray-sdk-go/xray"
	"github.com/davecgh/go-spew/spew"
)

type ConsoleEmitter struct {
}

func (c *ConsoleEmitter) Emit(seg *xray.Segment) {
	spew.Dump(seg)
}

func (c *ConsoleEmitter) RefreshEmitterWithAddress(raddr *net.UDPAddr) {
	return
}

var _ xray.Emitter = (*ConsoleEmitter)(nil)

func init() {
	xray.Configure(xray.Config{
		DaemonAddr:     "127.0.0.1:2000", // default
		ServiceVersion: "1.2.3",
		// console emitter to view the hierarchy of the traces locally
		// without the xray daemon
		Emitter: &ConsoleEmitter{},
	})
}

func main() {
	http.Handle("/", xray.Handler(xray.NewFixedSegmentNamer("myApp"), http.HandlerFunc(top)))
	http.ListenAndServe(":7000", nil)
}

func top(w http.ResponseWriter, r *http.Request) {
	// use the context provided by xray for nested hierarchy
	ctx, subSeg := xray.BeginSubsegment(r.Context(), "top")
	_, childSeg := xray.BeginSubsegment(ctx, "top-sleep")
	time.Sleep(time.Millisecond * 50)
	childSeg.Close(nil)
	middle(w, r)
	subSeg.Close(nil)
}

func middle(w http.ResponseWriter, r *http.Request) {
	ctx, subSeg := xray.BeginSubsegment(r.Context(), "middle")
	_, childSeg := xray.BeginSubsegment(ctx, "middle-sleep")
	time.Sleep(time.Millisecond * 100)
	childSeg.Close(nil)
	bottom(w, r)
	subSeg.Close(nil)
}

func bottom(w http.ResponseWriter, r *http.Request) {
	_, subSeg := xray.BeginSubsegment(r.Context(), "bottom")
	w.Write([]byte("Hello!"))
	subSeg.Close(nil)
}

huangapple
  • 本文由 发表于 2022年10月12日 22:09:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/74043317.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定