From b214df742bd83bb5a3b928f452d2dcc334b1dd75 Mon Sep 17 00:00:00 2001 From: "Gerasimos (Makis) Maropoulos" Date: Tue, 28 Feb 2017 05:37:53 +0200 Subject: [PATCH] Nothing special: when iris.DevLogger() used then group logs based on time. Former-commit-id: 921e2d5baabd3d299f4a719ef0a0abd924bc3bc9 --- .gitignore | 1 + DONATIONS.md | 2 +- adaptors/gorillamux/gorillamux.go | 9 ++-- adaptors/httprouter/httprouter.go | 3 +- adaptors/sessions/sessions.go | 1 + adaptors/typescript/_example/main.go | 5 ++ adaptors/typescript/editor/editor.go | 9 ++-- adaptors/typescript/typescript.go | 8 +-- adaptors/websocket/websocket.go | 6 +++ iris.go | 80 ++++++++++++++++++++++++++-- policy.go | 2 +- 11 files changed, 106 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index c101ac2e..667b16e5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .settings .project +.vscode 2M_donation_timeline.cpd performance_tips.txt notes.txt diff --git a/DONATIONS.md b/DONATIONS.md index d485d74f..3dcafc15 100644 --- a/DONATIONS.md +++ b/DONATIONS.md @@ -70,4 +70,4 @@ I'm grateful for all the generous donations. Iris is fully funded by these dona - **Thanks** to all of **You**, 424 EUR donated to [Holy Metropolis of Ioannina](http://www.imioanninon.gr/main/) for clothes, foods and medications for our fellow human beings. -**Available**: VAT(50) + VAT(20) + VAT(20) + VAT(50) + VAT(6) + VAT(20) + VAT(100) + VAT(20) + VAT(20) + VAT(50) + VAT(30) + VAT(50) + VAT(20) + VAT(5) + VAT(25) + VAT(20) + VAT(20) + VAT(20) - 424 - 13 = 47,45 + 18,97 + 18,61 + 47,05 + 5,34 + 18,97 + 98,04 + 18,97 + 18,61 + 47,95 + 28,24 + 47,05 + 18,97 + 4,59 + 23,80 + 18,77 + 18,97 + 18,61 + 33,76 - 424 - 13 = **114,83 EUR** +**Available**: VAT(50) + VAT(20) + VAT(20) + VAT(50) + VAT(6) + VAT(20) + VAT(100) + VAT(20) + VAT(20) + VAT(50) + VAT(30) + VAT(50) + VAT(20) + VAT(5) + VAT(25) + VAT(20) + VAT(20) + VAT(20) + VAT(35) - 424 - 13 = 47,45 + 18,97 + 18,61 + 47,05 + 5,34 + 18,97 + 98,04 + 18,97 + 18,61 + 47,95 + 28,24 + 47,05 + 18,97 + 4,59 + 23,80 + 18,77 + 18,97 + 18,61 + 33,76 - 424 - 13 = **114,83 EUR** diff --git a/adaptors/gorillamux/gorillamux.go b/adaptors/gorillamux/gorillamux.go index 531e9f81..33684964 100644 --- a/adaptors/gorillamux/gorillamux.go +++ b/adaptors/gorillamux/gorillamux.go @@ -55,10 +55,11 @@ func New() iris.Policies { var logger func(iris.LogMode, string) return iris.Policies{ - EventPolicy: iris.EventPolicy{Boot: func(s *iris.Framework) { - logger = s.Log - s.Set(iris.OptionOther(iris.RouterNameConfigKey, Name)) - }}, + EventPolicy: iris.EventPolicy{ + Boot: func(s *iris.Framework) { + logger = s.Log + s.Set(iris.OptionOther(iris.RouterNameConfigKey, Name)) + }}, RouterReversionPolicy: iris.RouterReversionPolicy{ // path normalization done on iris' side StaticPath: staticPath, diff --git a/adaptors/httprouter/httprouter.go b/adaptors/httprouter/httprouter.go index de3f347f..0c619538 100644 --- a/adaptors/httprouter/httprouter.go +++ b/adaptors/httprouter/httprouter.go @@ -518,8 +518,7 @@ func New() iris.Policies { Boot: func(s *iris.Framework) { logger = s.Log s.Set(iris.OptionOther(iris.RouterNameConfigKey, Name)) - }, - }, + }}, RouterReversionPolicy: iris.RouterReversionPolicy{ // path normalization done on iris' side StaticPath: func(path string) string { diff --git a/adaptors/sessions/sessions.go b/adaptors/sessions/sessions.go index f3e1315f..18efdc58 100644 --- a/adaptors/sessions/sessions.go +++ b/adaptors/sessions/sessions.go @@ -76,6 +76,7 @@ func (s *sessions) Adapt(frame *iris.Policies) { } policy.Adapt(frame) + } // UseDatabase adds a session database to the manager's provider, diff --git a/adaptors/typescript/_example/main.go b/adaptors/typescript/_example/main.go index 07733d55..01428493 100644 --- a/adaptors/typescript/_example/main.go +++ b/adaptors/typescript/_example/main.go @@ -6,6 +6,11 @@ import ( "gopkg.in/kataras/iris.v6/adaptors/typescript" ) +// NOTE: Some machines don't allow to install typescript automatically, so if you don't have typescript installed +// and the typescript adaptor doesn't works for you then follow the below steps: +// 1. close the iris server +// 2. open your terminal and execute: npm install -g typescript +// 3. start your iris server, it should be work, as expected, now. func main() { app := iris.New() app.Adapt(iris.DevLogger()) diff --git a/adaptors/typescript/editor/editor.go b/adaptors/typescript/editor/editor.go index 2613f35f..88c387c2 100644 --- a/adaptors/typescript/editor/editor.go +++ b/adaptors/typescript/editor/editor.go @@ -172,12 +172,13 @@ func (e *Editor) start() { cmd := npm.CommandBuilder("node", npm.NodeModuleAbs("alm/src/server.js")) cmd.AppendArguments("-a", e.config.Username+":"+e.config.Password, - "-h", e.config.Hostname, "-t", strconv.Itoa(e.config.Port), "-d", e.config.WorkingDir[0:len(e.config.WorkingDir)-1]) + "-h", e.config.Hostname, "-t", strconv.Itoa(e.config.Port), "-d", e.config.WorkingDir) // for auto-start in the browser: cmd.AppendArguments("-o") if e.config.KeyFile != "" && e.config.CertFile != "" { cmd.AppendArguments("--httpskey", e.config.KeyFile, "--httpscert", e.config.CertFile) } + prefix := "" // when debug is not disabled // show any messages to the user( they are useful here) // to the io.Writer that iris' user is defined from configuration @@ -189,7 +190,7 @@ func (e *Editor) start() { go func() { for outputScanner.Scan() { - e.logger(iris.DevMode, "Editor: "+outputScanner.Text()) + e.logger(iris.DevMode, prefix+outputScanner.Text()) } }() @@ -198,7 +199,7 @@ func (e *Editor) start() { errScanner := bufio.NewScanner(errReader) go func() { for errScanner.Scan() { - e.logger(iris.DevMode, "Editor: "+errScanner.Text()) + e.logger(iris.DevMode, prefix+errScanner.Text()) } }() } @@ -207,7 +208,7 @@ func (e *Editor) start() { err := cmd.Start() if err != nil { - e.logger(iris.ProdMode, "Error while running alm-tools. Trace: "+err.Error()) + e.logger(iris.ProdMode, prefix+err.Error()) return } diff --git a/adaptors/typescript/typescript.go b/adaptors/typescript/typescript.go index 57a1fb78..7e4e3aef 100644 --- a/adaptors/typescript/typescript.go +++ b/adaptors/typescript/typescript.go @@ -104,15 +104,15 @@ func (t *TsAdaptor) start() { } } - t.logger(iris.DevMode, fmt.Sprintf("%d Typescript project(s) compiled ( %d monitored by a background file watcher ) ", len(projects), watchedProjects)) + // t.logger(iris.DevMode, fmt.Sprintf("%d Typescript project(s) compiled ( %d monitored by a background file watcher ) ", len(projects), watchedProjects)) } else { //search for standalone typescript (.ts) files and compile them files := t.getTypescriptFiles() if len(files) > 0 { - watchedFiles := 0 + /* watchedFiles := 0 if t.Config.Tsconfig.CompilerOptions.Watch { watchedFiles = len(files) - } + }*/ //it must be always > 0 if we came here, because of if hasTypescriptFiles == true. for _, file := range files { absPath, err := filepath.Abs(file) @@ -142,7 +142,7 @@ func (t *TsAdaptor) start() { }() } - t.logger(iris.DevMode, fmt.Sprintf("%d Typescript file(s) compiled ( %d monitored by a background file watcher )", len(files), watchedFiles)) + // t.logger(iris.DevMode, fmt.Sprintf("%d Typescript file(s) compiled ( %d monitored by a background file watcher )", len(files), watchedFiles)) } } diff --git a/adaptors/websocket/websocket.go b/adaptors/websocket/websocket.go index e54ba3b1..d4af56e4 100644 --- a/adaptors/websocket/websocket.go +++ b/adaptors/websocket/websocket.go @@ -56,6 +56,12 @@ func (s *server) Adapt(frame *iris.Policies) { // serve the client side on domain:port/iris-ws.js f.StaticContent(wsClientSidePath, "application/javascript", ClientSource).ChangeName(clientSideLookupName) } + + // If we want to show configuration fields... I'm not sure for this yet, so let it commented: f.Logf(iris.DevMode, "%#v", s.config) + }, + + Build: func(f *iris.Framework) { + f.Log(iris.DevMode, "Serving Websockets on "+f.Config.VHost+s.config.Endpoint) }, } diff --git a/iris.go b/iris.go index 3130346b..9df71cc6 100644 --- a/iris.go +++ b/iris.go @@ -133,7 +133,7 @@ type Framework struct { once sync.Once // used to 'Boot' once } -var defaultGlobalLoggerOuput = log.New(os.Stdout, "[Iris] ", log.LstdFlags) +var defaultGlobalLoggerOuput = log.New(os.Stdout, "", log.LstdFlags) // DevLogger returns a new Logger which prints both ProdMode and DevMode messages // to the default global logger printer. @@ -144,8 +144,26 @@ var defaultGlobalLoggerOuput = log.New(os.Stdout, "[Iris] ", log.LstdFlags) // Users can always ignore that and adapt a custom LoggerPolicy, // which will use your custom printer instead. func DevLogger() LoggerPolicy { + lastLog := time.Now() + distanceDuration := 850 * time.Millisecond return func(mode LogMode, logMessage string) { - defaultGlobalLoggerOuput.Println(logMessage) + if strings.Contains(logMessage, banner) { + fmt.Print(logMessage) + lastLog = time.Now() + return + } + nowLog := time.Now() + if nowLog.Before(lastLog.Add(distanceDuration)) { + // don't use the log.Logger to print this message + // if the last one was printed before some seconds. + fmt.Println(logMessage) + lastLog = nowLog + return + } + // begin with new line in order to have the time once at the top + // and the child logs below it. + defaultGlobalLoggerOuput.Println("\u2192\n" + logMessage) + lastLog = nowLog } } @@ -186,6 +204,11 @@ func New(setters ...OptionSetter) *Framework { } })) + s.Adapt(EventPolicy{Boot: func(*Framework) { + // Print the banner first, even if we have to print errors later. + s.Log(DevMode, banner+"\n\n") + }}) + } // +------------------------------------------------------------+ @@ -382,11 +405,52 @@ func (s *Framework) Set(setters ...OptionSetter) { // Log logs to the defined logger policy. // -// The default outputs to the os.Stdout when EnvMode is 'ProductionEnv' +// The default outputs to the os.Stdout when EnvMode is 'iris.ProdMode' func (s *Framework) Log(mode LogMode, log string) { s.policies.LoggerPolicy(mode, log) } +// Author's note: +// +// I implemented this and worked for configuration fields logs but I'm not sure +// if users want to print adaptor's configuration, i.e: websocket, sessions +// so comment this feature, and +// if/when I get good feedback from the private beta testers I'll uncomment these on public repo too. +// +// +// Logf same as .Log but receives arguments like fmt.Printf. +// Note: '%#v' and '%+v' named arguments are being printed, pretty. +// +// The default outputs to the os.Stdout when EnvMode is 'iris.ProdMode' +// func (s *Framework) Logf(mode LogMode, format string, v ...interface{}) { +// if mode == DevMode { +// marker := 0 +// for i := 0; i < len(format); i++ { +// if format[i] == '%' { +// if i < len(format)-2 { +// if part := format[i : i+3]; part == "%#v" || part == "%+v" { +// if len(v) > marker { +// spew.Config.Indent = "\t\t\t" +// spew.Config.DisablePointerAddresses = true +// spew.Config.DisableCapacities = true +// spew.Config.DisablePointerMethods = true +// spew.Config.DisableMethods = true +// arg := v[marker] +// format = strings.Replace(format, part, "%s", 1) +// v[marker] = spew.Sdump(arg) +// } +// } +// } +// marker++ +// } +// } +// } +// +// log := fmt.Sprintf(format, v...) +// +// s.policies.LoggerPolicy(mode, log) +// } + // Must checks if the error is not nil, if it isn't // panics on registered iris' logger or // to a recovery event handler, otherwise does nothing. @@ -499,7 +563,15 @@ func (s *Framework) Serve(ln net.Listener) error { } func (s *Framework) postServe() { - bannerMessage := fmt.Sprintf("| Running at %s\n\n%s\n", s.Config.VHost, banner) + routerInfo := "" + if routerNameVal := s.Config.Other[RouterNameConfigKey]; routerNameVal != nil { + if routerName, ok := routerNameVal.(string); ok { + routerInfo = "using " + routerName + } + } + + bannerMessage := fmt.Sprintf("Serving HTTP on %s port %d %s", ParseHostname(s.Config.VHost), ParsePort(s.Config.VHost), routerInfo) + s.Log(DevMode, bannerMessage) ch := make(chan os.Signal, 1) diff --git a/policy.go b/policy.go index 20fc80ff..e3067735 100644 --- a/policy.go +++ b/policy.go @@ -92,7 +92,7 @@ const ( // ProdMode the production level logger write mode, // responsible to fatal errors, errors that happen which // your app can't continue running. - ProdMode LogMode = iota + ProdMode LogMode = 1 << iota // DevMode is the development level logger write mode, // responsible to the rest of the errors, for example // if you set a app.Favicon("myfav.ico"..) and that fav doesn't exists