zapw

module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Dec 27, 2020 License: Apache-2.0

README

🕵️‍♂️ Zapw

GitHub Actions

Finds common errors for zap using static analysis. Why?

Installation

Run the following command to download and install zapw onto your system:

go get -u github.com/sethvargo/zapw/cmd/zapw

This will make the zapw CLI command available on your machine.

Usage

Zapw does not presently have any flags or customization. Run it against any Go project on your machine:

cd my-project/
zapw ./...

When the tool finds a violation, it reports it using the default analysis output:

/path/to/pkg.go:13:2: zap.SugaredLogger must have an even number of "With" elements
/path/to/pkg.go:19:3: zap.SugaredLogger requires keys to be strings (got int)

See also: caveats.

Why?

Zap is an excellent logger, and I've used it in a variety of projects. When used properly, it's fantastic! When used improperly... you might have a bad day, specifically if you're using the SugaredLogger. That logger provides a really nice interface for adding structured data to log messages without needing to build fields or think about types. It's notably slower (due to the use of reflection), so there's often a tradeoff between dev-time optimization and runtime optimization.

If you do choose to use the SugaredLogger, there's two well-documented caveats which I'll summarize here:

With fields (e.g. With, Debugw, Errorw) accept a mix of loosely-typed key-value pairs. When processing pairs, the first element of the pair is used as the field key and the second as the field value.

  1. Field keys must be strings. In development, passing a non-string key panics. In production, an separate error is logged and execution continues.

    logger.Warnw("oh no", 42, "universe")
                       // ^ invalid, keys must be strings
    
  2. Orphaned keys are invalid. Passing an orphaned key triggers similar behavior: panics in development and errors in production.

    logger.Warn("hello", "world")
                      // ^ invalid, must be key-value pairs (orphaned key)
    

Emphasizing a few items from above:

  1. The system behaves differently in development vs production. This means there's a divergence between what's running on your local machine during coding and what's running in production.

  2. In development, the logger only panics if that line is executed. Without ~100% test coverage, you cannot be absolutely certain the cases described above do not exist in your codebase.

  3. In production, invalid log messages are dropped and an error is logged instead. That means you might be missing critical log information.

To mitigate this, zapw (this project) uses static analysis to find instances of the violations listed above. It's very fast (~1.2s on 2.2M LOC) and can easily be integrated into your CI/CD processes.

Caveats

Zapw only finds instances that meet the following criteria:

  • Function name is a known With function (e.g. With, Debugw, Errorw)

  • Function receiver is go.uber.org/zap.SugaredLogger

Concretely, custom types that embed and expose the logger directly will be found. Custom types that embed the logger privately, or functions that consume the logger, will not be found.

// good
type okEmbed struct {
  *zap.SugaredLogger
}

// bad - zapw will not find misuse of this struct
type badEmbed struct {
  logger *zap.SugaredLogger
}

func (e *badEmbed) Warnw(s string, args ...interface{}) {
  e.logger.Warnw(s, args...)
}

// bad - zapw will not find misuse of this function
func doLog(l *zap.SugaredLogger, s string, args ...interface{}) {
  l.Warnw(s, args...)
}

These problems are both possible to solve, but they dramatically increase the code complexity and runtime of the analysis tool.

License

Copyright 2020 Seth Vargo

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Zapw is not affiliated with the zap project.

Directories

Path Synopsis
cmd
Package zapw defines an analyzer that finds mistakes with variadic "with" arguments in zap's SugaredLogger.
Package zapw defines an analyzer that finds mistakes with variadic "with" arguments in zap's SugaredLogger.

Jump to

Keyboard shortcuts

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