-
Notifications
You must be signed in to change notification settings - Fork 467
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add inspector command for system inspection (#2663)
* add inspector command and tests
- Loading branch information
Showing
9 changed files
with
469 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,247 @@ | ||
package commands | ||
|
||
import ( | ||
"os" | ||
"runtime" | ||
|
||
cmdkit "github.com/ipfs/go-ipfs-cmdkit" | ||
cmds "github.com/ipfs/go-ipfs-cmds" | ||
sysi "github.com/whyrusleeping/go-sysinfo" | ||
|
||
"github.com/filecoin-project/go-filecoin/config" | ||
"github.com/filecoin-project/go-filecoin/repo" | ||
) | ||
|
||
var inspectCmd = &cmds.Command{ | ||
Helptext: cmdkit.HelpText{ | ||
Tagline: "Show info about the filecoin node", | ||
}, | ||
Subcommands: map[string]*cmds.Command{ | ||
"all": allInspectCmd, | ||
"runtime": runtimeInspectCmd, | ||
"disk": diskInspectCmd, | ||
"memory": memoryInspectCmd, | ||
"config": configInspectCmd, | ||
"environment": envInspectCmd, | ||
}, | ||
} | ||
var allInspectCmd = &cmds.Command{ | ||
Helptext: cmdkit.HelpText{ | ||
Tagline: "Print all diagnostic information.", | ||
ShortDescription: ` | ||
Prints out information about filecoin process and its environment. | ||
`, | ||
}, | ||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { | ||
var allInfo AllInspectorInfo | ||
allInfo.Runtime = GetInspectorAPI(env).Runtime() | ||
|
||
dsk, err := GetInspectorAPI(env).Disk() | ||
if err != nil { | ||
return err | ||
} | ||
allInfo.Disk = dsk | ||
|
||
mem, err := GetInspectorAPI(env).Memory() | ||
if err != nil { | ||
return err | ||
} | ||
allInfo.Memory = mem | ||
allInfo.Config = GetInspectorAPI(env).Config() | ||
allInfo.Environment = GetInspectorAPI(env).Environment() | ||
return cmds.EmitOnce(res, allInfo) | ||
}, | ||
} | ||
|
||
var runtimeInspectCmd = &cmds.Command{ | ||
Helptext: cmdkit.HelpText{ | ||
Tagline: "Print runtime diagnostic information.", | ||
ShortDescription: ` | ||
Prints out information about the golang runtime. | ||
`, | ||
}, | ||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { | ||
out := GetInspectorAPI(env).Runtime() | ||
return cmds.EmitOnce(res, out) | ||
}, | ||
} | ||
|
||
var diskInspectCmd = &cmds.Command{ | ||
Helptext: cmdkit.HelpText{ | ||
Tagline: "Print filesystem usage information.", | ||
ShortDescription: ` | ||
Prints out information about the filesystem. | ||
`, | ||
}, | ||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { | ||
out, err := GetInspectorAPI(env).Disk() | ||
if err != nil { | ||
return err | ||
} | ||
return cmds.EmitOnce(res, out) | ||
}, | ||
} | ||
|
||
var memoryInspectCmd = &cmds.Command{ | ||
Helptext: cmdkit.HelpText{ | ||
Tagline: "Print memory usage information.", | ||
ShortDescription: ` | ||
Prints out information about memory usage. | ||
`, | ||
}, | ||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { | ||
out, err := GetInspectorAPI(env).Memory() | ||
if err != nil { | ||
return err | ||
} | ||
return cmds.EmitOnce(res, out) | ||
}, | ||
} | ||
|
||
var configInspectCmd = &cmds.Command{ | ||
Helptext: cmdkit.HelpText{ | ||
Tagline: "Print in-memory config information.", | ||
ShortDescription: ` | ||
Prints out information about your filecoin nodes config. | ||
`, | ||
}, | ||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { | ||
out := GetInspectorAPI(env).Config() | ||
return cmds.EmitOnce(res, out) | ||
}, | ||
} | ||
|
||
var envInspectCmd = &cmds.Command{ | ||
Helptext: cmdkit.HelpText{ | ||
Tagline: "Print filecoin environment information.", | ||
ShortDescription: ` | ||
Prints out information about your filecoin nodes environment. | ||
`, | ||
}, | ||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { | ||
out := GetInspectorAPI(env).Environment() | ||
return cmds.EmitOnce(res, out) | ||
}, | ||
} | ||
|
||
// NewInspectorAPI returns a `Inspector` used to inspect the go-filecoin node. | ||
func NewInspectorAPI(r repo.Repo) *Inspector { | ||
return &Inspector{ | ||
repo: r, | ||
} | ||
} | ||
|
||
// Inspector contains information used to inspect the go-filecoin node. | ||
type Inspector struct { | ||
repo repo.Repo | ||
} | ||
|
||
// AllInspectorInfo contains all information the inspector can gather. | ||
type AllInspectorInfo struct { | ||
Config *config.Config | ||
Runtime *RuntimeInfo | ||
Environment *EnvironmentInfo | ||
Disk *DiskInfo | ||
Memory *MemoryInfo | ||
} | ||
|
||
// RuntimeInfo contains information about the golang runtime. | ||
type RuntimeInfo struct { | ||
OS string | ||
Arch string | ||
Version string | ||
Compiler string | ||
NumProc int | ||
GoMaxProcs int | ||
NumGoRoutines int | ||
NumCGoCalls int64 | ||
} | ||
|
||
// EnvironmentInfo contains information about the environment filecoin is running in. | ||
type EnvironmentInfo struct { | ||
FilAPI string `json:"FIL_API"` | ||
FilPath string `json:"FIL_PATH"` | ||
GoPath string `json:"GOPATH"` | ||
} | ||
|
||
// DiskInfo contains information about disk usage and type. | ||
type DiskInfo struct { | ||
Free uint64 | ||
Total uint64 | ||
FSType string | ||
} | ||
|
||
// MemoryInfo contains information about memory usage. | ||
type MemoryInfo struct { | ||
Swap uint64 | ||
Virtual uint64 | ||
} | ||
|
||
// Runtime returns infrormation about the golang runtime. | ||
func (g *Inspector) Runtime() *RuntimeInfo { | ||
return &RuntimeInfo{ | ||
OS: runtime.GOOS, | ||
Arch: runtime.GOARCH, | ||
Version: runtime.Version(), | ||
Compiler: runtime.Compiler, | ||
NumProc: runtime.NumCPU(), | ||
GoMaxProcs: runtime.GOMAXPROCS(0), | ||
NumGoRoutines: runtime.NumGoroutine(), | ||
NumCGoCalls: runtime.NumCgoCall(), | ||
} | ||
} | ||
|
||
// Environment returns information about the environment filecoin is running in. | ||
func (g *Inspector) Environment() *EnvironmentInfo { | ||
return &EnvironmentInfo{ | ||
FilAPI: os.Getenv("FIL_API"), | ||
FilPath: os.Getenv("FIL_PATH"), | ||
GoPath: os.Getenv("GOPATH"), | ||
} | ||
} | ||
|
||
// Disk return information about filesystem the filecoin nodes repo is on. | ||
func (g *Inspector) Disk() (*DiskInfo, error) { | ||
fsr, ok := g.repo.(*repo.FSRepo) | ||
if !ok { | ||
// we are using a in memory repo | ||
return &DiskInfo{ | ||
Free: 0, | ||
Total: 0, | ||
FSType: "0", | ||
}, nil | ||
} | ||
|
||
p, err := fsr.Path() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
dinfo, err := sysi.DiskUsage(p) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &DiskInfo{ | ||
Free: dinfo.Free, | ||
Total: dinfo.Total, | ||
FSType: dinfo.FsType, | ||
}, nil | ||
} | ||
|
||
// Memory return information about system meory usage. | ||
func (g *Inspector) Memory() (*MemoryInfo, error) { | ||
meminfo, err := sysi.MemoryInfo() | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &MemoryInfo{ | ||
Swap: meminfo.Swap, | ||
Virtual: meminfo.Used, | ||
}, nil | ||
} | ||
|
||
// Config return the current config values of the filecoin node. | ||
func (g *Inspector) Config() *config.Config { | ||
return g.repo.Config() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package commands_test | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
"time" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
|
||
tf "github.com/filecoin-project/go-filecoin/testhelpers/testflags" | ||
"github.com/filecoin-project/go-filecoin/tools/fast" | ||
"github.com/filecoin-project/go-filecoin/tools/fast/fastesting" | ||
) | ||
|
||
func TestInspectConfig(t *testing.T) { | ||
tf.IntegrationTest(t) | ||
|
||
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(10*time.Second)) | ||
defer cancel() | ||
|
||
// Get basic testing environment | ||
ctx, env := fastesting.NewTestEnvironment(ctx, t, fast.EnvironmentOpts{}) | ||
|
||
// Teardown after test ends | ||
defer func() { | ||
err := env.Teardown(ctx) | ||
require.NoError(t, err) | ||
}() | ||
|
||
nd := env.RequireNewNodeStarted() | ||
|
||
icfg, err := nd.InspectConfig(ctx) | ||
require.NoError(t, err) | ||
|
||
rcfg, err := nd.Config() | ||
require.NoError(t, err) | ||
|
||
// API is not the same since the FAST plugin reads the config file from disk, | ||
// this is a limitation of FAST. | ||
// FAST sets API.Address to /ip4/0.0.0.0/0 in the config file to avoid port collisions. | ||
// The Inspector returns an in memory representation of the config that has | ||
// received a port assignment from the kernel, meaning it is no longer /ip4/0.0.0.0/0 | ||
assert.Equal(t, rcfg.Bootstrap, icfg.Bootstrap) | ||
assert.Equal(t, rcfg.Datastore, icfg.Datastore) | ||
assert.Equal(t, rcfg.Swarm, icfg.Swarm) | ||
assert.Equal(t, rcfg.Mining, icfg.Mining) | ||
assert.Equal(t, rcfg.Wallet, icfg.Wallet) | ||
assert.Equal(t, rcfg.Heartbeat, icfg.Heartbeat) | ||
assert.Equal(t, rcfg.Net, icfg.Net) | ||
assert.Equal(t, rcfg.Mpool, icfg.Mpool) | ||
} |
Oops, something went wrong.