Skip to content

Commit

Permalink
Report GraphQL stats from alpha.
Browse files Browse the repository at this point in the history
  • Loading branch information
Arijit Das committed Jan 17, 2020
1 parent 44cbf94 commit fd70d55
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 4 deletions.
5 changes: 5 additions & 0 deletions dgraph/cmd/alpha/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ they form a Raft group and provide synchronous replication.
"Actual usage by the process would be more than specified here.")
flag.String("mutations", "allow",
"Set mutation mode to allow, disallow, or strict.")
flag.Bool("telemetry", true, "Send anonymous telemetry data to Dgraph devs.")

// Useful for running multiple servers on the same machine.
flag.IntP("port_offset", "o", 0,
Expand Down Expand Up @@ -499,6 +500,10 @@ func setupServer() {
}
}()

if Alpha.Conf.GetBool("telemetry") {
go edgraph.PeriodicallyPostTelemetry()
}

glog.Infoln("gRPC server started. Listening on port", grpcPort())
glog.Infoln("HTTP server started. Listening on port", httpPort())
wg.Wait()
Expand Down
7 changes: 4 additions & 3 deletions dgraph/cmd/zero/zero.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/dgraph-io/dgraph/conn"
"github.com/dgraph-io/dgraph/protos/pb"
"github.com/dgraph-io/dgraph/x"
"github.com/dgraph-io/dgraph/telemetry"
"github.com/gogo/protobuf/proto"
"github.com/golang/glog"
"github.com/pkg/errors"
Expand Down Expand Up @@ -94,7 +95,7 @@ func (s *Server) Init() {
}

