freckle-app 1.15.5.0 → 1.16.0.0
raw patch · 5 files changed
+76/−5 lines, 5 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Freckle.App: instance Control.Monad.IO.Class.MonadIO m => Freckle.App.Http.MonadHttp (Freckle.App.AppT app m)
+ Freckle.App: instance (Control.Monad.IO.Unlift.MonadUnliftIO m, OpenTelemetry.Trace.Core.HasTracer app) => Freckle.App.Http.MonadHttp (Freckle.App.AppT app m)
+ Freckle.App.OpenTelemetry.Http: httpAttributes :: Request -> HashMap Text Attribute
+ Freckle.App.OpenTelemetry.Http: httpResponseAttributes :: Response body -> HashMap Text Attribute
+ Freckle.App.OpenTelemetry.Http: httpSpanArguments :: Request -> SpanArguments
+ Freckle.App.OpenTelemetry.Http: httpSpanName :: Request -> Text
Files
- CHANGELOG.md +9/−1
- freckle-app.cabal +2/−1
- library/Freckle/App.hs +6/−2
- library/Freckle/App/OpenTelemetry/Http.hs +58/−0
- package.yaml +1/−1
CHANGELOG.md view
@@ -1,4 +1,12 @@-## [_Unreleased_](https://github.com/freckle/freckle-app/compare/v1.15.5.0...main)+## [_Unreleased_](https://github.com/freckle/freckle-app/compare/v1.16.0.0...main)++## [v1.16.0.0](https://github.com/freckle/freckle-app/compare/v1.15.5.0...v1.16.0.0)++- Add tracing to HTTP requests made within `AppT`++ This is a potentially breaking change for users of `AppT app` because it now+ requires `HasTracer app`. This instance most likely already exists, since it's+ required to use `runDB` too. ## [v1.15.5.0](https://github.com/freckle/freckle-app/compare/v1.15.4.0...v1.15.5.0)
freckle-app.cabal view
@@ -1,6 +1,6 @@ cabal-version: 1.18 name: freckle-app-version: 1.15.5.0+version: 1.16.0.0 license: MIT license-file: LICENSE maintainer: Freckle Education@@ -60,6 +60,7 @@ Freckle.App.Memcached.Servers Freckle.App.OpenTelemetry Freckle.App.OpenTelemetry.Context+ Freckle.App.OpenTelemetry.Http Freckle.App.OpenTelemetry.ThreadContext Freckle.App.Prelude Freckle.App.Random
library/Freckle/App.hs view
@@ -191,6 +191,8 @@ import qualified Freckle.App.Database.XRay as XRay import Freckle.App.Http (MonadHttp (..)) import Freckle.App.OpenTelemetry+import Freckle.App.OpenTelemetry.Context+import Freckle.App.OpenTelemetry.Http import System.IO (BufferMode (..), hSetBuffering, stderr, stdout) runApp@@ -240,8 +242,10 @@ primitive = AppT . lift . lift . lift . primitive {-# INLINE primitive #-} -instance MonadIO m => MonadHttp (AppT app m) where- httpLbs = liftIO . httpLbs+instance (MonadUnliftIO m, HasTracer app) => MonadHttp (AppT app m) where+ httpLbs req = inSpan (httpSpanName req) (httpSpanArguments req) $ do+ resp <- liftIO . httpLbs =<< injectContext req+ resp <$ addCurrentSpanAttributes (httpResponseAttributes resp) instance (Monad m, HasTracer app) => MonadTracer (AppT app m) where getTracer = view tracerL
+ library/Freckle/App/OpenTelemetry/Http.hs view
@@ -0,0 +1,58 @@+module Freckle.App.OpenTelemetry.Http+ ( httpSpanName+ , httpSpanArguments+ , httpAttributes+ , httpResponseAttributes+ ) where++import Freckle.App.Prelude++import qualified Data.CaseInsensitive as CI+import qualified Data.HashMap.Strict as HashMap+import qualified Data.Text as T+import Data.Text.Encoding (decodeUtf8With)+import Data.Text.Encoding.Error (lenientDecode)+import Freckle.App.OpenTelemetry+ ( SpanArguments (..)+ , byteStringToAttribute+ , clientSpanArguments+ )+import Network.HTTP.Client (Request, Response)+import qualified Network.HTTP.Client as HTTP+import Network.HTTP.Types.Status (statusCode)+import OpenTelemetry.Attributes (Attribute, ToAttribute (..))++httpSpanName :: Request -> Text+httpSpanName req =+ decodeUtf8With lenientDecode $ HTTP.method req <> " " <> HTTP.path req++httpSpanArguments :: Request -> SpanArguments+httpSpanArguments req = clientSpanArguments {attributes = httpAttributes req}++httpAttributes :: Request -> HashMap Text Attribute+httpAttributes req =+ HashMap.fromList+ [ ("service.name", byteStringToAttribute $ HTTP.host req)+ , ("resource.name", toAttribute $ httpSpanName req)+ , ("http.host", byteStringToAttribute $ HTTP.host req)+ , ("http.method", byteStringToAttribute $ HTTP.method req)+ , ("http.path", byteStringToAttribute $ HTTP.path req)+ , ("http.query", byteStringToAttribute $ HTTP.queryString req)+ ]++httpResponseAttributes :: Response body -> HashMap Text Attribute+httpResponseAttributes resp = statusAttr <> foldMap (uncurry headerAttr) (HTTP.responseHeaders resp)+ where+ statusAttr =+ HashMap.singleton "http.status_code"+ . toAttribute+ . statusCode+ $ HTTP.responseStatus resp++ headerAttr k = HashMap.singleton (headerAttrKey k) . byteStringToAttribute++ headerAttrKey =+ ("http.response.headers." <>)+ . T.toLower+ . decodeUtf8With lenientDecode+ . CI.original
package.yaml view
@@ -1,5 +1,5 @@ name: freckle-app-version: 1.15.5.0+version: 1.16.0.0 maintainer: Freckle Education category: Utils github: freckle/freckle-app