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

解决思路:

  • 自己写代码处理异常拦截,甚至直接在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. Code Chef January Challenge 2019题解

    传送门 \(div2\)那几道题不来做了太水了-- \(DPAIRS\) 一个显然合法的方案:\(A\)最小的和\(B\)所有连,\(A\)剩下的和\(B\)最大的连 算了咕上瘾了,咕咕咕 const ...

  2. 指针版P3690 【模板】Link Cut Tree (动态树)

    题面 传送门 题解 鉴于数组版实在是太慢我用指针版重新写了一遍 代码基本是借鉴了lxl某道关于\(LCT\)的题 //minamoto #include<bits/stdc++.h> #d ...

  3. hadoop-1.2.1-1.x86_64.rpm、jdk-7u45-linux-x64.tar.gz安装(64位)

    一,   配置信息 机器是64位,所以操作系统.软件都是64位的. 操作系统:CentOS6.2(64位): Hadoop是hadoop-1.2.1-1.x86_64.rpm: JDK是jdk-7u4 ...

  4. [转] 红帽7搭建Zabbix监控

    zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案. zabbix能监视各种网络参数,保证服务器系统的安全运营:并提供灵活的通知机制以让系统管理员快速定位/解决 ...

  5. Windows文件共享,报错"该用户已禁用"解决方案

    文章背景:学校机器有俩个用户think和adminsitrator.默认administrator禁用,think属于administrators组. 经排错得问题出现情况.因为同学们都是Think用 ...

  6. 48.rocketMQ

    一.简介 RocketMQ是阿里旗下的一款产品,分为开源版本和非开源版本.相比于ActiveMQ,RocketMQ支持顺序消费.事务机制.失败重试机制.消息可查询.消息订阅.较强的水平扩展能力.亿级堆 ...

  7. 架构师养成记--35.redis集群搭建

    前记:redis哨兵经验之谈.哨兵做主从切换可能要花费一两秒,这一两秒可能会丢失很多数据.解决方法之一是在java代码中做控制,try catch 到 链接断开的异常就sleep 一两秒钟再conti ...

  8. 新人须知的网站文件和MySQL数据库备份流程思路

    昨天老左再次遇到一个网友告知使用的一台服务器自己无意中点击主机商面板的导致服务器被重新安装系统(居然这也可以),问问是否可以恢复数据.这个同学和之前遇到好几次的网友真相似,从开始购买服务器,到自己网站 ...

  9. jQuery 获取元素当前位置offset()与position()

    <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8& ...

  10. [ZJOI2019]语言[树链的并、线段树合并]

    题意 题目链接 分析 考虑枚举每个点的答案,最后除以 2 即可. 可以与 \(u\) 构成合法点对 的集合 为所有经过了 \(u\) 的链的并.因为这些链两两有交,根据结论 "树上两条相交的 ...