An all-in-one obversvability kit
Go to file
2022-12-20 00:41:28 -06:00
cmd got things to work with HTTP and stdout 2022-11-03 08:42:02 -05:00
examples add observer implementation 2022-12-20 00:41:28 -06:00
format add observer implementation 2022-12-20 00:41:28 -06:00
http minor edits to http constants to support future spec compliance 2022-12-19 12:15:52 -06:00
legal got things to work with HTTP and stdout 2022-11-03 08:42:02 -05:00
observer add observer implementation 2022-12-20 00:41:28 -06:00
pb minor improvements to trace api 2022-12-14 10:23:55 -06:00
tools/gen-tags got things to work with HTTP and stdout 2022-11-03 08:42:02 -05:00
.gitignore initial implementation 2022-11-01 16:15:22 -05:00
api.go minor improvements to trace api 2022-12-14 10:23:55 -06:00
AUTHORS got things to work with HTTP and stdout 2022-11-03 08:42:02 -05:00
client.go add observer implementation 2022-12-20 00:41:28 -06:00
go.mod initial implementation 2022-11-01 16:15:22 -05:00
go.sum initial implementation 2022-11-01 16:15:22 -05:00
go.work got things to work with HTTP and stdout 2022-11-03 08:42:02 -05:00
LICENSE got things to work with HTTP and stdout 2022-11-03 08:42:02 -05:00
Makefile minor improvements to trace api 2022-12-14 10:23:55 -06:00
okit.go add observer implementation 2022-12-20 00:41:28 -06:00
README.md add disclaimer to readme 2022-12-19 21:07:58 -06:00
tags.ext.go port common labels into tag functions 2022-12-19 12:15:14 -06:00
tags.go got things to work with HTTP and stdout 2022-11-03 08:42:02 -05:00

okit

Short for "observability kit", okit aims to provide an all-in-one solution to application observability.

DISCLAIMER! This is an early preview. There are significant portions of this repository that still need to be implemented. Check out the issues to see how you can help.

Why

Traditional approaches to observability treat logging, application metrics, and tracing as independent operations, with independent data streams. In practice, these elements are more or less all the same, with some minor differences between them. Developers often have to choose between logging a message, emitting a metric, or expanding a trace.

Logging

  • Used by developers and operators to determine what issues an application may be facing.
  • High cardinality data (errors, stack traces, user id / signature).
  • Often sent to stdout/stderr and can optionally be captured by traditional logging solutions.

Tracing

  • Used by developers and operators to troubleshoot performance issues across a set of distributed systems.
  • Medium cardinality data (consistent structure, high variability in tag values)
  • Typically available in real-time to assess product performance.

Metrics

  • Used by developers and product managers to determine details about how their product is doing.
  • Medium/High cardinality data (user id / signature, other metadata fields).
  • Typically available in real-time to assess user experience / feature performance.

In addition to the complexity that each of these solutions bring with them, you often need to import a custom library for each, and thus increase your dependency footprint.

Usage

Basic

Basic usage for okit is fairly straight forward. You can create dedicated client, use the default, or even replace the default. The example below demonstrates how to use the default client.

package main

import (
	"context"

	"go.pitz.tech/okit"
)

func main() {
	var tags []okit.Tag

	// Metric emission
	okit.Observe("temperature_c", 20.9, tags...)

	// Multi-dimensional events
	okit.Emit("user_signup", tags...)

	// Tracing
	ctx := context.Background()
	defer okit.Trace(&ctx, tags...).Done()

	// Logging
	okit.Debug("a message used for debugging", tags...)
	okit.Info("an informational message for the user", tags...)
	okit.Warn("a warning indicating an issue with the system", tags...)
	okit.Error("the system encountered an error", tags...)
}

HTTP

okit comes with built-in functionality to make it easy to trace HTTP operations.

package main

import (
	"net/http"

	okithttp "go.pitz.tech/okit/http"
)

func main() {
	// Instrument HTTP Clients
	okithttp.InstrumentClient(http.DefaultClient)

	mux := http.NewServeMux()

	{ // Add reporting endpoints
		endpoint := okithttp.NewEndpoint()
		mux.HandleFunc("/health", endpoint.Health)
		mux.HandleFunc("/metrics", endpoint.Metrics)
		mux.HandleFunc("/trace", endpoint.Trace)
	}

	// Instrument HTTP Handlers
	handler := okithttp.InstrumentHandler(mux)
	err := http.ListenAndServe("0.0.0.0:8080", handler)
	if err != nil {
		panic(err)
	}
}

Implementation

Wire Protocol

TBD

Tracing

Because okit aims at providing an all-in-one solution, tracing not only produces spec compliant traces for ingestion into remote systems but also produces bookend log events for developers and operators.

Logging

Logging follows a fairly standard implementation. It allows messages to be logged at different levels including debug, info, warn, and error. A fifth, trace level is also available that allows tracing bookend events to be enabled disabled. Logging output can be written as text or as JSON.

Metrics

Metrics are implemented using an observation based approach. Results are recorded and stored locally for administrators to be able to query.

Events

Multi-dimensional events are a lot like metrics. The most common use case is when metrics have a statically coded value of 1. For example, page views, checkout, and many other user-driven actions.