Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
wants to merge 12 commits into from
4 changes: 1 addition & 3 deletions cmd/syncthing/gui.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (

"github.com/rcrowley/go-metrics"
"github.com/syncthing/syncthing/lib/config"
"github.com/syncthing/syncthing/lib/connections"
"github.com/syncthing/syncthing/lib/db"
"github.com/syncthing/syncthing/lib/discover"
"github.com/syncthing/syncthing/lib/events"
Expand Down Expand Up @@ -101,8 +100,7 @@ type modelIntf interface {
CurrentSequence(folder string) (int64, bool)
RemoteSequence(folder string) (int64, bool)
State(folder string) (string, time.Time, error)
Connections() []connections.Connection
BlockStats() map[string]int
UsageReportingStats(version int) map[string]interface{}
}

type configIntf interface {
Expand Down
7 changes: 1 addition & 6 deletions cmd/syncthing/mocked_model_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ package main
import (
"time"

"github.com/syncthing/syncthing/lib/connections"
"github.com/syncthing/syncthing/lib/db"
"github.com/syncthing/syncthing/lib/model"
"github.com/syncthing/syncthing/lib/protocol"
Expand Down Expand Up @@ -116,10 +115,6 @@ func (m *mockedModel) State(folder string) (string, time.Time, error) {
return "", time.Time{}, nil
}

func (m *mockedModel) Connections() []connections.Connection {
return nil
}

func (m *mockedModel) BlockStats() map[string]int {
func (m *mockedModel) UsageReportingStats(version int) map[string]interface{} {
return nil
}
10 changes: 4 additions & 6 deletions cmd/syncthing/usage_report.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,16 +181,14 @@ func reportData(cfg configIntf, m modelIntf, connectionsService connectionsIntf,
res["upgradeAllowedPre"] = !(upgrade.DisabledByCompilation || noUpgradeFromEnv) && opts.AutoUpgradeIntervalH > 0 && opts.UpgradeToPreReleases

if version >= 3 {
connTypes := make(map[string]int)
for _, conn := range m.Connections() {
connTypes[conn.Transport()]++
}
res["connectionTypes"] = connTypes
res["blockStats"] = m.BlockStats()
res["uptime"] = time.Now().Sub(startTime).Seconds()
res["natType"] = connectionsService.NATType()
}

for key, value := range m.UsageReportingStats(version){
res[key] = value
}

return res
}

Expand Down
109 changes: 93 additions & 16 deletions lib/model/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,25 +406,102 @@ func (m *Model) RestartFolder(cfg config.FolderConfiguration) {
m.fmut.Unlock()
}

func (m *Model) Connections() []connections.Connection {
m.pmut.Lock()
conns := make([]connections.Connection, 0, len(m.conn))
for _, conn := range m.conn {
conns = append(conns, conn)
}
m.pmut.Unlock()
return conns
}
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

func (m *Model) BlockStats() map[string]int {
m.fmut.Lock()
stats := make(map[string]int)
for _, folder := range m.folderRunners {
for k, v := range folder.BlockStats() {
stats[k] += v
// 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.HasPrefix(line, "**") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think doube star prefixes are noops, e.g. **/temp isn't rooted, is it?

line = line[2:]
}
if strings.HasSuffix(line, "**") {
line = line[:len(line)-2]
}

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
}
m.fmut.Unlock()
return stats
}

Expand Down