Skip to content

Commit

Permalink
feat: summarize to use errors instead of panics
Browse files Browse the repository at this point in the history
Signed-off-by: Andres Taylor <[email protected]>
  • Loading branch information
systay committed Dec 4, 2024
1 parent aecd218 commit de921ee
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 84 deletions.
27 changes: 15 additions & 12 deletions go/summarize/force-graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package summarize

import (
"encoding/json"
"errors"
"fmt"
"html/template"
"net"
Expand Down Expand Up @@ -132,43 +133,43 @@ func createGraphKey(tableA, tableB string) graphKey {
return graphKey{Tbl1: tableB, Tbl2: tableA}
}

func renderQueryGraph(s *Summary) {
func renderQueryGraph(s *Summary) error {
data := createForceGraphData(s)

listener, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
panic(err)
return fmt.Errorf("could not create a listener: %w", err)
}
defer listener.Close()

// Get the assigned port
addr, ok := listener.Addr().(*net.TCPAddr)
if !ok {
exit("could not create a listener")
return errors.New("could not create a listener")
}
fmt.Printf("Server started at http://localhost:%d\nExit the program with CTRL+C\n", addr.Port)

// Start the server
// nolint: gosec,nolintlint // this is all ran locally so no need to care about vulnerabilities around timeouts
err = http.Serve(listener, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
serveIndex(w, data)
return http.Serve(listener, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
err := serveIndex(w, data)
if err != nil {
fmt.Println(err.Error())
}
}))
if err != nil {
exit(err.Error())
}
}

// Function to dynamically generate and serve index.html
func serveIndex(w http.ResponseWriter, data forceGraphData) {
func serveIndex(w http.ResponseWriter, data forceGraphData) error {
dataBytes, err := json.Marshal(data.data)
if err != nil {
exit(err.Error())
return fmt.Errorf("could not marshal data: %w", err)
}

tmpl, err := template.New("index").Parse(templateHTML)
if err != nil {
http.Error(w, "Failed to parse template", http.StatusInternalServerError)
return
return err
}

d := struct {
Expand All @@ -182,8 +183,10 @@ func serveIndex(w http.ResponseWriter, data forceGraphData) {

if err := tmpl.Execute(w, d); err != nil {
http.Error(w, "Failed to execute template", http.StatusInternalServerError)
return
return err
}

return nil
}

/*
Expand Down
8 changes: 7 additions & 1 deletion go/summarize/markdown.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,13 @@ func renderHotQueries(md *markdown.MarkDown, queries []keys.QueryAnalysisResult,
}
}

func renderTableUsage(md *markdown.MarkDown, tableSummaries []*TableSummary, includeRowCount bool) {
func renderTableUsage(md *markdown.MarkDown, in []*TableSummary, includeRowCount bool) {
var tableSummaries []*TableSummary
for _, tbl := range in {
if !tbl.IsEmpty() {
tableSummaries = append(tableSummaries, tbl)
}
}
if len(tableSummaries) == 0 {
return
}
Expand Down
36 changes: 19 additions & 17 deletions go/summarize/reading.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package summarize

import (
"encoding/json"
"fmt"
"os"
"sort"
"strconv"
Expand All @@ -27,10 +28,10 @@ import (
"github.com/vitessio/vt/go/transactions"
)

func readTracedFile(fileName string) traceSummary {
func readTracedFile(fileName string) (traceSummary, error) {
c, err := os.ReadFile(fileName)
if err != nil {
exit("Error opening file: " + err.Error())
return traceSummary{}, fmt.Errorf("error opening file: %w", err)
}

type traceOutput struct {
Expand All @@ -40,7 +41,7 @@ func readTracedFile(fileName string) traceSummary {
var to traceOutput
err = json.Unmarshal(c, &to)
if err != nil {
exit("Error parsing json: " + err.Error())
return traceSummary{}, fmt.Errorf("error parsing json: %w", err)
}

sort.Slice(to.Queries, func(i, j int) bool {
Expand All @@ -58,13 +59,15 @@ func readTracedFile(fileName string) traceSummary {
return traceSummary{
Name: fileName,
TracedQueries: to.Queries,
}
}, nil
}

func readTransactionFile(fileName string) func(s *Summary) error {
type summarizer = func(s *Summary) error

func readTransactionFile(fileName string) (summarizer, error) {
c, err := os.ReadFile(fileName)
if err != nil {
exit("Error opening file: " + err.Error())
return nil, fmt.Errorf("error opening file: %w", err)
}

type txOutput struct {
Expand All @@ -75,37 +78,36 @@ func readTransactionFile(fileName string) func(s *Summary) error {
var to txOutput
err = json.Unmarshal(c, &to)
if err != nil {
exit("Error parsing json: " + err.Error())
return nil, fmt.Errorf("error parsing json: %w", err)
}
return func(s *Summary) error {
s.analyzedFiles = append(s.analyzedFiles, fileName)
return summarizeTransactions(s, to.Signatures)
}
}, nil
}

func readKeysFile(fileName string) func(s *Summary) error {
func readKeysFile(fileName string) (summarizer, error) {
c, err := os.ReadFile(fileName)
if err != nil {
exit("Error opening file: " + err.Error())
return nil, fmt.Errorf("error opening file: %w", err)
}

var ko keys.Output
err = json.Unmarshal(c, &ko)
if err != nil {
exit("Error parsing json: " + err.Error())
return nil, fmt.Errorf("error parsing json: %w", err)
}

return func(s *Summary) error {
s.analyzedFiles = append(s.analyzedFiles, fileName)
summarizeKeysQueries(s, &ko)
return nil
}
return summarizeKeysQueries(s, &ko)
}, nil
}

func readDBInfoFile(fileName string) func(s *Summary) error {
func readDBInfoFile(fileName string) (summarizer, error) {
schemaInfo, err := dbinfo.Load(fileName)
if err != nil {
panic(err)
return nil, fmt.Errorf("error parsing dbinfo: %w", err)
}

return func(s *Summary) error {
Expand All @@ -120,5 +122,5 @@ func readDBInfoFile(fileName string) func(s *Summary) error {
table.RowCount = ti.Rows
}
return nil
}
}, nil
}
4 changes: 3 additions & 1 deletion go/summarize/reading_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestReadTransaction(t *testing.T) {
file := readTransactionFile("../testdata/small-slow-query-transactions.json")
file, err := readTransactionFile("../testdata/small-slow-query-transactions.json")
require.NoError(t, err)
assert.NotNil(t, file)
}
24 changes: 12 additions & 12 deletions go/summarize/summarize-keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func (p Position) String() string {
return "GROUP"
}

panic("unknown Position")
return "UNKNOWN"
}

func (ci ColumnInformation) String() string {
Expand Down Expand Up @@ -139,31 +139,30 @@ func (ts TableSummary) UseCount() int {

type getMetric = func(q keys.QueryAnalysisResult) float64

func getMetricForHotness(metric string) getMetric {
func getMetricForHotness(metric string) (getMetric, error) {
switch metric {
case "usage-count":
return func(q keys.QueryAnalysisResult) float64 {
return float64(q.UsageCount)
}
}, nil
case "total-rows-examined":
return func(q keys.QueryAnalysisResult) float64 {
return float64(q.RowsExamined)
}
}, nil
case "avg-rows-examined":
return func(q keys.QueryAnalysisResult) float64 {
return float64(q.RowsExamined) / float64(q.UsageCount)
}
}, nil
case "total-time", "":
return func(q keys.QueryAnalysisResult) float64 {
return q.QueryTime
}
}, nil
case "avg-time":
return func(q keys.QueryAnalysisResult) float64 {
return q.QueryTime / float64(q.UsageCount)
}
}, nil
default:
exit(fmt.Sprintf("unknown metric: %s", metric))
panic("unreachable")
return nil, fmt.Errorf("unknown metric: %s", metric)
}
}

Expand All @@ -185,7 +184,7 @@ func makeKey(lhs, rhs operators.Column) graphKey {
return graphKey{rhs.Table, lhs.Table}
}

func summarizeKeysQueries(summary *Summary, queries *keys.Output) {
func summarizeKeysQueries(summary *Summary, queries *keys.Output) error {
tableSummaries := make(map[string]*TableSummary)
tableUsageWriteCounts := make(map[string]int)
tableUsageReadCounts := make(map[string]int)
Expand Down Expand Up @@ -218,11 +217,11 @@ func summarizeKeysQueries(summary *Summary, queries *keys.Output) {
table.ReadQueryCount = tblSummary.ReadQueryCount
table.WriteQueryCount = tblSummary.WriteQueryCount
if table.ColumnUses != nil {
panic("ColumnUses already set for table" + tblSummary.Table)
return fmt.Errorf("ColumnUses already set for table %s", tblSummary.Table)
}
table.ColumnUses = tblSummary.ColumnUses
if table.JoinPredicates != nil {
panic("JoinPredicates already set for table" + tblSummary.Table)
return fmt.Errorf("JoinPredicates already set for table %s", tblSummary.Table)
}
table.JoinPredicates = tblSummary.JoinPredicates
}
Expand Down Expand Up @@ -269,6 +268,7 @@ func summarizeKeysQueries(summary *Summary, queries *keys.Output) {
}
return summary.joins[i].Tbl2 < summary.joins[j].Tbl2
})
return nil
}

func checkQueryForHotness(hotQueries *[]keys.QueryAnalysisResult, query keys.QueryAnalysisResult, metricReader getMetric) {
Expand Down
26 changes: 17 additions & 9 deletions go/summarize/summarize-keys_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,18 +70,23 @@ func TestSummarizeKeysFile(t *testing.T) {
sb := &strings.Builder{}
now := time.Date(2024, time.January, 1, 1, 2, 3, 0, time.UTC)

fnKeys := readKeysFile("../testdata/keys-log.json")
fnSchemaInfo := readDBInfoFile("../testdata/keys-schema-info.json")
fnKeys, err := readKeysFile("../testdata/keys-log.json")
require.NoError(t, err)

fnSchemaInfo, err := readDBInfoFile("../testdata/keys-schema-info.json")
require.NoError(t, err)

s := NewSummary("")
s, err := NewSummary("")
require.NoError(t, err)

err := fnKeys(s)
err = fnKeys(s)
require.NoError(t, err)

err = fnSchemaInfo(s)
require.NoError(t, err)

s.PrintMarkdown(sb, now)
err = s.PrintMarkdown(sb, now)
require.NoError(t, err)

expected, err := os.ReadFile("../testdata/keys-summary.md")
require.NoError(t, err)
Expand All @@ -102,16 +107,19 @@ func TestSummarizeKeysWithHotnessFile(t *testing.T) {

for _, metric := range tests {
t.Run(metric, func(t *testing.T) {
fn := readKeysFile("../testdata/bigger_slow_query_log.json")
fn, err := readKeysFile("../testdata/bigger_slow_query_log.json")
require.NoError(t, err)
sb := &strings.Builder{}
now := time.Date(2024, time.January, 1, 1, 2, 3, 0, time.UTC)

s := NewSummary(metric)
s, err := NewSummary(metric)
require.NoError(t, err)

err := fn(s)
err = fn(s)
require.NoError(t, err)

s.PrintMarkdown(sb, now)
err = s.PrintMarkdown(sb, now)
require.NoError(t, err)

expected, err := os.ReadFile(fmt.Sprintf("../testdata/bigger_slow_log_%s.md", metric))
require.NoError(t, err)
Expand Down
4 changes: 3 additions & 1 deletion go/summarize/summarize-trace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func tf1() traceSummary {
Expand Down Expand Up @@ -183,7 +184,8 @@ Summary:
}

func TestSummarizeTraceFile(t *testing.T) {
tq := readTracedFile("../testdata/trace-log.json")
tq, err := readTracedFile("../testdata/trace-log.json")
require.NoError(t, err)
sb := &strings.Builder{}
printTraceSummary(sb, 80, noHighlight, tq)
expected := `Query: INSERT INTO region (R_REGIONKEY, R_NAME, R_COMMENT) VALUES (1, 'ASIA',...
Expand Down
11 changes: 7 additions & 4 deletions go/summarize/summarize-transactions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,17 @@ func TestSummarizeTransactionsFile(t *testing.T) {
sb := &strings.Builder{}
now := time.Date(2024, time.January, 1, 1, 2, 3, 0, time.UTC)

fnTx := readTransactionFile("../testdata/small-slow-query-transactions.json")
fnTx, err := readTransactionFile("../testdata/small-slow-query-transactions.json")
require.NoError(t, err)

s := NewSummary("")
s, err := NewSummary("")
require.NoError(t, err)

err := fnTx(s)
err = fnTx(s)
require.NoError(t, err)

s.PrintMarkdown(sb, now)
err = s.PrintMarkdown(sb, now)
require.NoError(t, err)

expected, err := os.ReadFile("../testdata/transactions-summary.md")
require.NoError(t, err)
Expand Down
Loading

0 comments on commit de921ee

Please sign in to comment.