Gin Practice Six Build blog API ' s (v)

Source: Internet
Author: User
Tags sprintf
This is a creation in Article, where the information may have evolved or changed.

API ' s-logging

In the previous section, we solved the problem that API's could be accessed arbitrarily, so we now have one more question.

It is our log, which is output to the console, which is obviously unreasonable for a project, so this section simply encapsulates the library so that log it supports a simple file log!

New logging Package

We are pkg under new logging directory, new file.go and log.go file, write content:

    1. File.go:
Package Loggingimport ("OS" "Time" "FMT" "Log") var (logsavepath = "runtime/logs/" logsavename = "Log" Logfileext = "Log" TimeFormat = "20060102") func Getlogfilepath () string {return FMT. Sprintf ("%s", Logsavepath)}func Getlogfilefullpath () string {prefixpath: = Getlogfilepath () Suffixpath: = Fmt. Sprintf ("%s%s.%s", Logsavename, time. Now (). Format (TimeFormat), Logfileext) return to FMT. Sprintf ("%s%s", Prefixpath, Suffixpath)}func openlogfile (FilePath string) *os. File {_, Err: = OS. Stat (filePath) switch {case OS. Isnotexist (Err): MkDir (Getlogfilepath ()) Case OS. Ispermission (Err): Log. Fatalf ("Permission:%v", err)} handle, err: = OS. OpenFile (FilePath, OS. O_append | Os. O_create | Os. O_wronly, 0644) if err! = Nil {log. Fatalf ("Fail to OpenFile:%v", err)} return Handle}func MkDir (FilePath string) {dir, _: = OS. GETWD () Err: = OS. Mkdirall (dir + "/" + Getlogfilepath (), OS. Modeperm) if Err! = Nil {panic (err)}} 
    • os.Stat: Returns the file information structure description file. If an error occurs, it returns*PathError
type PathError struct {    Op   string    Path string    Err  error}
    • os.IsNotExist: ErrNotExist syscall A number of errors that can be accepted, it returns a Boolean value to know that the file does not exist or that the directory does not exist
    • os.IsPermission: Some errors that can be accepted, ErrPermission syscall it returns a Boolean value that can tell if the permission is satisfied
    • os.OpenFile: The method that calls the file, supports the incoming file name, specifies the mode call file, the file permission, and the returned file can be used for I/O. If an error occurs, the *PathError .
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  // 如果可以,打开时)
    • os.Getwd: Returns the root path name corresponding to the current directory
    • os.MkdirAll: creates the corresponding directory and the desired subdirectory, or returns if successful nilerror
    • os.ModePerm: const DefineModePerm FileMode = 0777
    1. Log.go
Package Loggingimport ("Log", "OS" "Runtime" "Path/filepath" "FMT") type level Intvar (F *os. File Defaultprefix = "" defaultcallerdepth = 2 logger *log.     Logger Logprefix = "" Levelflags = []string{"Debug", "INFO", "WARN", "ERROR", "FATAL"}) const (DEBUG level = Iota INFO WARNING ERROR FATAL) func init () {filePath: = Getlogfilefullpath () F = OpenLogFile (FilePath) Lo Gger = log. New (F, Defaultprefix, log. lstdflags)}func Debug (v ... interface{}) {Setprefix (Debug) logger. Println (v)}func Info (v. ... interface{}) {Setprefix (info) logger. Println (v)}func Warn (v ... interface{}) {Setprefix (WARNING) logger. Println (v)}func error (v ... interface{}) {Setprefix (Error) logger. Println (v)}func Fatal (v ... interface{}) {Setprefix (Fatal) logger. Fatalln (v)}func Setprefix (Level level) {_, file, line, OK: Runtime. Caller (defaultcallerdepth) if ok {logprefix = fmt. Sprintf ("[%s][%s:%d]", Levelflags[level], FilepAth. Base (file), line)} else {logprefix = FMT. Sprintf ("[%s]", Levelflags[level])} logger. Setprefix (Logprefix)}
    • Log. NEW: Create a fresh logger. outdefines a handle to write to the log data IO . prefixdefines the beginning of each generated journal line. flagdefines the logging properties
func New(out io.Writer, prefix string, flag int) *Logger {    return &Logger{out: out, prefix: prefix, flag: flag}}
    • Log. Lstdflags: One of the formatting attributes of the logging, the remaining options are as follows
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)

Current directory structure:

gin-blog/├── conf│   └── app.ini├── main.go├── middleware│   └── jwt│       └── jwt.go├── models│   ├── article.go│   ├── auth.go│   ├── models.go│   └── tag.go├── pkg│   ├── e│   │   ├── code.go│   │   └── msg.go│   ├── logging│   │   ├── file.go│   │   └── log.go│   ├── setting│   │   └── setting.go│   └── util│       ├── jwt.go│       └── pagination.go├── routers│   ├── api│   │   ├── auth.go│   │   └── v1│   │       ├── article.go│   │       └── tag.go│   └── router.go├── runtime

Our custom logging package has been basically completed, then let it be connected to our project!

We open log the code that contains the package earlier,

    1. Open routers the directory, article.go tag.goauth.go
    2. logDelete the package reference, modify the reference to our own log package asgin-blog/pkg/logging
    3. Change the original to log.Println(...)log.Info(...)

For example auth.go , what the file modifies:

package apiimport (    "net/http"    "github.com/gin-gonic/gin"    "github.com/astaxie/beego/validation"    "gin-blog/pkg/e"    "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,    })}

Validation features

After modifying the file, restart the service, let's try it!

After getting the token to the API, we deliberately pass the error URL parameter to the interface, such as:http://127.0.0.1:8000/api/v1/articles?tag_id=0&state=9999999&token=eyJhbG..

Then we go to $GOPATH/gin-blog/runtime/logs check the log:

$ 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][INFO][article.go:79]2018/02/16 18:38:39 [tag_id 标签ID必须大于0]

Log structure all normal, our record mode is Info , so the prefix is right, and we are into the problem, but also recorded the error, so the wrong is very convenient!

At this point, this section is complete, this is just a simple extension, actually our online project to use the file log, is more complicated, to start your brain extrapolate it!

Reference

Sample code for this series

    • Go-gin-example
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.