gobox

package module
v1.21.0 Latest Latest
Warning

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

Go to latest
Published: Oct 25, 2021 License: Apache-2.0 Imports: 0 Imported by: 0

README

gobox

go.dev reference CircleCI Generated via Bootstrap

gobox is a collection of libraries that are useful for implementing Go services, libraries, and more.

Contents

  1. Go idioms
    1. Standard idioms
    2. Log errors with events.NewErrorInfo
    3. Do not use context.WithValue
    4. Do not use fmt.PrintXXX or the standard log package
    5. Do not use non-literal messages with log
    6. Use code generation for stringifying enums
    7. Use events.Org for logging org tenancy info.
  2. Prerequisites
  3. Installing Go
  4. Building and testing gobox
  5. Documentation
  6. Examples

Go idioms

Standard idioms

Please see Code review comments, go proverbs and Idiomatic Go.

Log errors with events.NewErrorInfo

When logging errors, use log.Debug(ctx, "some debug event", events.NewErrorInfo(err)) instead of using log.F{"error": err}. NewErrorInfo logs errors using outreach naming conventions and also takes care of logging stack traces.

Do not use context.WithValue

Context is often abused for thread local state. There are very few legitimate uses for this (tracing is one of those).

Do not use fmt.PrintXXX or the standard log package

Prefer the gobox log package. This logs data in structured format suitable for outreach go services.

Do not use non-literal messages with log

Do not use the following pattern:

   message := fmt.Sprintf("working on org: %s", model.Org.ShortName)
   log.Info(ctx, message, modelInfo)

The first arg of log.XXX calls should be a literal string so we can quickly find out where a log message comes from. The rest of the args can hold any structured data we want. The events package exposes a few common logging structures.

Use code generation for stringifying enums

See go generate:

For example, given this snippet,

package painkiller

//go:generate ./scripts/gobin.sh golang.org/x/tools/cmd/stringer@v0.1.0 -type=Pill
type Pill int

const (
  Placebo Pill = iota
  Aspirin
  Ibuprofen
  Paracetamol
  Acetaminophen = Paracetamol
)

running go generate ./... from the root of the repo will create the file pill_string.go, in package painkiller, containing a definition of func (Pill) String() string which can be used to get the string representation of the enum.

A suggested workflow is to run go generate ./... from the root of the repo before sending PRs out.

Use events.Org for logging org tenancy info.

Org information can be logged with standard naming conventions using:

   orgInfo := events.Org{Bento: xyz, DatabaseHost: ...}
   log.Debug(ctx, "doing xyz", orgInfo)

In most cases, though you probably have some other model struct which has this info. In those cases, the preferred route is to make those model types themselves loggable:

type Model struct {...}

