Skip to content

Commit

Permalink
Merge pull request #42 from permutive-engineering/release-prep
Browse files Browse the repository at this point in the history
  • Loading branch information
janstenpickle authored Jan 30, 2023
2 parents cfab8eb + bc5a3f8 commit bd817d1
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 32 deletions.
3 changes: 3 additions & 0 deletions .scala-steward.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pullRequests.grouping = [
{ name = "all", title = "Dependency updates", "filter" = [{"group" = "*"}] }
]
93 changes: 93 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Prometheus4Cats Contrib

This repository contains a series of integrations for [Prometheus4Cats] that instrument other libraries or metric
sources. Each integration is documented below:

## Bigtable

Google Bigtable [Java client instrumentation](https://cloud.google.com/bigtable/docs/client-side-metrics).
Uses a [Prometheus4Cats] callback registry to inspect the client metrics registered with OpenCensus.

Use the [`BigtableOpenCensusMetrics`](bigtable/src/main/scala/prometheus4cats/bigtable/BigtableOpenCensusMetrics.scala)
smart constructor to enable metric collection on the Java client and registering them with a
[`MetricFactory.WithCallbacks`].

```sbt
"com.permutive" %% "prometheus4cats-contrib-google-cloud-bigtable" % "<VERSION>"
```

## Cats-Effect

[Cats-Effect] metrics taken from JMX MBeans. This includes a
[CPU starvation](https://typelevel.org/cats-effect/docs/core/starvation-and-tuning) counter.

Use the [`CatsEffectMBeans`](cats-effect/src/main/scala/prometheus4cats/catseffect/CatsEffectMBeans.scala)
smart constructor register callbacks for [Cats-Effect] MBeans with [`MetricFactory.WithCallbacks`].

```sbt
"com.permutive" %% "prometheus4cats-contrib-cats-effect" % "<VERSION>"
```

## FS2-Kafka

[FS2-Kafka] integration that instruments consumers and producers. Uses a [Prometheus4Cats] callback registry to inspect
built-in [Kafka client metrics](https://docs.confluent.io/platform/current/kafka/monitoring.html#).

Use the smart constructors in [`KafkaMetrics`](fs2-kafka/src/main/scala/prometheus4cats/fs2kafka/KafkaMetrics.scala)
to register callbacks for producers and consumers with a [`MetricFactory.WithCallbacks`].

```sbt
"com.permutive" %% "prometheus4cats-contrib-fs2-kafka" % "<VERSION>"
```

## Refreshable

Instrumented implementation of [Refreshable]. Provides the following metrics:

| Metric Name | Labels | Metric Type | Description |
|--------------------------------------|-----------------------------------|-------------|-------------------------------------------------------------------------------------------------------------|
| `refreshable_read_total` | `refreshable_name`, `value_state` | Counter | Number of times this Refreshable has been read, with a label denoting the state of the value |
| `refreshable_is_running` | `refreshable_name` | Gauge | Whether this Refreshable is running - `1` if true, `0` if false |
| `refreshable_retries_exhausted` | `refreshable_name` | Gauge | Whether retries have been exhausted for this Refreshable - `1` if true, `0` if false |
| `refreshable_refresh_failing` | `refreshable_name` | Gauge | Whether refresh is currently failing - `1` if true, `0` if false |
| `refreeshable_refresh_success_total` | `refreshable_name` | Counter | Number of times the refresh operation has succeeded |
| `refreshable_refresh_failure_total` | `refreshable_name` | Counter | Number of times refresh failed |
| `refreshable_status` | `refreshable_name`, `value_state` | Gauge | The current status of this Refreshable - a value of `1` against the label value indicates the current state |

Use the [`InstrumentedRefreshable`](refreshable/src/main/scala/prometheus4cats/refreshable/InstrumentedRefreshable.scala)
smart constructor to instrument a given `Refreshable` when used with an instance of [`MetricFactory.WithCallbacks`].

```sbt
"com.permutive" %% "prometheus4cats-contrib-refreshable" % "<VERSION>"
```

## Trace4Cats

Instrumented implementations of [Trace4Cats] interfaces. Provides the following metrics:

| Interface | Metric Name | Labels | Metric Type | Description |
|-----------------|--------------------------------------|-------------------------------------------|-------------|----------------------------------------------------|
| `EntryPoint` | `trace4cats_entry_point_spans_total` | `span_kind`, `is_root`, `sample_decision` | Counter | Total number of spans created |
| `SpanCompleter` | `trace4cats_completer_spans_total` | `completer_name` | Counter | Total number of spans completed |
| `SpanCompleter` | `trace4cats_completer_complete_time` | `completer_name` | Histogram | Time it takes to complete a span in seconds |
| `SpanExporter` | `trace4cats_exporter_batches_total` | `exporter_name` | Counter | Total number of batches sent via this exporter |
| `SpanExporter` | `trace4cats_exporter_export_time` | `exporter_name` | Histogram | Time it takes to export a span batch in seconds |
| `SpanExporter` | `trace4cats_exporter_batch_size` | `exporter_name` | Histogram | Size distribution of batches sent by this exporter |

Use the [`InstrumentedEntrypoint`](trace4cats/src/main/scala/prometheus4cats/trace4cats/InstrumentedEntrypoint.scala),
[`InstrumentedSpanCompleter`](trace4cats/src/main/scala/prometheus4cats/trace4cats/InstrumentedSpanCompleter.scala) and
[`InstrumentedSpanExporter`](trace4cats/src/main/scala/prometheus4cats/trace4cats/InstrumentedSpanExporter.scala) with
a [`MetricFactory`] to return instrumented wrappers of the underlying implementations.

```sbt
"com.permutive" %% "prometheus4cats-contrib-trace4cats" % "<VERSION>"
```

[Cats-Effect]: https://typelevel.org/cats-effect
[FS2-Kafka]: https://fd4s.github.io/fs2-kafka/
[Refreshable]: https://github.com/permutive-engineering/refreshable
[Trace4Cats]: https://github.com/trace4cats/trace4cats
[Prometheus4Cats]: https://github.com/permutive-engineering/prometheus4cats

[`MetricFactory`]: https://permutive-engineering.github.io/prometheus4cats/interface/metric-factory.html
[`MetricFactory.WithCallbacks`]: https://permutive-engineering.github.io/prometheus4cats/interface/metric-factory.html
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ val Scala213 = "2.13.10"
ThisBuild / crossScalaVersions := Seq("2.12.17", Scala213, "3.2.1")
ThisBuild / scalaVersion := Scala213 // the default Scala

val Prometheus4Cats = "1.0.0-RC3"
val Prometheus4Cats = "1.0.0"

val CollectionCompat = "2.9.0"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,7 @@ class KafkaMetricsSuite extends CatsEffectSuite with TestContainerForAll {
Resource.eval(IO.delay(new CollectorRegistry())).flatMap { reg =>
JavaMetricRegistry
.fromSimpleClientRegistry[IO](
reg,
metricCollectionCallbackTimeout = 1.second
reg
)
.map(MetricFactory.builder.build(_) -> reg)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@

package prometheus4cats.refreshable

import cats.Applicative
import cats.data.NonEmptyList
import cats.{Applicative, Functor}
import cats.effect.kernel.syntax.monadCancel._
import cats.effect.kernel.syntax.resource._
import cats.effect.kernel.syntax.spawn._
Expand Down Expand Up @@ -144,30 +145,27 @@ object InstrumentedRefreshable {
).tupled
}

// TODO this might need a new release of prometheus4cats so multiple label values can be returned to represent when
// there are no errors or no cancellation, we'll have to see how this looks in prometheus
// FIXME multiple instances of this callback break prometheus4cats
// private def callback[F[_]: Functor, A](
// name: String,
// refreshable: Refreshable[F, A],
// metricFactory: MetricFactory.WithCallbacks[F]
// ): Resource[F, Unit] =
// metricFactory
// .withPrefix(prefix)
// .gauge("status")
// .ofLong
// .help("The current status of this Refreshable")
// .label[String](refreshableLabelName)
// .label[CachedValue[A]](
// "value_state",
// {
// case CachedValue.Success(_) => "success"
// case CachedValue.Error(_, _) => "error"
// case CachedValue.Cancelled(_) => "cancelled"
// }
// )
// .callback(refreshable.get.map { v => (1, (name, v)) })
// .build
private def callback[F[_]: Functor, A](
name: String,
refreshable: Refreshable[F, A],
metricFactory: MetricFactory.WithCallbacks[F]
): Resource[F, Unit] =
metricFactory
.withPrefix(prefix)
.gauge("status")
.ofLong
.help("The current status of this Refreshable")
.label[String](refreshableLabelName)
.label[CachedValue[A]](
"value_state",
{
case CachedValue.Success(_) => "success"
case CachedValue.Error(_, _) => "error"
case CachedValue.Cancelled(_) => "cancelled"
}
)
.callback(refreshable.get.map { v => NonEmptyList.one((1L, (name, v))) })
.build

private def metrics[F[_]: MonadCancelThrow, A](
name: String,
Expand Down Expand Up @@ -268,7 +266,7 @@ object InstrumentedRefreshable {
.onExhaustedRetries(onExhaustedRetries)
.resource
.evalTap(_ => runningGauge.set(true, name))
// .flatTap(callback(name, _, metricFactory))
.flatTap(callback(name, _, metricFactory))
.map { refreshable =>
new InstrumentedRefreshable[F, A](
refreshable,
Expand Down Expand Up @@ -298,9 +296,7 @@ object InstrumentedRefreshable {
refreshFailureCounter
)
) =>
// callback(name, refreshable, metricFactory)
// .evalTap(_ => runningGauge.set(true, name))
Resource
callback(name, refreshable, metricFactory) >> Resource
.uncancelable((_: Poll[Resource[F, *]]) =>
Resource.make(runningGauge.set(true, name))(_ =>
runningGauge.set(false, name)
Expand Down

0 comments on commit bd817d1

Please sign in to comment.