vfs: add vfs/stats remote control to show statistics - fixes #5816

This commit is contained in:
Nick Craig-Wood 2021-11-17 16:11:08 +00:00
parent 729117af68
commit d252816706
5 changed files with 123 additions and 0 deletions

View File

@ -389,3 +389,51 @@ func rcList(ctx context.Context, in rc.Params) (out rc.Params, err error) {
out["vfses"] = names
return out, nil
}
func init() {
rc.Add(rc.Call{
Path: "vfs/stats",
Title: "Stats for a VFS.",
Help: `
This returns stats for the selected VFS.
{
// Status of the disk cache - only present if --vfs-cache-mode > off
"diskCache": {
"bytesUsed": 0,
"erroredFiles": 0,
"files": 0,
"hashType": 1,
"outOfSpace": false,
"path": "/home/user/.cache/rclone/vfs/local/mnt/a",
"pathMeta": "/home/user/.cache/rclone/vfsMeta/local/mnt/a",
"uploadsInProgress": 0,
"uploadsQueued": 0
},
"fs": "/mnt/a",
"inUse": 1,
// Status of the in memory metadata cache
"metadataCache": {
"dirs": 1,
"files": 0
},
// Options as returned by options/get
"opt": {
"CacheMaxAge": 3600000000000,
// ...
"WriteWait": 1000000000
}
}
` + getVFSHelp,
Fn: rcStats,
})
}
func rcStats(ctx context.Context, in rc.Params) (out rc.Params, err error) {
vfs, err := getVFS(in)
if err != nil {
return nil, err
}
return vfs.Stats(), nil
}

View File

@ -119,3 +119,15 @@ func TestRcList(t *testing.T) {
},
}, out)
}
func TestRcStats(t *testing.T) {
r, vfs, cleanup, call := rcNewRun(t, "vfs/stats")
defer cleanup()
out, err := call.Fn(context.Background(), nil)
require.NoError(t, err)
assert.Equal(t, fs.ConfigString(r.Fremote), out["fs"])
assert.Equal(t, int32(1), out["inUse"])
assert.Equal(t, 0, out["metadataCache"].(rc.Params)["files"])
assert.Equal(t, 1, out["metadataCache"].(rc.Params)["dirs"])
assert.Equal(t, vfs.Opt, out["opt"].(vfscommon.Options))
}

View File

@ -36,6 +36,7 @@ import (
"github.com/rclone/rclone/fs"
"github.com/rclone/rclone/fs/cache"
"github.com/rclone/rclone/fs/log"
"github.com/rclone/rclone/fs/rc"
"github.com/rclone/rclone/fs/walk"
"github.com/rclone/rclone/vfs/vfscache"
"github.com/rclone/rclone/vfs/vfscommon"
@ -241,6 +242,32 @@ func New(f fs.Fs, opt *vfscommon.Options) *VFS {
return vfs
}
// Stats returns info about the VFS
func (vfs *VFS) Stats() (out rc.Params) {
out = make(rc.Params)
out["fs"] = fs.ConfigString(vfs.f)
out["opt"] = vfs.Opt
out["inUse"] = atomic.LoadInt32(&vfs.inUse)
var (
dirs int
files int
)
vfs.root.walk(func(d *Dir) {
dirs++
files += len(d.items)
})
inf := make(rc.Params)
out["metadataCache"] = inf
inf["dirs"] = dirs
inf["files"] = files
if vfs.cache != nil {
out["diskCache"] = vfs.cache.Stats()
}
return out
}
// Return the number of active cache entries and a VFS if any are in
// the cache.
func activeCacheEntries() (vfs *VFS, count int) {

View File

@ -21,6 +21,7 @@ import (
"github.com/rclone/rclone/fs/fserrors"
"github.com/rclone/rclone/fs/hash"
"github.com/rclone/rclone/fs/operations"
"github.com/rclone/rclone/fs/rc"
"github.com/rclone/rclone/lib/encoder"
"github.com/rclone/rclone/lib/file"
"github.com/rclone/rclone/vfs/vfscache/writeback"
@ -145,6 +146,29 @@ func New(ctx context.Context, fremote fs.Fs, opt *vfscommon.Options, avFn AddVir
return c, nil
}
// Stats returns info about the Cache
func (c *Cache) Stats() (out rc.Params) {
out = make(rc.Params)
// read only - no locking needed to read these
out["path"] = c.root
out["pathMeta"] = c.metaRoot
out["hashType"] = c.hashType
uploadsInProgress, uploadsQueued := c.writeback.Stats()
out["uploadsInProgress"] = uploadsInProgress
out["uploadsQueued"] = uploadsQueued
c.mu.Lock()
defer c.mu.Unlock()
out["files"] = len(c.item)
out["erroredFiles"] = len(c.errItems)
out["bytesUsed"] = c.used
out["outOfSpace"] = c.outOfSpace
return out
}
// createDir creates a directory path, along with any necessary parents
func createDir(dir string) error {
return file.MkdirAll(dir, 0700)

View File

@ -701,3 +701,15 @@ func TestCacheDump(t *testing.T) {
out = c.Dump()
assert.Equal(t, "Cache{\n}\n", out)
}
func TestCacheStats(t *testing.T) {
_, c, cleanup := newTestCache(t)
defer cleanup()
out := c.Stats()
assert.Equal(t, int64(0), out["bytesUsed"])
assert.Equal(t, 0, out["erroredFiles"])
assert.Equal(t, 0, out["files"])
assert.Equal(t, 0, out["uploadsInProgress"])
assert.Equal(t, 0, out["uploadsQueued"])
}