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

algod: Write to stdout when config.LogSizeLimit is 0 or -o is passed to algod. #3903

Merged
merged 8 commits into from
Apr 23, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 75 additions & 38 deletions cmd/algod/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package main

import (
"flag"
"fmt"
"io/ioutil"
"math/rand"
Expand All @@ -29,6 +28,7 @@ import (

"github.com/algorand/go-deadlock"
"github.com/gofrs/flock"
"github.com/spf13/cobra"

"github.com/algorand/go-algorand/config"
"github.com/algorand/go-algorand/crypto"
Expand All @@ -43,42 +43,75 @@ import (
"github.com/algorand/go-algorand/util/tokens"
)

var dataDirectory = flag.String("d", "", "Root Algorand daemon data path")
var genesisFile = flag.String("g", "", "Genesis configuration file")
var genesisPrint = flag.Bool("G", false, "Print genesis ID")
var versionCheck = flag.Bool("v", false, "Display and write current build version and exit")
var branchCheck = flag.Bool("b", false, "Display the git branch behind the build")
var channelCheck = flag.Bool("c", false, "Display and release channel behind the build")
var initAndExit = flag.Bool("x", false, "Initialize the ledger and exit")
var peerOverride = flag.String("p", "", "Override phonebook with peer ip:port (or semicolon separated list: ip:port;ip:port;ip:port...)")
var listenIP = flag.String("l", "", "Override config.EndpointAddress (REST listening address) with ip:port")
var sessionGUID = flag.String("s", "", "Telemetry Session GUID to use")
var telemetryOverride = flag.String("t", "", `Override telemetry setting if supported (Use "true", "false", "0" or "1"`)
var seed = flag.String("seed", "", "input to math/rand.Seed()")
type algodArgs struct {
dataDirectory string
genesisFile string
genesisPrint bool
versionCheck bool
branchCheck bool
channelCheck bool
initAndExit bool
logToStdout bool
peerOverride string
listenIP string
sessionGUID string
telemetryOverride string
seed string
}

var command *cobra.Command

func init() {
var args algodArgs

command = &cobra.Command{
Use: "algod",
Short: "Algorand daemon",
Long: `algod allows a node to participate in the agreement protocol, submit and confirm transactions, and view the state of the Algorand Ledger.`,
Run: func(_ *cobra.Command, _ []string) {
run(args)
},
}
command.Flags().StringVarP(&args.dataDirectory, "dataDir", "d", "", "Root Algorand daemon data path")
command.Flags().StringVarP(&args.genesisFile, "genesisFile", "g", "", "Genesis configuration file")
command.Flags().BoolVarP(&args.genesisPrint, "printGenesis", "G", false, "Print genesis ID")
command.Flags().BoolVarP(&args.versionCheck, "version", "v", false, "Display and write current build version and exit")
command.Flags().BoolVarP(&args.branchCheck, "branchCheck", "b", false, "Display the git branch behind the build")
command.Flags().BoolVarP(&args.channelCheck, "channelCheck", "c", false, "Display and release channel behind the build")
command.Flags().BoolVarP(&args.initAndExit, "initAndExit", "x", false, "Initialize the ledger and exit")
command.Flags().BoolVarP(&args.logToStdout, "logToStdout", "o", false, "Write to stdout instead of node.log by overriding config.LogSizeLimit to 0")
command.Flags().StringVarP(&args.peerOverride, "peerOverride", "p", "", "Override phonebook with peer ip:port (or semicolon separated list: ip:port;ip:port;ip:port...)")
command.Flags().StringVarP(&args.listenIP, "listenIP", "l", "", "Override config.EndpointAddress (REST listening address) with ip:port")
command.Flags().StringVarP(&args.sessionGUID, "sessionGUID", "s", "", "Telemetry Session GUID to use")
command.Flags().StringVarP(&args.telemetryOverride, "telemetryOverride", "t", "", `Override telemetry setting if supported (Use "true", "false", "0" or "1"`)
command.Flags().StringVarP(&args.seed, "seed", "", "", "input to math/rand.Seed()")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs to respond to "-seed" to be compatible with flag. But every other flag option only had the natural single letter -x and fits with -x/--xtralongname

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That might be a deal breaker here, that is the one part of the interface that had to change.

}

func main() {
flag.Parse()
exitCode := run()
os.Exit(exitCode)
if err := command.Execute(); err != nil {
fmt.Fprintf(os.Stderr, "algod process exiting with error: %s", err)
os.Exit(1)
}
os.Exit(0)
}

func run() int {
dataDir := resolveDataDir()
func run(args algodArgs) int {
dataDir := resolveDataDir(args.dataDirectory)
absolutePath, absPathErr := filepath.Abs(dataDir)
config.UpdateVersionDataDir(absolutePath)

if *seed != "" {
seedVal, err := strconv.ParseInt(*seed, 10, 64)
if args.seed != "" {
seedVal, err := strconv.ParseInt(args.seed, 10, 64)
if err != nil {
fmt.Fprintf(os.Stderr, "bad seed %#v: %s\n", *seed, err)
fmt.Fprintf(os.Stderr, "bad seed %#v: %s\n", args.seed, err)
return 1
}
rand.Seed(seedVal)
} else {
rand.Seed(time.Now().UnixNano())
}

if *versionCheck {
if args.versionCheck {
fmt.Println(config.FormatVersionAndLicense())
return 0
}
Expand All @@ -91,12 +124,12 @@ func run() int {
baseHeartbeatEvent.Info.Branch = version.Branch
baseHeartbeatEvent.Info.CommitHash = version.GetCommitHash()

if *branchCheck {
if args.branchCheck {
fmt.Println(config.Branch)
return 0
}

if *channelCheck {
if args.channelCheck {
fmt.Println(config.Channel)
return 0
}
Expand All @@ -112,7 +145,7 @@ func run() int {
return 1
}

genesisPath := *genesisFile
genesisPath := args.genesisFile
if genesisPath == "" {
genesisPath = filepath.Join(dataDir, config.GenesisJSONFile)
}
Expand All @@ -131,7 +164,7 @@ func run() int {
return 1
}

if *genesisPrint {
if args.genesisPrint {
fmt.Println(genesis.ID())
return 0
}
Expand Down Expand Up @@ -188,14 +221,14 @@ func run() int {
telemetryConfig.SendToLog = telemetryConfig.SendToLog || cfg.TelemetryToLog

// Apply telemetry override.
telemetryConfig.Enable = logging.TelemetryOverride(*telemetryOverride, &telemetryConfig)
telemetryConfig.Enable = logging.TelemetryOverride(args.telemetryOverride, &telemetryConfig)
remoteTelemetryEnabled = telemetryConfig.Enable

if telemetryConfig.Enable || telemetryConfig.SendToLog {
// If session GUID specified, use it.
if *sessionGUID != "" {
if len(*sessionGUID) == 36 {
telemetryConfig.SessionGUID = *sessionGUID
if args.sessionGUID != "" {
if len(args.sessionGUID) == 36 {
telemetryConfig.SessionGUID = args.sessionGUID
}
}
err = log.EnableTelemetry(telemetryConfig)
Expand Down Expand Up @@ -233,15 +266,15 @@ func run() int {
}

// Allow overriding default listening address
if *listenIP != "" {
cfg.EndpointAddress = *listenIP
if args.listenIP != "" {
cfg.EndpointAddress = args.listenIP
}

// If overriding peers, disable SRV lookup
telemetryDNSBootstrapID := cfg.DNSBootstrapID
var peerOverrideArray []string
if *peerOverride != "" {
peerOverrideArray = strings.Split(*peerOverride, ";")
if args.peerOverride != "" {
peerOverrideArray = strings.Split(args.peerOverride, ";")
cfg.DNSBootstrapID = ""

// The networking code waits until we have GossipFanout
Expand Down Expand Up @@ -292,14 +325,18 @@ func run() int {
}
}

if args.logToStdout {
cfg.LogSizeLimit = 0
}

err = s.Initialize(cfg, phonebookAddresses, string(genesisText))
if err != nil {
fmt.Fprintln(os.Stderr, err)
log.Error(err)
return 1
}

if *initAndExit {
if args.initAndExit {
return 0
}

Expand Down Expand Up @@ -365,14 +402,14 @@ func run() int {
return 0
}

func resolveDataDir() string {
func resolveDataDir(dataDirectory string) string {
// Figure out what data directory to tell algod to use.
// If not specified on cmdline with '-d', look for default in environment.
var dir string
if dataDirectory == nil || *dataDirectory == "" {
if dataDirectory == "" {
dir = os.Getenv("ALGORAND_DATA")
} else {
dir = *dataDirectory
dir = dataDirectory
}
return dir
}
7 changes: 4 additions & 3 deletions cmd/algod/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,22 @@ import (
)

func BenchmarkAlgodStartup(b *testing.B) {
var args algodArgs
tmpDir, err := ioutil.TempDir(os.TempDir(), "BenchmarkAlgodStartup")
require.NoError(b, err)
defer os.RemoveAll(tmpDir)
genesisFile, err := ioutil.ReadFile("../../installer/genesis/devnet/genesis.json")
require.NoError(b, err)

dataDirectory = &tmpDir
args.dataDirectory = tmpDir
bInitAndExit := true
initAndExit = &bInitAndExit
args.initAndExit = bInitAndExit
b.StartTimer()
for n := 0; n < b.N; n++ {
err := ioutil.WriteFile(filepath.Join(tmpDir, config.GenesisJSONFile), genesisFile, 0766)
require.NoError(b, err)
fmt.Printf("file %s was written\n", filepath.Join(tmpDir, config.GenesisJSONFile))
run()
run(args)
os.RemoveAll(tmpDir)
os.Mkdir(tmpDir, 0766)
}
Expand Down
2 changes: 1 addition & 1 deletion config/localTemplate.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ type Local struct {
// SRV-based phonebook
DNSBootstrapID string `version[0]:"<network>.algorand.network"`

// Log file size limit in bytes
// Log file size limit in bytes. When set to 0 logs will be written to stdout.
LogSizeLimit uint64 `version[0]:"1073741824"`

// text/template for creating log archive filename.
Expand Down
9 changes: 8 additions & 1 deletion daemon/algod/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"context"
"errors"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
Expand Down Expand Up @@ -82,7 +83,13 @@ func (s *Server) Initialize(cfg config.Local, phonebookAddresses []string, genes
maxLogAge = 0
}
}
logWriter := logging.MakeCyclicFileWriter(liveLog, archive, cfg.LogSizeLimit, maxLogAge)

var logWriter io.Writer
if cfg.LogSizeLimit > 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if args.logToStdout || cfg.LogSizeLimit <= 0 { ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main function overrides cfg.LogSizeLimit, so this is still the right condition.

logWriter = logging.MakeCyclicFileWriter(liveLog, archive, cfg.LogSizeLimit, maxLogAge)
} else {
logWriter = os.Stdout
}
s.log.SetOutput(logWriter)
s.log.SetJSONFormatter()
s.log.SetLevel(logging.Level(cfg.BaseLoggerDebugLevel))
Expand Down