feat(tracing/http-transport): emit breadcrumbs
This commit is contained in:
parent
18f9295c60
commit
91fc1dc9c1
2 changed files with 41 additions and 18 deletions
|
@ -35,16 +35,6 @@ func RequestLogger(l zerolog.Logger, requestHeaders, responseHeaders bool) fiber
|
||||||
reqCh := make(chan request, reqLoggerBufSize)
|
reqCh := make(chan request, reqLoggerBufSize)
|
||||||
resCh := make(chan response, reqLoggerBufSize)
|
resCh := make(chan response, reqLoggerBufSize)
|
||||||
|
|
||||||
formatHeaderAttribute := func(t, k string, v []string, i int) string {
|
|
||||||
attr := fmt.Sprintf("%s.headers.%s", t, k)
|
|
||||||
|
|
||||||
if len(v) != 1 {
|
|
||||||
attr = fmt.Sprintf("%s.%d", attr, i)
|
|
||||||
}
|
|
||||||
|
|
||||||
return attr
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
@ -170,3 +160,13 @@ func RequestLogger(l zerolog.Logger, requestHeaders, responseHeaders bool) fiber
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func formatHeaderAttribute(t, k string, v []string, i int) string {
|
||||||
|
attr := fmt.Sprintf("%s.headers.%s", t, k)
|
||||||
|
|
||||||
|
if len(v) != 1 {
|
||||||
|
attr = fmt.Sprintf("%s.%d", attr, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
return attr
|
||||||
|
}
|
||||||
|
|
|
@ -35,14 +35,14 @@ func (t *Telemetry) NewTracedTransport(transport http.RoundTripper, forwardTrace
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *HTTPTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
func (t *HTTPTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
span := t.telemetry.
|
s := t.telemetry.
|
||||||
StartSpan(req.Context(), "http.client", fmt.Sprintf("%s %s", req.Method, req.URL), WithOtelOptions(trace.WithSpanKind(trace.SpanKindClient))).
|
StartSpan(req.Context(), "http.client", fmt.Sprintf("%s %s", req.Method, req.URL), WithOtelOptions(trace.WithSpanKind(trace.SpanKindClient))).
|
||||||
AddAttributes(
|
AddAttributes(
|
||||||
semconv.HTTPRequestMethodKey.String(req.Method),
|
semconv.HTTPRequestMethodKey.String(req.Method),
|
||||||
semconv.URLFull(req.URL.String()),
|
semconv.URLFull(req.URL.String()),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer s.End()
|
||||||
ctx := span.Context()
|
ctx := s.Context()
|
||||||
req = req.WithContext(ctx)
|
req = req.WithContext(ctx)
|
||||||
|
|
||||||
if t.forwardTrace {
|
if t.forwardTrace {
|
||||||
|
@ -50,13 +50,19 @@ func (t *HTTPTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, header := range t.tracedRequestHeaders {
|
for _, header := range t.tracedRequestHeaders {
|
||||||
if v := req.Header.Get(header); v != "" {
|
vv := req.Header.Values(header)
|
||||||
span.AddAttributes(attribute.String(fmt.Sprintf("http.request.header.%s", header), v))
|
for i, v := range vv {
|
||||||
|
s.AddAttributes(attribute.String(formatHeaderAttribute("http.request", header, vv, i), v))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := t.Transport.RoundTrip(req)
|
resp, err := t.Transport.RoundTrip(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
s.CaptureBreadcrumb(SeverityError, BreadcrumbTypeHTTP, BreadcrumbCatagoryHTTP, fmt.Sprintf("Failed to send request to %s: %v", req.URL.String(), err), map[string]any{
|
||||||
|
"url": req.URL.String(),
|
||||||
|
"method": req.Method,
|
||||||
|
})
|
||||||
|
|
||||||
if hub := sentry.GetHubFromContext(ctx); hub != nil {
|
if hub := sentry.GetHubFromContext(ctx); hub != nil {
|
||||||
hub.CaptureException(err)
|
hub.CaptureException(err)
|
||||||
}
|
}
|
||||||
|
@ -64,13 +70,30 @@ func (t *HTTPTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
span.
|
{
|
||||||
|
severity := SeverityDebug
|
||||||
|
if resp.StatusCode < http.StatusBadRequest {
|
||||||
|
severity = SeverityInfo
|
||||||
|
} else if resp.StatusCode < http.StatusInternalServerError {
|
||||||
|
severity = SeverityError
|
||||||
|
} else {
|
||||||
|
severity = SeverityError
|
||||||
|
}
|
||||||
|
s.CaptureBreadcrumb(severity, BreadcrumbTypeHTTP, BreadcrumbCatagoryHTTP, req.URL.String(), map[string]any{
|
||||||
|
"url": req.URL.String(),
|
||||||
|
"method": req.Method,
|
||||||
|
"status": resp.StatusCode,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
s.
|
||||||
AddAttributes(semconv.HTTPResponseStatusCode(resp.StatusCode)).
|
AddAttributes(semconv.HTTPResponseStatusCode(resp.StatusCode)).
|
||||||
SetStatus(httpStatusToSpanStatus(resp.StatusCode, false), "")
|
SetStatus(httpStatusToSpanStatus(resp.StatusCode, false), "")
|
||||||
|
|
||||||
for _, header := range t.tracedResponseHeaders {
|
for _, header := range t.tracedResponseHeaders {
|
||||||
if v := resp.Header.Get(header); v != "" {
|
vv := resp.Header.Values(header)
|
||||||
span.AddAttributes(attribute.String(fmt.Sprintf("http.response.header.%s", header), v))
|
for i, v := range vv {
|
||||||
|
s.AddAttributes(attribute.String(formatHeaderAttribute("http.response", header, vv, i), v))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue