All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.janstenpickle.trace4cats.rate.sampling.RateSpanSampler.scala Maven / Gradle / Ivy

The newest version!
package io.janstenpickle.trace4cats.rate.sampling

import cats.Applicative
import cats.effect.kernel.{Resource, Temporal}
import cats.syntax.functor._
import io.janstenpickle.trace4cats.kernel.SpanSampler
import io.janstenpickle.trace4cats.model.{SampleDecision, SpanContext, SpanKind, TraceId}
import io.janstenpickle.trace4cats.rate.{TokenBucket, TokenInterval}

import scala.concurrent.duration._

object RateSpanSampler {
  def apply[F[_]: Applicative: TokenBucket]: SpanSampler[F] = apply(rootSpansOnly = true)

  def apply[F[_]: Applicative: TokenBucket](rootSpansOnly: Boolean): SpanSampler[F] =
    new SpanSampler[F] {
      override def shouldSample(
        parentContext: Option[SpanContext],
        traceId: TraceId,
        spanName: String,
        spanKind: SpanKind
      ): F[SampleDecision] = {
        val sampleDecisionF: F[SampleDecision] = TokenBucket[F].request1.map {
          case false => SampleDecision.Drop
          case true => SampleDecision.Include
        }

        parentContext.map(_.traceFlags.sampled).fold(sampleDecisionF) {
          case SampleDecision.Include =>
            if (rootSpansOnly) Applicative[F].pure(SampleDecision.Include)
            else sampleDecisionF
          case SampleDecision.Drop => Applicative[F].pure(SampleDecision.Drop)
        }
      }

    }

  def create[F[_]: Temporal](bucketSize: Int, tokenRate: Double): Resource[F, SpanSampler[F]] =
    create(bucketSize, tokenRate, rootSpansOnly = true)

  def create[F[_]: Temporal](bucketSize: Int, tokenRate: Double, rootSpansOnly: Boolean): Resource[F, SpanSampler[F]] =
    TokenInterval(tokenRate)
      .fold(Resource.pure[F, SpanSampler[F]](SpanSampler.always[F]))(create[F](bucketSize, _, rootSpansOnly))

  def create[F[_]: Temporal](bucketSize: Int, tokenInterval: FiniteDuration): Resource[F, SpanSampler[F]] =
    create(bucketSize, tokenInterval, rootSpansOnly = true)

  def create[F[_]: Temporal](
    bucketSize: Int,
    tokenInterval: FiniteDuration,
    rootSpansOnly: Boolean
  ): Resource[F, SpanSampler[F]] =
    TokenBucket.create[F](bucketSize, tokenInterval).map(implicit tb => apply[F](rootSpansOnly))
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy