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.
This commit is contained in:
@@ -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)
|
Find(&devices).Error; err != nil {
|
||||||
|
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)
|
||||||
|
|||||||
Reference in New Issue
Block a user