add Party.SetRoutesNoLog and mvc.Application.SetControllersNoLog as requested at #1630

This commit is contained in:
Gerasimos (Makis) Maropoulos 2020-09-15 00:23:09 +03:00
parent 0f7cf7f35c
commit 3baee7db34
No known key found for this signature in database
GPG Key ID: 5DBE766BD26A54E7
6 changed files with 92 additions and 20 deletions

View File

@ -364,6 +364,9 @@ Response:
Other Improvements: Other Improvements:
- Add `Party.SetRoutesNoLog(disable bool) Party` to disable (the new) verbose logging of next routes.
- Add `mvc.Application.SetControllersNoLog(disable bool) *mvc.Application` to disable (the new) verbose logging of next controllers. As requested at [#1630](https://github.com/kataras/iris/issues/1630).
- Fix [#1621](https://github.com/kataras/iris/issues/1621) and add a new `cache.WithKey` to customize the cached entry key. - Fix [#1621](https://github.com/kataras/iris/issues/1621) and add a new `cache.WithKey` to customize the cached entry key.
- Add a `Response() *http.Response` to the Response Recorder. - Add a `Response() *http.Response` to the Response Recorder.

View File

@ -14,12 +14,17 @@ func main() {
app := iris.New() app := iris.New()
app.Use(recover.New()) app.Use(recover.New())
app.Logger().SetLevel("debug") app.Logger().SetLevel("debug")
// Disable verbose logging of routes for this and its children parties
// when the log level is "debug": app.SetRoutesNoLog(true)
mvc.Configure(app.Party("/basic"), basicMVC) mvc.Configure(app.Party("/basic"), basicMVC)
app.Listen(":8080") app.Listen(":8080")
} }
func basicMVC(app *mvc.Application) { func basicMVC(app *mvc.Application) {
// Disable verbose logging of controllers for this and its children mvc apps
// when the log level is "debug": app.SetControllersNoLog(true)
// You can use normal middlewares at MVC apps of course. // You can use normal middlewares at MVC apps of course.
app.Router.Use(func(ctx iris.Context) { app.Router.Use(func(ctx iris.Context) {
ctx.Application().Logger().Infof("Path: %s", ctx.Path()) ctx.Application().Logger().Infof("Path: %s", ctx.Path())

View File

@ -198,6 +198,8 @@ type APIBuilder struct {
macros *macro.Macros macros *macro.Macros
// the api builder global routes repository // the api builder global routes repository
routes *repository routes *repository
// disables the debug logging of routes under a per-party and its children.
routesNoLog bool
// the per-party handlers, order // the per-party handlers, order
// of handlers registration matters, // of handlers registration matters,
@ -643,6 +645,7 @@ func (api *APIBuilder) createRoutes(errorCode int, methods []string, relativePat
// route.Use(api.beginGlobalHandlers...) // route.Use(api.beginGlobalHandlers...)
// route.Done(api.doneGlobalHandlers...) // route.Done(api.doneGlobalHandlers...)
route.NoLog = api.routesNoLog
routes[i] = route routes[i] = route
} }
@ -714,6 +717,7 @@ func (api *APIBuilder) Party(relativePath string, handlers ...context.Handler) P
logger: api.logger, logger: api.logger,
macros: api.macros, macros: api.macros,
routes: api.routes, routes: api.routes,
routesNoLog: api.routesNoLog,
beginGlobalHandlers: api.beginGlobalHandlers, beginGlobalHandlers: api.beginGlobalHandlers,
doneGlobalHandlers: api.doneGlobalHandlers, doneGlobalHandlers: api.doneGlobalHandlers,
@ -866,6 +870,18 @@ func (api *APIBuilder) GetRouteReadOnlyByPath(tmplPath string) context.RouteRead
return r.ReadOnly return r.ReadOnly
} }
// SetRoutesNoLog disables (true) the verbose logging for the next registered
// routes under this Party and its children.
//
// To disable logging for controllers under MVC Application,
// see `mvc/Application.SetControllersNoLog` instead.
//
// Defaults to false when log level is "debug".
func (api *APIBuilder) SetRoutesNoLog(disable bool) Party {
api.routesNoLog = disable
return api
}
type ( type (
// PartyMatcherFunc used to build a filter which decides // PartyMatcherFunc used to build a filter which decides
// if the given Party is responsible to fire its `UseRouter` handlers or not. // if the given Party is responsible to fire its `UseRouter` handlers or not.

View File

@ -39,6 +39,15 @@ type Party interface {
// Learn more at: https://github.com/kataras/iris/tree/master/_examples/routing/dynamic-path // Learn more at: https://github.com/kataras/iris/tree/master/_examples/routing/dynamic-path
Macros() *macro.Macros Macros() *macro.Macros
// SetRoutesNoLog disables (true) the verbose logging for the next registered
// routes under this Party and its children.
//
// To disable logging for controllers under MVC Application,
// see `mvc/Application.SetControllersNoLog` instead.
//
// Defaults to false when log level is "debug".
SetRoutesNoLog(disable bool) Party
// OnErrorCode registers a handlers chain for this `Party` for a specific HTTP status code. // OnErrorCode registers a handlers chain for this `Party` for a specific HTTP status code.
// Read more at: http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml // Read more at: http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
// Look `UseError` and `OnAnyErrorCode` too. // Look `UseError` and `OnAnyErrorCode` too.

View File

@ -7,6 +7,7 @@ import (
"io/ioutil" "io/ioutil"
"path/filepath" "path/filepath"
"strings" "strings"
"sync"
"text/template" "text/template"
"github.com/kataras/iris/v12/context" "github.com/kataras/iris/v12/context"
@ -144,16 +145,15 @@ func load(assetNames []string, asset func(string) ([]byte, error), options ...Lo
t := m.Languages[langIndex] t := m.Languages[langIndex]
locale := &defaultLocale{ locale := &defaultLocale{
index: langIndex, index: langIndex,
id: t.String(), id: t.String(),
tag: &t, tag: &t,
templateKeys: templateKeys, templateKeys: templateKeys,
lineKeys: lineKeys, lineKeys: lineKeys,
other: other, other: other,
defaultMessageFunc: m.defaultMessageFunc, defaultMessageFunc: m.defaultMessageFunc,
} }
var longestValueLength int
for k, v := range keyValues { for k, v := range keyValues {
// fmt.Printf("[%d] %s = %v of type: [%T]\n", langIndex, k, v, v) // fmt.Printf("[%d] %s = %v of type: [%T]\n", langIndex, k, v, v)
@ -176,24 +176,34 @@ func load(assetNames []string, asset func(string) ([]byte, error), options ...Lo
} }
} }
if t, err := template.New(k). t, err := template.New(k).Delims(c.Left, c.Right).Funcs(funcs).Parse(value)
Delims(c.Left, c.Right). if err == nil {
Funcs(funcs).
Parse(value); err == nil {
templateKeys[k] = t templateKeys[k] = t
continue
} else if c.Strict { } else if c.Strict {
return nil, err return nil, err
} }
if valueLength := len(value); valueLength > longestValueLength {
longestValueLength = valueLength
}
} }
lineKeys[k] = value lineKeys[k] = value
default: default:
other[k] = v other[k] = v
} }
locales[langIndex] = locale
} }
// pre-allocate the initial internal buffer.
// Note that Reset should be called immediately.
initBuf := []byte(strings.Repeat("x", longestValueLength))
locale.tmplBufPool = &sync.Pool{
New: func() interface{} {
// try to eliminate the internal "grow" method as much as possible.
return bytes.NewBuffer(initBuf)
},
}
locales[langIndex] = locale
} }
if n := len(locales); n == 0 { if n := len(locales); n == 0 {
@ -263,6 +273,8 @@ type defaultLocale struct {
other map[string]interface{} other map[string]interface{}
defaultMessageFunc MessageFunc defaultMessageFunc MessageFunc
tmplBufPool *sync.Pool
} }
func (l *defaultLocale) Index() int { func (l *defaultLocale) Index() int {
@ -289,18 +301,26 @@ func (l *defaultLocale) GetMessageContext(ctx *context.Context, key string, args
func (l *defaultLocale) getMessage(langInput, key string, args ...interface{}) string { func (l *defaultLocale) getMessage(langInput, key string, args ...interface{}) string {
// search on templates. // search on templates.
if tmpl, ok := l.templateKeys[key]; ok { if tmpl, ok := l.templateKeys[key]; ok {
var data interface{} var (
data interface{}
text string
)
if len(args) > 0 { if len(args) > 0 {
data = args[0] data = args[0]
} }
buf := new(bytes.Buffer) buf := l.tmplBufPool.Get().(*bytes.Buffer)
buf.Reset()
err := tmpl.Execute(buf, data) err := tmpl.Execute(buf, data)
if err != nil { if err != nil {
return err.Error() text = err.Error()
} else {
text = buf.String()
} }
return buf.String() l.tmplBufPool.Put(buf)
return text
} }
if text, ok := l.lineKeys[key]; ok { if text, ok := l.lineKeys[key]; ok {

View File

@ -33,6 +33,10 @@ type Application struct {
Router router.Party Router router.Party
Controllers []*ControllerActivator Controllers []*ControllerActivator
websocketControllers []websocket.ConnHandler websocketControllers []websocket.ConnHandler
// Disables verbose logging for controllers under this and its children mvc apps.
// Defaults to false.
controllersNoLog bool
} }
func newApp(subRouter router.Party, container *hero.Container) *Application { func newApp(subRouter router.Party, container *hero.Container) *Application {
@ -115,6 +119,18 @@ func (app *Application) SetName(appName string) *Application {
return app return app
} }
// SetControllersNoLog disables verbose logging for next registered controllers
// under this App and its children of `Application.Party` or `Application.Clone`.
//
// To disable logging for routes under a Party,
// see `Party.SetRoutesNoLog` instead.
//
// Defaults to false when log level is "debug".
func (app *Application) SetControllersNoLog(disable bool) *Application {
app.controllersNoLog = disable
return app
}
// Register appends one or more values as dependencies. // Register appends one or more values as dependencies.
// The value can be a single struct value-instance or a function // The value can be a single struct value-instance or a function
// which has one input and one output, the input should be // which has one input and one output, the input should be
@ -286,7 +302,9 @@ func (app *Application) handle(controller interface{}, options ...Option) *Contr
app.Controllers = append(app.Controllers, c) app.Controllers = append(app.Controllers, c)
// Note: log on register-time, so they can catch any failures before build. // Note: log on register-time, so they can catch any failures before build.
logController(app.Router.Logger(), c) if !app.controllersNoLog {
logController(app.Router.Logger(), c)
}
return c return c
} }
@ -308,6 +326,7 @@ func (app *Application) HandleError(handler func(ctx *context.Context, err error
// Example: `.Clone(app.Party("/path")).Handle(new(TodoSubController))`. // Example: `.Clone(app.Party("/path")).Handle(new(TodoSubController))`.
func (app *Application) Clone(party router.Party) *Application { func (app *Application) Clone(party router.Party) *Application {
cloned := newApp(party, app.container.Clone()) cloned := newApp(party, app.container.Clone())
cloned.controllersNoLog = app.controllersNoLog
return cloned return cloned
} }