content: {-# LANGUAGE OverloadedStrings #-}
  
  module OpenTelemetry.Network.Wai.Middleware where
  
  import qualified Data.ByteString.Char8 as BS8
  import Network.HTTP.Types
  import Network.Wai
  import OpenTelemetry.Eventlog
  import OpenTelemetry.Propagation
  
  -- Semantic conventions for HTTP spans:
  -- https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/http.md
  
  mkMiddleware :: IO (Application -> Application)
  mkMiddleware = do
    requestCounter <- mkCounter "requests"
    return $ \app req sendResp -> do
      withSpan "WAI handler" $ \sp -> do
        add requestCounter 1
        case propagateFromHeaders w3cTraceContext (requestHeaders req) of
          Just ctx -> setParentSpanContext sp ctx
          _ -> pure ()
        setTag sp "span.kind" "server"
        setTag sp "component" "http"
        setTag sp "http.method" $ requestMethod req
        setTag sp "http.target" $ rawPathInfo req
        setTag sp "http.flavor" $ BS8.pack $ show (httpVersion req)
        app req $ \resp -> do
          setTag sp "http.status_code" (BS8.pack $ show $ statusCode $ responseStatus resp)
          sendResp resp
  