Add DB Connection and Logging
* Utilize LogRus * Create a DB connection using PGX. * Create an internal boot package for starting the application.
This commit is contained in:
parent
d0d4f2498e
commit
827475f029
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
|
|
||||||
ipld-ethcl-indexer
|
ipld-ethcl-indexer
|
||||||
|
ipld-ethcl-indexer.log
|
||||||
|
11
cmd/head.go
11
cmd/head.go
@ -7,7 +7,10 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/vulcanize/ipld-ethcl-indexer/internal/boot"
|
||||||
)
|
)
|
||||||
|
|
||||||
// headCmd represents the head command
|
// headCmd represents the head command
|
||||||
@ -17,9 +20,17 @@ var headCmd = &cobra.Command{
|
|||||||
Long: `Capture only the blocks and state at head.`,
|
Long: `Capture only the blocks and state at head.`,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
fmt.Println("head called")
|
fmt.Println("head called")
|
||||||
|
startHeadTracking()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func startHeadTracking() {
|
||||||
|
_, err := boot.BootApplication(dbAddress, dbPort, dbName, dbUsername, dbPassword, dbDriver)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Unable to Start application with error: ", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
captureCmd.AddCommand(headCmd)
|
captureCmd.AddCommand(headCmd)
|
||||||
|
|
||||||
|
66
cmd/root.go
66
cmd/root.go
@ -8,18 +8,22 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
cfgFile string
|
cfgFile string
|
||||||
dbUserName string
|
dbUsername string
|
||||||
dbPassword string
|
dbPassword string
|
||||||
|
dbName string
|
||||||
dbAddress string
|
dbAddress string
|
||||||
dbPort uint16
|
dbDriver string
|
||||||
|
dbPort int
|
||||||
lhAddress string
|
lhAddress string
|
||||||
lhPort uint16
|
lhPort uint16
|
||||||
|
logWithCommand log.Entry
|
||||||
)
|
)
|
||||||
|
|
||||||
// rootCmd represents the base command when called without any subcommands
|
// rootCmd represents the base command when called without any subcommands
|
||||||
@ -28,6 +32,7 @@ var rootCmd = &cobra.Command{
|
|||||||
Short: "This application will keep track of all BeaconState's and SginedBeaconBlock's on the Beacon Chain.",
|
Short: "This application will keep track of all BeaconState's and SginedBeaconBlock's on the Beacon Chain.",
|
||||||
Long: `This is an application that will capture the BeaconState's and SginedBeaconBlock's on the Beacon Chain.
|
Long: `This is an application that will capture the BeaconState's and SginedBeaconBlock's on the Beacon Chain.
|
||||||
It can either do this will keeping track of head, or backfilling historic data.`,
|
It can either do this will keeping track of head, or backfilling historic data.`,
|
||||||
|
PersistentPreRun: initFuncs,
|
||||||
// Uncomment the following line if your bare application
|
// Uncomment the following line if your bare application
|
||||||
// has an action associated with it:
|
// has an action associated with it:
|
||||||
// Run: func(cmd *cobra.Command, args []string) {},
|
// Run: func(cmd *cobra.Command, args []string) {},
|
||||||
@ -42,6 +47,43 @@ func Execute() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prerun for Cobra
|
||||||
|
func initFuncs(cmd *cobra.Command, args []string) {
|
||||||
|
viper.BindEnv("log.file", "LOGRUS_FILE")
|
||||||
|
logfile := viper.GetString("log.file")
|
||||||
|
if logfile != "" {
|
||||||
|
file, err := os.OpenFile(logfile,
|
||||||
|
os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||||
|
if err == nil {
|
||||||
|
log.Infof("Directing output to %s", logfile)
|
||||||
|
log.SetOutput(file)
|
||||||
|
} else {
|
||||||
|
log.SetOutput(os.Stdout)
|
||||||
|
log.Info("Failed to log to file, using default stdout")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.SetOutput(os.Stdout)
|
||||||
|
}
|
||||||
|
if err := logLevel(); err != nil {
|
||||||
|
log.Fatal("Could not set log level: ", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the log level for the application
|
||||||
|
func logLevel() error {
|
||||||
|
viper.BindEnv("log.level", "LOGRUS_LEVEL")
|
||||||
|
lvl, err := log.ParseLevel(viper.GetString("log.level"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.SetLevel(lvl)
|
||||||
|
if lvl > log.InfoLevel {
|
||||||
|
log.SetReportCaller(true)
|
||||||
|
}
|
||||||
|
log.Info("Log level set to ", lvl.String())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
cobra.OnInitialize(initConfig)
|
cobra.OnInitialize(initConfig)
|
||||||
|
|
||||||
@ -51,18 +93,24 @@ func init() {
|
|||||||
|
|
||||||
// Optional Flags
|
// Optional Flags
|
||||||
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.ipld-ethcl-indexer.yaml)")
|
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.ipld-ethcl-indexer.yaml)")
|
||||||
|
rootCmd.PersistentFlags().String("log-level", log.InfoLevel.String(), "log level (trace, debug, info, warn, error, fatal, panic)")
|
||||||
|
rootCmd.PersistentFlags().String("log-file", "ipld-ethcl-indexer.log", "file path for logging")
|
||||||
|
|
||||||
// Required Flags
|
// Required Flags
|
||||||
|
|
||||||
//// DB Specific
|
//// DB Specific
|
||||||
rootCmd.PersistentFlags().StringVarP(&dbUserName, "db.username", "u", "", "Database username (required)")
|
rootCmd.PersistentFlags().StringVarP(&dbUsername, "db.username", "", "", "Database username (required)")
|
||||||
rootCmd.PersistentFlags().StringVarP(&dbPassword, "db.password", "p", "", "Database Password (required)")
|
rootCmd.PersistentFlags().StringVarP(&dbPassword, "db.password", "", "", "Database Password (required)")
|
||||||
rootCmd.PersistentFlags().StringVarP(&dbAddress, "db.address", "a", "", "Port to connect to DB(required)")
|
rootCmd.PersistentFlags().StringVarP(&dbAddress, "db.address", "", "", "Port to connect to DB(required)")
|
||||||
rootCmd.PersistentFlags().Uint16VarP(&dbPort, "db.port", "o", 0, "Port to connect to DB(required)")
|
rootCmd.PersistentFlags().StringVarP(&dbName, "db.name", "n", "", "Database name connect to DB(required)")
|
||||||
|
rootCmd.PersistentFlags().StringVarP(&dbDriver, "db.driver", "", "", "Database Driver to connect to DB(required)")
|
||||||
|
rootCmd.PersistentFlags().IntVarP(&dbPort, "db.port", "", 0, "Port to connect to DB(required)")
|
||||||
rootCmd.MarkPersistentFlagRequired("db.username")
|
rootCmd.MarkPersistentFlagRequired("db.username")
|
||||||
rootCmd.MarkPersistentFlagRequired("db.password")
|
rootCmd.MarkPersistentFlagRequired("db.password")
|
||||||
rootCmd.MarkPersistentFlagRequired("db.address")
|
rootCmd.MarkPersistentFlagRequired("db.address")
|
||||||
rootCmd.MarkPersistentFlagRequired("db.port")
|
rootCmd.MarkPersistentFlagRequired("db.port")
|
||||||
|
rootCmd.MarkPersistentFlagRequired("db.name")
|
||||||
|
rootCmd.MarkPersistentFlagRequired("db.driver")
|
||||||
|
|
||||||
//// Lighthouse Specific
|
//// Lighthouse Specific
|
||||||
rootCmd.PersistentFlags().StringVarP(&lhAddress, "lh.address", "l", "", "Address to connect to lighthouse node (required if username is set)")
|
rootCmd.PersistentFlags().StringVarP(&lhAddress, "lh.address", "l", "", "Address to connect to lighthouse node (required if username is set)")
|
||||||
@ -71,11 +119,17 @@ func init() {
|
|||||||
rootCmd.MarkPersistentFlagRequired("lh.port")
|
rootCmd.MarkPersistentFlagRequired("lh.port")
|
||||||
|
|
||||||
// Bind Flags with Viper
|
// Bind Flags with Viper
|
||||||
|
// Optional
|
||||||
|
viper.BindPFlag("log.level", rootCmd.PersistentFlags().Lookup("log-level"))
|
||||||
|
viper.BindPFlag("log.file", rootCmd.PersistentFlags().Lookup("log-file"))
|
||||||
|
|
||||||
//// DB Flags
|
//// DB Flags
|
||||||
viper.BindPFlag("db.username", rootCmd.PersistentFlags().Lookup("db.username"))
|
viper.BindPFlag("db.username", rootCmd.PersistentFlags().Lookup("db.username"))
|
||||||
viper.BindPFlag("db.password", rootCmd.PersistentFlags().Lookup("db.password"))
|
viper.BindPFlag("db.password", rootCmd.PersistentFlags().Lookup("db.password"))
|
||||||
viper.BindPFlag("db.address", rootCmd.PersistentFlags().Lookup("db.address"))
|
viper.BindPFlag("db.address", rootCmd.PersistentFlags().Lookup("db.address"))
|
||||||
viper.BindPFlag("db.port", rootCmd.PersistentFlags().Lookup("db.port"))
|
viper.BindPFlag("db.port", rootCmd.PersistentFlags().Lookup("db.port"))
|
||||||
|
viper.BindPFlag("db.name", rootCmd.PersistentFlags().Lookup("db.name"))
|
||||||
|
viper.BindPFlag("db.driver", rootCmd.PersistentFlags().Lookup("db.driver"))
|
||||||
|
|
||||||
// LH specific
|
// LH specific
|
||||||
viper.BindPFlag("lh.address", rootCmd.PersistentFlags().Lookup("lh.address"))
|
viper.BindPFlag("lh.address", rootCmd.PersistentFlags().Lookup("lh.address"))
|
||||||
|
23
internal/boot/boot.go
Normal file
23
internal/boot/boot.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package boot
|
||||||
|
|
||||||
|
import (
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/vulcanize/ipld-ethcl-indexer/pkg/database/sql/postgres"
|
||||||
|
)
|
||||||
|
|
||||||
|
func setUpLightHouse() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function will perform some boot operations.
|
||||||
|
// 1. Setup a logger
|
||||||
|
// 2. Connect to the database.
|
||||||
|
// 3. Connect to to the lighthouse client.
|
||||||
|
func BootApplication(dbHostname string, dbPort int, dbName string, dbUsername string, dbPassword string, driverName string) (*postgres.DB, error) {
|
||||||
|
log.Debug("Setting up DB connection")
|
||||||
|
DB, err := SetupDb(dbHostname, dbPort, dbName, dbUsername, dbPassword, driverName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return DB, nil
|
||||||
|
}
|
29
internal/boot/setup_database.go
Normal file
29
internal/boot/setup_database.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// This file will allow users to setup a new DB based on the user provided inputs.
|
||||||
|
|
||||||
|
package boot
|
||||||
|
|
||||||
|
import (
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/vulcanize/ipld-ethcl-indexer/pkg/database/sql/postgres"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SetupDb(dbHostname string, dbPort int, dbName string, dbUsername string, dbPassword string, driverName string) (*postgres.DB, error) {
|
||||||
|
log.Debug("Resolving Driver Type")
|
||||||
|
DbDriver, err := postgres.ResolveDriverType(driverName)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Can't Connect to DB")
|
||||||
|
}
|
||||||
|
log.Info("Using Driver:", DbDriver)
|
||||||
|
|
||||||
|
postgresConfig := postgres.Config{
|
||||||
|
Hostname: dbHostname,
|
||||||
|
Port: dbPort,
|
||||||
|
DatabaseName: dbName,
|
||||||
|
Username: dbUsername,
|
||||||
|
Password: dbPassword,
|
||||||
|
Driver: DbDriver,
|
||||||
|
}
|
||||||
|
DB, err := postgres.NewPostgresDB(postgresConfig)
|
||||||
|
return DB, err
|
||||||
|
|
||||||
|
}
|
3
internal/boot/startup.md
Normal file
3
internal/boot/startup.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Overview
|
||||||
|
|
||||||
|
This small package will group all the functions needed to start the application. The functions listed here can be utilized regardless of whether the application is meant to track `head` or for `historic` processing.
|
@ -53,10 +53,6 @@ type Config struct {
|
|||||||
MaxConnLifetime time.Duration
|
MaxConnLifetime time.Duration
|
||||||
ConnTimeout time.Duration
|
ConnTimeout time.Duration
|
||||||
|
|
||||||
// node info params
|
|
||||||
ID string
|
|
||||||
ClientName string
|
|
||||||
|
|
||||||
// driver type
|
// driver type
|
||||||
Driver DriverType
|
Driver DriverType
|
||||||
}
|
}
|
@ -4,7 +4,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-ethcl-indexer/pkg/dbtools/sql"
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/vulcanize/ipld-ethcl-indexer/pkg/database/sql"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ sql.Database = &DB{}
|
var _ sql.Database = &DB{}
|
||||||
@ -14,15 +15,10 @@ var _ sql.Database = &DB{}
|
|||||||
// This will make sure that if you want a driver, it conforms to the interface.
|
// This will make sure that if you want a driver, it conforms to the interface.
|
||||||
|
|
||||||
// NewPostgresDB returns a postgres.DB using the provided Config and driver type.
|
// NewPostgresDB returns a postgres.DB using the provided Config and driver type.
|
||||||
func NewPostgresDB(c Config, driverName string) (*DB, error) {
|
func NewPostgresDB(c Config) (*DB, error) {
|
||||||
var driver *pgxDriver
|
var driver *pgxDriver
|
||||||
|
|
||||||
driverType, err := ResolveDriverType(driverName)
|
driver, err := createDriver(c)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
driver, err = createDriver(c, driverType)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -31,15 +27,18 @@ func NewPostgresDB(c Config, driverName string) (*DB, error) {
|
|||||||
return &DB{driver}, nil
|
return &DB{driver}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createDriver(c Config, driverType DriverType) (*pgxDriver, error) {
|
func createDriver(c Config) (*pgxDriver, error) {
|
||||||
switch driverType {
|
switch c.Driver {
|
||||||
case PGX:
|
case PGX:
|
||||||
|
log.Debug("Creating New Driver")
|
||||||
driver, err := newPGXDriver(context.Background(), c)
|
driver, err := newPGXDriver(context.Background(), c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Error Creating Driver, err: %e", err)
|
return nil, fmt.Errorf("Error Creating Driver, err: %e", err)
|
||||||
}
|
}
|
||||||
|
log.Info("Successfully created a driver for PGX")
|
||||||
return driver, nil
|
return driver, nil
|
||||||
default:
|
default:
|
||||||
|
log.Fatal("Couldnt find a driver to create for: ", c.Driver)
|
||||||
return nil, fmt.Errorf("Can't find a driver to create")
|
return nil, fmt.Errorf("Can't find a driver to create")
|
||||||
}
|
}
|
||||||
|
|
@ -8,7 +8,7 @@ import (
|
|||||||
"github.com/jackc/pgconn"
|
"github.com/jackc/pgconn"
|
||||||
"github.com/jackc/pgx/v4"
|
"github.com/jackc/pgx/v4"
|
||||||
"github.com/jackc/pgx/v4/pgxpool"
|
"github.com/jackc/pgx/v4/pgxpool"
|
||||||
"github.com/vulcanize/ipld-ethcl-indexer/pkg/dbtools/sql"
|
"github.com/vulcanize/ipld-ethcl-indexer/pkg/database/sql"
|
||||||
)
|
)
|
||||||
|
|
||||||
// pgxDriver driver, implements sql.Driver
|
// pgxDriver driver, implements sql.Driver
|
@ -7,7 +7,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/jackc/pgx/v4/pgxpool"
|
"github.com/jackc/pgx/v4/pgxpool"
|
||||||
"github.com/vulcanize/ipld-ethcl-indexer/pkg/dbtools/sql"
|
"github.com/vulcanize/ipld-ethcl-indexer/pkg/database/sql"
|
||||||
"github.com/vulcanize/ipld-ethcl-indexer/pkg/testhelpers"
|
"github.com/vulcanize/ipld-ethcl-indexer/pkg/testhelpers"
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user