cmd/syncthing: Expand usage stats even more (ref #3628)

Also add diffing functionality

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4422
This commit is contained in:
Audrius Butkevicius 2017-10-15 07:45:15 +00:00 committed by Jakob Borg
parent 1e9e9cbebb
commit 059185b325
3 changed files with 151 additions and 6 deletions

View File

@ -12,6 +12,7 @@ import (
"crypto/rand"
"crypto/tls"
"encoding/json"
"net"
"net/http"
"runtime"
"sort"
@ -183,6 +184,124 @@ func reportData(cfg configIntf, m modelIntf, connectionsService connectionsIntf,
if version >= 3 {
res["uptime"] = int(time.Now().Sub(startTime).Seconds())
res["natType"] = connectionsService.NATType()
res["alwaysLocalNets"] = len(opts.AlwaysLocalNets) > 0
res["cacheIgnoredFiles"] = opts.CacheIgnoredFiles
res["overwriteRemoteDeviceNames"] = opts.OverwriteRemoteDevNames
res["progressEmitterEnabled"] = opts.ProgressUpdateIntervalS > -1
res["customDefaultFolderPath"] = opts.DefaultFolderPath != "~"
res["weakHashSelection"] = opts.WeakHashSelectionMethod.String()
res["customTrafficClass"] = opts.TrafficClass != 0
res["customTempIndexMinBlocks"] = opts.TempIndexMinBlocks != 10
res["temporariesDisabled"] = opts.KeepTemporariesH == 0
res["temporariesCustom"] = opts.KeepTemporariesH != 24
res["limitBandwidthInLan"] = opts.LimitBandwidthInLan
res["customReleaseURL"] = opts.ReleasesURL != "https://upgrades.syncthing.net/meta.json"
res["restartOnWakeup"] = opts.RestartOnWakeup
res["customStunServers"] = len(opts.StunServers) == 0 || opts.StunServers[0] != "default" || len(opts.StunServers) > 1
folderUsesV3 := map[string]int{
"scanProgressDisabled": 0,
"conflictsDisabled": 0,
"conflictsUnlimited": 0,
"conflictsOther": 0,
"disableSparseFiles": 0,
"disableTempIndexes": 0,
"alwaysWeakHash": 0,
"customWeakHashThreshold": 0,
}
pullOrder := make(map[string]int)
filesystemType := make(map[string]int)
for _, cfg := range cfg.Folders() {
if cfg.ScanProgressIntervalS < 0 {
folderUsesV3["scanProgressDisabled"]++
}
if cfg.MaxConflicts == 0 {
folderUsesV3["conflictsDisabled"]++
} else if cfg.MaxConflicts < 0 {
folderUsesV3["conflictsUnlimited"]++
} else {
folderUsesV3["conflictsOther"]++
}
if cfg.DisableSparseFiles {
folderUsesV3["disableSparseFiles"]++
}
if cfg.DisableTempIndexes {
folderUsesV3["disableTempIndexes"]++
}
if cfg.WeakHashThresholdPct < 0 {
folderUsesV3["alwaysWeakHash"]++
} else if cfg.WeakHashThresholdPct != 25 {
folderUsesV3["customWeakHashThreshold"]++
}
pullOrder[cfg.Order.String()]++
filesystemType[cfg.FilesystemType.String()]++
}
folderUsesV3Interface := map[string]interface{}{
"pullOrder": pullOrder,
"filesystemType": filesystemType,
}
for key, value := range folderUsesV3 {
folderUsesV3Interface[key] = value
}
res["folderUsesV3"] = folderUsesV3Interface
guiCfg := cfg.GUI()
// Anticipate multiple GUI configs in the future, hence store counts.
guiStats := map[string]int{
"enabled": 0,
"useTLS": 0,
"useAuth": 0,
"useAPIKey": 0,
"insecureAdminAccess": 0,
"debugging": 0,
"insecureSkipHostCheck": 0,
"insecureAllowFrameLoading": 0,
"listenLocal": 0,
"listenUnspecified": 0,
}
theme := make(map[string]int)
if guiCfg.Enabled {
guiStats["enabled"]++
if guiCfg.UseTLS() {
guiStats["useTLS"]++
}
if len(guiCfg.User) > 0 && len(guiCfg.Password) > 0 {
guiStats["useAuth"]++
}
if len(guiCfg.APIKey) > 0 {
guiStats["useAPIKey"]++
}
if guiCfg.InsecureAdminAccess {
guiStats["insecureAdminAccess"]++
}
if guiCfg.Debugging {
guiStats["debugging"]++
}
if guiCfg.InsecureSkipHostCheck {
guiStats["insecureSkipHostCheck"]++
}
if guiCfg.InsecureAllowFrameLoading {
guiStats["insecureAllowFrameLoading"]++
}
addr, err := net.ResolveTCPAddr("tcp", guiCfg.Address())
if err == nil {
if addr.IP.IsLoopback() {
guiStats["listenLocal"]++
} else if addr.IP.IsUnspecified() {
guiStats["listenUnspecified"]++
}
}
theme[guiCfg.Theme]++
}
guiStatsInterface := map[string]interface{}{
"theme": theme,
}
for key, value := range guiStats {
guiStatsInterface[key] = value
}
res["guiStats"] = guiStatsInterface
}
for key, value := range m.UsageReportingStats(version) {

View File

@ -2,7 +2,7 @@ angular.module('syncthing.core')
.config(function($locationProvider) {
$locationProvider.html5Mode({enabled: true, requireBase: false}).hashPrefix('!');
})
.controller('SyncthingController', function ($scope, $http, $location, LocaleService, Events, $filter) {
.controller('SyncthingController', function ($scope, $http, $location, LocaleService, Events, $filter, $q) {
'use strict';
// private/helper definitions
@ -33,8 +33,9 @@ angular.module('syncthing.core')
$scope.folderRejections = {};
$scope.protocolChanged = false;
$scope.reportData = {};
$scope.reportDataPreview = {};
$scope.reportDataPreview = '';
$scope.reportDataPreviewVersion = '';
$scope.reportDataPreviewDiff = false;
$scope.reportPreview = false;
$scope.folders = {};
$scope.seenError = '';
@ -135,7 +136,7 @@ angular.module('syncthing.core')
}).error($scope.emitHTTPError);
$http.get(urlbase + '/svc/report').success(function (data) {
$scope.reportDataPreview = $scope.reportData = data;
$scope.reportData = data;
if ($scope.system && $scope.config.options.urSeen < $scope.system.urVersionMax) {
// Usage reporting format has changed, prompt the user to re-accept.
$('#ur').modal();
@ -1769,9 +1770,27 @@ angular.module('syncthing.core')
$scope.refreshReportDataPreview = function () {
$scope.reportDataPreview = '';
$http.get(urlbase + '/svc/report?version=' + $scope.reportDataPreviewVersion).success(function (data) {
$scope.reportDataPreview = data;
}).error($scope.emitHTTPError);
if (!$scope.reportDataPreviewVersion) {
return;
}
var version = parseInt($scope.reportDataPreviewVersion);
if ($scope.reportDataPreviewDiff && version > 2) {
$q.all([
$http.get(urlbase + '/svc/report?version=' + version),
$http.get(urlbase + '/svc/report?version=' + (version-1)),
]).then(function (responses) {
var newReport = responses[0].data;
var oldReport = responses[1].data;
angular.forEach(oldReport, function(_, key) {
delete newReport[key];
});
$scope.reportDataPreview = newReport;
});
} else {
$http.get(urlbase + '/svc/report?version=' + version).success(function (data) {
$scope.reportDataPreview = data;
}).error($scope.emitHTTPError);
}
};
$scope.rescanAllFolders = function () {

View File

@ -7,8 +7,15 @@
<p><a href="https://data.syncthing.net/" target="_blank">https://data.syncthing.net/</a></p>
<label translate>Version</label>
<select id="urPreviewVersion" class="form-control" ng-model="$parent.$parent.reportDataPreviewVersion" ng-change="refreshReportDataPreview()" >
<option selected value>Select a version</option>
<option ng-repeat="n in urVersions()" value="{{n}}">Version {{n}}</option>
</select>
<div class="checkbox" ng-if="$parent.$parent.reportDataPreviewVersion > 2">
<label>
<input type="checkbox" ng-model="$parent.$parent.$parent.reportDataPreviewDiff" ng-change="refreshReportDataPreview()"/>
<span translate>Show diff with previous version</span>
</label>
</div>
<hr>
<form>
<textarea class="form-control" rows="20" ng-if="reportDataPreview">{{reportDataPreview | json}}</textarea>