 9bdcbe0447
			
		
	
	9bdcbe0447
	
	
	
		
			
			Major integrations and fixes: - Added BACKBEAT SDK integration for P2P operation timing - Implemented beat-aware status tracking for distributed operations - Added Docker secrets support for secure license management - Resolved KACHING license validation via HTTPS/TLS - Updated docker-compose configuration for clean stack deployment - Disabled rollback policies to prevent deployment failures - Added license credential storage (CHORUS-DEV-MULTI-001) Technical improvements: - BACKBEAT P2P operation tracking with phase management - Enhanced configuration system with file-based secrets - Improved error handling for license validation - Clean separation of KACHING and CHORUS deployment stacks 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			165 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			165 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # Frequently Asked Questions
 | |
| 
 | |
| ## Design
 | |
| 
 | |
| ### Why spend so much effort on logger performance?
 | |
| 
 | |
| Of course, most applications won't notice the impact of a slow logger: they
 | |
| already take tens or hundreds of milliseconds for each operation, so an extra
 | |
| millisecond doesn't matter.
 | |
| 
 | |
| On the other hand, why *not* make structured logging fast? The `SugaredLogger`
 | |
| isn't any harder to use than other logging packages, and the `Logger` makes
 | |
| structured logging possible in performance-sensitive contexts. Across a fleet
 | |
| of Go microservices, making each application even slightly more efficient adds
 | |
| up quickly.
 | |
| 
 | |
| ### Why aren't `Logger` and `SugaredLogger` interfaces?
 | |
| 
 | |
| Unlike the familiar `io.Writer` and `http.Handler`, `Logger` and
 | |
| `SugaredLogger` interfaces would include *many* methods. As [Rob Pike points
 | |
| out][go-proverbs], "The bigger the interface, the weaker the abstraction."
 | |
| Interfaces are also rigid — *any* change requires releasing a new major
 | |
| version, since it breaks all third-party implementations.
 | |
| 
 | |
| Making the `Logger` and `SugaredLogger` concrete types doesn't sacrifice much
 | |
| abstraction, and it lets us add methods without introducing breaking changes.
 | |
| Your applications should define and depend upon an interface that includes
 | |
| just the methods you use.
 | |
| 
 | |
| ### Why are some of my logs missing?
 | |
| 
 | |
| Logs are dropped intentionally by zap when sampling is enabled. The production
 | |
