原文:https://www.goinggo.net/2013/11/using-log-package-in-go.html

----------------------------------------------------------------------------------------------------------------

Linux is unique to Windows in many ways, and writing programs in Linux is no exception. The use of standard out, standard err and null devices is not only a good idea but it’s the law. If your programs are going to be logging information, it is best to follow the destination conventions. This way your programs will work with all of the Mac/Linux tooling and hosted environments.

Go has a package in the standard library called log and a type called logger. Using the log package will give you everything you need to be a good citizen. You will be able to write to all the standard devices, custom files or any destination that support the io.Writer interface.

I have provided a really simple sample that will get you started with using logger:

package main

import (
    "io"
    "io/ioutil"
    "log"
    "os"
)

var (
    Trace   *log.Logger
    Info    *log.Logger
    Warning *log.Logger
    Error   *log.Logger
)

func Init(
    traceHandle io.Writer,
    infoHandle io.Writer,
    warningHandle io.Writer,
    errorHandle io.Writer) {

Trace = log.New(traceHandle,
        "TRACE: ",
        log.Ldate|log.Ltime|log.Lshortfile)

Info = log.New(infoHandle,
        "INFO: ",
        log.Ldate|log.Ltime|log.Lshortfile)

Warning = log.New(warningHandle,
        "WARNING: ",
        log.Ldate|log.Ltime|log.Lshortfile)

Error = log.New(errorHandle,
        "ERROR: ",
        log.Ldate|log.Ltime|log.Lshortfile)
}

func main() {
    Init(ioutil.Discard, os.Stdout, os.Stdout, os.Stderr)

Trace.Println("I have something standard to say")
    Info.Println("Special Information")
    Warning.Println("There is something you need to know about")
    Error.Println("Something has failed")
}

When you run this program you will get the follow output:

INFO: 2013/11/05 18:11:01 main.go:44: Special Information
WARNING: 2013/11/05 18:11:01 main.go:45: There is something you need to know about
ERROR: 2013/11/05 18:11:01 main.go:46: Something has failed

You will notice that Trace logging is not being displayed. Let’s look at the code to find out why.

Look at the Trace logger pieces:

var Trace *log.Logger

Trace = log.New(traceHandle,
    "TRACE: ",
    log.Ldate|log.Ltime|log.Lshortfile)

Init(ioutil.Discard, os.Stdout, os.Stdout, os.Stderr)

Trace.Println("I have something standard to say")

The code creates a package level variable called Trace which is a pointer to a log.Logger object. Then inside the Init function, a new log.Logger object is created. The parameters to the log.New function are as follows:

func New(out io.Writer, prefix string, flag int) *Logger

out:    The out variable sets the destination to which log data will be written.
prefix: The prefix appears at the beginning of each generated log line.
flags:  The flag argument defines the logging properties.

Flags:
const (
// Bits or’ed together to control what’s printed. There is no control over the
// order they appear (the order listed here) or the format they present (as
// described in the comments). A colon appears after these items:
// 2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message
Ldate = 1 << iota // the date: 2009/01/23
Ltime             // the time: 01:23:23
Lmicroseconds     // microsecond resolution: 01:23:23.123123. assumes Ltime.
Llongfile         // full file name and line number: /a/b/c/d.go:23
Lshortfile        // final file name element and line number: d.go:23. overrides Llongfile
LstdFlags = Ldate | Ltime // initial values for the standard logger
)

In this sample program the destination for Trace is ioutil.Discard. This is a null device where all write calls succeed without doing anything. Therefore when you write using Trace, nothing appears in the terminal window.

Look at Info:

var Info *log.Logger

Info = log.New(infoHandle,
    "INFO: ",
    log.Ldate|log.Ltime|log.Lshortfile)

Init(ioutil.Discard, os.Stdout, os.Stdout, os.Stderr)

Info.Println("Special Information")

For Info os.Stdout is passed into Init for the infoHandle. This means when you write using Info, the message will appear on the terminal window, via standard out.

Last, look at Error:

var Error *log.Logger

Error = log.New(errorHandle,
    "INFO: ",
    log.Ldate|log.Ltime|log.Lshortfile)

Init(ioutil.Discard, os.Stdout, os.Stdout, os.Stderr)

Error.Println("Special Information")

This time os.Stderr is passed into Init for the errorHandle. This means when you write using Error, the message will appear on the terminal window, via standard error. However, passing these messages to os.Stderr allows other applications running your program to know an error has occurred.

Since any destination that support the io.Writer interface is accepted, you can create and use files:

file, err := os.OpenFile("file.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
    log.Fatalln("Failed to open log file", output, ":", err)
}

MyFile = log.New(file,
    "PREFIX: ",
    log.Ldate|log.Ltime|log.Lshortfile)

In the sample code, a file is opened and then passed into the log.New call. Now when you use MyFile to write, the writes go to file.txt.

You can also have the logger write to multiple destinations at the same time.

file, err := os.OpenFile("file.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
    log.Fatalln("Failed to open log file", output, ":", err)
}

multi := io.MultiWriter(fileos.Stdout)

MyFile := log.New(multi,
    "PREFIX: ",
    log.Ldate|log.Ltime|log.Lshortfile)

Here writes are going to the file and to standard out.

Notice the use of log.Fatalln in the handling of any error with OpenFile. The log package provides an initial logger that can be configured as well. Here is a sample program using log with the standard configuration:

package main

import (
    "log"
)

func main() {
    log.Println("Hello World")
}

Here is the output:

2013/11/05 18:42:26 Hello World

If you want to remove the formatting or change it, you can use the log.SetFlags function:

package main

import (
    "log"
)

func main() {
    log.SetFlags(0)
    log.Println("Hello World")
}

Here is the output:

Hello World

