feat: send heartbeat ASAP on each new calendar day

This commit is contained in:
James Houlahan
2021-01-07 14:53:50 +01:00
parent 48808992ec
commit a9f44731dc
5 changed files with 56 additions and 20 deletions

View File

@ -19,6 +19,7 @@
package bridge package bridge
import ( import (
"fmt"
"strconv" "strconv"
"time" "time"
@ -72,7 +73,10 @@ func New(
} }
if s.GetBool(settings.FirstStartKey) { if s.GetBool(settings.FirstStartKey) {
b.SendMetric(metrics.New(metrics.Setup, metrics.FirstStart, metrics.Label(constants.Version))) if err := b.SendMetric(metrics.New(metrics.Setup, metrics.FirstStart, metrics.Label(constants.Version))); err != nil {
logrus.WithError(err).Error("Failed to send metric")
}
s.SetBool(settings.FirstStartKey, false) s.SetBool(settings.FirstStartKey, false)
} }
@ -83,19 +87,25 @@ func New(
// heartbeat sends a heartbeat signal once a day. // heartbeat sends a heartbeat signal once a day.
func (b *Bridge) heartbeat() { func (b *Bridge) heartbeat() {
ticker := time.NewTicker(1 * time.Minute) for range time.Tick(time.Minute) {
lastHeartbeatDay, err := strconv.ParseInt(b.settings.Get(settings.LastHeartbeatKey), 10, 64)
for range ticker.C {
next, err := strconv.ParseInt(b.settings.Get(settings.NextHeartbeatKey), 10, 64)
if err != nil { if err != nil {
continue continue
} }
nextTime := time.Unix(next, 0)
if time.Now().After(nextTime) { // If we're still on the same day, don't send a heartbeat.
b.SendMetric(metrics.New(metrics.Heartbeat, metrics.Daily, metrics.NoLabel)) if time.Now().YearDay() == int(lastHeartbeatDay) {
nextTime = nextTime.Add(24 * time.Hour) continue
b.settings.Set(settings.NextHeartbeatKey, strconv.FormatInt(nextTime.Unix(), 10))
} }
// We're on the next (or a different) day, so send a heartbeat.
if err := b.SendMetric(metrics.New(metrics.Heartbeat, metrics.Daily, metrics.NoLabel)); err != nil {
logrus.WithError(err).Error("Failed to send heartbeat")
continue
}
// Heartbeat was sent successfully so update the last heartbeat day.
b.settings.Set(settings.LastHeartbeatKey, fmt.Sprintf("%v", time.Now().YearDay()))
} }
} }

View File

@ -29,7 +29,7 @@ import (
const ( const (
FirstStartKey = "first_time_start" FirstStartKey = "first_time_start"
FirstStartGUIKey = "first_time_start_gui" FirstStartGUIKey = "first_time_start_gui"
NextHeartbeatKey = "next_heartbeat" LastHeartbeatKey = "last_heartbeat"
APIPortKey = "user_port_api" APIPortKey = "user_port_api"
IMAPPortKey = "user_port_imap" IMAPPortKey = "user_port_imap"
SMTPPortKey = "user_port_smtp" SMTPPortKey = "user_port_smtp"
@ -71,7 +71,7 @@ const (
func (s *Settings) setDefaultValues() { func (s *Settings) setDefaultValues() {
s.setDefault(FirstStartKey, "true") s.setDefault(FirstStartKey, "true")
s.setDefault(FirstStartGUIKey, "true") s.setDefault(FirstStartGUIKey, "true")
s.setDefault(NextHeartbeatKey, fmt.Sprintf("%v", time.Now().Unix())) s.setDefault(LastHeartbeatKey, fmt.Sprintf("%v", time.Now().YearDay()))
s.setDefault(AllowProxyKey, "true") s.setDefault(AllowProxyKey, "true")
s.setDefault(AutostartKey, "true") s.setDefault(AutostartKey, "true")
s.setDefault(AutoUpdateKey, "true") s.setDefault(AutoUpdateKey, "true")

View File

@ -21,6 +21,7 @@ import (
"strconv" "strconv"
"github.com/ProtonMail/proton-bridge/internal/metrics" "github.com/ProtonMail/proton-bridge/internal/metrics"
"github.com/sirupsen/logrus"
) )
type metricsManager struct { type metricsManager struct {
@ -44,21 +45,31 @@ func newExportMetricsManager(ie *ImportExport) *metricsManager {
func (m *metricsManager) Load(numberOfMailboxes int) { func (m *metricsManager) Load(numberOfMailboxes int) {
label := strconv.Itoa(numberOfMailboxes) label := strconv.Itoa(numberOfMailboxes)
m.ie.SendMetric(metrics.New(m.category, metrics.TransferLoad, metrics.Label(label))) if err := m.ie.SendMetric(metrics.New(m.category, metrics.TransferLoad, metrics.Label(label))); err != nil {
logrus.WithError(err).Error("Failed to send metric")
}
} }
func (m *metricsManager) Start() { func (m *metricsManager) Start() {
m.ie.SendMetric(metrics.New(m.category, metrics.TransferStart, metrics.NoLabel)) if err := m.ie.SendMetric(metrics.New(m.category, metrics.TransferStart, metrics.NoLabel)); err != nil {
logrus.WithError(err).Error("Failed to send metric")
}
} }
func (m *metricsManager) Complete() { func (m *metricsManager) Complete() {
m.ie.SendMetric(metrics.New(m.category, metrics.TransferComplete, metrics.NoLabel)) if err := m.ie.SendMetric(metrics.New(m.category, metrics.TransferComplete, metrics.NoLabel)); err != nil {
logrus.WithError(err).Error("Failed to send metric")
}
} }
func (m *metricsManager) Cancel() { func (m *metricsManager) Cancel() {
m.ie.SendMetric(metrics.New(m.category, metrics.TransferCancel, metrics.NoLabel)) if err := m.ie.SendMetric(metrics.New(m.category, metrics.TransferCancel, metrics.NoLabel)); err != nil {
logrus.WithError(err).Error("Failed to send metric")
}
} }
func (m *metricsManager) Fail() { func (m *metricsManager) Fail() {
m.ie.SendMetric(metrics.New(m.category, metrics.TransferFail, metrics.NoLabel)) if err := m.ie.SendMetric(metrics.New(m.category, metrics.TransferFail, metrics.NoLabel)); err != nil {
logrus.WithError(err).Error("Failed to send metric")
}
} }

View File

@ -324,7 +324,9 @@ func (u *Users) addNewUser(apiUser *pmapi.User, auth *pmapi.Auth, hashedPassphra
return errors.Wrap(err, "failed to initialise user") return errors.Wrap(err, "failed to initialise user")
} }
u.SendMetric(metrics.New(metrics.Setup, metrics.NewUser, metrics.NoLabel)) if err := u.SendMetric(metrics.New(metrics.Setup, metrics.NewUser, metrics.NoLabel)); err != nil {
log.WithError(err).Error("Failed to send metric")
}
return err return err
} }
@ -444,13 +446,13 @@ func (u *Users) DeleteUser(userID string, clearStore bool) error {
} }
// SendMetric sends a metric. We don't want to return any errors, only log them. // SendMetric sends a metric. We don't want to return any errors, only log them.
func (u *Users) SendMetric(m metrics.Metric) { func (u *Users) SendMetric(m metrics.Metric) error {
c := u.clientManager.GetAnonymousClient() c := u.clientManager.GetAnonymousClient()
defer c.Logout() defer c.Logout()
cat, act, lab := m.Get() cat, act, lab := m.Get()
if err := c.SendSimpleMetric(string(cat), string(act), string(lab)); err != nil { if err := c.SendSimpleMetric(string(cat), string(act), string(lab)); err != nil {
log.Error("Sending metric failed: ", err) return err
} }
log.WithFields(logrus.Fields{ log.WithFields(logrus.Fields{
@ -458,6 +460,8 @@ func (u *Users) SendMetric(m metrics.Metric) {
"act": act, "act": act,
"lab": lab, "lab": lab,
}).Debug("Metric successfully sent") }).Debug("Metric successfully sent")
return nil
} }
// AllowProxy instructs the app to use DoH to access an API proxy if necessary. // AllowProxy instructs the app to use DoH to access an API proxy if necessary.

View File

@ -22,6 +22,11 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/)
* GODT-806 Changed GUI dialog on manual update. Added autoupdates checkbox. Simplifyed installation process GUI. * GODT-806 Changed GUI dialog on manual update. Added autoupdates checkbox. Simplifyed installation process GUI.
* Bump gopenpgp dependency to v2.1.3 for improved memory usage. * Bump gopenpgp dependency to v2.1.3 for improved memory usage.
* GODT-912 Changed scroll bar behaviour in settings tab * GODT-912 Changed scroll bar behaviour in settings tab
* GODT-858 Bump go-rfc5322 dependency to v0.5.0 to handle some invalid RFC5322 groups and add support for semicolon delimiter in address-list.
* GODT-923 Fix listener locking.
* GODT-389 Prefer `From` header instead of `MAIL FROM` address.
* GODT-898 Only set ContentID for inline attachments.
* GODT-149 Send heartbeat ASAP on each new calendar day.
### Removed ### Removed
* GODT-208 Remove deprecated use of BuildNameToCertificate. * GODT-208 Remove deprecated use of BuildNameToCertificate.
@ -31,3 +36,9 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/)
### Fixed ### Fixed
* GODT-979 Fix panic when trying to parse a multipart/alternative section that has no child sections. * GODT-979 Fix panic when trying to parse a multipart/alternative section that has no child sections.
### Changed
* GODT-389 Prefer `From` header instead of `MAIL FROM` address.
* GODT-898 Only set ContentID for inline attachments.
* GODT-773 Replace `INTERNALDATE` older than birthday of RFC822 by birthday of RFC822 to not crash Apple Mail.
* GODT-927 Avoid to call API with empty label name.
* GODT-732 Fix usage of fontawesome