func (s *Server) periodicallyPostTelemetry() {
glog.V(2).Infof("Starting telemetry data collection...")
glog.V(2).Infof("Starting telemetry data collection for zero...")
start := time.Now()

ticker := time.NewTicker(time.Minute)
Expand All @@ -109,14 +110,14 @@ func (s *Server) periodicallyPostTelemetry() {
continue
}
ms := s.membershipState()
t := newTelemetry(ms)
t := telemetry.NewZeroTelemetry(ms)
if t == nil {
continue
}
t.SinceHours = int(time.Since(start).Hours())
glog.V(2).Infof("Posting Telemetry data: %+v", t)

err := t.post()
err := t.Post()
glog.V(2).Infof("Telemetry data posted with error: %v", err)
if err == nil {
lastPostedAt = time.Now()
Expand Down
41 changes: 40 additions & 1 deletion edgraph/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"sort"
"strconv"
"strings"
"sync/atomic"
"time"
"unicode"

Expand All @@ -37,6 +38,7 @@ import (
"github.com/dgraph-io/dgraph/protos/pb"
"github.com/dgraph-io/dgraph/query"
"github.com/dgraph-io/dgraph/schema"
"github.com/dgraph-io/dgraph/telemetry"
"github.com/dgraph-io/dgraph/types"
"github.com/dgraph-io/dgraph/types/facets"
"github.com/dgraph-io/dgraph/worker"
Expand Down Expand Up @@ -76,9 +78,45 @@ const (
isGraphQL key = iota
)

var (
graphqlQueryCount uint64
nonGraphqlQueryCount uint64
)

// Server implements protos.DgraphServer
type Server struct{}

// PeriodicallyPostTelemetry periodically report telemetry data for alpha.
func PeriodicallyPostTelemetry() {
glog.V(2).Infof("Starting telemetry data collection for alpha...")
start := time.Now()

ticker := time.NewTicker(time.Minute)
defer ticker.Stop()

var lastPostedAt time.Time
for range ticker.C {
if time.Since(lastPostedAt) < time.Hour {
continue
}
ms := worker.GetMembershipState()
t := telemetry.NewAlphaTelemetry(ms, graphqlQueryCount, nonGraphqlQueryCount)
if t == nil {
continue
}
t.SinceHours = int(time.Since(start).Hours())
glog.V(2).Infof("Posting Telemetry data: %+v", t)

err := t.Post()
glog.V(2).Infof("Telemetry data posted with error: %v", err)
if err == nil {
atomic.StoreUint64(&graphqlQueryCount, 0)
atomic.StoreUint64(&nonGraphqlQueryCount, 0)
lastPostedAt = time.Now()
}
}
}

// Alter handles requests to change the schema or remove parts or all of the data.
func (s *Server) Alter(ctx context.Context, op *api.Operation) (*api.Payload, error) {
ctx, span := otrace.StartSpan(ctx, "Server.Alter")
Expand Down Expand Up @@ -666,17 +704,18 @@ func (s *Server) State(ctx context.Context) (*api.Response, error) {

// Query handles queries or mutations
func (s *Server) Query(ctx context.Context, req *api.Request) (*api.Response, error) {
atomic.AddUint64(&nonGraphqlQueryCount, 1)
return s.doQuery(ctx, req, NeedAuthorize)
}

// QueryForGraphql handles queries or mutations
func (s *Server) QueryForGraphql(ctx context.Context, req *api.Request) (*api.Response, error) {
atomic.AddUint64(&graphqlQueryCount, 1)
return s.doQuery(context.WithValue(ctx, isGraphQL, true), req, NeedAuthorize)
}

func (s *Server) doQuery(ctx context.Context, req *api.Request, authorize int) (
resp *api.Response, rerr error) {

if ctx.Err() != nil {
return nil, ctx.Err()
}
Expand Down
125 changes: 125 additions & 0 deletions telemetry/telemetry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* Copyright 2018 Dgraph Labs, Inc. and Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package telemetry

import (
"bytes"
"encoding/json"
"io/ioutil"
"net/http"
"runtime"

"github.com/dgraph-io/dgraph/protos/pb"
"github.com/dgraph-io/dgraph/x"
"github.com/golang/glog"
)

// Telemetry holds information about the state of the zero and alpha server.
type Telemetry struct {
Arch string
Cid string
ClusterSize int
DiskUsageMB int64
NumAlphas int
NumGroups int
NumTablets int
NumZeros int
OS string
SinceHours int
Version string
GraphqlQueryCount uint64
NonGraphqlQueryCount uint64
}

var keenURL = "https://ping.dgraph.io/3.0/projects/5b809dfac9e77c0001783ad0/events"

// NewZeroTelemetry returns a Telemetry struct that holds information about the state of zero
// server.
func NewZeroTelemetry(ms *pb.MembershipState) *Telemetry {
if len(ms.Cid) == 0 {
glog.V(2).Infoln("No CID found yet")
return nil
}
t := &Telemetry{
Cid: ms.Cid,
NumGroups: len(ms.GetGroups()),
NumZeros: len(ms.GetZeros()),
Version: x.Version(),
OS: runtime.GOOS,
Arch: runtime.GOARCH,
}
for _, g := range ms.GetGroups() {
t.NumAlphas += len(g.GetMembers())
for _, tablet := range g.GetTablets() {
t.NumTablets++
t.DiskUsageMB += tablet.GetSpace()
}
}
t.DiskUsageMB /= (1 << 20)
t.ClusterSize = t.NumAlphas + t.NumZeros
return t
}

// NewAlphaTelemetry returns a Telemetry struct that holds information about the state of alpha
// server.
func NewAlphaTelemetry(ms *pb.MembershipState, graphqlQueryCount uint64,
nonGraphqlQueryCount uint64) *Telemetry {
t := &Telemetry{
Cid: ms.Cid,
Version: x.Version(),
OS: runtime.GOOS,
Arch: runtime.GOARCH,
GraphqlQueryCount: graphqlQueryCount,
NonGraphqlQueryCount: nonGraphqlQueryCount,
}
return t
}

// Post reports the Telemetry to the stats server.
func (t *Telemetry) Post() error {
data, err := json.Marshal(t)
if err != nil {
return err
}
url := keenURL + "/dev"
if len(t.Version) > 0 {
url = keenURL + "/pings"
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "D0398E8C83BB30F67C519FDA6175975F680921890C35B36C34BE1095445"+
"97497CA758881BD7D56CC2355A2F36B4560102CBC3279AC7B27E5391372C36A31167EB0D06BF3764894AD20"+
"A0554BAFF14C292A40BC252BB9FF008736A0FD1D44E085")

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return err
}

defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
glog.V(2).Infof("Telemetry response status: %v", resp.Status)
glog.V(2).Infof("Telemetry response body: %s", body)
return nil
}

0 comments on commit fd70d55

Please sign in to comment.