tracehandler_test.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. package handler
  2. import (
  3. "context"
  4. "io"
  5. "net/http"
  6. "net/http/httptest"
  7. "strconv"
  8. "testing"
  9. "github.com/stretchr/testify/assert"
  10. ztrace "github.com/zeromicro/go-zero/core/trace"
  11. "github.com/zeromicro/go-zero/rest/chain"
  12. "go.opentelemetry.io/otel"
  13. "go.opentelemetry.io/otel/propagation"
  14. "go.opentelemetry.io/otel/trace"
  15. )
  16. func TestOtelHandler(t *testing.T) {
  17. ztrace.StartAgent(ztrace.Config{
  18. Name: "go-zero-test",
  19. Endpoint: "http://localhost:14268/api/traces",
  20. Batcher: "jaeger",
  21. Sampler: 1.0,
  22. })
  23. defer ztrace.StopAgent()
  24. for _, test := range []string{"", "bar"} {
  25. t.Run(test, func(t *testing.T) {
  26. h := chain.New(TraceHandler("foo", test)).Then(
  27. http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  28. span := trace.SpanFromContext(r.Context())
  29. assert.True(t, span.SpanContext().IsValid())
  30. assert.True(t, span.IsRecording())
  31. }))
  32. ts := httptest.NewServer(h)
  33. defer ts.Close()
  34. client := ts.Client()
  35. err := func(ctx context.Context) error {
  36. ctx, span := otel.Tracer("httptrace/client").Start(ctx, "test")
  37. defer span.End()
  38. req, _ := http.NewRequest("GET", ts.URL, nil)
  39. otel.GetTextMapPropagator().Inject(ctx, propagation.HeaderCarrier(req.Header))
  40. res, err := client.Do(req)
  41. assert.Nil(t, err)
  42. return res.Body.Close()
  43. }(context.Background())
  44. assert.Nil(t, err)
  45. })
  46. }
  47. }
  48. func TestDontTracingSpan(t *testing.T) {
  49. ztrace.StartAgent(ztrace.Config{
  50. Name: "go-zero-test",
  51. Endpoint: "http://localhost:14268/api/traces",
  52. Batcher: "jaeger",
  53. Sampler: 1.0,
  54. })
  55. defer ztrace.StopAgent()
  56. for _, test := range []string{"", "bar", "foo"} {
  57. t.Run(test, func(t *testing.T) {
  58. h := chain.New(TraceHandler("foo", test, WithTraceIgnorePaths([]string{"bar"}))).Then(
  59. http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  60. span := trace.SpanFromContext(r.Context())
  61. spanCtx := span.SpanContext()
  62. if test == "bar" {
  63. assert.False(t, spanCtx.IsValid())
  64. assert.False(t, span.IsRecording())
  65. return
  66. }
  67. assert.True(t, span.IsRecording())
  68. assert.True(t, spanCtx.IsValid())
  69. }))
  70. ts := httptest.NewServer(h)
  71. defer ts.Close()
  72. client := ts.Client()
  73. err := func(ctx context.Context) error {
  74. ctx, span := otel.Tracer("httptrace/client").Start(ctx, "test")
  75. defer span.End()
  76. req, _ := http.NewRequest("GET", ts.URL, nil)
  77. otel.GetTextMapPropagator().Inject(ctx, propagation.HeaderCarrier(req.Header))
  78. res, err := client.Do(req)
  79. assert.Nil(t, err)
  80. return res.Body.Close()
  81. }(context.Background())
  82. assert.Nil(t, err)
  83. })
  84. }
  85. }
  86. func TestTraceResponseWriter(t *testing.T) {
  87. ztrace.StartAgent(ztrace.Config{
  88. Name: "go-zero-test",
  89. Endpoint: "http://localhost:14268/api/traces",
  90. Batcher: "jaeger",
  91. Sampler: 1.0,
  92. })
  93. defer ztrace.StopAgent()
  94. for _, test := range []int{0, 200, 300, 400, 401, 500, 503} {
  95. t.Run(strconv.Itoa(test), func(t *testing.T) {
  96. h := chain.New(TraceHandler("foo", "bar")).Then(
  97. http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  98. span := trace.SpanFromContext(r.Context())
  99. spanCtx := span.SpanContext()
  100. assert.True(t, span.IsRecording())
  101. assert.True(t, spanCtx.IsValid())
  102. if test != 0 {
  103. w.WriteHeader(test)
  104. }
  105. w.Write([]byte("hello"))
  106. }))
  107. ts := httptest.NewServer(h)
  108. defer ts.Close()
  109. client := ts.Client()
  110. err := func(ctx context.Context) error {
  111. ctx, span := otel.Tracer("httptrace/client").Start(ctx, "test")
  112. defer span.End()
  113. req, _ := http.NewRequest("GET", ts.URL, nil)
  114. otel.GetTextMapPropagator().Inject(ctx, propagation.HeaderCarrier(req.Header))
  115. res, err := client.Do(req)
  116. assert.Nil(t, err)
  117. resBody := make([]byte, 5)
  118. _, err = res.Body.Read(resBody)
  119. assert.Equal(t, io.EOF, err)
  120. assert.Equal(t, []byte("hello"), resBody, "response body fail")
  121. return res.Body.Close()
  122. }(context.Background())
  123. assert.Nil(t, err)
  124. })
  125. }
  126. }