Backend: Log errors in database

Signed-off-by: Michael Mayer <michael@liquidbytes.net>
This commit is contained in:
Michael Mayer 2020-05-19 13:48:05 +02:00
parent a785a9d708
commit 4300d45482
7 changed files with 78 additions and 16 deletions

View file

@ -59,12 +59,14 @@ func (c *Config) CloseDb() error {
func (c *Config) InitDb() { func (c *Config) InitDb() {
entity.SetDbProvider(c) entity.SetDbProvider(c)
entity.MigrateDb() entity.MigrateDb()
go entity.SaveErrorMessages()
} }
// InitTestDb drops all tables in the currently configured database and re-creates them. // InitTestDb drops all tables in the currently configured database and re-creates them.
func (c *Config) InitTestDb() { func (c *Config) InitTestDb() {
entity.SetDbProvider(c) entity.SetDbProvider(c)
entity.ResetTestFixtures() entity.ResetTestFixtures()
go entity.SaveErrorMessages()
} }
// connectToDatabase establishes a database connection. // connectToDatabase establishes a database connection.

View file

@ -29,6 +29,7 @@ type Types map[string]interface{}
// List of database entities and their table names. // List of database entities and their table names.
var Entities = Types{ var Entities = Types{
"errors": &Error{},
"accounts": &Account{}, "accounts": &Account{},
"files": &File{}, "files": &File{},
"files_share": &FileShare{}, "files_share": &FileShare{},

51
internal/entity/error.go Normal file
View file

@ -0,0 +1,51 @@
package entity
import (
"time"
"github.com/photoprism/photoprism/internal/event"
"github.com/sirupsen/logrus"
)
// Error represents an error message log.
type Error struct {
ID uint `gorm:"primary_key"`
ErrorTime time.Time `sql:"index"`
ErrorLevel string `gorm:"type:varbinary(32)"`
ErrorMessage string `gorm:"type:varbinary(2048)"`
}
// SaveErrorMessages subscribes to error logs and stored them in the errors table.
func SaveErrorMessages() {
s := event.Subscribe("log.*")
defer func() {
event.Unsubscribe(s)
}()
for msg := range s.Receiver {
level, ok := msg.Fields["level"]
if !ok {
continue
}
logLevel, err := logrus.ParseLevel(level.(string))
if err != nil || logLevel >= logrus.InfoLevel {
continue
}
newError := Error{ErrorLevel: logLevel.String()}
if val, ok := msg.Fields["msg"]; ok {
newError.ErrorMessage = val.(string)
}
if val, ok := msg.Fields["time"]; ok {
newError.ErrorTime = val.(time.Time)
}
Db().Create(&newError)
}
}

View file

@ -106,7 +106,7 @@ func SavePhotoForm(model Photo, form form.Photo, geoApi string) error {
} }
if err := model.IndexKeywords(); err != nil { if err := model.IndexKeywords(); err != nil {
log.Warnf("%s (%s)", err.Error(), model.PhotoUUID) log.Error(err)
} }
edited := time.Now().UTC() edited := time.Now().UTC()
@ -219,7 +219,7 @@ func (m *Photo) BeforeSave(scope *gorm.Scope) error {
// IndexKeywords adds given keywords to the photo entry // IndexKeywords adds given keywords to the photo entry
func (m *Photo) IndexKeywords() error { func (m *Photo) IndexKeywords() error {
if !m.DetailsLoaded() { if !m.DetailsLoaded() {
return fmt.Errorf("photo: can't index keywords, description not loaded (%s)", m.PhotoUUID) return fmt.Errorf("photo: can't index keywords, details not loaded (%s)", m.PhotoUUID)
} }
db := Db() db := Db()

View file

@ -117,7 +117,7 @@ var PhotoFixtures = PhotoMap{
PhotoCountry: "zz", PhotoCountry: "zz",
PhotoYear: 2790, PhotoYear: 2790,
PhotoMonth: 2, PhotoMonth: 2,
Details: Details{}, Details: DetailsFixtures.Get("lake", 1000001),
DescriptionSrc: "", DescriptionSrc: "",
Camera: CameraFixtures.Pointer("canon-eos-6d"), Camera: CameraFixtures.Pointer("canon-eos-6d"),
Lens: LensFixtures.Pointer("lens-f-380"), Lens: LensFixtures.Pointer("lens-f-380"),
@ -166,7 +166,7 @@ var PhotoFixtures = PhotoMap{
PhotoCountry: "zz", PhotoCountry: "zz",
PhotoYear: 1990, PhotoYear: 1990,
PhotoMonth: 3, PhotoMonth: 3,
Details: Details{}, Details: DetailsFixtures.Get("lake", 1000002),
DescriptionSrc: "", DescriptionSrc: "",
Camera: nil, Camera: nil,
Lens: LensFixtures.Pointer("lens-f-380"), Lens: LensFixtures.Pointer("lens-f-380"),
@ -215,7 +215,7 @@ var PhotoFixtures = PhotoMap{
PhotoCountry: "zz", PhotoCountry: "zz",
PhotoYear: 1990, PhotoYear: 1990,
PhotoMonth: 4, PhotoMonth: 4,
Details: Details{}, Details: DetailsFixtures.Get("lake", 1000003),
DescriptionSrc: "", DescriptionSrc: "",
Camera: nil, Camera: nil,
Lens: nil, Lens: nil,
@ -267,7 +267,7 @@ var PhotoFixtures = PhotoMap{
PhotoCountry: "zz", PhotoCountry: "zz",
PhotoYear: 2014, PhotoYear: 2014,
PhotoMonth: 7, PhotoMonth: 7,
Details: Details{}, Details: DetailsFixtures.Get("lake", 1000004),
DescriptionSrc: "", DescriptionSrc: "",
Camera: CameraFixtures.Pointer("canon-eos-6d"), Camera: CameraFixtures.Pointer("canon-eos-6d"),
Lens: LensFixtures.Pointer("lens-f-380"), Lens: LensFixtures.Pointer("lens-f-380"),
@ -320,7 +320,7 @@ var PhotoFixtures = PhotoMap{
PhotoCountry: "zz", PhotoCountry: "zz",
PhotoYear: 2014, PhotoYear: 2014,
PhotoMonth: 7, PhotoMonth: 7,
Details: Details{}, Details: DetailsFixtures.Get("lake", 1000005),
DescriptionSrc: "", DescriptionSrc: "",
Camera: CameraFixtures.Pointer("canon-eos-6d"), Camera: CameraFixtures.Pointer("canon-eos-6d"),
Lens: LensFixtures.Pointer("lens-f-380"), Lens: LensFixtures.Pointer("lens-f-380"),
@ -369,7 +369,7 @@ var PhotoFixtures = PhotoMap{
PhotoCountry: "zz", PhotoCountry: "zz",
PhotoYear: 2014, PhotoYear: 2014,
PhotoMonth: 7, PhotoMonth: 7,
Details: Details{}, Details: DetailsFixtures.Get("lake", 1000006),
DescriptionSrc: "", DescriptionSrc: "",
Camera: nil, Camera: nil,
Lens: nil, Lens: nil,
@ -418,7 +418,7 @@ var PhotoFixtures = PhotoMap{
PhotoCountry: "zz", PhotoCountry: "zz",
PhotoYear: 2014, PhotoYear: 2014,
PhotoMonth: 7, PhotoMonth: 7,
Details: Details{}, Details: DetailsFixtures.Get("lake", 1000007),
DescriptionSrc: "", DescriptionSrc: "",
Camera: nil, Camera: nil,
Lens: nil, Lens: nil,
@ -467,7 +467,7 @@ var PhotoFixtures = PhotoMap{
PhotoCountry: "zz", PhotoCountry: "zz",
PhotoYear: 2014, PhotoYear: 2014,
PhotoMonth: 7, PhotoMonth: 7,
Details: Details{}, Details: DetailsFixtures.Get("lake", 1000008),
DescriptionSrc: "", DescriptionSrc: "",
Camera: nil, Camera: nil,
Lens: nil, Lens: nil,
@ -516,7 +516,7 @@ var PhotoFixtures = PhotoMap{
PhotoCountry: "zz", PhotoCountry: "zz",
PhotoYear: 2014, PhotoYear: 2014,
PhotoMonth: 7, PhotoMonth: 7,
Details: Details{}, Details: DetailsFixtures.Get("lake", 1000009),
DescriptionSrc: "", DescriptionSrc: "",
Camera: nil, Camera: nil,
Lens: nil, Lens: nil,
@ -565,7 +565,7 @@ var PhotoFixtures = PhotoMap{
PhotoCountry: "zz", PhotoCountry: "zz",
PhotoYear: 2014, PhotoYear: 2014,
PhotoMonth: 7, PhotoMonth: 7,
Details: Details{}, Details: DetailsFixtures.Get("lake", 10000010),
DescriptionSrc: "", DescriptionSrc: "",
Camera: nil, Camera: nil,
Lens: nil, Lens: nil,
@ -614,7 +614,7 @@ var PhotoFixtures = PhotoMap{
PhotoCountry: "zz", PhotoCountry: "zz",
PhotoYear: 2014, PhotoYear: 2014,
PhotoMonth: 7, PhotoMonth: 7,
Details: Details{}, Details: DetailsFixtures.Get("lake", 10000011),
DescriptionSrc: "", DescriptionSrc: "",
Camera: nil, Camera: nil,
Lens: nil, Lens: nil,

View file

@ -97,7 +97,15 @@ func TestPhoto_Save(t *testing.T) {
PlaceID: "765", PlaceID: "765",
PhotoCountry: "de", PhotoCountry: "de",
Keywords: []Keyword{}, Keywords: []Keyword{},
Details: Details{}, Details: Details{
PhotoID: 11111,
Keywords: "test cat dog",
Subject: "animals",
Artist: "Bender",
Notes: "notes",
Copyright: "copy",
License: "",
},
} }
err := photo.Save() err := photo.Save()
@ -276,7 +284,7 @@ func TestPhoto_DetailsLoaded(t *testing.T) {
assert.True(t, m.DetailsLoaded()) assert.True(t, m.DetailsLoaded())
}) })
t.Run("false", func(t *testing.T) { t.Run("false", func(t *testing.T) {
m := PhotoFixtures.Get("Photo05") m := PhotoFixtures.Get("Photo12")
assert.False(t, m.DetailsLoaded()) assert.False(t, m.DetailsLoaded())
}) })
} }

View file

@ -431,7 +431,7 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) (
} }
if err := photo.IndexKeywords(); err != nil { if err := photo.IndexKeywords(); err != nil {
log.Warnf("%s (%s)", err.Error(), photo.PhotoUUID) log.Error(err)
} }
} else { } else {
if photo.PhotoQuality >= 0 { if photo.PhotoQuality >= 0 {