1// Unless explicitly stated otherwise all files in this repository are licensed 2// under the Apache License Version 2.0. 3// This product includes software developed at Datadog (https://www.datadoghq.com/). 4// Copyright 2016 Datadog, Inc. 5 6// Package fiber provides tracing functions for tracing the fiber package (https://github.com/gofiber/fiber). 7package fiber // import "gopkg.in/DataDog/dd-trace-go.v1/contrib/gofiber/fiber.v2" 8 9import ( 10 "fmt" 11 "math" 12 "net/http" 13 "strconv" 14 15 "github.com/gofiber/fiber/v2" 16 17 "gopkg.in/DataDog/dd-trace-go.v1/ddtrace" 18 "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext" 19 "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer" 20 "gopkg.in/DataDog/dd-trace-go.v1/internal/log" 21) 22 23// Middleware returns middleware that will trace incoming requests. 24func Middleware(opts ...Option) func(c *fiber.Ctx) error { 25 cfg := new(config) 26 defaults(cfg) 27 for _, fn := range opts { 28 fn(cfg) 29 } 30 log.Debug("gofiber/fiber.v2: Middleware: %#v", cfg) 31 return func(c *fiber.Ctx) error { 32 opts := []ddtrace.StartSpanOption{ 33 tracer.SpanType(ext.SpanTypeWeb), 34 tracer.ServiceName(cfg.serviceName), 35 tracer.Tag(ext.HTTPMethod, c.Method()), 36 tracer.Tag(ext.HTTPURL, string(c.Request().URI().PathOriginal())), 37 tracer.Measured(), 38 } 39 if !math.IsNaN(cfg.analyticsRate) { 40 opts = append(opts, tracer.Tag(ext.EventSampleRate, cfg.analyticsRate)) 41 } 42 43 opts = append(opts, cfg.spanOpts...) 44 span, _ := tracer.StartSpanFromContext(c.Context(), "http.request", opts...) 45 46 fmt.Printf("Starting Span") 47 defer span.Finish() 48 49 resourceName := c.Path() 50 if resourceName == "" { 51 resourceName = "unknown" 52 } 53 resourceName = c.Method() + " " + resourceName 54 span.SetTag(ext.ResourceName, resourceName) 55 56 // pass the execution down the line 57 err := c.Next() 58 59 status := c.Response().StatusCode() 60 // on the off chance we don't yet have a status after the rest of the things have run 61 if status == 0 { 62 // 0 - means we do not have a status code at this point 63 // in case the response was returned by a middleware without one 64 status = http.StatusOK 65 } 66 span.SetTag(ext.HTTPCode, strconv.Itoa(status)) 67 68 if cfg.isStatusError(status) { 69 // mark 5xx server error 70 span.SetTag(ext.Error, fmt.Errorf("%d: %s", status, http.StatusText(status))) 71 } 72 return err 73 } 74} 75