不论应用是如何部署的,我们都期望能扑捉到应用的错误日志,

解决思路:

  • 自己写代码处理异常拦截,甚至直接在main函数中写异常拦截。
  • stderr重定向到某个文件里
  • 使用 syscall.Dup2

第一种方法比较简单, 我们这里主要看后两种:

使用 stderr替换的代码:

package main

import (
    "fmt"
    "os"
)

func main() {
    f, _ := os.OpenFile("C:\\tmp\\11.txt", os.O_WRONLY|os.O_CREATE|os.O_SYNC,
        0755)
    os.Stdout = f
    os.Stderr = f
    fmt.Println("fmt")
    fmt.Print(make(map[int]int)[0])
}

这里的 Stdout 、Stderr  的含义如下, 同样也适用win:

在通常情况下,UNIX每个程序在开始运行的时刻,都会有3个已经打开的stream. 分别用来输入,输出,打印诊断和错误信息。通常他们会被连接到用户终端. 但也可以改变到其它文件或设备。

Linux内核启动的时候默认打开的这三个I/O设备文件:标准输入文件stdin,标准输出文件stdout,标准错误输出文件stderr,分别得到文件描述符 0, 1, 2。

stdin是标准输入,stdout是标准输出,stderr是标准错误输出。大多数的命令行程序从stdin输入,输出到stdout或stderr。

 

上面方法,可能会拦截不到一些系统级别的崩溃信息,这时候就需要走下面的方案了。

使用 syscall.Dup2  的例子如下, 注意 windows 下会编译直接报错: undefined: syscall.Dup2, 只有 linux 下才可以用。

syscall.Dup2 is a linux/OSX only thing. there's no windows equivalent。

参考: https://github.com/golang/go/issues/325

package main

import (
    "fmt"
    "os"
    "syscall"
)

func main() {
    logFile, _ := os.OpenFile("/tmp/x", os.O_WRONLY|os.O_CREATE|os.O_SYNC, 0755)
    syscall.Dup2(int(logFile.Fd()), 1)
    syscall.Dup2(int(logFile.Fd()), 2)
    fmt.Printf("Hello from fmt\n")
    panic("Hello from panic\n")
}

 

这两个区别,我看到有下面描述文字:

https://github.com/golang/go/issues/325

 

 

比较变态的是,我看到下面的写法,确保记录异常日志。

if crashFile, err := os.OpenFile(fmt.Sprintf("%v--crash.log", path), os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0664); err == nil {
    crashFile.WriteString(fmt.Sprintf("%v Opened crashfile at %v", os.Getpid(), time.Now()))
    os.Stderr = crashFile
    syscall.Dup2(int(crashFile.Fd()), 2)
}   

 

 

参考资料:

怎么把所有包括底层类库,输出到stderr的内容, 重新定向到一个日志文件里面?
https://groups.google.com/forum/#!topic/golang-china/qUtCQSq6_S8

Replacing os.Stdout/os.Stderr should redirect panic #325
https://github.com/golang/go/issues/325

runtime: support for daemonize
https://github.com/golang/go/issues/227

stdin, stdout, stderr以及重定向
http://my.oschina.net/qihh/blog/55308

Windows管道(Pipe)重定向stdout,stderr,stdin
http://blog.csdn.net/c80486/article/details/6589292

stdin, stdout, stderr 详解
http://www.cnblogs.com/puputu/archive/2010/06/02/1749769.html

golang中os/exec包用法
http://blog.csdn.net/chenbaoke/article/details/42556949

12.3 应用部署
https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/12.3.md

Go到目前还没有解决成为守护进程(Daemonize)的问题吧?各位是怎么解决的?
http://segmentfault.com/q/1010000000699471

