Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Logging overhaul #225

Merged
merged 14 commits into from
Dec 9, 2021
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,20 @@ If you want to use an AWS KMS symmetric encryption key for encrypting the stored
| EncryptionKeyType | `FLOW_WALLET_ENCRYPTION_KEY_TYPE` | Encryption key type | `local` | `aws_kms` |
| EncryptionKey | `FLOW_WALLET_ENCRYPTION_KEY` | KMS encryption key ARN | - | `arn:aws:kms:eu-central-1:012345678910:key/00000000-aaaa-bbbb-cccc-12345678910` |

### Log level

The default log level of the service is `info`. You can change the log level by setting the environment variable `FLOW_WALLET_LOG_LEVEL`.

Valid log leves are (case-insensitive):

panic
fatal
error
warn, warning
info
debug
trace

### All possible configuration variables

Refer to [configs/configs.go](configs/configs.go) for details and documentation.
Expand Down
6 changes: 6 additions & 0 deletions accounts/account_added.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package accounts

import (
"github.com/onflow/flow-go-sdk"
log "github.com/sirupsen/logrus"
)

type AccountAddedPayload struct {
Expand All @@ -20,11 +21,16 @@ var AccountAdded accountAdded // singleton of type accountAdded

// Register adds an event handler for this event
func (e *accountAdded) Register(handler accountAddedHandler) {
log.Debug("Registering AccountAdded event handler")
e.handlers = append(e.handlers, handler)
}

// Trigger sends out an event with the payload
func (e *accountAdded) Trigger(payload AccountAddedPayload) {
log.
WithFields(log.Fields{"payload": payload}).
Trace("Handling AccountAdded event")

for _, handler := range e.handlers {
go handler.Handle(payload)
}
Expand Down
21 changes: 21 additions & 0 deletions accounts/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/onflow/flow-go-sdk"
"github.com/onflow/flow-go-sdk/client"
flow_templates "github.com/onflow/flow-go-sdk/templates"
log "github.com/sirupsen/logrus"
"go.uber.org/ratelimit"
)

Expand Down Expand Up @@ -63,6 +64,8 @@ func NewService(
}

func (s *Service) InitAdminAccount(ctx context.Context) error {
log.Debug("Initializing admin account")

a, err := s.store.Account(s.cfg.AdminAddress)
if err != nil {
if !strings.Contains(err.Error(), "record not found") {
Expand All @@ -84,6 +87,11 @@ func (s *Service) InitAdminAccount(ctx context.Context) error {
return err
}

log.WithFields(log.Fields{
"keyCount": keyCount,
"wantedCount": s.cfg.AdminProposalKeyCount,
}).Debug("Checking admin account proposal keys")

if keyCount < s.cfg.AdminProposalKeyCount {
err = s.addAdminProposalKeys(ctx, s.cfg.AdminProposalKeyCount-keyCount)
if err != nil {
Expand All @@ -100,6 +108,11 @@ func (s *Service) InitAdminAccount(ctx context.Context) error {
}

func (s *Service) addAdminProposalKeys(ctx context.Context, count uint16) error {

log.
WithFields(log.Fields{"count": count}).
Debug("Adding admin account proposal keys")

code := template_strings.AddProposalKeyTransaction
args := []transactions.Argument{
cadence.NewInt(s.cfg.AdminKeyIndex),
Expand All @@ -121,6 +134,8 @@ func (s *Service) List(limit, offset int) (result []Account, err error) {
// and stores both in datastore.
// It returns a job, the new account and a possible error.
func (s *Service) Create(ctx context.Context, sync bool) (*jobs.Job, *Account, error) {
log.WithFields(log.Fields{"sync": sync}).Trace("Create account")

if !sync {
job, err := s.wp.CreateJob(AccountCreateJobType, "")
if err != nil {
Expand All @@ -144,6 +159,8 @@ func (s *Service) Create(ctx context.Context, sync bool) (*jobs.Job, *Account, e
}

func (s *Service) AddNonCustodialAccount(_ context.Context, address string) (*Account, error) {
log.WithFields(log.Fields{"address": address}).Trace("Add non-custodial account")

a := &Account{
Address: flow_helpers.HexString(address),
Type: AccountTypeNonCustodial,
Expand All @@ -158,6 +175,8 @@ func (s *Service) AddNonCustodialAccount(_ context.Context, address string) (*Ac
}

func (s *Service) DeleteNonCustodialAccount(_ context.Context, address string) error {
log.WithFields(log.Fields{"address": address}).Trace("Delete non-custodial account")

a, err := s.store.Account(flow_helpers.HexString(address))
if err != nil {
if strings.Contains(err.Error(), "record not found") {
Expand All @@ -177,6 +196,8 @@ func (s *Service) DeleteNonCustodialAccount(_ context.Context, address string) e

// Details returns a specific account, does not include private keys
func (s *Service) Details(address string) (Account, error) {
log.WithFields(log.Fields{"address": address}).Trace("Account details")

// Check if the input is a valid address
address, err := flow_helpers.ValidateAddress(address, s.cfg.ChainID)
if err != nil {
Expand Down
11 changes: 8 additions & 3 deletions chain_events/event.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package chain_events

import (
"fmt"

"github.com/onflow/flow-go-sdk"
log "github.com/sirupsen/logrus"
)

type handler interface {
Expand All @@ -18,14 +17,20 @@ var Event event // singleton of type event

// Register adds an event handler for this event
func (e *event) Register(handler handler) {
log.Debug("Registering Flow event handler")
e.handlers = append(e.handlers, handler)
}

// Trigger sends out an event with the payload
func (e *event) Trigger(payload flow.Event) {
log.
WithFields(log.Fields{"payload": payload}).
Trace("Handling Flow event")

if len(e.handlers) == 0 {
fmt.Println("Warning: no listeners for chain events")
log.Warn("No listeners for chain events")
}

for _, handler := range e.handlers {
go handler.Handle(payload)
}
Expand Down
50 changes: 27 additions & 23 deletions chain_events/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ package chain_events

import (
"context"
"log"
"os"

"strings"
"time"

"github.com/flow-hydraulics/flow-wallet-api/system"
"github.com/onflow/flow-go-sdk"
"github.com/onflow/flow-go-sdk/client"
log "github.com/sirupsen/logrus"
"gorm.io/gorm"
)

Expand All @@ -18,7 +18,6 @@ type GetEventTypes func() ([]string, error)
type Listener struct {
ticker *time.Ticker
done chan bool
logger *log.Logger
fc *client.Client
db Store
getTypes GetEventTypes
Expand All @@ -39,7 +38,6 @@ func (ListenerStatus) TableName() string {
}

func NewListener(
logger *log.Logger,
fc *client.Client,
db Store,
getTypes GetEventTypes,
Expand All @@ -48,15 +46,17 @@ func NewListener(
startingHeight uint64,
opts ...ListenerOption,
) *Listener {
if logger == nil {
logger = log.New(os.Stdout, "[EVENT-POLLER] ", log.LstdFlags|log.Lshortfile)
}

listener := &Listener{
nil, make(chan bool),
logger, fc, db, getTypes,
maxDiff, interval, startingHeight,
nil,
ticker: nil,
latenssi marked this conversation as resolved.
Show resolved Hide resolved
done: make(chan bool),
fc: fc,
db: db,
getTypes: getTypes,
maxBlocks: maxDiff,
interval: interval,
startingHeight: startingHeight,
systemService: nil,
}

// Go through options
Expand Down Expand Up @@ -96,13 +96,6 @@ func (l *Listener) run(ctx context.Context, start, end uint64) error {
return nil
}

func (l *Listener) handleError(err error) {
l.logger.Println(err)
if strings.Contains(err.Error(), "key not found") {
l.logger.Println(`"key not found" error indicates data is not available at this height, please manually set correct starting height`)
}
}

func (l *Listener) Start() *Listener {
if l.ticker != nil {
// Already started
Expand Down Expand Up @@ -157,16 +150,24 @@ func (l *Listener) Start() *Listener {
})

if err != nil {
if _, isLockError := err.(*LockError); !isLockError {
l.handleError(err)
if _, isLockError := err.(*LockError); isLockError {
// Skip LockError as it means another listener is already handling this round
continue
}

log.
WithFields(log.Fields{"error": err}).
Warn("Error while handling Flow events")

if strings.Contains(err.Error(), "key not found") {
log.Warn(`"key not found" error indicates data is not available at this height, please manually set correct starting height`)
}
// Skip on LockError as it means another listener is already handling this round
}
}
}
}()

l.logger.Println("started")
log.Info("Started Flow event listener")

return l
}
Expand All @@ -193,13 +194,16 @@ func (l *Listener) initHeight() error {
}

func (l *Listener) Stop() {
l.logger.Println("stopping...")
log.Info("Stopping Flow event listener")

if l.ticker != nil {
l.ticker.Stop()
}

if l.done != nil {
l.done <- true
}

l.ticker = nil
}

Expand Down
29 changes: 27 additions & 2 deletions configs/configs.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,35 @@
package configs

import (
"log"
"os"
"time"

"github.com/caarlos0/env/v6"
"github.com/joho/godotenv"
"github.com/onflow/flow-go-sdk"
log "github.com/sirupsen/logrus"
)

func init() {
lvl, ok := os.LookupEnv("FLOW_WALLET_LOG_LEVEL")
if !ok {
// LOG_LEVEL not set, default to info
lvl = "info"
}

ll, err := log.ParseLevel(lvl)
if err != nil {
ll = log.DebugLevel
}

log.SetLevel(ll)

log.SetFormatter(&log.TextFormatter{
DisableColors: true,
FullTimestamp: true,
})
}

type Config struct {
// -- Feature flags --

Expand Down Expand Up @@ -115,18 +136,22 @@ type Config struct {

type Options struct {
EnvFilePath string
Version string
}

// ParseConfig parses environment variables and flags to a valid Config.
func ParseConfig(opt *Options) (*Config, error) {
if opt != nil && opt.EnvFilePath != "" {
// Load variables from a file to the environment of the process
if err := godotenv.Load(opt.EnvFilePath); err != nil {
log.Printf("Could not load environment variables from file.\n%s\nIf running inside a docker container this can be ignored.\n\n", err)
log.
WithFields(log.Fields{"error": err}).
Warn("Could not load environment variables from file. If running inside a docker container this can be ignored.")
}
}

cfg := Config{}

if err := env.Parse(&cfg); err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ require (
github.com/onflow/cadence v0.20.0
github.com/onflow/flow-go-sdk v0.23.0
github.com/onflow/flow/protobuf/go/flow v0.2.3 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
github.com/sirupsen/logrus v1.8.1
github.com/zeebo/blake3 v0.2.1 // indirect
go.uber.org/goleak v1.1.12
go.uber.org/ratelimit v0.2.0
Expand Down
6 changes: 2 additions & 4 deletions handlers/accounts.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package handlers

import (
"log"
"net/http"

"github.com/flow-hydraulics/flow-wallet-api/accounts"
Expand All @@ -11,13 +10,12 @@ import (
// It provides list, create and details APIs.
// It uses an account service to interface with data.
type Accounts struct {
log *log.Logger
service *accounts.Service
}

// NewAccounts initiates a new accounts server.
func NewAccounts(l *log.Logger, service *accounts.Service) *Accounts {
return &Accounts{l, service}
func NewAccounts(service *accounts.Service) *Accounts {
return &Accounts{service}
}

func (s *Accounts) List() http.Handler {
Expand Down
Loading