Skip to content

Commit

Permalink
add a setting to enable/disable sct temperature history retrieval
Browse files Browse the repository at this point in the history
  • Loading branch information
mcarbonne committed Jul 19, 2024
1 parent d0f6acf commit 3aa0233
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 23 deletions.
2 changes: 1 addition & 1 deletion webapp/backend/pkg/database/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type DeviceRepo interface {
SaveSmartAttributes(ctx context.Context, wwn string, collectorSmartData collector.SmartInfo) (measurements.Smart, error)
GetSmartAttributeHistory(ctx context.Context, wwn string, durationKey string, selectEntries int, selectEntriesOffset int, attributes []string) ([]measurements.Smart, error)

SaveSmartTemperature(ctx context.Context, wwn string, deviceProtocol string, collectorSmartData collector.SmartInfo) error
SaveSmartTemperature(ctx context.Context, wwn string, deviceProtocol string, collectorSmartData collector.SmartInfo, retrieveSCTTemperatureHistory bool) error

GetSummary(ctx context.Context) (map[string]*models.DeviceSummary, error)
GetSmartTemperatureHistory(ctx context.Context, durationKey string) (map[string][]measurements.SmartTemperature, error)
Expand Down
8 changes: 4 additions & 4 deletions webapp/backend/pkg/database/mock/mock_database.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 17 additions & 2 deletions webapp/backend/pkg/database/scrutiny_repository_migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,21 @@ func (sr *scrutinyRepository) Migrate(ctx context.Context) error {
return tx.Create(&defaultSettings).Error
},
},
{
ID: "m20240719190500", // add retrieve_sct_history setting.
Migrate: func(tx *gorm.DB) error {
//add retrieve_sct_history setting default.
var defaultSettings = []m20220716214900.Setting{
{
SettingKeyName: "collector.retrieve_sct_temperature_history",
SettingKeyDescription: "Whether to retrieve SCT Temperature history (true | false)",
SettingDataType: "bool",
SettingValueBool: true,
},
}
return tx.Create(&defaultSettings).Error
},
},
})

