diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..394b974f1 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,16 @@ +language: go +go: + - 1.5 + - 1.6 + - tip +env: + global: + - GO15VENDOREXPERIMENT=1 +cache: + directories: + - vendor +install: + - make dependencies +script: + - make coveralls + - make lint diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 000000000..8765c9fbc --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,19 @@ +Copyright (c) 2016 Uber Technologies, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..1a1a65fce --- /dev/null +++ b/Makefile @@ -0,0 +1,41 @@ +export GO15VENDOREXPERIMENT=1 + +BENCH_FLAGS ?= -cpuprofile=cpu.pprof -memprofile=mem.pprof -benchmem +PACKAGES ?= $(shell glide novendor) + +.PHONY: all +all: lint test + +.PHONY: dependencies +dependencies: + glide --version || go get -u -f github.com/Masterminds/glide + glide install + go install ./vendor/github.com/golang/lint/golint + go install ./vendor/github.com/axw/gocov/gocov + go install ./vendor/github.com/mattn/goveralls + +.PHONY: lint +lint: + rm -rf lint.log + @echo "Checking formatting..." + gofmt -d -s *.go benchmarks 2>&1 | tee lint.log + @echo "Checking vet..." + go tool vet *.go 2>&1 | tee -a lint.log + go tool vet benchmarks 2>&1 | tee -a lint.log + @echo "Checking lint..." + golint . 2>&1 | tee -a lint.log + golint benchmarks 2>&1 | tee -a lint.log + @[ ! -s lint.log ] + +.PHONY: test +test: + go test -race $(PACKAGES) + +.PHONY: coveralls +coveralls: + goveralls -service=travis-ci $(PACKAGES) + +.PHONY: bench +BENCH ?= . +bench: + go test -bench=$(BENCH) $(BENCH_FLAGS) ./benchmarks diff --git a/README.md b/README.md new file mode 100644 index 000000000..2e66a6c92 --- /dev/null +++ b/README.md @@ -0,0 +1,73 @@ +# :zap: zap [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] + +Fast, structured, leveled logging in Go. + +## Structure + +Zap takes an opinionated stance on logging and doesn't provide any +`printf`-style helpers. Rather than `logger.Printf("Error %v writing logs to +%v, lost %v messages.", err, f, m)`, flog encourages the more structured + +``` +Logger. + WithError(err). + With("msgCount", m). + With("fileName", f). + Info("Error writing logs.") +``` + +This a bit more verbose, but it enables powerful ad-hoc analysis, flexible +dashboarding, and accurate message bucketing. In short, it helps you get the +most out of tools like ELK, Splunk, and Sentry. All log messages are +JSON-serialized. + +## 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` to log tons +of `interface{}`s makes your application slow. + +Zap's API offers a variety of type-safe ways to annotate a logger's context +without incurring tons of overhead. It also offers a suite of conditional +annotations, so collecting rich debugging context doesn't impact normal +operations. + +As measured by its own benchmarking suite, not only is zap more performant +than comparable structured logging libraries — it's also faster than the +standard library. Like all benchmarks, take these with a grain of salt. + +Add 5 fields to the logging context, one at a time: + +| Library | Time | Bytes Allocated | Objects Allocated | +| :--- | :---: | :---: | ---: | +| zap | 3340 ns/op | 5713 B/op | 16 allocs/op | +| logrus | 66776 ns/op | 52646 B/op | 254 allocs/op | + +Add 5 fields to the logging context as a single map: + +| Library | Time | Bytes Allocated | Objects Allocated | +| :--- | :---: | :---: | ---: | +| zap | 1615 ns/op | 1504 B/op | 6 allocs/op | +| logrus | 36592 ns/op | 21409 B/op | 209 allocs/op | + +Log static strings, without any context or `printf`-style formatting: + +| Library | Time | Bytes Allocated | Objects Allocated | +| :--- | :---: | :---: | ---: | +| zap | 328 ns/op | 32 B/op | 1 allocs/op | +| standard library | 840 ns/op | 592 B/op | 2 allocs/op | + +## Development Status: Alpha + +Breaking changes are certain. + +