打印

在使用go写一些小程序时,我们没必要引入额外的包,直接使用fmt标准包打印即可:

import "fmt"func main() {fmt.Println("line1")fmt.Print("line2")fmt.Printf("line%d \n", 3)str1 := fmt.Sprintln("hello", 3)str2 := fmt.Sprint("hello ", 1, " 2")str3 := fmt.Sprintf("hello %d", 1)fmt.Print(str1, str2, str3)
}
line1
line2line3
hello 3
hello 1 2hello 1

那么,有些场景下,我们希望能同时打印到日志文件中要怎么办呢?

log包

标准库提供了log组件,用法和fmt一致,有3种方式:

import “log"func main() {log.Println("line1")log.Print("line2")log.Printf("line%d \n", 3)
}

和fmt的区别就是多了时间:

2021/08/25 17:23:47 line1
2021/08/25 17:23:47 line2
2021/08/25 17:23:47 line3

我们通过SetFlag函数,可以设置打印的格式:

// For example, flags Ldate | Ltime (or LstdFlags) produce,
// 2009/01/23 01:23:23 message
// while flags Ldate | Ltime | Lmicroseconds | Llongfile produce,
// 2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message
const (Ldate         = 1 << iota     // the date in the local time zone: 2009/01/23Ltime                         // the time in the local time zone: 01:23:23Lmicroseconds                 // microsecond resolution: 01:23:23.123123.  assumes Ltime.Llongfile                     // full file name and line number: /a/b/c/d.go:23Lshortfile                    // final file name element and line number: d.go:23. overrides LlongfileLUTC                          // if Ldate or Ltime is set, use UTC rather than the local time zoneLmsgprefix                    // move the "prefix" from the beginning of the line to before the messageLstdFlags     = Ldate | Ltime // initial values for the standard logger
)

比如,我们只需要时间和文件名:

import “log"func main() {log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)log.Println("line1")log.Print("line2")log.Printf("line%d \n", 3)
}

此时,再次运行,则会打印文件和行号:

2021/08/25 17:27:56 mod_unread_redis.go:32: line1
2021/08/25 17:27:56 mod_unread_redis.go:33: line2
2021/08/25 17:27:56 mod_unread_redis.go:34: line3

如何输出日志到文件?

log包使用非常简单,默认情况下,只会输出到控制台。

我们可以使用SetOutput改变输出流,比如输出到文件。

先来看一下函数原型,其接收一个io.Writer接口:

// SetOutput sets the output destination for the standard logger.
func SetOutput(w io.Writer) {// ...
}

那么,我们就可以创建一个文件流设置一下就行了。

// 创建、追加、读写,777,所有权限
f, err := os.OpenFile("log.log", os.O_CREATE|os.O_APPEND|os.O_RDWR, os.ModePerm)
if err != nil {return
}
defer func() {f.Close()
}()log.SetOutput(f)

此时,在运行,我们发现日志会输出到文件,但是控制台没有任何东西输出了。

如何同时输出到控制台和文件?

标准库io包中,有一个MultiWriter,可以把文件流和控制台标准输出流整合到一个io.Writer上,其实现上就是一个数组,在执行写操作时,遍历数组:

// MultiWriter creates a writer that duplicates its writes to all the
// provided writers, similar to the Unix tee(1) command.
//
// Each write is written to each listed writer, one at a time.
// If a listed writer returns an error, that overall write operation
// stops and returns the error; it does not continue down the list.
func MultiWriter(writers ...Writer) Writer {allWriters := make([]Writer, 0, len(writers))for _, w := range writers {if mw, ok := w.(*multiWriter); ok {allWriters = append(allWriters, mw.writers...)} else {allWriters = append(allWriters, w)}}return &multiWriter{allWriters}
}// 重写io.Writer的Write函数函数,本质上就是遍历数组,比较巧妙
func (t *multiWriter) Write(p []byte) (n int, err error) {for _, w := range t.writers {n, err = w.Write(p)if err != nil {return}if n != len(p) {err = ErrShortWritereturn}}return len(p), nil
}

使用方式如下:

func main() {f, err := os.OpenFile("log.log", os.O_CREATE|os.O_APPEND|os.O_RDWR, os.ModePerm)if err != nil {return}defer func() {f.Close()}()// 组合一下即可,os.Stdout代表标准输出流multiWriter := io.MultiWriter(os.Stdout, f)log.SetOutput(multiWriter)log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)log.Println("line1")log.Print("line2")log.Printf("line%d \n", 3)
}

此时,再运行,则会同时输出到控制台和文件中。

2021/08/25 17:38:02 mod_unread_redis.go:42: line1
2021/08/25 17:38:02 mod_unread_redis.go:43: line2
2021/08/25 17:38:02 mod_unread_redis.go:44: line3