Now all the formatting has been removed. If you want to send the output to a different destination use the log.SetOutput:

package main

import (
    "io/ioutil"
    "log"
)

func main() {
    log.SetOutput(ioutil.Discard)
    log.Println("Hello World")
}

Now nothing will display on the terminal window. You can use any destination that support the io.Writer interface.

Based on this example I wrote a new logging package for all my programs:

go get github.com/goinggo/tracelog

I wish I knew about log and loggers when I started writing Go programs. Expect to see a lot more of the log package from me in the future.

go语言使用官方的 log package 来记录日志的更多相关文章

  1. Visual Studio 2013 RTM 中文语言包官方下载地址发布

    如果你下载的是英文版,你想安装一个中文的visual studio 2013,那么你大可不必重新下载安装visual studio 2013,因为微软提供了Visual Studio 2013 RTM ...

  2. 【原创】go语言学习(十一)package简介

    目录 Go源码组织方式 main函数和main包 编译命令 自定义包 init函数以及执行行顺序 _标识符 Go源码组织方式 1. Go通过package的方式来组织源码 package 包名 注意: ...

  3. centos 6.4 /var/log/secure 不记录日志的問題

    先确保日志服务开启:不妨重启下日志服务:由于目前RHEL 6/centos 6已经使用rsyslog替换了syslog.,所以不要在找/etc/syslog.conf了:重启命令:/etc/init. ...

  4. go语言碎片整理之标准库log

    log Go语言内置的log包实现了简单的日志服务.本文介绍了标准库log的基本使用. 使用Logger log包定义了Logger类型,该类型提供了一些格式化输出的方法.本包也提供了一个预定义的“标 ...

  5. Go语言系列之标准库log

    Go语言内置的log包实现了简单的日志服务.本文介绍了标准库log的基本使用. 使用Logger log包定义了Logger类型,该类型提供了一些格式化输出的方法.本包也提供了一个预定义的" ...

  6. Python 官方中文教程(简)

    Python 官方教程 前言 这是一次系统学习Python官方教程的学习笔记 整个教程一共16章, 在学习过程中记录自己不知道的和一些重要的知识, 水平有限, 请指正. Python3.7 官方教程. ...

  7. Android与Swift iOS开发:语言与框架对比

    Swift是现在Apple主推的语言,2014年新推出的语言,比Scala等“新”语言还要年轻10岁.2015年秋已经开源.目前在linux上可用,最近已经支持Android NDK:在树莓派上有Sw ...

  8. 【Go语言】集合与文件操作

    本文目录 1.数据集合的主要操作 1_1.字典的声明 1_2.字典的初始化和创建 1_3.字典的访问和操作 1_4.其他类型的数据集 2.文件操作 2_1.文件操作概述os包和path包 2_2.文件 ...

  9. Go语言学习笔记(一) : 搭建Windows下的Go开发环境

    最近突然对Go语言产生了兴趣,主要是因为在使用python的时候遇到了一些不爽的问题,然后发现了Go.Go是Google出的一个动态语言,语法和C++接近,性能也非常的好,而且还支持编译成exe发布, ...

随机推荐

  1. 专题十二:实现一个简单的FTP服务器

    引言: 在本专题中将和大家分享如何自己实现一个简单的FTP服务器.在我们平时的上网过程中,一般都是使用FTP的客户端来对商家提供的服务器进行访问(上传.下载文件),例如我们经常用到微软的SkyDriv ...

  2. [ TJOI 2010 ] 打扫房间

    \(\\\) Description 给出一个\(N\times M\) 的网格,一些格子是污点,求是否能用多个封闭的环路覆盖所有不是污点的格点. 封闭的环路覆盖的含义是,每条路径都必须是一个环,且每 ...

  3. CSS 潜藏着的BFC

    在写样式时,往往是添加了一个样式,又或者是修改了某个属性,就达到了我们的预期. 而BFC就潜藏在其中,当你修改样式时,一不小心就能触发它而毫无察觉,因此没有意识到BFC的神奇之处. 什么是BFC(Bl ...

  4. express模块安装使用命令配置

    之前的博客nodejs安装和配置好路径之后就可以安装express了: 随便打开个文件夹右键选择,git bash here 命令行里输入[npm install express -g] -g是全局安 ...

  5. text-shadow的用法详解

    1.兼容性:text-shadow 和 box-shadow 这两个属性在主流现代浏览器上得到了很好的支持( > Chrome 4.0, > Firefox 3.5, > Safar ...

  6. centos上安装supervisor来管理dotnetcore等应用程序

    supervisor 介绍: 这是一款用python编写的进程管理工具,可以守护他管理的所有进程,防止异常退出,以及提供一个可视化的web界面来手动管理,打开关闭重启各种应用,界面如下: 关于在cen ...

  7. Android Studio 入门 Hello World

    Android Studio 入门 Hello World Gavin要加油 1.5k 6月22日 发布 推荐 1 推荐 收藏 17 收藏,2.1k 浏览 引言 前两天开始学习android开发,本来 ...

  8. 安装好Pycharm后如何配置Python解释器简易教程

    呃呃,遇到坑了...... 安装完Python,没有去配置好Python解释器,直接打开Python项目包,去运行程序,程序输出结果只是显示 Process finished with exit co ...

  9. Linux文件排序和FASTA文件操作

    文件排序 seq: 产生一系列的数字; man seq查看其具体使用.我们这使用seq产生下游分析所用到的输入文件. # 产生从1到10的数,步长为1 $ seq 1 10 1 2 3 4 5 6 7 ...

  10. CAD得到所有实体方法(网页版)

    主要用到函数说明: IMxDrawSelectionSet::AllSelect 得到当前空间的所有实体.详细说明如下: 参数 说明 [in,defaultvalue(NULL)] IMxDrawRe ...