Make WARN the new default log log level
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Thu, 1 Nov 2018 21:27:42 +0000 (22:27 +0100)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Sat, 3 Nov 2018 11:06:23 +0000 (12:06 +0100)
This commit also pulls down the log level for a set of WARN statements to INFO. There should be no ERRORs or WARNINGs in a regular Hugo build. That is the story about the Boy Who Cried Wolf.

Since the WARN log is now more visible, this commit also improves on some of them, most notable the "layout not found", which now would look something like this:

```bash
WARN 2018/11/02 09:02:18 Found no layout for "home", language "en", output format "CSS": create a template below /layouts with one of these filenames: index.en.css.css, home.en.css.css, list.en.css.css, index.css.css, home.css.css, list.css.css, index.en.css, home.en.css, list.en.css, index.css, home.css, list.css, _default/index.en.css.css, _default/home.en.css.css, _default/list.en.css.css, _default/index.css.css, _default/home.css.css, _default/list.css.css, _default/index.en.css, _default/home.en.css, _default/list.en.css, _default/index.css, _default/home.css, _default/list.css
```

Fixes #5203

commands/hugo.go
hugolib/alias.go
hugolib/page.go
hugolib/page_content.go
hugolib/pagebundler_capture.go
hugolib/site.go
i18n/i18n.go
tpl/data/data.go