最后更新时间:2022-04-21

Go标准库日志打印,以及同时输出到控制台和文件相关推荐

  1. Android日志输出到控制台、文件(XLog开源日志工具)

    Android日志输出到控制台.文件(XLog开源日志工具) Android项目开发中,需要将Log同时输出到控制台 与 文件,并要求将日志文件压缩并上传到远程服务端(便于分析App使用过程中用户反馈 ...

  2. NDK中C++标准库、STL的配置;Include其他头文件

    原文: Android学习笔记--NDK中C++标准库.STL的配置:Include其他头文件 1.STL的使用,以stlport为例 官方的说法是只需要在Application.mk文件中添加如下一 ...

  3. Python3 日志同时输出到控制台和文件

    python3中想要将程序的日志打印到文件中,便于后期查看原因.但是在开发阶段又想让日志打印到控制台,这时候可以用一个类将其封装起来,用法就跟java差不多,配置也很简单. 需要用到python内置模 ...

  4. log日志打印封装,并保存到本地文件

    封装了本地日志,可以通过config 文件动态控制log的打印,方便上线前日志打印的检查,并且如果在测试环境下,日志等级为i以上的日志都会存文件,并且文件以日期命名,最大数量为5,可以配置. 代码如下 ...

  5. Go 学习笔记(46)— Go 标准库之 fmt(输入/输出格式化参数、Printf/Fprintf/Sprintf区别、Println/Fprintln/Sprintln 区别)

    1. 概述 import "fmt" fmt 包实现了类似 C 语言 printf 和 scanf 的格式化 I/O .格式化动作( verb )源自 C 语言但更简单. 2. P ...

  6. 标准库:pprint --- 数据美化输出

    Lib/pprint.py pprint 模块提供了"美化打印"任意 Python 数据结构的功能,这种美化形式可用作对解释器的输入. 如果经格式化的结构包含非基本 Python ...

  7. 使用Microsoft EnterpriseLibrary(微软企业库)日志组件把系统日志写入数据库和xml文件...

    这里只是说明在项目中如何配置使用微软企业库的日志组件,对数据库方面的配置请参考其他资料. 1.在项目中添加Microsoft.Practices.EnterpriseLibrary.Data.dll. ...

  8. C++ MFC日志Log类 棒棒的 控制台或文件或一起输出

    设置MFC边操作边通过控制台实时看printf日志 #include "pch.h" #include "log_sys.h"// 默认构造函数 Logger: ...

  9. 将js中console.log打印的内容输出保存到txt文件的简单方法

    方法 :结合DOS 简单的将输出信息保存到一个文件命令以及用node执行js代码的方法 电脑cmd输入如下命令: node print.js >D:\output.txt 其中node为安装好的 ...

最新文章

  1. lt;二gt;读lt;lt;大话设计模式gt;gt;之策略模式
  2. redis 4.0.8 源码包安装集群
  3. uc/os-II(source)各种文件含义集锦
  4. 大数据体系【协议】系列-1:gossip协议
  5. android sdk中添加自定义api,android SDK中添加自定义api【转】
  6. 信息学奥赛一本通(1401:机器翻译)
  7. 电机的入门之路系列3--直流电机的工作原理
  8. 多线程python实现方式_python多线程的两种实现方式(代码教程)
  9. Scala初体验之:Map
  10. 专业视频压制神器下载——解决会声会影、PR、AE处理视频后过大的问题(三款工具)专业视频压制软件
  11. isupper函数python_python字符串是否是大写-python 字符串大写-python isupper函数-python isupper函数未定义-嗨客网...
  12. step5: 编写spider爬取
  13. 播布客小布老师所有视频
  14. 微信公众号迁移,认证; 名称触发商标怎么办
  15. 【编程马拉松】【011-鸽兔同校】
  16. iOS应用内部浮窗实现
  17. HIDS入侵检测能力评估list
  18. 智联招聘中申请职位之后你根本不知道你申请的职位是啥,而且不想说...
  19. 玩转X-CTR100 l STM32F4 l PS2无线手柄-4WD智能小车
  20. DCCA互相关系数 理论

热门文章

  1. 最新 2022百威英博AI面试真题题库
  2. 第十七届全国大学生智能车竞赛华南赛区奖项
  3. Java微信开发-微信java开发接入平台实例
  4. 浅谈ThreadLocal
  5. 高数_第6章无穷级数__调和级数
  6. 各种电子图书馆文章转为Word文档的方法
  7. asp.net1044-学院宿舍报修信息系统#毕业设计
  8. jquery回弹_jQuery实现移动端下拉展现新版的内容回弹动画
  9. 低成本的单节锂电池充电芯片
  10. 数据可视化之全球咖啡豆的产销:全球总产量平稳上升,预计今年总产量约1.75亿袋