diag.go 1.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
package commands

import (
	"errors"
	"fmt"
	"io"
	"time"

	cmds "github.com/jbenet/go-ipfs/commands"
	diagn "github.com/jbenet/go-ipfs/diagnostics"
)

type DiagnosticConnection struct {
	ID      string
	Latency int64
}

type DiagnosticPeer struct {
	ID           string
	LifeSpan     float64
	BandwidthIn  uint64
	BandwidthOut uint64
	Connections  []DiagnosticConnection
}

type DiagnosticOutput struct {
	Peers []DiagnosticPeer
}

var diagCmd = &cmds.Command{
	Run: func(res cmds.Response, req cmds.Request) {
		n := req.Context().Node

34
		if !n.Online() {
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
			res.SetError(errors.New("Cannot run diagnostic in offline mode!"), cmds.ErrNormal)
			return
		}

		info, err := n.Diagnostics.GetDiagnostic(time.Second * 20)
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		output := make([]DiagnosticPeer, len(info))
		for i, peer := range info {
			connections := make([]DiagnosticConnection, len(peer.Connections))
			for j, conn := range peer.Connections {
				connections[j] = DiagnosticConnection{
					ID:      conn.ID,
					Latency: conn.Latency.Nanoseconds(),
				}
			}

			output[i] = DiagnosticPeer{
				ID:           peer.ID,
				LifeSpan:     peer.LifeSpan.Minutes(),
				BandwidthIn:  peer.BwIn,
				BandwidthOut: peer.BwOut,
				Connections:  connections,
			}
		}

		res.SetOutput(&DiagnosticOutput{output})
	},
	Type: &DiagnosticOutput{},
}

func PrintDiagnostics(info []*diagn.DiagInfo, out io.Writer) {
	for _, i := range info {
		fmt.Fprintf(out, "Peer: %s\n", i.ID)
		fmt.Fprintf(out, "\tUp for: %s\n", i.LifeSpan.String())
		fmt.Fprintf(out, "\tConnected To:\n")
		for _, c := range i.Connections {
			fmt.Fprintf(out, "\t%s\n\t\tLatency = %s\n", c.ID, c.Latency.String())
		}
		fmt.Fprintln(out)
	}
}