index 7d2fa980389da480d1152c81e31b01ec34cdc62e..175c6dc9999c1fc4f1163b085455140c972429b8 100644 (file)
@@ -131,7 +131,7 @@ func (c *commandeer) createLogger(cfg config.Provider, running bool) (*loggers.L
                logThreshold    = jww.LevelWarn
                logFile         = cfg.GetString("logFile")
                outHandle       = os.Stdout
-               stdoutThreshold = jww.LevelError
+               stdoutThreshold = jww.LevelWarn
        )
 
        if c.h.verboseLog || c.h.logging || (c.h.logFile != "") {
@@ -294,7 +294,7 @@ func (c *commandeer) fullBuild() error {
                        if !os.IsNotExist(err) {
                                return errors.Wrap(err, "Error copying static files")
                        }
-                       c.logger.WARN.Println("No Static directory found")
+                       c.logger.INFO.Println("No Static directory found")
                }
                langCount = cnt
                langCount = cnt
@@ -405,7 +405,7 @@ func (c *commandeer) doWithPublishDirs(f func(sourceFs *filesystems.SourceFilesy
        staticFilesystems := c.hugo.BaseFs.SourceFilesystems.Static
 
        if len(staticFilesystems) == 0 {
-               c.logger.WARN.Println("No static directories found to sync")
+               c.logger.INFO.Println("No static directories found to sync")
                return langCount, nil
        }
 
index bcf8f1963ec198b58ea3748dfb341941a74b8e11..c44f32dbba10341f4c3e23bd38e0b2b5df96e20e 100644 (file)
@@ -174,7 +174,7 @@ func (a aliasHandler) targetPathAlias(src string) (string, error) {
                        return "", fmt.Errorf("Cannot create \"%s\": Windows filename restriction", originalAlias)
                }
                for _, m := range msgs {
-                       a.log.WARN.Println(m)
+                       a.log.INFO.Println(m)
                }
        }
 
index d91082b3bc674c954130e513a55eeefb9492ef5f..070df133bea6da0f77245bf16506ae05aea8038f 100644 (file)
@@ -326,7 +326,7 @@ func (p *Page) initContent() {
 
                select {
                case <-ctx.Done():
-                       p.s.Log.WARN.Printf("WARNING: Timed out creating content for page %q (.Content will be empty). This is most likely a circular shortcode content loop that should be fixed. If this is just a shortcode calling a slow remote service, try to set \"timeout=20000\" (or higher, value is in milliseconds) in config.toml.\n", p.pathOrTitle())
+                       p.s.Log.WARN.Printf("Timed out creating content for page %q (.Content will be empty). This is most likely a circular shortcode content loop that should be fixed. If this is just a shortcode calling a slow remote service, try to set \"timeout=30000\" (or higher, value is in milliseconds) in config.toml.\n", p.pathOrTitle())
                case err := <-c:
                        if err != nil {
                                p.s.SendError(err)
@@ -1456,7 +1456,7 @@ func (p *Page) updateMetaData(frontmatter map[string]interface{}) error {
 
        if draft != nil && published != nil {
                p.Draft = *draft
-               p.s.Log.WARN.Printf("page %q has both draft and published settings in its frontmatter. Using draft.", p.File.Path())
+               p.s.Log.WARN.Printf("page %q has both draft and published settings in its frontmatter. Using draft.", p.Filename())
        } else if draft != nil {
                p.Draft = *draft
        } else if published != nil {
@@ -1973,8 +1973,6 @@ func (p *Page) initLanguage() {
                language := ml.Language(p.lang)
 
                if language == nil {
-                       // It can be a file named stefano.chiodino.md.
-                       p.s.Log.WARN.Printf("Page language (if it is that) not found in multilang setup: %s.", p.lang)
                        language = ml.DefaultLang
                }
 
index dc043f8241a14b6e0e8bd98cd446ff2aa21c4114..75124a1df9e6bfa4bbbd96b4011f3cdee9529ef2 100644 (file)
@@ -188,7 +188,7 @@ func (p *Page) parse(reader io.Reader) error {
                if gi != nil {
                        p.GitInfo = gi
                } else if enabled {
-                       p.s.Log.WARN.Printf("Failed to find GitInfo for page %q", p.Path())
+                       p.s.Log.INFO.Printf("Failed to find GitInfo for page %q", p.Path())
                }
        }
 
index c152262cc6e9ba3ad0ade991c0e5df7c425811dd..446d3b0c741d5aca734959808d120ad731b7555b 100644 (file)
@@ -679,7 +679,7 @@ func (c *capturer) isSeen(dirname string) bool {
        seen := c.seen[dirname]
        c.seen[dirname] = true
        if seen {
-               c.logger.WARN.Printf("Content dir %q already processed; skipped to avoid infinite recursion.", dirname)
+               c.logger.INFO.Printf("Content dir %q already processed; skipped to avoid infinite recursion.", dirname)
                return true
 
        }
index e58dd39b29f0b881a781448a643838b7d7465c32..761d4a6bd3c2c00c41e62164842593fbdbad1df2 100644 (file)
@@ -956,7 +956,7 @@ func (s *Site) handleDataFile(r source.ReadableFile) error {
                        higherPrecedentMap := higherPrecedentData.(map[string]interface{})
                        for key, value := range data.(map[string]interface{}) {
                                if _, exists := higherPrecedentMap[key]; exists {
-                                       s.Log.WARN.Printf("Data for key '%s' in path '%s' is overridden higher precedence data already in the data tree", key, r.Path())
+                                       s.Log.WARN.Printf("Data for key '%s' in path '%s' is overridden by higher precedence data already in the data tree", key, r.Path())
                                } else {
                                        higherPrecedentMap[key] = value
                                }
@@ -1759,24 +1759,49 @@ func (s *Site) renderAndWritePage(statCounter *uint64, name string, targetPath s
        return s.publisher.Publish(pd)
 }
 
+var infoOnMissingLayout = map[string]bool{
+       // The 404 layout is very much optional in Hugo, but we do look for it.
+       "404": true,
+}
+
 func (s *Site) renderForLayouts(name string, d interface{}, w io.Writer, layouts ...string) (err error) {
        var templ tpl.Template
 
        templ = s.findFirstTemplate(layouts...)
        if templ == nil {
-               s.Log.WARN.Printf("[%s] Unable to locate layout for %q: %s\n", s.Language.Lang, name, layouts)
+               log := s.Log.WARN
+               if infoOnMissingLayout[name] {
+                       log = s.Log.INFO
+               }
+
+               if p, ok := d.(*PageOutput); ok {
+                       log.Printf("Found no layout for %q, language %q, output format %q: create a template below /layouts with one of these filenames: %s\n", name, s.Language.Lang, p.outputFormat.Name, layoutsLogFormat(layouts))
+               } else {
+                       log.Printf("Found no layout for %q, language %q: create a template below /layouts with one of these filenames: %s\n", name, s.Language.Lang, layoutsLogFormat(layouts))
+               }
                return nil
        }
 
        if err = templ.Execute(w, d); err != nil {
-               if p, ok := d.(*PageOutput); ok {
-                       return p.errorf(err, "render of %q failed", name)
-               }
                return _errors.Wrapf(err, "render of %q failed", name)
        }
        return
 }
 
+func layoutsLogFormat(layouts []string) string {
+       var filtered []string
+       for _, l := range layouts {
+               // This is  a technical prefix of no interest to the user.
+               lt := strings.TrimPrefix(l, "_text/")
+               // We have this in the lookup path for historical reasons.
+               lt = strings.TrimPrefix(lt, "page/")
+               filtered = append(filtered, lt)
+       }
+
+       filtered = helpers.UniqueStrings(filtered)
+       return strings.Join(filtered, ", ")
+}
+
 func (s *Site) findFirstTemplate(layouts ...string) tpl.Template {
        for _, layout := range layouts {
                if templ, found := s.Tmpl.Lookup(layout); found {
index d395bbf62bd337ca0ec32a2520b0fa90b61cb37f..25f2d300e402325931495a7f44e9b424a5d4fccc 100644 (file)
@@ -45,11 +45,11 @@ func (t Translator) Func(lang string) bundle.TranslateFunc {
        if f, ok := t.translateFuncs[lang]; ok {
                return f
        }
-       t.logger.WARN.Printf("Translation func for language %v not found, use default.", lang)
+       t.logger.INFO.Printf("Translation func for language %v not found, use default.", lang)
        if f, ok := t.translateFuncs[t.cfg.GetString("defaultContentLanguage")]; ok {
                return f
        }
-       t.logger.WARN.Println("i18n not initialized, check that you have language file (in i18n) that matches the site language or the default language.")
+       t.logger.INFO.Println("i18n not initialized; if you need string translations, check that you have a bundle in /i18n that matches the site language or the default language.")
        return func(translationID string, args ...interface{}) string {
                return ""
        }
@@ -61,7 +61,7 @@ func (t Translator) initFuncs(bndl *bundle.Bundle) {
 
        defaultT, err := bndl.Tfunc(defaultContentLanguage)
        if err != nil {
-               t.logger.WARN.Printf("No translation bundle found for default language %q", defaultContentLanguage)
+               t.logger.INFO.Printf("No translation bundle found for default language %q", defaultContentLanguage)
        }
 
        enableMissingTranslationPlaceholders := t.cfg.GetBool("enableMissingTranslationPlaceholders")
index 8b3eb8292efd979481ff2b1a74778a8504d0a3c4..cecce4b4574abfb10a028bfddb6227cd16f4e384 100644 (file)
@@ -50,7 +50,7 @@ func (ns *Namespace) GetCSV(sep string, urlParts ...string) (d [][]string, err e
        url := strings.Join(urlParts, "")
 
        var clearCacheSleep = func(i int, u string) {
-               ns.deps.Log.WARN.Printf("Retry #%d for %s and sleeping for %s", i, url, resSleep)
+               ns.deps.Log.INFO.Printf("Retry #%d for %s and sleeping for %s", i, url, resSleep)
                time.Sleep(resSleep)
                deleteCache(url, ns.deps.Fs.Source, ns.deps.Cfg)
        }
@@ -109,8 +109,8 @@ func (ns *Namespace) GetJSON(urlParts ...string) (v interface{}, err error) {
                }
                err = json.Unmarshal(c, &v)
                if err != nil {
-                       ns.deps.Log.WARN.Printf("Cannot read JSON from resource %s: %s", url, err)
-                       ns.deps.Log.WARN.Printf("Retry #%d for %s and sleeping for %s", i, url, resSleep)
+                       ns.deps.Log.INFO.Printf("Cannot read JSON from resource %s: %s", url, err)
+                       ns.deps.Log.INFO.Printf("Retry #%d for %s and sleeping for %s", i, url, resSleep)
                        time.Sleep(resSleep)
                        deleteCache(url, ns.deps.Fs.Source, ns.deps.Cfg)
                        continue