mirror of
https://github.com/kataras/iris.git
synced 2025-03-15 17:36:29 +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)
|
* [API Versioning](routing/versioning/main.go)
|
||||||
* [Sitemap](routing/sitemap/main.go)
|
* [Sitemap](routing/sitemap/main.go)
|
||||||
* Logging
|
* 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 File Logger](logging/file-logger/main.go)
|
||||||
* [Application JSON Logger](logging/json-logger/main.go)
|
* [Application JSON Logger](logging/json-logger/main.go)
|
||||||
* [Rollbar](logging/rollbar/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
|
* API Documentation
|
||||||
* [Yaag](apidoc/yaag/main.go)
|
* [Yaag](apidoc/yaag/main.go)
|
||||||
* [Swagger](https://github.com/iris-contrib/swagger/tree/master/example)
|
* [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()
|
requestData, err := ctx.GetBody()
|
||||||
requestBodyLength := len(requestData)
|
requestBodyLength := len(requestData)
|
||||||
if ac.BytesReceivedBody {
|
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 {
|
if err != nil && ac.RequestBody {
|
||||||
requestBody = ac.getErrorText(err)
|
requestBody = ac.getErrorText(err)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user