| configuration (as returned by `NewProductionConfig()` enables sampling which will
 | |
| cause repeated logs within a second to be sampled. See more details on why sampling
 | |
| is enabled in [Why sample application logs](https://github.com/uber-go/zap/blob/master/FAQ.md#why-sample-application-logs).
 | |
| 
 | |
| ### Why sample application logs?
 | |
| 
 | |
| Applications often experience runs of errors, either because of a bug or
 | |
| because of a misbehaving user. Logging errors is usually a good idea, but it
 | |
| can easily make this bad situation worse: not only is your application coping
 | |
| with a flood of errors, it's also spending extra CPU cycles and I/O logging
 | |
| those errors. Since writes are typically serialized, logging limits throughput
 | |
| when you need it most.
 | |
| 
 | |
| Sampling fixes this problem by dropping repetitive log entries. Under normal
 | |
| conditions, your application writes out every entry. When similar entries are
 | |
| logged hundreds or thousands of times each second, though, zap begins dropping
 | |
| duplicates to preserve throughput.
 | |
| 
 | |
| ### Why do the structured logging APIs take a message in addition to fields?
 | |
| 
 | |
| Subjectively, we find it helpful to accompany structured context with a brief
 | |
| description. This isn't critical during development, but it makes debugging
 | |
| and operating unfamiliar systems much easier.
 | |
| 
 | |
| More concretely, zap's sampling algorithm uses the message to identify
 | |
| duplicate entries. In our experience, this is a practical middle ground
 | |
| between random sampling (which often drops the exact entry that you need while
 | |
| debugging) and hashing the complete entry (which is prohibitively expensive).
 | |
| 
 | |
| ### Why include package-global loggers?
 | |
| 
 | |
| Since so many other logging packages include a global logger, many
 | |
| applications aren't designed to accept loggers as explicit parameters.
 | |
| Changing function signatures is often a breaking change, so zap includes
 | |
| global loggers to simplify migration.
 | |
| 
 | |
| Avoid them where possible.
 | |
| 
 | |
| ### Why include dedicated Panic and Fatal log levels?
 | |
| 
 | |
| In general, application code should handle errors gracefully instead of using
 | |
| `panic` or `os.Exit`. However, every rule has exceptions, and it's common to
 | |
| crash when an error is truly unrecoverable. To avoid losing any information
 | |
| — especially the reason for the crash — the logger must flush any
 | |
| buffered entries before the process exits.
 | |
| 
 | |
| Zap makes this easy by offering `Panic` and `Fatal` logging methods that
 | |
| automatically flush before exiting. Of course, this doesn't guarantee that
 | |
| logs will never be lost, but it eliminates a common error.
 | |
| 
 | |
| See the discussion in uber-go/zap#207 for more details.
 | |
| 
 | |
| ### What's `DPanic`?
 | |
| 
 | |
| `DPanic` stands for "panic in development." In development, it logs at
 | |
| `PanicLevel`; otherwise, it logs at `ErrorLevel`. `DPanic` makes it easier to
 | |
| catch errors that are theoretically possible, but shouldn't actually happen,
 | |
| *without* crashing in production.
 | |
| 
 | |
| If you've ever written code like this, you need `DPanic`:
 | |
| 
 | |
| ```go
 | |
| if err != nil {
 | |
|   panic(fmt.Sprintf("shouldn't ever get here: %v", err))
 | |
| }
 | |
| ```
 | |
| 
 | |
| ## Installation
 | |
| 
 | |
| ### What does the error `expects import "go.uber.org/zap"` mean?
 | |
| 
 | |
| Either zap was installed incorrectly or you're referencing the wrong package
 | |
| name in your code.
 | |
| 
 | |
| Zap's source code happens to be hosted on GitHub, but the [import
 | |
| path][import-path] is `go.uber.org/zap`. This gives us, the project
 | |
| maintainers, the freedom to move the source code if necessary. However, it
 | |
| means that you need to take a little care when installing and using the
 | |
| package.
 | |
| 
 | |
| If you follow two simple rules, everything should work: install zap with `go
 | |
| get -u go.uber.org/zap`, and always import it in your code with `import
 | |
| "go.uber.org/zap"`. Your code shouldn't contain *any* references to
 | |
| `github.com/uber-go/zap`.
 | |
| 
 | |
| ## Usage
 | |
| 
 | |
| ### Does zap support log rotation?
 | |
| 
 | |
| Zap doesn't natively support rotating log files, since we prefer to leave this
 | |
| to an external program like `logrotate`.
 | |
| 
 | |
| However, it's easy to integrate a log rotation package like
 | |
| [`gopkg.in/natefinch/lumberjack.v2`][lumberjack] as a `zapcore.WriteSyncer`.
 | |
| 
 | |
| ```go
 | |
| // lumberjack.Logger is already safe for concurrent use, so we don't need to
 | |
| // lock it.
 | |
| w := zapcore.AddSync(&lumberjack.Logger{
 | |
|   Filename:   "/var/log/myapp/foo.log",
 | |
|   MaxSize:    500, // megabytes
 | |
|   MaxBackups: 3,
 | |
|   MaxAge:     28, // days
 | |
| })
 | |
| core := zapcore.NewCore(
 | |
|   zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()),
 | |
|   w,
 | |
|   zap.InfoLevel,
 | |
| )
 | |
| logger := zap.New(core)
 | |
| ```
 | |
| 
 | |
| ## Extensions
 | |
| 
 | |
| We'd love to support every logging need within zap itself, but we're only
 | |
| familiar with a handful of log ingestion systems, flag-parsing packages, and
 | |
| the like. Rather than merging code that we can't effectively debug and
 | |
| support, we'd rather grow an ecosystem of zap extensions.
 | |
| 
 | |
| We're aware of the following extensions, but haven't used them ourselves:
 | |
| 
 | |
| | Package | Integration |
 | |
| | --- | --- |
 | |
| | `github.com/tchap/zapext` | Sentry, syslog |
 | |
| | `github.com/fgrosse/zaptest` | Ginkgo |
 | |
| | `github.com/blendle/zapdriver` | Stackdriver |
 | |
| | `github.com/moul/zapgorm` | Gorm |
 | |
| | `github.com/moul/zapfilter` | Advanced filtering rules |
 | |
| 
 | |
| [go-proverbs]: https://go-proverbs.github.io/
 | |
| [import-path]: https://golang.org/cmd/go/#hdr-Remote_import_paths
 | |
| [lumberjack]: https://godoc.org/gopkg.in/natefinch/lumberjack.v2
 |