Skip to content

Commit

Permalink
feat(server/cli): add analyze-log
Browse files Browse the repository at this point in the history
  • Loading branch information
nedpals committed Mar 10, 2024
1 parent 2643160 commit 7745bc9
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 0 deletions.
150 changes: 150 additions & 0 deletions server/cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,24 @@ import (
"io"
"log"
"os"
"path/filepath"
"strings"
"time"

"github.com/nedpals/bugbuddy/server/daemon"
"github.com/nedpals/bugbuddy/server/daemon/types"
"github.com/nedpals/bugbuddy/server/executor"
"github.com/nedpals/bugbuddy/server/helpers"
"github.com/nedpals/bugbuddy/server/logger"
log_analyzer "github.com/nedpals/bugbuddy/server/logger/analyzer"
errorquotient "github.com/nedpals/bugbuddy/server/logger/analyzer/error_quotient"
red "github.com/nedpals/bugbuddy/server/logger/analyzer/repeated_error_density"
timetosolve "github.com/nedpals/bugbuddy/server/logger/analyzer/time_to_solve"
"github.com/nedpals/bugbuddy/server/lsp_server"
"github.com/nedpals/bugbuddy/server/release"
"github.com/nedpals/errgoengine"
"github.com/spf13/cobra"
"github.com/tealeg/xlsx"
)

var rootCmd = &cobra.Command{
Expand Down Expand Up @@ -196,12 +204,154 @@ var runCommandCmd = &cobra.Command{
},
}

type analyzeResults struct {
FilePath string
ErrorQuotient float64
RepeatedErrorDensity float64
TimeToSolve time.Duration
}

var analyzeLogCmd = &cobra.Command{
Use: "analyze-log",
Short: "Analyzes a set of log files. The results will be saved to an excel file.",
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
loggerLoaders := []log_analyzer.LoggerLoader{}

for _, path := range args {
matches, err := filepath.Glob(path)
if err != nil {
log.Fatalln(err)
}

for _, match := range matches {
// check if match is a directory
fi, err := os.Stat(match)
if err != nil {
log.Fatalln(err)
}

if fi.IsDir() {
log.Fatalln("directories are not supported")
}

loggerLoaders = append(loggerLoaders, func() (*logger.Logger, error) {
return logger.NewLoggerFromPath(match)
})

log.Println("loaded", match)
}
}

// TODO: set as configurable flags
analyzers := []string{"eq", "red", "tts"}

// map[analyzer]map[participantId]map[filePath]struct{FilePath string, ErrorQuotient float64, RepeatedErrorDensity float64, TimeToSolve time.Duration}
results := map[string]map[string]*analyzeResults{}

for _, analyzer := range analyzers {
switch analyzer {
case "eq":
eqa := log_analyzer.New[errorquotient.Analyzer](loggerLoaders...)
if err := eqa.Analyze(); err != nil {
log.Fatalln(err)
}

for participantId, filePaths := range eqa.ResultsByParticipant {
if _, ok := results[participantId]; !ok {
results[participantId] = map[string]*analyzeResults{}
}

for filePath, eq := range filePaths {
if _, ok := results[participantId][filePath]; !ok {
results[participantId][filePath] = &analyzeResults{FilePath: filePath}
}

results[participantId][filePath].ErrorQuotient = eq
}
}
case "red":
red := log_analyzer.New[red.Analyzer](loggerLoaders...)
if err := red.Analyze(); err != nil {
log.Fatalln(err)
}

for participantId, filePaths := range red.ResultsByParticipant {
if _, ok := results[participantId]; !ok {
results[participantId] = map[string]*analyzeResults{}
}

for filePath, red := range filePaths {
if _, ok := results[participantId][filePath]; !ok {
results[participantId][filePath] = &analyzeResults{FilePath: filePath}
}

results[participantId][filePath].RepeatedErrorDensity = red
}
}
case "tts":
tts := log_analyzer.New[timetosolve.Analyzer](loggerLoaders...)
if err := tts.Analyze(); err != nil {
log.Fatalln(err)
}

for participantId, filePaths := range tts.ResultsByParticipant {
if _, ok := results[participantId]; !ok {
results[participantId] = map[string]*analyzeResults{}
}

for filePath, tts := range filePaths {
if _, ok := results[participantId][filePath]; !ok {
results[participantId][filePath] = &analyzeResults{FilePath: filePath}
}

results[participantId][filePath].TimeToSolve = tts
}
}
}
}

// save the results to an excel file
wb := xlsx.NewFile()

for participantId, filePaths := range results {
sheet, err := wb.AddSheet(participantId)
if err != nil {
log.Fatalln(err)
}

// write the header
row := sheet.AddRow()
row.AddCell().SetValue("File Path")
row.AddCell().SetValue("Error Quotient")
row.AddCell().SetValue("Repeated Error Density")
row.AddCell().SetValue("Time To Solve")

for _, result := range filePaths {
row = sheet.AddRow()
row.AddCell().SetValue(result.FilePath)
row.AddCell().SetValue(result.ErrorQuotient)
row.AddCell().SetValue(result.RepeatedErrorDensity)
row.AddCell().SetValue(result.TimeToSolve.String())
}
}

// TODO: set as configurable flag
if err := wb.Save("results.xlsx"); err != nil {
log.Fatalln(err)
}

return nil
},
}

func init() {
rootCmd.AddCommand(lspCmd)
rootCmd.AddCommand(daemonCmd)
rootCmd.AddCommand(analyzeCmd)
rootCmd.AddCommand(participantIdCmd)
rootCmd.AddCommand(runCommandCmd)
rootCmd.AddCommand(analyzeLogCmd)
participantIdCmd.PersistentFlags().Bool("generate", false, "generate a new participant ID")
rootCmd.AddCommand(resetCmd)
rootCmd.PersistentFlags().IntP("port", "p", daemon.DEFAULT_PORT, "the port to use for the daemon")
Expand Down
1 change: 1 addition & 0 deletions server/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ require (
github.com/google/uuid v1.5.0 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/tealeg/xlsx v1.0.5 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/tools v0.16.1 // indirect
lukechampine.com/uint128 v1.3.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions server/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/tealeg/xlsx v1.0.5 h1:+f8oFmvY8Gw1iUXzPk+kz+4GpbDZPK1FhPiQRd+ypgE=
github.com/tealeg/xlsx v1.0.5/go.mod h1:btRS8dz54TDnvKNosuAqxrM1QgN1udgk9O34bDCnORM=
go.lsp.dev/jsonrpc2 v0.10.0 h1:Pr/YcXJoEOTMc/b6OTmcR1DPJ3mSWl/SWiU1Cct6VmI=
go.lsp.dev/jsonrpc2 v0.10.0/go.mod h1:fmEzIdXPi/rf6d4uFcayi8HpFP1nBF99ERP1htC72Ac=
go.lsp.dev/pkg v0.0.0-20210717090340-384b27a52fb2 h1:hCzQgh6UcwbKgNSRurYWSqh8MufqRRPODRBblutn4TE=
Expand Down

0 comments on commit 7745bc9

Please sign in to comment.