Golang把所有包括底层类库,输出到stderr的内容, 重新定向到一个日志文件里面?的更多相关文章

  1. tail -f 实时跟踪一个日志文件的输出内容

    tail -f  实时跟踪一个日志文件的输出内容 http://hittyt.iteye.com/blog/1927026 https://blog.csdn.net/mengxianhua/arti ...

  2. Linux下Shell命令的输出信息同时显示在屏幕和保存到日志文件中

    #直接覆盖日志文件 ls -l | tee ./t.log #将输出内容附加到日志文件 ls -l | tee -a ./t.log 使用的是tee命令

  3. flipt 一个基于golang 的特性工具开发类库

    以前介绍过一个Flagr 的基于golang 的特性功能开发类库(技术雷达推荐),今天看到一个类似也很不错的方案flipt 参考架构 包含的特性 快速,使用golang 编写,同时进行了性能优化 运行 ...

  4. log4j.properties配置与将异常输出到Log日志文件实例

    将异常输出到 log日志文件 实际项目中的使用: <dependencies> <dependency> <groupId>org.slf4j</groupI ...

  5. log4j配置输出到多个日志文件

    通常我们项目里,有一些重要的日志想单独的输出到指定的文件,而不是全总输出到系统的日志文件中.那么我们log4j为我们提供了这种功能,以下我们来一步一步看是怎么做的.这里以property的配置方式写. ...

  6. log4j配置输出到多个日志文件(转)

    參考资料:http://logging.apache.org/log4j/1.2/manual.html 通常我们项目里,有一些重要的日志想单独的输出到指定的文件,而不是全总输出到系统的日志文件中.那 ...

  7. log4j输出多个自定义日志文件,动态配置路径

    Log4J的配置文件(Configuration File)就是用来设置记录器的级别.存放器和布局的,它可接key=value格式的设置或xml格式的设置信息.通过配置,可以创建出Log4J的运行环境 ...

  8. 记一次log4j日志文件输出错误的解决

    log4j错误信息:log4j:ERROR Failed to rename [D:/logs/wmts_] to [D:/logs/wmts_2015-12-21.log ]. 起因:部门网站使用B ...

  9. log4j日志输出到日志文件中和控制台中 +log4j配置详解

    1.引入log4j的jar包 https://mvnrepository.com/,可以找到log4j的jar和依赖. 2.创建log4j.properties,并配置log4j #设置日志的级别 , ...

随机推荐

  1. 【文文殿下】CF1029F Multicolored Markers

    这道题考场上卡了文文相当长的时间,所以写个题解泄泄愤QAQ 题意:给你$a$块红瓷砖,$b$块白瓷砖,在一个无限大的地上拼装,要求整体是一个矩形,并且至少有一种颜色是一个矩形,求最小周长. 题解: 首 ...

  2. WebLogic “Java 反序列化”过程远程命令执行

    WebLogic “Java 反序列化”过程远程命令执行 详细信息: https://www.seebug.org/vuldb/ssvid-89726 说明: 反序列化是指特定语言中将传递的对象序列化 ...

  3. drools入门示例

    Drools是一个基于java的规则引擎,开源的,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境生效.随着互联网金融的兴 ...

  4. leetcode-887-三维形体投影面积

    题目描述: 在 N * N 的网格中,我们放置了一些与 x,y,z 三轴对齐的 1 * 1 * 1 立方体. 每个值 v = grid[i][j] 表示 v 个正方体叠放在单元格 (i, j) 上. ...

  5. day1: python3.5学习

    1. 基础知识 变量:用于存储信息,方便后面的调用 常量:python中是没有常量这一概念的,若想定义一个常量,需要将变量名大写 举例:name = "Helen"   #定义一个 ...

  6. .NET中的async和await关键字使用及Task异步调用实例

    其实早在.NET 4.5的时候M$就在.NET中引入了async和await关键字(VB为Async和Await)来简化异步调用的编程模式.我也早就体验过了,现在写一篇日志来记录一下顺便凑日志数量(以 ...

  7. weiFenLuo.winFormsUI.Docking.dll学习

    引用方法: 1.建立一个WinForm工程,默认生成了一个WinForm窗体. 2.引用—>添加引用—>浏览—>weiFenLuo.winFormsUI.Docking.dll. 3 ...

  8. linux安装oracle 报错[INS-20802] Oracle Net Configuration Assistant failed 解决办法

    [INS-20802] Oracle Net Configuration Assistant failed 首先从LinuxIDC.com下载这个补丁包,然后用 unzip p8670579_1120 ...

  9. C# .net 使用正则表达式去掉字符串中的数字

    /// <summary>/// 去掉字符串中的数字/// </summary>/// <param name="key"></param ...

  10. 【数组】Unique Paths

    题目: A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). ...