jettison

package module
v0.0.0-...-25be6c5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 3, 2024 License: MIT Imports: 0 Imported by: 4

README

Jettison

Go Report Card Go Doc

What is it?

Jettison is a library providing structured logs and errors in a way that's interoperable with gRPC. It does this under the hood by serialising message details to protobuf messages and attaching them to gRPC Status objects - see the gRPC docs for details of how this works. Jettison is also compatible with the Go 2 error spec, which can be found in the draft design page.

Features

Jettison is in alpha, but the following features are planned:

  • [✓] Simple, gRPC-compatible utilities for building up structured errors/logs.
  • [✓] Support for error identification and unwrapping as per the Go 2 spec.
  • [✓] Structured error/log formatting utilities for both machines (JSON) and humans.
  • [✕] Key/value pair type support for compatibility with Elasticsearch.

API

Errors

The jettison/errors package provides functions for creating and working with gRPC-compatible error values. You can attach arbitrary metadata to jettison errors, decorate them with source/stacktrace information and wrap errors to form a chain as the stack unwinds. Passing jettison errors over gRPC preserves all metadata structure, in contrast to other error types (which get marshalled to a string by default).

Jettison also provides gRPC middleware that automatically groups the errors in a chain by the gRPC server (or "hop") they originated from.

See the jettison/example package for a more complete usage example, including a gRPC server/client passing jettison errors over the wire.

import (
    "github.com/luno/jettison"
    "github.com/luno/jettison/errors"
)

func ExampleNew() {
	// Construct your error as usual, with additional metadata.
	err := errors.New("something went wrong", j.KV("key", "value"))

	// Wrap errors with additional metadata as they get passed down the stack.
	err = errors.Wrap(err, "something else went wrong", j.KV("another_key", "another_value"))

	// Pass it around - including over gRPC - like you would any other error.
}
Logs

The jettison/log package provides structured JSON logging, with additional utilities for logging jettison errors. You can attach metadata to logs in the same manner as you attach metadata to errors.

import (
    "context"

    "github.com/luno/jettison"
    "github.com/luno/jettison/errors"
    "github.com/luno/jettison/log"
)

func ExampleInfo() {
	ctx := context.Background()

	// You can log general info as you normally would.
	log.Info(ctx, "entering the example function", j.KV("key", "value"))
}

func ExampleError() {
	ctx := context.Background()

	err := errors.New("a jettison error", j.KV("key", "value"))

	// Errors can be logged separately, with metadata marshalled to JSON in
	// a machine-friendly manner.
	log.Error(ctx, err, j.KV("another_key", "another_value"))
}

An example log written via log.Info:

{
  "message": "entering the example function",
  "source": "jettison/example/example.go:9",
  "level": "info",
  "parameters": [
    {
      "key": "key",
      "value": "value"
    }
  ]
}

An example log written via log.Error:

{
  "message": "a jettison error",
  "source": "jettison/example/example.go:18",
  "level": "error",
  "hops": [
    {
      "binary": "example",
      "errors": [
        {
          "message": "a jettison error",
          "source": "jettison/example/example.go:14",
          "parameters": [
            {
              "key": "key",
              "value": "value"
            }
          ]
        }
      ]
    }
  ],
  "parameters": [
    {
      "key": "key",
      "value": "value"
    },
    {
      "key": "another_key",
      "value": "another_value"
    }
  ]
}
Utilities

The jettison/j package contains aliases for common jettison options, saving you a couple of keystrokes:

import (
    "github.com/luno/jettison/errors"
    "github.com/luno/jettison/j"
)

func ExampleKS() {
	err := errors.New("using j.KS",
		j.KS("string_key", "value"))

	fmt.Printf("%%+v: %+v\n", err)
	fmt.Printf("%%#v: %#v\n", err)
}

func ExampleKV() {
	err := errors.New("using j.KV",
		j.KV("int_key", 1))

	fmt.Printf("%%+v: %+v\n", err)
	fmt.Printf("%%#v: %#v\n", err)
}

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
cmd
Package main contains an example implementation of a gRPC server and client that use Jettison to communicate structed errors.
Package main contains an example implementation of a gRPC server and client that use Jettison to communicate structed errors.
j
Package j provides abridged aliases for jettison options with some best practices built in.
Package j provides abridged aliases for jettison options with some best practices built in.
Package jtest provides simple test assertion functions for the jettison errors package.
Package jtest provides simple test assertion functions for the jettison errors package.
Package models contains representations of Jettison objects that are passed to loggers.
Package models contains representations of Jettison objects that are passed to loggers.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL