# Contributing to opentelemetry-go

The Go special interest group (SIG) meets regularly. See the
OpenTelemetry
[community](https://github.com/open-telemetry/community#golang-sdk)
repo for information on this and other language SIGs.

See the [public meeting
notes](https://docs.google.com/document/d/1E5e7Ld0NuU1iVvf-42tOBpu2VBBLYnh73GJuITGJTTU/edit)
for a summary description of past meetings. To request edit access,
join the meeting or get in touch on
[Slack](https://cloud-native.slack.com/archives/C01NPAXACKT).

## Development

You can view and edit the source code by cloning this repository:

```sh
git clone https://github.com/open-telemetry/opentelemetry-go.git
```

Run `make test` to run the tests instead of `go test`.

There are some generated files checked into the repo. To make sure
that the generated files are up-to-date, run `make` (or `make
precommit` - the `precommit` target is the default).

The `precommit` target also fixes the formatting of the code and
checks the status of the go module files.

Additionally, there is a `codespell` target that checks for common
typos in the code. It is not run by default, but you can run it
manually with `make codespell`. It will set up a virtual environment
in `venv` and install `codespell` there.

If after running `make precommit` the output of `git status` contains
`nothing to commit, working tree clean` then it means that everything
is up-to-date and properly formatted.

## Pull Requests

### How to Send Pull Requests

Everyone is welcome to contribute code to `opentelemetry-go` via
GitHub pull requests (PRs).

To create a new PR, fork the project in GitHub and clone the upstream
repo:

```sh
go get -d go.opentelemetry.io/otel
```

(This may print some warning about "build constraints exclude all Go
files", just ignore it.)

This will put the project in `${GOPATH}/src/go.opentelemetry.io/otel`. You
can alternatively use `git` directly with:

```sh
git clone https://github.com/open-telemetry/opentelemetry-go
```

(Note that `git clone` is *not* using the `go.opentelemetry.io/otel` name -
that name is a kind of a redirector to GitHub that `go get` can
understand, but `git` does not.)

This would put the project in the `opentelemetry-go` directory in
current working directory.

Enter the newly created directory and add your fork as a new remote:

```sh
git remote add <YOUR_FORK> git@github.com:<YOUR_GITHUB_USERNAME>/opentelemetry-go
```

Check out a new branch, make modifications, run linters and tests, update
`CHANGELOG.md`, and push the branch to your fork:

```sh
git checkout -b <YOUR_BRANCH_NAME>
# edit files
# update changelog
make precommit
git add -p
git commit
git push <YOUR_FORK> <YOUR_BRANCH_NAME>
```

Open a pull request against the main `opentelemetry-go` repo. Be sure to add the pull
request ID to the entry you added to `CHANGELOG.md`.

Avoid rebasing and force-pushing to your branch to facilitate reviewing the pull request.
Rewriting Git history makes it difficult to keep track of iterations during code review.
All pull requests are squashed to a single commit upon merge to `main`.

### How to Receive Comments

* If the PR is not ready for review, please put `[WIP]` in the title,
  tag it as `work-in-progress`, or mark it as
  [`draft`](https://github.blog/2019-02-14-introducing-draft-pull-requests/).
* Make sure CLA is signed and CI is clear.

### How to Get PRs Merged

A PR is considered **ready to merge** when:

* It has received two qualified approvals[^1].

  This is not enforced through automation, but needs to be validated by the
  maintainer merging.
  * The qualified approvals need to be from [Approver]s/[Maintainer]s
    affiliated with different companies. Two qualified approvals from
    [Approver]s or [Maintainer]s affiliated with the same company counts as a
    single qualified approval.
  * PRs introducing changes that have already been discussed and consensus
    reached only need one qualified approval. The discussion and resolution
    needs to be linked to the PR.
  * Trivial changes[^2] only need one qualified approval.

* All feedback has been addressed.
  * All PR comments and suggestions are resolved.
  * All GitHub Pull Request reviews with a status of "Request changes" have
    been addressed. Another review by the objecting reviewer with a different
    status can be submitted to clear the original review, or the review can be
    dismissed by a [Maintainer] when the issues from the original review have
    been addressed.
  * Any comments or reviews that cannot be resolved between the PR author and
    reviewers can be submitted to the community [Approver]s and [Maintainer]s
    during the weekly SIG meeting. If consensus is reached among the
    [Approver]s and [Maintainer]s during the SIG meeting the objections to the
    PR may be dismissed or resolved or the PR closed by a [Maintainer].
  * Any substantive changes to the PR require existing Approval reviews be
    cleared unless the approver explicitly states that their approval persists
    across changes. This includes changes resulting from other feedback.
    [Approver]s and [Maintainer]s can help in clearing reviews and they should
    be consulted if there are any questions.

* The PR branch is up to date with the base branch it is merging into.
  * To ensure this does not block the PR, it should be configured to allow
    maintainers to update it.

* It has been open for review for at least one working day. This gives people
  reasonable time to review.
  * Trivial changes[^2] do not have to wait for one day and may be merged with
    a single [Maintainer]'s approval.

* All required GitHub workflows have succeeded.
* Urgent fix can take exception as long as it has been actively communicated
  among [Maintainer]s.

Any [Maintainer] can merge the PR once the above criteria have been met.

[^1]: A qualified approval is a GitHub Pull Request review with "Approve"
  status from an OpenTelemetry Go [Approver] or [Maintainer].
[^2]: Trivial changes include: typo corrections, cosmetic non-substantive
  changes, documentation corrections or updates, dependency updates, etc.

## Design Choices

As with other OpenTelemetry clients, opentelemetry-go follows the
[OpenTelemetry Specification](https://opentelemetry.io/docs/specs/otel).

It's especially valuable to read through the [library
guidelines](https://opentelemetry.io/docs/specs/otel/library-guidelines).

### Focus on Capabilities, Not Structure Compliance

OpenTelemetry is an evolving specification, one where the desires and
use cases are clear, but the method to satisfy those uses cases are
not.

As such, Contributions should provide functionality and behavior that
conforms to the specification, but the interface and structure is
flexible.

It is preferable to have contributions follow the idioms of the
language rather than conform to specific API names or argument
patterns in the spec.

For a deeper discussion, see
[this](https://github.com/open-telemetry/opentelemetry-specification/issues/165).

## Documentation

Each (non-internal, non-test) package must be documented using
[Go Doc Comments](https://go.dev/doc/comment),
preferably in a `doc.go` file.

Prefer using [Examples](https://pkg.go.dev/testing#hdr-Examples)
instead of putting code snippets in Go doc comments.
In some cases, you can even create [Testable Examples](https://go.dev/blog/examples).

You can install and run a "local Go Doc site" in the following way:

  ```sh
  go install golang.org/x/pkgsite/cmd/pkgsite@latest
  pkgsite
  ```

[`go.opentelemetry.io/otel/metric`](https://pkg.go.dev/go.opentelemetry.io/otel/metric)
is an example of a very well-documented package.

### README files

Each (non-internal, non-test, non-documentation) package must contain a
`README.md` file containing at least a title, and a `pkg.go.dev` badge.

The README should not be a repetition of Go doc comments.

You can verify the presence of all README files with the `make verify-readmes`
command.

## Style Guide

One of the primary goals of this project is that it is actually used by
developers. With this goal in mind the project strives to build
user-friendly and idiomatic Go code adhering to the Go community's best
practices.

For a non-comprehensive but foundational overview of these best practices
the [Effective Go](https://golang.org/doc/effective_go.html) documentation
is an excellent starting place.

As a convenience for developers building this project the `make precommit`
will format, lint, validate, and in some cases fix the changes you plan to
submit. This check will need to pass for your changes to be able to be
merged.

In addition to idiomatic Go, the project has adopted certain standards for
implementations of common patterns. These standards should be followed as a
default, and if they are not followed documentation needs to be included as
to the reasons why.

### Configuration

When creating an instantiation function for a complex `type T struct`, it is
useful to allow variable number of options to be applied. However, the strong
type system of Go restricts the function design options. There are a few ways
to solve this problem, but we have landed on the following design.

#### `config`

Configuration should be held in a `struct` named `config`, or prefixed with
specific type name this Configuration applies to if there are multiple
`config` in the package. This type must contain configuration options.

```go
// config contains configuration options for a thing.
type config struct {
	// options ...
}
```

In general the `config` type will not need to be used externally to the
package and should be unexported. If, however, it is expected that the user
will likely want to build custom options for the configuration, the `config`
should be exported. Please, include in the documentation for the `config`
how the user can extend the configuration.

It is important that internal `config` are not shared across package boundaries.
Meaning a `config` from one package should not be directly used by another. The
one exception is the API packages.  The configs from the base API, eg.
`go.opentelemetry.io/otel/trace.TracerConfig` and
`go.opentelemetry.io/otel/metric.InstrumentConfig`, are intended to be consumed
by the SDK therefore it is expected that these are exported.

When a config is exported we want to maintain forward and backward
compatibility, to achieve this no fields should be exported but should
instead be accessed by methods.

Optionally, it is common to include a `newConfig` function (with the same
naming scheme). This function wraps any defaults setting and looping over
all options to create a configured `config`.

```go
// newConfig returns an appropriately configured config.
func newConfig(options ...Option) config {
	// Set default values for config.
	config := config{/* […] */}
	for _, option := range options {
		config = option.apply(config)
	}
	// Perform any validation here.
	return config
}
```

If validation of the `config` options is also performed this can return an
error as well that is expected to be handled by the instantiation function
or propagated to the user.

Given the design goal of not having the user need to work with the `config`,
the `newConfig` function should also be unexported.

#### `Option`

To set the value of the options a `config` contains, a corresponding
`Option` interface type should be used.

```go
type Option interface {
	apply(config) config
}
```

Having `apply` unexported makes sure that it will not be used externally.
Moreover, the interface becomes sealed so the user cannot easily implement
the interface on its own.

The `apply` method should return a modified version of the passed config.
This approach, instead of passing a pointer, is used to prevent the config from being allocated to the heap.

The name of the interface should be prefixed in the same way the
corresponding `config` is (if at all).

#### Options

All user configurable options for a `config` must have a related unexported
implementation of the `Option` interface and an exported configuration
function that wraps this implementation.

The wrapping function name should be prefixed with `With*` (or in the
special case of a boolean options `Without*`) and should have the following
function signature.

```go
func With*(…) Option { … }
```

##### `bool` Options

```go
type defaultFalseOption bool

func (o defaultFalseOption) apply(c config) config {
	c.Bool = bool(o)
    return c
}

// WithOption sets a T to have an option included.
func WithOption() Option {
	return defaultFalseOption(true)
}
```

```go
type defaultTrueOption bool

func (o defaultTrueOption) apply(c config) config {
	c.Bool = bool(o)
    return c
}

// WithoutOption sets a T to have Bool option excluded.
func WithoutOption() Option {
	return defaultTrueOption(false)
}
```

##### Declared Type Options

```go
type myTypeOption struct {
	MyType MyType
}

func (o myTypeOption) apply(c config) config {
	c.MyType = o.MyType
    return c
}

// WithMyType sets T to have include MyType.
func WithMyType(t MyType) Option {
	return myTypeOption{t}
}
```

##### Functional Options

```go
type optionFunc func(config) config

func (fn optionFunc) apply(c config) config {
	return fn(c)
}

// WithMyType sets t as MyType.
func WithMyType(t MyType) Option {
	return optionFunc(func(c config) config {
		c.MyType = t
        return c
	})
}
```

#### Instantiation

Using this configuration pattern to configure instantiation with a `NewT`
function.

```go
func NewT(options ...Option) T {…}
```

Any required parameters can be declared before the variadic `options`.

#### Dealing with Overlap

Sometimes there are multiple complex `struct` that share common
configuration and also have distinct configuration. To avoid repeated
portions of `config`s, a common `config` can be used with the union of
options being handled with the `Option` interface.

For example.

```go
// config holds options for all animals.
type config struct {
	Weight      float64
	Color       string
	MaxAltitude float64
}

// DogOption apply Dog specific options.
type DogOption interface {
	applyDog(config) config
}

// BirdOption apply Bird specific options.
type BirdOption interface {
	applyBird(config) config
}

// Option apply options for all animals.
type Option interface {
	BirdOption
	DogOption
}

type weightOption float64

func (o weightOption) applyDog(c config) config {
	c.Weight = float64(o)
	return c
}

func (o weightOption) applyBird(c config) config {
	c.Weight = float64(o)
	return c
}

func WithWeight(w float64) Option { return weightOption(w) }

type furColorOption string

func (o furColorOption) applyDog(c config) config {
	c.Color = string(o)
	return c
}

func WithFurColor(c string) DogOption { return furColorOption(c) }

type maxAltitudeOption float64

func (o maxAltitudeOption) applyBird(c config) config {
	c.MaxAltitude = float64(o)
	return c
}

func WithMaxAltitude(a float64) BirdOption { return maxAltitudeOption(a) }

func NewDog(name string, o ...DogOption) Dog    {…}
func NewBird(name string, o ...BirdOption) Bird {…}
```

### Interfaces

To allow other developers to better comprehend the code, it is important
to ensure it is sufficiently documented. One simple measure that contributes
to this aim is self-documenting by naming method parameters. Therefore,
where appropriate, methods of every exported interface type should have
their parameters appropriately named.

#### Interface Stability

All exported stable interfaces that include the following warning in their
documentation are allowed to be extended with additional methods.

> Warning: methods may be added to this interface in minor releases.

These interfaces are defined by the OpenTelemetry specification and will be
updated as the specification evolves.

Otherwise, stable interfaces MUST NOT be modified.

#### How to Change Specification Interfaces

When an API change must be made, we will update the SDK with the new method one
release before the API change. This will allow the SDK one version before the
API change to work seamlessly with the new API.

If an incompatible version of the SDK is used with the new API the application
will fail to compile.

#### How Not to Change Specification Interfaces

We have explored using a v2 of the API to change interfaces and found that there
was no way to introduce a v2 and have it work seamlessly with the v1 of the API.
Problems happened with libraries that upgraded to v2 when an application did not,
and would not produce any telemetry.

More detail of the approaches considered and their limitations can be found in
the [Use a V2 API to evolve interfaces](https://github.com/open-telemetry/opentelemetry-go/issues/3920)
issue.

#### How to Change Other Interfaces

If new functionality is needed for an interface that cannot be changed it MUST
be added by including an additional interface. That added interface can be a
simple interface for the specific functionality that you want to add or it can
be a super-set of the original interface. For example, if you wanted to a
`Close` method to the `Exporter` interface:

```go
type Exporter interface {
	Export()
}
```

A new interface, `Closer`, can be added:

```go
type Closer interface {
	Close()
}
```

Code that is passed the `Exporter` interface can now check to see if the passed
value also satisfies the new interface. E.g.

```go
func caller(e Exporter) {
	/* ... */
	if c, ok := e.(Closer); ok {
		c.Close()
	}
	/* ... */
}
```

Alternatively, a new type that is the super-set of an `Exporter` can be created.

```go
type ClosingExporter struct {
	Exporter
	Close()
}
```

This new type can be used similar to the simple interface above in that a
passed `Exporter` type can be asserted to satisfy the `ClosingExporter` type
and the `Close` method called.

This super-set approach can be useful if there is explicit behavior that needs
to be coupled with the original type and passed as a unified type to a new
function, but, because of this coupling, it also limits the applicability of
the added functionality. If there exist other interfaces where this
functionality should be added, each one will need their own super-set
interfaces and will duplicate the pattern. For this reason, the simple targeted
interface that defines the specific functionality should be preferred.

See also:
[Keeping Your Modules Compatible: Working with interfaces](https://go.dev/blog/module-compatibility#working-with-interfaces).

### Testing

The tests should never leak goroutines.

Use the term `ConcurrentSafe` in the test name when it aims to verify the
absence of race conditions. The top-level tests with this term will be run
many times in the `test-concurrent-safe` CI job to increase the chance of
catching concurrency issues. This does not apply to subtests when this term
is not in their root name.

### Internal packages

The use of internal packages should be scoped to a single module. A sub-module
should never import from a parent internal package. This creates a coupling
between the two modules where a user can upgrade the parent without the child
and if the internal package API has changed it will fail to upgrade[^3].

There are two known exceptions to this rule:

- `go.opentelemetry.io/otel/internal/global`
  - This package manages global state for all of opentelemetry-go. It needs to
  be a single package in order to ensure the uniqueness of the global state.
- `go.opentelemetry.io/otel/internal/baggage`
  - This package provides values in a `context.Context` that need to be
  recognized by `go.opentelemetry.io/otel/baggage` and
  `go.opentelemetry.io/otel/bridge/opentracing` but remain private.

If you have duplicate code in multiple modules, make that code into a Go
template stored in `go.opentelemetry.io/otel/internal/shared` and use [gotmpl]
to render the templates in the desired locations. See [#4404] for an example of
this.

[^3]: https://github.com/open-telemetry/opentelemetry-go/issues/3548

### Ignoring context cancellation

OpenTelemetry API implementations need to ignore the cancellation of the context that are
passed when recording a value (e.g. starting a span, recording a measurement, emitting a log).
Recording methods should not return an error describing the cancellation state of the context
when they complete, nor should they abort any work.

This rule may not apply if the OpenTelemetry specification defines a timeout mechanism for
the method. In that case the context cancellation can be used for the timeout with the
restriction that this behavior is documented for the method. Otherwise, timeouts
are expected to be handled by the user calling the API, not the implementation.

Stoppage of the telemetry pipeline is handled by calling the appropriate `Shutdown` method
of a provider. It is assumed the context passed from a user is not used for this purpose.

Outside of the direct recording of telemetry from the API (e.g. exporting telemetry,
force flushing telemetry, shutting down a signal provider) the context cancellation
should be honored. This means all work done on behalf of the user provided context
should be canceled.

## Approvers and Maintainers

### Triagers

- [Cheng-Zhen Yang](https://github.com/scorpionknifes), Independent

### Approvers

### Maintainers

- [Damien Mathieu](https://github.com/dmathieu), Elastic
- [David Ashpole](https://github.com/dashpole), Google
- [Robert Pająk](https://github.com/pellared), Splunk
- [Sam Xie](https://github.com/XSAM), Cisco/AppDynamics
- [Tyler Yahn](https://github.com/MrAlias), Splunk

### Emeritus

- [Aaron Clawson](https://github.com/MadVikingGod)
- [Anthony Mirabella](https://github.com/Aneurysm9)
- [Chester Cheung](https://github.com/hanyuancheung)
- [Evan Torrie](https://github.com/evantorrie)
- [Gustavo Silva Paiva](https://github.com/paivagustavo)
- [Josh MacDonald](https://github.com/jmacd)
- [Liz Fong-Jones](https://github.com/lizthegrey)

### Become an Approver or a Maintainer

See the [community membership document in OpenTelemetry community
repo](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md).

[Approver]: #approvers
[Maintainer]: #maintainers
[gotmpl]: https://pkg.go.dev/go.opentelemetry.io/build-tools/gotmpl
[#4404]: https://github.com/open-telemetry/opentelemetry-go/pull/4404

Perforator is a cluster-wide continuous profiling tool designed for large data centers


# OpenTelemetry-Go

[![CI](https://github.com/open-telemetry/opentelemetry-go/workflows/ci/badge.svg)](https://github.com/open-telemetry/opentelemetry-go/actions?query=workflow%3Aci+branch%3Amain)
[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-go/coverage.svg?branch=main)](https://app.codecov.io/gh/open-telemetry/opentelemetry-go?branch=main)
[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel)](https://pkg.go.dev/go.opentelemetry.io/otel)
[![Go Report Card](https://goreportcard.com/badge/go.opentelemetry.io/otel)](https://goreportcard.com/report/go.opentelemetry.io/otel)
[![Slack](https://img.shields.io/badge/slack-@cncf/otel--go-brightgreen.svg?logo=slack)](https://cloud-native.slack.com/archives/C01NPAXACKT)

OpenTelemetry-Go is the [Go](https://golang.org/) implementation of [OpenTelemetry](https://opentelemetry.io/).
It provides a set of APIs to directly measure performance and behavior of your software and send this data to observability platforms.

## Project Status

| Signal  | Status             |
|---------|--------------------|
| Traces  | Stable             |
| Metrics | Stable             |
| Logs    | Beta[^1]           |

Progress and status specific to this repository is tracked in our
[project boards](https://github.com/open-telemetry/opentelemetry-go/projects)
and
[milestones](https://github.com/open-telemetry/opentelemetry-go/milestones).

Project versioning information and stability guarantees can be found in the
[versioning documentation](VERSIONING.md).

[^1]: https://github.com/orgs/open-telemetry/projects/43

### Compatibility

OpenTelemetry-Go ensures compatibility with the current supported versions of
the [Go language](https://golang.org/doc/devel/release#policy):

> Each major Go release is supported until there are two newer major releases.
> For example, Go 1.5 was supported until the Go 1.7 release, and Go 1.6 was supported until the Go 1.8 release.

For versions of Go that are no longer supported upstream, opentelemetry-go will
stop ensuring compatibility with these versions in the following manner:

- A minor release of opentelemetry-go will be made to add support for the new
  supported release of Go.
- The following minor release of opentelemetry-go will remove compatibility
  testing for the oldest (now archived upstream) version of Go. This, and
  future, releases of opentelemetry-go may include features only supported by
  the currently supported versions of Go.

Currently, this project supports the following environments.

| OS       | Go Version | Architecture |
|----------|------------|--------------|
| Ubuntu   | 1.23       | amd64        |
| Ubuntu   | 1.22       | amd64        |
| Ubuntu   | 1.23       | 386          |
| Ubuntu   | 1.22       | 386          |
| Linux    | 1.23       | arm64        |
| Linux    | 1.22       | arm64        |
| macOS 13 | 1.23       | amd64        |
| macOS 13 | 1.22       | amd64        |
| macOS    | 1.23       | arm64        |
| macOS    | 1.22       | arm64        |
| Windows  | 1.23       | amd64        |
| Windows  | 1.22       | amd64        |
| Windows  | 1.23       | 386          |
| Windows  | 1.22       | 386          |

While this project should work for other systems, no compatibility guarantees
are made for those systems currently.

## Getting Started

You can find a getting started guide on [opentelemetry.io](https://opentelemetry.io/docs/languages/go/getting-started/).

OpenTelemetry's goal is to provide a single set of APIs to capture distributed
traces and metrics from your application and send them to an observability
platform. This project allows you to do just that for applications written in
Go. There are two steps to this process: instrument your application, and
configure an exporter.

### Instrumentation

To start capturing distributed traces and metric events from your application
it first needs to be instrumented. The easiest way to do this is by using an
instrumentation library for your code. Be sure to check out [the officially
supported instrumentation
libraries](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/main/instrumentation).

If you need to extend the telemetry an instrumentation library provides or want
to build your own instrumentation for your application directly you will need
to use the
[Go otel](https://pkg.go.dev/go.opentelemetry.io/otel)
package. The [examples](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/main/examples)
are a good way to see some practical uses of this process.

### Export

Now that your application is instrumented to collect telemetry, it needs an
export pipeline to send that telemetry to an observability platform.

All officially supported exporters for the OpenTelemetry project are contained in the [exporters directory](./exporters).

| Exporter                              | Logs | Metrics | Traces |
|---------------------------------------|:----:|:-------:|:------:|
| [OTLP](./exporters/otlp/)             |  ✓   |    ✓    |   ✓    |
| [Prometheus](./exporters/prometheus/) |      |    ✓    |        |
| [stdout](./exporters/stdout/)         |  ✓   |    ✓    |   ✓    |
| [Zipkin](./exporters/zipkin/)         |      |         |   ✓    |

## Contributing

See the [contributing documentation](CONTRIBUTING.md).


# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.11.0] - 2023-05-02
### Fixed
- Fix initialization of `Value` wrappers.

### Added
- Add `String` method to `atomic.Pointer[T]` type allowing users to safely print
underlying values of pointers.

[1.11.0]: https://github.com/uber-go/atomic/compare/v1.10.0...v1.11.0

## [1.10.0] - 2022-08-11
### Added
- Add `atomic.Float32` type for atomic operations on `float32`.
- Add `CompareAndSwap` and `Swap` methods to `atomic.String`, `atomic.Error`,
  and `atomic.Value`.
- Add generic `atomic.Pointer[T]` type for atomic operations on pointers of any
  type. This is present only for Go 1.18 or higher, and is a drop-in for
  replacement for the standard library's `sync/atomic.Pointer` type.

### Changed
- Deprecate `CAS` methods on all types in favor of corresponding
  `CompareAndSwap` methods.

Thanks to @eNV25 and @icpd for their contributions to this release.

[1.10.0]: https://github.com/uber-go/atomic/compare/v1.9.0...v1.10.0

## [1.9.0] - 2021-07-15
### Added
- Add `Float64.Swap` to match int atomic operations.
- Add `atomic.Time` type for atomic operations on `time.Time` values.

[1.9.0]: https://github.com/uber-go/atomic/compare/v1.8.0...v1.9.0

## [1.8.0] - 2021-06-09
### Added
- Add `atomic.Uintptr` type for atomic operations on `uintptr` values.
- Add `atomic.UnsafePointer` type for atomic operations on `unsafe.Pointer` values.

[1.8.0]: https://github.com/uber-go/atomic/compare/v1.7.0...v1.8.0

## [1.7.0] - 2020-09-14
### Added
- Support JSON serialization and deserialization of primitive atomic types.
- Support Text marshalling and unmarshalling for string atomics.

### Changed
- Disallow incorrect comparison of atomic values in a non-atomic way.

### Removed
- Remove dependency on `golang.org/x/{lint, tools}`.

[1.7.0]: https://github.com/uber-go/atomic/compare/v1.6.0...v1.7.0

## [1.6.0] - 2020-02-24
### Changed
- Drop library dependency on `golang.org/x/{lint, tools}`.

[1.6.0]: https://github.com/uber-go/atomic/compare/v1.5.1...v1.6.0

## [1.5.1] - 2019-11-19
- Fix bug where `Bool.CAS` and `Bool.Toggle` do work correctly together
  causing `CAS` to fail even though the old value matches.

[1.5.1]: https://github.com/uber-go/atomic/compare/v1.5.0...v1.5.1

## [1.5.0] - 2019-10-29
### Changed
- With Go modules, only the `go.uber.org/atomic` import path is supported now.
  If you need to use the old import path, please add a `replace` directive to
  your `go.mod`.

[1.5.0]: https://github.com/uber-go/atomic/compare/v1.4.0...v1.5.0

## [1.4.0] - 2019-05-01
### Added
 - Add `atomic.Error` type for atomic operations on `error` values.

[1.4.0]: https://github.com/uber-go/atomic/compare/v1.3.2...v1.4.0

## [1.3.2] - 2018-05-02
### Added
- Add `atomic.Duration` type for atomic operations on `time.Duration` values.

[1.3.2]: https://github.com/uber-go/atomic/compare/v1.3.1...v1.3.2

## [1.3.1] - 2017-11-14
### Fixed
- Revert optimization for `atomic.String.Store("")` which caused data races.

[1.3.1]: https://github.com/uber-go/atomic/compare/v1.3.0...v1.3.1

## [1.3.0] - 2017-11-13
### Added
- Add `atomic.Bool.CAS` for compare-and-swap semantics on bools.

### Changed
- Optimize `atomic.String.Store("")` by avoiding an allocation.

[1.3.0]: https://github.com/uber-go/atomic/compare/v1.2.0...v1.3.0

## [1.2.0] - 2017-04-12
### Added
- Shadow `atomic.Value` from `sync/atomic`.

[1.2.0]: https://github.com/uber-go/atomic/compare/v1.1.0...v1.2.0

## [1.1.0] - 2017-03-10
### Added
- Add atomic `Float64` type.

### Changed
- Support new `go.uber.org/atomic` import path.

[1.1.0]: https://github.com/uber-go/atomic/compare/v1.0.0...v1.1.0

## [1.0.0] - 2016-07-18

- Initial release.

[1.0.0]: https://github.com/uber-go/atomic/releases/tag/v1.0.0


# atomic [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] [![Go Report Card][reportcard-img]][reportcard]

Simple wrappers for primitive types to enforce atomic access.

## Installation

```shell
$ go get -u go.uber.org/atomic@v1
```

### Legacy Import Path

As of v1.5.0, the import path `go.uber.org/atomic` is the only supported way
of using this package. If you are using Go modules, this package will fail to
compile with the legacy import path path `github.com/uber-go/atomic`.

We recommend migrating your code to the new import path but if you're unable
to do so, or if your dependencies are still using the old import path, you
will have to add a `replace` directive to your `go.mod` file downgrading the
legacy import path to an older version.

```
replace github.com/uber-go/atomic => github.com/uber-go/atomic v1.4.0
```

You can do so automatically by running the following command.

```shell
$ go mod edit -replace github.com/uber-go/atomic=github.com/uber-go/atomic@v1.4.0
```

## Usage

The standard library's `sync/atomic` is powerful, but it's easy to forget which
variables must be accessed atomically. `go.uber.org/atomic` preserves all the
functionality of the standard library, but wraps the primitive types to
provide a safer, more convenient API.

```go
var atom atomic.Uint32
atom.Store(42)
atom.Sub(2)
atom.CAS(40, 11)
```

See the [documentation][doc] for a complete API specification.

## Development Status

Stable.

---

Released under the [MIT License](LICENSE.txt).

[doc-img]: https://godoc.org/github.com/uber-go/atomic?status.svg
[doc]: https://godoc.org/go.uber.org/atomic
[ci-img]: https://github.com/uber-go/atomic/actions/workflows/go.yml/badge.svg
[ci]: https://github.com/uber-go/atomic/actions/workflows/go.yml
[cov-img]: https://codecov.io/gh/uber-go/atomic/branch/master/graph/badge.svg
[cov]: https://codecov.io/gh/uber-go/atomic
[reportcard-img]: https://goreportcard.com/badge/go.uber.org/atomic
[reportcard]: https://goreportcard.com/report/go.uber.org/atomic


# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [1.3.0]
### Fixed
- Built-in ignores now match function names more accurately.
  They will no longer ignore stacks because of file names
  that look similar to function names. (#112)
### Added
- Add an `IgnoreAnyFunction` option to ignore stack traces
  that have the provided function anywhere in the stack. (#113)
- Ignore `testing.runFuzzing` and `testing.runFuzzTests` alongside
  other already-ignored test functions (`testing.RunTests`, etc). (#105)
### Changed
- Miscellaneous CI-related fixes. (#103, #108, #114)

[1.3.0]: https://github.com/uber-go/goleak/compare/v1.2.1...v1.3.0

## [1.2.1]
### Changed
- Drop golang/x/lint dependency.

[1.2.1]: https://github.com/uber-go/goleak/compare/v1.2.0...v1.2.1

## [1.2.0]
### Added
- Add Cleanup option that can be used for registering cleanup callbacks. (#78)

### Changed
- Mark VerifyNone as a test helper. (#75)

Thanks to @tallclair for their contribution to this release.

[1.2.0]: https://github.com/uber-go/goleak/compare/v1.1.12...v1.2.0

## [1.1.12]
### Fixed
- Fixed logic for ignoring trace related goroutines on Go versions 1.16 and above.

[1.1.12]: https://github.com/uber-go/goleak/compare/v1.1.11...v1.1.12

## [1.1.11]
### Fixed
- Documentation fix on how to test.
- Update dependency on stretchr/testify to v1.7.0. (#59)
- Update dependency on golang.org/x/tools to address CVE-2020-14040. (#62)

[1.1.11]: https://github.com/uber-go/goleak/compare/v1.1.10...v1.1.11

## [1.1.10]
### Added
- [#49]: Add option to ignore current goroutines, which checks for any additional leaks and allows for incremental adoption of goleak in larger projects.

Thanks to @denis-tingajkin for their contributions to this release.

[#49]: https://github.com/uber-go/goleak/pull/49
[1.1.10]: https://github.com/uber-go/goleak/compare/v1.0.0...v1.1.10

## [1.0.0]
### Changed
- Migrate to Go modules.

### Fixed
- Ignore trace related goroutines that cause false positives with -trace.

[1.0.0]: https://github.com/uber-go/goleak/compare/v0.10.0...v1.0.0

## [0.10.0]
- Initial release.

[0.10.0]: https://github.com/uber-go/goleak/compare/v0.10.0...HEAD


# goleak [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov]

Goroutine leak detector to help avoid Goroutine leaks.

## Installation

You can use `go get` to get the latest version:

`go get -u go.uber.org/goleak`

`goleak` also supports semver releases.

Note that go-leak only [supports][release] the two most recent minor versions of Go.

## Quick Start

To verify that there are no unexpected goroutines running at the end of a test:

```go
func TestA(t *testing.T) {
	defer goleak.VerifyNone(t)

	// test logic here.
}
```

Instead of checking for leaks at the end of every test, `goleak` can also be run
at the end of every test package by creating a `TestMain` function for your
package:

```go
func TestMain(m *testing.M) {
	goleak.VerifyTestMain(m)
}
```

## Determine Source of Package Leaks

When verifying leaks using `TestMain`, the leak test is only run once after all tests
have been run. This is typically enough to ensure there's no goroutines leaked from
tests, but when there are leaks, it's hard to determine which test is causing them.

You can use the following bash script to determine the source of the failing test:

```sh
# Create a test binary which will be used to run each test individually
$ go test -c -o tests

# Run each test individually, printing "." for successful tests, or the test name
# for failing tests.
$ for test in $(go test -list . | grep -E "^(Test|Example)"); do ./tests -test.run "^$test\$" &>/dev/null && echo -n "." || echo -e "\n$test failed"; done
```

This will only print names of failing tests which can be investigated individually. E.g.,

```
.....
TestLeakyTest failed
.......
```

## Stability

goleak is v1 and follows [SemVer](http://semver.org/) strictly.

No breaking changes will be made to exported APIs before 2.0.

[doc-img]: https://godoc.org/go.uber.org/goleak?status.svg
[doc]: https://godoc.org/go.uber.org/goleak
[ci-img]: https://github.com/uber-go/goleak/actions/workflows/ci.yml/badge.svg
[ci]: https://github.com/uber-go/goleak/actions/workflows/ci.yml
[cov-img]: https://codecov.io/gh/uber-go/goleak/branch/master/graph/badge.svg
[cov]: https://codecov.io/gh/uber-go/goleak
[release]: https://go.dev/doc/devel/release#policy


Releases
========

v1.11.0 (2023-03-28)
====================
-   `Errors` now supports any error that implements multiple-error
    interface.
-   Add `Every` function to allow checking if all errors in the chain
    satisfies `errors.Is` against the target error.

v1.10.0 (2023-03-08)
====================

-   Comply with Go 1.20's multiple-error interface.
-   Drop Go 1.18 support.
    Per the support policy, only Go 1.19 and 1.20 are supported now.
-   Drop all non-test external dependencies.

v1.9.0 (2022-12-12)
===================

-   Add `AppendFunc` that allow passsing functions to similar to
    `AppendInvoke`.

-   Bump up yaml.v3 dependency to 3.0.1.

v1.8.0 (2022-02-28)
===================

-   `Combine`: perform zero allocations when there are no errors.

v1.7.0 (2021-05-06)
===================

-   Add `AppendInvoke` to append into errors from `defer` blocks.

v1.6.0 (2020-09-14)
===================

-   Actually drop library dependency on development-time tooling.

v1.5.0 (2020-02-24)
===================

-   Drop library dependency on development-time tooling.

v1.4.0 (2019-11-04)
===================

-   Add `AppendInto` function to more ergonomically build errors inside a
    loop.

v1.3.0 (2019-10-29)
===================

-   Switch to Go modules.

v1.2.0 (2019-09-26)
===================

-   Support extracting and matching against wrapped errors with `errors.As`
    and `errors.Is`.

v1.1.0 (2017-06-30)
===================

-   Added an `Errors(error) []error` function to extract the underlying list of
    errors for a multierr error.

v1.0.0 (2017-05-31)
===================

No changes since v0.2.0. This release is committing to making no breaking
changes to the current API in the 1.X series.

v0.2.0 (2017-04-11)
===================

-   Repeatedly appending to the same error is now faster due to fewer
    allocations.

v0.1.0 (2017-31-03)
===================

-   Initial release


# multierr [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov]

`multierr` allows combining one or more Go `error`s together.

## Features

- **Idiomatic**:
  multierr follows best practices in Go, and keeps your code idiomatic.
    - It keeps the underlying error type hidden,
      allowing you to deal in `error` values exclusively.
    - It provides APIs to safely append into an error from a `defer` statement.
- **Performant**:
  multierr is optimized for performance:
    - It avoids allocations where possible.
    - It utilizes slice resizing semantics to optimize common cases
      like appending into the same error object from a loop.
- **Interoperable**:
  multierr interoperates with the Go standard library's error APIs seamlessly:
    - The `errors.Is` and `errors.As` functions *just work*.
- **Lightweight**:
  multierr comes with virtually no dependencies.

## Installation

```bash
go get -u go.uber.org/multierr@latest
```

## Status

Stable: No breaking changes will be made before 2.0.

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

Released under the [MIT License].

[MIT License]: LICENSE.txt
[doc-img]: https://pkg.go.dev/badge/go.uber.org/multierr
[doc]: https://pkg.go.dev/go.uber.org/multierr
[ci-img]: https://github.com/uber-go/multierr/actions/workflows/go.yml/badge.svg
[cov-img]: https://codecov.io/gh/uber-go/multierr/branch/master/graph/badge.svg
[ci]: https://github.com/uber-go/multierr/actions/workflows/go.yml
[cov]: https://codecov.io/gh/uber-go/multierr


# Changelog
All notable changes to this project will be documented in this file.

This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 1.27.0 (20 Feb 2024)
Enhancements:
* [#1378][]: Add `WithLazy` method for `SugaredLogger`.
* [#1399][]: zaptest: Add `NewTestingWriter` for customizing TestingWriter with more flexibility than `NewLogger`.
* [#1406][]: Add `Log`, `Logw`, `Logln` methods for `SugaredLogger`.
* [#1416][]: Add `WithPanicHook` option for testing panic logs.

Thanks to @defval, @dimmo, @arxeiss, and @MKrupauskas for their contributions to this release.

[#1378]: https://github.com/uber-go/zap/pull/1378
[#1399]: https://github.com/uber-go/zap/pull/1399
[#1406]: https://github.com/uber-go/zap/pull/1406
[#1416]: https://github.com/uber-go/zap/pull/1416

## 1.26.0 (14 Sep 2023)
Enhancements:
* [#1297][]: Add Dict as a Field.
* [#1319][]: Add `WithLazy` method to `Logger` which lazily evaluates the structured
context.
* [#1350][]: String encoding is much (~50%) faster now.

Thanks to @hhk7734, @jquirke, and @cdvr1993 for their contributions to this release.

[#1297]: https://github.com/uber-go/zap/pull/1297
[#1319]: https://github.com/uber-go/zap/pull/1319
[#1350]: https://github.com/uber-go/zap/pull/1350

## 1.25.0 (1 Aug 2023)

This release contains several improvements including performance, API additions,
and two new experimental packages whose APIs are unstable and may change in the
future.

Enhancements:
* [#1246][]: Add `zap/exp/zapslog` package for integration with slog.
* [#1273][]: Add `Name` to `Logger` which returns the Logger's name if one is set.
* [#1281][]: Add `zap/exp/expfield` package which contains helper methods
`Str` and `Strs` for constructing String-like zap.Fields.
* [#1310][]: Reduce stack size on `Any`.

Thanks to @knight42, @dzakaammar, @bcspragu, and @rexywork for their contributions
to this release.

[#1246]: https://github.com/uber-go/zap/pull/1246
[#1273]: https://github.com/uber-go/zap/pull/1273
[#1281]: https://github.com/uber-go/zap/pull/1281
[#1310]: https://github.com/uber-go/zap/pull/1310

## 1.24.0 (30 Nov 2022)

Enhancements:
* [#1148][]: Add `Level` to both `Logger` and `SugaredLogger` that reports the
  current minimum enabled log level.
* [#1185][]: `SugaredLogger` turns errors to zap.Error automatically.

Thanks to @Abirdcfly, @craigpastro, @nnnkkk7, and @sashamelentyev for their
contributions to this release.

[#1148]: https://github.coml/uber-go/zap/pull/1148
[#1185]: https://github.coml/uber-go/zap/pull/1185

## 1.23.0 (24 Aug 2022)

Enhancements:
* [#1147][]: Add a `zapcore.LevelOf` function to determine the level of a
  `LevelEnabler` or `Core`.
* [#1155][]: Add `zap.Stringers` field constructor to log arrays of objects
  that implement `String() string`.

[#1147]: https://github.com/uber-go/zap/pull/1147
[#1155]: https://github.com/uber-go/zap/pull/1155

## 1.22.0 (8 Aug 2022)

Enhancements:
* [#1071][]: Add `zap.Objects` and `zap.ObjectValues` field constructors to log
  arrays of objects. With these two constructors, you don't need to implement
  `zapcore.ArrayMarshaler` for use with `zap.Array` if those objects implement
  `zapcore.ObjectMarshaler`.
* [#1079][]: Add `SugaredLogger.WithOptions` to build a copy of an existing
  `SugaredLogger` with the provided options applied.
* [#1080][]: Add `*ln` variants to `SugaredLogger` for each log level.
  These functions provide a string joining behavior similar to `fmt.Println`.
* [#1088][]: Add `zap.WithFatalHook` option to control the behavior of the
  logger for `Fatal`-level log entries. This defaults to exiting the program.
* [#1108][]: Add a `zap.Must` function that you can use with `NewProduction` or
  `NewDevelopment` to panic if the system was unable to build the logger.
* [#1118][]: Add a `Logger.Log` method that allows specifying the log level for
  a statement dynamically.

Thanks to @cardil, @craigpastro, @sashamelentyev, @shota3506, and @zhupeijun
for their contributions to this release.

[#1071]: https://github.com/uber-go/zap/pull/1071
[#1079]: https://github.com/uber-go/zap/pull/1079
[#1080]: https://github.com/uber-go/zap/pull/1080
[#1088]: https://github.com/uber-go/zap/pull/1088
[#1108]: https://github.com/uber-go/zap/pull/1108
[#1118]: https://github.com/uber-go/zap/pull/1118

## 1.21.0 (7 Feb 2022)

Enhancements:
*  [#1047][]: Add `zapcore.ParseLevel` to parse a `Level` from a string.
*  [#1048][]: Add `zap.ParseAtomicLevel` to parse an `AtomicLevel` from a
   string.

Bugfixes:
* [#1058][]: Fix panic in JSON encoder when `EncodeLevel` is unset.

Other changes:
* [#1052][]: Improve encoding performance when the `AddCaller` and
  `AddStacktrace` options are used together.

[#1047]: https://github.com/uber-go/zap/pull/1047
[#1048]: https://github.com/uber-go/zap/pull/1048
[#1052]: https://github.com/uber-go/zap/pull/1052
[#1058]: https://github.com/uber-go/zap/pull/1058

Thanks to @aerosol and @Techassi for their contributions to this release.

## 1.20.0 (4 Jan 2022)

Enhancements:
* [#989][]: Add `EncoderConfig.SkipLineEnding` flag to disable adding newline
  characters between log statements.
* [#1039][]: Add `EncoderConfig.NewReflectedEncoder` field to customize JSON
  encoding of reflected log fields.

Bugfixes:
* [#1011][]: Fix inaccurate precision when encoding complex64 as JSON.
* [#554][], [#1017][]: Close JSON namespaces opened in `MarshalLogObject`
  methods when the methods return.
* [#1033][]: Avoid panicking in Sampler core if `thereafter` is zero.

Other changes:
* [#1028][]: Drop support for Go < 1.15.

[#554]: https://github.com/uber-go/zap/pull/554
[#989]: https://github.com/uber-go/zap/pull/989
[#1011]: https://github.com/uber-go/zap/pull/1011
[#1017]: https://github.com/uber-go/zap/pull/1017
[#1028]: https://github.com/uber-go/zap/pull/1028
[#1033]: https://github.com/uber-go/zap/pull/1033
[#1039]: https://github.com/uber-go/zap/pull/1039

Thanks to @psrajat, @lruggieri, @sammyrnycreal for their contributions to this release.

## 1.19.1 (8 Sep 2021)

Bugfixes:
* [#1001][]: JSON: Fix complex number encoding with negative imaginary part. Thanks to @hemantjadon.
* [#1003][]: JSON: Fix inaccurate precision when encoding float32.

[#1001]: https://github.com/uber-go/zap/pull/1001
[#1003]: https://github.com/uber-go/zap/pull/1003

## 1.19.0 (9 Aug 2021)

Enhancements:
* [#975][]: Avoid panicking in Sampler core if the level is out of bounds.
* [#984][]: Reduce the size of BufferedWriteSyncer by aligning the fields
  better.

[#975]: https://github.com/uber-go/zap/pull/975
[#984]: https://github.com/uber-go/zap/pull/984

Thanks to @lancoLiu and @thockin for their contributions to this release.

## 1.18.1 (28 Jun 2021)

Bugfixes:
* [#974][]: Fix nil dereference in logger constructed by `zap.NewNop`.

[#974]: https://github.com/uber-go/zap/pull/974

## 1.18.0 (28 Jun 2021)

Enhancements:
* [#961][]: Add `zapcore.BufferedWriteSyncer`, a new `WriteSyncer` that buffers
  messages in-memory and flushes them periodically.
* [#971][]: Add `zapio.Writer` to use a Zap logger as an `io.Writer`.
* [#897][]: Add `zap.WithClock` option to control the source of time via the
  new `zapcore.Clock` interface.
* [#949][]: Avoid panicking in `zap.SugaredLogger` when arguments of `*w`
  methods don't match expectations.
* [#943][]: Add support for filtering by level or arbitrary matcher function to
  `zaptest/observer`.
* [#691][]: Comply with `io.StringWriter` and `io.ByteWriter` in Zap's
  `buffer.Buffer`.

Thanks to @atrn0, @ernado, @heyanfu, @hnlq715, @zchee
for their contributions to this release.

[#691]: https://github.com/uber-go/zap/pull/691
[#897]: https://github.com/uber-go/zap/pull/897
[#943]: https://github.com/uber-go/zap/pull/943
[#949]: https://github.com/uber-go/zap/pull/949
[#961]: https://github.com/uber-go/zap/pull/961
[#971]: https://github.com/uber-go/zap/pull/971

## 1.17.0 (25 May 2021)

Bugfixes:
* [#867][]: Encode `<nil>` for nil `error` instead of a panic.
* [#931][], [#936][]: Update minimum version constraints to address
  vulnerabilities in dependencies.

Enhancements:
* [#865][]: Improve alignment of fields of the Logger struct, reducing its
  size from 96 to 80 bytes.
* [#881][]: Support `grpclog.LoggerV2` in zapgrpc.
* [#903][]: Support URL-encoded POST requests to the AtomicLevel HTTP handler
  with the `application/x-www-form-urlencoded` content type.
* [#912][]: Support multi-field encoding with `zap.Inline`.
* [#913][]: Speed up SugaredLogger for calls with a single string.
* [#928][]: Add support for filtering by field name to `zaptest/observer`.

Thanks to @ash2k, @FMLS, @jimmystewpot, @Oncilla, @tsoslow, @tylitianrui, @withshubh, and @wziww for their contributions to this release.

[#865]: https://github.com/uber-go/zap/pull/865
[#867]: https://github.com/uber-go/zap/pull/867
[#881]: https://github.com/uber-go/zap/pull/881
[#903]: https://github.com/uber-go/zap/pull/903
[#912]: https://github.com/uber-go/zap/pull/912
[#913]: https://github.com/uber-go/zap/pull/913
[#928]: https://github.com/uber-go/zap/pull/928
[#931]: https://github.com/uber-go/zap/pull/931
[#936]: https://github.com/uber-go/zap/pull/936

## 1.16.0 (1 Sep 2020)

Bugfixes:
* [#828][]: Fix missing newline in IncreaseLevel error messages.
* [#835][]: Fix panic in JSON encoder when encoding times or durations
  without specifying a time or duration encoder.
* [#843][]: Honor CallerSkip when taking stack traces.
* [#862][]: Fix the default file permissions to use `0666` and rely on the umask instead.
* [#854][]: Encode `<nil>` for nil `Stringer` instead of a panic error log.

Enhancements:
* [#629][]: Added `zapcore.TimeEncoderOfLayout` to easily create time encoders
  for custom layouts.
* [#697][]: Added support for a configurable delimiter in the console encoder.
* [#852][]: Optimize console encoder by pooling the underlying JSON encoder.
* [#844][]: Add ability to include the calling function as part of logs.
* [#843][]: Add `StackSkip` for including truncated stacks as a field.
* [#861][]: Add options to customize Fatal behaviour for better testability.

Thanks to @SteelPhase, @tmshn, @lixingwang, @wyxloading, @moul, @segevfiner, @andy-retailnext and @jcorbin for their contributions to this release.

[#629]: https://github.com/uber-go/zap/pull/629
[#697]: https://github.com/uber-go/zap/pull/697
[#828]: https://github.com/uber-go/zap/pull/828
[#835]: https://github.com/uber-go/zap/pull/835
[#843]: https://github.com/uber-go/zap/pull/843
[#844]: https://github.com/uber-go/zap/pull/844
[#852]: https://github.com/uber-go/zap/pull/852
[#854]: https://github.com/uber-go/zap/pull/854
[#861]: https://github.com/uber-go/zap/pull/861
[#862]: https://github.com/uber-go/zap/pull/862

## 1.15.0 (23 Apr 2020)

Bugfixes:
* [#804][]: Fix handling of `Time` values out of `UnixNano` range.
* [#812][]: Fix `IncreaseLevel` being reset after a call to `With`.

Enhancements:
* [#806][]: Add `WithCaller` option to supersede the `AddCaller` option. This
  allows disabling annotation of log entries with caller information if
  previously enabled with `AddCaller`.
* [#813][]: Deprecate `NewSampler` constructor in favor of
  `NewSamplerWithOptions` which supports a `SamplerHook` option. This option
   adds support for monitoring sampling decisions through a hook.

Thanks to @danielbprice for their contributions to this release.

[#804]: https://github.com/uber-go/zap/pull/804
[#812]: https://github.com/uber-go/zap/pull/812
[#806]: https://github.com/uber-go/zap/pull/806
[#813]: https://github.com/uber-go/zap/pull/813

## 1.14.1 (14 Mar 2020)

Bugfixes:
* [#791][]: Fix panic on attempting to build a logger with an invalid Config.
* [#795][]: Vendoring Zap with `go mod vendor` no longer includes Zap's
  development-time dependencies.
* [#799][]: Fix issue introduced in 1.14.0 that caused invalid JSON output to
  be generated for arrays of `time.Time` objects when using string-based time
  formats.

Thanks to @YashishDua for their contributions to this release.

[#791]: https://github.com/uber-go/zap/pull/791
[#795]: https://github.com/uber-go/zap/pull/795
[#799]: https://github.com/uber-go/zap/pull/799

## 1.14.0 (20 Feb 2020)

Enhancements:
* [#771][]: Optimize calls for disabled log levels.
* [#773][]: Add millisecond duration encoder.
* [#775][]: Add option to increase the level of a logger.
* [#786][]: Optimize time formatters using `Time.AppendFormat` where possible.

Thanks to @caibirdme for their contributions to this release.

[#771]: https://github.com/uber-go/zap/pull/771
[#773]: https://github.com/uber-go/zap/pull/773
[#775]: https://github.com/uber-go/zap/pull/775
[#786]: https://github.com/uber-go/zap/pull/786

## 1.13.0 (13 Nov 2019)

Enhancements:
* [#758][]: Add `Intp`, `Stringp`, and other similar `*p` field constructors
  to log pointers to primitives with support for `nil` values.

Thanks to @jbizzle for their contributions to this release.

[#758]: https://github.com/uber-go/zap/pull/758

## 1.12.0 (29 Oct 2019)

Enhancements:
* [#751][]: Migrate to Go modules.

[#751]: https://github.com/uber-go/zap/pull/751

## 1.11.0 (21 Oct 2019)

Enhancements:
* [#725][]: Add `zapcore.OmitKey` to omit keys in an `EncoderConfig`.
* [#736][]: Add `RFC3339` and `RFC3339Nano` time encoders.

Thanks to @juicemia, @uhthomas for their contributions to this release.

[#725]: https://github.com/uber-go/zap/pull/725
[#736]: https://github.com/uber-go/zap/pull/736

## 1.10.0 (29 Apr 2019)

Bugfixes:
* [#657][]: Fix `MapObjectEncoder.AppendByteString` not adding value as a
  string.
* [#706][]: Fix incorrect call depth to determine caller in Go 1.12.

Enhancements:
* [#610][]: Add `zaptest.WrapOptions` to wrap `zap.Option` for creating test
  loggers.
* [#675][]: Don't panic when encoding a String field.
* [#704][]: Disable HTML escaping for JSON objects encoded using the
  reflect-based encoder.

Thanks to @iaroslav-ciupin, @lelenanam, @joa, @NWilson for their contributions
to this release.

[#657]: https://github.com/uber-go/zap/pull/657
[#706]: https://github.com/uber-go/zap/pull/706
[#610]: https://github.com/uber-go/zap/pull/610
[#675]: https://github.com/uber-go/zap/pull/675
[#704]: https://github.com/uber-go/zap/pull/704

## 1.9.1 (06 Aug 2018)

Bugfixes:

* [#614][]: MapObjectEncoder should not ignore empty slices.

[#614]: https://github.com/uber-go/zap/pull/614

## 1.9.0 (19 Jul 2018)

Enhancements:
* [#602][]: Reduce number of allocations when logging with reflection.
* [#572][], [#606][]: Expose a registry for third-party logging sinks.

Thanks to @nfarah86, @AlekSi, @JeanMertz, @philippgille, @etsangsplk, and
@dimroc for their contributions to this release.

[#602]: https://github.com/uber-go/zap/pull/602
[#572]: https://github.com/uber-go/zap/pull/572
[#606]: https://github.com/uber-go/zap/pull/606

## 1.8.0 (13 Apr 2018)

Enhancements:
* [#508][]: Make log level configurable when redirecting the standard
  library's logger.
* [#518][]: Add a logger that writes to a `*testing.TB`.
* [#577][]: Add a top-level alias for `zapcore.Field` to clean up GoDoc.

Bugfixes:
* [#574][]: Add a missing import comment to `go.uber.org/zap/buffer`.

Thanks to @DiSiqueira and @djui for their contributions to this release.

[#508]: https://github.com/uber-go/zap/pull/508
[#518]: https://github.com/uber-go/zap/pull/518
[#577]: https://github.com/uber-go/zap/pull/577
[#574]: https://github.com/uber-go/zap/pull/574

## 1.7.1 (25 Sep 2017)

Bugfixes:
* [#504][]: Store strings when using AddByteString with the map encoder.

[#504]: https://github.com/uber-go/zap/pull/504

## 1.7.0 (21 Sep 2017)

Enhancements:

* [#487][]: Add `NewStdLogAt`, which extends `NewStdLog` by allowing the user
  to specify the level of the logged messages.

[#487]: https://github.com/uber-go/zap/pull/487

## 1.6.0 (30 Aug 2017)

Enhancements:

* [#491][]: Omit zap stack frames from stacktraces.
* [#490][]: Add a `ContextMap` method to observer logs for simpler
  field validation in tests.

[#490]: https://github.com/uber-go/zap/pull/490
[#491]: https://github.com/uber-go/zap/pull/491

## 1.5.0 (22 Jul 2017)

Enhancements:

* [#460][] and [#470][]: Support errors produced by `go.uber.org/multierr`.
* [#465][]: Support user-supplied encoders for logger names.

Bugfixes:

* [#477][]: Fix a bug that incorrectly truncated deep stacktraces.

Thanks to @richard-tunein and @pavius for their contributions to this release.

[#477]: https://github.com/uber-go/zap/pull/477
[#465]: https://github.com/uber-go/zap/pull/465
[#460]: https://github.com/uber-go/zap/pull/460
[#470]: https://github.com/uber-go/zap/pull/470

## 1.4.1 (08 Jun 2017)

This release fixes two bugs.

Bugfixes:

* [#435][]: Support a variety of case conventions when unmarshaling levels.
* [#444][]: Fix a panic in the observer.

[#435]: https://github.com/uber-go/zap/pull/435
[#444]: https://github.com/uber-go/zap/pull/444

## 1.4.0 (12 May 2017)

This release adds a few small features and is fully backward-compatible.

Enhancements:

* [#424][]: Add a `LineEnding` field to `EncoderConfig`, allowing users to
  override the Unix-style default.
* [#425][]: Preserve time zones when logging times.
* [#431][]: Make `zap.AtomicLevel` implement `fmt.Stringer`, which makes a
  variety of operations a bit simpler.

[#424]: https://github.com/uber-go/zap/pull/424
[#425]: https://github.com/uber-go/zap/pull/425
[#431]: https://github.com/uber-go/zap/pull/431

## 1.3.0 (25 Apr 2017)

This release adds an enhancement to zap's testing helpers as well as the
ability to marshal an AtomicLevel. It is fully backward-compatible.

Enhancements:

* [#415][]: Add a substring-filtering helper to zap's observer. This is
  particularly useful when testing the `SugaredLogger`.
* [#416][]: Make `AtomicLevel` implement `encoding.TextMarshaler`.

[#415]: https://github.com/uber-go/zap/pull/415
[#416]: https://github.com/uber-go/zap/pull/416

## 1.2.0 (13 Apr 2017)

This release adds a gRPC compatibility wrapper. It is fully backward-compatible.

Enhancements:

* [#402][]: Add a `zapgrpc` package that wraps zap's Logger and implements
  `grpclog.Logger`.

[#402]: https://github.com/uber-go/zap/pull/402

## 1.1.0 (31 Mar 2017)

This release fixes two bugs and adds some enhancements to zap's testing helpers.
It is fully backward-compatible.

Bugfixes:

* [#385][]: Fix caller path trimming on Windows.
* [#396][]: Fix a panic when attempting to use non-existent directories with
  zap's configuration struct.

Enhancements:

* [#386][]: Add filtering helpers to zaptest's observing logger.

Thanks to @moitias for contributing to this release.

[#385]: https://github.com/uber-go/zap/pull/385
[#396]: https://github.com/uber-go/zap/pull/396
[#386]: https://github.com/uber-go/zap/pull/386

## 1.0.0 (14 Mar 2017)

This is zap's first stable release. All exported APIs are now final, and no
further breaking changes will be made in the 1.x release series. Anyone using a
semver-aware dependency manager should now pin to `^1`.

Breaking changes:

* [#366][]: Add byte-oriented APIs to encoders to log UTF-8 encoded text without
  casting from `[]byte` to `string`.
* [#364][]: To support buffering outputs, add `Sync` methods to `zapcore.Core`,
  `zap.Logger`, and `zap.SugaredLogger`.
* [#371][]: Rename the `testutils` package to `zaptest`, which is less likely to
  clash with other testing helpers.

Bugfixes:

* [#362][]: Make the ISO8601 time formatters fixed-width, which is friendlier
  for tab-separated console output.
* [#369][]: Remove the automatic locks in `zapcore.NewCore`, which allows zap to
  work with concurrency-safe `WriteSyncer` implementations.
* [#347][]: Stop reporting errors when trying to `fsync` standard out on Linux
  systems.
* [#373][]: Report the correct caller from zap's standard library
  interoperability wrappers.

Enhancements:

* [#348][]: Add a registry allowing third-party encodings to work with zap's
  built-in `Config`.
* [#327][]: Make the representation of logger callers configurable (like times,
  levels, and durations).
* [#376][]: Allow third-party encoders to use their own buffer pools, which
  removes the last performance advantage that zap's encoders have over plugins.
* [#346][]: Add `CombineWriteSyncers`, a convenience function to tee multiple
  `WriteSyncer`s and lock the result.
* [#365][]: Make zap's stacktraces compatible with mid-stack inlining (coming in
  Go 1.9).
* [#372][]: Export zap's observing logger as `zaptest/observer`. This makes it
  easier for particularly punctilious users to unit test their application's
  logging.

Thanks to @suyash, @htrendev, @flisky, @Ulexus, and @skipor for their
contributions to this release.

[#366]: https://github.com/uber-go/zap/pull/366
[#364]: https://github.com/uber-go/zap/pull/364
[#371]: https://github.com/uber-go/zap/pull/371
[#362]: https://github.com/uber-go/zap/pull/362
[#369]: https://github.com/uber-go/zap/pull/369
[#347]: https://github.com/uber-go/zap/pull/347
[#373]: https://github.com/uber-go/zap/pull/373
[#348]: https://github.com/uber-go/zap/pull/348
[#327]: https://github.com/uber-go/zap/pull/327
[#376]: https://github.com/uber-go/zap/pull/376
[#346]: https://github.com/uber-go/zap/pull/346
[#365]: https://github.com/uber-go/zap/pull/365
[#372]: https://github.com/uber-go/zap/pull/372

## 1.0.0-rc.3 (7 Mar 2017)

This is the third release candidate for zap's stable release. There are no
breaking changes.

Bugfixes:

* [#339][]: Byte slices passed to `zap.Any` are now correctly treated as binary blobs
  rather than `[]uint8`.

Enhancements:

* [#307][]: Users can opt into colored output for log levels.
* [#353][]: In addition to hijacking the output of the standard library's
  package-global logging functions, users can now construct a zap-backed
  `log.Logger` instance.
* [#311][]: Frames from common runtime functions and some of zap's internal
  machinery are now omitted from stacktraces.

Thanks to @ansel1 and @suyash for their contributions to this release.

[#339]: https://github.com/uber-go/zap/pull/339
[#307]: https://github.com/uber-go/zap/pull/307
[#353]: https://github.com/uber-go/zap/pull/353
[#311]: https://github.com/uber-go/zap/pull/311

## 1.0.0-rc.2 (21 Feb 2017)

This is the second release candidate for zap's stable release. It includes two
breaking changes.

Breaking changes:

* [#316][]: Zap's global loggers are now fully concurrency-safe
  (previously, users had to ensure that `ReplaceGlobals` was called before the
  loggers were in use). However, they must now be accessed via the `L()` and
  `S()` functions. Users can update their projects with

  ```
  gofmt -r "zap.L -> zap.L()" -w .
  gofmt -r "zap.S -> zap.S()" -w .
  ```
* [#309][] and [#317][]: RC1 was mistakenly shipped with invalid
  JSON and YAML struct tags on all config structs. This release fixes the tags
  and adds static analysis to prevent similar bugs in the future.

Bugfixes:

* [#321][]: Redirecting the standard library's `log` output now
  correctly reports the logger's caller.

Enhancements:

* [#325][] and [#333][]: Zap now transparently supports non-standard, rich
  errors like those produced by `github.com/pkg/errors`.
* [#326][]: Though `New(nil)` continues to return a no-op logger, `NewNop()` is
  now preferred. Users can update their projects with `gofmt -r 'zap.New(nil) ->
  zap.NewNop()' -w .`.
* [#300][]: Incorrectly importing zap as `github.com/uber-go/zap` now returns a
  more informative error.

Thanks to @skipor and @chapsuk for their contributions to this release.

[#316]: https://github.com/uber-go/zap/pull/316
[#309]: https://github.com/uber-go/zap/pull/309
[#317]: https://github.com/uber-go/zap/pull/317
[#321]: https://github.com/uber-go/zap/pull/321
[#325]: https://github.com/uber-go/zap/pull/325
[#333]: https://github.com/uber-go/zap/pull/333
[#326]: https://github.com/uber-go/zap/pull/326
[#300]: https://github.com/uber-go/zap/pull/300

## 1.0.0-rc.1 (14 Feb 2017)

This is the first release candidate for zap's stable release. There are multiple
breaking changes and improvements from the pre-release version. Most notably:

* **Zap's import path is now "go.uber.org/zap"** — all users will
  need to update their code.
* User-facing types and functions remain in the `zap` package. Code relevant
  largely to extension authors is now in the `zapcore` package.
* The `zapcore.Core` type makes it easy for third-party packages to use zap's
  internals but provide a different user-facing API.
* `Logger` is now a concrete type instead of an interface.
* A less verbose (though slower) logging API is included by default.
* Package-global loggers `L` and `S` are included.
* A human-friendly console encoder is included.
* A declarative config struct allows common logger configurations to be managed
  as configuration instead of code.
* Sampling is more accurate, and doesn't depend on the standard library's shared
  timer heap.

## 0.1.0-beta.1 (6 Feb 2017)

This is a minor version, tagged to allow users to pin to the pre-1.0 APIs and
upgrade at their leisure. Since this is the first tagged release, there are no
backward compatibility concerns and all functionality is new.

Early zap adopters should pin to the 0.1.x minor version until they're ready to
upgrade to the upcoming stable release.


# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age,
body size, disability, ethnicity, gender identity and expression, level of
experience, nationality, personal appearance, race, religion, or sexual
identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment
include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or
  advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
  address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an
appointed representative at an online or offline event. Representation of a
project may be further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at oss-conduct@uber.com. The project
team will review and investigate all complaints, and will respond in a way
that it deems appropriate to the circumstances. The project team is obligated
to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 1.4, available at
[http://contributor-covenant.org/version/1/4][version].

[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/


# Contributing

We'd love your help making zap the very best structured logging library in Go!

If you'd like to add new exported APIs, please [open an issue][open-issue]
describing your proposal — discussing API changes ahead of time makes
pull request review much smoother. In your issue, pull request, and any other
communications, please remember to treat your fellow contributors with
respect! We take our [code of conduct](CODE_OF_CONDUCT.md) seriously.

Note that you'll need to sign [Uber's Contributor License Agreement][cla]
before we can accept any of your contributions. If necessary, a bot will remind
you to accept the CLA when you open your pull request.

## Setup

[Fork][fork], then clone the repository:

```bash
mkdir -p $GOPATH/src/go.uber.org
cd $GOPATH/src/go.uber.org
git clone git@github.com:your_github_username/zap.git
cd zap
git remote add upstream https://github.com/uber-go/zap.git
git fetch upstream
```

Make sure that the tests and the linters pass:

```bash
make test
make lint
```

## Making Changes

Start by creating a new branch for your changes:

```bash
cd $GOPATH/src/go.uber.org/zap
git checkout master
git fetch upstream
git rebase upstream/master
git checkout -b cool_new_feature
```

Make your changes, then ensure that `make lint` and `make test` still pass. If
you're satisfied with your changes, push them to your fork.

```bash
git push origin cool_new_feature
```

Then use the GitHub UI to open a pull request.

At this point, you're waiting on us to review your changes. We _try_ to respond
to issues and pull requests within a few business days, and we may suggest some
improvements or alternatives. Once your changes are approved, one of the
project maintainers will merge them.

We're much more likely to approve your changes if you:

- Add tests for new functionality.
- Write a [good commit message][commit-message].
- Maintain backward compatibility.

[fork]: https://github.com/uber-go/zap/fork
[open-issue]: https://github.com/uber-go/zap/issues/new
[cla]: https://cla-assistant.io/uber-go/zap
[commit-message]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html


# :zap: zap

Blazing fast, structured, leveled logging in Go.

![Zap logo](assets/logo.png)

[![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov]

## Installation

`go get -u go.uber.org/zap`

Note that zap only supports the two most recent minor versions of Go.

## Quick Start

In contexts where performance is nice, but not critical, use the
`SugaredLogger`. It's 4-10x faster than other structured logging
packages and includes both structured and `printf`-style APIs.

```go
logger, _ := zap.NewProduction()
defer logger.Sync() // flushes buffer, if any
sugar := logger.Sugar()
sugar.Infow("failed to fetch URL",
  // Structured context as loosely typed key-value pairs.
  "url", url,
  "attempt", 3,
  "backoff", time.Second,
)
sugar.Infof("Failed to fetch URL: %s", url)
```

When performance and type safety are critical, use the `Logger`. It's even
faster than the `SugaredLogger` and allocates far less, but it only supports
structured logging.

```go
logger, _ := zap.NewProduction()
defer logger.Sync()
logger.Info("failed to fetch URL",
  // Structured context as strongly typed Field values.
  zap.String("url", url),
  zap.Int("attempt", 3),
  zap.Duration("backoff", time.Second),
)
```

See the [documentation][doc] and [FAQ](FAQ.md) for more details.

## Performance

For applications that log in the hot path, reflection-based serialization and
string formatting are prohibitively expensive — they're CPU-intensive
and make many small allocations. Put differently, using `encoding/json` and
`fmt.Fprintf` to log tons of `interface{}`s makes your application slow.

Zap takes a different approach. It includes a reflection-free, zero-allocation
JSON encoder, and the base `Logger` strives to avoid serialization overhead
and allocations wherever possible. By building the high-level `SugaredLogger`
on that foundation, zap lets users *choose* when they need to count every
allocation and when they'd prefer a more familiar, loosely typed API.

As measured by its own [benchmarking suite][], not only is zap more performant
than comparable structured logging packages — it's also faster than the
standard library. Like all benchmarks, take these with a grain of salt.[1](#footnote-versions)

Log a message and 10 fields:

| Package | Time | Time % to zap | Objects Allocated |
| :------ | :--: | :-----------: | :---------------: |
| :zap: zap | 656 ns/op | +0% | 5 allocs/op
| :zap: zap (sugared) | 935 ns/op | +43% | 10 allocs/op
| zerolog | 380 ns/op | -42% | 1 allocs/op
| go-kit | 2249 ns/op | +243% | 57 allocs/op
| slog (LogAttrs) | 2479 ns/op | +278% | 40 allocs/op
| slog | 2481 ns/op | +278% | 42 allocs/op
| apex/log | 9591 ns/op | +1362% | 63 allocs/op
| log15 | 11393 ns/op | +1637% | 75 allocs/op
| logrus | 11654 ns/op | +1677% | 79 allocs/op

Log a message with a logger that already has 10 fields of context:

| Package | Time | Time % to zap | Objects Allocated |
| :------ | :--: | :-----------: | :---------------: |
| :zap: zap | 67 ns/op | +0% | 0 allocs/op
| :zap: zap (sugared) | 84 ns/op | +25% | 1 allocs/op
| zerolog | 35 ns/op | -48% | 0 allocs/op
| slog | 193 ns/op | +188% | 0 allocs/op
| slog (LogAttrs) | 200 ns/op | +199% | 0 allocs/op
| go-kit | 2460 ns/op | +3572% | 56 allocs/op
| log15 | 9038 ns/op | +13390% | 70 allocs/op
| apex/log | 9068 ns/op | +13434% | 53 allocs/op
| logrus | 10521 ns/op | +15603% | 68 allocs/op

Log a static string, without any context or `printf`-style templating:

| Package | Time | Time % to zap | Objects Allocated |
| :------ | :--: | :-----------: | :---------------: |
| :zap: zap | 63 ns/op | +0% | 0 allocs/op
| :zap: zap (sugared) | 81 ns/op | +29% | 1 allocs/op
| zerolog | 32 ns/op | -49% | 0 allocs/op
| standard library | 124 ns/op | +97% | 1 allocs/op
| slog | 196 ns/op | +211% | 0 allocs/op
| slog (LogAttrs) | 200 ns/op | +217% | 0 allocs/op
| go-kit | 213 ns/op | +238% | 9 allocs/op
| apex/log | 771 ns/op | +1124% | 5 allocs/op
| logrus | 1439 ns/op | +2184% | 23 allocs/op
| log15 | 2069 ns/op | +3184% | 20 allocs/op

## Development Status: Stable

All APIs are finalized, and no breaking changes will be made in the 1.x series
of releases. Users of semver-aware dependency management systems should pin
zap to `^1`.

## Contributing

We encourage and support an active, healthy community of contributors —
including you! Details are in the [contribution guide](CONTRIBUTING.md) and
the [code of conduct](CODE_OF_CONDUCT.md). The zap maintainers keep an eye on
issues and pull requests, but you can also report any negative conduct to
oss-conduct@uber.com. That email list is a private, safe space; even the zap
maintainers don't have access, so don't hesitate to hold us to a high
standard.

Released under the [MIT License](LICENSE).

1 In particular, keep in mind that we may be
benchmarking against slightly older versions of other packages. Versions are
pinned in the [benchmarks/go.mod][] file. [↩](#anchor-versions)

[doc-img]: https://pkg.go.dev/badge/go.uber.org/zap
[doc]: https://pkg.go.dev/go.uber.org/zap
[ci-img]: https://github.com/uber-go/zap/actions/workflows/go.yml/badge.svg
[ci]: https://github.com/uber-go/zap/actions/workflows/go.yml
[cov-img]: https://codecov.io/gh/uber-go/zap/branch/master/graph/badge.svg
[cov]: https://codecov.io/gh/uber-go/zap
[benchmarking suite]: https://github.com/uber-go/zap/tree/master/benchmarks
[benchmarks/go.mod]: https://github.com/uber-go/zap/blob/master/benchmarks/go.mod


# hasql

[![PkgGoDev](https://pkg.go.dev/badge/golang.yandex/hasql)](https://pkg.go.dev/golang.yandex/hasql)
[![GoDoc](https://godoc.org/golang.yandex/hasql?status.svg)](https://godoc.org/golang.yandex/hasql)
![tests](https://github.com/yandex/go-hasql/workflows/tests/badge.svg?branch=master)
![lint](https://github.com/yandex/go-hasql/workflows/lint/badge.svg?branch=master)
[![Go Report Card](https://goreportcard.com/badge/golang.yandex/hasql)](https://goreportcard.com/report/golang.yandex/hasql)
[![codecov](https://codecov.io/gh/yandex/go-hasql/branch/master/graph/badge.svg)](https://codecov.io/gh/yandex/go-hasql)

`hasql` provides simple and reliable way to access high-availability database setups with multiple hosts.

## Status
`hasql` is production-ready and is actively used inside Yandex' production environment.

## Prerequisites

- **[Go](https://golang.org)**: any one of the **two latest major** [releases](https://golang.org/doc/devel/release.html).

## Installation

With [Go module](https://github.com/golang/go/wiki/Modules) support, simply add the following import

```go
import "golang.yandex/hasql"
```

to your code, and then `go [build|run|test]` will automatically fetch the
necessary dependencies.

Otherwise, to install the `hasql` package, run the following command:

```console
$ go get -u golang.yandex/hasql
```

## How does it work
`hasql` operates using standard `database/sql` connection pool objects. User creates `*sql.DB` objects for each node of database cluster and passes them to constructor. Library keeps up to date information on state of each node by 'pinging' them periodically. User is provided with a set of interfaces to retrieve `*sql.DB` object suitable for required operation.

```go
dbFoo, _ := sql.Open("pgx", "host=foo")
dbBar, _ := sql.Open("pgx", "host=bar")
cl, err := hasql.NewCluster(
    []hasql.Node{hasql.NewNode("foo", dbFoo), hasql.NewNode("bar", dbBar) },
    checkers.PostgreSQL,
)
if err != nil { ... }

node := cl.Primary()
if node == nil {
    err := cl.Err() // most recent errors for all nodes in the cluster
}

// Do anything you like
fmt.Println("Node address", node.Addr)

ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
if err = node.DB().PingContext(ctx); err != nil { ... }
```

`hasql` does not configure provided connection pools in any way. It is user's job to set them up properly. Library does handle their lifetime though - pools are closed when `Cluster` object is closed.

### Supported criteria
_Alive primary_|_Alive standby_|_Any alive_ node, or _none_ otherwise
```go
node := c.Primary()
if node == nil { ... }
```

_Alive primary_|_Alive standby_, or _any alive_ node, or _none_ otherwise
```go
node := c.PreferPrimary()
if node == nil { ... }
```

### Ways of accessing nodes
Any of _currently alive_ nodes _satisfying criteria_, or _none_ otherwise
```go
node := c.Primary()
if node == nil { ... }
```

Any of _currently alive_ nodes _satisfying criteria_, or _wait_ for one to become _alive_
```go
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
node, err := c.WaitForPrimary(ctx)
if err == nil { ... }
```

### Node pickers
When user asks `Cluster` object for a node a random one from a list of suitable nodes is returned. User can override this behavior by providing a custom node picker.

Library provides a couple of predefined pickers. For example if user wants 'closest' node (with lowest latency) `PickNodeClosest` picker should be used.

```go
cl, err := hasql.NewCluster(
    []hasql.Node{hasql.NewNode("foo", dbFoo), hasql.NewNode("bar", dbBar) },
    checkers.PostgreSQL,
    hasql.WithNodePicker(hasql.PickNodeClosest()),
)
if err != nil { ... }
```

## Supported databases
Since library works over standard `database/sql` it supports any database that has a `database/sql` driver. All it requires is a database-specific checker function that can tell if node is primary or standby.

Check out `golang.yandex/hasql/checkers` package for more information.

### Caveats
Node's state is transient at any given time. If `Primary()` returns a node it does not mean that node is still primary when you execute statement on it. All it means is that it was primary when it was last checked. Nodes can change their state at a whim or even go offline and `hasql` can't control it in any manner.

This is one of the reasons why nodes do not expose their perceived state to user.

## Extensions
### Instrumentation
You can add instrumentation via `Tracer` object similar to [httptrace](https://godoc.org/net/http/httptrace) in standard library.

### sqlx
`hasql` can operate over `database/sql` pools wrapped with [sqlx](https://github.com/jmoiron/sqlx). It works the same as with standard library but requires user to import `golang.yandex/hasql/sqlx` instead.

Refer to `golang.yandex/hasql/sqlx` package for more information.


# How to contribute

We definitely welcome your patches and contributions to gRPC! Please read the gRPC
organization's [governance rules](https://github.com/grpc/grpc-community/blob/master/governance.md)
and [contribution guidelines](https://github.com/grpc/grpc-community/blob/master/CONTRIBUTING.md) before proceeding.

If you are new to github, please start by reading [Pull Request howto](https://help.github.com/articles/about-pull-requests/)

## Legal requirements

In order to protect both you and ourselves, you will need to sign the
[Contributor License Agreement](https://identity.linuxfoundation.org/projects/cncf).

## Guidelines for Pull Requests
How to get your contributions merged smoothly and quickly.

- Create **small PRs** that are narrowly focused on **addressing a single
  concern**. We often times receive PRs that are trying to fix several things at
  a time, but only one fix is considered acceptable, nothing gets merged and
  both author's & review's time is wasted. Create more PRs to address different
  concerns and everyone will be happy.

- If you are searching for features to work on, issues labeled [Status: Help
  Wanted](https://github.com/grpc/grpc-go/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22Status%3A+Help+Wanted%22)
  is a great place to start. These issues are well-documented and usually can be
  resolved with a single pull request.

- If you are adding a new file, make sure it has the copyright message template
  at the top as a comment. You can copy over the message from an existing file
  and update the year.

- The grpc package should only depend on standard Go packages and a small number
  of exceptions. If your contribution introduces new dependencies which are NOT
  in the [list](https://godoc.org/google.golang.org/grpc?imports), you need a
  discussion with gRPC-Go authors and consultants.

- For speculative changes, consider opening an issue and discussing it first. If
  you are suggesting a behavioral or API change, consider starting with a [gRFC
  proposal](https://github.com/grpc/proposal).

- Provide a good **PR description** as a record of **what** change is being made
  and **why** it was made. Link to a github issue if it exists.

- If you want to fix formatting or style, consider whether your changes are an
  obvious improvement or might be considered a personal preference. If a style
  change is based on preference, it likely will not be accepted. If it corrects
  widely agreed-upon anti-patterns, then please do create a PR and explain the
  benefits of the change.

- Unless your PR is trivial, you should expect there will be reviewer comments
  that you'll need to address before merging. We'll mark it as `Status: Requires
  Reporter Clarification` if we expect you to respond to these comments in a
  timely manner. If the PR remains inactive for 6 days, it will be marked as
  `stale` and automatically close 7 days after that if we don't hear back from
  you.

- Maintain **clean commit history** and use **meaningful commit messages**. PRs
  with messy commit history are difficult to review and won't be merged. Use
  `rebase -i upstream/master` to curate your commit history and/or to bring in
  latest changes from master (but avoid rebasing in the middle of a code
  review).

- Keep your PR up to date with upstream/master (if there are merge conflicts, we
  can't really merge your change).

- **All tests need to be passing** before your change can be merged. We
  recommend you **run tests locally** before creating your PR to catch breakages
  early on.
  - `VET_SKIP_PROTO=1 ./vet.sh` to catch vet errors
  - `go test -cpu 1,4 -timeout 7m ./...` to run the tests
  - `go test -race -cpu 1,4 -timeout 7m ./...` to run tests in race mode

- Exceptions to the rules can be made if there's a compelling reason for doing so.


# gRPC-Go

[![GoDoc](https://pkg.go.dev/badge/google.golang.org/grpc)][API]
[![GoReportCard](https://goreportcard.com/badge/grpc/grpc-go)](https://goreportcard.com/report/github.com/grpc/grpc-go)
[![codecov](https://codecov.io/gh/grpc/grpc-go/graph/badge.svg)](https://codecov.io/gh/grpc/grpc-go)

The [Go][] implementation of [gRPC][]: A high performance, open source, general
RPC framework that puts mobile and HTTP/2 first. For more information see the
[Go gRPC docs][], or jump directly into the [quick start][].

## Prerequisites

- **[Go][]**: any one of the **three latest major** [releases][go-releases].

## Installation

Simply add the following import to your code, and then `go [build|run|test]`
will automatically fetch the necessary dependencies:

```go
import "google.golang.org/grpc"
```

> **Note:** If you are trying to access `grpc-go` from **China**, see the
> [FAQ](#FAQ) below.

## Learn more

- [Go gRPC docs][], which include a [quick start][] and [API
  reference][API] among other resources
- [Low-level technical docs](Documentation) from this repository
- [Performance benchmark][]
- [Examples](examples)

## FAQ

### I/O Timeout Errors

The `golang.org` domain may be blocked from some countries. `go get` usually
produces an error like the following when this happens:

```console
$ go get -u google.golang.org/grpc
package google.golang.org/grpc: unrecognized import path "google.golang.org/grpc" (https fetch: Get https://google.golang.org/grpc?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)
```

To build Go code, there are several options:

- Set up a VPN and access google.golang.org through that.

- With Go module support: it is possible to use the `replace` feature of `go
  mod` to create aliases for golang.org packages.  In your project's directory:

  ```sh
  go mod edit -replace=google.golang.org/grpc=github.com/grpc/grpc-go@latest
  go mod tidy
  go mod vendor
  go build -mod=vendor
  ```

  Again, this will need to be done for all transitive dependencies hosted on
  golang.org as well. For details, refer to [golang/go issue
  #28652](https://github.com/golang/go/issues/28652).

### Compiling error, undefined: grpc.SupportPackageIsVersion

Please update to the latest version of gRPC-Go using
`go get google.golang.org/grpc`.

### How to turn on logging

The default logger is controlled by environment variables. Turn everything on
like this:

```console
$ export GRPC_GO_LOG_VERBOSITY_LEVEL=99
$ export GRPC_GO_LOG_SEVERITY_LEVEL=info
```

### The RPC failed with error `"code = Unavailable desc = transport is closing"`

This error means the connection the RPC is using was closed, and there are many
possible reasons, including:
 1. mis-configured transport credentials, connection failed on handshaking
 1. bytes disrupted, possibly by a proxy in between
 1. server shutdown
 1. Keepalive parameters caused connection shutdown, for example if you have
    configured your server to terminate connections regularly to [trigger DNS
    lookups](https://github.com/grpc/grpc-go/issues/3170#issuecomment-552517779).
    If this is the case, you may want to increase your
    [MaxConnectionAgeGrace](https://pkg.go.dev/google.golang.org/grpc/keepalive?tab=doc#ServerParameters),
    to allow longer RPC calls to finish.

It can be tricky to debug this because the error happens on the client side but
the root cause of the connection being closed is on the server side. Turn on
logging on __both client and server__, and see if there are any transport
errors.

[API]: https://pkg.go.dev/google.golang.org/grpc
[Go]: https://golang.org
[Go module]: https://github.com/golang/go/wiki/Modules
[gRPC]: https://grpc.io
[Go gRPC docs]: https://grpc.io/docs/languages/go
[Performance benchmark]: https://performance-dot-grpc-testing.appspot.com/explore?dashboard=5180705743044608
[quick start]: https://grpc.io/docs/languages/go/quickstart
[go-releases]: https://golang.org/doc/devel/release.html


Instructions
============

Install the package with:

    go get gopkg.in/check.v1

Import it with:

    import "gopkg.in/check.v1"

and use _check_ as the package name inside the code.

For more details, visit the project page:

* http://labix.org/gocheck

and the API documentation:

* https://gopkg.in/check.v1


# YAML support for the Go language

Introduction
------------

The yaml package enables Go programs to comfortably encode and decode YAML
values. It was developed within [Canonical](https://www.canonical.com) as
part of the [juju](https://juju.ubuntu.com) project, and is based on a
pure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML)
C library to parse and generate YAML data quickly and reliably.

Compatibility
-------------

The yaml package supports most of YAML 1.1 and 1.2, including support for
anchors, tags, map merging, etc. Multi-document unmarshalling is not yet
implemented, and base-60 floats from YAML 1.1 are purposefully not
supported since they're a poor design and are gone in YAML 1.2.

Installation and usage
----------------------

The import path for the package is *gopkg.in/yaml.v2*.

To install it, run:

    go get gopkg.in/yaml.v2

API documentation
-----------------

If opened in a browser, the import path itself leads to the API documentation:

  * [https://gopkg.in/yaml.v2](https://gopkg.in/yaml.v2)

API stability
-------------

The package API for yaml v2 will remain stable as described in [gopkg.in](https://gopkg.in).

License
-------

The yaml package is licensed under the Apache License 2.0. Please see the LICENSE file for details.

Example
-------

```Go
package main

import (
        "fmt"
        "log"

        "gopkg.in/yaml.v2"
)

var data = `
a: Easy!
b:
  c: 2
  d: [3, 4]
`

// Note: struct fields must be public in order for unmarshal to
// correctly populate the data.
type T struct {
        A string
        B struct {
                RenamedC int   `yaml:"c"`
                D        []int `yaml:",flow"`
        }
}

func main() {
        t := T{}

        err := yaml.Unmarshal([]byte(data), &t)
        if err != nil {
                log.Fatalf("error: %v", err)
        }
        fmt.Printf("--- t:\n%v\n\n", t)

        d, err := yaml.Marshal(&t)
        if err != nil {
                log.Fatalf("error: %v", err)
        }
        fmt.Printf("--- t dump:\n%s\n\n", string(d))

        m := make(map[interface{}]interface{})

        err = yaml.Unmarshal([]byte(data), &m)
        if err != nil {
                log.Fatalf("error: %v", err)
        }
        fmt.Printf("--- m:\n%v\n\n", m)

        d, err = yaml.Marshal(&m)
        if err != nil {
                log.Fatalf("error: %v", err)
        }
        fmt.Printf("--- m dump:\n%s\n\n", string(d))
}
```

This example will generate the following output:

```
--- t:
{Easy! {2 [3 4]}}

--- t dump:
a: Easy!
b:
  c: 2
  d: [3, 4]

--- m:
map[a:Easy! b:map[c:2 d:[3 4]]]

--- m dump:
a: Easy!
b:
  c: 2
  d:
  - 3
  - 4
```


# YAML support for the Go language

Introduction
------------

The yaml package enables Go programs to comfortably encode and decode YAML
values. It was developed within [Canonical](https://www.canonical.com) as
part of the [juju](https://juju.ubuntu.com) project, and is based on a
pure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML)
C library to parse and generate YAML data quickly and reliably.

Compatibility
-------------

The yaml package supports most of YAML 1.2, but preserves some behavior
from 1.1 for backwards compatibility.

Specifically, as of v3 of the yaml package:

 - YAML 1.1 bools (_yes/no, on/off_) are supported as long as they are being
   decoded into a typed bool value. Otherwise they behave as a string. Booleans
   in YAML 1.2 are _true/false_ only.
 - Octals encode and decode as _0777_ per YAML 1.1, rather than _0o777_
   as specified in YAML 1.2, because most parsers still use the old format.
   Octals in the  _0o777_ format are supported though, so new files work.
 - Does not support base-60 floats. These are gone from YAML 1.2, and were
   actually never supported by this package as it's clearly a poor choice.

and offers backwards
compatibility with YAML 1.1 in some cases.
1.2, including support for
anchors, tags, map merging, etc. Multi-document unmarshalling is not yet
implemented, and base-60 floats from YAML 1.1 are purposefully not
supported since they're a poor design and are gone in YAML 1.2.

Installation and usage
----------------------

The import path for the package is *gopkg.in/yaml.v3*.

To install it, run:

    go get gopkg.in/yaml.v3

API documentation
-----------------

If opened in a browser, the import path itself leads to the API documentation:

  - [https://gopkg.in/yaml.v3](https://gopkg.in/yaml.v3)

API stability
-------------

The package API for yaml v3 will remain stable as described in [gopkg.in](https://gopkg.in).

License
-------

The yaml package is licensed under the MIT and Apache License 2.0 licenses.
Please see the LICENSE file for details.

Example
-------

```Go
package main

import (
        "fmt"
        "log"

        "gopkg.in/yaml.v3"
)

var data = `
a: Easy!
b:
  c: 2
  d: [3, 4]
`

// Note: struct fields must be public in order for unmarshal to
// correctly populate the data.
type T struct {
        A string
        B struct {
                RenamedC int   `yaml:"c"`
                D        []int `yaml:",flow"`
        }
}

func main() {
        t := T{}

        err := yaml.Unmarshal([]byte(data), &t)
        if err != nil {
                log.Fatalf("error: %v", err)
        }
        fmt.Printf("--- t:\n%v\n\n", t)

        d, err := yaml.Marshal(&t)
        if err != nil {
                log.Fatalf("error: %v", err)
        }
        fmt.Printf("--- t dump:\n%s\n\n", string(d))

        m := make(map[interface{}]interface{})

        err = yaml.Unmarshal([]byte(data), &m)
        if err != nil {
                log.Fatalf("error: %v", err)
        }
        fmt.Printf("--- m:\n%v\n\n", m)

        d, err = yaml.Marshal(&m)
        if err != nil {
                log.Fatalf("error: %v", err)
        }
        fmt.Printf("--- m dump:\n%s\n\n", string(d))
}
```

This example will generate the following output:

```
--- t:
{Easy! {2 [3 4]}}

--- t dump:
a: Easy!
b:
  c: 2
  d: [3, 4]

--- m:
map[a:Easy! b:map[c:2 d:[3 4]]]

--- m dump:
a: Easy!
b:
  c: 2
  d:
  - 3
  - 4
```


# libc

Package libc provides C-runtime services. Work in progress.

This package is a continuation of the Crt package in modernc.org/crt/v3.

Installation

    $ go get [-u] modernc.org/libc

Documentation: [godoc.org/modernc.org/libc](http://godoc.org/modernc.org/libc)

Building with `make` requires the following Go packages

* github.com/golang/lint/golint
* github.com/mdempsky/maligned
* github.com/mdempsky/unconvert
* honnef.co/go/tools/cmd/unused
* honnef.co/go/tools/cmd/gosimple
* github.com/client9/misspell/cmd/misspell


# memory

Package memory implements a memory allocator.

## Build status

available at https://modern-c.appspot.com/-/builder/?importpath=modernc.org%2fmemory

Installation

    $ go get modernc.org/memory

Documentation: [godoc.org/modernc.org/memory](http://godoc.org/modernc.org/memory)