aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/xyz/driver/core/reporting/Reporter.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala/xyz/driver/core/reporting/Reporter.scala')
-rw-r--r--src/main/scala/xyz/driver/core/reporting/Reporter.scala183
1 files changed, 0 insertions, 183 deletions
diff --git a/src/main/scala/xyz/driver/core/reporting/Reporter.scala b/src/main/scala/xyz/driver/core/reporting/Reporter.scala
deleted file mode 100644
index 469084c..0000000
--- a/src/main/scala/xyz/driver/core/reporting/Reporter.scala
+++ /dev/null
@@ -1,183 +0,0 @@
-package xyz.driver.core
-package reporting
-
-import scala.concurrent.Future
-
-/** Context-aware diagnostic utility for distributed systems, combining logging and tracing.
- *
- * Diagnostic messages (i.e. logs) are a vital tool for monitoring applications. Tying such messages to an
- * execution context, such as a stack trace, simplifies debugging greatly by giving insight to the chains of events
- * that led to a particular message. In synchronous systems, execution contexts can easily be determined by an
- * external observer, and, as such, do not need to be propagated explicitly to sub-components (e.g. a stack trace on
- * the JVM shows all relevant information). In asynchronous systems and especially distributed systems however,
- * execution contexts are not easily determined by an external observer and hence need to be explicitly passed across
- * service boundaries.
- *
- * This reporter provides tracing and logging utilities that explicitly require references to execution contexts
- * (called [[SpanContext]]s here) intended to be passed across service boundaries. It embraces Scala's
- * implicit-parameter-as-a-context paradigm.
- *
- * Tracing is intended to be compatible with the
- * [[https://github.com/opentracing/specification/blob/master/specification.md OpenTrace specification]], and hence its
- * guidelines on naming and tagging apply to methods provided by this Reporter as well.
- *
- * Usage example:
- * {{{
- * val reporter: Reporter = ???
- * object Repo {
- * def getUserQuery(userId: String)(implicit ctx: SpanContext) = reporter.trace("query"){ implicit ctx =>
- * reporter.debug("Running query")
- * // run query
- * }
- * }
- * object Service {
- * def getUser(userId: String)(implicit ctx: SpanContext) = reporter.trace("get_user"){ implicit ctx =>
- * reporter.debug("Getting user")
- * Repo.getUserQuery(userId)
- * }
- * }
- * reporter.traceRoot("static_get", Map("user" -> "john")) { implicit ctx =>
- * Service.getUser("john")
- * }
- * }}}
- *
- * '''Note that computing traces may be a more expensive operation than traditional logging frameworks provide (in terms
- * of memory and processing). It should be used in interesting and actionable code paths.'''
- *
- * @define rootWarning Note: the idea of the reporting framework is to pass along references to traces as
- * implicit parameters. This method should only be used for top-level traces when no parent
- * traces are available.
- */
-trait Reporter {
- import Reporter._
-
- def traceWithOptionalParent[A](
- name: String,
- tags: Map[String, String],
- parent: Option[(SpanContext, CausalRelation)])(op: SpanContext => A): A
- def traceWithOptionalParentAsync[A](
- name: String,
- tags: Map[String, String],
- parent: Option[(SpanContext, CausalRelation)])(op: SpanContext => Future[A]): Future[A]
-
- /** Trace the execution of an operation, if no parent trace is available.
- *
- * $rootWarning
- */
- final def traceRoot[A](name: String, tags: Map[String, String] = Map.empty)(op: SpanContext => A): A =
- traceWithOptionalParent(
- name,
- tags,
- None
- )(op)
-
- /** Trace the execution of an asynchronous operation, if no parent trace is available.
- *
- * $rootWarning
- *
- * @see traceRoot
- */
- final def traceRootAsync[A](name: String, tags: Map[String, String] = Map.empty)(
- op: SpanContext => Future[A]): Future[A] =
- traceWithOptionalParentAsync(
- name,
- tags,
- None
- )(op)
-
- /** Trace the execution of an operation, in relation to a parent context.
- *
- * @param name The name of the operation. Note that this name should not be too specific. According to the
- * OpenTrace RFC: "An operation name, a human-readable string which concisely represents the work done
- * by the Span (for example, an RPC method name, a function name, or the name of a subtask or stage
- * within a larger computation). The operation name should be the most general string that identifies a
- * (statistically) interesting class of Span instances. That is, `"get_user"` is better than
- * `"get_user/314159"`".
- * @param tags Attributes associated with the traced event. Following the above example, if `"get_user"` is an
- * operation name, a good tag would be `("account_id" -> 314159)`.
- * @param relation Relation of the operation to its parent context.
- * @param op The operation to be traced. The trace will complete once the operation returns.
- * @param ctx Context of the parent trace.
- * @tparam A Return type of the operation.
- * @return The value of the child operation.
- */
- final def trace[A](
- name: String,
- tags: Map[String, String] = Map.empty,
- relation: CausalRelation = CausalRelation.Child)(op: /* implicit (gotta wait for Scala 3) */ SpanContext => A)(
- implicit ctx: SpanContext): A =
- traceWithOptionalParent(
- name,
- tags,
- Some(ctx -> relation)
- )(op)
-
- /** Trace the operation of an asynchronous operation.
- *
- * Contrary to the synchronous version of this method, a trace is completed once the child operation completes
- * (rather than returns).
- *
- * @see trace
- */
- final def traceAsync[A](
- name: String,
- tags: Map[String, String] = Map.empty,
- relation: CausalRelation = CausalRelation.Child)(
- op: /* implicit (gotta wait for Scala 3) */ SpanContext => Future[A])(implicit ctx: SpanContext): Future[A] =
- traceWithOptionalParentAsync(
- name,
- tags,
- Some(ctx -> relation)
- )(op)
-
- /** Log a message. */
- def log(severity: Severity, message: String, reason: Option[Throwable])(implicit ctx: SpanContext): Unit
-
- /** Log a debug message. */
- final def debug(message: String)(implicit ctx: SpanContext): Unit = log(Severity.Debug, message, None)
- final def debug(message: String, reason: Throwable)(implicit ctx: SpanContext): Unit =
- log(Severity.Debug, message, Some(reason))
-
- /** Log an informational message. */
- final def info(message: String)(implicit ctx: SpanContext): Unit = log(Severity.Informational, message, None)
- final def info(message: String, reason: Throwable)(implicit ctx: SpanContext): Unit =
- log(Severity.Informational, message, Some(reason))
-
- /** Log a warning message. */
- final def warn(message: String)(implicit ctx: SpanContext): Unit = log(Severity.Warning, message, None)
- final def warn(message: String, reason: Throwable)(implicit ctx: SpanContext): Unit =
- log(Severity.Warning, message, Some(reason))
-
- /** Log an error message. */
- final def error(message: String)(implicit ctx: SpanContext): Unit = log(Severity.Error, message, None)
- final def error(message: String, reason: Throwable)(implicit ctx: SpanContext): Unit =
- log(Severity.Error, message, Some(reason))
-
-}
-
-object Reporter {
-
- /** A relation in cause.
- *
- * Corresponds to
- * [[https://github.com/opentracing/specification/blob/master/specification.md#references-between-spans OpenTrace references between spans]]
- */
- sealed trait CausalRelation
- object CausalRelation {
-
- /** One event is the child of another. The parent completes once the child is complete. */
- case object Child extends CausalRelation
-
- /** One event follows from another, not necessarily being the parent. */
- case object Follows extends CausalRelation
- }
-
- sealed trait Severity
- object Severity {
- case object Debug extends Severity
- case object Informational extends Severity
- case object Warning extends Severity
- case object Error extends Severity
- }
-
-}