-
Notifications
You must be signed in to change notification settings - Fork 697
A Sprint function for services that use json logging #20
Comments
Can you use
? |
Similarly I'd like to be able to pass the print output to golang/glog in a single line of code like:
IMHO using multiple lines could mean a lot of boiler plate for something frequent like a log statement. |
If you want a different presentation I recommend copying the body of Fprint On Sat, 7 May 2016, 17:34 jd3nn1s, [email protected] wrote:
|
Hi guys,
Unless I'm mistaken this would involve processing the string after the fact to ensure that it is single line for JSON logging which is unideal for performance considering how many logs can be churned out. Copying the body of Fprint and altering is essentially what this function is, however I believe this is not an edge case and is common enough to warrant being in the main package. If you disagree can we discuss the following alternatives?
Thank you |
If logging errors is such a bottleneck in your application, you may have other problems.
I agree, but this package will only support one string format. If you'd like to propose a single line format for this extended output, I'm happy to discuss changing it, but it will not be configurable. |
I should clarify that I meant multiple lines of code. I don't have a problem with multi-line log statements in my use-case, if there are more than a few levels of wrapped errors it could be pretty unreadable on a single line. If the error message is used in JSON it should be encoded/escaped anyway in case something logs a quote. |
I'm sorry, I'm no very confused. Could you please explain to me what would On Sun, 8 May 2016, 09:30 jd3nn1s, [email protected] wrote:
|
A function that returns a string containing what .Fprint() writes to w. |
func printErrors(err error) string {
var b bytes.Buffer
errors.Fprint(&b, err)
var s string
// Format it however you'd like
// ...
return s
} Would this wrapper not achieve what you are asking for? Right now there are already multiple conflicting requests—one to simply write out a string, and another to concatenate it with custom separators. All of this seems to be better suited to a simple helper function in your own application since it doesn't need to access any private types. |
I'm suggesting something simpler:
Sure, it could be implemented outside as a helper function. IMHO it is useful enough to be part of the library the same way Print() is. It doesn't introduce any new string format either, it reuses the one established by Fprint(). |
You are suggesting that, but @Jimah is not—hence the issue (there's not even consensus, which is an indicator that this is better left outside of this package). |
I think that's a false dichotomy. The question of changing the format is separate from making the existing format available as a string. @davecheney has also said that the package will only support one string format, so I'm not sure even that is in contention. |
@jd3nn1s I'm sorry but I won't be adding the function you described in #20 (comment), it's not unique or important enough to add to this package. Fprintf is more general and can be used to implement the three line helper you suggested. Thank you for your understanding. |
@Jimah I'm concerned this issue is going around in circles. Could you please reply to #20 (comment) with your thoughts. Thanks |
@davecheney Hi Dave, I believe the string representation should be separated by > symbols to indicate the failure path of the code. I agree that a helper function which only returns the string representation of the current format should stay outside of the package. |
As a note, the one line string format could also be created as a helper function outside of the package in a fairly straightforward way as follows: var b bytes.Buffer
Fprint(&b, err)
exploded := strings.Split(b.String(), "\n")
exploded = exploded[:len(exploded)-1]
return strings.Join(exploded, " > ") Including this within the package would, however, encourage a standardised one line format. So readfile.go:27: could not read config Becomes readfile.go:27: could not read config > readfile.go:14: open failed > open /Users/dfc/.settings.xml: no such file or directory |
@Jimah why don't we just change the output from
Then we can drop |
@davecheney I like this idea a lot, I do think that the separator between error causes needs to be something other than a colon though in case people want to transform it within their own applications (as colons are already used for file:line). Maybe a semicolon? |
Sorry, it has to be a colon, that's the tradition established by fmt.Errorf and gopl.io |
@Jimah alternatively, would you prefer something like this
|
Ah ok, that makes sense. |
Apologies for closing and reopening, they put those buttons so close together! A Stacktrace would be more flexible and won't interfere with people's current implementations, that may be the best path forward. It would also be better for our implementation as we could split the errors out into different json keys. |
@Jimah i'm having trouble following your use case. In #20 (comment) you propose transforming It would be helpful if you could describe the end result, preferably in JSON. |
The first, single line solution would result in this (excluding any other data): {
"error": "readfile.go:27: could not read config: readfile.go:14: open failed: open /Users/dfc/.settings.xml: no such file or directory"
} Whereas the alternative stacktrace approach would result in this: {
"errors": [
"readfile.go:27: could not read config",
"readfile.go:14: open failed",
"open /Users/dfc/.settings.xml: no such file or directory"
]
} I'm open to implementing either result, I think the stacktrace approach would be easier to read especially if there are many errors chained. |
Why can't you just do this var b bytes.Buffer
errors.Fprint(&b, err)
stack := strings.Split(b.String(), "\n") |
That would work and I'm happy to go with it as a helper function outside of the package if it is decided not to be included. Do you think there is value in offering this as a part of this package? It's not much code and it may prove useful to other people offering it out of the box. |
None, for two reasons.
|
Alright, good stuff. Thank you for your time. I'm happy to close the issue if the other participants are. |
errors.Print had a number of problems. Firstly, it was hard coded to print to os.Stderr, which made it difficult to test, and hard to write an example test for. Secondly, comments made in issue #20 make it clear that helpers need to have a high bar for inclusion in this package, and something that wrapped errors.Fprint in a way that was hard to test fails that bar. So, Remove errors.Print, which frees the identifier for being reused later, and reduces the size of the package.
errors.Print had a number of problems. Firstly, it was hard coded to print to os.Stderr, which made it difficult to test, and hard to write an example test for. Secondly, comments made in issue #20 make it clear that helpers need to have a high bar for inclusion in this package, and something that wrapped errors.Fprint in a way that was hard to test fails that bar. So, Remove errors.Print, which frees the identifier for being reused later, and reduces the size of the package.
Not surprised to see Print() removed after this discussion - I'm also fine with this issue being closed. Thank you for your work to improve error handling in Go! |
Thank you for helping me clarify the purpose of this package. It needs to On Tue, 10 May 2016, 14:10 jd3nn1s, [email protected] wrote:
|
Hello,
In the services that we run we utilise json logging for all of our error logs, I had a peruse and it seems that the current print functions either require a writer or go straight to os.Stderr.
I think it would be very helpful for us, as well as for other users of this package, if there was a function that performs the same as fprint but returns a string for use.
I've created a proof of concept here: https://github.com/jimah/errors/blob/master/errors.go#L253
For example output please see the tests.
Thank you for your time!
The text was updated successfully, but these errors were encountered: