mirror of
https://github.com/rclone/rclone.git
synced 2024-12-22 23:22:08 +01:00
vfs: add vfs/stats remote control to show statistics - fixes #5816
This commit is contained in:
parent
729117af68
commit
d252816706
48
vfs/rc.go
48
vfs/rc.go
@ -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
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
|
27
vfs/vfs.go
27
vfs/vfs.go
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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"])
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user