Skip to content

Instantly share code, notes, and snippets.

@jdegoes
Created April 10, 2020 15:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jdegoes/6570d5f81ac33a79cab65cfd4b58c14c to your computer and use it in GitHub Desktop.
Save jdegoes/6570d5f81ac33a79cab65cfd4b58c14c to your computer and use it in GitHub Desktop.
ZMX Design Sketch
package zio
import zio.duration.Duration
package object zmx extends MetricsDataModel with MetricsConfigDataModel {
type Diagnostics = Has[Diagnostics.Service]
object Diagnostics {
trait Service {
}
/**
* The Diagnostics service will listen on the specified port for commands to perform fiber
* dumps, either across all fibers or across the specified fiber ids.
*/
def live(port: Int, host: Option[String]): ZLayer[Any, Nothing, Diagnostics] = ???
}
type CoreMetrics = Has[CoreMetrics.Service]
object CoreMetrics {
trait Service {
def enable: UIO[Unit]
def disable: UIO[Unit]
def isEnabled: UIO[Boolean]
}
def enable: ZIO[CoreMetrics, Nothing, Unit] = ZIO.accessM[CoreMetrics](_.get.enable)
def disable: ZIO[CoreMetrics, Nothing, Unit] = ZIO.accessM[CoreMetrics](_.get.disable)
def isEnabled: ZIO[CoreMetrics, Nothing, Boolean] = ZIO.accessM[CoreMetrics](_.get.isEnabled)
/**
* The `CoreMetrics` service installs hooks into ZIO runtime system to track
* important core metrics, such as number of fibers, fiber status, fiber
* lifetimes, etc.
*/
def live: ZLayer[Metrics, Nothing, CoreMetrics] = ???
}
type Metrics = Has[Metrics.Service]
object Metrics {
trait AbstractService[+F[+_]] {
private[zio] def unsafeService: UnsafeService
def counter(name: String, value: Double): F[Unit]
def counter(name: String, value: Double, sampleRate: Double, tags: Tag*): F[Unit]
def increment(name: String): F[Unit]
def increment(name: String, sampleRate: Double, tags: Tag*): F[Unit]
def decrement(name: String): F[Unit]
def decrement(name: String, sampleRate: Double, tags: Tag*): F[Unit]
def gauge(name: String, value: Double, tags: Tag*): F[Unit]
def meter(name: String, value: Double, tags: Tag*): F[Unit]
def timer(name: String, value: Double): F[Unit]
def timer(name: String, value: Double, sampleRate: Double, tags: Tag*): F[Unit]
def set(name: String, value: String, tags: Tag*): F[Unit]
def histogram(name: String, value: Double): F[Unit]
def histogram(name: String, value: Double, sampleRate: Double, tags: Tag*): F[Unit]
def serviceCheck(name: String, status: ServiceCheckStatus): F[Unit] =
serviceCheck(name, status, None, None, None, Seq.empty[Tag])
def serviceCheck(
name: String,
status: ServiceCheckStatus,
timestamp: Option[Long],
hostname: Option[String],
message: Option[String],
tags: Seq[Tag]
): F[Unit]
def event(name: String, text: String): F[Unit] =
event(name, text, None, None, None, None, None, None, Seq.empty[Tag])
def event(
name: String,
text: String,
timestamp: Option[Long],
hostname: Option[String],
aggregationKey: Option[String],
priority: Option[EventPriority],
sourceTypeName: Option[String],
alertType: Option[EventAlertType],
tags: Seq[Tag]
): F[Unit]
}
private[zio] type Id[+A] = A
private[zio] trait UnsafeService extends AbstractService[Id] { self =>
private[zio] def unsafeService: UnsafeService = self
}
trait Service extends AbstractService[UIO]
object Service {
private[zio] def fromUnsafeService(unsafe: UnsafeService): Service =
???
}
/**
* Sets the counter of the specified name for the specified value.
*/
def counter(name: String, value: Double): ZIO[Metrics, Nothing, Unit] =
ZIO.accessM[Metrics](_.get.counter(name, value))
/**
* Constructs a live `Metrics` service based on the given configuration.
*/
def live(config: MetricsConfig): ZLayer[Any, Nothing, Metrics] = ???
}
}
trait MetricsDataModel {
sealed case class Tag(key: String, value: String) {
override def toString() = s"$key:$value"
}
sealed trait ServiceCheckStatus {
val value: Int
}
object ServiceCheckStatus {
case object Ok extends ServiceCheckStatus {
val value: Int = 0
}
case object Warning extends ServiceCheckStatus {
val value: Int = 1
}
case object Critical extends ServiceCheckStatus {
val value: Int = 2
}
case object Unknown extends ServiceCheckStatus {
val value: Int = 3
}
}
sealed trait EventPriority {
val value: String
}
object EventPriority {
case object Low extends EventPriority {
val value = "low"
}
case object Normal extends EventPriority {
val value = "normal"
}
}
sealed trait EventAlertType {
val value: String
}
object EventAlertType {
case object Error extends EventAlertType {
val value = "error"
}
case object Info extends EventAlertType {
val value = "info"
}
case object Success extends EventAlertType {
val value = "success"
}
case object Warning extends EventAlertType {
val value = "warning"
}
}
sealed trait Metric[+A] {
def name: String
def value: A
def tags: Chunk[Tag]
}
object Metric {
sealed case class Counter(name: String, value: Double, sampleRate: Double, tags: Chunk[Tag]) extends Metric[Double]
sealed case class Event(
name: String,
value: String,
timestamp: Option[Long],
hostname: Option[String],
aggregationKey: Option[String],
priority: Option[EventPriority],
sourceTypeName: Option[String],
alertType: Option[EventAlertType],
tags: Chunk[Tag]
) extends Metric[String] {
def text: String = value
}
sealed case class Gauge(name: String, value: Double, tags: Chunk[Tag]) extends Metric[Double]
sealed case class Histogram(name: String, value: Double, sampleRate: Double, tags: Chunk[Tag]) extends Metric[Double]
sealed case class Meter(name: String, value: Double, tags: Chunk[Tag]) extends Metric[Double]
sealed case class ServiceCheck(
name: String,
status: ServiceCheckStatus,
timestamp: Option[Long],
hostname: Option[String],
message: Option[String],
tags: Chunk[Tag]
) extends Metric[ServiceCheckStatus] {
def value: ServiceCheckStatus = status
}
sealed case class Set(name: String, value: String, tags: Chunk[Tag]) extends Metric[String]
sealed case class Timer(name: String, value: Double, sampleRate: Double, tags: Chunk[Tag]) extends Metric[Double]
}
}
trait MetricsConfigDataModel {
sealed case class MetricsConfig(
bufferSize: Int, timeout: Duration, port: Option[Int], host: Option[String]
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment