10000 0.3.1 by simagix · Pull Request #11 · simagix/hatchet · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
8000

0.3.1 #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
< 8000 div style="left: -107px; top: -7px" data-view-component="true" class="Popover-message Box position-relative mx-auto text-left color-shadow-large p-2 mt-2">
Diff view
Diff view
8 changes: 4 additions & 4 deletions README_DEV.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ The easiest way is to go to the home page `http://localhost:3721` and following
- `/hatchets/{hatchet}/charts/ops?type={}` views average ops time chart, types are:
- stats
- counts
- `/hatchets/{hatchet}/charts/reslen?type={}` views response length chart, types are:
- ips
- `/hatchets/{hatchet}/charts/reslen-ip?ip={}` views response length by IPs chart, types are:
- `/hatchets/{hatchet}/charts/reslen-ns?ns={}` views response length by IPs chart, types are:
```

## Query SQLite3 Database
Expand All @@ -45,15 +45,15 @@ The database file is *data/hatchet.db*; use the *sqlite3* command as below:
sqlite3 ./data/hatchet.db
```

After a log file is processed, 3 tables are created in the SQLite3 database. Part of the table name are from the processed log file. For example, a table *mongod*_{hex} (e.g., mongod_1b3d5f7) is created after a log file $HOME/Downloads/**mongod**.log.gz is processed. The other 3 tables are 1) mongod_{hex}_ops stores stats of slow ops, 2) mongod_{hex}_clients stores clients information, and 3) mongod_{hex}_audit keeps audit data. A few SQL commands follow.
After a log file is processed, 3 tables are created in the SQLite3 database. Part of the table name are from the processed log file. For example, a table *mongod*_{hex} (e.g., mongod_1b3d5f7) is created after a log file $HOME/Downloads/**mongod**.log.gz is processed. The other 4 tables are 1) mongod_{hex}_ops stores stats of slow ops, 2) mongod_{hex}_clients stores clients information, 3) mongod_{hex}_audit keeps audit data, and 4) mongod_{hex}_drivers to store driver information. A few SQL commands follow.

### Query All Data
```sqlite3
SELECT * FROM mongod_1b3d5f7;
```

```sqlite3
SELECT date, severity, component, context, substr(message, 1, 60) message FROM mongod_1b3d5f7;
SELECT date, severity, component, context, SUBSTR(message, 1, 60) message FROM mongod_1b3d5f7;
```

```sqlite3
Expand Down
348 changes: 348 additions & 0 deletions audit_template.go

Large diffs are not rendered by default.

81 changes: 63 additions & 18 deletions charts_handler.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
// Copyright 2022-present Kuei-chun Chen. All rights reserved.
/*
* Copyright 2022-present Kuei-chun Chen. All rights reserved.
* charts_handler.go
*/

package hatchet

Expand All @@ -16,6 +19,14 @@ const (
BAR_CHART = "bar_chart"
BUBBLE_CHART = "bubble_chart"
PIE_CHART = "pie_chart"

T_OPS = "ops"
T_RESLEN_UP = "reslen-ip"
T_OPS_COUNTS = "ops-counts"
T_CONNS_ACCEPTED = "connections-accepted"
T_CONNS_TIME = "connections-time"
T_CONNS_TOTAL = "connections-total"
T_RESLEN_NS = "reslen-ns"
)

