diff --git a/cmd/server.go b/cmd/server.go index 3e43869c5..9ef9aa1a8 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -17,6 +17,7 @@ package cmd import ( "fmt" "io" + "log" "os" "os/signal" "runtime/pprof" @@ -44,7 +45,20 @@ It will load existing data from the configured directory, and start listening client connections on the configured port.`, RunE: func(cmd *cobra.Command, args []string) error { - fmt.Fprintf(Server.Stderr, "Pilosa %s, build time %s\n", pilosa.Version, pilosa.BuildTime) + // TODO this code is duplicated from server/server.go:Server.Run() because it hasnt run yet + var logOutput io.Writer + if Server.Config.LogPath == "" { + logOutput = stderr + } else { + var err error + logOutput, err = os.OpenFile(Server.Config.LogPath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600) + if err != nil { + return err + } + } + logger := log.New(logOutput, "", log.LstdFlags) + logger.Printf("Pilosa %s, build time %s\n", pilosa.Version, pilosa.BuildTime) + // fmt.Fprintf(Server.Stderr, "Pilosa %s, build time %s\n", pilosa.Version, pilosa.BuildTime) // Start CPU profiling. if Server.CPUProfile != "" { @@ -73,7 +87,7 @@ on the configured port.`, signal.Notify(c, os.Interrupt) select { case sig := <-c: - fmt.Fprintf(Server.Stderr, "Received %s; gracefully shutting down...\n", sig.String()) + logger.Printf("Received %s; gracefully shutting down...\n", sig.String()) // Second signal causes a hard shutdown. go func() { <-c; os.Exit(1) }() @@ -82,7 +96,7 @@ on the configured port.`, return err } case <-Server.Done: - fmt.Fprintf(Server.Stderr, "Server closed externally") + logger.Printf("Server closed externally") } return nil }, diff --git a/fragment.go b/fragment.go index 4758f18e8..278a23bcf 100644 --- a/fragment.go +++ b/fragment.go @@ -265,7 +265,7 @@ func (f *Fragment) openCache() error { // Unmarshal cache data. var pb internal.Cache if err := proto.Unmarshal(buf, &pb); err != nil { - log.Printf("error unmarshaling cache data, skipping: path=%s, err=%s", path, err) + f.logger().Printf("error unmarshaling cache data, skipping: path=%s, err=%s", path, err) return nil } diff --git a/gossip/gossip.go b/gossip/gossip.go index 1b15522a7..c8d9a616d 100644 --- a/gossip/gossip.go +++ b/gossip/gossip.go @@ -18,7 +18,6 @@ import ( "fmt" "io" "log" - "os" "golang.org/x/sync/errgroup" @@ -98,9 +97,9 @@ type gossipConfig struct { } // NewGossipNodeSet returns a new instance of GossipNodeSet. -func NewGossipNodeSet(name string, gossipHost string, gossipPort int, gossipSeed string, sh pilosa.StatusHandler) *GossipNodeSet { +func NewGossipNodeSet(name string, gossipHost string, gossipPort int, gossipSeed string, sh pilosa.StatusHandler, logOutput io.Writer) *GossipNodeSet { g := &GossipNodeSet{ - LogOutput: os.Stderr, + LogOutput: logOutput, } //TODO: pull memberlist config from pilosa.cfg file diff --git a/holder.go b/holder.go index 59fef1560..2fdb58e97 100644 --- a/holder.go +++ b/holder.go @@ -92,7 +92,7 @@ func (h *Holder) Open() error { continue } - h.logger().Printf("opening index: %s", filepath.Base(fi.Name())) + h.logger().Printf("opening index: %s", filepath.Base(fi.Name())) // TODO h.LogOutput not set until server.go:Server.Open() index, err := h.newIndex(h.IndexPath(filepath.Base(fi.Name())), filepath.Base(fi.Name())) if err == ErrName { diff --git a/server/server.go b/server/server.go index 7738f513c..dfa5b6e61 100644 --- a/server/server.go +++ b/server/server.go @@ -22,6 +22,7 @@ import ( "errors" "fmt" "io" + "log" "math/rand" "net" "os" @@ -100,7 +101,10 @@ func (m *Command) Run(args ...string) (err error) { if err = m.Server.Open(); err != nil { return fmt.Errorf("server.Open: %v", err) } - fmt.Fprintf(m.Stderr, "Listening as http://%s\n", m.Server.Host) + + logger := log.New(m.Server.LogOutput, "", log.LstdFlags) // TODO make this a function? + + logger.Printf("Listening as http://%s\n", m.Server.Host) return nil } @@ -132,8 +136,10 @@ func (m *Command) SetupServer() error { m.Server.LogOutput = logFile } + logger := log.New(m.Server.LogOutput, "", log.LstdFlags) + // Configure holder. - fmt.Fprintf(m.Stderr, "Using data from: %s\n", m.Config.DataDir) + logger.Printf("Using data from: %s\n", m.Config.DataDir) m.Server.Holder.Path = m.Config.DataDir m.Server.MetricInterval = time.Duration(m.Config.Metric.PollingInterval) m.Server.Holder.Stats, err = NewStatsClient(m.Config.Metric.Service, m.Config.Metric.Host) @@ -160,7 +166,7 @@ func (m *Command) SetupServer() error { switch m.Config.Cluster.Type { case "http": m.Server.Broadcaster = httpbroadcast.NewHTTPBroadcaster(m.Server, internalPortStr) - m.Server.BroadcastReceiver = httpbroadcast.NewHTTPBroadcastReceiver(internalPortStr, m.Stderr) + m.Server.BroadcastReceiver = httpbroadcast.NewHTTPBroadcastReceiver(internalPortStr, m.Server.LogOutput) m.Server.Cluster.NodeSet = httpbroadcast.NewHTTPNodeSet() err := m.Server.Cluster.NodeSet.(*httpbroadcast.HTTPNodeSet).Join(m.Server.Cluster.Nodes) if err != nil { @@ -180,7 +186,7 @@ func (m *Command) SetupServer() error { if err != nil { gossipHost = m.Config.Host } - gossipNodeSet := gossip.NewGossipNodeSet(m.Config.Host, gossipHost, gossipPort, gossipSeed, m.Server) + gossipNodeSet := gossip.NewGossipNodeSet(m.Config.Host, gossipHost, gossipPort, gossipSeed, m.Server, m.Server.LogOutput) m.Server.Cluster.NodeSet = gossipNodeSet m.Server.Broadcaster = gossipNodeSet m.Server.BroadcastReceiver = gossipNodeSet