mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-12 14:18:32 +00:00
More profiler tests
This commit is contained in:
@@ -8,6 +8,10 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
updateSamplesEnvVar = "UPDATE_SAMPLES"
|
||||
)
|
||||
|
||||
func RootPath() (string, error) {
|
||||
out, err := exec.Command("git", "rev-parse", "--show-toplevel").Output()
|
||||
if err != nil {
|
||||
@@ -42,14 +46,21 @@ func LoadJson(filename string, destination interface{}) error {
|
||||
|
||||
func WriteJson(filename string, data interface{}) error {
|
||||
|
||||
buf, err := json.Marshal(data)
|
||||
buf, err := json.MarshalIndent(data, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(filename, buf, 0)
|
||||
err = ioutil.WriteFile(filename, buf, 777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func ShouldUpdateSamples() bool {
|
||||
if os.Getenv(updateSamplesEnvVar) != "" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@@ -50,21 +50,27 @@ type Profiler interface {
|
||||
GetLastError() error
|
||||
QueriesChan() chan []QueryInfoAndCounters
|
||||
TimeoutsChan() <-chan time.Time
|
||||
ProcessDoc(proto.SystemProfile, map[StatsGroupKey]*QueryInfoAndCounters) error
|
||||
Start()
|
||||
Stop()
|
||||
}
|
||||
|
||||
type Profile struct {
|
||||
filters []filter.Filter
|
||||
iterator pmgo.IterManager
|
||||
ticker <-chan time.Time
|
||||
queriesChan chan []QueryInfoAndCounters
|
||||
stopChan chan bool
|
||||
docsChan chan proto.SystemProfile
|
||||
timeoutsChan chan time.Time
|
||||
filters []filter.Filter
|
||||
iterator pmgo.IterManager
|
||||
ticker <-chan time.Time
|
||||
queriesChan chan []QueryInfoAndCounters
|
||||
stopChan chan bool
|
||||
docsChan chan proto.SystemProfile
|
||||
timeoutsChan chan time.Time
|
||||
// For the moment ProcessDoc is exportable to it could be called from the "outside"
|
||||
// For that reason, we need a mutex to make it thread safe. In the future this func
|
||||
// will be unexported
|
||||
countersMapLock sync.Mutex
|
||||
queriesInfoAndCounters map[StatsGroupKey]*QueryInfoAndCounters
|
||||
keyFilters []string
|
||||
fingerprinter fingerprinter.Fingerprinter
|
||||
lock sync.Mutex
|
||||
running bool
|
||||
lastError error
|
||||
stopWaitGroup sync.WaitGroup
|
||||
@@ -142,6 +148,8 @@ func (p *Profile) QueriesChan() chan []QueryInfoAndCounters {
|
||||
}
|
||||
|
||||
func (p *Profile) Start() {
|
||||
p.lock.Lock()
|
||||
defer p.lock.Unlock()
|
||||
if !p.running {
|
||||
p.running = true
|
||||
p.stopChan = make(chan bool)
|
||||
@@ -150,15 +158,15 @@ func (p *Profile) Start() {
|
||||
}
|
||||
|
||||
func (p *Profile) Stop() {
|
||||
p.lock.Lock()
|
||||
defer p.lock.Unlock()
|
||||
if p.running {
|
||||
select {
|
||||
case p.stopChan <- true:
|
||||
default:
|
||||
}
|
||||
close(p.timeoutsChan)
|
||||
// Wait for getData to receive the stop signal
|
||||
p.stopWaitGroup.Wait()
|
||||
p.iterator.Close()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,6 +188,7 @@ MAIN_GETDATA_LOOP:
|
||||
p.queriesChan <- mapToArray(p.queriesInfoAndCounters)
|
||||
p.queriesInfoAndCounters = make(map[StatsGroupKey]*QueryInfoAndCounters) // Reset stats
|
||||
case <-p.stopChan:
|
||||
// Close the iterator to break the loop on getDocs
|
||||
p.iterator.Close()
|
||||
break MAIN_GETDATA_LOOP
|
||||
}
|
||||
@@ -212,10 +221,7 @@ func (p *Profile) getDocs() {
|
||||
}
|
||||
}
|
||||
p.queriesChan <- mapToArray(p.queriesInfoAndCounters)
|
||||
select {
|
||||
case p.stopChan <- true:
|
||||
default:
|
||||
}
|
||||
p.Stop()
|
||||
}
|
||||
|
||||
func (p *Profile) ProcessDoc(doc proto.SystemProfile, stats map[StatsGroupKey]*QueryInfoAndCounters) error {
|
||||
@@ -226,12 +232,15 @@ func (p *Profile) ProcessDoc(doc proto.SystemProfile, stats map[StatsGroupKey]*Q
|
||||
}
|
||||
var s *QueryInfoAndCounters
|
||||
var ok bool
|
||||
p.countersMapLock.Lock()
|
||||
defer p.countersMapLock.Unlock()
|
||||
|
||||
key := StatsGroupKey{
|
||||
Operation: doc.Op,
|
||||
Fingerprint: fp,
|
||||
Namespace: doc.Ns,
|
||||
}
|
||||
if s, ok = p.queriesInfoAndCounters[key]; !ok {
|
||||
if s, ok = stats[key]; !ok {
|
||||
realQuery, _ := util.GetQueryField(doc.Query)
|
||||
s = &QueryInfoAndCounters{
|
||||
ID: fmt.Sprintf("%x", md5.Sum([]byte(fmt.Sprintf("%s", key)))),
|
||||
@@ -241,7 +250,7 @@ func (p *Profile) ProcessDoc(doc proto.SystemProfile, stats map[StatsGroupKey]*Q
|
||||
TableScan: false,
|
||||
Query: realQuery,
|
||||
}
|
||||
p.queriesInfoAndCounters[key] = s
|
||||
stats[key] = s
|
||||
}
|
||||
s.Count++
|
||||
s.NScanned = append(s.NScanned, float64(doc.DocsExamined))
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package profiler
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"reflect"
|
||||
@@ -25,6 +26,11 @@ type testVars struct {
|
||||
|
||||
var vars testVars
|
||||
|
||||
func parseDate(dateStr string) time.Time {
|
||||
date, _ := time.Parse(time.RFC3339Nano, dateStr)
|
||||
return date
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
var err error
|
||||
if vars.RootPath, err = tutil.RootPath(); err != nil {
|
||||
@@ -58,8 +64,8 @@ func TestRegularIterator(t *testing.T) {
|
||||
fp := fingerprinter.NewFingerprinter(fingerprinter.DEFAULT_KEY_FILTERS)
|
||||
prof := NewProfiler(iter, filters, nil, fp)
|
||||
|
||||
firstSeen, _ := time.Parse(time.RFC3339Nano, "2017-04-01T23:01:19.914-03:00")
|
||||
lastSeen, _ := time.Parse(time.RFC3339Nano, "2017-04-01T23:01:20.214-03:00")
|
||||
firstSeen, _ := time.Parse(time.RFC3339Nano, "2017-04-01T23:01:19.914+00:00")
|
||||
lastSeen, _ := time.Parse(time.RFC3339Nano, "2017-04-01T23:01:20.214+00:00")
|
||||
want := []QueryInfoAndCounters{
|
||||
QueryInfoAndCounters{
|
||||
ID: "c6466139b21c392acd0699e863b50d81",
|
||||
@@ -113,17 +119,14 @@ func TestIteratorTimeout(t *testing.T) {
|
||||
iter.EXPECT().Timeout().Return(false),
|
||||
// When there are no more docs, iterator will close
|
||||
iter.EXPECT().Close(),
|
||||
// And we are closing it again (to force the getData go-routine to end)
|
||||
// at the profiler.Stop() method
|
||||
iter.EXPECT().Close(),
|
||||
)
|
||||
filters := []filter.Filter{}
|
||||
|
||||
fp := fingerprinter.NewFingerprinter(fingerprinter.DEFAULT_KEY_FILTERS)
|
||||
prof := NewProfiler(iter, filters, nil, fp)
|
||||
|
||||
firstSeen, _ := time.Parse(time.RFC3339Nano, "2017-04-01T23:01:19.914-03:00")
|
||||
lastSeen, _ := time.Parse(time.RFC3339Nano, "2017-04-01T23:01:19.914-03:00")
|
||||
firstSeen, _ := time.Parse(time.RFC3339Nano, "2017-04-01T23:01:19.914+00:00")
|
||||
lastSeen, _ := time.Parse(time.RFC3339Nano, "2017-04-01T23:01:19.914+00:00")
|
||||
want := []QueryInfoAndCounters{
|
||||
QueryInfoAndCounters{
|
||||
ID: "c6466139b21c392acd0699e863b50d81",
|
||||
@@ -196,7 +199,7 @@ func TestTailIterator(t *testing.T) {
|
||||
iter.EXPECT().Timeout().Return(false),
|
||||
// A Tail iterator will wait if the are no available docs.
|
||||
// Do a 1500 ms sleep before returning the second doc to simulate a tail wait
|
||||
// and to let the ticker ticks
|
||||
// and to let the ticker tick
|
||||
iter.EXPECT().Next(gomock.Any()).Do(sleep).SetArg(0, docs[1]).Return(true),
|
||||
iter.EXPECT().Timeout().Return(false),
|
||||
iter.EXPECT().Next(gomock.Any()).Return(false),
|
||||
@@ -209,12 +212,6 @@ func TestTailIterator(t *testing.T) {
|
||||
fp := fingerprinter.NewFingerprinter(fingerprinter.DEFAULT_KEY_FILTERS)
|
||||
prof := NewProfiler(iter, filters, ticker.C, fp)
|
||||
|
||||
firstSeen, _ := time.Parse(time.RFC3339Nano, "2017-04-01T23:01:20.214-03:00")
|
||||
lastSeen, _ := time.Parse(time.RFC3339Nano, "2017-04-01T23:01:20.214-03:00")
|
||||
|
||||
firstSeen2, _ := time.Parse(time.RFC3339Nano, "2017-04-01T23:01:19.914-03:00")
|
||||
lastSeen2, _ := time.Parse(time.RFC3339Nano, "2017-04-01T23:01:19.914-03:00")
|
||||
|
||||
want := []QueryInfoAndCounters{
|
||||
QueryInfoAndCounters{
|
||||
ID: "c6466139b21c392acd0699e863b50d81",
|
||||
@@ -225,8 +222,8 @@ func TestTailIterator(t *testing.T) {
|
||||
"shardVersion": []interface{}{float64(0), "000000000000000000000000"},
|
||||
},
|
||||
Fingerprint: "find",
|
||||
FirstSeen: firstSeen,
|
||||
LastSeen: lastSeen,
|
||||
FirstSeen: parseDate("2017-04-01T23:01:20.214+00:00"),
|
||||
LastSeen: parseDate("2017-04-01T23:01:20.214+00:00"),
|
||||
TableScan: false,
|
||||
Count: 1,
|
||||
BlockedTime: Times(nil),
|
||||
@@ -245,8 +242,8 @@ func TestTailIterator(t *testing.T) {
|
||||
"shardVersion": []interface{}{float64(0), "000000000000000000000000"},
|
||||
},
|
||||
Fingerprint: "find",
|
||||
FirstSeen: firstSeen2,
|
||||
LastSeen: lastSeen2,
|
||||
FirstSeen: parseDate("2017-04-01T23:01:19.914+00:00"),
|
||||
LastSeen: parseDate("2017-04-01T23:01:19.914+00:00"),
|
||||
TableScan: false,
|
||||
Count: 1,
|
||||
BlockedTime: Times(nil),
|
||||
@@ -271,3 +268,202 @@ func TestTailIterator(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCalcStats(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
docs := []proto.SystemProfile{}
|
||||
err := tutil.LoadJson(vars.RootPath+samples+"profiler_docs_stats.json", &docs)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot load samples: %s", err.Error())
|
||||
}
|
||||
|
||||
want := []QueryStats{}
|
||||
err = tutil.LoadJson(vars.RootPath+samples+"profiler_docs_stats.want.json", &want)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot load expected results: %s", err.Error())
|
||||
}
|
||||
|
||||
iter := pmgomock.NewMockIterManager(ctrl)
|
||||
gomock.InOrder(
|
||||
iter.EXPECT().Next(gomock.Any()).SetArg(0, docs[0]).Return(true),
|
||||
iter.EXPECT().Timeout().Return(false),
|
||||
iter.EXPECT().Next(gomock.Any()).SetArg(0, docs[1]).Return(true),
|
||||
iter.EXPECT().Timeout().Return(false),
|
||||
iter.EXPECT().Next(gomock.Any()).SetArg(0, docs[2]).Return(true),
|
||||
iter.EXPECT().Timeout().Return(false),
|
||||
iter.EXPECT().Next(gomock.Any()).Return(false),
|
||||
iter.EXPECT().Timeout().Return(false),
|
||||
iter.EXPECT().Close(),
|
||||
)
|
||||
|
||||
filters := []filter.Filter{}
|
||||
fp := fingerprinter.NewFingerprinter(fingerprinter.DEFAULT_KEY_FILTERS)
|
||||
prof := NewProfiler(iter, filters, nil, fp)
|
||||
|
||||
prof.Start()
|
||||
select {
|
||||
case queries := <-prof.QueriesChan():
|
||||
stats := CalcQueriesStats(queries, 1)
|
||||
if os.Getenv("UPDATE_SAMPLES") != "" {
|
||||
tutil.WriteJson(vars.RootPath+samples+"profiler_docs_stats.want.json", stats)
|
||||
}
|
||||
if !reflect.DeepEqual(stats, want) {
|
||||
t.Errorf("Invalid stats.\nGot:%#v\nWant: %#v\n", stats, want)
|
||||
}
|
||||
case <-time.After(2 * time.Second):
|
||||
t.Error("Didn't get any query")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCalcTotalStats(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
docs := []proto.SystemProfile{}
|
||||
err := tutil.LoadJson(vars.RootPath+samples+"profiler_docs_stats.json", &docs)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot load samples: %s", err.Error())
|
||||
}
|
||||
|
||||
want := QueryStats{}
|
||||
err = tutil.LoadJson(vars.RootPath+samples+"profiler_docs_total_stats.want.json", &want)
|
||||
if err != nil && !tutil.ShouldUpdateSamples() {
|
||||
t.Fatalf("cannot load expected results: %s", err.Error())
|
||||
}
|
||||
|
||||
iter := pmgomock.NewMockIterManager(ctrl)
|
||||
gomock.InOrder(
|
||||
iter.EXPECT().Next(gomock.Any()).SetArg(0, docs[0]).Return(true),
|
||||
iter.EXPECT().Timeout().Return(false),
|
||||
iter.EXPECT().Next(gomock.Any()).SetArg(0, docs[1]).Return(true),
|
||||
iter.EXPECT().Timeout().Return(false),
|
||||
iter.EXPECT().Next(gomock.Any()).SetArg(0, docs[2]).Return(true),
|
||||
iter.EXPECT().Timeout().Return(false),
|
||||
iter.EXPECT().Next(gomock.Any()).Return(false),
|
||||
iter.EXPECT().Timeout().Return(false),
|
||||
iter.EXPECT().Close(),
|
||||
)
|
||||
|
||||
filters := []filter.Filter{}
|
||||
fp := fingerprinter.NewFingerprinter(fingerprinter.DEFAULT_KEY_FILTERS)
|
||||
prof := NewProfiler(iter, filters, nil, fp)
|
||||
|
||||
prof.Start()
|
||||
select {
|
||||
case queries := <-prof.QueriesChan():
|
||||
stats := CalcTotalQueriesStats(queries, 1)
|
||||
if os.Getenv("UPDATE_SAMPLES") != "" {
|
||||
fmt.Println("Updating samples: " + vars.RootPath + samples + "profiler_docs_total_stats.want.json")
|
||||
err := tutil.WriteJson(vars.RootPath+samples+"profiler_docs_total_stats.want.json", stats)
|
||||
if err != nil {
|
||||
fmt.Printf("cannot update samples: %s", err.Error())
|
||||
}
|
||||
}
|
||||
if !reflect.DeepEqual(stats, want) {
|
||||
t.Errorf("Invalid stats.\nGot:%#v\nWant: %#v\n", stats, want)
|
||||
}
|
||||
case <-time.After(2 * time.Second):
|
||||
t.Error("Didn't get any query")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCalcTotalCounters(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
docs := []proto.SystemProfile{}
|
||||
err := tutil.LoadJson(vars.RootPath+samples+"profiler_docs_stats.json", &docs)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot load samples: %s", err.Error())
|
||||
}
|
||||
|
||||
want := totalCounters{}
|
||||
err = tutil.LoadJson(vars.RootPath+samples+"profiler_docs_total_counters.want.json", &want)
|
||||
if err != nil && !tutil.ShouldUpdateSamples() {
|
||||
t.Fatalf("cannot load expected results: %s", err.Error())
|
||||
}
|
||||
|
||||
iter := pmgomock.NewMockIterManager(ctrl)
|
||||
gomock.InOrder(
|
||||
iter.EXPECT().Next(gomock.Any()).SetArg(0, docs[0]).Return(true),
|
||||
iter.EXPECT().Timeout().Return(false),
|
||||
iter.EXPECT().Next(gomock.Any()).SetArg(0, docs[1]).Return(true),
|
||||
iter.EXPECT().Timeout().Return(false),
|
||||
iter.EXPECT().Next(gomock.Any()).SetArg(0, docs[2]).Return(true),
|
||||
iter.EXPECT().Timeout().Return(false),
|
||||
iter.EXPECT().Next(gomock.Any()).Return(false),
|
||||
iter.EXPECT().Timeout().Return(false),
|
||||
iter.EXPECT().Close(),
|
||||
)
|
||||
|
||||
filters := []filter.Filter{}
|
||||
fp := fingerprinter.NewFingerprinter(fingerprinter.DEFAULT_KEY_FILTERS)
|
||||
prof := NewProfiler(iter, filters, nil, fp)
|
||||
|
||||
prof.Start()
|
||||
select {
|
||||
case queries := <-prof.QueriesChan():
|
||||
counters := calcTotalCounters(queries)
|
||||
if tutil.ShouldUpdateSamples() {
|
||||
fmt.Println("Updating samples: " + vars.RootPath + samples + "profiler_docs_total_counters.want.json")
|
||||
err := tutil.WriteJson(vars.RootPath+samples+"profiler_docs_total_counters.want.json", counters)
|
||||
if err != nil {
|
||||
fmt.Printf("cannot update samples: %s", err.Error())
|
||||
}
|
||||
}
|
||||
if !reflect.DeepEqual(counters, want) {
|
||||
t.Errorf("Invalid counters.\nGot:%#v\nWant: %#v\n", counters, want)
|
||||
}
|
||||
case <-time.After(2 * time.Second):
|
||||
t.Error("Didn't get any query")
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessDoc(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
docs := []proto.SystemProfile{}
|
||||
err := tutil.LoadJson(vars.RootPath+samples+"profiler_docs_stats.json", &docs)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot load samples: %s", err.Error())
|
||||
}
|
||||
|
||||
iter := pmgomock.NewMockIterManager(ctrl)
|
||||
filters := []filter.Filter{}
|
||||
fp := fingerprinter.NewFingerprinter(fingerprinter.DEFAULT_KEY_FILTERS)
|
||||
prof := NewProfiler(iter, filters, nil, fp)
|
||||
|
||||
var stats = make(map[StatsGroupKey]*QueryInfoAndCounters)
|
||||
|
||||
err = prof.ProcessDoc(docs[1], stats)
|
||||
if err != nil {
|
||||
t.Errorf("Error processing doc: %s\n", err.Error())
|
||||
}
|
||||
statsKey := StatsGroupKey{Operation: "query", Fingerprint: "s2", Namespace: "samples.col1"}
|
||||
statsVal := &QueryInfoAndCounters{
|
||||
ID: "84e09ef6a3dc35f472df05fa98eee7d3",
|
||||
Namespace: "samples.col1",
|
||||
Operation: "query",
|
||||
Query: map[string]interface{}{"s2": map[string]interface{}{"$gte": "41991", "$lt": "33754"}},
|
||||
Fingerprint: "s2",
|
||||
FirstSeen: parseDate("2017-04-10T13:15:53.532-03:00"),
|
||||
LastSeen: parseDate("2017-04-10T13:15:53.532-03:00"),
|
||||
TableScan: false,
|
||||
Count: 1,
|
||||
BlockedTime: nil,
|
||||
LockTime: nil,
|
||||
NReturned: []float64{0},
|
||||
NScanned: []float64{10000},
|
||||
QueryTime: []float64{7},
|
||||
ResponseLength: []float64{215},
|
||||
}
|
||||
|
||||
want := map[StatsGroupKey]*QueryInfoAndCounters{statsKey: statsVal}
|
||||
|
||||
if !reflect.DeepEqual(stats, want) {
|
||||
t.Errorf("Error in ProcessDoc.\nGot:%#v\nWant: %#v\n", stats, want)
|
||||
}
|
||||
}
|
||||
|
@@ -140,6 +140,7 @@ func main() {
|
||||
queries := <-prof.QueriesChan()
|
||||
|
||||
uptime := uptime(session)
|
||||
|
||||
queriesStats := profiler.CalcQueriesStats(queries, uptime)
|
||||
sortedQueryStats := sortQueries(queriesStats, opts.OrderBy)
|
||||
|
||||
|
@@ -76,7 +76,7 @@
|
||||
]
|
||||
},
|
||||
"ResponseLength": 1061230,
|
||||
"Ts": "2017-04-01T23:01:20.214-03:00",
|
||||
"Ts": "2017-04-01T23:01:20.214+00:00",
|
||||
"User": "",
|
||||
"WriteConflicts": 0
|
||||
},
|
||||
@@ -157,7 +157,7 @@
|
||||
]
|
||||
},
|
||||
"ResponseLength": 1061230,
|
||||
"Ts": "2017-04-01T23:01:19.914-03:00",
|
||||
"Ts": "2017-04-01T23:01:19.914+00:00",
|
||||
"User": "",
|
||||
"WriteConflicts": 0
|
||||
}
|
||||
|
265
src/go/tests/profiler_docs_stats.json
Normal file
265
src/go/tests/profiler_docs_stats.json
Normal file
@@ -0,0 +1,265 @@
|
||||
[
|
||||
{
|
||||
"AllUsers": [],
|
||||
"Client": "127.0.0.1",
|
||||
"CursorExhausted": false,
|
||||
"DocsExamined": 75,
|
||||
"ExecStats": {
|
||||
"Advanced": 75,
|
||||
"ExecutionTimeMillisEstimate": 10,
|
||||
"InputStage": {
|
||||
"Advanced": 0,
|
||||
"Direction": "",
|
||||
"DocsExamined": 0,
|
||||
"ExecutionTimeMillisEstimate": 0,
|
||||
"Filter": {
|
||||
"Date": {
|
||||
"Eq": ""
|
||||
}
|
||||
},
|
||||
"Invalidates": 0,
|
||||
"IsEOF": 0,
|
||||
"NReturned": 0,
|
||||
"NeedTime": 0,
|
||||
"NeedYield": 0,
|
||||
"RestoreState": 0,
|
||||
"SaveState": 0,
|
||||
"Stage": "",
|
||||
"Works": 0
|
||||
},
|
||||
"Invalidates": 0,
|
||||
"IsEOF": 0,
|
||||
"LimitAmount": 0,
|
||||
"NReturned": 75,
|
||||
"NeedTime": 1,
|
||||
"NeedYield": 0,
|
||||
"RestoreState": 0,
|
||||
"SaveState": 1,
|
||||
"Stage": "COLLSCAN",
|
||||
"Works": 76
|
||||
},
|
||||
"KeyUpdates": 0,
|
||||
"KeysExamined": 0,
|
||||
"Locks": {
|
||||
"Collection": {
|
||||
"AcquireCount": {
|
||||
"R": 0
|
||||
}
|
||||
},
|
||||
"Database": {
|
||||
"AcquireCount": {
|
||||
"R": 1
|
||||
}
|
||||
},
|
||||
"Global": {
|
||||
"AcquireCount": {
|
||||
"R": 2
|
||||
}
|
||||
},
|
||||
"MMAPV1Journal": {
|
||||
"AcquireCount": {
|
||||
"R": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"Millis": 0,
|
||||
"Nreturned": 75,
|
||||
"Ns": "samples.col1",
|
||||
"NumYield": 0,
|
||||
"Op": "query",
|
||||
"Protocol": "op_command",
|
||||
"Query": {
|
||||
"find": "col1",
|
||||
"shardVersion": [
|
||||
0,
|
||||
"000000000000000000000000"
|
||||
]
|
||||
},
|
||||
"ResponseLength": 1061230,
|
||||
"Ts": "2017-04-10T13:16:23.29-03:00",
|
||||
"User": "",
|
||||
"WriteConflicts": 0
|
||||
},
|
||||
{
|
||||
"AllUsers": [],
|
||||
"Client": "127.0.0.1",
|
||||
"CursorExhausted": true,
|
||||
"DocsExamined": 10000,
|
||||
"ExecStats": {
|
||||
"Advanced": 0,
|
||||
"ExecutionTimeMillisEstimate": 10,
|
||||
"InputStage": {
|
||||
"Advanced": 0,
|
||||
"Direction": "",
|
||||
"DocsExamined": 0,
|
||||
"ExecutionTimeMillisEstimate": 0,
|
||||
"Filter": {
|
||||
"Date": {
|
||||
"Eq": ""
|
||||
}
|
||||
},
|
||||
"Invalidates": 0,
|
||||
"IsEOF": 0,
|
||||
"NReturned": 0,
|
||||
"NeedTime": 0,
|
||||
"NeedYield": 0,
|
||||
"RestoreState": 0,
|
||||
"SaveState": 0,
|
||||
"Stage": "",
|
||||
"Works": 0
|
||||
},
|
||||
"Invalidates": 0,
|
||||
"IsEOF": 1,
|
||||
"LimitAmount": 0,
|
||||
"NReturned": 0,
|
||||
"NeedTime": 10001,
|
||||
"NeedYield": 0,
|
||||
"RestoreState": 78,
|
||||
"SaveState": 78,
|
||||
"Stage": "COLLSCAN",
|
||||
"Works": 10002
|
||||
},
|
||||
"KeyUpdates": 0,
|
||||
"KeysExamined": 0,
|
||||
"Locks": {
|
||||
"Collection": {
|
||||
"AcquireCount": {
|
||||
"R": 0
|
||||
}
|
||||
},
|
||||
"Database": {
|
||||
"AcquireCount": {
|
||||
"R": 79
|
||||
}
|
||||
},
|
||||
"Global": {
|
||||
"AcquireCount": {
|
||||
"R": 158
|
||||
}
|
||||
},
|
||||
"MMAPV1Journal": {
|
||||
"AcquireCount": {
|
||||
"R": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"Millis": 7,
|
||||
"Nreturned": 0,
|
||||
"Ns": "samples.col1",
|
||||
"NumYield": 78,
|
||||
"Op": "query",
|
||||
"Protocol": "op_command",
|
||||
"Query": {
|
||||
"filter": {
|
||||
"s2": {
|
||||
"$gte": "41991",
|
||||
"$lt": "33754"
|
||||
}
|
||||
},
|
||||
"find": "col1",
|
||||
"shardVersion": [
|
||||
0,
|
||||
"000000000000000000000000"
|
||||
]
|
||||
},
|
||||
"ResponseLength": 215,
|
||||
"Ts": "2017-04-10T13:15:53.532-03:00",
|
||||
"User": "",
|
||||
"WriteConflicts": 0
|
||||
},
|
||||
{
|
||||
"AllUsers": [],
|
||||
"Client": "127.0.0.1",
|
||||
"CursorExhausted": true,
|
||||
"DocsExamined": 0,
|
||||
"ExecStats": {
|
||||
"Advanced": 0,
|
||||
"ExecutionTimeMillisEstimate": 0,
|
||||
"InputStage": {
|
||||
"Advanced": 0,
|
||||
"Direction": "",
|
||||
"DocsExamined": 0,
|
||||
"ExecutionTimeMillisEstimate": 0,
|
||||
"Filter": {
|
||||
"Date": {
|
||||
"Eq": ""
|
||||
}
|
||||
},
|
||||
"Invalidates": 0,
|
||||
"IsEOF": 1,
|
||||
"NReturned": 0,
|
||||
"NeedTime": 1,
|
||||
"NeedYield": 0,
|
||||
"RestoreState": 0,
|
||||
"SaveState": 0,
|
||||
"Stage": "SORT_KEY_GENERATOR",
|
||||
"Works": 2
|
||||
},
|
||||
"Invalidates": 0,
|
||||
"IsEOF": 1,
|
||||
"LimitAmount": 0,
|
||||
"NReturned": 0,
|
||||
"NeedTime": 1,
|
||||
"NeedYield": 0,
|
||||
"RestoreState": 0,
|
||||
"SaveState": 0,
|
||||
"Stage": "PROJECTION",
|
||||
"Works": 2
|
||||
},
|
||||
"KeyUpdates": 0,
|
||||
"KeysExamined": 0,
|
||||
"Locks": {
|
||||
"Collection": {
|
||||
"AcquireCount": {
|
||||
"R": 0
|
||||
}
|
||||
},
|
||||
"Database": {
|
||||
"AcquireCount": {
|
||||
"R": 1
|
||||
}
|
||||
},
|
||||
"Global": {
|
||||
"AcquireCount": {
|
||||
"R": 2
|
||||
}
|
||||
},
|
||||
"MMAPV1Journal": {
|
||||
"AcquireCount": {
|
||||
"R": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"Millis": 0,
|
||||
"Nreturned": 0,
|
||||
"Ns": "samples.col1",
|
||||
"NumYield": 0,
|
||||
"Op": "query",
|
||||
"Protocol": "op_command",
|
||||
"Query": {
|
||||
"filter": {
|
||||
"user_id": {
|
||||
"$gte": 3384024924,
|
||||
"$lt": 195092007
|
||||
}
|
||||
},
|
||||
"find": "col1",
|
||||
"projection": {
|
||||
"$sortKey": {
|
||||
"$meta": "sortKey"
|
||||
}
|
||||
},
|
||||
"shardVersion": [
|
||||
0,
|
||||
"000000000000000000000000"
|
||||
],
|
||||
"sort": {
|
||||
"user_id": 1
|
||||
}
|
||||
},
|
||||
"ResponseLength": 215,
|
||||
"Ts": "2017-04-10T13:15:53.524-03:00",
|
||||
"User": "",
|
||||
"WriteConflicts": 0
|
||||
}
|
||||
]
|
161
src/go/tests/profiler_docs_stats.want.json
Normal file
161
src/go/tests/profiler_docs_stats.want.json
Normal file
@@ -0,0 +1,161 @@
|
||||
[
|
||||
{
|
||||
"ID": "c6466139b21c392acd0699e863b50d81",
|
||||
"Namespace": "samples.col1",
|
||||
"Operation": "query",
|
||||
"Query": "{\"find\":\"col1\",\"shardVersion\":[0,\"000000000000000000000000\"]}",
|
||||
"Fingerprint": "find",
|
||||
"FirstSeen": "2017-04-10T13:16:23.29-03:00",
|
||||
"LastSeen": "2017-04-10T13:16:23.29-03:00",
|
||||
"Count": 1,
|
||||
"QPS": 1,
|
||||
"Rank": 0,
|
||||
"Ratio": 1,
|
||||
"QueryTime": {
|
||||
"Pct": 0,
|
||||
"Total": 0,
|
||||
"Min": 0,
|
||||
"Max": 0,
|
||||
"Avg": 0,
|
||||
"Pct95": 0,
|
||||
"StdDev": 0,
|
||||
"Median": 0
|
||||
},
|
||||
"ResponseLength": {
|
||||
"Pct": 0.9995949739087844,
|
||||
"Total": 1061230,
|
||||
"Min": 1061230,
|
||||
"Max": 1061230,
|
||||
"Avg": 1061230,
|
||||
"Pct95": 1061230,
|
||||
"StdDev": 0,
|
||||
"Median": 1061230
|
||||
},
|
||||
"Returned": {
|
||||
"Pct": 100,
|
||||
"Total": 75,
|
||||
"Min": 75,
|
||||
"Max": 75,
|
||||
"Avg": 75,
|
||||
"Pct95": 75,
|
||||
"StdDev": 0,
|
||||
"Median": 75
|
||||
},
|
||||
"Scanned": {
|
||||
"Pct": 0.7444168734491315,
|
||||
"Total": 75,
|
||||
"Min": 75,
|
||||
"Max": 75,
|
||||
"Avg": 75,
|
||||
"Pct95": 75,
|
||||
"StdDev": 0,
|
||||
"Median": 75
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "84e09ef6a3dc35f472df05fa98eee7d3",
|
||||
"Namespace": "samples.col1",
|
||||
"Operation": "query",
|
||||
"Query": "{\"s2\":{\"$gte\":\"41991\",\"$lt\":\"33754\"}}",
|
||||
"Fingerprint": "s2",
|
||||
"FirstSeen": "2017-04-10T13:15:53.532-03:00",
|
||||
"LastSeen": "2017-04-10T13:15:53.532-03:00",
|
||||
"Count": 1,
|
||||
"QPS": 1,
|
||||
"Rank": 0,
|
||||
"Ratio": 0,
|
||||
"QueryTime": {
|
||||
"Pct": 100,
|
||||
"Total": 7,
|
||||
"Min": 7,
|
||||
"Max": 7,
|
||||
"Avg": 7,
|
||||
"Pct95": 7,
|
||||
"StdDev": 0,
|
||||
"Median": 7
|
||||
},
|
||||
"ResponseLength": {
|
||||
"Pct": 0.00020251304560782172,
|
||||
"Total": 215,
|
||||
"Min": 215,
|
||||
"Max": 215,
|
||||
"Avg": 215,
|
||||
"Pct95": 215,
|
||||
"StdDev": 0,
|
||||
"Median": 215
|
||||
},
|
||||
"Returned": {
|
||||
"Pct": 0,
|
||||
"Total": 0,
|
||||
"Min": 0,
|
||||
"Max": 0,
|
||||
"Avg": 0,
|
||||
"Pct95": 0,
|
||||
"StdDev": 0,
|
||||
"Median": 0
|
||||
},
|
||||
"Scanned": {
|
||||
"Pct": 99.25558312655087,
|
||||
"Total": 10000,
|
||||
"Min": 10000,
|
||||
"Max": 10000,
|
||||
"Avg": 10000,
|
||||
"Pct95": 10000,
|
||||
"StdDev": 0,
|
||||
"Median": 10000
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "69e3b2f5f0aefcec868c0fa5ec8cebe5",
|
||||
"Namespace": "samples.col1",
|
||||
"Operation": "query",
|
||||
"Query": "{\"user_id\":{\"$gte\":3384024924,\"$lt\":195092007}}",
|
||||
"Fingerprint": "user_id",
|
||||
"FirstSeen": "2017-04-10T13:15:53.524-03:00",
|
||||
"LastSeen": "2017-04-10T13:15:53.524-03:00",
|
||||
"Count": 1,
|
||||
"QPS": 1,
|
||||
"Rank": 0,
|
||||
"Ratio": 0,
|
||||
"QueryTime": {
|
||||
"Pct": 0,
|
||||
"Total": 0,
|
||||
"Min": 0,
|
||||
"Max": 0,
|
||||
"Avg": 0,
|
||||
"Pct95": 0,
|
||||
"StdDev": 0,
|
||||
"Median": 0
|
||||
},
|
||||
"ResponseLength": {
|
||||
"Pct": 0.00020251304560782172,
|
||||
"Total": 215,
|
||||
"Min": 215,
|
||||
"Max": 215,
|
||||
"Avg": 215,
|
||||
"Pct95": 215,
|
||||
"StdDev": 0,
|
||||
"Median": 215
|
||||
},
|
||||
"Returned": {
|
||||
"Pct": 0,
|
||||
"Total": 0,
|
||||
"Min": 0,
|
||||
"Max": 0,
|
||||
"Avg": 0,
|
||||
"Pct95": 0,
|
||||
"StdDev": 0,
|
||||
"Median": 0
|
||||
},
|
||||
"Scanned": {
|
||||
"Pct": 0,
|
||||
"Total": 0,
|
||||
"Min": 0,
|
||||
"Max": 0,
|
||||
"Avg": 0,
|
||||
"Pct95": 0,
|
||||
"StdDev": 0,
|
||||
"Median": 0
|
||||
}
|
||||
}
|
||||
]
|
7
src/go/tests/profiler_docs_total_counters.want.json
Normal file
7
src/go/tests/profiler_docs_total_counters.want.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"Count": 3,
|
||||
"Scanned": 10075,
|
||||
"Returned": 75,
|
||||
"QueryTime": 7,
|
||||
"Bytes": 1061660
|
||||
}
|
53
src/go/tests/profiler_docs_total_stats.want.json
Executable file
53
src/go/tests/profiler_docs_total_stats.want.json
Executable file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"ID": "",
|
||||
"Namespace": "",
|
||||
"Operation": "",
|
||||
"Query": "null",
|
||||
"Fingerprint": "",
|
||||
"FirstSeen": "0001-01-01T00:00:00Z",
|
||||
"LastSeen": "0001-01-01T00:00:00Z",
|
||||
"Count": 0,
|
||||
"QPS": 0,
|
||||
"Rank": 0,
|
||||
"Ratio": 134.33333333333334,
|
||||
"QueryTime": {
|
||||
"Pct": 100,
|
||||
"Total": 7,
|
||||
"Min": 0,
|
||||
"Max": 7,
|
||||
"Avg": 2.3333333333333335,
|
||||
"Pct95": 7,
|
||||
"StdDev": 3.2998316455372216,
|
||||
"Median": 0
|
||||
},
|
||||
"ResponseLength": {
|
||||
"Pct": 1,
|
||||
"Total": 1061660,
|
||||
"Min": 215,
|
||||
"Max": 1061230,
|
||||
"Avg": 353886.6666666667,
|
||||
"Pct95": 1061230,
|
||||
"StdDev": 500167.26762709644,
|
||||
"Median": 215
|
||||
},
|
||||
"Returned": {
|
||||
"Pct": 100,
|
||||
"Total": 75,
|
||||
"Min": 0,
|
||||
"Max": 75,
|
||||
"Avg": 25,
|
||||
"Pct95": 75,
|
||||
"StdDev": 35.35533905932738,
|
||||
"Median": 0
|
||||
},
|
||||
"Scanned": {
|
||||
"Pct": 100,
|
||||
"Total": 10075,
|
||||
"Min": 0,
|
||||
"Max": 10000,
|
||||
"Avg": 3358.3333333333335,
|
||||
"Pct95": 10000,
|
||||
"StdDev": 4696.46734850308,
|
||||
"Median": 75
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user