Skip to content

Commit 6c89a2e

Browse files
authored
Track a few anonymous metrics to measure Dgraph adoption (#2554)
- Assign a unique Cluster ID to each Dgraph cluster. - Track the size of cluster, i.e. number of Zero, Alpha nodes, groups, tablets, total size of tablets, OS, architecture and Dgraph version. None of this has any uniquely identifying information, just generic anonymous stats which can be aggregated to get a sense of Dgraph's adoption curve.
1 parent fe83c75 commit 6c89a2e

File tree

7 files changed

+452
-195
lines changed

7 files changed

+452
-195
lines changed

dgraph/cmd/zero/raft.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import (
2222
"github.com/dgraph-io/dgraph/conn"
2323
"github.com/dgraph-io/dgraph/protos/intern"
2424
"github.com/dgraph-io/dgraph/x"
25+
"github.com/golang/glog"
26+
"github.com/google/uuid"
2527
"golang.org/x/net/context"
2628
"golang.org/x/net/trace"
2729
)
@@ -178,6 +180,12 @@ func (n *node) applyProposal(e raftpb.Entry) (string, error) {
178180

179181
state := n.server.state
180182
state.Counter = e.Index
183+
if len(p.Cid) > 0 {
184+
if len(state.Cid) > 0 {
185+
return p.Key, errInvalidProposal
186+
}
187+
state.Cid = p.Cid
188+
}
181189
if p.MaxRaftId > 0 {
182190
if p.MaxRaftId <= state.MaxRaftId {
183191
return p.Key, errInvalidProposal
@@ -411,6 +419,23 @@ func (n *node) initAndStartNode() error {
411419
x.Check(err)
412420
peers := []raft.Peer{{ID: n.Id, Context: data}}
413421
n.SetRaft(raft.StartNode(n.Cfg, peers))
422+
423+
go func() {
424+
// This is a new cluster. So, propose a new ID for the cluster.
425+
for {
426+
id := uuid.New().String()
427+
err := n.proposeAndWait(context.Background(), &intern.ZeroProposal{Cid: id})
428+
if err == nil {
429+
glog.Infof("CID set for cluster: %v", id)
430+
return
431+
}
432+
if err == errInvalidProposal {
433+
return
434+
}
435+
glog.Errorf("While proposing CID: %v. Retrying...", err)
436+
time.Sleep(3 * time.Second)
437+
}
438+
}()
414439
}
415440

416441
go n.Run()

dgraph/cmd/zero/run.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ instances to achieve high-availability.
7272
flag.String("peer", "", "Address of another dgraphzero server.")
7373
flag.StringP("wal", "w", "zw", "Directory storing WAL.")
7474
flag.Duration("rebalance_interval", 8*time.Minute, "Interval for trying a predicate move.")
75+
flag.Bool("telemetry", true, "Send anonymous telemetry data to Dgraph devs.")
7576
}
7677

7778
func setupListener(addr string, port int, kind string) (listener net.Listener, err error) {
@@ -196,6 +197,10 @@ func run() {
196197
// This must be here. It does not work if placed before Grpc init.
197198
x.Check(st.node.initAndStartNode())
198199

200+
if Zero.Conf.GetBool("telemetry") {
201+
go st.zero.periodicallyPostTelemetry()
202+
}
203+
199204
sdCh := make(chan os.Signal, 1)
200205
signal.Notify(sdCh, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
201206

dgraph/cmd/zero/telemetry.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Copyright 2018 Dgraph Labs, Inc.
3+
*
4+
* This file is available under the Apache License, Version 2.0,
5+
* with the Commons Clause restriction.
6+
*/
7+
8+
package zero
9+
10+
import (
11+
"bytes"
12+
"encoding/json"
13+
"io/ioutil"
14+
"net/http"
15+
"runtime"
16+
17+
"github.com/dgraph-io/dgraph/protos/intern"
18+
"github.com/dgraph-io/dgraph/x"
19+
"github.com/golang/glog"
20+
)
21+
22+
type Telemetry struct {
23+
Arch string
24+
Cid string
25+
ClusterSize int
26+
DiskUsageMB int64
27+
NumAlphas int
28+
NumGroups int
29+
NumTablets int
30+
NumZeros int
31+
OS string
32+
SinceHours int
33+
Version string
34+
}
35+
36+
var keenUrl = "https://api.keen.io/3.0/projects/5b809dfac9e77c0001783ad0/events"
37+
38+
func newTelemetry(ms *intern.MembershipState) *Telemetry {
39+
if len(ms.Cid) == 0 {
40+
glog.V(2).Infoln("No CID found yet")
41+
return nil
42+
}
43+
t := &Telemetry{
44+
Cid: ms.Cid,
45+
NumGroups: len(ms.GetGroups()),
46+
NumZeros: len(ms.GetZeros()),
47+
Version: x.Version(),
48+
OS: runtime.GOOS,
49+
Arch: runtime.GOARCH,
50+
}
51+
for _, g := range ms.GetGroups() {
52+
t.NumAlphas += len(g.GetMembers())
53+
for _, tablet := range g.GetTablets() {
54+
t.NumTablets++
55+
t.DiskUsageMB += tablet.GetSpace()
56+
}
57+
}
58+
t.DiskUsageMB /= (1 << 20)
59+
t.ClusterSize = t.NumAlphas + t.NumZeros
60+
glog.V(2).Infof("Posting Telemetry data: %+v", t)
61+
return t
62+
}
63+
64+
func (t *Telemetry) post() error {
65+
data, err := json.Marshal(t)
66+
if err != nil {
67+
return err
68+
}
69+
url := keenUrl + "/dev"
70+
if len(t.Version) > 0 {
71+
url = keenUrl + "/pings"
72+
}
73+
req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
74+
if err != nil {
75+
return err
76+
}
77+
req.Header.Set("Content-Type", "application/json")
78+
req.Header.Set("Authorization", "D0398E8C83BB30F67C519FDA6175975F680921890C35B36C34BE109544597497CA758881BD7D56CC2355A2F36B4560102CBC3279AC7B27E5391372C36A31167EB0D06BF3764894AD20A0554BAFF14C292A40BC252BB9FF008736A0FD1D44E085")
79+
80+
client := &http.Client{}
81+
resp, err := client.Do(req)
82+
if err != nil {
83+
return err
84+
}
85+
86+
defer resp.Body.Close()
87+
body, err := ioutil.ReadAll(resp.Body)
88+
if err != nil {
89+
return err
90+
}
91+
glog.V(2).Infof("Telemetry response status: %v", resp.Status)
92+
glog.V(2).Infof("Telemetry response body: %s", body)
93+
return nil
94+
}

dgraph/cmd/zero/zero.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"github.com/dgraph-io/dgraph/protos/intern"
2020
"github.com/dgraph-io/dgraph/x"
2121
"github.com/gogo/protobuf/proto"
22+
"github.com/golang/glog"
2223
)
2324

2425
var (
@@ -74,6 +75,37 @@ func (s *Server) Init() {
7475
go s.purgeOracle()
7576
}
7677

78+
func (s *Server) periodicallyPostTelemetry() {
79+
glog.V(2).Infof("Starting telemetry data collection...")
80+
start := time.Now()
81+
82+
ticker := time.NewTicker(time.Minute)
83+
defer ticker.Stop()
84+
85+
var lastPostedAt time.Time
86+
for range ticker.C {
87+
if !s.Node.AmLeader() {
88+
continue
89+
}
90+
if time.Since(lastPostedAt) < time.Hour {
91+
continue
92+
}
93+
ms := s.membershipState()
94+
t := newTelemetry(ms)
95+
if t == nil {
96+
continue
97+
}
98+
t.SinceHours = int(time.Since(start).Hours())
99+
glog.V(2).Infof("Posting Telemetry data: %+v", t)
100+
101+
err := t.post()
102+
glog.V(2).Infof("Telemetry data posted with error: %v", err)
103+
if err == nil {
104+
lastPostedAt = time.Now()
105+
}
106+
}
107+
}
108+
77109
func (s *Server) triggerLeaderChange() {
78110
s.Lock()
79111
defer s.Unlock()

dgraph/docker-compose.yml

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
version: "3.5"
66
services:
77
zero1:
8-
image: debian:latest
8+
image: dgraph/dgraph:latest
99
container_name: bank-dg0.1
1010
working_dir: /data/dg0.1
1111
ports:
1212
- 5080:5080
1313
- 6080:6080
14-
command: /gobin/dgraph zero --my=zero1:5080 --replicas 3 --idx 1 --bindall --expose_trace --profile_mode block --block_rate 10
14+
command: /gobin/dgraph zero --my=zero1:5080 --replicas 3 --idx 1 --bindall --expose_trace --profile_mode block --block_rate 10 --logtostderr -v=2
1515
volumes:
1616
- type: bind
1717
source: $GOPATH/bin
@@ -22,7 +22,7 @@ services:
2222
# target: /data
2323

2424
zero2:
25-
image: debian:latest
25+
image: dgraph/dgraph:latest
2626
container_name: bank-dg0.2
2727
command: /gobin/dgraph zero -o 2 --my=zero2:5082 --replicas 3 --peer=zero1:5080 --idx 2
2828
ports:
@@ -35,7 +35,7 @@ services:
3535
read_only: true
3636

3737
zero3:
38-
image: debian:latest
38+
image: dgraph/dgraph:latest
3939
container_name: bank-dg0.3
4040
command: /gobin/dgraph zero -o 3 --my=zero3:5083 --replicas 3 --peer=zero1:5080 --idx 3
4141
ports:
@@ -49,6 +49,7 @@ services:
4949

5050
# zero4:
5151
# image: debian:latest
52+
# image: dgraph/dgraph:latest
5253
# container_name: bank-dg0.4
5354
# command: /gobin/dgraph zero --my=zero4:5080 --replicas 3 --peer=zero1:5080 --idx 4
5455
# volumes:
@@ -59,6 +60,7 @@ services:
5960

6061
# zero5:
6162
# image: debian:latest
63+
# image: dgraph/dgraph:latest
6264
# container_name: bank-dg0.5
6365
# command: /gobin/dgraph zero --my=zero5:5080 --replicas 3 --peer=zero1:5080 --idx 5
6466
# volumes:
@@ -68,7 +70,7 @@ services:
6870
# read_only: true
6971

7072
dg1:
71-
image: debian:latest
73+
image: dgraph/dgraph:latest
7274
container_name: bank-dg1
7375
working_dir: /data/dg1
7476
volumes:
@@ -85,7 +87,7 @@ services:
8587
command: /gobin/dgraph server --my=dg1:7180 --lru_mb=1024 --zero=zero1:5080 -o 100 --expose_trace --trace 1.0 --profile_mode block --block_rate 10
8688

8789
dg2:
88-
image: debian:latest
90+
image: dgraph/dgraph:latest
8991
container_name: bank-dg2
9092
working_dir: /data/dg2
9193
volumes:
@@ -102,7 +104,7 @@ services:
102104
command: /gobin/dgraph server --my=dg2:7182 --lru_mb=1024 --zero=zero1:5080 -o 102 --expose_trace --trace 1.0 --profile_mode block --block_rate 10
103105

104106
dg3:
105-
image: debian:latest
107+
image: dgraph/dgraph:latest
106108
container_name: bank-dg3
107109
working_dir: /data/dg3
108110
volumes:
@@ -120,6 +122,7 @@ services:
120122

121123
# dg4:
122124
# image: debian:latest
125+
# image: dgraph/dgraph:latest
123126
# container_name: bank-dg4
124127
# working_dir: /data/dg4
125128
# volumes:
@@ -137,6 +140,7 @@ services:
137140

138141
# dg5:
139142
# image: debian:latest
143+
# image: dgraph/dgraph:latest
140144
# container_name: bank-dg5
141145
# working_dir: /data/dg5
142146
# volumes:

0 commit comments

Comments
 (0)