Giter Club home page Giter Club logo

http4s-prometheus-metrics's Introduction

Http4s Build Status Maven Central Typelevel library Cats friendly

Http4s is a minimal, idiomatic Scala interface for HTTP services. Http4s is Scala's answer to Ruby's Rack, Python's WSGI, Haskell's WAI, and Java's Servlets.

val http = HttpRoutes.of {
  case GET -> Root / "hello" =>
    Ok("Hello, better world.")
}

Learn more at http4s.org.

If you run into any difficulties please enable partial unification in your build.sbt (not needed for Scala 2.13 and beyond, because Scala 2.13.0+ has partial unification switched on by default)

scalacOptions ++= Seq("-Ypartial-unification")

Requirements

Running the blaze backend requires a modern, supported version of the JVM to build and run, as it relies on server APIs unavailable before JDK8u252. Any JDK newer than JDK8u252, including 9+ is supported.

Code of Conduct

http4s is proud to be a Typelevel project. We are committed to providing a friendly, safe and welcoming environment for all, and ask that the community adhere to the Scala Code of Conduct.

License

This software is licensed under the Apache 2 license, quoted below.

Copyright 2013-2021 http4s [https://http4s.org]

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

[http://www.apache.org/licenses/LICENSE-2.0]

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Acknowledgments

YourKit

Special thanks to YourKit for supporting this project's ongoing performance tuning efforts with licenses to their excellent product.

http4s-prometheus-metrics's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

http4s-prometheus-metrics's Issues

How to do this in Kubernetes?

I was wondering what the first step would be to integrating this into a kubernetes cluster. Does anyone know of a tutorial that applies this library or something similar?

`PrometheusExportService.addDefaults` using `CollectorRegistry.defaultRegistry` registers `jvm_classes_loaded` multiple times.

Below is a simple reproduction of the issue, tested with version 0.23.12

Reproduction

import cats._
import cats.implicits._
import cats.effect._
import cats.effect.unsafe.implicits._
import io.prometheus.client._
import scala.jdk.CollectionConverters._
import org.http4s.metrics.prometheus._

def printCR(name: String, cr: CollectorRegistry): IO[Unit] = 
  IO.println(s"$name: ${cr.metricFamilySamples.asScala.map(_.name).take(3).mkString("\n  ")}")

def go(name: String, cr: CollectorRegistry): IO[Unit] = {
  IO.println(name) *>
    printCR(s"$name Start", cr) *>
    PrometheusExportService.addDefaults[IO](cr)
      .use { _ => 
        printCR(s"$name After", cr)
      }
  }

{
  go("New Collector", new CollectorRegistry()) *>
  go("Default Collector", CollectorRegistry.defaultRegistry) 
}.unsafeRunSync()

Yields

New Collector
New Collector Start: 
New Collector After: jvm
  process_cpu_seconds
  process_start_time_seconds
Default Collector
Default Collector Start: 
java.lang.IllegalArgumentException: Failed to register Collector of type ClassLoadingExports: The Collector exposes the same name multiple times: jvm_classes_loaded
  at io.prometheus.client.CollectorRegistry.assertNoDuplicateNames(CollectorRegistry.java:71)
  at io.prometheus.client.CollectorRegistry.register(CollectorRegistry.java:51)
  at io.prometheus.client.Collector.register(Collector.java:307)
  at org.http4s.metrics.prometheus.Prometheus$.$anonfun$registerCollector$1(Prometheus.scala:287)
  at println @ printCR(<console>:9)
  at make @ org.http4s.metrics.prometheus.Prometheus$.registerCollector(Prometheus.scala:287)
  at make @ org.http4s.metrics.prometheus.Prometheus$.registerCollector(Prometheus.scala:287)
  ... 5 elided

Documentation improvement on composable HttpRoutes with metrics

Hi team,

I discovered a weird behaviour if metrics are enabled on an HttpRoutes value that is composed with some other value.

For example let's say there are apiRoutes and adminRoutes defined and compose like this:

val metrics: MetricsOps[F] = ???
val apiRoutes: HttpRoutes[F] = ???
val adminRoutes: HttpRoutes[F] = ???

val apiRoutesWithMetrics = Metrics[IO](metrics)(apiRoutes)

httpApp = (
        apiRoutesWithMetrics <+> adminRoutes.  //  <+> SemigroupK Cats
      ).mapF(_.getOrElseF(NotFound()))

return httpApp // <- this is used to create the http4s webserver

Whenever there is a request meant for the adminRoutes the metrics defined for apiRoutesWithMetrics gets incremented for 4xx requests although the request is send back to the client with 200 OK status.

If the routes are composed the other way around adminRoutes <+> apiRoutesWithMetrics this behaviour does not happen.

I'm guessing is because the request goes through the first routes and exists with NotFound (400) and the metrics are incremented and then the request go to the admin routes and there is a route defined but the metrics are already incremented.

I'm not saying it's a bug in the library but maybe there can be added to the documentation.
I'm happy to add it.

What is your opinion on this?

Regards,
Robert

A long-running / blocking enumeration of metrics from all registered collectors starves the server.

Currently the process of enumerating the metrics from all registered collectors is wrapped in Sync[F].delay:

If this is a lengthy / IO-bound operation, this might starve the compute pool of the server. It seems a better choice is to use Sync[F].blocking for that task.

Follow-up of discussion on Discord: https://discord.com/channels/632277896739946517/632286375311573032/1164491603017207808

How to actually use this

Hey, for someone with only limited knowledge around all this Resource/F things it would be extremely helpful to get a simple example in the Readme.md on how to actually use it, i.e. how to combine the PrometheusExportService with an existing http4s App…

Grafana dashboard

It would make getting started easier if this repo has a grafana dashboard that demonstrates how all the metrics exported here can be used.

Maintainers wanted!

Please comment if you are interested in helping to maintain this module :) Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.