-
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
write error: sync /dev/stdout: invalid argument #328
Comments
These logs are coming from That shouldn't happen when syncing Can you provide one or more of:
|
please see this gist for the code: uber-zap-logger.go To reproduce:
There is no stacktrace I can help you with |
Can you trim that example code back? There's a lot there, and I suspect that most of it isn't relevant to this issue. If you can show me the smallest possible code snippet that fails this way, I'm happy to debug from there. |
This is trivial to reproduce: package main
import "go.uber.org/zap"
func main() {
log, err := zap.NewDevelopment()
if err != nil {
return
}
log.Fatal("dying now")
}
|
Thanks a lot @Ulexus, I forgot to come back to this |
This points out a surprise I had in the API. Since the logging output is buffered, I would have expected the API to offer some sort of |
@Ulexus I'm unable to reproduce, which suggests that this is somehow environment-dependent.
If you and @toefel18 can post the output of Regarding your API question, output isn't buffered by default. |
and thanks for the clarification on buffering |
I have also verified that the same problem occurs running in Docker containers using the It also occurs whether executing a built binary (go build; ./testgo) or when using |
Thanks for the report @toefel18 and @Ulexus The issue here is that The documentation for
The OSX documentation is similar:
This simple example reproduces the issue with $ cat main.go
package main
import (
"fmt"
"os"
)
func main() {
fmt.Println(os.Stdout.Sync())
} OSX:
Linux:
@akshayjshah We have a couple of options here:
|
Aha; that makes sense, then. It looks like Thus, you can try a type assertion on |
Ah, the joys of platform-dependent behavior. Thanks for the detailed report and follow-up! @Ulexus are you interested in opening a PR to fix this? |
@Ulexus Unfortunately https://golang.org/src/os/error.go#L13:
The specific error returned seems to be dependent on the |
Since It is true that if the WriteSyncer is not an instance of I'll see if I can whip something up as a PR, sure. |
Sorry, what I meant to say is that package main
import (
"fmt"
"os"
)
func main() {
err := os.Stdout.Sync()
fmt.Println("err", err)
fmt.Println("is ErrInvalid", err == os.ErrInvalid)
} Output on Linux:
|
Aha; I did not interpret that comment as an exclusive description. I see from your example that it is. I think the easiest solution here is to just modify Does that sound reasonable? |
In particular, something like this: func AddSync(w io.Writer) WriteSyncer {
switch w := w.(type) {
case WriteSyncer:
if !checkSync(w) {
return writerWrapper{w}
}
return w
default:
return writerWrapper{w}
}
}
// checkSync executes a Sync() on the WriteSyncer to check whether it operates
// cleanly. In the particular case of the WriteSyncer being a special file,
// calling Sync will return an `os.ErrInvalid` error. If, for whatever reason,
// the call of `Sync()` returns an error, this will return a `false`.
func checkSync(w WriteSyncer) bool {
if err := w.Sync(); err != nil {
return false
}
return true
} |
If call to `Sync()` fails, wrap the WriteSyncer with a fake `Sync()`. Fixes uber-go#328
I think that checking the first error and then deciding whether to ignore errors might be a little surprising. I think I'd prefer to either always ignore, or write a function to detect these I think @peter-edge had some thoughts on the PR as well. |
I'd prefer to ignore these errors entirely (in the short term, at least). This isn't a breaking API change, and I'd like to tread cautiously when introducing Go version and OS-dependent behavior. In practice, there's little that the user can do about failures to sync files. Network-backed We can always revisit this later - I'll file a separate issue to track that. |
If call to `Sync()` fails, wrap the WriteSyncer with a fake `Sync()`. Fixes uber-go#328
Currently logger.Sync fails often (or always), reading uber-go/zap#328 seems like it's safe to ignore.
According to uber-go/zap#328, `Sync` can fail, but it is not a problem. Ignore it.
Prior to this commit, this is how all `tkn chains` output starts like: ``` $ tkn chain payload build-push-run-output-image-p229w sync /dev/stderr: invalid argument ... ... ``` This commit gets rid of the `sync /dev/stderr: invalid argument` error by ignoring it, which is safe: see uber-go/zap#328
Prior to this commit, this is how all `tkn chains` output starts like: ``` $ tkn chain payload build-push-run-output-image-p229w sync /dev/stderr: invalid argument ... ... ``` This commit gets rid of the `sync /dev/stderr: invalid argument` error by ignoring it, which is safe: see uber-go/zap#328
Calling `Sync` on stdout/stderr on Linux raises an error that can be ignored. See uber-go/zap#328. Fixes cerbos#1514 Signed-off-by: Charith Ellawala <charith@cerbos.dev>
Calling `Sync` on stdout/stderr on Linux raises an error that can be ignored. See uber-go/zap#328. Fixes #1514 Signed-off-by: Charith Ellawala <charith@cerbos.dev>
I'm a bit confused. When writing to |
If you want to check for this invalid argument you can do so with: if errors.Is(syncErr, syscall.EINVAL) {
// Sync is not supported on os.Stderr / os.Stdout on all platforms.
} |
@stevenh I'm not sure if that's intended as a response to my question, or unrelated. In my case, I know the error will always occur, because I'm always logging to |
My intent was to let people know its With regards to buffering, even if there isn't buffering it's good practice to flush your output to avoid loss. This can happen even if its at the OS layer, so beyond go's control. By default writer := bufio.NewWriter(os.Stdout) |
Thanks for opensourcing this library!
Everything is fine during program execution, but when the application shuts down (due to an error) zap logs to stderr:
write error: sync /dev/stdout: invalid argument
Output:
Relevant set-up code:
The text was updated successfully, but these errors were encountered: