折腾:

【已解决】go语言中实现log信息同时输出到文件和控制台(命令行)

期间,已经通过io的MultiWriter搞定了同时输出信息到文件和console,但是不支持level。

所以,再去试试这个log4go。

github.com/keepeye/log4go

【折腾过程】

1.大概看了看,貌似功能很强大。

有点类似于之前的C#的NLog,为C#的log功能扩展;

此处log4go,是针对go语言的log功能的扩展。

2.此log4go,是go语言的第三方的包,所以,先要去搞懂:

【记录】go语言中安装第三方包package(库):log4go

3.安装完毕后,再去参考官网的:

http://code.google.com/p/log4go/wiki/GettingStarted

去看看如何使用。

4.先去导入:

1
2
//import l4g "log4go.googlecode.com/hg"
import l4g "code.google.com/p/log4go"

结果是:

1
2
3
E:\Dev_Root\go\src\EmulateLoginBaidu>go run EmulateLoginBaidu.go
# command-line-arguments
.\EmulateLoginBaidu.go:34: imported and not used: "code.google.com/p/log4go"

这说明:

正确导入了(但只是暂时还没去使用而已)

5.接着去使用。

用如下代码:

1
2
3
4
5
6
7
8
9
10
11
//do some init for crifanLib
func initCrifanLib(){
    l4g.Info("init for crifanLib")
    //gLogger.Println("init for crifanLib");
    gCurCookies = nil
    return
}
 
//init for logger
func initLogger(){
    l4g.Debug("in initLogger")

效果是:

6.看到其解释了:

上述用的,是默认的,已经实现了的,对于console的log

默认配置为:DEBUG的level:debug及以上的level都显示。

所有的level,依次是:Finest, Fine, Debug, Trace, Info, Warning, Error, Critical

而此处,我想要实现:

(1)重新更改此console的level为Info

(2)添加此处的log文件作为输出,且设置level所有,即最低一级的Finest

7.先去添加log文件:

但是想要去看对应的文档的,结果原先作者的说明:

先去:

1
godoc -http=:6060

(我此处实际上本身已经打开godoc的server了)

再去打开地址:

http://localhost:6060/pkg/log4go.googlecode.com/svn/stable/

结果肯定不对的。

后来经过自己的分析,去访问:

http://localhost:6060/pkg/code.google.com/p/log4go/

就可以了。

8.去看看对应的:

http://localhost:6060/pkg/code.google.com/p/log4go/#AddFilter

内容是:

func AddFilter

func AddFilter(name string, lvl level, writer LogWriter)

Wrapper for (*Logger).AddFilter

去试试代码。

结果基本实现了所要的效果:

即:

对于代码中debug信息,只在文件中显示

对于info及以上的信息,console和文件,都显示。

实现了level的自定义。

9.目前,唯一一个小问题,不是我喜欢的:

对于,我经常调试程序,

希望每次重新运行时,对于log文件,都自动清空。

而不要对于log文件是APPEND模式:

每次的输出,都添加到后面。

而不清空log文件。

10.所以,再去想办法,新建log时,判断是否已经存在文件,如果存在去删除掉:

【已解决】go语言中判断文件是否存在如果有已存在则删除

【总结】

最终,基本实现了全部的效果:

1.每次运行程序,可以OVERWRITE旧的log文件,而不是APPEND

2.可以同时输出内容到log文件和console

3.且console和log文件的输出level都可以配置:

此处要的是:

INFO及以上的,都可以在console中显示;

全部信息(包括debug),都可以在log文件中显示。

全部代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*
 * [File]
 * EmulateLoginBaidu.go
 *
 * [Function]
 * 【记录】用go语言实现模拟登陆百度
 *
 * [Version]
 * 2013-09-19
 *
 * [Contact]
 */
package main
 
import (
    //"fmt"
    //"builtin"
    //"log"
    "os"
    "runtime"
    "path"
    "strings"
    //"io"
    "time"
    "io/ioutil"
    "net/http"
    //"net/http/cookiejar"
    //"sync"
    //"net/url"
)
 
//import l4g "log4go.googlecode.com/hg"
//import l4g "code.google.com/p/log4go"
import "

github.com/keepeye/log4go

"

 
/***************************************************************************************************
    Global Variables
***************************************************************************************************/
var gCurCookies []*http.Cookie;
//var gLogger *log.Logger;
var gLogger log4go.Logger;
 
/***************************************************************************************************
    Functions
***************************************************************************************************/
//do init before all others
func initAll(){
    gCurCookies = nil
    gLogger = nil
     
    initLogger()
    initCrifanLib()
}
 
//de-init for all
func deinitAll(){
    gCurCookies = nil
    if(nil == gLogger) {
        gLogger.Close();
        gLogger = nil
    }
}
 
//do some init for crifanLib
func initCrifanLib(){
    gLogger.Debug("init for crifanLib")
    gCurCookies = nil
    return
}
 
//init for logger
func initLogger(){
    var filenameOnly string
    filenameOnly = GetCurFilename()
    var logFilename string =  filenameOnly + ".log";
     
    //gLogger = log4go.NewLogger()
    gLogger = make(log4go.Logger)
    //for console
    //gLogger.AddFilter("stdout", log4go.INFO, log4go.NewConsoleLogWriter())
    gLogger.AddFilter("stdout", log4go.INFO, log4go.NewConsoleLogWriter())
    //for log file
    if _, err := os.Stat(logFilename); err == nil {
        //fmt.Printf("found old log file %s, now remove it\n", logFilename)
        os.Remove(logFilename)
    }
    //gLogger.AddFilter("logfile", log4go.FINEST, log4go.NewFileLogWriter(logFilename, true))
    gLogger.AddFilter("logfile", log4go.FINEST, log4go.NewFileLogWriter(logFilename, false))
    gLogger.Info("Current time is : %s", time.Now().Format("15:04:05 MST 2006/01/02"))
 
    return
}
 
// GetCurFilename
// Get current file name, without suffix
func GetCurFilename() string {
    _, fulleFilename, _, _ := runtime.Caller(0)
    //fmt.Println(fulleFilename)
    var filenameWithSuffix string
    filenameWithSuffix = path.Base(fulleFilename)
    //fmt.Println("filenameWithSuffix=", filenameWithSuffix)
    var fileSuffix string
    fileSuffix = path.Ext(filenameWithSuffix)
    //fmt.Println("fileSuffix=", fileSuffix)
     
    var filenameOnly string
    filenameOnly = strings.TrimSuffix(filenameWithSuffix, fileSuffix)
    //fmt.Println("filenameOnly=", filenameOnly)
     
    return filenameOnly
}
 
//get url response html
func GetUrlRespHtml(url string) string{
    gLogger.Debug("GetUrlRespHtml, url=%s", url)
    var respHtml string = "";
     
    resp, err := http.Get(url)
    if err != nil {
        gLogger.Warn("http get url=%s response errror=%s\n", url, err)
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    //gLogger.Debug("body=%s\n", body)
 
    gCurCookies = resp.Cookies()
     
    respHtml = string(body)
 
    return respHtml
}
 
func printCurCookies() {
    var cookieNum int = len(gCurCookies);
    gLogger.Info("cookieNum=%d", cookieNum)
    for i := 0; i < cookieNum; i++ {
        var curCk *http.Cookie = gCurCookies[i];
        //gLogger.Info("curCk.Raw=%s", curCk.Raw)
        gLogger.Info("------ Cookie [%d]------", i)
        gLogger.Info("Name\t=%s", curCk.Name)
        gLogger.Info("Value\t=%s", curCk.Value)
        gLogger.Info("Path\t=%s", curCk.Path)
        gLogger.Info("Domain\t=%s", curCk.Domain)
        gLogger.Info("Expires\t=%s", curCk.Expires)
        gLogger.Info("RawExpires=%s", curCk.RawExpires)
        gLogger.Info("MaxAge\t=%d", curCk.MaxAge)
        gLogger.Info("Secure\t=%t", curCk.Secure)
        gLogger.Info("HttpOnly=%t", curCk.HttpOnly)
        gLogger.Info("Raw\t=%s", curCk.Raw)
        gLogger.Info("Unparsed=%s", curCk.Unparsed)
    }
}
 
func main() {
    initAll()
 
    gLogger.Info("this is EmulateLoginBaidu.go")
 
    var baiduMainUrl string
    baiduMainUrl = "http://www.baidu.com/";
    //baiduMainUrl := "http://www.baidu.com/";
    //var baiduMainUrl string = "http://www.baidu.com/";
    gLogger.Info("baiduMainUrl=%s", baiduMainUrl)
    respHtml := GetUrlRespHtml(baiduMainUrl)
    gLogger.Debug("respHtml=%s", respHtml)
    printCurCookies()
     
    deinitAll()
}

效果是:

console中输出的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
E:\Dev_Root\go\src\EmulateLoginBaidu>go run EmulateLoginBaidu.go
[09/20/13 18:39:40] [INFO] Current time is : 18:39:40 +0800 2013/09/20
[09/20/13 18:39:40] [INFO] this is EmulateLoginBaidu.go
[09/20/13 18:39:40] [INFO] baiduMainUrl=http://www.baidu.com/
[09/20/13 18:39:40] [INFO] cookieNum=3
[09/20/13 18:39:40] [INFO] ------ Cookie [0]------
[09/20/13 18:39:40] [INFO] Name =BDSVRTM
[09/20/13 18:39:40] [INFO] Value        =3
[09/20/13 18:39:40] [INFO] Path =/
[09/20/13 18:39:40] [INFO] Domain       =
[09/20/13 18:39:40] [INFO] Expires      =0001-01-01 00:00:00 +0000 UTC
[09/20/13 18:39:40] [INFO] RawExpires=
[09/20/13 18:39:40] [INFO] MaxAge       =0
[09/20/13 18:39:40] [INFO] Secure       =false
[09/20/13 18:39:40] [INFO] HttpOnly=false
[09/20/13 18:39:40] [INFO] Raw  =BDSVRTM=3; path=/
[09/20/13 18:39:40] [INFO] Unparsed=[]
[09/20/13 18:39:40] [INFO] ------ Cookie [1]------
[09/20/13 18:39:40] [INFO] Name =H_PS_PSSID
[09/20/13 18:39:40] [INFO] Value        =3415_1431_2975_2981
[09/20/13 18:39:40] [INFO] Path =/
[09/20/13 18:39:40] [INFO] Domain       =.baidu.com
[09/20/13 18:39:40] [INFO] Expires      =0001-01-01 00:00:00 +0000 UTC
[09/20/13 18:39:40] [INFO] RawExpires=
[09/20/13 18:39:40] [INFO] MaxAge       =0
[09/20/13 18:39:40] [INFO] Secure       =false
[09/20/13 18:39:40] [INFO] HttpOnly=false
[09/20/13 18:39:40] [INFO] Raw  =H_PS_PSSID=3415_1431_2975_2981; path=/; domain=.baidu.com
[09/20/13 18:39:40] [INFO] Unparsed=[]
[09/20/13 18:39:40] [INFO] ------ Cookie [2]------
[09/20/13 18:39:40] [INFO] Name =BAIDUID
[09/20/13 18:39:40] [INFO] Value        =AF99372EE54C9816618EED94475DDD26:FG=1
[09/20/13 18:39:40] [INFO] Path =/
[09/20/13 18:39:40] [INFO] Domain       =.baidu.com
[09/20/13 18:39:40] [INFO] Expires      =0001-01-01 00:00:00 +0000 UTC
[09/20/13 18:39:40] [INFO] RawExpires=Fri, 20-Sep-43 10:39:32 GMT
 
E:\Dev_Root\go\src\EmulateLoginBaidu>

log文件中输出的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
[2013/09/20 18:39:40 ] [INFO] (main.initLogger:91) Current time is : 18:39:40 +0800 2013/09/20
[2013/09/20 18:39:40 ] [DEBG] (main.initCrifanLib:68) init for crifanLib
[2013/09/20 18:39:40 ] [INFO] (main.main:159) this is EmulateLoginBaidu.go
[2013/09/20 18:39:40 ] [INFO] (main.main:165) baiduMainUrl=http://www.baidu.com/
[2013/09/20 18:39:40 ] [DEBG] (main.GetUrlRespHtml:117) GetUrlRespHtml, url=http://www.baidu.com/
[2013/09/20 18:39:40 ] [DEBG] (main.main:167) respHtml=<!DOCTYPE html><!--STATUS OK--><html><head><meta http-equiv="content-type" content="text/html;charset=utf-8"><title>百度一下,你就知道</title><style >html,.......... new Date(_t + 10000).toGMTString()})}catch(e){}</script></html><!--0556c44ca22cac33-->
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:137) cookieNum=3
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:141) ------ Cookie [0]------
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:142) Name   =BDSVRTM
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:143) Value  =3
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:144) Path   =/
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:145) Domain =
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:146) Expires    =0001-01-01 00:00:00 +0000 UTC
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:147) RawExpires=
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:148) MaxAge =0
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:149) Secure =false
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:150) HttpOnly=false
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:151) Raw    =BDSVRTM=3; path=/
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:152) Unparsed=[]
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:141) ------ Cookie [1]------
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:142) Name   =H_PS_PSSID
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:143) Value  =3415_1431_2975_2981
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:144) Path   =/
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:145) Domain =.baidu.com
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:146) Expires    =0001-01-01 00:00:00 +0000 UTC
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:147) RawExpires=
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:148) MaxAge =0
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:149) Secure =false
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:150) HttpOnly=false
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:151) Raw    =H_PS_PSSID=3415_1431_2975_2981; path=/; domain=.baidu.com
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:152) Unparsed=[]
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:141) ------ Cookie [2]------
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:142) Name   =BAIDUID
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:143) Value  =AF99372EE54C9816618EED94475DDD26:FG=1
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:144) Path   =/
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:145) Domain =.baidu.com
[2013/09/20 18:39:40 ] [INFO] (main.printCurCookies:146) Expires    =0001-01-01 00:00:00 +0000 UTC

