Git Product home page Git Product logo

blindsight's Introduction

Blindsight

Build Status Bintray Scala Steward badge

Suffering in silence, you check the logs for fresh telemetry.

You think: That can't be right.

-- Blindsight, Peter Watts

Blindsight is "observability through logging" where observability is defined as baked in high cardinality structured data with field types. The name is taken from Peter Watts' excellent first contact novel, Blindsight.

Blindsight is a logging library written in Scala that wraps SLF4J to add useful features that solve several outstanding problems with logging:

Dependencies

The only hard dependency is the SLF4J API, but the DSL functionality is only implemented for Logback with logstash-logback-encoder.

Blindsight is a pure SLF4J wrapper: it delegates all logging through to the SLF4J API and does not configure or manage the SLF4J implementation at all.

Versions are published for Scala 2.11, 2.12, and 2.13.

Install

See Setup for how to install Blindsight.

Because Blindsight uses a very recent version of Logstash that depends on Jackson 2.11.0, you may need to update your dependencies for the jackson-scala-module if you're using Play or Akka.

libraryDependencies += "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.11.0"

Benchmarks

Benchmarks are available here.

Usage

To use a Blindsight Logger:

import com.tersesystems.blindsight._

val logger = LoggerFactory.getLogger
logger.info("I am an SLF4J-like logger")

or in block form for diagnostic logging:

logger.debug { debug => debug("I am an SLF4J-like logger") }

Structured DSL:

import com.tersesystems.blindsight._
import com.tersesystems.blindsight.DSL._

logger.info("Logs with argument {}", bobj("array" -> Seq("one", "two", "three")))

Statement Interpolation:

val dayOfWeek = "Monday"
val temp = 72 

// macro expands this to:
// Statement("It is {} and the temperature is {} degrees.", Arguments(dayOfWeek, temp))
val statement: Statement = st"It is ${dayOfWeek} and the temperature is ${temp} degrees."

logger.info(statement)

Marker/Argument Type Classes:

case class Lotto(
  id: Long,
  winningNumbers: List[Int],
  winners: List[Winner],
  drawDate: Option[java.util.Date]
) {
  lazy val asBObject: BObject = "lotto" ->
      ("lotto-id"          -> id) ~
        ("winning-numbers" -> winningNumbers) ~
        ("draw-date"       -> drawDate.map(_.toString)) ~
        ("winners"         -> winners.map(w => w.asBObject))
}

object Lotto {
  implicit val toArgument: ToArgument[Lotto] = ToArgument { lotto => Argument(lotto.asBObject) }
}

val winners =
  List(Winner(23, List(2, 45, 34, 23, 3, 5)), Winner(54, List(52, 3, 12, 11, 18, 22)))
val lotto = Lotto(5, List(2, 45, 34, 23, 7, 5, 3), winners, None)

logger.info("message {}", lotto) // auto-converted to structured output

Fluent logging:

logger.fluent.info
  .message("The Magic Words are")
  .argument(Arguments("Squeamish", "Ossifrage"))
  .logWithPlaceholders()

Semantic logging:

// log only user events
logger.semantic[UserEvent].info(userEvent)

// Works well with refinement types
import eu.timepit.refined.api.Refined
import eu.timepit.refined.string._
import eu.timepit.refined._
logger.semantic[String Refined Url].info(refineMV(Url)("https://tersesystems.com"))

Flow logging:

import com.tersesystems.blindsight.flow._

implicit def flowBehavior[B]: FlowBehavior[B] = new SimpleFlowBehavior

val arg1: Int = 1
val arg2: Int = 2
val result:Int = logger.flow.trace(arg1 + arg2)

Conditional logging:

logger.onCondition(booleanCondition).info("Only logs when condition is true")

logger.info.when(booleanCondition) { info => info("when true") }

And context aware logging:

import DSL._

// Add key/value pairs with DSL and return a logger
val markerLogger = logger.withMarker(bobj("userId" -> userId))

// log with generated logger
markerLogger.info("Logging with user id added as a context marker!")

// can retrieve state markers
val contextMarkers: Markers = logger.markers

Example

There's an example application at https://github.com/tersesystems/play-blindsight that integrates with Honeycomb Tracing using the flow logger:

trace.png

Documentation

See the documentation for more details.

License

Blindsight is released under the "Apache 2" license. See LICENSE for specifics and copyright declaration.

blindsight's People

Contributors

wsargent avatar scala-steward avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.