haskell-servant / servant-ekg Goto Github PK
View Code? Open in Web Editor NEWThis project forked from christian-marie/servant-ekg
License: BSD 3-Clause "New" or "Revised" License
This project forked from christian-marie/servant-ekg
License: BSD 3-Clause "New" or "Revised" License
I was able to add prometheus metrics supports with this super small snippet:
import Data.Proxy (Proxy)
import Data.Text (Text)
import qualified Data.Text as Text
import Network.Wai (Application, Request)
import Network.Wai.Middleware.Prometheus (instrumentHandlerValue)
import Servant.Ekg
( APIEndpoint (APIEndpoint),
HasEndpoint (getEndpoint),
)
-- | A middleware that records latency metrics for all endpoints in 'api'
instrumentServantHandlers :: HasEndpoint api => Proxy api -> Application -> Application
instrumentServantHandlers proxy app = do
instrumentHandlerValue (makeLabel proxy) app
makeLabel :: HasEndpoint api => Proxy api -> Request -> Text
makeLabel proxy req = case getEndpoint proxy req of
Nothing -> "<unknown>"
Just (APIEndpoint pathParts _method) -> "/" <> Text.intercalate "/" pathParts
type GetMetrics = "metrics" :> Get '[PlainText] Text
handleGetMetrics :: Handler Text
handleGetMetrics = do
Encoding.decodeUtf8With Encoding.lenientDecode <$> Prometheus.exportMetricsAsText
It only depends on the HasEndpoint
typeclass. I'm wondering if maybe we should move HasEndpoint
into the servant
core package to make Prometheus support possible without people having to pull in the ekg
dependency? cc @haskell-servant/maintainers
IDK if servant-prometheus
deserves its only library or should just be a cookbook with the above code.
Servant responds to HEAD
requests with the result of the GET
path (minus the body), since haskell-servant/servant@050aa21
If the WAI verb is HEAD
, and the path verb is GET
, this path should match.
e.g.
instance ReflectMethod method => HasEndpoint (Verb method status cts a) where
getEndpoint _ req =
if requestMethod req == method || (requestMethod req == methodHead && method == methodGet) then
Just (APIEndpoint [] method)
else
Nothing
enumerateEndpoints _ = [APIEndpoint mempty method]
where method = reflectMethod (Proxy :: Proxy method)
Though actually, this is incomplete; a GET
route should also register a HEAD
route in enumerateEndpoints
, and the WAI verb should be used in preference to the route verb in the result of getEndpoint
.
I've been using the repository as the source for the package, but I would be interested in using a version on Hackage. Does it make sense to push a new version?
I'm happy to move the https://github.com/christian-marie/servant-ekg project here, but, as per christian-marie#4 I'm not sure how.
Does anyone know the process?
Do we need GitHub support to do this?
Building test suite 'spec' for servant-ekg-0.3.2..
[1 of 2] Compiling Servant.EkgSpec ( test/Servant/EkgSpec.hs, dist/build/spec/spec-tmp/Servant/EkgSpec.o )
test/Servant/EkgSpec.hs:66:23: error:
• No instance for (HasEndpoint
(Fragment Int :> Servant.Test.ComprehensiveAPI.GET))
arising from a use of ‘monitorEndpoints’
• In the first argument of ‘(=<<)’, namely
‘monitorEndpoints comprehensiveAPI’
In a stmt of a 'do' block:
_typeLevelTest <- monitorEndpoints comprehensiveAPI =<< newStore
In the second argument of ‘($)’, namely
‘do _typeLevelTest <- monitorEndpoints comprehensiveAPI
=<< newStore
True `shouldBe` True’
|
66 | _typeLevelTest <- monitorEndpoints comprehensiveAPI =<< newStore
What do you think about using a monotonic clock like the one in System.Clock instead of getCurrentTime? System clocks occasionally move backwards in order to correct clock skew, which makes a mess of latency statistics.
(To be clear, I haven't yet seen this issue with this particular library, but it's a known challenge.)
Happy to follow up with a PR if you like the idea.
Otherwise this is going to be slow...
Would it be possible to get an update for servant-ekg
that supports the current version of warp-3.3.5
? I tried the build with the upper bound edited out and it succeeded just fine, so maybe all there is to it is to edit the Cabal file an Hackage to allow the newer version.
Using lts-14.27
.
The API type has overlapping endpoints plus a raw endpoint for Pandoc-generated API documentation. The application runs hoisted on a custom monad
type TheAPI = "try" :> "this" :> ...
:<|> "try" :> "that" :> ...
:<|> "try" :> "those" :> ...
:<|> "lookup"
:<|> Raw
theAPI :: Proxy TheAPI
theAPI = Proxy
apiServer :: ServerT TheAPI CustomM
apiServer = ... :<|> ... etc
myApp config = serve theAPI $ hoistServer theAPI (nt cconfig) apiServer
where nt
does the natural transformation via runReaderT
and runLoggerT
.
After a vanilla System.Remote.Monitoring.forkServer
, I'm wrapping the application as follows
wrapWithEkg <- newStore >>= monitorEndpoints theAPI
runSettings settings (wrapWithEkg $ myApp cfg)
where runSettings
does runTLS
over a custom TCP port.
I can connect to EKG. The standard EKG metrics are there, but none of the Servant specific measurements show up.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.