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

trace4cats.meta.MetaTraceUtil.scala Maven / Gradle / Ivy

There is a newer version: 0.14.7
Show newest version
package trace4cats.meta

import cats.Monad
import cats.data.NonEmptyList
import cats.effect.kernel.Resource.ExitCase
import cats.effect.kernel.{Clock, Resource}
import cats.syntax.flatMap._
import cats.syntax.functor._
import fs2.Chunk
import trace4cats.kernel.BuildInfo
import trace4cats.model._

object MetaTraceUtil {
  def trace[F[_]: Monad: Clock](
    context: SpanContext,
    spanName: String,
    spanKind: SpanKind,
    attributes: Map[String, AttributeValue],
    links: Option[NonEmptyList[Link]],
    onFinish: CompletedSpan.Builder => F[Unit]
  ): Resource[F, MetaTrace] = {

    lazy val (ctx, lnks) = links match {
      case None => (context, links)
      case Some(NonEmptyList(head, tail)) =>
        (
          context.copy(traceId = head.traceId, parent = Some(Parent(head.spanId, isRemote = false))),
          NonEmptyList.fromList(tail)
        )
    }

    Resource
      .makeCase(Clock[F].realTimeInstant) { (start, exit) =>
        Clock[F].realTimeInstant.flatMap { end =>
          val status = exit match {
            case ExitCase.Succeeded => SpanStatus.Ok
            case ExitCase.Errored(e) => SpanStatus.Internal(Option(e.getMessage).getOrElse(e.toString))
            case ExitCase.Canceled => SpanStatus.Cancelled
          }

          val metaSpan = CompletedSpan
            .Builder(
              ctx,
              spanName,
              spanKind,
              start,
              end,
              attributes.updated("trace4cats.version", BuildInfo.version),
              status,
              lnks,
              None
            )

          onFinish(metaSpan)
        }

      }
      .as(MetaTrace(ctx.traceId, ctx.spanId))
  }

  def extractMetadata(batch: Chunk[CompletedSpan]): (Int, Option[NonEmptyList[Link]]) = {
    val (batchSize, links) = batch.foldLeft((0, Set.empty[Link])) { case ((count, links), span) =>
      val updatedLinks = span.metaTrace match {
        case Some(meta) => links + Link(meta.traceId, meta.spanId)
        case None => links
      }

      (count + 1, updatedLinks)
    }

    (batchSize, NonEmptyList.fromList(links.toList))

  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy