就是我们的日志,都是输出到控制台上的,这显然对于一个项目来说是不合理的,因此我们这一节简单封装log
库,使其支持简单的文件日志!
项目地址:
我们在pkg
下新建logging
目录,新建file.go
和log.go
文件,写入内容:
1、 file.go:
os.Stat
:返回文件信息结构描述文件。如果出现错误,会返回*PathError
type PathError struct {
Op string
Path string
Err error
}
os.IsNotExist
:能够接受ErrNotExist
、syscall
的一些错误,它会返回一个布尔值,能够得知文件不存在或目录不存在os.IsPermission
:能够接受ErrPermission
、syscall
的一些错误,它会返回一个布尔值,能够得知权限是否满足-
const (
// Exactly one of O_RDONLY, O_WRONLY, or O_RDWR must be specified.
O_RDONLY int = syscall.O_RDONLY // 以只读模式打开文件
O_WRONLY int = syscall.O_WRONLY // 以只写模式打开文件
O_RDWR int = syscall.O_RDWR // 以读写模式打开文件
// The remaining values may be or'ed in to control behavior.
O_APPEND int = syscall.O_APPEND // 在写入时将数据追加到文件中
O_CREATE int = syscall.O_CREAT // 如果不存在,则创建一个新文件
O_EXCL int = syscall.O_EXCL // 使用O_CREATE时,文件必须不存在
O_SYNC int = syscall.O_SYNC // 同步IO
O_TRUNC int = syscall.O_TRUNC // 如果可以,打开时
)
- :创建对应的目录以及所需的子目录,若成功则返回
nil
,否则返回error
os.ModePerm
:const
定义ModePerm FileMode = 0777
2、 log.go
log.New
:创建一个新的日志记录器。out
定义要写入日志数据的IO
句柄。prefix
定义每个生成的日志行的开头。flag
定义了日志记录属性func New(out io.Writer, prefix string, flag int) *Logger {
return &Logger{out: out, prefix: prefix, flag: flag}
}
log.LstdFlags
:日志记录的格式属性之一,其余的选项如下const (
Ldate = 1 << iota // the date in the local time zone: 2009/01/23
Ltime // the time in the local time zone: 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
LUTC // if Ldate or Ltime is set, use UTC rather than the local time zone
LstdFlags = Ldate | Ltime // initial values for the standard logger
)
当前目录结构:
我们打开先前包含log
包的代码,
- 打开
routers
目录下的article.go
、tag.go
、auth.go
- 将
log
包的引用删除,修改引用我们自己的日志包为gin-blog/pkg/logging
- 将原本的
log.Println(...)
改为log.Info(...)
例如auth.go
文件的修改内容:
package api
"net/http"
"github.com/gin-gonic/gin"
"github.com/astaxie/beego/validation"
"gin-blog/pkg/util"
"gin-blog/models"
"gin-blog/pkg/logging"
)
...
func GetAuth(c *gin.Context) {
...
code := e.INVALID_PARAMS
if ok {
...
} else {
for _, err := range valid.Errors {
logging.Info(err.Key, err.Message)
}
}
c.JSON(http.StatusOK, gin.H{
"code" : code,
"msg" : e.GetMsg(code),
"data" : data,
})
}
修改文件后,重启服务,我们来试试吧!
获取到API的Token后,我们故意传错误URL参数给接口,如:http://127.0.0.1:8000/api/v1/articles?tag_id=0&state=9999999&token=eyJhbG..
然后我们到$GOPATH/gin-blog/runtime/logs
查看日志:
$ tail -f log20180216.log
[INFO][article.go:79]2018/02/16 18:33:12 [state 状态只允许0或1]
[INFO][article.go:79]2018/02/16 18:33:42 [state 状态只允许0或1]
[INFO][article.go:79]2018/02/16 18:33:42 [tag_id 标签ID必须大于0]
[INFO][article.go:79]2018/02/16 18:38:39 [state 状态只允许0或1]
至此,本节就完成了,这只是一个简单的扩展,实际上我们线上项目要使用的文件日志,是更复杂一些,开动你的大脑 举一反三吧!