从本文开始,咱们来看一下如何从零搭建一个 Go 我的项目。
回顾一下根底的 Go 我的项目运行过程
首先,新建一个 sports
的文件,而后键入此文件目录下,抉择在终端中关上,应用如下命令初始化我的项目:
go mod init sports
而后,咱们创立一个 main.go
的文件,写入如下代码:
package mainimport "fmt"func writeMessage() { fmt.Println("Let's Go")}func main() { writeMessage()}
回到终端,编译并执行咱们的我的项目:
go run .
就像之前第一次写一个 HelloWorld
我的项目一样,run
命令会胜利编译并执行咱们的 Println()
内的字符串 Let's Go,输入后果如下:
$ go run .Let's Go
创立一些根本的我的项目性能
家喻户晓,Web 利用有一些根底的服务和性能如日志、文件配置等等。所以咱们能够为 sports
我的项目提供一些根本的服务,这些服务将为运行网络应用程序提供根底。
创立日志接口 Logger
先来实现第一个服务器性能——日志。Go 规范库中的 log
包为创立日志提供了一套十分用户敌对的基本功能,但在理论开发过程中,仍须要一些额定的性能来筛选一些信息详情。
创立 sports/logging
文件夹,而后在这个文件夹上面创立一个 logging.go
文件,而后写入如下代码:
package loggingtype LogLevel intconst ( 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
接口,并具体申明了具体的日志音讯的具体方法,别离有着不同的日志级别,LogLevel
从 Trace
到 Fatal
。值得注意的是也有一个无级别的 None
, 意味着没有日志输入。
对于每个级别的重要性,Logger
接口定义两个办法:
- 一个用于承受简略字符串的办法,如
Debug
- 一个用于接管模板字符串和占位符值的办法,如
Debugf
将日志性能定义为接口的益处是:在须要更改或替换性能时,只须要更改实现,咱们的调用接口并不需要扭转;接口也使得性能作为服务提供给应用程序。
Logger 接口的具体实现
日志接口定义好了之后,咱们来创立具体的 Logger
接口的实现。
创立一个 logger_default.go
的文件,而后写入如下的代码:
package loggingimport ( "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()
函数创立一个具备最小重大水平日志 DefaultLogger
和 log.Loggers
将音讯写入规范输入。
最终咱们的目录构造如下:
测试日志性能
为了做一个简略的测试,咱们能够批改最开始的 main()
函数,以便查看日志性能是否能胜利打印出日志音讯,回到 main.go
,写入如下代码:
package mainimport ( // "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
创立的最小日志级别被设置为 Information
,这意味着更低的日志级别(Trace
和 Debug
)将被疏忽,再次编译和执行 sports
我的项目,就会看到本地的日志输入,可能你依照我的操作只会工夫戳不同,如下:
$ go run .11:46:55 INFO Let's Go, logger
终端后果如图所示:
总结
到了本文的总结时刻了,为了学习 Go Web 我的项目,本文先回顾了一下 Go 我的项目的初始化构建和运行过程,而后往咱们的 sports
我的项目中增加了一个日志性能,逐步完善日志接口和实现,最初在主函数中进行了一个简略的日志输入测试。
心愿本文能对你有所帮忙,如果喜爱本文,能够点个关注。
这里是宇宙之一粟,下一篇文章见!
宇宙古今无有穷期,毕生不过顷刻,当思奋争。