mirror of
https://github.com/octoleo/syncthing.git
synced 2024-11-08 22:31:04 +00:00
Publish more event details
This commit is contained in:
parent
ec212f73eb
commit
f88a7a8e6a
@ -209,7 +209,7 @@ func restGetModel(m *model.Model, w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
res["inSyncFiles"], res["inSyncBytes"] = globalFiles-needFiles, globalBytes-needBytes
|
res["inSyncFiles"], res["inSyncBytes"] = globalFiles-needFiles, globalBytes-needBytes
|
||||||
|
|
||||||
res["state"] = m.State(repo)
|
res["state"], res["stateChanged"] = m.State(repo)
|
||||||
res["version"] = m.LocalVersion(repo)
|
res["version"] = m.LocalVersion(repo)
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
|
@ -163,6 +163,8 @@ func main() {
|
|||||||
|
|
||||||
confDir = expandTilde(confDir)
|
confDir = expandTilde(confDir)
|
||||||
|
|
||||||
|
events.Default.Log(events.Starting, map[string]string{"home": confDir})
|
||||||
|
|
||||||
if _, err := os.Stat(confDir); err != nil && confDir == getDefaultConfDir() {
|
if _, err := os.Stat(confDir); err != nil && confDir == getDefaultConfDir() {
|
||||||
// We are supposed to use the default configuration directory. It
|
// We are supposed to use the default configuration directory. It
|
||||||
// doesn't exist. In the past our default has been ~/.syncthing, so if
|
// doesn't exist. In the past our default has been ~/.syncthing, so if
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/calmh/syncthing/beacon"
|
"github.com/calmh/syncthing/beacon"
|
||||||
|
"github.com/calmh/syncthing/events"
|
||||||
"github.com/calmh/syncthing/protocol"
|
"github.com/calmh/syncthing/protocol"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -256,12 +257,12 @@ func (d *Discoverer) recvAnnouncements() {
|
|||||||
|
|
||||||
var newNode bool
|
var newNode bool
|
||||||
if bytes.Compare(pkt.This.ID, d.myID[:]) != 0 {
|
if bytes.Compare(pkt.This.ID, d.myID[:]) != 0 {
|
||||||
n := d.registerNode(addr, pkt.This)
|
newNode = d.registerNode(addr, pkt.This)
|
||||||
newNode = newNode || n
|
|
||||||
for _, node := range pkt.Extra {
|
for _, node := range pkt.Extra {
|
||||||
if bytes.Compare(node.ID, d.myID[:]) != 0 {
|
if bytes.Compare(node.ID, d.myID[:]) != 0 {
|
||||||
n := d.registerNode(nil, node)
|
if d.registerNode(nil, node) {
|
||||||
newNode = newNode || n
|
newNode = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -302,6 +303,13 @@ func (d *Discoverer) registerNode(addr net.Addr, node Node) bool {
|
|||||||
_, seen := d.registry[id]
|
_, seen := d.registry[id]
|
||||||
d.registry[id] = addrs
|
d.registry[id] = addrs
|
||||||
d.registryLock.Unlock()
|
d.registryLock.Unlock()
|
||||||
|
|
||||||
|
if !seen {
|
||||||
|
events.Default.Log(events.NodeDiscovered, map[string]interface{}{
|
||||||
|
"node": id.String(),
|
||||||
|
"addrs": addrs,
|
||||||
|
})
|
||||||
|
}
|
||||||
return !seen
|
return !seen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,13 +11,16 @@ type EventType uint64
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
Ping = 1 << iota
|
Ping = 1 << iota
|
||||||
|
Starting
|
||||||
StartupComplete
|
StartupComplete
|
||||||
|
NodeDiscovered
|
||||||
NodeConnected
|
NodeConnected
|
||||||
NodeDisconnected
|
NodeDisconnected
|
||||||
LocalIndexUpdated
|
LocalIndexUpdated
|
||||||
RemoteIndexUpdated
|
RemoteIndexUpdated
|
||||||
ItemStarted
|
ItemStarted
|
||||||
ItemCompleted
|
ItemCompleted
|
||||||
|
StateChanged
|
||||||
|
|
||||||
AllEvents = ^EventType(0)
|
AllEvents = ^EventType(0)
|
||||||
)
|
)
|
||||||
@ -26,8 +29,12 @@ func (t EventType) String() string {
|
|||||||
switch t {
|
switch t {
|
||||||
case Ping:
|
case Ping:
|
||||||
return "Ping"
|
return "Ping"
|
||||||
|
case Starting:
|
||||||
|
return "Starting"
|
||||||
case StartupComplete:
|
case StartupComplete:
|
||||||
return "StartupComplete"
|
return "StartupComplete"
|
||||||
|
case NodeDiscovered:
|
||||||
|
return "NodeDiscovered"
|
||||||
case NodeConnected:
|
case NodeConnected:
|
||||||
return "NodeConnected"
|
return "NodeConnected"
|
||||||
case NodeDisconnected:
|
case NodeDisconnected:
|
||||||
@ -38,6 +45,8 @@ func (t EventType) String() string {
|
|||||||
return "RemoteIndexUpdated"
|
return "RemoteIndexUpdated"
|
||||||
case ItemStarted:
|
case ItemStarted:
|
||||||
return "ItemStarted"
|
return "ItemStarted"
|
||||||
|
case StateChanged:
|
||||||
|
return "StateChanged"
|
||||||
default:
|
default:
|
||||||
return "Unknown"
|
return "Unknown"
|
||||||
}
|
}
|
||||||
|
118
model/model.go
118
model/model.go
@ -33,6 +33,21 @@ const (
|
|||||||
RepoCleaning
|
RepoCleaning
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (s repoState) String() string {
|
||||||
|
switch s {
|
||||||
|
case RepoIdle:
|
||||||
|
return "idle"
|
||||||
|
case RepoScanning:
|
||||||
|
return "scanning"
|
||||||
|
case RepoCleaning:
|
||||||
|
return "cleaning"
|
||||||
|
case RepoSyncing:
|
||||||
|
return "syncing"
|
||||||
|
default:
|
||||||
|
return "unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Somewhat arbitrary amount of bytes that we choose to let represent the size
|
// Somewhat arbitrary amount of bytes that we choose to let represent the size
|
||||||
// of an unsynchronized directory entry or a deleted file. We need it to be
|
// of an unsynchronized directory entry or a deleted file. We need it to be
|
||||||
// larger than zero so that it's visible that there is some amount of bytes to
|
// larger than zero so that it's visible that there is some amount of bytes to
|
||||||
@ -57,8 +72,9 @@ type Model struct {
|
|||||||
suppressor map[string]*suppressor // repo -> suppressor
|
suppressor map[string]*suppressor // repo -> suppressor
|
||||||
rmut sync.RWMutex // protects the above
|
rmut sync.RWMutex // protects the above
|
||||||
|
|
||||||
repoState map[string]repoState // repo -> state
|
repoState map[string]repoState // repo -> state
|
||||||
smut sync.RWMutex
|
repoStateChanged map[string]time.Time // repo -> time when state changed
|
||||||
|
smut sync.RWMutex
|
||||||
|
|
||||||
protoConn map[protocol.NodeID]protocol.Connection
|
protoConn map[protocol.NodeID]protocol.Connection
|
||||||
rawConn map[protocol.NodeID]io.Closer
|
rawConn map[protocol.NodeID]io.Closer
|
||||||
@ -84,22 +100,23 @@ var (
|
|||||||
// for file data without altering the local repository in any way.
|
// for file data without altering the local repository in any way.
|
||||||
func NewModel(indexDir string, cfg *config.Configuration, clientName, clientVersion string, db *leveldb.DB) *Model {
|
func NewModel(indexDir string, cfg *config.Configuration, clientName, clientVersion string, db *leveldb.DB) *Model {
|
||||||
m := &Model{
|
m := &Model{
|
||||||
indexDir: indexDir,
|
indexDir: indexDir,
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
db: db,
|
db: db,
|
||||||
clientName: clientName,
|
clientName: clientName,
|
||||||
clientVersion: clientVersion,
|
clientVersion: clientVersion,
|
||||||
repoCfgs: make(map[string]config.RepositoryConfiguration),
|
repoCfgs: make(map[string]config.RepositoryConfiguration),
|
||||||
repoFiles: make(map[string]*files.Set),
|
repoFiles: make(map[string]*files.Set),
|
||||||
repoNodes: make(map[string][]protocol.NodeID),
|
repoNodes: make(map[string][]protocol.NodeID),
|
||||||
nodeRepos: make(map[protocol.NodeID][]string),
|
nodeRepos: make(map[protocol.NodeID][]string),
|
||||||
repoState: make(map[string]repoState),
|
repoState: make(map[string]repoState),
|
||||||
suppressor: make(map[string]*suppressor),
|
repoStateChanged: make(map[string]time.Time),
|
||||||
protoConn: make(map[protocol.NodeID]protocol.Connection),
|
suppressor: make(map[string]*suppressor),
|
||||||
rawConn: make(map[protocol.NodeID]io.Closer),
|
protoConn: make(map[protocol.NodeID]protocol.Connection),
|
||||||
nodeVer: make(map[protocol.NodeID]string),
|
rawConn: make(map[protocol.NodeID]io.Closer),
|
||||||
sentLocalVer: make(map[protocol.NodeID]map[string]uint64),
|
nodeVer: make(map[protocol.NodeID]string),
|
||||||
sup: suppressor{threshold: int64(cfg.Options.MaxChangeKbps)},
|
sentLocalVer: make(map[protocol.NodeID]map[string]uint64),
|
||||||
|
sup: suppressor{threshold: int64(cfg.Options.MaxChangeKbps)},
|
||||||
}
|
}
|
||||||
|
|
||||||
var timeout = 20 * 60 // seconds
|
var timeout = 20 * 60 // seconds
|
||||||
@ -322,16 +339,20 @@ func (m *Model) Index(nodeID protocol.NodeID, repo string, fs []protocol.FileInf
|
|||||||
}
|
}
|
||||||
|
|
||||||
m.rmut.RLock()
|
m.rmut.RLock()
|
||||||
if r, ok := m.repoFiles[repo]; ok {
|
r, ok := m.repoFiles[repo]
|
||||||
|
m.rmut.RUnlock()
|
||||||
|
if ok {
|
||||||
r.Replace(nodeID, fs)
|
r.Replace(nodeID, fs)
|
||||||
} else {
|
} else {
|
||||||
l.Fatalf("Index for nonexistant repo %q", repo)
|
l.Fatalf("Index for nonexistant repo %q", repo)
|
||||||
}
|
}
|
||||||
m.rmut.RUnlock()
|
m.rmut.RUnlock()
|
||||||
|
|
||||||
events.Default.Log(events.RemoteIndexUpdated, map[string]string{
|
events.Default.Log(events.RemoteIndexUpdated, map[string]interface{}{
|
||||||
"node": nodeID.String(),
|
"node": nodeID.String(),
|
||||||
"repo": repo,
|
"repo": repo,
|
||||||
|
"items": len(fs),
|
||||||
|
"version": r.LocalVersion(nodeID),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,16 +369,21 @@ func (m *Model) IndexUpdate(nodeID protocol.NodeID, repo string, fs []protocol.F
|
|||||||
}
|
}
|
||||||
|
|
||||||
m.rmut.RLock()
|
m.rmut.RLock()
|
||||||
if r, ok := m.repoFiles[repo]; ok {
|
r, ok := m.repoFiles[repo]
|
||||||
|
m.rmut.RUnlock()
|
||||||
|
m.rmut.RLock()
|
||||||
|
if ok {
|
||||||
r.Update(nodeID, fs)
|
r.Update(nodeID, fs)
|
||||||
} else {
|
} else {
|
||||||
l.Fatalf("IndexUpdate for nonexistant repo %q", repo)
|
l.Fatalf("IndexUpdate for nonexistant repo %q", repo)
|
||||||
}
|
}
|
||||||
m.rmut.RUnlock()
|
m.rmut.RUnlock()
|
||||||
|
|
||||||
events.Default.Log(events.RemoteIndexUpdated, map[string]string{
|
events.Default.Log(events.RemoteIndexUpdated, map[string]interface{}{
|
||||||
"node": nodeID.String(),
|
"node": nodeID.String(),
|
||||||
"repo": repo,
|
"repo": repo,
|
||||||
|
"items": len(fs),
|
||||||
|
"version": r.LocalVersion(nodeID),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -620,7 +646,13 @@ func (m *Model) updateLocal(repo string, f protocol.FileInfo) {
|
|||||||
m.rmut.RLock()
|
m.rmut.RLock()
|
||||||
m.repoFiles[repo].Update(protocol.LocalNodeID, []protocol.FileInfo{f})
|
m.repoFiles[repo].Update(protocol.LocalNodeID, []protocol.FileInfo{f})
|
||||||
m.rmut.RUnlock()
|
m.rmut.RUnlock()
|
||||||
events.Default.Log(events.LocalIndexUpdated, map[string]string{"repo": repo})
|
events.Default.Log(events.LocalIndexUpdated, map[string]interface{}{
|
||||||
|
"repo": repo,
|
||||||
|
"name": f.Name,
|
||||||
|
"modified": time.Unix(f.Modified, 0),
|
||||||
|
"flags": fmt.Sprintf("0%o", f.Flags),
|
||||||
|
"size": f.Size(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Model) requestGlobal(nodeID protocol.NodeID, repo, name string, offset int64, size int, hash []byte) ([]byte, error) {
|
func (m *Model) requestGlobal(nodeID protocol.NodeID, repo, name string, offset int64, size int, hash []byte) ([]byte, error) {
|
||||||
@ -797,26 +829,30 @@ func (m *Model) clusterConfig(node protocol.NodeID) protocol.ClusterConfigMessag
|
|||||||
|
|
||||||
func (m *Model) setState(repo string, state repoState) {
|
func (m *Model) setState(repo string, state repoState) {
|
||||||
m.smut.Lock()
|
m.smut.Lock()
|
||||||
m.repoState[repo] = state
|
oldState := m.repoState[repo]
|
||||||
|
changed, ok := m.repoStateChanged[repo]
|
||||||
|
if state != oldState {
|
||||||
|
m.repoState[repo] = state
|
||||||
|
m.repoStateChanged[repo] = time.Now()
|
||||||
|
eventData := map[string]interface{}{
|
||||||
|
"repo": repo,
|
||||||
|
"to": state.String(),
|
||||||
|
}
|
||||||
|
if ok {
|
||||||
|
eventData["duration"] = time.Since(changed).Seconds()
|
||||||
|
eventData["from"] = oldState.String()
|
||||||
|
}
|
||||||
|
events.Default.Log(events.StateChanged, eventData)
|
||||||
|
}
|
||||||
m.smut.Unlock()
|
m.smut.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Model) State(repo string) string {
|
func (m *Model) State(repo string) (string, time.Time) {
|
||||||
m.smut.RLock()
|
m.smut.RLock()
|
||||||
state := m.repoState[repo]
|
state := m.repoState[repo]
|
||||||
|
changed := m.repoStateChanged[repo]
|
||||||
m.smut.RUnlock()
|
m.smut.RUnlock()
|
||||||
switch state {
|
return state.String(), changed
|
||||||
case RepoIdle:
|
|
||||||
return "idle"
|
|
||||||
case RepoScanning:
|
|
||||||
return "scanning"
|
|
||||||
case RepoCleaning:
|
|
||||||
return "cleaning"
|
|
||||||
case RepoSyncing:
|
|
||||||
return "syncing"
|
|
||||||
default:
|
|
||||||
return "unknown"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Model) Override(repo string) {
|
func (m *Model) Override(repo string) {
|
||||||
|
Loading…
Reference in New Issue
Block a user