day 11 - log服务想说的话

log是什麽?为什麽要写log? 写了有什麽帮助?

写log就像是在帮服务表达它的各种心情, 一个request从api接口进来之後走过的每个路径,遇到的每个关卡跟发生的错误,都是可以log下来的资讯,至於log要纪录到多详尽则是要看api本身的属性。api input的参数是我会纪录下来的项目之一,另外像是重要的api执行时间、外部api回应时间跟结果我也会纪录下来,再来是发生的所有错误会依照错误的紧急程度区分为NoticeWarningErrorEmergency......等,让其他人在读我的log的时候也能清楚明了的知道服务发生什麽事和紧急程度为何, log不是只写给自己看的,它是要让服务有任何状况时,大家都可以读懂log反应出来的资讯。

这边选择的是logrus这个套件来记录log,为了保留之後更换套件的弹性,所以一样会再把套件包装一次。大概的包装方式如下:

log
├── log.go
└── log_test.go
package coconutLog

import (
	"github.com/sirupsen/logrus"
)

type Logger struct {
	Log *logrus.Logger
}

type Entry struct {
	Entry *logrus.Entry
}

func New() *Logger {
	log := logrus.New()
	log.SetFormatter(&logrus.JSONFormatter{})

	return &Logger{
		Log: log,
	}
}

func (l *Logger) Debugf(format string, args ...interface{}) {
	l.Log.Printf(format, args...)
}

func (l *Logger) Errorf(format string, args ...interface{}) {
	l.Log.Errorf(format, args...)
}

func (l *Logger) WithFields(fields map[string]interface{}) (e *Entry) {
	e = &Entry{
		Entry: l.Log.WithFields(fields),
	}

	return e
}

func (l *Logger) WithError(err error) (e *Entry) {
	e = &Entry{
		Entry: l.Log.WithError(err),
	}

	return e
}

func (e *Entry) Debugf(format string, args ...interface{}) {
	e.Entry.Printf(format, args...)
}

func (e *Entry) Errorf(format string, args ...interface{}) {
	e.Entry.Errorf(format, args...)
}

一样,包装後写go test

package coconutLog

import (
	"errors"
	"testing"
)

func TestLog(t *testing.T) {
	logger := New()
	logger.Debugf("前天星期%s", "三")
	logger.WithFields(map[string]interface{}{"昨天": "9/9"}).Debugf("星期%s", "四")
	logger.WithFields(map[string]interface{}{"今天": "9/10"}).Errorf("星期%s", "五")
	logger.WithError(errors.New("後天")).Errorf("星期%s", "六")
	logger.Errorf("最後是 星期%s", "天")
}

logrus提供各种讯息的等级来区分log的紧急程度,另外加上log.SetFormatter(&logrus.JSONFormatter{})之後就可以转成JSON格式输出,方便於资料的收集跟输出格式整理。

-> % go test
{"level":"info","msg":"前天星期三","time":"2021-09-17T11:52:24+08:00"}
{"level":"info","msg":"星期四","time":"2021-09-17T11:52:24+08:00","昨天":"9/9"}
{"level":"error","msg":"星期五","time":"2021-09-17T11:52:24+08:00","今天":"9/10"}
{"error":"後天","level":"error","msg":"星期六","time":"2021-09-17T11:52:24+08:00"}
{"level":"error","msg":"最後是 星期天","time":"2021-09-17T11:52:24+08:00"}
PASS
ok      github.com/evelynocean/coconut/lib/log  0.719s

写好log是一件很重要的事情, 我会在专案完成近80%的时候开始逐行检视是否需要补上log, 在服务刚上线的时候log可以协助查看API的状况, 等到服务运行一阵子之後就可以评估关掉debug跟info等级的log, 减少log的纪录量, 或是针对常常跳警报的项目增加log, 确实记录状况发生当下的资讯来辅助查找问题。另外还要评估log的保存时长, 排程去清理掉旧的log资讯, 避免硬碟被塞爆。


<<:  改造你的VSCode,大幅提升你的Coding效率

>>:  Day 4 - Object 物件组合技

Day 19 - Maybe Monad

yo, what's up 在之前我们都是用 Identity 作为例子,但其功用并不大,所以今天要...

Day8 Vue Computed vs Method

我们在模板中要进行计算或转换资料时computed及method通常能做到一样的效果,这麽说的话那不...

Day 23:「儿子,这是你的零用钱」- 元件间的资料传递

兔大夫: 「请问是兔豪的家属吗?」 兔豪爸: 「是,我就是。 请问我鹅子他...」 兔大夫: 「抱...

缺乏计画的目标,只能叫做愿望。----目标设定篇(上)

缺乏计画的目标,只能叫做愿望。 A goal without a plan is just a wi...

jquery实例演练01

JQuery基础用法 JQuery 效果 - 隐藏和显示 JQuery.hide()=> 隐藏...