diff --git a/cmd/eagle/root.go b/cmd/eagle/root.go index e04f65c3..d214141d 100644 --- a/cmd/eagle/root.go +++ b/cmd/eagle/root.go @@ -38,7 +38,7 @@ var rootCmd = &cobra.Command{ log.Info("starting server") err := server.Start() if err != nil && !errors.Is(err, http.ErrServerClosed) { - log.Errorf("failed to start server: %s", err) + log.Errorw("failed to start server", "err", err) } quit <- os.Interrupt }() diff --git a/core/eagle.go b/core/eagle.go index e5234b7a..cb4a0fb7 100644 --- a/core/eagle.go +++ b/core/eagle.go @@ -1,6 +1,5 @@ package core type Notifier interface { - Info(msg string) - Error(err error) + Notify(msg string) } diff --git a/log/notifier.go b/log/notifier.go index e9db7e11..b609f6f8 100644 --- a/log/notifier.go +++ b/log/notifier.go @@ -8,14 +8,10 @@ type LogNotifier struct { func NewLogNotifier() *LogNotifier { return &LogNotifier{ - log: S().Named("notify"), + log: S().Named("notifier"), } } -func (n *LogNotifier) Info(msg string) { +func (n *LogNotifier) Notify(msg string) { n.log.Info(msg) } - -func (n *LogNotifier) Error(err error) { - n.log.Error(err) -} diff --git a/plugins/mastodon/mastodon.go b/plugins/mastodon/mastodon.go index 60bdc4b3..b091d9be 100644 --- a/plugins/mastodon/mastodon.go +++ b/plugins/mastodon/mastodon.go @@ -113,7 +113,7 @@ func (m *Mastodon) uploadPhotos(ctx context.Context, photos []server.Photo) []ma attachment, err := m.client.UploadMediaFromBytes(ctx, photo.Data) if err != nil { - m.log.Warnw("photo upload failed", "err", err) + m.log.Warnw("photo upload failed", "mimetype", photo.MimeType, "err", err) continue } diff --git a/server/micropub.go b/server/micropub.go index ffee66f8..ce147bab 100644 --- a/server/micropub.go +++ b/server/micropub.go @@ -30,7 +30,7 @@ const ( func (s *Server) getMicropubChannels() []micropub.Channel { taxons, err := s.bolt.GetTaxonomy(context.Background(), s.c.Micropub.ChannelsTaxonomy) if err != nil { - s.log.Warnw("could not fetch channels taxonomy", "taxonomy", s.c.Micropub.ChannelsTaxonomy, "err", err) + s.log.Errorw("failed to fetch channels taxonomy", "taxonomy", s.c.Micropub.ChannelsTaxonomy, "err", err) return nil } @@ -45,7 +45,7 @@ func (s *Server) getMicropubChannels() []micropub.Channel { func (s *Server) getMicropubCategories() []string { taxons, err := s.bolt.GetTaxonomy(context.Background(), s.c.Micropub.CategoriesTaxonomy) if err != nil { - s.log.Warnw("could not fetch categories taxonomy", "taxonomy", s.c.Micropub.CategoriesTaxonomy, "err", err) + s.log.Errorw("failed to fetch categories taxonomy", "taxonomy", s.c.Micropub.CategoriesTaxonomy, "err", err) return nil } @@ -279,7 +279,7 @@ func (m *micropubServer) syndicate(e *core.Entry, syndicators []string) { // Get the photos to use during syndication photos, err := m.getPhotos(e) if err != nil { - m.s.log.Warnw("failed to get photos for syndication", "err", err) + m.s.log.Errorw("failed to get photos for syndication", "entry", e.ID, "err", err) return } @@ -296,7 +296,7 @@ func (m *micropubServer) syndicate(e *core.Entry, syndicators []string) { if syndicator, ok := m.s.syndicators[name]; ok { syndication, removed, err := syndicator.Syndicate(context.Background(), e, photos) if err != nil { - m.s.log.Warnw("failed to syndicate", "name", name, "err", err) + m.s.log.Errorw("failed to syndicate", "entry", e.ID, "syndicator", name, "err", err) continue } @@ -317,7 +317,7 @@ func (m *micropubServer) syndicate(e *core.Entry, syndicators []string) { err = m.s.core.SaveEntry(e) if err != nil { - m.s.log.Warnw("failed save entry", "id", e.ID, "err", err) + m.s.log.Errorw("failed save entry", "id", e.ID, "err", err) } } @@ -354,7 +354,7 @@ func (m *micropubServer) postSave(e *core.Entry, req *micropub.Request, oldTarge err := hookPlugin.PostSaveHook(e) if err != nil { - m.s.n.Error(fmt.Errorf("plugin %s post save hook failed sync failed: %w", name, err)) + m.s.log.Errorw("plugin post save hook failed", "plugin", name, "err", err) } } @@ -367,12 +367,12 @@ func (m *micropubServer) postSave(e *core.Entry, req *micropub.Request, oldTarge err = m.s.meilisearch.Add(e) } if err != nil { - m.s.n.Error(fmt.Errorf("meilisearch sync failed: %w", err)) + m.s.log.Errorw("meilisearch sync failed", "err", err) } } // Rebuild - m.s.buildNotify(false) + m.s.build(false) // No further action for drafts or no webmentions if e.Draft || e.NoWebmentions { @@ -381,7 +381,7 @@ func (m *micropubServer) postSave(e *core.Entry, req *micropub.Request, oldTarge err := m.s.core.SendWebmentions(e.Permalink, oldTargets...) if err != nil { - m.s.n.Error(fmt.Errorf("sending webmentions failed: %w", err)) + m.s.log.Errorw("failed to send webmentions", "id", e.ID, "err", err) } } diff --git a/server/panel.go b/server/panel.go index 3480382e..736f44ce 100644 --- a/server/panel.go +++ b/server/panel.go @@ -226,7 +226,7 @@ func (s *Server) panelPostAction(w http.ResponseWriter, r *http.Request) { return } - go s.buildNotify(false) + go s.build(false) s.servePanel(w, r, data) } diff --git a/server/render.go b/server/render.go index c388397a..7e978e79 100644 --- a/server/render.go +++ b/server/render.go @@ -70,7 +70,7 @@ func (s *Server) renderDocument(w http.ResponseWriter, r *http.Request, doc *goq err := s.templates.ExecuteTemplate(&buf, template, data) if err != nil { w.WriteHeader(http.StatusInternalServerError) - s.n.Error(fmt.Errorf("serving html: %w", err)) + s.log.Errorw("failed to serve html", "url", r.URL.Path, "err", err) return } @@ -80,7 +80,7 @@ func (s *Server) renderDocument(w http.ResponseWriter, r *http.Request, doc *goq html, err := doc.Html() if err != nil { w.WriteHeader(http.StatusInternalServerError) - s.n.Error(fmt.Errorf("serving html for %s: %w", r.URL.Path, err)) + s.log.Errorw("failed to get document html", "url", r.URL.Path, "err", err) return } @@ -88,7 +88,7 @@ func (s *Server) renderDocument(w http.ResponseWriter, r *http.Request, doc *goq w.WriteHeader(code) _, err = w.Write([]byte(html)) if err != nil { - s.n.Error(fmt.Errorf("serving html for %s: %w", r.URL.Path, err)) + s.log.Errorw("failed to write html", "url", r.URL.Path, "err", err) } } @@ -111,7 +111,7 @@ func (s *Server) panelTemplate(w http.ResponseWriter, r *http.Request, code int, w.WriteHeader(code) err := panelTemplates.ExecuteTemplate(w, template, data) if err != nil { - s.n.Error(fmt.Errorf("serving html: %w", err)) + s.log.Errorw("failed to execute template", "url", r.URL.Path, "err", err) } } @@ -120,7 +120,7 @@ func (s *Server) serveJSON(w http.ResponseWriter, code int, data interface{}) { w.WriteHeader(code) err := json.NewEncoder(w).Encode(data) if err != nil { - s.n.Error(fmt.Errorf("serving html: %w", err)) + s.log.Errorw("failed to write JSON", "err", err) } } diff --git a/server/server.go b/server/server.go index 56b96620..b779dec4 100644 --- a/server/server.go +++ b/server/server.go @@ -5,7 +5,6 @@ import ( "embed" "encoding/base64" "errors" - "fmt" "html/template" "net" "net/http" @@ -151,8 +150,7 @@ func (s *Server) Start() error { if s.c.Tor { err = s.startTor(errCh, router) if err != nil { - err = fmt.Errorf("onion service failed to start: %w", err) - s.log.Error(err) + s.log.Errorw("onion service failed to start", "err", err) } } @@ -233,20 +231,20 @@ func (s *Server) indexAll() { entries, err := s.core.GetEntries(false) if err != nil { - s.n.Error(err) + s.log.Errorw("failed to get entries", "err", err) return } if s.meilisearch != nil { err := s.meilisearch.ResetIndex() if err != nil { - s.n.Error(err) + s.log.Errorw("failed to reset meilisearch index", "err", err) } start := time.Now() err = s.meilisearch.Add(entries...) if err != nil { - s.n.Error(err) + s.log.Errorw("failed to add to meilisearch index", "err", err) } s.log.Infof("meilisearch update took %dms", time.Since(start).Milliseconds()) } @@ -254,7 +252,7 @@ func (s *Server) indexAll() { if s.c.Micropub != nil { err := s.bolt.ResetTaxonomies(context.Background()) if err != nil { - s.n.Error(err) + s.log.Errorw("failed to reset taxonomies", "err", err) } start := time.Now() @@ -262,14 +260,14 @@ func (s *Server) indexAll() { if s.c.Micropub.CategoriesTaxonomy != "" { err = s.indexAllTaxonomies(entries, s.c.Micropub.CategoriesTaxonomy) if err != nil { - s.n.Error(err) + s.log.Errorw("failed to index all taxonomies", "taxonomy", s.c.Micropub.CategoriesTaxonomy, "err", err) } } if s.c.Micropub.ChannelsTaxonomy != "" { err = s.indexAllTaxonomies(entries, s.c.Micropub.ChannelsTaxonomy) if err != nil { - s.n.Error(err) + s.log.Errorw("failed to index all taxonomies", "taxonomy", s.c.Micropub.ChannelsTaxonomy, "err", err) } } @@ -291,8 +289,7 @@ func (s *Server) withRecoverer(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { defer func() { if rvr := recover(); rvr != nil && rvr != http.ErrAbortHandler { - err := fmt.Errorf("panic while serving: %v: %s", rvr, string(debug.Stack())) - s.n.Error(err) + s.log.Errorw("panic while serving", "rvr", rvr, "stack", string(debug.Stack())) w.WriteHeader(http.StatusInternalServerError) } }() @@ -329,7 +326,7 @@ func (s *Server) withSecurityHeaders(next http.Handler) http.Handler { func (s *Server) syncStorage() { changedFiles, err := s.core.Sync() if err != nil { - s.n.Error(fmt.Errorf("sync storage: %w", err)) + s.log.Errorw("failed to sync storage", "err", err) return } @@ -353,7 +350,7 @@ func (s *Server) syncStorage() { buildClean = true continue } else if err != nil { - s.n.Error(fmt.Errorf("cannot open entry to update %s: %w", id, err)) + s.log.Errorw("failed to open entry to update", "id", id, "err", err) continue } else { ee = append(ee, e) @@ -370,11 +367,11 @@ func (s *Server) syncStorage() { if s.meilisearch != nil { err = s.meilisearch.Add(ee...) if err != nil { - s.n.Error(fmt.Errorf("meilisearch sync failed: %w", err)) + s.log.Errorw("failed to add entries to meilisearch", "err", err) } } - s.buildNotify(buildClean) + s.build(buildClean) // TODO: smh call postSave here @@ -388,7 +385,7 @@ func (s *Server) syncStorage() { err = s.core.SendWebmentions(e.Permalink, previousLinks[e.Permalink]...) if err != nil { - s.n.Error(fmt.Errorf("send webmentions: %w", err)) + s.log.Errorw("failed to send webmentions", "id", e.Permalink, "err", err) } } } @@ -408,10 +405,10 @@ func idsFromChangedFiles(changedFiles []string) []string { return ids } -func (s *Server) buildNotify(clean bool) { +func (s *Server) build(clean bool) { err := s.core.Build(clean) if err != nil { - s.n.Error(fmt.Errorf("build failed: %w", err)) + s.log.Errorw("failed to build", "err", err) } } @@ -426,7 +423,7 @@ func (s *Server) buildHook(dir string) { if oldFs != nil { err := os.RemoveAll(oldFs.dir) if err != nil { - s.n.Error(fmt.Errorf("could not delete old directory: %w", err)) + s.log.Errorw("failed to delete old build directory", "path", oldFs.dir, "err", err) } } } diff --git a/server/server_init.go b/server/server_init.go index 700f00c8..ad5cfad4 100644 --- a/server/server_init.go +++ b/server/server_init.go @@ -178,7 +178,7 @@ func (s *Server) initCron() error { } if err := cronPlugin.DailyCron(); err != nil { - s.n.Error(fmt.Errorf("cron job (plugin %s): %w", name, err)) + s.log.Errorw("plugin cron job execution failed", "plugin", name, "err", err) } } diff --git a/server/webhook.go b/server/webhook.go index d59238e9..43554ae1 100644 --- a/server/webhook.go +++ b/server/webhook.go @@ -30,7 +30,7 @@ func (s *Server) webhookPost(w http.ResponseWriter, r *http.Request) { mac := hmac.New(sha1.New, []byte(s.c.WebhookSecret)) _, err = mac.Write(payload) if err != nil { - s.log.Error("webhook: could not write mac", err) + s.log.Errorw("webhook: could not write mac", "err", err) return } expectedMAC := hex.EncodeToString(mac.Sum(nil)) diff --git a/server/webmentions.go b/server/webmentions.go index ff7db123..f5bfba44 100644 --- a/server/webmentions.go +++ b/server/webmentions.go @@ -85,7 +85,7 @@ func (s *Server) commentsPost(w http.ResponseWriter, r *http.Request) { return } - s.n.Info(fmt.Sprintf("💬 #mention pending approval for %q", e.Permalink)) + s.n.Notify(fmt.Sprintf("💬 #mention pending approval for %q", e.Permalink)) http.Redirect(w, r, s.c.Comments.Redirect, http.StatusSeeOther) } @@ -102,7 +102,7 @@ func (s *Server) webmentionPost(w http.ResponseWriter, r *http.Request) { err := json.NewDecoder(r.Body).Decode(&payload) if err != nil { w.WriteHeader(http.StatusBadRequest) - s.log.Warnf("error when decoding webmention: %s", err.Error()) + s.log.Errorw("error decoding webmention", "err", err) return } @@ -120,20 +120,16 @@ func (s *Server) handleWebmention(payload *webmentionPayload) { s.log.Infow("received webmention", "webmention", payload) e, err := s.core.GetEntryFromPermalink(payload.Target) if err != nil { - err = fmt.Errorf("could not get entry for permalink %s: %w", payload.Target, err) - s.log.Errorf("webmention", err) - s.n.Error(err) + s.log.Errorw("failed to get entry for permalink", "target", payload.Target, "err", err) return } if payload.Deleted { err = s.core.DeleteWebmention(e.ID, payload.Source) if err != nil { - err = fmt.Errorf("could not delete webmention for %s: %w", payload.Target, err) - s.log.Errorf("webmention", err) - s.n.Error(err) + s.log.Errorw("failed to delete webmention", "target", payload.Target, "err", err) } else { - s.n.Info(fmt.Sprintf("💬 #mention deleted for %q: %q", e.Permalink, payload.Source)) + s.n.Notify(fmt.Sprintf("💬 #mention deleted for %q: %q", e.Permalink, payload.Source)) } return } @@ -149,10 +145,8 @@ func (s *Server) handleWebmention(payload *webmentionPayload) { err = s.bolt.AddMention(context.Background(), mention) if err != nil { - err = fmt.Errorf("could not add webmention for %s: %w", payload.Target, err) - s.log.Errorf("webmention", err) - s.n.Error(err) + s.log.Errorw("failed to add webmention", "target", payload.Target, "err", err) } else { - s.n.Info(fmt.Sprintf("💬 #mention pending approval for %q: %q", e.Permalink, payload.Source)) + s.n.Notify(fmt.Sprintf("💬 #mention pending approval for %q: %q", e.Permalink, payload.Source)) } } diff --git a/services/media/media.go b/services/media/media.go index 24abcf61..c40d75e8 100644 --- a/services/media/media.go +++ b/services/media/media.go @@ -100,7 +100,7 @@ func (m *Media) upload(filename, ext string, data []byte) (string, error) { if isImage(ext) { str, err := m.uploadImage(filename, data) if err != nil { - m.log.Warnf("could not upload image: %s", err.Error()) + m.log.Errorf("failed to upload image", "filename", filename, "ext", ext, "err", err) } else { return str, nil } diff --git a/services/telegram/telegram.go b/services/telegram/telegram.go index d24eb8f8..4df18d34 100644 --- a/services/telegram/telegram.go +++ b/services/telegram/telegram.go @@ -8,15 +8,15 @@ import ( ) type Telegram struct { - chat int64 - errLog *zap.SugaredLogger - bot *tb.Bot + chat int64 + log *zap.SugaredLogger + bot *tb.Bot } func NewTelegram(c *core.Telegram) (*Telegram, error) { n := &Telegram{ - chat: c.ChatID, - errLog: log.S().Named("telegram"), + chat: c.ChatID, + log: log.S().Named("telegram"), } bot, err := tb.NewBot(tb.Settings{Token: c.Token}) if err != nil { @@ -27,26 +27,13 @@ func NewTelegram(c *core.Telegram) (*Telegram, error) { return n, nil } -func (n *Telegram) Info(msg string) { +func (n *Telegram) Notify(msg string) { _, err := n.bot.Send(&tb.Chat{ID: n.chat}, msg, &tb.SendOptions{ DisableWebPagePreview: true, ParseMode: tb.ModeDefault, }) if err != nil { - n.errLog.Error(err) - } -} - -func (n *Telegram) Error(err error) { - n.errLog.Error(err) - - _, botErr := n.bot.Send(&tb.Chat{ID: n.chat}, "An error occurred:\n"+err.Error(), &tb.SendOptions{ - DisableWebPagePreview: true, - ParseMode: tb.ModeDefault, - }) - - if botErr != nil { - n.errLog.Error(err) + n.log.Error(err) } }