type Chart struct {
Expand All @@ -27,18 +38,20 @@ type Chart struct {

var charts = map[string]Chart{
"instruction": {0, "select a chart", "", ""},
"ops": {1, "Average Operation Time",
T_OPS: {1, "Average Operation Time",
"Display average operations time over a period of time", "/ops?type=stats"},
"reslen": {2, "Response Length ",
"Display total response length from client IPs", "/reslen?type=ips"},
"ops-counts": {3, "Operation Counts",
T_OPS_COUNTS: {2, "Operation Counts",
"Display total counts of operations", "/ops?type=counts"},
"connections-accepted": {4, "Accepted Connections",
T_CONNS_ACCEPTED: {3, "Accepted Connections",
"Display accepted connections from clients", "/connections?type=accepted"},
"connections-time": {5, "Accepted & Ended Connections",
T_CONNS_TIME: {4, "Accepted & Ended Connections",
"Display accepted vs ended connections over a period of time", "/connections?type=time"},
"connections-total": {6, "Accepted & Ended from IPs",
T_CONNS_TOTAL: {5, "Accepted & Ended from IPs",
"Display accepted vs ended connections by client IPs", "/connections?type=total"},
T_RESLEN_UP: {6, "Response Length by IPs ",
"Display total response length by client IPs", "/reslen-ip?ip="},
T_RESLEN_NS: {7, "Response Length by Namespaces ",
"Display total response length by namespaces", "/reslen-ns?ns="},
}

// ChartsHandler responds to charts API calls
Expand All @@ -65,11 +78,12 @@ func ChartsHandler(w http.ResponseWriter, r *http.Request, params httprouter.Par
start, end = getStartEndDates(duration)
}

if attr == "ops" {
if attr == T_OPS {
chartType := r.URL.Query().Get("type")
op := r.URL.Query().Get("op")
if chartType == "stats" {
chartType := "ops"
docs, err := dbase.GetAverageOpTime(duration)
chartType := T_OPS
docs, err := dbase.GetAverageOpTime(op, duration)
if len(docs) > 0 {
start = docs[0].Date
end = docs[len(docs)-1].Date
Expand All @@ -90,7 +104,7 @@ func ChartsHandler(w http.ResponseWriter, r *http.Request, params httprouter.Par
return
}
} else if chartType == "counts" {
chartType = "ops-counts"
chartType = T_OPS_COUNTS
docs, err := dbase.GetOpsCounts(duration)
if err != nil {
json.NewEncoder(w).Encode(map[string]interface{}{"ok": 0, "error": err.Error()})
Expand All @@ -116,7 +130,7 @@ func ChartsHandler(w http.ResponseWriter, r *http.Request, params httprouter.Par
log.Println("type", chartType, "duration", duration)
}
if chartType == "" || chartType == "accepted" {
chartType = "connections-accepted"
chartType = T_CONNS_ACCEPTED
docs, err := dbase.GetAcceptedConnsCounts(duration)
if err != nil {
json.NewEncoder(w).Encode(map[string]interface{}{"ok": 0, "error": err.Error()})
Expand Down Expand Up @@ -154,13 +168,40 @@ func ChartsHandler(w http.ResponseWriter, r *http.Request, params httprouter.Par
}
return
}
} else if attr == "reslen" {
chartType := r.URL.Query().Get("type")
} else if attr == T_RESLEN_UP {
ip := r.URL.Query().Get("ip")
chartType := attr
if dbase.GetVerbose() {
log.Println("type", chartType, "duration", duration)
}
docs, err := dbase.GetReslenByIP(ip, duration)
if err != nil {
json.NewEncoder(w).Encode(map[string]interface{}{"ok": 0, "error": err.Error()})
return
}
templ, err := GetChartTemplate(PIE_CHART)
if err != nil {
json.NewEncoder(w).Encode(map[string]interface{}{"ok": 0, "error": err.Error()})
return
}
chart := charts[chartType]
if ip != "" {
chart.Title += fmt.Sprintf(" (%v)", ip)
}
doc := map[string]interface{}{"Hatchet": hatchetName, "NameValues": docs, "Chart": chart,
"Type": chartType, "Summary": summary, "Start": start, "End": end}
if err = templ.Execute(w, doc); err != nil {
json.NewEncoder(w).Encode(map[string]interface{}{"ok": 0, "error": err.Error()})
return
}
return
} else if attr == T_RESLEN_NS {
ns := r.URL.Query().Get("ns")
chartType := attr
if dbase.GetVerbose() {
log.Println("type", chartType, "duration", duration)
}
chartType = "reslen"
docs, err := dbase.GetReslenByClients(duration)
docs, err := dbase.GetReslenByNamespace(ns, duration)
if err != nil {
json.NewEncoder(w).Encode(map[string]interface{}{"ok": 0, "error": err.Error()})
return
Expand All @@ -170,7 +211,11 @@ func ChartsHandler(w http.ResponseWriter, r *http.Request, params httprouter.Par
json.NewEncoder(w).Encode(map[string]interface{}{"ok": 0, "error": err.Error()})
return
}
doc := map[string]interface{}{"Hatchet": hatchetName, "NameValues": docs, "Chart": charts[chartType],
chart := charts[chartType]
if ns != "" {
chart.Title += fmt.Sprintf(" (%v)", ns)
}
doc := map[string]interface{}{"Hatchet": hatchetName, "NameValues": docs, "Chart": chart,
"Type": chartType, "Summary": summary, "Start": start, "End": end}
if err = templ.Execute(w, doc); err != nil {
json.NewEncoder(w).Encode(map[string]interface{}{"ok": 0, "error": err.Error()})
Expand Down
25 changes: 17 additions & 8 deletions charts_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ func GetChartTemplate(chartType string) (*template.Template, error) {
html += getConnectionsChart()
}
html += `
<div align=left>
<input type='datetime-local' id='start' value='{{.Start}}'></input>
<input type='datetime-local' id='end' value='{{.End}}'></input>
<button return false;" class="button">Refresh</button>
<div id='hatchetChart' align='center' width='100%'/>
</div></body></html>`
<div style="float: left; width: 100%; clear: left;">
<input type='datetime-local' id='start' value='{{.Start}}'></input>
<input type='datetime-local' id='end' value='{{.End}}'></input>
<button return false;" class="button">Refresh</button>
</div>
<div id='hatchetChart' style="width: 100%; clear: left;"></div>

</body></html>`

return template.New("hatchet").Funcs(template.FuncMap{
"descr": func(v OpCount) template.HTML {
Expand Down Expand Up @@ -84,6 +86,7 @@ func getOpStatsChart() string {
// 'hAxis': { textPosition: 'none' },
'hAxis': { slantedText: true, slantedTextAngle: 30 },
'vAxis': {title: '{{.VAxisLabel}}', minValue: 0},
'width': '100%',
'height': 480,
'titleTextStyle': {'fontSize': 20},
{{if eq $ctype "ops"}}
Expand Down Expand Up @@ -123,6 +126,7 @@ func getPieChart() string {
var options = {
'backgroundColor': { 'fill': 'transparent' },
'title': '{{.Chart.Title}}',
'width': '100%',
'height': 480,
'titleTextStyle': {'fontSize': 20},
'slices': {},
Expand Down Expand Up @@ -157,9 +161,9 @@ func getConnectionsChart() string {

{{range $i, $v := .Remote}}
{{if eq $ctype "connections-time"}}
[new Date("{{$v.Value}}"), {{$v.Accepted}}, {{$v.Ended}}],
[new Date("{{$v.IP}}"), {{$v.Accepted}}, {{$v.Ended}}],
{{else}}
['{{$v.Value}}', {{$v.Accepted}}, {{$v.Ended}}],
['{{$v.IP}}', {{$v.Accepted}}, {{$v.Ended}}],
{{end}}
{{end}}
]);
Expand All @@ -169,11 +173,16 @@ func getConnectionsChart() string {
'title': '{{.Chart.Title}}',
'hAxis': { slantedText: true, slantedTextAngle: 30 },
'vAxis': {title: 'Count', minValue: 0},
'width': '100%',
'height': 480,
'titleTextStyle': {'fontSize': 20},
'legend': { 'position': 'right' } };
// Instantiate and draw our chart, passing in some options.
{{if eq $ctype "connections-time"}}
var chart = new google.visualization.LineChart(document.getElementById('hatchetChart'));
{{else}}
var chart = new google.visualization.ColumnChart(document.getElementById('hatchetChart'));
{{end}}
chart.draw(data, options);
}
</script>
Expand Down
22 changes: 16 additions & 6 deletions database.go
Original file line number Diff line number Diff line change
@@ -1,32 +1,43 @@
// Copyright 2022-present Kuei-chun Chen. All rights reserved.
/*
* Copyright 2022-present Kuei-chun Chen. All rights reserved.
* database.go
*/

package hatchet

type NameValue struct {
Name string
Value int
}

type NameValues struct {
Name string
Values []int
}

type Database interface {
Begin() error
Close() error
Commit() error
CreateMetaData() error
GetAcceptedConnsCounts(duration string) ([]NameValue, error)
GetAuditData() (map[string][]NameValue, error)
GetAverageOpTime(duration string) ([]OpCount, error)
GetAuditData() (map[string][]NameValues, error)
GetAverageOpTime(op string, duration string) ([]OpCount, error)
GetClientPreparedStmt() string
GetConnectionStats(chartType string, duration string) ([]Remote, error)
GetConnectionStats(chartType string, duration string) ([]RemoteClient, error)
GetHatchetInfo() HatchetInfo
GetHatchetInitStmt() string
GetHatchetNames() ([]string, error)
GetHatchetPreparedStmt() string
GetLogs(opts ...string) ([]LegacyLog, error)
GetOpsCounts(duration string) ([]NameValue, error)
GetReslenByClients(duration string) ([]NameValue, error)
GetReslenByNamespace(ip string, duration string) ([]NameValue, error)
GetReslenByIP(ip string, duration string) ([]NameValue, error)
GetSlowOps(orderBy string, order string, collscan bool) ([]OpStat, error)
GetSlowestLogs(topN int) ([]LegacyLog, error)
GetVerbose() bool
InsertClientConn(index int, doc *Logv2Info) error
InsertDriver(index int, doc *Logv2Info) error
InsertLog(index int, end string, doc *Logv2Info, stat *OpStat) error
SearchLogs(opts ...string) ([]LegacyLog, error)
SetVerbose(v bool)
Expand All @@ -36,4 +47,3 @@ type Database interface {
func GetDatabase(hatchetName string) (Database, error) {
return GetSQLite3DB(hatchetName)
}

Loading
0