mirror of
https://github.com/octoleo/syncthing.git
synced 2025-02-02 11:58:28 +00:00
parent
92533dd9f0
commit
c7d6a6d780
@ -604,14 +604,6 @@
|
|||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<th><span class="fas fa-fw fa-microchip"></span> <span translate>RAM Utilization</span></th>
|
|
||||||
<td class="text-right">{{system.sys | binary}}B</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th><span class="fas fa-fw fa-tachometer-alt"></span> <span translate>CPU Utilization</span></th>
|
|
||||||
<td class="text-right">{{system.cpuPercent | alwaysNumber | percent}}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<th><span class="fas fa-fw fa-sitemap"></span> <span translate>Listeners</span></th>
|
<th><span class="fas fa-fw fa-sitemap"></span> <span translate>Listeners</span></th>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
|
@ -81,7 +81,6 @@ type service struct {
|
|||||||
fss model.FolderSummaryService
|
fss model.FolderSummaryService
|
||||||
urService *ur.Service
|
urService *ur.Service
|
||||||
systemConfigMut sync.Mutex // serializes posts to /rest/system/config
|
systemConfigMut sync.Mutex // serializes posts to /rest/system/config
|
||||||
cpu Rater
|
|
||||||
contr Controller
|
contr Controller
|
||||||
noUpgrade bool
|
noUpgrade bool
|
||||||
tlsDefaultCommonName string
|
tlsDefaultCommonName string
|
||||||
@ -95,10 +94,6 @@ type service struct {
|
|||||||
systemLog logger.Recorder
|
systemLog logger.Recorder
|
||||||
}
|
}
|
||||||
|
|
||||||
type Rater interface {
|
|
||||||
Rate() float64
|
|
||||||
}
|
|
||||||
|
|
||||||
type Controller interface {
|
type Controller interface {
|
||||||
ExitUpgrading()
|
ExitUpgrading()
|
||||||
Restart()
|
Restart()
|
||||||
@ -111,7 +106,7 @@ type Service interface {
|
|||||||
WaitForStart() error
|
WaitForStart() error
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(id protocol.DeviceID, cfg config.Wrapper, assetDir, tlsDefaultCommonName string, m model.Model, defaultSub, diskSub events.BufferedSubscription, evLogger events.Logger, discoverer discover.CachingMux, connectionsService connections.Service, urService *ur.Service, fss model.FolderSummaryService, errors, systemLog logger.Recorder, cpu Rater, contr Controller, noUpgrade bool) Service {
|
func New(id protocol.DeviceID, cfg config.Wrapper, assetDir, tlsDefaultCommonName string, m model.Model, defaultSub, diskSub events.BufferedSubscription, evLogger events.Logger, discoverer discover.CachingMux, connectionsService connections.Service, urService *ur.Service, fss model.FolderSummaryService, errors, systemLog logger.Recorder, contr Controller, noUpgrade bool) Service {
|
||||||
s := &service{
|
s := &service{
|
||||||
id: id,
|
id: id,
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
@ -130,7 +125,6 @@ func New(id protocol.DeviceID, cfg config.Wrapper, assetDir, tlsDefaultCommonNam
|
|||||||
systemConfigMut: sync.NewMutex(),
|
systemConfigMut: sync.NewMutex(),
|
||||||
guiErrors: errors,
|
guiErrors: errors,
|
||||||
systemLog: systemLog,
|
systemLog: systemLog,
|
||||||
cpu: cpu,
|
|
||||||
contr: contr,
|
contr: contr,
|
||||||
noUpgrade: noUpgrade,
|
noUpgrade: noUpgrade,
|
||||||
tlsDefaultCommonName: tlsDefaultCommonName,
|
tlsDefaultCommonName: tlsDefaultCommonName,
|
||||||
@ -951,9 +945,7 @@ func (s *service) getSystemStatus(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
res["connectionServiceStatus"] = s.connectionsService.ListenerStatus()
|
res["connectionServiceStatus"] = s.connectionsService.ListenerStatus()
|
||||||
res["lastDialStatus"] = s.connectionsService.ConnectionStatus()
|
res["lastDialStatus"] = s.connectionsService.ConnectionStatus()
|
||||||
// cpuUsage.Rate() is in milliseconds per second, so dividing by ten
|
res["cpuPercent"] = 0 // deprecated from API
|
||||||
// gives us percent
|
|
||||||
res["cpuPercent"] = s.cpu.Rate() / 10 / float64(runtime.NumCPU())
|
|
||||||
res["pathSeparator"] = string(filepath.Separator)
|
res["pathSeparator"] = string(filepath.Separator)
|
||||||
res["urVersionMax"] = ur.Version
|
res["urVersionMax"] = ur.Version
|
||||||
res["uptime"] = s.urService.UptimeS()
|
res["uptime"] = s.urService.UptimeS()
|
||||||
|
@ -107,7 +107,7 @@ func TestStopAfterBrokenConfig(t *testing.T) {
|
|||||||
}
|
}
|
||||||
w := config.Wrap("/dev/null", cfg, events.NoopLogger)
|
w := config.Wrap("/dev/null", cfg, events.NoopLogger)
|
||||||
|
|
||||||
srv := New(protocol.LocalDeviceID, w, "", "syncthing", nil, nil, nil, events.NoopLogger, nil, nil, nil, nil, nil, nil, nil, nil, false).(*service)
|
srv := New(protocol.LocalDeviceID, w, "", "syncthing", nil, nil, nil, events.NoopLogger, nil, nil, nil, nil, nil, nil, nil, false).(*service)
|
||||||
defer os.Remove(token)
|
defer os.Remove(token)
|
||||||
srv.started = make(chan string)
|
srv.started = make(chan string)
|
||||||
|
|
||||||
@ -522,12 +522,11 @@ func startHTTP(cfg *mockedConfig) (string, *suture.Supervisor, error) {
|
|||||||
connections := new(mockedConnections)
|
connections := new(mockedConnections)
|
||||||
errorLog := new(mockedLoggerRecorder)
|
errorLog := new(mockedLoggerRecorder)
|
||||||
systemLog := new(mockedLoggerRecorder)
|
systemLog := new(mockedLoggerRecorder)
|
||||||
cpu := new(mockedCPUService)
|
|
||||||
addrChan := make(chan string)
|
addrChan := make(chan string)
|
||||||
|
|
||||||
// Instantiate the API service
|
// Instantiate the API service
|
||||||
urService := ur.New(cfg, m, connections, false)
|
urService := ur.New(cfg, m, connections, false)
|
||||||
svc := New(protocol.LocalDeviceID, cfg, assetDir, "syncthing", m, eventSub, diskEventSub, events.NoopLogger, discoverer, connections, urService, &mockedFolderSummaryService{}, errorLog, systemLog, cpu, nil, false).(*service)
|
svc := New(protocol.LocalDeviceID, cfg, assetDir, "syncthing", m, eventSub, diskEventSub, events.NoopLogger, discoverer, connections, urService, &mockedFolderSummaryService{}, errorLog, systemLog, nil, false).(*service)
|
||||||
defer os.Remove(token)
|
defer os.Remove(token)
|
||||||
svc.started = addrChan
|
svc.started = addrChan
|
||||||
|
|
||||||
@ -1026,7 +1025,7 @@ func TestEventMasks(t *testing.T) {
|
|||||||
cfg := new(mockedConfig)
|
cfg := new(mockedConfig)
|
||||||
defSub := new(mockedEventSub)
|
defSub := new(mockedEventSub)
|
||||||
diskSub := new(mockedEventSub)
|
diskSub := new(mockedEventSub)
|
||||||
svc := New(protocol.LocalDeviceID, cfg, "", "syncthing", nil, defSub, diskSub, events.NoopLogger, nil, nil, nil, nil, nil, nil, nil, nil, false).(*service)
|
svc := New(protocol.LocalDeviceID, cfg, "", "syncthing", nil, defSub, diskSub, events.NoopLogger, nil, nil, nil, nil, nil, nil, nil, false).(*service)
|
||||||
defer os.Remove(token)
|
defer os.Remove(token)
|
||||||
|
|
||||||
if mask := svc.getEventMask(""); mask != DefaultEventMask {
|
if mask := svc.getEventMask(""); mask != DefaultEventMask {
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
// Copyright (C) 2017 The Syncthing Authors.
|
|
||||||
//
|
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
||||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
||||||
|
|
||||||
package api
|
|
||||||
|
|
||||||
type mockedCPUService struct{}
|
|
||||||
|
|
||||||
func (*mockedCPUService) Rate() float64 {
|
|
||||||
return 42
|
|
||||||
}
|
|
@ -612,7 +612,6 @@ func (p *Process) Connections() (map[string]ConnectionStats, error) {
|
|||||||
|
|
||||||
type SystemStatus struct {
|
type SystemStatus struct {
|
||||||
Alloc int64
|
Alloc int64
|
||||||
CPUPercent float64
|
|
||||||
Goroutines int
|
Goroutines int
|
||||||
MyID protocol.DeviceID
|
MyID protocol.DeviceID
|
||||||
PathSeparator string
|
PathSeparator string
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
// Copyright (C) 2017 The Syncthing Authors.
|
|
||||||
//
|
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
||||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
||||||
|
|
||||||
package syncthing
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
metrics "github.com/rcrowley/go-metrics"
|
|
||||||
)
|
|
||||||
|
|
||||||
const cpuTickRate = 5 * time.Second
|
|
||||||
|
|
||||||
type cpuService struct {
|
|
||||||
avg metrics.EWMA
|
|
||||||
stop chan struct{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newCPUService() *cpuService {
|
|
||||||
return &cpuService{
|
|
||||||
// 10 second average. Magic alpha value comes from looking at EWMA package
|
|
||||||
// definitions of EWMA1, EWMA5. The tick rate *must* be five seconds (hard
|
|
||||||
// coded in the EWMA package).
|
|
||||||
avg: metrics.NewEWMA(1 - math.Exp(-float64(cpuTickRate)/float64(time.Second)/10.0)),
|
|
||||||
stop: make(chan struct{}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *cpuService) Serve() {
|
|
||||||
// Initialize prevUsage to an actual value returned by cpuUsage
|
|
||||||
// instead of zero, because at least Windows returns a huge negative
|
|
||||||
// number here that then slowly increments...
|
|
||||||
prevUsage := cpuUsage()
|
|
||||||
ticker := time.NewTicker(cpuTickRate)
|
|
||||||
defer ticker.Stop()
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-ticker.C:
|
|
||||||
curUsage := cpuUsage()
|
|
||||||
s.avg.Update(int64((curUsage - prevUsage) / time.Millisecond))
|
|
||||||
prevUsage = curUsage
|
|
||||||
s.avg.Tick()
|
|
||||||
case <-s.stop:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *cpuService) Stop() {
|
|
||||||
close(s.stop)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *cpuService) Rate() float64 {
|
|
||||||
return s.avg.Rate()
|
|
||||||
}
|
|
@ -1,78 +0,0 @@
|
|||||||
// Copyright (C) 2014 The Syncthing Authors.
|
|
||||||
//
|
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
||||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
||||||
|
|
||||||
//+build solaris
|
|
||||||
|
|
||||||
package syncthing
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type id_t int32
|
|
||||||
type ulong_t uint32
|
|
||||||
|
|
||||||
type timestruc_t struct {
|
|
||||||
Tv_sec int64
|
|
||||||
Tv_nsec int64
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tv timestruc_t) Nano() int64 {
|
|
||||||
return tv.Tv_sec*1e9 + tv.Tv_nsec
|
|
||||||
}
|
|
||||||
|
|
||||||
type prusage_t struct {
|
|
||||||
Pr_lwpid id_t /* lwp id. 0: process or defunct */
|
|
||||||
Pr_count int32 /* number of contributing lwps */
|
|
||||||
Pr_tstamp timestruc_t /* real time stamp, time of read() */
|
|
||||||
Pr_create timestruc_t /* process/lwp creation time stamp */
|
|
||||||
Pr_term timestruc_t /* process/lwp termination time stamp */
|
|
||||||
Pr_rtime timestruc_t /* total lwp real (elapsed) time */
|
|
||||||
Pr_utime timestruc_t /* user level CPU time */
|
|
||||||
Pr_stime timestruc_t /* system call CPU time */
|
|
||||||
Pr_ttime timestruc_t /* other system trap CPU time */
|
|
||||||
Pr_tftime timestruc_t /* text page fault sleep time */
|
|
||||||
Pr_dftime timestruc_t /* data page fault sleep time */
|
|
||||||
Pr_kftime timestruc_t /* kernel page fault sleep time */
|
|
||||||
Pr_ltime timestruc_t /* user lock wait sleep time */
|
|
||||||
Pr_slptime timestruc_t /* all other sleep time */
|
|
||||||
Pr_wtime timestruc_t /* wait-cpu (latency) time */
|
|
||||||
Pr_stoptime timestruc_t /* stopped time */
|
|
||||||
Pr_minf ulong_t /* minor page faults */
|
|
||||||
Pr_majf ulong_t /* major page faults */
|
|
||||||
Pr_nswap ulong_t /* swaps */
|
|
||||||
Pr_inblk ulong_t /* input blocks */
|
|
||||||
Pr_oublk ulong_t /* output blocks */
|
|
||||||
Pr_msnd ulong_t /* messages sent */
|
|
||||||
Pr_mrcv ulong_t /* messages received */
|
|
||||||
Pr_sigs ulong_t /* signals received */
|
|
||||||
Pr_vctx ulong_t /* voluntary context switches */
|
|
||||||
Pr_ictx ulong_t /* involuntary context switches */
|
|
||||||
Pr_sysc ulong_t /* system calls */
|
|
||||||
Pr_ioch ulong_t /* chars read and written */
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
var procFile = fmt.Sprintf("/proc/%d/usage", os.Getpid())
|
|
||||||
|
|
||||||
func cpuUsage() time.Duration {
|
|
||||||
fd, err := os.Open(procFile)
|
|
||||||
if err != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
var rusage prusage_t
|
|
||||||
err = binary.Read(fd, binary.LittleEndian, rusage)
|
|
||||||
fd.Close()
|
|
||||||
if err != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return time.Duration(rusage.Pr_utime.Nano() + rusage.Pr_stime.Nano())
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
// Copyright (C) 2014 The Syncthing Authors.
|
|
||||||
//
|
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
||||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
||||||
|
|
||||||
//+build !windows,!solaris
|
|
||||||
|
|
||||||
package syncthing
|
|
||||||
|
|
||||||
import "syscall"
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
func cpuUsage() time.Duration {
|
|
||||||
var rusage syscall.Rusage
|
|
||||||
syscall.Getrusage(syscall.RUSAGE_SELF, &rusage)
|
|
||||||
return time.Duration(rusage.Utime.Nano() + rusage.Stime.Nano())
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
// Copyright (C) 2014 The Syncthing Authors.
|
|
||||||
//
|
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
||||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
||||||
|
|
||||||
//+build windows
|
|
||||||
|
|
||||||
package syncthing
|
|
||||||
|
|
||||||
import "syscall"
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
func cpuUsage() time.Duration {
|
|
||||||
handle, err := syscall.GetCurrentProcess()
|
|
||||||
if err != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
defer syscall.CloseHandle(handle)
|
|
||||||
|
|
||||||
var ctime, etime, ktime, utime syscall.Filetime
|
|
||||||
if err := syscall.GetProcessTimes(handle, &ctime, &etime, &ktime, &utime); err != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return time.Duration(ktime.Nanoseconds() + utime.Nanoseconds())
|
|
||||||
}
|
|
@ -420,13 +420,10 @@ func (a *App) setupGUI(m model.Model, defaultSub, diskSub events.BufferedSubscri
|
|||||||
l.Warnln("Insecure admin access is enabled.")
|
l.Warnln("Insecure admin access is enabled.")
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu := newCPUService()
|
|
||||||
a.mainService.Add(cpu)
|
|
||||||
|
|
||||||
summaryService := model.NewFolderSummaryService(a.cfg, m, a.myID, a.evLogger)
|
summaryService := model.NewFolderSummaryService(a.cfg, m, a.myID, a.evLogger)
|
||||||
a.mainService.Add(summaryService)
|
a.mainService.Add(summaryService)
|
||||||
|
|
||||||
apiSvc := api.New(a.myID, a.cfg, a.opts.AssetDir, tlsDefaultCommonName, m, defaultSub, diskSub, a.evLogger, discoverer, connectionsService, urService, summaryService, errors, systemLog, cpu, &controller{a}, a.opts.NoUpgrade)
|
apiSvc := api.New(a.myID, a.cfg, a.opts.AssetDir, tlsDefaultCommonName, m, defaultSub, diskSub, a.evLogger, discoverer, connectionsService, urService, summaryService, errors, systemLog, &controller{a}, a.opts.NoUpgrade)
|
||||||
a.mainService.Add(apiSvc)
|
a.mainService.Add(apiSvc)
|
||||||
|
|
||||||
if err := apiSvc.WaitForStart(); err != nil {
|
if err := apiSvc.WaitForStart(); err != nil {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user