diff --git a/cmd/cmd_root.go b/cmd/cmd_root.go index 367b214..97f379a 100644 --- a/cmd/cmd_root.go +++ b/cmd/cmd_root.go @@ -101,9 +101,9 @@ var configHelpCmd = &cobra.Command{ } var rootCmd = &cobra.Command{ - Use: "osem_notify", - Short: "Root command displaying help", - Long: "Run healthchecks and send notifications for boxes on opensensemap.org", + Use: "osem_notify", + Short: "Root command displaying help", + Long: "Run healthchecks and send notifications for boxes on opensensemap.org", Version: "1.3.0", PersistentPreRunE: func(cmd *cobra.Command, args []string) error { // set up logger diff --git a/cmd/shared.go b/cmd/shared.go index b1a580b..1caaead 100644 --- a/cmd/shared.go +++ b/cmd/shared.go @@ -93,14 +93,14 @@ func checkAndNotify(boxIds []string) error { } var ( // values are set during cli flag parsing of checkAllCmd & watchAllCmd - date string - exposure string - grouptag string - model string + date string + exposure string + grouptag string + model string phenomenon string ) -func parseBoxFilters () core.BoxFilters { +func parseBoxFilters() core.BoxFilters { filters := core.BoxFilters{} if date != "" { filters.Date = date // TODO: parse date & format as ISO date? diff --git a/core/checkrunner.go b/core/checkrunner.go index 5fd2e6a..82e2158 100644 --- a/core/checkrunner.go +++ b/core/checkrunner.go @@ -86,7 +86,7 @@ func (results BoxCheckResults) Log() { } func CheckBoxes(boxLocalConfs map[string]*NotifyConfig, osem *OsemClient) (BoxCheckResults, error) { - log.Debug("Checking notifications for ", len(boxLocalConfs), " box(es)") + log.Info("Checking notifications for ", len(boxLocalConfs), " box(es)") results := BoxCheckResults{} errs := []string{} @@ -94,7 +94,7 @@ func CheckBoxes(boxLocalConfs map[string]*NotifyConfig, osem *OsemClient) (BoxCh // @TODO: check boxes in parallel, capped at 5 at once. and/or rate limit? for boxId, localConf := range boxLocalConfs { boxLogger := log.WithField("boxId", boxId) - boxLogger.Info("checking box for events") + boxLogger.Debug("checking box for events") box, res, err := checkBox(boxId, localConf, osem) if err != nil { diff --git a/core/healthcheck_measurement_faulty.go b/core/healthcheck_measurement_faulty.go index d6005ab..364d6d2 100644 --- a/core/healthcheck_measurement_faulty.go +++ b/core/healthcheck_measurement_faulty.go @@ -2,7 +2,8 @@ package core import ( "fmt" - "strconv" + + "github.com/noerw/osem_notify/utils" ) var checkMeasurementFaulty = checkType{ @@ -20,7 +21,7 @@ var checkMeasurementFaulty = checkType{ Status: CheckOk, } - val, err := strconv.ParseFloat(s.LastMeasurement.Value, 64) + val, err := utils.ParseFloat(s.LastMeasurement.Value) if err != nil { return result, err } @@ -42,8 +43,10 @@ type faultyValue struct { } var faultyVals = map[faultyValue]bool{ + // @TODO: add UV & light sensor: check for 0 if not sunset based on boxlocation + // @TODO: add BME280 and other sensors.. faultyValue{sensor: "BMP280", val: 0.0}: true, - faultyValue{sensor: "HDC1008", val: 0.0}: true, + faultyValue{sensor: "HDC1008", val: 0.0}: true, // @FIXME: check should be on luftfeuchte only! faultyValue{sensor: "HDC1008", val: -40}: true, - faultyValue{sensor: "SDS 011", val: 0.0}: true, + faultyValue{sensor: "SDS 011", val: 0.0}: true, // @FIXME: 0.0 seems to be a correct value, need to check over longer periods } diff --git a/core/healthcheck_measurement_minmax.go b/core/healthcheck_measurement_minmax.go index fa71b59..49b97b4 100644 --- a/core/healthcheck_measurement_minmax.go +++ b/core/healthcheck_measurement_minmax.go @@ -2,7 +2,8 @@ package core import ( "fmt" - "strconv" + + "github.com/noerw/osem_notify/utils" ) const ( @@ -36,12 +37,12 @@ func validateMeasurementMinMax(e NotifyEvent, s Sensor, b Box) (CheckResult, err Status: CheckOk, } - thresh, err := strconv.ParseFloat(e.Threshold, 64) + thresh, err := utils.ParseFloat(e.Threshold) if err != nil { return result, err } - val, err := strconv.ParseFloat(s.LastMeasurement.Value, 64) + val, err := utils.ParseFloat(s.LastMeasurement.Value) if err != nil { return result, err } diff --git a/core/healthchecks.go b/core/healthchecks.go index 26c1631..a6754b2 100644 --- a/core/healthchecks.go +++ b/core/healthchecks.go @@ -84,7 +84,7 @@ func (box Box) RunChecks() ([]CheckResult, error) { result, err := checker.checkFunc(event, s, box) if err != nil { - boxLogger.Errorf("error checking event %s", event.Type) + boxLogger.Errorf("error checking event %s: %v", event.Type, err) } results = append(results, result) diff --git a/core/notifier_email.go b/core/notifier_email.go index 970ccfb..cce1f5a 100644 --- a/core/notifier_email.go +++ b/core/notifier_email.go @@ -65,11 +65,12 @@ func (n EmailNotifier) Submit(notification Notification) error { from := viper.GetString("email.from") body := fmt.Sprintf( - "From: openSenseMap Notifier <%s>\nDate: %s\nSubject: %s\nContent-Type: text/plain; charset=\"utf-8\"\n\n%s", + "From: openSenseMap Notifier <%s>\nDate: %s\nSubject: %s\nContent-Type: text/plain; charset=\"utf-8\"\n\n%s%s", from, time.Now().Format(time.RFC1123Z), notification.Subject, - notification.Body) + notification.Body, + "\n\n--\nSent automatically by osem_notify (https://github.com/noerw/osem_notify)") // Connect to the server, authenticate, set the sender and recipient, // and send the email all in one step. diff --git a/core/notifier_slack.go b/core/notifier_slack.go index 2524737..c13aada 100644 --- a/core/notifier_slack.go +++ b/core/notifier_slack.go @@ -11,8 +11,8 @@ import ( var slackClient = sling.New().Client(&http.Client{}) -var notificationColors = map[string]string { - CheckOk: "#00ff00", +var notificationColors = map[string]string{ + CheckOk: "#00ff00", CheckErr: "#ff0000", } @@ -47,9 +47,9 @@ func (n SlackNotifier) New(config TransportConfig) (AbstractNotifier, error) { func (n SlackNotifier) Submit(notification Notification) error { message := &SlackMessage{ - Username: "osem_notify box healthcheck", + Username: "osem_notify box healthcheck", Text: notification.Subject, - Attachments: []SlackAttachment{ { notification.Body, notificationColors[notification.Status] } }, + Attachments: []SlackAttachment{{notification.Body, notificationColors[notification.Status]}}, } req, err := slackClient.Post(n.webhook).BodyJSON(message).Request() diff --git a/core/notifiers.go b/core/notifiers.go index b32881a..50264d8 100644 --- a/core/notifiers.go +++ b/core/notifiers.go @@ -139,7 +139,7 @@ func ComposeNotification(box *Box, checks []CheckResult) Notification { resolved string resolvedList string errList string - status string + status string ) if len(resolvedTexts) != 0 { resolvedList = fmt.Sprintf("Resolved issue(s):\n\n%s\n\n", strings.Join(resolvedTexts, "\n")) @@ -153,9 +153,9 @@ func ComposeNotification(box *Box, checks []CheckResult) Notification { } return Notification{ - Status: status, + Status: status, Subject: fmt.Sprintf("Issues %swith your box \"%s\" on opensensemap.org!", resolved, box.Name), - Body: fmt.Sprintf("A check at %s identified the following updates for your box \"%s\":\n\n%s%sYou may visit https://opensensemap.org/explore/%s for more details.\n\n--\nSent automatically by osem_notify (https://github.com/noerw/osem_notify)", + Body: fmt.Sprintf("A check at %s identified the following updates for your box \"%s\":\n\n%s%sYou may visit https://opensensemap.org/explore/%s for more details.", time.Now().Round(time.Minute), box.Name, errList, resolvedList, box.Id), } } diff --git a/core/osem_api.go b/core/osem_api.go index eebc1c0..9d480aa 100644 --- a/core/osem_api.go +++ b/core/osem_api.go @@ -9,7 +9,7 @@ import ( ) type OsemError struct { - Code int `json:"code"` + Code string `json:"code"` Message string `json:"message"` } diff --git a/utils/config.go b/utils/config.go index a0a68a5..e4e48ca 100644 --- a/utils/config.go +++ b/utils/config.go @@ -3,6 +3,8 @@ package utils import ( "os" "path" + "strconv" + "strings" log "github.com/sirupsen/logrus" "github.com/spf13/viper" @@ -70,3 +72,7 @@ func PrintConfig() { func printKV(key, val interface{}) { log.Debugf("%20s: %v", key, val) } + +func ParseFloat(val string) (float64, error) { + return strconv.ParseFloat(strings.TrimSpace(val), 64) +}