From 16a794a2450a423348fea63b88073e7a8fc5ed67 Mon Sep 17 00:00:00 2001 From: "Gerasimos (Makis) Maropoulos" Date: Thu, 10 Sep 2020 21:40:30 +0300 Subject: [PATCH] acesslog new example: custom fields and custom template --- _examples/README.md | 1 + .../request-logger/accesslog-template/main.go | 43 +++++++++++++++++++ core/memstore/memstore.go | 9 ++++ middleware/accesslog/log.go | 4 +- 4 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 _examples/logging/request-logger/accesslog-template/main.go diff --git a/_examples/README.md b/_examples/README.md index 99ca6710..cd04a20b 100644 --- a/_examples/README.md +++ b/_examples/README.md @@ -73,6 +73,7 @@ * Logging * [Request Logger](logging/request-logger/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: 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) diff --git a/_examples/logging/request-logger/accesslog-template/main.go b/_examples/logging/request-logger/accesslog-template/main.go new file mode 100644 index 00000000..66b02dd4 --- /dev/null +++ b/_examples/logging/request-logger/accesslog-template/main.go @@ -0,0 +1,43 @@ +package main + +import ( + "github.com/kataras/iris/v12" + "github.com/kataras/iris/v12/middleware/accesslog" +) + +func main() { + /* + This example will show you how you can + register custom fields and log them separately + with a custom format through the Template formatter. + */ + + app := iris.New() + ac := accesslog.File("./access.log").AddOutput(app.Logger().Printer) + ac.TimeFormat = "2006-01-02 15:04:05" + + // 1. Register a field. + ac.AddFields(func(ctx iris.Context, fields *accesslog.Fields) { + fields.Set("IP", ctx.RemoteAddr()) + }) + // 2. Use Template formatter's `Text` value + // to customize the look & feel of a log. + // You could also use its `Tmpl` field to + // set a *template.Template instance. + ac.SetFormatter(&accesslog.Template{ + Text: `{{.Now.Format .TimeFormat}} {{.Path}} {{.Code}} {{.Fields.Get "IP" }} +`, + }) + // Example Output: + // 2020-09-10 21:38:13 / 200 ::1 + + app.UseRouter(ac.Handler) + + app.Get("/", index) + + app.Listen(":8080") +} + +func index(ctx iris.Context) { + ctx.WriteString("Index") +} diff --git a/core/memstore/memstore.go b/core/memstore/memstore.go index 10ef05c4..51e8ec3f 100644 --- a/core/memstore/memstore.go +++ b/core/memstore/memstore.go @@ -816,6 +816,15 @@ func (r *Store) GetDefault(key string, def interface{}) interface{} { return vv } +// Exists is a small helper which reports whether a key exists. +// It's not recommended to be used outside of templates. +// Use Get or GetEntry instead which will give you back the entry value too, +// so you don't have to loop again the key-value storage to get its value. +func (r *Store) Exists(key string) bool { + _, ok := r.GetEntry(key) + return ok +} + // Get returns the entry's value based on its key. // If not found returns nil. func (r *Store) Get(key string) interface{} { diff --git a/middleware/accesslog/log.go b/middleware/accesslog/log.go index 5b5a2bda..3f68f2ff 100644 --- a/middleware/accesslog/log.go +++ b/middleware/accesslog/log.go @@ -36,9 +36,9 @@ type Log struct { // Sorted URL Query arguments. Query []memstore.StringEntry `json:"query,omitempty"` // Dynamic path parameters. - PathParams []memstore.Entry `json:"params,omitempty"` + PathParams memstore.Store `json:"params,omitempty"` // Fields any data information useful to represent this Log. - Fields []memstore.Entry `json:"fields,omitempty"` + Fields memstore.Store `json:"fields,omitempty"` // The actual number of bytes received and sent on the network (headers + body). BytesReceived int `json:"bytes_received"`