Comments (30)
@linchao0815 这个场景还没有研究过,我先研究一下具体用法,然后尽快给出一个方案
from rk-boot.
@linchao0815 Hi
Q1: 我这里写了一个 Demo 程序,可以参考一下。
实现的逻辑是这样的。因为没有办法把 context 传递给 asynq worker,所以,只能把 trace metadata 放在 task payload 里。
Demo 程序里的办法是,Task 里定义一个 TraceHeader http.Header,然后,把 gRPC context 里的 Trace metadata Copy 到 里面。worker server 里添加一个 middleware,让 middleware 读出 trace metadata,然后,创建一个 span,并且上报到 jaeger。
Demo: https://github.com/rookie-ninja/rk-demo/tree/master/grpc/v2/asynq-jaeger
Q2: 这里是两个 grpc server 相互之间 share same traceId 的 Demo 程序。
Demo: https://github.com/rookie-ninja/rk-demo/tree/master/grpc/v2/distributed-log
from rk-boot.
@dongxuny 非常感謝您的幫助,目前我在測試Q1的回應sample code
Q1.1 由於我們將grpc 和asynq work 實作在同一個server中, 想請問worker 用到的trace.yaml要如何直接使用grpc-server.yaml的定義? 如何不用另外定義trace.yaml?
Q1.2 若我在woker 的task 中再呼叫其它的fun, 若也要使用jager 追蹤再呼叫的fun該如何實作?
from rk-boot.
@dongxuny Q2 問題我重新描述,client A是使用http , server B使用grpc , server B如何回應traceId不定義在proto中而附加在http resopnse中, client A第二個request 再利用http headher帶入traceId給sever B,而使jaeger追踨這三個以上的API ?
from rk-boot.
@dongxuny 非常感謝您的幫助,目前我在測試Q1的回應sample code Q1.1 由於我們將grpc 和asynq work 實作在同一個server中, 想請問worker 用到的trace.yaml要如何直接使用grpc-server.yaml的定義? 如何不用另外定義trace.yaml? Q1.2 若我在woker 的task 中再呼叫其它的fun, 若也要使用jager 追蹤再呼叫的fun該如何實作?
用同一个 YAML 这个没问题,我把例子改一下。呼叫其他 Func 原理上一样,我在例子上也加一下,应该就能比较清晰。
from rk-boot.
@dongxuny Q2 問題我重新描述,client A是使用http , server B使用grpc , server B如何回應traceId不定義在proto中而附加在http resopnse中, client A第二個request 再利用http headher帶入traceId給sever B,而使jaeger追踨這三個以上的API ?
场景清楚了,我重新整理一下例子吧,这个在现在的 rk-boot 里可以实现。
from rk-boot.
@dongxuny Q2 問題我重新描述,client A是使用http , server B使用grpc , server B如何回應traceId不定義在proto中而附加在http resopnse中, client A第二個request 再利用http headher帶入traceId給sever B,而使jaeger追踨這三個以上的API ?
@linchao0815 根据我理解的场景,重新上传了例子,可以参考一下。如果希望 http-server 不创建 trace,而使用 grpc-server 产生的 trace,场景会略有不同,不过还是建议 http-server 创建 trace,跟例子里一样。
https://github.com/rookie-ninja/rk-demo/tree/master/grpc/v2/distributed-log
from rk-boot.
@dongxuny 非常感謝您的幫助,目前我在測試Q1的回應sample code Q1.1 由於我們將grpc 和asynq work 實作在同一個server中, 想請問worker 用到的trace.yaml要如何直接使用grpc-server.yaml的定義? 如何不用另外定義trace.yaml? Q1.2 若我在woker 的task 中再呼叫其它的fun, 若也要使用jager 追蹤再呼叫的fun該如何實作?
@linchao0815 根据需求,更新了例子,参考一下~
https://github.com/rookie-ninja/rk-demo/tree/master/grpc/v2/asynq-jaeger
from rk-boot.
@dongxuny 我試著利用您的二個例子組合我的需求,但遇到問題,
https://github.com/linchao0815/grpc_asynq.git
請參如上 grpc-serverA.go Login(), task.HandleDemoTask() ,在執行 go run httpclient.go 並無法在jaeger中有正確追蹤
我希望在jaeger enqueue -> Login 都可以在jaeger中看到相關
from rk-boot.
@linchao0815 我会 Fork 你的例子,然后做一些修改。
在执行 go run httpclient.go 的时候开始,就生成一个 Trace,然后进行追踪。
from rk-boot.
@linchao0815 这里是我 Fork 了你的项目之后,做的修改,可以参考一下。
https://github.com/dongxuny/grpc_asynq
效果如下图:
from rk-boot.
@dongxuny 感謝您的快速回應
可以麻煩在httpclient.go 提供
send("http://localhost:2008/v1/enqueue", {""}
)
接收回應取得tracieID, 再次呼叫send("http://localhost:2008/v1/enqueue", {""}
)
而在jager中能看到二個相依的enqueue->enqueue
from rk-boot.
@linchao0815 根据描述,更新了例子。https://github.com/dongxuny/grpc_asynq
新的例子里,发送 second-enqueue 之前,不会等待 first-enqueue Task 结束。TraceID 在整个生命周期里是唯一的,span.SpanContext().TraceID().String() 这个函数可以在任何地方得到一摸一样的 TraceID。
from rk-boot.
@dongxuny 我參考您的範例試著修改要整合到我的專案,但遇到底層一些panic,我再修改https://github.com/linchao0815/grpc_asynq 模擬, 我有使用https://github.com/linchao0815/protoc-gen-go-asynqgen 來將asynq做類似proto-go 輸出框架,將需要呼叫span相關再gen code中實作,而不在實作API中每個地方都要再呼叫span
另UnaryInterceptor/grpc.UnaryClientInterceptor 也做每個API 收到/送出 時處理span
我試了幾天還是無法解決painc, 我對於何時該處理span由於有太多種方式,一直無法理解XD
麻煩大神協助!
from rk-boot.
@linchao0815 好的,我先了解一下 https://github.com/linchao0815/protoc-gen-go-asynqgen,然后,试一下。
from rk-boot.
@linchao0815 按照你的思路改了一下 protoc-gen-go-asynqgen
代码逻辑解释起来有些复杂,简单来说:把 Trace 信息复制过来,复制过去的过程。可以参考一下例子。
这是应用例子:https://github.com/dongxuny/grpc_asynq
from rk-boot.
感謝 大神幫忙!
from rk-boot.
@dongxuny 請問在trace中的 ignore: ["/v1/CreateUser"] ,我設定但無效, jaeger中還是會看到
app:
name: rk
grpc:
- name: userServer
enabled: true
port: 2008
enableReflection: true
enableRkGwOption: true
sw:
enabled: true
path: "sw"
jsonPath: "api/gen/v1"
middleware:
trace:
enabled: true
ignore: ["/v1/CreateUser"]
exporter:
jaeger:
agent:
enabled: false
collector:
enabled: true
from rk-boot.
@linchao0815 grpc 里 ignore 应该用 grpc 的Path,我给你个例子吧。
from rk-boot.
@linchao0815 这是 ignore 日志的例子,trace 的 ignore 也一样。
https://github.com/rookie-ninja/rk-demo/tree/master/grpc/v2/ignore-middleware
gRPC 得用 gRPC 的 Path。
from rk-boot.
@dongxuny
我加到
trace:
ignore:
我只是不想log到 jaeger ,但還是希望可以呼叫此api,但加了會出現以下錯誤
{"error":{"code":500,"status":"Internal Server Error","message":"runtime error: invalid memory address or nil pointer dereference","details":[]}}
雖然加到
logging:
ignore:
不會有上面錯誤, 但jaeger中還是會看到, 因為服務上k8s 使用ingress 會一直被呼叫healthcheck,不想在jaeger一直看到healthcheck
from rk-boot.
@linchao0815 ignore 只会忽略 jaeger,不会影响 API 的调用。你的这个错误是从哪里出来的?有全部的 Stack trace 吗?
或者把你的 boot.yaml 配置发一下。
from rk-boot.
@linchao0815 我重新写了个 trace ignore 的例子,可以对比一下哈。
https://github.com/rookie-ninja/rk-demo/tree/master/grpc/v2/ignore-middleware
from rk-boot.
@linchao0815 ignore 只会忽略 jaeger,不会影响 API 的调用。你的这个错误是从哪里出来的?有全部的 Stack trace 吗? 或者把你的 boot.yaml 配置发一下。
@dongxuny 請參考以下範例
https://github.com/linchao0815/grpc_asynq.git
$ go run user-server.go
$ curl localhost:2008/HealthCheck
就會出現以下
2022-10-20T13:58:42.210+0800 ERROR panic/interceptor.go:42 panic occurs:
goroutine 45 [running]:
runtime/debug.Stack()
C:/Program Files/Go/src/runtime/debug/stack.go:24 +0x65
github.com/rookie-ninja/rk-grpc/v2/middleware/panic.UnaryServerInterceptor.func1.1()
C:/Users/linchao/go/pkg/mod/github.com/rookie-ninja/rk-grpc/[email protected]/middleware/panic/interceptor.go:42 +0x208
panic({0xc37fe0, 0xef92e0})
C:/Program Files/Go/src/runtime/panic.go:838 +0x207
context.WithValue({0x0?, 0x0?}, {0xc367e0?, 0xef90f8?}, {0xd3a3a0?, 0x155fdf8?})
C:/Program Files/Go/src/context/context.go:525 +0x178
go.opentelemetry.io/otel/trace.ContextWithSpan(...)
C:/Users/linchao/go/pkg/mod/go.opentelemetry.io/otel/[email protected]/context.go:25
go.opentelemetry.io/otel/trace.noopTracer.Start({}, {0x0, 0x0}, {0xc0001afd70?, 0x0?}, {0xb?, 0xc0001ecd00?, 0x30e287?})
C:/Users/linchao/go/pkg/mod/go.opentelemetry.io/otel/[email protected]/noop.go:53 +0x7c
github.com/rookie-ninja/rk-grpc/v2/middleware/context.GetTraceSpan({0x0, 0x0})
C:/Users/linchao/go/pkg/mod/github.com/rookie-ninja/rk-grpc/[email protected]/middleware/context/context.go:162 +0x7a
github.com/rookie-ninja/rk-demo/grpcInterceptor.UnaryInterceptor({0x0, 0x0}, {0xce4700, 0xc0001afb00}, 0xc00021e300?, 0xc000010258?)
S:/NFT/test/grpc_asynq/grpcInterceptor/grpcInterceptor.go:19 +0xe5
google.golang.org/grpc.chainUnaryInterceptors.func1.1({0x0?, 0x0?}, {0xce4700?, 0xc0001afb00?})
C:/Users/linchao/go/pkg/mod/google.golang.org/[email protected]/server.go:1129 +0x5b
github.com/rookie-ninja/rk-grpc/v2/middleware/tracing.UnaryServerInterceptor.func1({0xf05328?, 0xc0001afb60?}, {0xce4700, 0xc0001afb00}, 0xc000512300, 0xc000012200)
C:/Users/linchao/go/pkg/mod/github.com/rookie-ninja/rk-grpc/[email protected]/middleware/tracing/server_interceptor.go:54 +0x794
google.golang.org/grpc.chainUnaryInterceptors.func1.1({0xf05328?, 0xc0001afb60?}, {0xce4700?, 0xc0001afb00?})
C:/Users/linchao/go/pkg/mod/google.golang.org/[email protected]/server.go:1132 +0x83
github.com/rookie-ninja/rk-grpc/v2/middleware/panic.UnaryServerInterceptor.func1({0xf05328?, 0xc0001afb60?}, {0xce4700, 0xc0001afb00}, 0xc0f0e0?, 0xc000012200)
C:/Users/linchao/go/pkg/mod/github.com/rookie-ninja/rk-grpc/[email protected]/middleware/panic/interceptor.go:46 +0x19e
google.golang.org/grpc.chainUnaryInterceptors.func1.1({0xf05328?, 0xc0001afb60?}, {0xce4700?, 0xc0001afb00?})
C:/Users/linchao/go/pkg/mod/google.golang.org/[email protected]/server.go:1132 +0x83
github.com/rookie-ninja/rk-grpc/v2/middleware/log.UnaryServerInterceptor.func1({0xf05328?, 0xc0001afad0?}, {0xce4700, 0xc0001afb00}, 0xc000512300, 0xc000012200)
C:/Users/linchao/go/pkg/mod/github.com/rookie-ninja/rk-grpc/[email protected]/middleware/log/server_interceptor.go:54 +0x8ef
google.golang.org/grpc.chainUnaryInterceptors.func1.1({0xf05328?, 0xc0001afad0?}, {0xce4700?, 0xc0001afb00?})
C:/Users/linchao/go/pkg/mod/google.golang.org/[email protected]/server.go:1132 +0x83
google.golang.org/grpc.chainUnaryInterceptors.func1({0xf05328, 0xc0001afad0}, {0xce4700, 0xc0001afb00}, 0xc000512300, 0xc000010258)
C:/Users/linchao/go/pkg/mod/google.golang.org/[email protected]/server.go:1134 +0x12b
github.com/rookie-ninja/rk-demo/api/gen/v1._User_HealthCheck_Handler({0xcc0ee0?, 0xc0001f9480}, {0xf05328, 0xc0001afad0}, 0xc000146380, 0xc000115a00)
S:/NFT/test/grpc_asynq/api/gen/v1/user_grpc.pb.go:116 +0x138
google.golang.org/grpc.(*Server).processUnaryRPC(0xc00047c780, {0xf08ef0, 0xc0000736c0}, 0xc0005f0000, 0xc0002a31a0, 0x14f05c0, 0x0)
C:/Users/linchao/go/pkg/mod/google.golang.org/[email protected]/server.go:1295 +0xb0b
google.golang.org/grpc.(*Server).handleStream(0xc00047c780, {0xf08ef0, 0xc0000736c0}, 0xc0005f0000, 0x0)
C:/Users/linchao/go/pkg/mod/google.golang.org/[email protected]/server.go:1636 +0xa1b
google.golang.org/grpc.(*Server).serveStreams.func1.2()
C:/Users/linchao/go/pkg/mod/google.golang.org/[email protected]/server.go:932 +0x98
created by google.golang.org/grpc.(*Server).serveStreams.func1
C:/Users/linchao/go/pkg/mod/google.golang.org/[email protected]/server.go:930 +0x28a
{"error": "rpc error: code = Internal desc = cannot create context from nil parent"}
from rk-boot.
@linchao0815 rk-entry 有一个很隐蔽的 Bug,修好了。并且把 rk-xxx 其他 package 的版本也升级了一下。我用你的例子验证了一下,不会再抛出 Panic 了。
升级成下面的版本应该就 OK,可以验证一下。
from rk-boot.
感謝!!
from rk-boot.
@dongxuny 我測試以下範例 https://github.com/dongxuny/grpc_asynq
我故意要在task中回傳err
func (t *userTaskServer) CreateUser(ctx context.Context, payload *demo.CreateUserPayload) error {
...
return fmt.Errorf("CreateUser test")
}
我發現底層的span.go
func (s *recordingSpan) SetStatus(code codes.Code, description string) {
if !s.IsRecording() {
return //會在此 return 導致err 沒有寫出, 因此無法在jaeger中查看到err的訊息
}
from rk-boot.
@dongxuny 請問上面有解?
from rk-boot.
@linchao0815 我先研究一下吧,可能会晚一点。
from rk-boot.
@linchao0815 https://github.com/dongxuny/protoc-gen-go-asynqgen 有个 Bug,改了之后,error 能在 jaeger 里查到了。
可以参考最新的 https://github.com/dongxuny/grpc_asynq。
from rk-boot.
Related Issues (20)
- New API error format requested
- grpc的sw中的自定义headers没有效果 HOT 2
- 一个进程启动grpc和gin时的swagger页面访问问题 HOT 3
- connect mongodb cluster error, can you provide a case? Thank you. HOT 3
- how can I find the jwt endpoints? HOT 3
- HTTP Access logs HOT 1
- Cannot override boot config values using environment variables HOT 3
- Is there anyway to configure the default event log at stdout when starting app? HOT 5
- 微信群二维码过期了 HOT 2
- Swagger/Docs Panic: no / before catch-all in path '\/sw\*any' HOT 7
- NewBoot should find boot.yaml in default project dir when called via Go Unit Test HOT 2
- Any plan to support orm `xorm`? HOT 1
- Unable to use Postgres DB in gRPC gateway endpoint HOT 1
- support rk-boot reload config on sighup or watch config HOT 1
- Does rk-boot provides integration with cobra CLI creating tool HOT 1
- Wechat group QRCode is expired
- http://localhost:8080/sw/ render failed HOT 1
- Any plan to support entgo HOT 1
- Enable Grafana Loki writer syncer in rk-boot family which will send logs to Loki directly. HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rk-boot.