hide filepath in stacktrace

polaris · · 507 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I&#39;m currently working on a little application and I build it on my development machine.</p> <p>When my compiled binary panics on another computer, it shows the stacktrace with filepaths from my dev machine (e.g. &#34;C:/Users/micro/go/src/go.iondynamics.net/siteMgr/srv/session/session.go:65 +0x13c&#34;)</p> <p>Is there a way to strip these during compilation to something like &#34;GOPATH/src/go.iondynamics.net/siteMgr/srv/session/session.go:65 +0x13c&#34; or &#34;GOROOT/src/net/http/server.go:1472 +0xf2e&#34;?</p> <hr/>**评论:**<br/><br/>dlsniper: <pre><p>As far as I know this is not currently possible from the compiler. Maybe you can search in the Go issues to see if there&#39;s anything there or open a new issue for this. However I think it is useful to have the full path as GOPATH can be a collection of paths and then it wouldn&#39;t be clear where the file comes from. I guess a simple tool could also change this in the logs if you really need this</p></pre>KEANO_: <pre><p>I agree for debugging purposes. A full stacktrace incl full path is pretty helpful. </p> <p>But in production-mode a less verbose output is imo preferable (or even better there shouldn&#39;t be panics at all :D)</p></pre>dlsniper: <pre><p>I guess the question is: what if the panic happens in production? If you do want this why not write a simple wrapper / processor for your logs and that&#39;s it :)</p></pre>KEANO_: <pre><p>My main() now defers a function with recover() and handles panics gracefully without a stack trace at all</p></pre>dlsniper: <pre><p>Please think twice before going down this road. Rarely there are cases where you can handle gracefully a panic. If the app still exists the that&#39;s good. For me losing the ability to trace the error would be equally important. </p></pre>KEANO_: <pre><p>I&#39;ve added this to my main()</p> <pre><code>if !*debug { defer func() { if r := recover(); r != nil { idl.Emerg(r) } }() } </code></pre> <p>If it&#39;s in production mode it &#34;catches&#34; all panics and keeps a log of the error via idl (which is a logging package)</p> <p>Do you think this is bad practice?</p> <p>edit: idl.Emerg calls os.Exit(1) after handling all log-events</p></pre>dlsniper: <pre><p>If you call exit that&#39;s a good thing. Keep in mind that panics may occur because the memory allocator ran out of space and other such issues</p></pre>cheesechoker: <pre><p>More of a workaround than a solution, but... </p> <p>You could build your app inside a virtual machine (or Docker container) where the source code lives in <code>/src</code> or whatever folder path you prefer.</p></pre>KEANO_: <pre><p>I thought about that, too. But this method is overkill for my tiny app.</p></pre>SportingSnow21: <pre><p>If you have a specific function that you&#39;re hacking, you can put a cleanup defer in it. It&#39;s not terribly pretty, but it will clean up the stack traces:</p> <pre><code>defer func() { if r := recover(); r!=nil{ log.Println(&#34;Recovered error: &#34;, r) // Get stack trace buf := make([]byte, 4096) buf = buf[:runtime.Stack(buf, false)] // Clean up stack trace buf = bytes.Replace(buf, []byte(os.GetEnv(&#34;GOPATH&#34;)), []byte(&#34;GOPATH&#34;), -1) buf = bytes.Replace(buf, []byte(os.GetEnv(&#34;GOROOT&#34;)), []byte(&#34;GOROOT&#34;), -1) // Print stack trace log.Println(string(buf)) } } </code></pre></pre>kavehmz: <pre><p>If you just want to have less information, one way is to define a &#34;recover&#34; in your main function.</p> <pre><code>package main import &#34;fmt&#34; func main() { defer func() { if r := recover(); r != nil { fmt.Println(&#34;There was an erorr &#34;, r) } }() b := 0 a := 1 / b fmt.Println(a, b) } </code></pre> <p><a href="https://play.golang.org/p/BHQ6-UWKx-" rel="nofollow">https://play.golang.org/p/BHQ6-UWKx-</a></p> <p>Try to add and remove defer section and see what happens.</p> <p>Another way is to set the GOTRACEBACK=none in your environment.</p> <p>You can find more about it here:</p> <p><a href="https://golang.org/pkg/runtime/#GOTRACEBACK" rel="nofollow">https://golang.org/pkg/runtime/#GOTRACEBACK</a> </p></pre>KEANO_: <pre><p>I&#39;ve read about GOTRACEBACK, but it is evaluated at runtime - not compilation.</p> <p>But recover() is pretty much the perfect solution. Thank you :) I always thought that the defer/recover section has to be in the same scope as the panic.</p> <p>So recover() and panics are somewhat like Java&#39;s catch-blocks and exceptions? Panics bubble up more than one scope... </p> <p>edit: manners</p></pre>kavehmz: <pre><p>It is as you say kinda similar to exceptions, in a way that it can give us control over a &#34;panic&#34;.</p> <p>But please be careful as how you use &#34;recover&#34;. I is kinda considered bad in Go style.</p> <p>Your case seems to be actually one of the situations that it might make sense to use &#34;recover&#34;.</p> <p><a href="https://golang.org/ref/spec#Handling_panics" rel="nofollow">https://golang.org/ref/spec#Handling_panics</a></p></pre>KEANO_: <pre><p>That was another reason why I didn&#39;t dive into the panic/recover mechanics, yet. I&#39;m not going to switch to panics. I&#39;ll stick to returning error-Interface</p> <p>But in this special case my main() now defers a recover block :) Thanks again</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

507 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传