# 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"
)
```

### Monitoring

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

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

## Developing LabKit

Anyone can contribute!

### Architectural guidelines

Please be aware of the following architectural guidelines.

### 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 (e.g. `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.

### Review Process

Please assign your MR to a reviewer for a first review, followed by a maintainer review.

Currently, the reviewers are:

1. [@igorwwwwwwwwwwwwwwwwwwww](https://gitlab.com/igorwwwwwwwwwwwwwwwwwwww)
1. [@jdrpereira](https://gitlab.com/jdrpereira)
1. [@8bitlife](https://gitlab.com/8bitlife)
1. [@reprazent](https://gitlab.com/reprazent)

The maintainers are:

1. [@andrewn](https://gitlab.com/andrewn)
1. [@hphilipps](https://gitlab.com/hphilipps)
1. [@steveazz](https://gitlab.com/steveazz)
1. [@zj-gitlab](https://gitlab.com/zj-gitlab)

### Release Process

LabKit uses [semantic releases](https://github.com/semantic-release/semantic-release). Please use the [Conventional Commits](https://www.conventionalcommits.org) commit format.

#### When to release a new version

A new release should only be created when there is a new user-facing
feature or a bug fix. CI, docs, and refactoring shouldn't result in a
new release unless it's a big change.

### Downstream Vendoring

While not strictly neccessary, it is preferred for the author of changes to also send downstream MRs to the applications that use LabKit. Since the library has a strict backwards compatibility policy, these upgrades *should* be fairly straightforward.

Use the `./downstream-vendor.sh` to update the LabKit library in all known GitLab applications. You will need to have `git+ssh` credentials setup to push directly to the repositories. The script currently does not work on forked projects unfortunately. Once completed, the script will output a list of MRs, for your review.

```console
$ ./downstream-vendor.sh
# .....
####################################
# completed successfully
# https://gitlab.com/gitlab-org/gitlab-workhorse/-/merge_requests/657
# https://gitlab.com/gitlab-org/gitaly/-/merge_requests/2816
# https://gitlab.com/gitlab-org/gitlab-pages/-/merge_requests/396
# https://gitlab.com/gitlab-org/container-registry/-/merge_requests/427
# https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/merge_requests/173
```
