Add SQL execution timing and tracing

This commit is contained in:
Vikram Rangnekar 2019-04-01 08:55:46 -04:00
parent 8ac8088b86
commit d66fb192bc
7 changed files with 73 additions and 3 deletions

1
.gitignore vendored
View File

@ -25,3 +25,4 @@
.vscode .vscode
main main
.DS_Store

View File

@ -227,6 +227,7 @@ Configuration files can either be in YAML or JSON their names are derived from t
host_port: 0.0.0.0:8080 host_port: 0.0.0.0:8080
web_ui: true web_ui: true
debug_level: 1 debug_level: 1
enable_tracing: true
# When to throw a 401 on auth failure # When to throw a 401 on auth failure
# valid values: always, per_query, never # valid values: always, per_query, never

View File

@ -2,6 +2,7 @@ title: Super Graph Development
host_port: 0.0.0.0:8080 host_port: 0.0.0.0:8080
web_ui: true web_ui: true
debug_level: 1 debug_level: 1
enable_tracing: true
# Throw a 401 on auth failure for queries that need auth # Throw a 401 on auth failure for queries that need auth
# valid values: always, per_query, never # valid values: always, per_query, never

View File

@ -2,6 +2,7 @@ title: Super Graph Production
host_port: 0.0.0.0:8080 host_port: 0.0.0.0:8080
web_ui: false web_ui: false
debug_level: 0 debug_level: 0
enable_tracing: false
auth_fail_block: always auth_fail_block: always
# Postgres related environment Variables # Postgres related environment Variables

View File

@ -9,7 +9,9 @@ import (
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"strings" "strings"
"time"
"github.com/dosco/super-graph/qcode"
"github.com/go-pg/pg" "github.com/go-pg/pg"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"github.com/valyala/fasttemplate" "github.com/valyala/fasttemplate"
@ -35,6 +37,32 @@ type gqlReq struct {
type gqlResp struct { type gqlResp struct {
Error string `json:"error,omitempty"` Error string `json:"error,omitempty"`
Data json.RawMessage `json:"data,omitempty"` Data json.RawMessage `json:"data,omitempty"`
Extensions extensions `json:"extensions"`
}
type extensions struct {
Tracing *trace `json:"tracing"`
}
type trace struct {
Version int `json:"version"`
StartTime time.Time `json:"startTime"`
EndTime time.Time `json:"endTime"`
Duration time.Duration `json:"duration"`
Execution execution `json:"execution"`
}
type execution struct {
Resolvers []resolver `json:"resolvers"`
}
type resolver struct {
Path []string `json:"path"`
ParentType string `json:"parentType"`
FieldName string `json:"fieldName"`
ReturnType string `json:"returnType"`
StartOffset int `json:"startOffset"`
Duration time.Duration `json:"duration"`
} }
func apiv1Http(w http.ResponseWriter, r *http.Request) { func apiv1Http(w http.ResponseWriter, r *http.Request) {
@ -99,6 +127,7 @@ func apiv1Http(w http.ResponseWriter, r *http.Request) {
if debug > 0 { if debug > 0 {
fmt.Println(finalSQL) fmt.Println(finalSQL)
} }
st := time.Now()
var root json.RawMessage var root json.RawMessage
_, err = db.Query(pg.Scan(&root), finalSQL) _, err = db.Query(pg.Scan(&root), finalSQL)
@ -108,7 +137,15 @@ func apiv1Http(w http.ResponseWriter, r *http.Request) {
return return
} }
json.NewEncoder(w).Encode(gqlResp{Data: json.RawMessage(root)}) et := time.Now()
resp := gqlResp{}
if tracing {
resp.Extensions = extensions{newTrace(st, et, qc)}
}
resp.Data = json.RawMessage(root)
json.NewEncoder(w).Encode(resp)
} }
/* /*
@ -174,3 +211,28 @@ func varValues(ctx context.Context) map[string]interface{} {
"user_id_provider": uidpFn, "user_id_provider": uidpFn,
} }
} }
func newTrace(st, et time.Time, qc *qcode.QCode) *trace {
du := et.Sub(et)
t := &trace{
Version: 1,
StartTime: st,
EndTime: et,
Duration: du,
Execution: execution{
[]resolver{
resolver{
Path: []string{qc.Query.Select.Table},
ParentType: "Query",
FieldName: qc.Query.Select.Table,
ReturnType: "object",
StartOffset: 1,
Duration: du,
},
},
},
}
return t
}

View File

@ -32,6 +32,7 @@ var (
pcompile *psql.Compiler pcompile *psql.Compiler
qcompile *qcode.Compiler qcompile *qcode.Compiler
authFailBlock int authFailBlock int
tracing bool
) )
func initLog() { func initLog() {
@ -74,6 +75,7 @@ func initConf() {
conf.SetDefault("host_port", "0.0.0.0:8080") conf.SetDefault("host_port", "0.0.0.0:8080")
conf.SetDefault("web_ui", false) conf.SetDefault("web_ui", false)
conf.SetDefault("debug_level", 0) conf.SetDefault("debug_level", 0)
conf.SetDefault("enable_tracing", false)
conf.SetDefault("database.type", "postgres") conf.SetDefault("database.type", "postgres")
conf.SetDefault("database.host", "localhost") conf.SetDefault("database.host", "localhost")
@ -84,6 +86,8 @@ func initConf() {
conf.SetDefault("env", "development") conf.SetDefault("env", "development")
conf.BindEnv("env", "GO_ENV") conf.BindEnv("env", "GO_ENV")
tracing = conf.GetBool("enable_tracing")
switch conf.GetString("auth_fail_block") { switch conf.GetString("auth_fail_block") {
case "always": case "always":
authFailBlock = authFailBlockAlways authFailBlock = authFailBlockAlways

Binary file not shown.

Before

Width:  |  Height:  |  Size: 949 KiB

After

Width:  |  Height:  |  Size: 911 KiB