mirror of
https://github.com/kataras/iris.git
synced 2025-03-13 21:36:28 +01:00
Add example for custom fast Accesslog Formatter
This commit is contained in:
parent
7113165cb8
commit
54a095c23f
|
@ -71,16 +71,17 @@
|
|||
* [API Versioning](routing/versioning/main.go)
|
||||
* [Sitemap](routing/sitemap/main.go)
|
||||
* Logging
|
||||
* [Request Logger](logging/request-logger/main.go)
|
||||
* [AccessLog: simple example](logging/request-logger/accesslog-simple/main.go)
|
||||
* [AccessLog: log request & response and more](logging/request-logger/accesslog)
|
||||
* [AccessLog: custom fields and template](logging/request-logger/accesslog-template/main.go)
|
||||
* [AccessLog: CSV Format](logging/request-logger/accesslog-csv/main.go)
|
||||
* [AccessLog: listen to logs and render them](logging/request-logger/accesslog-broker/main.go)
|
||||
* [Log Requests to a JSON File](logging/request-logger/request-logger-file-json/main.go)
|
||||
* [Application File Logger](logging/file-logger/main.go)
|
||||
* [Application JSON Logger](logging/json-logger/main.go)
|
||||
* [Rollbar](logging/rollbar/main.go)
|
||||
* AccessLog
|
||||
* [Log Requests to a JSON File](logging/request-logger/accesslog-simple/main.go)
|
||||
* [Using Log Rotation and more](logging/request-logger/accesslog)
|
||||
* [Custom Fields and Template](logging/request-logger/accesslog-template/main.go)
|
||||
* [Listen and render Logs to a Client](logging/request-logger/accesslog-broker/main.go)
|
||||
* [The CSV Formatter](logging/request-logger/accesslog-csv/main.go)
|
||||
* [Create your own Formatter](logging/request-logger/accesslog-formatter/main.go)
|
||||
<!-- * [Log Requests to a JSON File](logging/request-logger/request-logger-file-json/main.go) -->
|
||||
* API Documentation
|
||||
* [Yaag](apidoc/yaag/main.go)
|
||||
* [Swagger](https://github.com/iris-contrib/swagger/tree/master/example)
|
||||
|
|
129
_examples/logging/request-logger/accesslog-formatter/main.go
Normal file
129
_examples/logging/request-logger/accesslog-formatter/main.go
Normal file
|
@ -0,0 +1,129 @@
|
|||
// Package main shows to create a quite fast custom Log Formatter.
|
||||
// Note that, this example requires a little more knowledge about Go.
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/kataras/iris/v12"
|
||||
"github.com/kataras/iris/v12/middleware/accesslog"
|
||||
"github.com/kataras/iris/v12/middleware/requestid"
|
||||
)
|
||||
|
||||
func logFields(ctx iris.Context, fields *accesslog.Fields) {
|
||||
fields.Set("reqid", ctx.GetID())
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
|
||||
ac := accesslog.File("./access.log").
|
||||
AddFields(logFields).
|
||||
SetFormatter(newCustomFormatter(' ', "-\t\t\t\t\t"))
|
||||
ac.RequestBody = false
|
||||
ac.BytesReceivedBody = false
|
||||
ac.BytesSentBody = false
|
||||
defer ac.Close()
|
||||
|
||||
app.UseRouter(ac.Handler)
|
||||
app.UseRouter(requestid.New())
|
||||
|
||||
app.OnErrorCode(iris.StatusNotFound, notFound)
|
||||
app.Get("/", index)
|
||||
|
||||
app.Listen(":8080")
|
||||
}
|
||||
|
||||
func notFound(ctx iris.Context) {
|
||||
ctx.WriteString("The page you're looking for does not exist!")
|
||||
}
|
||||
|
||||
func index(ctx iris.Context) {
|
||||
ctx.WriteString("OK Index")
|
||||
}
|
||||
|
||||
type customFormatter struct {
|
||||
w io.Writer
|
||||
bufPool *sync.Pool
|
||||
|
||||
delim byte
|
||||
blank string
|
||||
}
|
||||
|
||||
var _ accesslog.Formatter = (*customFormatter)(nil)
|
||||
|
||||
func newCustomFormatter(delim byte, blank string) *customFormatter {
|
||||
return &customFormatter{delim: delim, blank: blank}
|
||||
}
|
||||
|
||||
func (f *customFormatter) SetOutput(dest io.Writer) {
|
||||
f.w = dest
|
||||
f.bufPool = &sync.Pool{
|
||||
New: func() interface{} {
|
||||
return new(bytes.Buffer)
|
||||
},
|
||||
}
|
||||
|
||||
if f.delim == 0 {
|
||||
f.delim = ' '
|
||||
}
|
||||
}
|
||||
|
||||
const newLine = '\n'
|
||||
|
||||
func (f *customFormatter) Format(log *accesslog.Log) (bool, error) {
|
||||
buf := f.bufPool.Get().(*bytes.Buffer)
|
||||
|
||||
buf.WriteString(log.Now.Format(log.TimeFormat))
|
||||
buf.WriteByte(f.delim)
|
||||
|
||||
reqid := log.Fields.GetString("reqid")
|
||||
f.writeTextOrBlank(buf, reqid)
|
||||
|
||||
buf.WriteString(uniformDuration(log.Latency))
|
||||
buf.WriteByte(f.delim)
|
||||
|
||||
buf.WriteString(log.IP)
|
||||
buf.WriteByte(f.delim)
|
||||
|
||||
buf.WriteString(strconv.Itoa(log.Code))
|
||||
buf.WriteByte(f.delim)
|
||||
|
||||
buf.WriteString(log.Method)
|
||||
buf.WriteByte(f.delim)
|
||||
|
||||
buf.WriteString(log.Path)
|
||||
|
||||
buf.WriteByte(newLine)
|
||||
|
||||
// _, err := buf.WriteTo(f.w)
|
||||
// or (to make sure that it resets on errors too):
|
||||
_, err := f.w.Write(buf.Bytes())
|
||||
buf.Reset()
|
||||
f.bufPool.Put(buf)
|
||||
|
||||
return true, err
|
||||
}
|
||||
|
||||
func (f *customFormatter) writeTextOrBlank(buf *bytes.Buffer, s string) {
|
||||
if len(s) == 0 {
|
||||
if len(f.blank) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
buf.WriteString(f.blank)
|
||||
} else {
|
||||
buf.WriteString(s)
|
||||
}
|
||||
|
||||
buf.WriteByte(f.delim)
|
||||
}
|
||||
|
||||
func uniformDuration(t time.Duration) string {
|
||||
return fmt.Sprintf("%*s", 12, t.String())
|
||||
}
|
|
@ -631,7 +631,7 @@ func (ac *AccessLog) after(ctx *context.Context, lat time.Duration, method, path
|
|||
requestData, err := ctx.GetBody()
|
||||
requestBodyLength := len(requestData)
|
||||
if ac.BytesReceivedBody {
|
||||
bytesReceived = requestBodyLength // store it, if the total is enabled then this will be overriden.
|
||||
bytesReceived = requestBodyLength // store it, if the total is enabled then this will be overridden.
|
||||
}
|
||||
if err != nil && ac.RequestBody {
|
||||
requestBody = ac.getErrorText(err)
|
||||
|
|
Loading…
Reference in New Issue
Block a user