Add SQL execution timing and tracing
This commit is contained in:
parent
8ac8088b86
commit
d66fb192bc
|
@ -25,3 +25,4 @@
|
||||||
|
|
||||||
.vscode
|
.vscode
|
||||||
main
|
main
|
||||||
|
.DS_Store
|
|
@ -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
|
||||||
|
|
1
dev.yml
1
dev.yml
|
@ -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
|
||||||
|
|
1
prod.yml
1
prod.yml
|
@ -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
|
||||||
|
|
64
serv/http.go
64
serv/http.go
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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 |
Loading…
Reference in New Issue