Other: Add more extensive logging

This commit is contained in:
James Houlahan
2022-11-03 23:02:34 +01:00
parent 8bb60afabd
commit c548ba85fe
24 changed files with 405 additions and 81 deletions

View File

@ -25,9 +25,11 @@ import (
"github.com/ProtonMail/gluon/queue"
"github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/ProtonMail/proton-bridge/v2/internal/events"
"github.com/ProtonMail/proton-bridge/v2/internal/logging"
"github.com/ProtonMail/proton-bridge/v2/internal/safe"
"github.com/ProtonMail/proton-bridge/v2/internal/vault"
"github.com/bradenaw/juniper/xslices"
"github.com/sirupsen/logrus"
"gitlab.protontech.ch/go/liteapi"
)
@ -63,6 +65,11 @@ func (user *User) handleAPIEvent(ctx context.Context, event liteapi.Event) error
// handleUserEvent handles the given user event.
func (user *User) handleUserEvent(_ context.Context, userEvent liteapi.User) error {
return safe.LockRet(func() error {
user.log.WithFields(logrus.Fields{
"userID": userEvent.ID,
"username": logging.Sensitive(userEvent.Name),
}).Info("Handling user event")
user.apiUser = userEvent
user.eventCh.Enqueue(events.UserChanged{
@ -100,6 +107,11 @@ func (user *User) handleAddressEvents(ctx context.Context, addressEvents []litea
func (user *User) handleCreateAddressEvent(ctx context.Context, event liteapi.AddressEvent) error {
if err := safe.LockRet(func() error {
user.log.WithFields(logrus.Fields{
"addressID": event.ID,
"email": logging.Sensitive(event.Address.Email),
}).Info("Handling address created event")
if _, ok := user.apiAddrs[event.Address.ID]; ok {
return fmt.Errorf("address %q already exists", event.ID)
}
@ -143,6 +155,11 @@ func (user *User) handleCreateAddressEvent(ctx context.Context, event liteapi.Ad
func (user *User) handleUpdateAddressEvent(_ context.Context, event liteapi.AddressEvent) error { //nolint:unparam
return safe.LockRet(func() error {
user.log.WithFields(logrus.Fields{
"addressID": event.ID,
"email": logging.Sensitive(event.Address.Email),
}).Info("Handling address updated event")
if _, ok := user.apiAddrs[event.Address.ID]; !ok {
return fmt.Errorf("address %q does not exist", event.Address.ID)
}
@ -161,6 +178,8 @@ func (user *User) handleUpdateAddressEvent(_ context.Context, event liteapi.Addr
func (user *User) handleDeleteAddressEvent(_ context.Context, event liteapi.AddressEvent) error {
return safe.LockRet(func() error {
user.log.WithField("addressID", event.ID).Info("Handling address deleted event")
addr, ok := user.apiAddrs[event.ID]
if !ok {
return fmt.Errorf("address %q does not exist", event.ID)
@ -209,6 +228,11 @@ func (user *User) handleLabelEvents(ctx context.Context, labelEvents []liteapi.L
func (user *User) handleCreateLabelEvent(_ context.Context, event liteapi.LabelEvent) error { //nolint:unparam
return safe.LockRet(func() error {
user.log.WithFields(logrus.Fields{
"labelID": event.ID,
"name": logging.Sensitive(event.Label.Name),
}).Info("Handling label created event")
if _, ok := user.apiLabels[event.Label.ID]; ok {
return fmt.Errorf("label %q already exists", event.ID)
}
@ -231,6 +255,11 @@ func (user *User) handleCreateLabelEvent(_ context.Context, event liteapi.LabelE
func (user *User) handleUpdateLabelEvent(_ context.Context, event liteapi.LabelEvent) error { //nolint:unparam
return safe.LockRet(func() error {
user.log.WithFields(logrus.Fields{
"labelID": event.ID,
"name": logging.Sensitive(event.Label.Name),
}).Info("Handling label updated event")
if _, ok := user.apiLabels[event.Label.ID]; !ok {
return fmt.Errorf("label %q does not exist", event.ID)
}
@ -253,6 +282,8 @@ func (user *User) handleUpdateLabelEvent(_ context.Context, event liteapi.LabelE
func (user *User) handleDeleteLabelEvent(_ context.Context, event liteapi.LabelEvent) error { //nolint:unparam
return safe.LockRet(func() error {
user.log.WithField("labelID", event.ID).Info("Handling label deleted event")
label, ok := user.apiLabels[event.ID]
if !ok {
return fmt.Errorf("label %q does not exist", event.ID)
@ -305,6 +336,11 @@ func (user *User) handleCreateMessageEvent(ctx context.Context, event liteapi.Me
}
return safe.RLockRet(func() error {
user.log.WithFields(logrus.Fields{
"messageID": event.ID,
"subject": logging.Sensitive(event.Message.Subject),
}).Info("Handling message created event")
return withAddrKR(user.apiUser, user.apiAddrs[event.Message.AddressID], user.vault.KeyPass(), func(_, addrKR *crypto.KeyRing) error {
buildRes, err := buildRFC822(full, addrKR)
if err != nil {
@ -320,6 +356,11 @@ func (user *User) handleCreateMessageEvent(ctx context.Context, event liteapi.Me
func (user *User) handleUpdateMessageEvent(_ context.Context, event liteapi.MessageEvent) error { //nolint:unparam
return safe.RLockRet(func() error {
user.log.WithFields(logrus.Fields{
"messageID": event.ID,
"subject": logging.Sensitive(event.Message.Subject),
}).Info("Handling message updated event")
update := imap.NewMessageMailboxesUpdated(
imap.MessageID(event.ID),
mapTo[string, imap.MailboxID](xslices.Filter(event.Message.LabelIDs, wantLabelID)),
@ -335,6 +376,8 @@ func (user *User) handleUpdateMessageEvent(_ context.Context, event liteapi.Mess
func (user *User) handleDeleteMessageEvent(_ context.Context, event liteapi.MessageEvent) error { //nolint:unparam
return safe.RLockRet(func() error {
user.log.WithField("messageID", event.ID).Info("Handling message deleted event")
for _, updateCh := range user.updateCh {
update := imap.NewMessagesDeleted(
imap.MessageID(event.ID),

View File

@ -257,7 +257,7 @@ func (conn *imapConnector) CreateMessage(
if messageID, ok, err := conn.sendHash.hasEntryWait(ctx, hash, time.Now().Add(90*time.Second)); err != nil {
return imap.Message{}, nil, fmt.Errorf("failed to check send hash: %w", err)
} else if ok {
conn.log.WithField("messageID", messageID).Debug("Message already sent")
conn.log.WithField("messageID", messageID).Warn("Message already sent")
message, err := conn.client.GetMessage(ctx, messageID)
if err != nil {

View File

@ -46,24 +46,26 @@ const (
// It sends a SyncStarted event and then either SyncFinished or SyncFailed
// depending on whether the sync was successful.
func (user *User) doSync(ctx context.Context) error {
user.log.Debug("Beginning user sync")
start := time.Now()
user.log.WithField("start", start).Info("Beginning user sync")
user.eventCh.Enqueue(events.SyncStarted{
UserID: user.ID(),
})
if err := user.sync(ctx); err != nil {
user.log.WithError(err).Debug("Failed to sync user")
user.log.WithError(err).Warn("Failed to sync user")
user.eventCh.Enqueue(events.SyncFailed{
UserID: user.ID(),
Err: err,
Error: err,
})
return fmt.Errorf("failed to sync: %w", err)
}
user.log.Debug("Finished user sync")
user.log.WithField("duration", time.Since(start)).Info("Finished user sync")
user.eventCh.Enqueue(events.SyncFinished{
UserID: user.ID(),
@ -76,7 +78,7 @@ func (user *User) sync(ctx context.Context) error {
return safe.RLockRet(func() error {
return withAddrKRs(user.apiUser, user.apiAddrs, user.vault.KeyPass(), func(_ *crypto.KeyRing, addrKRs map[string]*crypto.KeyRing) error {
if !user.vault.SyncStatus().HasLabels {
user.log.Debug("Syncing labels")
user.log.Info("Syncing labels")
if err := syncLabels(ctx, user.client, xslices.Unique(maps.Values(user.updateCh))...); err != nil {
return fmt.Errorf("failed to sync labels: %w", err)
@ -86,13 +88,13 @@ func (user *User) sync(ctx context.Context) error {
return fmt.Errorf("failed to set has labels: %w", err)
}
user.log.Debug("Synced labels")
user.log.Info("Synced labels")
} else {
user.log.Debug("Labels are already synced, skipping")
user.log.Info("Labels are already synced, skipping")
}
if !user.vault.SyncStatus().HasMessages {
user.log.Debug("Syncing messages")
user.log.Info("Syncing messages")
if err := syncMessages(
ctx,
@ -112,9 +114,9 @@ func (user *User) sync(ctx context.Context) error {
return fmt.Errorf("failed to set has messages: %w", err)
}
user.log.Debug("Synced messages")
user.log.Info("Synced messages")
} else {
user.log.Debug("Messages are already synced, skipping")
user.log.Info("Messages are already synced, skipping")
}
return nil

View File

@ -39,6 +39,7 @@ import (
"github.com/ProtonMail/proton-bridge/v2/pkg/message/parser"
"github.com/bradenaw/juniper/xslices"
"github.com/bradenaw/juniper/xsync"
"github.com/go-resty/resty/v2"
"github.com/sirupsen/logrus"
"gitlab.protontech.ch/go/liteapi"
"golang.org/x/exp/maps"
@ -91,7 +92,7 @@ func New(
syncWorkers, syncBuffer int,
showAllMail bool,
) (*User, error) { //nolint:funlen
logrus.WithField("userID", apiUser.ID).Debug("Creating new user")
logrus.WithField("userID", apiUser.ID).Info("Creating new user")
// Get the user's API addresses.
apiAddrs, err := client.GetAddresses(ctx)
@ -183,6 +184,12 @@ func New(
})
})
// Log all requests made by the user.
user.client.AddPostRequestHook(func(_ *resty.Client, r *resty.Response) error {
user.log.Infof("%v: %v %v", r.Status(), r.Request.Method, r.Request.URL)
return nil
})
// Stream events from the API, logging any errors that occur.
// This does nothing until the sync has been marked as complete.
// When we receive an API event, we attempt to handle it.
@ -204,6 +211,8 @@ func New(
return
}
user.log.WithField("event", event).Info("Received event")
if err := user.handleAPIEvent(ctx, event); err != nil {
user.log.WithError(err).Error("Failed to handle API event")
return
@ -219,11 +228,15 @@ func New(
// When triggered, attempt to sync the user.
user.goSync = user.tasks.Trigger(func(ctx context.Context) {
user.log.Debug("Sync triggered")
user.abortable.Do(ctx, func(ctx context.Context) {
if !user.vault.SyncStatus().IsComplete() {
if err := user.doSync(ctx); err != nil {
return
}
} else {
user.log.Debug("Sync is already complete, skipping")
}
})
})