-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Refactor build.sbt * Polish StatusMapper API * Remove unnecessary aspects from opencensus Tracing * Polish OpenTracing API * Make opentelemtry Tracing API more safe * Update opentracing doc * Fix compileExamples * Add possibility to set status code based on a failure result
- Loading branch information
Showing
13 changed files
with
498 additions
and
417 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,12 +2,12 @@ enablePlugins(ZioSbtEcosystemPlugin, ZioSbtCiPlugin) | |
|
||
inThisBuild( | ||
List( | ||
name := "ZIO Telemetry", | ||
organization := "dev.zio", | ||
zioVersion := "2.0.15", | ||
homepage := Some(url("https://zio.dev/zio-telemetry/")), | ||
licenses := List("Apache-2.0" -> url("http://www.apache.org/licenses/LICENSE-2.0")), | ||
developers := List( | ||
name := "ZIO Telemetry", | ||
organization := "dev.zio", | ||
zioVersion := "2.0.15", | ||
homepage := Some(url("https://zio.dev/zio-telemetry/")), | ||
licenses := List("Apache-2.0" -> url("http://www.apache.org/licenses/LICENSE-2.0")), | ||
developers := List( | ||
Developer( | ||
"mijicd", | ||
"Dejan Mijic", | ||
|
@@ -21,12 +21,11 @@ inThisBuild( | |
url("https://github.com/runtologist") | ||
) | ||
), | ||
crossScalaVersions := Seq(scala212.value, scala213.value, "3.3.0"), | ||
ciEnabledBranches := Seq("series/2.x"), | ||
pgpPassphrase := sys.env.get("PGP_PASSWORD").map(_.toArray), | ||
pgpPublicRing := file("/tmp/public.asc"), | ||
pgpSecretRing := file("/tmp/secret.asc"), | ||
scmInfo := Some( | ||
ciEnabledBranches := Seq("series/2.x"), | ||
pgpPassphrase := sys.env.get("PGP_PASSWORD").map(_.toArray), | ||
pgpPublicRing := file("/tmp/public.asc"), | ||
pgpSecretRing := file("/tmp/secret.asc"), | ||
scmInfo := Some( | ||
ScmInfo( | ||
url("https://github.com/zio/zio-telemetry/"), | ||
"scm:git:[email protected]:zio/zio-telemetry.git" | ||
|
@@ -45,9 +44,27 @@ addCommandAlias( | |
"opentracingExample/compile;opentelemetryExample/compile;opentelemetryInstrumentationExample/compile" | ||
) | ||
|
||
// Fix 'Flag set repeatedly' error allegedly introduced by the usage of sdtSettings | ||
lazy val tempFixScalacOptions = | ||
Seq("-deprecation", "-encoding", "utf8", "-feature", "-unchecked", "-language:implicitConversions") | ||
def stdModuleSettings(name: Option[String], packageName: Option[String]) = | ||
stdSettings(name, packageName) ++ | ||
Seq( | ||
crossScalaVersions := Seq(scala212.value, scala213.value, scala3.value), | ||
// Fix 'Flag set repeatedly' error allegedly introduced by the usage of sdtSettings: https://github.com/zio/zio-sbt/issues/221 | ||
scalacOptions --= Seq( | ||
"-deprecation", | ||
"-encoding", | ||
"utf8", | ||
"-feature", | ||
"-unchecked", | ||
"-language:implicitConversions" | ||
) | ||
) | ||
|
||
def stdExampleSettings(name: Option[String], packageName: Option[String]) = | ||
stdSettings(name, packageName) ++ | ||
Seq( | ||
crossScalaVersions := Seq(scala212.value, scala213.value), | ||
publish / skip := true | ||
) | ||
|
||
lazy val root = | ||
project | ||
|
@@ -60,11 +77,10 @@ lazy val opentracing = | |
.in(file("opentracing")) | ||
.settings(enableZIO()) | ||
.settings( | ||
stdSettings( | ||
stdModuleSettings( | ||
name = Some("zio-opentracing"), | ||
packageName = Some("zio.telemetry.opentracing") | ||
), | ||
scalacOptions --= tempFixScalacOptions | ||
) | ||
) | ||
.settings(libraryDependencies ++= Dependencies.opentracing) | ||
|
||
|
@@ -73,23 +89,21 @@ lazy val opentelemetry = | |
.in(file("opentelemetry")) | ||
.settings(enableZIO()) | ||
.settings( | ||
stdSettings( | ||
stdModuleSettings( | ||
name = Some("zio-opentelemetry"), | ||
packageName = Some("zio.telemetry.opentelemetry") | ||
), | ||
scalacOptions --= tempFixScalacOptions | ||
) | ||
) | ||
.settings(libraryDependencies ++= Dependencies.opentelemetry) | ||
|
||
lazy val opencensus = project | ||
.in(file("opencensus")) | ||
.settings(enableZIO()) | ||
.settings( | ||
stdSettings( | ||
stdModuleSettings( | ||
name = Some("zio-opencensus"), | ||
packageName = Some("zio.telemetry.opencensus") | ||
), | ||
scalacOptions --= tempFixScalacOptions | ||
) | ||
) | ||
.settings(libraryDependencies ++= Dependencies.opencensus) | ||
|
||
|
@@ -98,13 +112,11 @@ lazy val opentracingExample = | |
.in(file("opentracing-example")) | ||
.settings(enableZIO()) | ||
.settings( | ||
crossScalaVersions := Seq(scala212.value, scala213.value), | ||
stdSettings( | ||
stdExampleSettings( | ||
name = Some("opentracing-example"), | ||
packageName = Some("zio.telemetry.opentracing.example") | ||
) | ||
) | ||
.settings(publish / skip := true) | ||
.settings(libraryDependencies ++= Dependencies.opentracingExample) | ||
.dependsOn(opentracing) | ||
|
||
|
@@ -113,13 +125,11 @@ lazy val opentelemetryExample = | |
.in(file("opentelemetry-example")) | ||
.settings(enableZIO()) | ||
.settings( | ||
crossScalaVersions := Seq(scala212.value, scala213.value), | ||
stdSettings( | ||
stdExampleSettings( | ||
name = Some("opentelemetry-example"), | ||
packageName = Some("zio.telemetry.opentelemetry.example") | ||
) | ||
) | ||
.settings(publish / skip := true) | ||
.settings(libraryDependencies ++= Dependencies.opentelemetryExample) | ||
.dependsOn(opentelemetry) | ||
|
||
|
@@ -128,27 +138,25 @@ lazy val opentelemetryInstrumentationExample = | |
.in(file("opentelemetry-instrumentation-example")) | ||
.settings(enableZIO()) | ||
.settings( | ||
crossScalaVersions := Seq(scala212.value, scala213.value), | ||
stdSettings( | ||
stdExampleSettings( | ||
name = Some("opentelemetry-instrumentation-example"), | ||
packageName = Some("zio.telemetry.opentelemetry.instrumentation.example") | ||
) | ||
) | ||
.settings(publish / skip := true) | ||
.settings(libraryDependencies ++= Dependencies.opentelemetryInstrumentationExample) | ||
.dependsOn(opentelemetry) | ||
|
||
lazy val docs = | ||
project | ||
.in(file("zio-telemetry-docs")) | ||
.settings( | ||
crossScalaVersions := Seq(scala212.value, scala213.value, scala3.value), | ||
moduleName := "zio-telemetry-docs", | ||
scalacOptions -= "-Yno-imports", | ||
scalacOptions -= "-Xfatal-warnings", | ||
projectName := "ZIO Telemetry", | ||
mainModuleName := (opentracing / moduleName).value, | ||
projectStage := ProjectStage.ProductionReady, | ||
ScalaUnidoc / unidoc / unidocProjectFilter := inProjects(opentracing, opentelemetry, opencensus) | ||
ScalaUnidoc / unidoc / unidocProjectFilter := inProjects(opentracing, opentelemetry, opencensus), | ||
scalacOptions --= Seq("-Yno-imports", "-Xfatal-warnings") | ||
) | ||
.dependsOn(opentracing, opentelemetry, opencensus) | ||
.enablePlugins(WebsitePlugin) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
87 changes: 68 additions & 19 deletions
87
opentelemetry/src/main/scala/zio/telemetry/opentelemetry/tracing/StatusMapper.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,80 @@ | ||
package zio.telemetry.opentelemetry.tracing | ||
|
||
import io.opentelemetry.api.trace.StatusCode | ||
import zio.telemetry.opentelemetry.tracing.StatusMapper.StatusMapperResult | ||
import zio.telemetry.opentelemetry.tracing.StatusMapper.Result | ||
|
||
case class StatusMapper[-E, -A]( | ||
failure: PartialFunction[E, StatusMapperResult[Throwable]], | ||
success: PartialFunction[A, StatusMapperResult[String]] | ||
/** | ||
* Maps the result of a wrapped ZIO effect to the status of the [[io.opentelemetry.api.trace.Span]]. | ||
* | ||
* For more details, see: | ||
* [[https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#set-status Set status]] | ||
* | ||
* Usage examples: | ||
* {{{ | ||
* StatusMapper.failure[MyError](_ => StatusCode.ERROR)(e => Some(new RuntimeException(e.message))) | ||
* StatusMapper.failureNoException(_ => StatusCode.ERROR) | ||
* StatusMapper.failureThrowable(StatusCode.ERROR) | ||
* | ||
* StatusMapper.success[Response] { | ||
* resp => if(resp.code == 500) StatusCode.ERROR else StatusCode.OK | ||
* } { resp => | ||
* if(resp.code == 500) Some(resp.errorMessage) else None | ||
* } | ||
* StatusMapper.successNoDescription[Response](_ => StatusCode.OK) | ||
* | ||
* StatusMapper.both( | ||
* StatusMapper.failureThrowable(StatusCode.ERROR), | ||
* StatusMapper.successNoDescription[Any](_ => StatusCode.OK) | ||
* ) | ||
* }}} | ||
* @param failure | ||
* partial function to map the ZIO failure to [[io.opentelemetry.api.trace.StatusCode]] and [[java.lang.Throwable]]. | ||
* The latter is used to record the exception, see: | ||
* [[https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/exceptions.md#recording-an-exception Recording an exception]] | ||
* @param success | ||
* partial function to map the ZIO success to [[io.opentelemetry.api.trace.StatusCode]] and status description | ||
* @tparam E | ||
* @tparam A | ||
*/ | ||
sealed abstract class StatusMapper[-E, -A]( | ||
val failure: PartialFunction[E, Result[Throwable]], | ||
val success: PartialFunction[A, Result[String]] | ||
) | ||
|
||
object StatusMapper { | ||
|
||
final case class Failure[-E](pf: PartialFunction[E, Result[Throwable]]) | ||
extends StatusMapper[E, Any](pf, PartialFunction.empty) | ||
final case class Success[-A](pf: PartialFunction[A, Result[String]]) | ||
extends StatusMapper[Any, A](PartialFunction.empty, pf) | ||
|
||
final case class Result[+T](statusCode: StatusCode, error: Option[T] = None) | ||
|
||
private[tracing] def apply[E, A]( | ||
failure: PartialFunction[E, Result[Throwable]], | ||
success: PartialFunction[A, Result[String]] | ||
): StatusMapper[E, A] = | ||
new StatusMapper[E, A](failure, success) {} | ||
|
||
def both[E, A](failure: Failure[E], success: Success[A]): StatusMapper[E, A] = | ||
StatusMapper[E, A](failure.pf, success.pf) | ||
|
||
val default: StatusMapper[Any, Any] = | ||
StatusMapper(PartialFunction.empty, PartialFunction.empty) | ||
|
||
final case class StatusMapperResult[+T](statusCode: StatusCode, error: Option[T] = None) | ||
|
||
def failure(statusCode: StatusCode): StatusMapper[Throwable, Any] = StatusMapper( | ||
{ case e => StatusMapperResult(statusCode, Option(e)) }, | ||
PartialFunction.empty | ||
) | ||
|
||
def success[A]( | ||
statusCode: StatusCode, | ||
f: A => Option[String] = { (_: A) => Option.empty[String] } | ||
): StatusMapper[Any, A] = | ||
StatusMapper( | ||
PartialFunction.empty, | ||
{ case a => StatusMapperResult(statusCode, f(a)) } | ||
) | ||
def failure[E](toStatusCode: E => StatusCode)(toError: E => Option[Throwable]): Failure[E] = | ||
Failure { case e => Result(toStatusCode(e), toError(e)) } | ||
|
||
def failureNoException[E](toStatusCode: E => StatusCode): Failure[E] = | ||
Failure { case e => Result(toStatusCode(e)) } | ||
|
||
def failureThrowable(toStatusCode: Throwable => StatusCode): Failure[Throwable] = | ||
Failure { case e => Result(toStatusCode(e), Option(e)) } | ||
|
||
def success[A](toStatusCode: A => StatusCode)(toError: A => Option[String]): Success[A] = | ||
Success { case a => Result(toStatusCode(a), toError(a)) } | ||
|
||
def successNoDescription[A](toStatusCode: A => StatusCode): Success[A] = | ||
Success { case a => Result(toStatusCode(a)) } | ||
|
||
} |
Oops, something went wrong.