-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make user-supplied sinks operate on URIs #606
Conversation
Small formatting change for readability.
For future extensibility, make user-supplied factories for log sinks operate on URIs. Each user-supplied factory owns a scheme, and double-registering constructors for a scheme is an error. For back-compat, zap automatically registers a factory for the `file` scheme and treats URIs without a scheme as though they were for files.
Codecov Report
@@ Coverage Diff @@
## master #606 +/- ##
==========================================
+ Coverage 97.23% 97.37% +0.13%
==========================================
Files 40 40
Lines 2063 2095 +32
==========================================
+ Hits 2006 2040 +34
+ Misses 49 47 -2
Partials 8 8
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the slow review, change looks good. Just some small suggestions
config.go
Outdated
@@ -74,10 +74,10 @@ type Config struct { | |||
// EncoderConfig sets options for the chosen encoder. See | |||
// zapcore.EncoderConfig for details. | |||
EncoderConfig zapcore.EncoderConfig `json:"encoderConfig" yaml:"encoderConfig"` | |||
// OutputPaths is a list of paths to write logging output to. See Open for | |||
// OutputPaths is a list of URLs to write logging output to. See Open for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we mention that filenames are also supported?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, can do.
sink.go
Outdated
_sinkMutex.RLock() | ||
defer _sinkMutex.RUnlock() | ||
sinkFactory, ok := _sinkFactories[key] | ||
|
||
factory, ok := _sinkFactories[u.Scheme] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
optionally: can we hold the RLock
just while we're looking up the factory?
_sinkMutex.RLock()
factory, ok := _sinkFactories[u.Scheme]
_sinkMutex.RUnlock()
Shouldn't be an issue since it's just an RLock
, but want to avoid holding on to locks while triggering the factory which is user-supplied.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, can do.
} | ||
|
||
type nopCloserSink struct{ zapcore.WriteSyncer } | ||
func newFileSink(u *url.URL) (Sink, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
optional: should we ensure there's no fragments etc? ignoring seems OK too, but it might be a little surprising
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point.
sink.go
Outdated
case c == '.' || c == '+' || c == '-': | ||
continue | ||
} | ||
return "", fmt.Errorf("may not contain %q", string(c)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
%q
works fine for characters, it does single quotes instead of double quotes, which seems fine here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely.
sink.go
Outdated
if first := s[0]; 'a' > first || 'z' < first { | ||
return "", errors.New("must start with a letter") | ||
} | ||
if len(s) < 2 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the rest of the code will work fine for len(s) == 1
, any reason for this special case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, just left over from previous iterations on the code. My bad.
@prashantv Cleaned up per your suggestions. Validating file URLs more strictly was a really good idea. I'll leave this open for a few days in case you'd like to re-review. |
sink.go
Outdated
// particular scheme. | ||
// | ||
// All schemes must be ASCII, valid under section 3.1 of RFC 3986 | ||
// (https://tools.ietf.org/html/rfc3986#section-3.1), and may not already have |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: "must not"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, fixed.
sink.go
Outdated
// (https://tools.ietf.org/html/rfc3986#section-3.1), and may not already have | ||
// a factory registered. Zap automatically registers a factory for the "file" | ||
// scheme. | ||
func RegisterSink(scheme string, factory func(*url.URL) (Sink, error)) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this a breaking change? The factory function didn't accept a callback before.
I've been informed that this hasn't been released yet so it isn't a breaking Do you think we'll ever need to change this signature in the future? If yes, |
There's always a chance that we'll need to change this later; in that case, though, I don't see much difference between introducing a new interface and introducing a new registration function - in the latter case, we can keep the interface with both methods unexported. The current approach matches |
For future extensibility, make user-supplied factories for log sinks operate on URIs. Each user-supplied factory owns a scheme, and double-registering constructors for a scheme is an error. For back-compat, zap automatically registers a factory for the `file` scheme and treats URIs without a scheme as though they were for files.
For future extensibility, make user-supplied factories for log sinks
operate on URIs. Each user-supplied factory owns a scheme, and
double-registering constructors for a scheme is an error. For
back-compat, zap automatically registers a factory for the
file
schemeand treats URIs without a scheme as though they were for files.