The framework comes with
The Gin framework has its own logging function, which records log information through fmt.Fprint and fmt.Fprintf . The default is to write the log to the terminal, which can be set to write to a file gin.DefaultWriter .
Terminal disable color
gin.DisableConsoleColor()
Only write to file
package main
import (
"fmt"
"io"
"os"
"github.com/gin-gonic/gin"
)
// Logging uses
func main () {
// Disable console color, no console color is required when writing logs to file
gin . DisableConsoleColor ()
// Log to specified file
f , _ := os . Create ( "gin.log" )
gin . DefaultWriter = io . MultiWriter ( f )
// create container
engine := gin . Default ()
engine . GET ( "/log" , func ( context * gin . Context ) {
// log
fmt . Fprint ( gin . DefaultWriter , "[gin-log] log test use \n " )
fmt . Fprintf ( gin . DefaultWriter , "[gin-log] Method: %v \n " , context . Request . Method )
fmt . Fprintf ( gin . DefaultWriter , "[gin-log] Url: %v \n " , context . Request . URL )
fmt . Fprintf ( gin . DefaultWriter , "[gin-log] Header: %v \n " , context . Request . Header )
context . JSON ( 200 , gin . H { "msg" : "success" })
})
// start the service
_ = engine . Run ( ":9090" )
}
[ GIN-debug] [ WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
[ GIN-debug] [ WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env : export GIN_MODE = release
- using code: gin.SetMode( gin.ReleaseMode)
[ GIN-debug] GET /log -- > main.main.func1 ( 3 handlers)
[ GIN-debug] [ WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
[ GIN-debug] Listening and serving HTTP on :9090
[ gin-log] log test use
[ gin-log] Method: GET
[ gin-log] Url: /log
[ gin-log] Header: map[Accept:[text/html,application/xhtml+xml,application/xml; q = 0.9,image/avif,image/webp,* /* ; q = 0.8] Accept-Encoding:[gzip, deflate] Accept-Language:[en-US,en; q = 0.5] Connection:[keep-alive] Cookie:[_ga= GA1.1.141663794.1636793811] Sec-Fetch-Dest:[document] Sec-Fetch-Mode:[navigate] Sec-Fetch-Site:[none] Sec-Fetch-User:[?1] Upgrade-Insecure-Requests:[1] User-Agent:[Mozilla/5.0 ( Macintosh; Intel Mac OS X 10.15; rv:97.0) Gecko/20100101 Firefox/97.0]]
[ GIN] 2021/06/30 - 14:49:16 | 200 | 182.996µs | 127.0.0.1 | GET "/log"
Write to file and terminal at the same time
If you want to write the log to the file and the terminal at the same time, you only need to modify the above code io.MultiWriter(f) and modify it to the following content.
func main (){
...
f , _ := os . Create ( "gin.log" )
// write log to both file and console
gin . DefaultWriter = io . MultiWriter ( f , os . Stdout )
...
// start the service
_ = engine . Run ( ":9090" )
}
Integrate logrus
logrus is probably the most popular Go third-party logging library out there. At the moment, it has 17.9K Github Stars, and the source code is available here .
Installation
go get -u github.com/sirupsen/logrus
Setting properties
Create a logrus_use.go file and write the code as follows:
package main
import (
"os"
"path"
"github.com/sirupsen/logrus"
)
var (
logPath = "./log"
logFile = "gin.log"
)
var LogInstance = logrus . New ()
func init () {
// open a file
logFileName := path . Join ( logPath , logFile )
fileWriter , err := os . OpenFile ( logFileName , os . O_APPEND | os . O_WRONLY | os . O_CREATE , os . ModePerm )
if err != nil {
panic ( err )
}
// Set log output to file
LogInstance . SetOutput ( fileWriter )
// Set log output format
LogInstance . SetFormatter ( & logrus . JSONFormatter {})
// Set logging level
LogInstance . SetLevel ( logrus . DebugLevel )
}
Use
package main
import (
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
)
func main () {
engine := gin . Default ()
engine . GET ( "/log" , func ( context * gin . Context ) {
// Warning level log
LogInstance . WithFields ( logrus . Fields {
"Method" : context . Request . Method ,
}) . Warning ( "Warning level log" )
// Error level log
LogInstance . WithFields ( logrus . Fields {
"param-name" : context . DefaultQuery ( "name" , "" ),
}) . Error ( "Error level log" )
if context . DefaultQuery ( "key" , "" ) == "1" {
// Fatal level log (such logs will end the service)
LogInstance . WithFields ( logrus . Fields {
"Host" : context . Request . Host ,
}) . Fatal ( "Fatal level log" )
}
// Info level log
LogInstance . WithFields ( logrus . Fields {
"code" : context . Writer . Status (),
"url" : context . Request . URL . Path ,
"method" : context . Request . Method ,
}) . Info ( " info level log" )
context . JSON ( 200 , gin . H { "msg" : " success" })
})
_ = engine . Run ( ":9090" )
}
Log content
log file: log/gin.log
JSON format
{ "Method" :"GET" ,"level" :"warning" ,"msg" :"Warning level log" ,"time" :"2021-06-30T16:06:30+08:00" }
{ "level" :"error" ,"msg" :"Error level log" ,"param-name" :"" ,"time" :"2021-06-60T16:06:30+08:00" }
{ "code" :200,"level" :"info" ,"method" :"GET" ,"msg" :"Info level log" ,"time" :"2021-06-30T16:06:30+08:00" ,"url" :"/log" }
Text format
time = "2021-06-30T16:35:16+08:00" level = warning msg = "Warning level log" Method = GET
time = "2021-06-30T16:35:16+08:00" level = error msg = "Error level log" param-name=
time = "2021-06-30T16:35:16+08:00" level = info msg = "Info level log" code = 200 method = GET url = /log
Lumberjack is a Go package for writing logs to rolling files.
Installation
go get -u github.com/natefinch/lumberjack
Import
import "github.com/natefinch/lumberjack"
Use
Modify logrus_use.go file code
package main
import (
"path"
"github.com/natefinch/lumberjack"
"github.com/sirupsen/logrus"
)
var (
logPath = "./log"
logFile = "gin.log"
)
var LogInstance = logrus . New ()
// log initialization
func init () {
// open file
logFileName := path . Join ( logPath , logFile )
// log with rolling compression
rolling ( logFileName )
// set log output JSON Format
//LogInstance.SetFormatter(&logrus.JSONFormatter{})
LogInstance . SetFormatter ( & logrus . TextFormatter {})
//Set logging level
LogInstance . SetLevel ( logrus . DebugLevel )
}
// Log rolling settings
func rolling ( logFile string ) {
// Set the output
LogInstance . SetOutput ( & lumberjack . Logger {
Filename : logFile , // Log file location
MaxSize : 1 , // Maximum capacity of a single file, in MB
MaxBackups : 3 , // The maximum number of retained expired files
MaxAge : 1 , // The maximum time interval for retaining expired files, the unit is days
Compress : true , // Whether to compress the rolling log, use gzip compression
})
}
package main
import (
"strings"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
)
func main () {
engine := gin . Default ()
engine . GET ( "/log" , func ( context * gin . Context ) {
// Warning level log
LogInstance . WithFields ( logrus . Fields {
"Method" : context . Request . Method ,
}) . Warning ( "Warning level log" )
// Error level log
LogInstance . WithFields ( logrus . Fields {
"param-name" : context . DefaultQuery ( "name" , "" ),
}) . Error ( "Error level log" )
if context . DefaultQuery ( "key" , "" ) == "1" {
// Fatal level log (such logs will end the service)
LogInstance . WithFields ( logrus . Fields {
"Host" : context . Request . Host ,
}) . Fatal ( "Fatal level log" )
}
// Info level log
LogInstance . WithFields ( logrus . Fields {
"code" : context . Writer . Status (),
"url" : context . Request . URL . Path ,
"context" : strings . Repeat ( "Test" , 50000 ), // repeat
}) . Info ( "info level log" )
context . JSON ( 200 , gin . H { "msg" : "success" })
})
_ = engine . Run ( ":9090" )
}
package main
import (
"path"
"strings"
"github.com/gin-gonic/gin"
"github.com/natefinch/lumberjack"
"github.com/sirupsen/logrus"
)
var (
logPath = "./log"
logFile = "gin.log"
)
var LogInstance = logrus . New ()
// log initialization
func init () {
// open file
logFileName := path . Join ( logPath , logFile )
// log with rolling compression
rolling ( logFileName )
// set log output JSON Format
//LogInstance.SetFormatter(&logrus.JSONFormatter{})
LogInstance . SetFormatter ( & logrus . TextFormatter {})
//Set logging level
LogInstance . SetLevel ( logrus . DebugLevel )
}
// Log rolling settings
func rolling ( logFile string ) {
// Set the output
LogInstance . SetOutput ( & lumberjack . Logger {
Filename : logFile , // Log file location
MaxSize : 1 , // Maximum capacity of a single file, in MB
MaxBackups : 3 , // The maximum number of retained expired files
MaxAge : 1 , // The maximum time interval for retaining expired files, the unit is days
Compress : true , // Whether to compress the rolling log, use gzip compression
})
}
func main () {
engine := gin . Default ()
engine . GET ( "/log" , func ( context * gin . Context ) {
// Warning level log
LogInstance . WithFields ( logrus . Fields {
"Method" : context . Request . Method ,
}) . Warning ( "Warning level log" )
// Error level log
LogInstance . WithFields ( logrus . Fields {
"param-name" : context . DefaultQuery ( "name" , "" ),
}) . Error ( "Error level log" )
if context . DefaultQuery ( "key" , "" ) == "1" {
// Fatal level log (such logs will end the service)
LogInstance . WithFields ( logrus . Fields {
"Host" : context . Request . Host ,
}) . Fatal ( "Fatal level log" )
}
// Info level log
LogInstance . WithFields ( logrus . Fields {
"code" : context . Writer . Status (),
"url" : context . Request . URL . Path ,
"context" : strings . Repeat ( "Test" , 50000 ), // repeat
}) . Info ( "info level log" )
context . JSON ( 200 , gin . H { "msg" : "success" })
})
_ = engine . Run ( ":9090" )
}
Effects