From a7b69500b14912c77a690393ca8c1f5520b6a1a1 Mon Sep 17 00:00:00 2001
From: Jeromy <jeromyj@gmail.com>
Date: Fri, 10 Oct 2014 11:07:01 -0700
Subject: [PATCH] address concerns in PR and make log stuff more fun

---
 cmd/ipfs/diag.go      |  6 +--
 core/commands/diag.go |  5 ++-
 diagnostics/diag.go   | 86 +++++++++++++++++++++++++++----------------
 net/interface.go      |  3 ++
 net/net.go            |  5 +--
 net/swarm/swarm.go    |  4 +-
 util/util.go          | 19 +++++-----
 7 files changed, 78 insertions(+), 50 deletions(-)

diff --git a/cmd/ipfs/diag.go b/cmd/ipfs/diag.go
index c024d08db..657ddae17 100644
--- a/cmd/ipfs/diag.go
+++ b/cmd/ipfs/diag.go
@@ -8,16 +8,16 @@ import (
 )
 
 var cmdIpfsDiag = &commander.Command{
-	UsageLine: "diag",
+	UsageLine: "net-diag",
 	Short:     "Generate a diagnostics report",
-	Long: `ipfs diag - Generate a diagnostics report.
+	Long: `ipfs net-diag - Generate a diagnostics report.
 
 	Sends out a message to each node in the network recursively
 	requesting a listing of data about them including number of
 	connected peers and latencies between them.
 `,
 	Run:  diagCmd,
-	Flag: *flag.NewFlagSet("ipfs-diag", flag.ExitOnError),
+	Flag: *flag.NewFlagSet("ipfs-net-diag", flag.ExitOnError),
 }
 
 func init() {
diff --git a/core/commands/diag.go b/core/commands/diag.go
index f8061115f..c06499ec6 100644
--- a/core/commands/diag.go
+++ b/core/commands/diag.go
@@ -18,7 +18,10 @@ func Diag(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.W
 	if err != nil {
 		return err
 	}
-	raw := opts["raw"].(bool)
+	raw, ok := opts["raw"].(bool)
+	if !ok {
+		return errors.New("incorrect value to parameter 'raw'")
+	}
 	if raw {
 		enc := json.NewEncoder(out)
 		err = enc.Encode(info)
diff --git a/diagnostics/diag.go b/diagnostics/diag.go
index 111e54016..c598a625e 100644
--- a/diagnostics/diag.go
+++ b/diagnostics/diag.go
@@ -21,6 +21,8 @@ import (
 
 var log = util.Logger("diagnostics")
 
+const ResponseTimeout = time.Second * 10
+
 type Diagnostics struct {
 	network net.Network
 	sender  net.Sender
@@ -64,14 +66,7 @@ func (di *diagInfo) Marshal() []byte {
 }
 
 func (d *Diagnostics) getPeers() []*peer.Peer {
-	// <HACKY>
-	n, ok := d.network.(*net.IpfsNetwork)
-	if !ok {
-		return nil
-	}
-	s := n.GetSwarm()
-	return s.GetPeerList()
-	// </HACKY>
+	return d.network.GetPeerList()
 }
 
 func (d *Diagnostics) getDiagInfo() *diagInfo {
@@ -112,30 +107,50 @@ func (d *Diagnostics) GetDiagnostic(timeout time.Duration) ([]*diagInfo, error)
 	out = append(out, di)
 
 	pmes := newMessage(diagID)
+
+	respdata := make(chan []byte)
+	sends := 0
 	for _, p := range peers {
 		log.Debug("Sending getDiagnostic to: %s", p)
-		data, err := d.getDiagnosticFromPeer(ctx, p, pmes)
-		if err != nil {
-			log.Error("GetDiagnostic error: %v", err)
-			continue
-		}
-		buf := bytes.NewBuffer(data)
-		dec := json.NewDecoder(buf)
-		for {
-			di := new(diagInfo)
-			err := dec.Decode(di)
+		sends++
+		go func(p *peer.Peer) {
+			data, err := d.getDiagnosticFromPeer(ctx, p, pmes)
 			if err != nil {
-				if err != io.EOF {
-					log.Error("error decoding diagInfo: %v", err)
-				}
-				break
+				log.Error("GetDiagnostic error: %v", err)
+				respdata <- nil
+				return
 			}
-			out = append(out, di)
+			respdata <- data
+		}(p)
+	}
+
+	for i := 0; i < sends; i++ {
+		data := <-respdata
+		if data == nil {
+			continue
 		}
+		out = AppendDiagnostics(data, out)
 	}
 	return out, nil
 }
 
+func AppendDiagnostics(data []byte, cur []*diagInfo) []*diagInfo {
+	buf := bytes.NewBuffer(data)
+	dec := json.NewDecoder(buf)
+	for {
+		di := new(diagInfo)
+		err := dec.Decode(di)
+		if err != nil {
+			if err != io.EOF {
+				log.Error("error decoding diagInfo: %v", err)
+			}
+			break
+		}
+		cur = append(cur, di)
+	}
+	return cur
+}
+
 // TODO: this method no longer needed.
 func (d *Diagnostics) getDiagnosticFromPeer(ctx context.Context, p *peer.Peer, mes *Message) ([]byte, error) {
 	rpmes, err := d.sendRequest(ctx, p, mes)
@@ -179,7 +194,6 @@ func (d *Diagnostics) sendRequest(ctx context.Context, p *peer.Peer, pmes *Messa
 	return rpmes, nil
 }
 
-// NOTE: not yet finished, low priority
 func (d *Diagnostics) handleDiagnostic(p *peer.Peer, pmes *Message) (*Message, error) {
 	resp := newMessage(pmes.GetDiagID())
 	d.diagLock.Lock()
@@ -195,16 +209,26 @@ func (d *Diagnostics) handleDiagnostic(p *peer.Peer, pmes *Message) (*Message, e
 	di := d.getDiagInfo()
 	buf.Write(di.Marshal())
 
-	ctx, _ := context.WithTimeout(context.TODO(), time.Second*10)
+	ctx, _ := context.WithTimeout(context.TODO(), ResponseTimeout)
 
+	respdata := make(chan []byte)
+	sendcount := 0
 	for _, p := range d.getPeers() {
 		log.Debug("Sending diagnostic request to peer: %s", p)
-		out, err := d.getDiagnosticFromPeer(ctx, p, pmes)
-		if err != nil {
-			log.Error("getDiagnostic error: %v", err)
-			continue
-		}
-		_, err = buf.Write(out)
+		go func(p *peer.Peer) {
+			out, err := d.getDiagnosticFromPeer(ctx, p, pmes)
+			if err != nil {
+				log.Error("getDiagnostic error: %v", err)
+				respdata <- nil
+				return
+			}
+			respdata <- out
+		}(p)
+	}
+
+	for i := 0; i < sendcount; i++ {
+		out := <-respdata
+		_, err := buf.Write(out)
 		if err != nil {
 			log.Error("getDiagnostic write output error: %v", err)
 			continue
diff --git a/net/interface.go b/net/interface.go
index 85df4c8f1..76b4f4237 100644
--- a/net/interface.go
+++ b/net/interface.go
@@ -28,6 +28,9 @@ type Network interface {
 	// GetProtocols returns the protocols registered in the network.
 	GetProtocols() *mux.ProtocolMap
 
+	// GetPeerList returns the list of peers currently connected in this network.
+	GetPeerList() []*peer.Peer
+
 	// SendMessage sends given Message out
 	SendMessage(msg.NetMessage) error
 
diff --git a/net/net.go b/net/net.go
index 70a4830e3..b5864fe68 100644
--- a/net/net.go
+++ b/net/net.go
@@ -108,7 +108,6 @@ func (n *IpfsNetwork) Close() error {
 	return nil
 }
 
-// XXX
-func (n *IpfsNetwork) GetSwarm() *swarm.Swarm {
-	return n.swarm
+func (n *IpfsNetwork) GetPeerList() []*peer.Peer {
+	return n.swarm.GetPeerList()
 }
diff --git a/net/swarm/swarm.go b/net/swarm/swarm.go
index b066e79a6..fffc1fcef 100644
--- a/net/swarm/swarm.go
+++ b/net/swarm/swarm.go
@@ -203,11 +203,11 @@ func (s *Swarm) GetErrChan() chan error {
 
 func (s *Swarm) GetPeerList() []*peer.Peer {
 	var out []*peer.Peer
-	s.connsLock.Lock()
+	s.connsLock.RLock()
 	for _, p := range s.conns {
 		out = append(out, p.Peer)
 	}
-	s.connsLock.Unlock()
+	s.connsLock.RUnlock()
 	return out
 }
 
diff --git a/util/util.go b/util/util.go
index 3040e7e4b..ec486daac 100644
--- a/util/util.go
+++ b/util/util.go
@@ -138,25 +138,24 @@ func SetupLogging() {
 	logging.SetBackend(backend)
 	logging.SetFormatter(logging.MustStringFormatter(LogFormat))
 
-	// just uncomment Debug = True right here for all logging.
-	// but please don't commit that.
-	// Debug = True
-	if Debug {
-		logging.SetLevel(logging.DEBUG, "")
-	} else {
-		logging.SetLevel(logging.ERROR, "")
-	}
+	logging.SetLevel(logging.ERROR, "")
 
 	for n, log := range loggers {
 		logging.SetLevel(logging.ERROR, n)
-		log.Error("setting logger: %s to %v\n", n, logging.ERROR)
+		log.Error("setting logger: %s to %v", n, logging.ERROR)
+	}
+
+	logenv := os.Getenv("IPFS_LOGGING")
+	if logenv == "all" {
+		AllLoggersOn()
 	}
 }
 
 func AllLoggersOn() {
+	logging.SetLevel(logging.DEBUG, "")
 	for n, log := range loggers {
 		logging.SetLevel(logging.DEBUG, n)
-		log.Error("setting logger: %s to %v\n", n, logging.DEBUG)
+		log.Error("setting logger: %s to %v", n, logging.DEBUG)
 	}
 }
 
-- 
GitLab