adding error handling for all DB calls. Returning StatusInternalServerError whenever an error occurs. Adding additional logging to server handlers.

Make sure we "return" after a c.JSON call.
pull/51/head
Jason Kulatunga 4 years ago
parent 531fea76b2
commit 6a20228262

@ -5,25 +5,40 @@ import (
dbModels "github.com/analogj/scrutiny/webapp/backend/pkg/models/db" dbModels "github.com/analogj/scrutiny/webapp/backend/pkg/models/db"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/jinzhu/gorm" "github.com/jinzhu/gorm"
"github.com/sirupsen/logrus"
"net/http" "net/http"
) )
func GetDeviceDetails(c *gin.Context) { func GetDeviceDetails(c *gin.Context) {
db := c.MustGet("DB").(*gorm.DB) db := c.MustGet("DB").(*gorm.DB)
logger := c.MustGet("LOGGER").(logrus.FieldLogger)
device := dbModels.Device{} device := dbModels.Device{}
db.Debug(). if err := db.Preload("SmartResults", func(db *gorm.DB) *gorm.DB {
Preload("SmartResults", func(db *gorm.DB) *gorm.DB { return db.Order("smarts.created_at DESC").Limit(40)
return db.Order("smarts.created_at DESC").Limit(40) }).
}).
Preload("SmartResults.AtaAttributes"). Preload("SmartResults.AtaAttributes").
Preload("SmartResults.NvmeAttributes"). Preload("SmartResults.NvmeAttributes").
Preload("SmartResults.ScsiAttributes"). Preload("SmartResults.ScsiAttributes").
Where("wwn = ?", c.Param("wwn")). Where("wwn = ?", c.Param("wwn")).
First(&device) First(&device).Error; err != nil {
device.SquashHistory() logger.Errorln("An error occurred while retrieving device details", err)
device.ApplyMetadataRules() c.JSON(http.StatusInternalServerError, gin.H{"success": false})
return
}
if err := device.SquashHistory(); err != nil {
logger.Errorln("An error occurred while squashing device history", err)
c.JSON(http.StatusInternalServerError, gin.H{"success": false})
return
}
if err := device.ApplyMetadataRules(); err != nil {
logger.Errorln("An error occurred while applying scrutiny thresholds & rules", err)
c.JSON(http.StatusInternalServerError, gin.H{"success": false})
return
}
var deviceMetadata interface{} var deviceMetadata interface{}
if device.IsAta() { if device.IsAta() {

@ -4,20 +4,25 @@ import (
dbModels "github.com/analogj/scrutiny/webapp/backend/pkg/models/db" dbModels "github.com/analogj/scrutiny/webapp/backend/pkg/models/db"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/jinzhu/gorm" "github.com/jinzhu/gorm"
"github.com/sirupsen/logrus"
"net/http" "net/http"
) )
func GetDevicesSummary(c *gin.Context) { func GetDevicesSummary(c *gin.Context) {
db := c.MustGet("DB").(*gorm.DB) db := c.MustGet("DB").(*gorm.DB)
logger := c.MustGet("LOGGER").(logrus.FieldLogger)
devices := []dbModels.Device{} devices := []dbModels.Device{}
//We need the last x (for now all) Smart objects for each Device, so that we can graph Temperature //We need the last x (for now all) Smart objects for each Device, so that we can graph Temperature
//We also need the last //We also need the last
db.Debug(). if err := db.Preload("SmartResults", func(db *gorm.DB) *gorm.DB {
Preload("SmartResults", func(db *gorm.DB) *gorm.DB { return db.Order("smarts.created_at DESC") //OLD: .Limit(devicesCount)
return db.Order("smarts.created_at DESC") //OLD: .Limit(devicesCount) }).
}). Find(&devices).Error; err != nil {
Find(&devices) logger.Errorln("Could not get device summary from DB", err)
c.JSON(http.StatusInternalServerError, gin.H{"success": false})
return
}
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{
"success": true, "success": true,

@ -4,36 +4,43 @@ import (
dbModels "github.com/analogj/scrutiny/webapp/backend/pkg/models/db" dbModels "github.com/analogj/scrutiny/webapp/backend/pkg/models/db"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/jinzhu/gorm" "github.com/jinzhu/gorm"
log "github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"net/http" "net/http"
) )
// filter devices that are detected by various collectors. // filter devices that are detected by various collectors.
func RegisterDevices(c *gin.Context) { func RegisterDevices(c *gin.Context) {
db := c.MustGet("DB").(*gorm.DB) db := c.MustGet("DB").(*gorm.DB)
logger := c.MustGet("LOGGER").(logrus.FieldLogger)
var collectorDeviceWrapper dbModels.DeviceWrapper var collectorDeviceWrapper dbModels.DeviceWrapper
err := c.BindJSON(&collectorDeviceWrapper) err := c.BindJSON(&collectorDeviceWrapper)
if err != nil { if err != nil {
log.Error("Cannot parse detected devices") logger.Errorln("Cannot parse detected devices", err)
c.JSON(http.StatusOK, gin.H{"success": false}) c.JSON(http.StatusInternalServerError, gin.H{"success": false})
return
} }
//TODO: filter devices here (remove excludes, force includes) //TODO: filter devices here (remove excludes, force includes)
errs := []error{}
for _, dev := range collectorDeviceWrapper.Data { for _, dev := range collectorDeviceWrapper.Data {
//insert devices into DB if not already there. //insert devices into DB if not already there.
db.Where(dbModels.Device{WWN: dev.WWN}).FirstOrCreate(&dev) if err := db.Where(dbModels.Device{WWN: dev.WWN}).FirstOrCreate(&dev).Error; err != nil {
errs = append(errs, err)
}
} }
if err != nil { if len(errs) > 0 {
c.JSON(http.StatusOK, gin.H{ logger.Errorln("An error occurred while registering devices", errs)
c.JSON(http.StatusInternalServerError, gin.H{
"success": false, "success": false,
}) })
return
} else { } else {
c.JSON(http.StatusOK, dbModels.DeviceWrapper{ c.JSON(http.StatusOK, dbModels.DeviceWrapper{
Success: true, Success: true,
Data: collectorDeviceWrapper.Data, Data: collectorDeviceWrapper.Data,
}) })
return
} }
} }

@ -6,6 +6,7 @@ import (
dbModels "github.com/analogj/scrutiny/webapp/backend/pkg/models/db" dbModels "github.com/analogj/scrutiny/webapp/backend/pkg/models/db"
"github.com/analogj/scrutiny/webapp/backend/pkg/notify" "github.com/analogj/scrutiny/webapp/backend/pkg/notify"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
"net/http" "net/http"
"os" "os"
) )
@ -13,6 +14,7 @@ import (
// Send test notification // Send test notification
func SendTestNotification(c *gin.Context) { func SendTestNotification(c *gin.Context) {
appConfig := c.MustGet("CONFIG").(config.Interface) appConfig := c.MustGet("CONFIG").(config.Interface)
logger := c.MustGet("LOGGER").(logrus.FieldLogger)
testNotify := notify.Notify{ testNotify := notify.Notify{
Config: appConfig, Config: appConfig,
@ -28,7 +30,8 @@ func SendTestNotification(c *gin.Context) {
} }
err := testNotify.Send() err := testNotify.Send()
if err != nil { if err != nil {
c.JSON(http.StatusOK, gin.H{ logger.Errorln("An error occurred while sending test notification", err)
c.JSON(http.StatusInternalServerError, gin.H{
"success": false, "success": false,
}) })
} else { } else {

@ -5,36 +5,45 @@ import (
dbModels "github.com/analogj/scrutiny/webapp/backend/pkg/models/db" dbModels "github.com/analogj/scrutiny/webapp/backend/pkg/models/db"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/jinzhu/gorm" "github.com/jinzhu/gorm"
log "github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"net/http" "net/http"
) )
func UploadDeviceMetrics(c *gin.Context) { func UploadDeviceMetrics(c *gin.Context) {
db := c.MustGet("DB").(*gorm.DB) db := c.MustGet("DB").(*gorm.DB)
logger := c.MustGet("LOGGER").(logrus.FieldLogger)
var collectorSmartData collector.SmartInfo var collectorSmartData collector.SmartInfo
err := c.BindJSON(&collectorSmartData) err := c.BindJSON(&collectorSmartData)
if err != nil { if err != nil {
//TODO: cannot parse smart data logger.Errorln("Cannot parse SMART data", err)
log.Error("Cannot parse SMART data") c.JSON(http.StatusInternalServerError, gin.H{"success": false})
c.JSON(http.StatusOK, gin.H{"success": false}) return
} }
//update the device information if necessary //update the device information if necessary
var device dbModels.Device var device dbModels.Device
db.Where("wwn = ?", c.Param("wwn")).First(&device) db.Where("wwn = ?", c.Param("wwn")).First(&device)
device.UpdateFromCollectorSmartInfo(collectorSmartData) device.UpdateFromCollectorSmartInfo(collectorSmartData)
db.Model(&device).Updates(device) if err := db.Model(&device).Updates(device).Error; err != nil {
logger.Errorln("An error occurred while updating device data from smartctl metrics", err)
c.JSON(http.StatusInternalServerError, gin.H{"success": false})
return
}
// insert smart info // insert smart info
deviceSmartData := dbModels.Smart{} deviceSmartData := dbModels.Smart{}
err = deviceSmartData.FromCollectorSmartInfo(c.Param("wwn"), collectorSmartData) err = deviceSmartData.FromCollectorSmartInfo(c.Param("wwn"), collectorSmartData)
if err != nil { if err != nil {
c.JSON(http.StatusOK, gin.H{"success": false}) logger.Errorln("Could not process SMART metrics", err)
c.JSON(http.StatusInternalServerError, gin.H{"success": false})
return
}
if err := db.Create(&deviceSmartData).Error; err != nil {
logger.Errorln("An error occurred while saving smartctl metrics", err)
c.JSON(http.StatusInternalServerError, gin.H{"success": false})
return return
} }
db.Create(&deviceSmartData)
c.JSON(http.StatusOK, gin.H{"success": true}) c.JSON(http.StatusOK, gin.H{"success": true})
} }

@ -51,6 +51,7 @@ func LoggerMiddleware(logger logrus.FieldLogger) gin.HandlerFunc {
path := c.Request.URL.Path path := c.Request.URL.Path
blw := &responseBodyLogWriter{body: &bytes.Buffer{}, ResponseWriter: c.Writer} blw := &responseBodyLogWriter{body: &bytes.Buffer{}, ResponseWriter: c.Writer}
c.Writer = blw c.Writer = blw
c.Set("LOGGER", logger)
start := time.Now() start := time.Now()
c.Next() c.Next()
stop := time.Since(start) stop := time.Since(start)

Loading…
Cancel
Save