if err := m.Migrate(); err != nil {
Expand Down Expand Up @@ -421,8 +436,8 @@ func (sr *scrutinyRepository) Migrate(ctx context.Context) error {

// helpers

//When adding data to influxdb, an error may be returned if the data point is outside the range of the retention policy.
//This function will ignore retention policy errors, and allow the migration to continue.
// When adding data to influxdb, an error may be returned if the data point is outside the range of the retention policy.
// This function will ignore retention policy errors, and allow the migration to continue.
func ignorePastRetentionPolicyError(err error) error {
var influxDbWriteError *http.Error
if errors.As(err, &influxDbWriteError) {
Expand Down
58 changes: 43 additions & 15 deletions webapp/backend/pkg/database/scrutiny_repository_temperature.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,52 @@ import (
influxdb2 "github.com/influxdata/influxdb-client-go/v2"
)

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Temperature Data
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
func (sr *scrutinyRepository) SaveSmartTemperature(ctx context.Context, wwn string, deviceProtocol string, collectorSmartData collector.SmartInfo) error {
// collectorSmartData.AtaSctTemperatureHistory isn't reliable, only use current temperature
// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
func (sr *scrutinyRepository) SaveSmartTemperature(ctx context.Context, wwn string, deviceProtocol string, collectorSmartData collector.SmartInfo, retrieveSCTTemperatureHistory bool) error {
if len(collectorSmartData.AtaSctTemperatureHistory.Table) > 0 && retrieveSCTTemperatureHistory {

for ndx, temp := range collectorSmartData.AtaSctTemperatureHistory.Table {
//temp value may be null, we must skip/ignore them. See #393
if temp == 0 {
continue
}

smartTemp := measurements.SmartTemperature{
Date: time.Unix(collectorSmartData.LocalTime.TimeT, 0),
Temp: collectorSmartData.Temperature.Current,
}
minutesOffset := collectorSmartData.AtaSctTemperatureHistory.LoggingIntervalMinutes * int64(ndx) * 60
smartTemp := measurements.SmartTemperature{
Date: time.Unix(collectorSmartData.LocalTime.TimeT-minutesOffset, 0),
Temp: temp,
}

tags, fields := smartTemp.Flatten()
tags["device_wwn"] = wwn
p := influxdb2.NewPoint("temp",
tags,
fields,
smartTemp.Date)
err := sr.influxWriteApi.WritePoint(ctx, p)
if err != nil {
return err
}
}
// also add the current temperature.
} else {

tags, fields := smartTemp.Flatten()
tags["device_wwn"] = wwn
p := influxdb2.NewPoint("temp",
tags,
fields,
smartTemp.Date)
return sr.influxWriteApi.WritePoint(ctx, p)
smartTemp := measurements.SmartTemperature{
Date: time.Unix(collectorSmartData.LocalTime.TimeT, 0),
Temp: collectorSmartData.Temperature.Current,
}

tags, fields := smartTemp.Flatten()
tags["device_wwn"] = wwn
p := influxdb2.NewPoint("temp",
tags,
fields,
smartTemp.Date)
return sr.influxWriteApi.WritePoint(ctx, p)
}
return nil
}

func (sr *scrutinyRepository) GetSmartTemperatureHistory(ctx context.Context, durationKey string) (map[string][]measurements.SmartTemperature, error) {
Expand Down
4 changes: 4 additions & 0 deletions webapp/backend/pkg/models/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ type Settings struct {
FileSizeSIUnits bool `json:"file_size_si_units" mapstructure:"file_size_si_units"`
LineStroke string `json:"line_stroke" mapstructure:"line_stroke"`

Collector struct {
RetrieveSCTHistory bool `json:"retrieve_sct_temperature_history" mapstructure:"retrieve_sct_temperature_history"`
} `json:"collector" mapstructure:"collector"`

Metrics struct {
NotifyLevel int `json:"notify_level" mapstructure:"notify_level"`
StatusFilterAttributes int `json:"status_filter_attributes" mapstructure:"status_filter_attributes"`
Expand Down
2 changes: 1 addition & 1 deletion webapp/backend/pkg/web/handler/upload_device_metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func UploadDeviceMetrics(c *gin.Context) {
}

// save smart temperature data (ignore failures)
err = deviceRepo.SaveSmartTemperature(c, c.Param("wwn"), updatedDevice.DeviceProtocol, collectorSmartData)
err = deviceRepo.SaveSmartTemperature(c, c.Param("wwn"), updatedDevice.DeviceProtocol, collectorSmartData, appConfig.GetBool(fmt.Sprintf("%s.collector.retrieve_sct_temperature_history", config.DB_USER_SETTINGS_SUBKEY)))
if err != nil {
logger.Errorln("An error occurred while saving smartctl temp data", err)
c.JSON(http.StatusInternalServerError, gin.H{"success": false})
Expand Down
3 changes: 3 additions & 0 deletions webapp/backend/pkg/web/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ func (suite *ServerTestSuite) TestUploadDeviceMetricsRoute() {
fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes()
fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes()
fakeConfig.EXPECT().GetBool("user.metrics.repeat_notifications").Return(true).AnyTimes()
fakeConfig.EXPECT().GetBool("user.collector.retrieve_sct_temperature_history").Return(true).AnyTimes()
fakeConfig.EXPECT().GetBool("web.influxdb.tls.insecure_skip_verify").Return(false).AnyTimes()
fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes()
if _, isGithubActions := os.LookupEnv("GITHUB_ACTIONS"); isGithubActions {
Expand Down Expand Up @@ -250,6 +251,7 @@ func (suite *ServerTestSuite) TestPopulateMultiple() {
fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes()
fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes()
fakeConfig.EXPECT().GetBool("user.metrics.repeat_notifications").Return(true).AnyTimes()
fakeConfig.EXPECT().GetBool("user.collector.retrieve_sct_temperature_history").Return(true).AnyTimes()
fakeConfig.EXPECT().GetBool("web.influxdb.tls.insecure_skip_verify").Return(false).AnyTimes()
fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes()
if _, isGithubActions := os.LookupEnv("GITHUB_ACTIONS"); isGithubActions {
Expand Down Expand Up @@ -533,6 +535,7 @@ func (suite *ServerTestSuite) TestGetDevicesSummaryRoute_Nvme() {
fakeConfig.EXPECT().GetString("web.influxdb.org").Return("scrutiny").AnyTimes()
fakeConfig.EXPECT().GetString("web.influxdb.bucket").Return("metrics").AnyTimes()
fakeConfig.EXPECT().GetBool("user.metrics.repeat_notifications").Return(true).AnyTimes()
fakeConfig.EXPECT().GetBool("user.collector.retrieve_sct_temperature_history").Return(true).AnyTimes()
fakeConfig.EXPECT().GetBool("web.influxdb.tls.insecure_skip_verify").Return(false).AnyTimes()
fakeConfig.EXPECT().GetBool("web.influxdb.retention_policy").Return(false).AnyTimes()
fakeConfig.EXPECT().GetStringSlice("notify.urls").AnyTimes().Return([]string{})
Expand Down
8 changes: 8 additions & 0 deletions webapp/frontend/src/app/core/config/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ export interface AppConfig {
line_stroke?: LineStroke;

// Settings from Scrutiny API

collector?: {
retrieve_sct_temperature_history?: boolean
}

metrics?: {
notify_level?: MetricsNotifyLevel
Expand Down Expand Up @@ -79,6 +83,10 @@ export const appConfig: AppConfig = {
file_size_si_units: false,

line_stroke: 'smooth',

collector: {
retrieve_sct_temperature_history : true,
},

metrics: {
notify_level: MetricsNotifyLevel.Fail,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,16 @@ <h2 mat-dialog-title>Scrutiny Settings</h2>
</mat-select>
</mat-form-field>
</div>

<div class="flex flex-col mt-5 gt-md:flex-row">
<mat-form-field class="flex-auto gt-xs:pr-3 gt-md:pr-3">
<mat-label>Retrieve SCT Temperature History</mat-label>
<mat-select [(ngModel)]=retrieveSCTTemperatureHistory>
<mat-option [value]=true>Enabled</mat-option>
<mat-option [value]=false>Disabled</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>

</mat-dialog-content>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export class DashboardSettingsComponent implements OnInit {
fileSizeSIUnits: boolean;
lineStroke: string;
theme: string;
retrieveSCTTemperatureHistory: boolean;
statusThreshold: number;
statusFilterAttributes: number;
repeatNotifications: boolean;
Expand Down Expand Up @@ -54,6 +55,8 @@ export class DashboardSettingsComponent implements OnInit {
this.lineStroke = config.line_stroke;
this.theme = config.theme;

this.retrieveSCTTemperatureHistory = config.collector.retrieve_sct_temperature_history;

this.statusFilterAttributes = config.metrics.status_filter_attributes;
this.statusThreshold = config.metrics.status_threshold;
this.repeatNotifications = config.metrics.repeat_notifications;
Expand All @@ -70,6 +73,9 @@ export class DashboardSettingsComponent implements OnInit {
file_size_si_units: this.fileSizeSIUnits,
line_stroke: this.lineStroke as LineStroke,
theme: this.theme as Theme,
collector: {
retrieve_sct_temperature_history: this.retrieveSCTTemperatureHistory
},
metrics: {
status_filter_attributes: this.statusFilterAttributes as MetricsStatusFilterAttributes,
status_threshold: this.statusThreshold as MetricsStatusThreshold,
Expand Down

0 comments on commit 3aa0233

Please sign in to comment.