Proposal Details
This proposal is for a function with a signature like func CallerString(skip int) string
.
It returns basic info about the caller in some fixed format.
Since it only returns info about a single frame and only reports it as simple data, when skip
is a reasonable constant, it could be replaced at compile time as an optimization. Otherwise, it can be implemented in terms of Callers
.
Either way, it would simplify common logging/monitoring/error annotating uses that just need a tiny bit of context about a single caller for reporting to a developer.
Comment From: gabyhelp
Related Documentation
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
Comment From: ianlancetaylor
What would the string be?
I'm not sure what you mean when you suggest replacing it at compile time. It seems to me that is only possible when the caller is known. And that can only happen if the function that calls CallerString
is only called from one other location in the program. If it's called from more than one location, how can the compiler know what the value of CallerString
should be?
Comment From: jimmyfrasche
I doesn't matter precisely what the string is as long as it 1. contains enough information to identify the caller 2. is in a specified format that is human and machine readable
It could just be "path/file:lineNumber". I'm not concerned about the particulars as long as it is meets the listed criteria.
Say you had a function using it like
func F() T {
return G(runtime.CallerString(1))
}
I'm imagining some hypothetical set of optimizations where F
is inlined and the constant is decremented in kind and thus can be replaced with the information from the original call site for F
so when you call F()
you end up with a sequence of transformations: F()
to G(runtime.CallerString(0))
to G("my/file.go:10")
(or whatever format).
Comment From: seankhliao
Without skip it'd be #12876 #27329 #37620
Comment From: jimmyfrasche
It would serve a similar purpose. This is about providing a nicer interface.
The last place I used something like this was a parser for strings that would be provided in source (like how regexp.Compile
often takes a constant). Since there could be many of these in the same project, it took used runtime to grab the file/line info so it could report errors not just as an offset into a string but also the source location of that string. I just wanted a string but ended up having to read and reread a bunch of docs. I couldn't tell if it was sufficient to use runtime.Caller(1)
or if I needed to do like the example for Frames so that it worked even if things got inlined. I ended up using a modified version of the Frames example just in case but maybe that's overkill. I just wanted to make sure I got some debugging info that seemed like it should be easier to get.
Comment From: seankhliao
52751 sounds related, though that's more specialized to tests
Comment From: adonovan
The runtime package provides all the necessary primitives, and it's not obvious to me from its name what kind of string CallerString would actually return; and I can easily imagine wanting to tweak it a little. This merely convenient feature might be better provided by the internal library within your project, tailored to your specific needs.
Comment From: jimmyfrasche
The necessary primitives are not especially friendly and their generality makes the simple case overly complicated.
Getting basic info about a single frame is the common case by volume and it would be nice to have a clear, simple, robust way to get that.
Comment From: ianlancetaylor
@jimmyfrasche You say above that the string has to be machine readable, which means that it must be precisely defined. This proposal isn't going to go anywhere unless you provide a precise definition. Thanks.