整体效果还不错的说。

Go -- log4go日志的更多相关文章

  1. 改进log4go的一些设想

    log4go 的 4.0.2 版本(https://github.com/ccpaging/log4go/tree/4.0.2)发布以后, 看了看别的 go 语言日志文件设计.发现了一篇好文: log ...

  2. log4go的一些改进设想

    log4go 的 4.0.2 版本(https://github.com/ccpaging/log4go/tree/4.0.2)发布以后, 看了看别的 go 语言日志文件设计.发现了一篇好文: log ...

  3. log4go的日志滚动处理——适应生产环境的需要

    日志处理有三类使用环境,开发环境DE,测试环境TE,生产环境PE. 前两类可以看成是一类,重要的是屏幕显示--termlog.生产环境中主要用的是socklog 和 filelog,即网络传输日志和文 ...

  4. nxlog4go 简介 - 基于log4go的下一代go语言日志系统

    nxlog4go的项目网址: https://github.com/ccpaging/nxlog4go 项目历史 ccpaging's log4go forked from https://githu ...

  5. log4go的日志滚动处理——生产环境的适配

    日志处理有三类使用环境,开发环境DE,测试环境TE,生产环境PE. 前两类可以看成是一类,重要的是屏幕显示--termlog.生产环境中主要用的是socklog 和 filelog,即网络传输日志和文 ...

  6. log4go 的 Bug Fix 及 增强

    log4go 一直存在关闭时丢失记录的问题.网络上很多人怀疑是Flush.经过跟踪发现只要在 Close() 函数中增加以下语句: for i := 10; i > 0 && l ...

  7. log4go的全局封装Wrapper和标准log库函数的兼容

    方便易用的全局函数 大多数时候,只不过是写一个简单的测试程序.例如: package main import ( "log" ) func main(){ log.Fatal(&q ...

  8. log4go的输出优化

    又看了一些golang的日志包和相关的文章,仔细阅读了go 1.9.2系统提供的log和go-log,产生了对log4go的日志输出进行优化的想法. 结构化与multiwriter log使用mult ...

  9. golang的日志系统log和glog

    go语言有一个标准库,log,提供了最基本的日志功能,但是没有什么高级的功能,如果需要高级的特性,可以选择glog或log4go. 参考:https://cloud.tencent.com/devel ...

随机推荐

  1. 【Git版本控制】git---从已有分支拉出新的分支

    参考博文:git---从已有分支拉出新分支

  2. centos7 parted 扩容

    (系统:vmware上的centos7.4 ,使用工具:parted分区命令.) 最近发现磁盘不够用了,需要加点.## WARNING ! 下面是实验过程,不代表生产环境.若有重要数据请操作前备份. ...

  3. docker参考文档

    docker 使用笔记 http://www.cnblogs.com/xguo/p/3829329.html docker数据存储 | 单线程 http://opjasee.com/2014/06/2 ...

  4. UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 287: ordinal not in range(128)

    python的str默认是ascii编码,和unicode编码冲突,就会报这个错误. import sys reload(sys) sys.setdefaultencoding('utf8')

  5. ACM训练联盟周赛 G. Teemo's convex polygon

    65536K   Teemo is very interested in convex polygon. There is a convex n-sides polygon, and Teemo co ...

  6. oracle 安装 启动listener 建库相关

    安装 参考 http://www.cnblogs.com/gaojun/archive/2012/11/22/2783257.html 几个问题: 1. 用户删除问题 p001:~ # userdel ...

  7. hdu6069[素数筛法] 2017多校4

    对于[l , r]内的每个数,根据唯一分解定理有   所以有  因为     //可根据唯一分解定理推导 所以      题目要求 就可以运用它到上述公式 (注意不能暴力对l,r内的数一个个分解算贡献 ...

  8. Python之虚拟机操作:利用VIX二次开发,实现自己的pyvix(系列一)成果展示和python实例

    在日常工作中,需要使用python脚本去自动化控制VMware虚拟机,现有的pyvix功能较少,而且不适合个人编程习惯,故萌发了开发一个berlin版本pyvix的想法,暂且叫其OpenPyVix.O ...

  9. 【Luogu】P1312Mayan游戏(暴搜)

    题目链接 由于是暴搜题,所以这篇博客只讲怎么优化剪枝,以及一些细节. 模拟消除思路:因为消除可以拆分成小的横条或竖条,而这些条的长度至少为三,所以一块可消除的区域至少会有一个中心点.这里的中心点可以不 ...

  10. BZOJ 1855 [Scoi2010]股票交易 ——动态规划

    DP方程是比较简单的,主要有三种:什么都不做.买入.卖出. 发现买入卖出都是$\Theta (n^3)$但是转移方程都是线性的,而且决策和当前的情况是分开的. 所以可以单调队列优化. 复杂度$\The ...