Go?Web實(shí)戰(zhàn)之創(chuàng)建項(xiàng)目及增加日志功能
從本文開始,我們來(lái)看一下如何從零搭建一個(gè) Go 項(xiàng)目。
回顧一下基礎(chǔ)的 Go 項(xiàng)目運(yùn)行過(guò)程
首先,新建一個(gè) sports
的文件,然后鍵入此文件目錄下,選擇在終端中打開,使用如下命令初始化項(xiàng)目:
go mod init sports
然后,我們創(chuàng)建一個(gè) main.go
的文件,寫入如下代碼:
package main import "fmt" func writeMessage() { fmt.Println("Let's Go") } func main() { writeMessage() }
回到終端,編譯并執(zhí)行我們的項(xiàng)目:
go run .
就像之前第一次寫一個(gè) HelloWorld
項(xiàng)目一樣,run
命令會(huì)成功編譯并執(zhí)行我們的 Println()
內(nèi)的字符串 Let's Go,輸出結(jié)果如下:
$ go run . Let's Go
創(chuàng)建一些基本的項(xiàng)目功能
眾所周知,Web 應(yīng)用有一些基礎(chǔ)的服務(wù)和功能如日志、文件配置等等。所以我們可以為 sports
項(xiàng)目提供一些基本的服務(wù),這些服務(wù)將為運(yùn)行網(wǎng)絡(luò)應(yīng)用程序提供基礎(chǔ)。
創(chuàng)建日志接口 Logger
先來(lái)實(shí)現(xiàn)第一個(gè)服務(wù)器功能——日志。Go 標(biāo)準(zhǔn)庫(kù)中的 log
包為創(chuàng)建日志提供了一套非常用戶友好的基本功能,但在實(shí)際開發(fā)過(guò)程中,仍需要一些額外的功能來(lái)篩選一些信息詳情。
創(chuàng)建 sports/logging
文件夾,然后在這個(gè)文件夾下面創(chuàng)建一個(gè) logging.go
文件,然后寫入如下代碼:
package logging type LogLevel int const ( Trace LogLevel = iota Debug Information Warning Fatal None ) type Logger interface { Trace(string) Tracef(string, ...interface{}) Debug(string) Debugf(string, ...interface{}) Info(string) Infof(string, ...interface{}) Warn(string) Warnf(string, ...interface{}) Panic(string) Panicf(string, ...interface{}) }
上面的代碼定義了 Logger
接口,并具體聲明了具體的日志消息的具體方法,分別有著不同的日志級(jí)別,LogLevel
從 Trace
到 Fatal
。值得注意的是也有一個(gè)無(wú)級(jí)別的 None
, 意味著沒(méi)有日志輸出。
對(duì)于每個(gè)級(jí)別的重要性,Logger
接口定義兩個(gè)方法:
- 一個(gè)用于接受簡(jiǎn)單字符串的方法,如
Debug
- 一個(gè)用于接收模板字符串和占位符值的方法,如
Debugf
將日志功能定義為接口的好處是:在需要更改或替換功能時(shí),只需要更改實(shí)現(xiàn),我們的調(diào)用接口并不需要改變;接口也使得功能作為服務(wù)提供給應(yīng)用程序。
Logger 接口的具體實(shí)現(xiàn)
日志接口定義好了之后,我們來(lái)創(chuàng)建具體的 Logger
接口的實(shí)現(xiàn)。
創(chuàng)建一個(gè) logger_default.go
的文件,然后寫入如下的代碼:
package logging import ( "fmt" "log" ) type DefaultLogger struct { minLevel LogLevel loggers map[LogLevel]*log.Logger triggerPanic bool } func (l *DefaultLogger) MinLogLevel() LogLevel { return l.minLevel } func (l *DefaultLogger) write(level LogLevel, message string) { if l.minLevel <= level { l.loggers[level].Output(2, message) } } func (l *DefaultLogger) Trace(msg string) { l.write(Trace, msg) } func (l *DefaultLogger) Tracef(template string, vals ...interface{}) { l.write(Trace, fmt.Sprintf(template, vals...)) } func (l *DefaultLogger) Debug(msg string) { l.write(Debug, msg) } func (l *DefaultLogger) Debugf(template string, vals ...interface{}) { l.write(Debug, fmt.Sprintf(template, vals...)) } func (l *DefaultLogger) Info(msg string) { l.write(Information, msg) } func (l *DefaultLogger) Infof(template string, vals ...interface{}) { l.write(Information, fmt.Sprintf(template, vals...)) } func (l *DefaultLogger) Warn(msg string) { l.write(Warning, msg) } func (l *DefaultLogger) Warnf(template string, vals ...interface{}) { l.write(Warning, fmt.Sprintf(template, vals...)) } func (l *DefaultLogger) Panic(msg string) { l.write(Fatal, msg) if l.triggerPanic { panic(msg) } } func (l *DefaultLogger) Panicf(template string, vals ...interface{}) { formattedMsg := fmt.Sprintf(template, vals...) l.write(Fatal, formattedMsg) if l.triggerPanic { panic(formattedMsg) } }
NewDefaultLogger()
函數(shù)創(chuàng)建一個(gè)具有最小嚴(yán)重程度日志 DefaultLogger
和 log.Loggers
將消息寫入標(biāo)準(zhǔn)輸出。
最終我們的目錄結(jié)構(gòu)如下:
測(cè)試日志功能
為了做一個(gè)簡(jiǎn)單的測(cè)試,我們可以修改最開始的 main()
函數(shù),以便查看日志功能是否能成功打印出日志消息,回到 main.go
,寫入如下代碼:
package main import ( // "fmt" "sports/logging" ) func writeMessage(logger logging.Logger) { // fmt.Println("Let's Go") logger.Info("Let's Go, logger") } func main() { var logger logging.Logger = logging.NewDefaultLogger(logging.Information) writeMessage(logger) }
由 NewDefaultLogger
創(chuàng)建的最小日志級(jí)別被設(shè)置為 Information
,這意味著更低的日志級(jí)別(Trace
和 Debug
)將被忽略,再次編譯和執(zhí)行 sports
項(xiàng)目,就會(huì)看到本地的日志輸出,可能你按照我的操作只會(huì)時(shí)間戳不同,如下:
$ go run . 11:46:55 INFO Let's Go, logger
終端結(jié)果如圖所示:
總結(jié)
到了本文的總結(jié)時(shí)刻了,為了學(xué)習(xí) Go Web 項(xiàng)目,本文先回顧了一下 Go 項(xiàng)目的初始化構(gòu)建和運(yùn)行過(guò)程,然后往我們的 sports
項(xiàng)目中添加了一個(gè)日志功能,逐步完善日志接口和實(shí)現(xiàn),最后在主函數(shù)中進(jìn)行了一個(gè)簡(jiǎn)單的日志輸出測(cè)試。
到此這篇關(guān)于Go Web實(shí)戰(zhàn)之創(chuàng)建項(xiàng)目及增加日志功能的文章就介紹到這了,更多相關(guān)Go Web增加日志內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
加速開發(fā):使用Go語(yǔ)言和Gin框架構(gòu)建Web項(xiàng)目的利器
Go語(yǔ)言和Gin框架是構(gòu)建高性能Web項(xiàng)目的利器,Go語(yǔ)言的簡(jiǎn)潔性和并發(fā)性,以及Gin框架的輕量級(jí)和快速路由能力,使開發(fā)者能夠快速構(gòu)建可靠的Web應(yīng)用程序,需要的朋友可以參考下2023-09-09Go標(biāo)準(zhǔn)庫(kù)-ServeMux的使用與模式匹配深入探究
這篇文章主要為大家介紹了Go標(biāo)準(zhǔn)庫(kù)-ServeMux的使用與模式匹配深入探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01golang中l(wèi)og包自定義輸出日志格式與寫入到文件
這篇文章主要給大家介紹了關(guān)于golang中l(wèi)og包自定義輸出日志格式與寫入到文件的相關(guān)資料,日志輸出在任何項(xiàng)目中都極其重要,是有助于后續(xù)我們排查解決程序BUG,需要的朋友可以參考下2023-06-06go語(yǔ)言區(qū)塊鏈學(xué)習(xí)調(diào)用以太坊
這篇文章主要為大家介紹了go語(yǔ)言區(qū)塊鏈學(xué)習(xí)如何調(diào)用以太坊的示例實(shí)現(xiàn)過(guò)程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2021-10-10Go語(yǔ)言內(nèi)建函數(shù)cap的實(shí)現(xiàn)示例
cap 是一個(gè)常用的內(nèi)建函數(shù),它用于獲取某些數(shù)據(jù)結(jié)構(gòu)的容量,本文主要介紹了Go語(yǔ)言內(nèi)建函數(shù)cap的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下2024-08-08go編譯so庫(kù)讓python引用編譯后沒(méi)有.h文件的問(wèn)題
有時(shí)python需要引用go的一些開源庫(kù),這時(shí)就需要go編譯成python可調(diào)用的庫(kù),本文給大家介紹了go編譯so庫(kù)讓python引用,編譯后沒(méi)有.h文件的問(wèn)題,需要的朋友可以參考下2024-02-02beego獲取ajax數(shù)據(jù)的實(shí)例
下面小編就為大家分享一篇beego獲取ajax數(shù)據(jù)的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-12-12