cmd/syncthing: Add more stats to usage reports (ref #3628)

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4347
This commit is contained in:
Audrius Butkevicius
2017-10-12 06:16:46 +00:00
committed by Jakob Borg
parent 813e6ddf83
commit 2760d032ca
23 changed files with 358 additions and 117 deletions

View File

@@ -60,6 +60,10 @@ func (f *folder) Jobs() ([]string, []string) {
func (f *folder) BringToFront(string) {}
func (f *folder) BlockStats() map[string]int {
return nil
}
func (f *folder) scanSubdirs(subDirs []string) error {
if err := f.model.internalScanFolderSubdirs(f.ctx, f.folderID, subDirs); err != nil {
// Potentially sets the error twice, once in the scanner just

View File

@@ -52,6 +52,7 @@ type service interface {
Scan(subs []string) error
Serve()
Stop()
BlockStats() map[string]int
getState() (folderState, time.Time, error)
setState(state folderState)
@@ -405,6 +406,105 @@ func (m *Model) RestartFolder(cfg config.FolderConfiguration) {
m.fmut.Unlock()
}
func (m *Model) UsageReportingStats(version int) map[string]interface{} {
stats := make(map[string]interface{})
if version >= 3 {
// Block stats
m.fmut.Lock()
blockStats := make(map[string]int)
for _, folder := range m.folderRunners {
for k, v := range folder.BlockStats() {
blockStats[k] += v
}
}
m.fmut.Unlock()
stats["blockStats"] = blockStats
// Transport stats
m.pmut.Lock()
transportStats := make(map[string]int)
for _, conn := range m.conn {
transportStats[conn.Transport()]++
}
m.pmut.Unlock()
stats["transportStats"] = transportStats
// Ignore stats
ignoreStats := map[string]int{
"lines": 0,
"inverts": 0,
"folded": 0,
"deletable": 0,
"rooted": 0,
"includes": 0,
"escapedIncludes": 0,
"doubleStars": 0,
"stars": 0,
}
var seenPrefix [3]bool
for folder := range m.cfg.Folders() {
lines, _, err := m.GetIgnores(folder)
if err != nil {
continue
}
ignoreStats["lines"] += len(lines)
for _, line := range lines {
// Allow prefixes to be specified in any order, but only once.
for {
if strings.HasPrefix(line, "!") && !seenPrefix[0] {
seenPrefix[0] = true
line = line[1:]
ignoreStats["inverts"] += 1
} else if strings.HasPrefix(line, "(?i)") && !seenPrefix[1] {
seenPrefix[1] = true
line = line[4:]
ignoreStats["folded"] += 1
} else if strings.HasPrefix(line, "(?d)") && !seenPrefix[2] {
seenPrefix[2] = true
line = line[4:]
ignoreStats["deletable"] += 1
} else {
seenPrefix[0] = false
seenPrefix[1] = false
seenPrefix[2] = false
break
}
}
// Noops, remove
if strings.HasSuffix(line, "**") {
line = line[:len(line)-2]
}
if strings.HasPrefix(line, "**/") {
line = line[3:]
}
if strings.HasPrefix(line, "/") {
ignoreStats["rooted"] += 1
} else if strings.HasPrefix(line, "#include ") {
ignoreStats["includes"] += 1
if strings.Contains(line, "..") {
ignoreStats["escapedIncludes"] += 1
}
}
if strings.Contains(line, "**") {
ignoreStats["doubleStars"] += 1
// Remove not to trip up star checks.
strings.Replace(line, "**", "", -1)
}
if strings.Contains(line, "*") {
ignoreStats["stars"] += 1
}
}
}
stats["ignoreStats"] = ignoreStats
}
return stats
}
type ConnectionInfo struct {
protocol.Statistics
Connected bool
@@ -2449,6 +2549,7 @@ func (m *Model) CommitConfiguration(from, to config.Configuration) bool {
// Some options don't require restart as those components handle it fine
// by themselves.
from.Options.URAccepted = to.Options.URAccepted
from.Options.URSeen = to.Options.URSeen
from.Options.URUniqueID = to.Options.URUniqueID
from.Options.ListenAddresses = to.Options.ListenAddresses
from.Options.RelaysEnabled = to.Options.RelaysEnabled

View File

@@ -308,6 +308,9 @@ func (f *fakeConnection) RemoteAddr() net.Addr {
func (f *fakeConnection) Type() string {
return "fake"
}
func (f *fakeConnection) Transport() string {
return "fake"
}
func (f *fakeConnection) DownloadProgress(folder string, updates []protocol.FileDownloadProgressUpdate) {
f.downloadProgressMessages = append(f.downloadProgressMessages, downloadProgressMessage{

View File

@@ -93,6 +93,9 @@ type sendReceiveFolder struct {
errors map[string]string // path -> error string
errorsMut sync.Mutex
blockStats map[string]int
blockStatsMut sync.Mutex
}
func newSendReceiveFolder(model *Model, cfg config.FolderConfiguration, ver versioner.Versioner, fs fs.Filesystem) service {
@@ -107,6 +110,9 @@ func newSendReceiveFolder(model *Model, cfg config.FolderConfiguration, ver vers
remoteIndex: make(chan struct{}, 1), // This needs to be 1-buffered so that we queue a notification if we're busy doing a pull when it comes.
errorsMut: sync.NewMutex(),
blockStats: make(map[string]int),
blockStatsMut: sync.NewMutex(),
}
f.configureCopiersAndPullers()
@@ -875,6 +881,11 @@ func (f *sendReceiveFolder) renameFile(source, target protocol.FileInfo) {
}
if err == nil {
f.blockStatsMut.Lock()
f.blockStats["total"] += len(target.Blocks)
f.blockStats["renamed"] += len(target.Blocks)
f.blockStatsMut.Unlock()
// The file was renamed, so we have handled both the necessary delete
// of the source and the creation of the target. Fix-up the metadata,
// and update the local index of the target file.
@@ -1443,6 +1454,15 @@ func (f *sendReceiveFolder) finisherRoutine(in <-chan *sharedPullerState) {
if err != nil {
l.Debugln("Puller: final:", err)
f.newError(state.file.Name, err)
} else {
f.blockStatsMut.Lock()
f.blockStats["total"] += state.reused + state.copyTotal + state.pullTotal
f.blockStats["reused"] += state.reused
f.blockStats["pulled"] += state.pullTotal
f.blockStats["copyOrigin"] += state.copyOrigin
f.blockStats["copyOriginShifted"] += state.copyOriginShifted
f.blockStats["copyElsewhere"] += state.copyTotal - state.copyOrigin
f.blockStatsMut.Unlock()
}
events.Default.Log(events.ItemFinished, map[string]interface{}{
"folder": f.folderID,
@@ -1459,6 +1479,16 @@ func (f *sendReceiveFolder) finisherRoutine(in <-chan *sharedPullerState) {
}
}
func (f *sendReceiveFolder) BlockStats() map[string]int {
f.blockStatsMut.Lock()
stats := make(map[string]int)
for k, v := range f.blockStats {
stats[k] = v
}
f.blockStatsMut.Unlock()
return stats
}
// Moves the given filename to the front of the job queue
func (f *sendReceiveFolder) BringToFront(filename string) {
f.queue.BringToFront(filename)