# LabKit 🧪 🔬 🥼 🥽 🦠 🧫 🧬 💉

**LabKit** is **minimalist library** to provide functionality for Go services at GitLab.

------------------------------------------------------

## Packages

### Correlation

[![](https://godoc.org/gitlab.com/gitlab-org/labkit/correlation?status.svg)](http://godoc.org/gitlab.com/gitlab-org/labkit/correlation)

```go
import (
	"gitlab.com/gitlab-org/labkit/correlation"
)
```

### Logging

[![](https://godoc.org/gitlab.com/gitlab-org/labkit/log?status.svg)](http://godoc.org/gitlab.com/gitlab-org/labkit/log)

```go
import (
	logkit "gitlab.com/gitlab-org/labkit/log"
)
```

### Masking

[![](https://godoc.org/gitlab.com/gitlab-org/labkit/mask?status.svg)](http://godoc.org/gitlab.com/gitlab-org/labkit/mask)

```go
import (
	"gitlab.com/gitlab-org/labkit/mask"
)
```

### Metrics

[![](https://godoc.org/gitlab.com/gitlab-org/labkit/metrics?status.svg)](http://godoc.org/gitlab.com/gitlab-org/labkit/metrics)

```go
import (
	"gitlab.com/gitlab-org/labkit/metrics"
)
```

## Developing LabKit

Anyone can contribute!

Please be aware of the following however.

### Public APIs in LabKit should be stable

* LabKit is a library, not an application, and as such, we value compatibility highly.
* Public APIs in LabKit should be backward compatible. This should be done by making APIs forward extensible.
  * Add methods, but do not add (non-optional) parameters to existing methods.
  * Use [Functional Options](https://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis) where possible

### APIs should be intuitive and friendly

* APIs should have an intuitive interface.
* Spend time ensuring thinking about what the best interface is.
* Include excellent godocs, including package documentation in `doc.go`.

### Dependency Management

* Be extremely careful about the dependencies your packages include. Be prepared to justify any dependencies you bring into a package.
  * If not users will require a dependency, consider including it in a subpackage (eg `gitlab.com/gitlab-org/labkit/correlation/grpc`),
    especially if the dependency is large or has a deep dependency tree of it's own.
* Be even more careful about the dependencies that you expose through the API of a package
* Follow this rule: packages can depend on their parent packages, but not their siblings or children.
  * If required, declare common models in the root package

### Architectural Philosophy

Taken from [A Philosophy of Software Design, by John Ousterhout](https://www.amazon.com/Philosophy-Software-Design-John-Ousterhout/dp/1732102201).
This book is recommended reading.

* Modules should be deep
* Interfaces should be designed to make the most common usage as simple as possible
* Separate general-purpose and special-purpose code
* Design it twice
* Comments should describe things that are not obvious from the code
