github.com/Laisky/zap@v1.27.0/FAQ.md (about)

     1  # Frequently Asked Questions
     2  
     3  ## Design
     4  
     5  ### Why spend so much effort on logger performance?
     6  
     7  Of course, most applications won't notice the impact of a slow logger: they
     8  already take tens or hundreds of milliseconds for each operation, so an extra
     9  millisecond doesn't matter.
    10  
    11  On the other hand, why *not* make structured logging fast? The `SugaredLogger`
    12  isn't any harder to use than other logging packages, and the `Logger` makes
    13  structured logging possible in performance-sensitive contexts. Across a fleet
    14  of Go microservices, making each application even slightly more efficient adds
    15  up quickly.
    16  
    17  ### Why aren't `Logger` and `SugaredLogger` interfaces?
    18  
    19  Unlike the familiar `io.Writer` and `http.Handler`, `Logger` and
    20  `SugaredLogger` interfaces would include *many* methods. As [Rob Pike points
    21  out][go-proverbs], "The bigger the interface, the weaker the abstraction."
    22  Interfaces are also rigid — *any* change requires releasing a new major
    23  version, since it breaks all third-party implementations.
    24  
    25  Making the `Logger` and `SugaredLogger` concrete types doesn't sacrifice much
    26  abstraction, and it lets us add methods without introducing breaking changes.
    27  Your applications should define and depend upon an interface that includes
    28  just the methods you use.
    29  
    30  ### Why are some of my logs missing?
    31  
    32  Logs are dropped intentionally by zap when sampling is enabled. The production
    33  configuration (as returned by `NewProductionConfig()` enables sampling which will
    34  cause repeated logs within a second to be sampled. See more details on why sampling
    35  is enabled in [Why sample application logs](https://github.com/uber-go/zap/blob/master/FAQ.md#why-sample-application-logs).
    36  
    37  ### Why sample application logs?
    38  
    39  Applications often experience runs of errors, either because of a bug or
    40  because of a misbehaving user. Logging errors is usually a good idea, but it
    41  can easily make this bad situation worse: not only is your application coping
    42  with a flood of errors, it's also spending extra CPU cycles and I/O logging
    43  those errors. Since writes are typically serialized, logging limits throughput
    44  when you need it most.
    45  
    46  Sampling fixes this problem by dropping repetitive log entries. Under normal
    47  conditions, your application writes out every entry. When similar entries are
    48  logged hundreds or thousands of times each second, though, zap begins dropping
    49  duplicates to preserve throughput.
    50  
    51  ### Why do the structured logging APIs take a message in addition to fields?
    52  
    53  Subjectively, we find it helpful to accompany structured context with a brief
    54  description. This isn't critical during development, but it makes debugging
    55  and operating unfamiliar systems much easier.
    56  
    57  More concretely, zap's sampling algorithm uses the message to identify
    58  duplicate entries. In our experience, this is a practical middle ground
    59  between random sampling (which often drops the exact entry that you need while
    60  debugging) and hashing the complete entry (which is prohibitively expensive).
    61  
    62  ### Why include package-global loggers?
    63  
    64  Since so many other logging packages include a global logger, many
    65  applications aren't designed to accept loggers as explicit parameters.
    66  Changing function signatures is often a breaking change, so zap includes
    67  global loggers to simplify migration.
    68  
    69  Avoid them where possible.
    70  
    71  ### Why include dedicated Panic and Fatal log levels?
    72  
    73  In general, application code should handle errors gracefully instead of using
    74  `panic` or `os.Exit`. However, every rule has exceptions, and it's common to
    75  crash when an error is truly unrecoverable. To avoid losing any information
    76  — especially the reason for the crash — the logger must flush any
    77  buffered entries before the process exits.
    78  
    79  Zap makes this easy by offering `Panic` and `Fatal` logging methods that
    80  automatically flush before exiting. Of course, this doesn't guarantee that
    81  logs will never be lost, but it eliminates a common error.
    82  
    83  See the discussion in uber-go/zap#207 for more details.
    84  
    85  ### What's `DPanic`?
    86  
    87  `DPanic` stands for "panic in development." In development, it logs at
    88  `PanicLevel`; otherwise, it logs at `ErrorLevel`. `DPanic` makes it easier to
    89  catch errors that are theoretically possible, but shouldn't actually happen,
    90  *without* crashing in production.
    91  
    92  If you've ever written code like this, you need `DPanic`:
    93  
    94  ```go
    95  if err != nil {
    96    panic(fmt.Sprintf("shouldn't ever get here: %v", err))
    97  }
    98  ```
    99  
   100  ## Installation
   101  
   102  ### What does the error `expects import "github.com/Laisky/zap"` mean?
   103  
   104  Either zap was installed incorrectly or you're referencing the wrong package
   105  name in your code.
   106  
   107  Zap's source code happens to be hosted on GitHub, but the [import
   108  path][import-path] is `github.com/Laisky/zap`. This gives us, the project
   109  maintainers, the freedom to move the source code if necessary. However, it
   110  means that you need to take a little care when installing and using the
   111  package.
   112  
   113  If you follow two simple rules, everything should work: install zap with `go
   114  get -u github.com/Laisky/zap`, and always import it in your code with `import
   115  "github.com/Laisky/zap"`. Your code shouldn't contain *any* references to
   116  `github.com/uber-go/zap`.
   117  
   118  ## Usage
   119  
   120  ### Does zap support log rotation?
   121  
   122  Zap doesn't natively support rotating log files, since we prefer to leave this
   123  to an external program like `logrotate`.
   124  
   125  However, it's easy to integrate a log rotation package like
   126  [`gopkg.in/natefinch/lumberjack.v2`][lumberjack] as a `zapcore.WriteSyncer`.
   127  
   128  ```go
   129  // lumberjack.Logger is already safe for concurrent use, so we don't need to
   130  // lock it.
   131  w := zapcore.AddSync(&lumberjack.Logger{
   132    Filename:   "/var/log/myapp/foo.log",
   133    MaxSize:    500, // megabytes
   134    MaxBackups: 3,
   135    MaxAge:     28, // days
   136  })
   137  core := zapcore.NewCore(
   138    zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()),
   139    w,
   140    zap.InfoLevel,
   141  )
   142  logger := zap.New(core)
   143  ```
   144  
   145  ## Extensions
   146  
   147  We'd love to support every logging need within zap itself, but we're only
   148  familiar with a handful of log ingestion systems, flag-parsing packages, and
   149  the like. Rather than merging code that we can't effectively debug and
   150  support, we'd rather grow an ecosystem of zap extensions.
   151  
   152  We're aware of the following extensions, but haven't used them ourselves:
   153  
   154  | Package | Integration |
   155  | --- | --- |
   156  | `github.com/tchap/zapext` | Sentry, syslog |
   157  | `github.com/fgrosse/zaptest` | Ginkgo |
   158  | `github.com/blendle/zapdriver` | Stackdriver |
   159  | `github.com/moul/zapgorm` | Gorm |
   160  | `github.com/moul/zapfilter` | Advanced filtering rules |
   161  
   162  [go-proverbs]: https://go-proverbs.github.io/
   163  [import-path]: https://golang.org/cmd/go/#hdr-Remote_import_paths
   164  [lumberjack]: https://godoc.org/gopkg.in/natefinch/lumberjack.v2