<p>Basically can multiple goroutines share the same instance of a Write implementation without error? I realize that a zipper-effect may occur if two routines are writing multiple lines of text in individual write calls and that an intermediate buffer may be needed to keep the text together, but this is acceptable. I just want to make sure that I don't need to synchronize the calls somehow. I cannot find anything on this in the official godocs. Any help would be appreciated. Thanks!</p>
<hr/>**评论:**<br/><br/>TheMerovius: <pre><p><a href="http://godoc.org/io#Writer" rel="nofollow">io.Writer</a> doesn't document that the method needs to be safe for concurrent use, so you can't assume that it is. Both a writer that is concurrency-safe and one that isn't fulfills the interface. An *os.File, to the best of my knowledge, should be concurrency safe (you probably will get weird results of interleaved writes if you try, but your program won't <em>crash</em>). A *bytes.Buffer probably isn't. So if you don't know that an io.Writer you get is concurrency-safe, don't use it concurrently without locking.</p></pre>daveddev: <pre><p>For example:
<a href="https://golang.org/src/bytes/buffer.go?s=4333:4465#L119" rel="nofollow">https://golang.org/src/bytes/buffer.go?s=4333:4465#L119</a></p>
<p>A race condition surrounding this and similar methods seems like it would be prone to eventual failure.</p>
<p>I edited this because my original answer would likely have come across far more snarky than I intended. I'm sorry if any offense was taken.</p></pre>sakutz: <pre><p>Hi! Thanks for the info. No offense taken. I'm a real-life, honest-to-goodness asshole, so I recognize it's difficult to not sound snarky when being direct. </p>
<p>Hmm. </p>
<p>Basically I have multiple http.Handlers doing logging of requests and responses (more than basic stuff), and I'm wondering the best way to do that. I'm using the underlying out stream from logrus to write directly to the output, but now I'm wondering if I should have a writer per handler and potentially multiple backing files (one per route).</p>
<p>I could also just sync that method. May be easiest.</p></pre>pierrrre: <pre><p>log.Logger has an internal lock: <a href="https://golang.org/src/log/log.go?#L147" rel="nofollow">https://golang.org/src/log/log.go?#L147</a></p></pre>daveddev: <pre><p>If you are obtaining the writer using the logrus.Logger Writer() method, the returned Writer is created using <a href="https://golang.org/pkg/io/#Pipe" rel="nofollow">https://golang.org/pkg/io/#Pipe</a>. It states that it is safe for concurrent use.</p>
<p>Further, as <a href="/u/pierrrre" rel="nofollow">/u/pierrrre</a> mentions, if you are using a log.Logger with the Writer (e.g. <code>log.New(w, "", 0),</code>), it will also provide ordered access.</p></pre>sakutz: <pre><p>Thanks all. I think based on the feedback the best path forward is to use shared stdout, stderr streams for multiple instances of my logging handler, but inside the handler use instance-level buffers to create the logged output before writing it to the underlying target. This will ensure things are ordered as well as still be safe for concurrent use since the Writer returned by logrus is safe for concurrent use.</p>
<p>In my previous implementation of things it didn't matter as there was a single logging handler, but I switched things to using a different mux per route and thus I ended up needing multiple logging handlers in order to chain the middleware per mux.</p></pre>sakutz: <pre><p>By the way, the source currently looks like this <a href="https://github.com/akutz/libstorage/blob/feature/dadd/api/server/handlers/handlers_logging.go" rel="nofollow">https://github.com/akutz/libstorage/blob/feature/dadd/api/server/handlers/handlers_logging.go</a>.</p>
<p>You can see what I'm doing in the file.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传