func (m *Model) MarshalLog(addField func(key string, value interface{}) {
     m.Org().MarshalLog(addField)
     ... add any custom fields you want: addField("myCustomField", m.CustomInfo)...
}

func (m *Model) Org() events.Org {
     return events.Org{...}
}

Now Model can be used in logs like so:

   var myModel m
   log.Debug(ctx, "doing xyz", myModel)

Better still is to generate the MarshalLog function using struct tags

Prerequisites

  • Golang >= 1.13

Installing Go

This project uses Golang Modules

To install Golang on Linux or OSX, I strongly recommend using the asdf package manager

Once you have installed asdf, make sure to install the Golang plugins with

asdf plugin-add golang

Then install the actual version

asdf install golang 1.13

Set your default version for Golang

asdf global golang 1.13

Building and testing gobox

Client-side linting is via Golangci-lint. The following script runs lint as well as all the tests:

$ ./scripts/test.sh

Documentation

The authoritative documentation is best done by using godoc -http=localhost:6060 and then browsing to it locally

The markdown version of it can be generated by running godocdown

$ scripts/docs.sh

Note that the markdown version does not show code examples.

Examples

All the individual packages come with examples, so the local documentation link is a good place to start.

This repository also contains an example service handler as well the runnable cmd version of it that are intended to showcase the core functionality.

.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
pkg
app
Package app has the static app info
Package app has the static app info
async
Package async has helper utilities for running async code with proper tracing.
Package async has helper utilities for running async code with proper tracing.
box
Package box implements the definitions of a box configuration file and tools to access it.
Package box implements the definitions of a box configuration file and tools to access it.
caller
package caller provides info on the caller
package caller provides info on the caller
cfg
Package cfg manages config for outreach go services Every go app or package that needs config should define a strongly typed struct for it Example type HoneycombConfig struct { Disable bool `yaml:"Disable"` Dataset string `yaml:"Dataset"` APIHost string `yaml:"APIHost"` SampleRate float64 `yaml:"SampleRate"` Key cfg.Secret `yaml:"Key"` } func (x someComponent) someFunc(ctx context.Context) error { var hcConfig HoneycombConfig if err := cfg.Load("honeycomb.yaml", &hcConfig); err != nil { return err } ...
Package cfg manages config for outreach go services Every go app or package that needs config should define a strongly typed struct for it Example type HoneycombConfig struct { Disable bool `yaml:"Disable"` Dataset string `yaml:"Dataset"` APIHost string `yaml:"APIHost"` SampleRate float64 `yaml:"SampleRate"` Key cfg.Secret `yaml:"Key"` } func (x someComponent) someFunc(ctx context.Context) error { var hcConfig HoneycombConfig if err := cfg.Load("honeycomb.yaml", &hcConfig); err != nil { return err } ...
cleanup
Package cleanup provides helpers to make it easy to do cleanups.
Package cleanup provides helpers to make it easy to do cleanups.
codec
codec contains encoding/decoding utilities.
codec contains encoding/decoding utilities.
differs
Package differs contains custom diffing test utilities See the example for how to use them
Package differs contains custom diffing test utilities See the example for how to use them
env
env provides environment specific overrides All the functions provided by this package are meant to be called at app initialization and will effectively not do anything at all in production.
env provides environment specific overrides All the functions provided by this package are meant to be called at app initialization and will effectively not do anything at all in production.
events
Package events defines the standard logging event structures This is based on https://docs.google.com/document/d/1V1py1iXX9B9NAb30veHYNGOuymZ9o_C2pYSU9E6qmsg/edit# and https://outreach-io.atlassian.net/wiki/spaces/EN/pages/691405109/Logging+Standards
Package events defines the standard logging event structures This is based on https://docs.google.com/document/d/1V1py1iXX9B9NAb30veHYNGOuymZ9o_C2pYSU9E6qmsg/edit# and https://outreach-io.atlassian.net/wiki/spaces/EN/pages/691405109/Logging+Standards
exec
Package exec implements os/exec stdlib helpers
Package exec implements os/exec stdlib helpers
log
Package log implements standard go logging For logging: log.Info(ctx, "message", log.F{field: 42}) log.Error(...) log.Debug(...) log.Fatal(...) By default, log.Debug is not emitted but instead it is cached.
Package log implements standard go logging For logging: log.Info(ctx, "message", log.F{field: 42}) log.Error(...) log.Debug(...) log.Fatal(...) By default, log.Debug is not emitted but instead it is cached.
log/logtest
logtest provides the ability to test logs Usage: func MyTestFunc(t *testing.T) { logs := logTest.NewLogRecorder(t) defer logs.Close() .....
logtest provides the ability to test logs Usage: func MyTestFunc(t *testing.T) { logs := logTest.NewLogRecorder(t) defer logs.Close() .....
metrics
Package metrics implements the outreach metrics API This consists of the Count and Latency functions
Package metrics implements the outreach metrics API This consists of the Count and Latency functions
orerr
Package orerr implements outreach specific error utilities.
Package orerr implements outreach specific error utilities.
orio
Package orio implements IO utilities.
Package orio implements IO utilities.
secrets
Package secrets manages secrets config for outreach applications All secrets are assumed to be stored securely in the filesystem.
Package secrets manages secrets config for outreach applications All secrets are assumed to be stored securely in the filesystem.
shuffler
Package shuffler primarily provides the Suite struct that functions as a test runner and randomizer when embedded in your test struct.
Package shuffler primarily provides the Suite struct that functions as a test runner and randomizer when embedded in your test struct.
sshconfig
Package sshconfig implements a small ssh config parser based on the output of `ssh -G`.
Package sshconfig implements a small ssh config parser based on the output of `ssh -G`.
sshhelper
Package sshhelper is a toolkit for common ssh-related operations.
Package sshhelper is a toolkit for common ssh-related operations.
tester
Package tester implements a test runner compatible with testing.T Usage: t := tester.New() tester.Run(t, "testA", func(t *tester.T) { ...
Package tester implements a test runner compatible with testing.T Usage: t := tester.New() tester.Run(t, "testA", func(t *tester.T) { ...
trace
Package trace wraps standard tracing for outreach.
Package trace wraps standard tracing for outreach.
ometrics Module
tools
logger
main The logger cmd can be used to generate log marshalers for structs.
main The logger cmd can be used to generate log marshalers for structs.

Jump to

Keyboard shortcuts

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