Skip to content
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

feat(plans): add plans explorer and viewer #193

Merged
merged 25 commits into from Aug 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
ff97282
feat: add ListLineageStats api endpoint and model
hbollon Jun 28, 2021
f06c251
feat: update Terraboard overview to list by lineage
hbollon Jun 28, 2021
e94f5b1
feat: add last modified path on lineage overview
hbollon Jun 29, 2021
405c127
feat: add lineage column on search view with filter
hbollon Jun 30, 2021
f15d5ae
refactor: remove obsolete lineage.html file
hbollon Jul 15, 2021
880a3e4
feat(vuejs): init vue project + router config + icon and assets
hbollon Jul 6, 2021
a279e0e
feat(vue): add dynamic title managing through mixin
hbollon Jul 8, 2021
ff94a94
feat(vue): add navbar and footer components
hbollon Jul 9, 2021
232e4c8
feat(vuejs): add overview with charts powered bu Chart.JS 3
hbollon Jul 12, 2021
e3481a8
feat(vuejs): callback on state quick access selection
hbollon Jul 15, 2021
7eefd22
feat(vuejs): compare view & controller
hbollon Jul 20, 2021
f370c5f
feat(vuejs): search view / controller
hbollon Jul 21, 2021
7f0aafd
fix(vuejs): issue with dynamic title mixin + code cleanup
hbollon Jul 21, 2021
cc467bf
fix(logger): trace method issue with logrus implementation for Gorm
hbollon Jul 29, 2021
7cdd9a5
feat(plans): add plans explorer view
hbollon Jul 29, 2021
78a0e25
feat(plans): fetch & list latest plans on lineage view
hbollon Aug 2, 2021
1339e5e
feat(plan): dynamic links on PlansExplorer view
hbollon Aug 2, 2021
40d6a1a
fix(vuejs): refresh issue on lineage change on state view
hbollon Aug 3, 2021
06d0a2e
feat(plans): add parsed plan panel
hbollon Aug 4, 2021
4276055
feat(plans): details tab on plan view
hbollon Aug 4, 2021
10c4f58
fix(vuejs): extraneous non-emits event listeners issue
hbollon Aug 4, 2021
91ac1eb
chore: update package-lock.json with new npm version
hbollon Aug 4, 2021
5cd7969
fix(frontend): set role=button on plans explorer's carets
hbollon Aug 18, 2021
2b57197
feat(frontend): add lineage view to list associated states/views
hbollon Aug 27, 2021
f0ae54b
feat(frontend): remove identifier and add workspace to lineage view
hbollon Aug 30, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 9 additions & 2 deletions api/api.go
Expand Up @@ -276,14 +276,21 @@ func SubmitPlan(w http.ResponseWriter, r *http.Request, db *db.Database) {

// GetPlans provides all Plan by lineage.
// Optional "&limit=X" parameter to limit requested quantity of plans.
// Optional "&page=X" parameter to add an offset to the query and enable pagination.
// Sorted by most recent to oldest.
// /api/plans GET endpoint callback
// Also return pagination informations (current page ans total items count in database)
func GetPlans(w http.ResponseWriter, r *http.Request, db *db.Database) {
lineage := r.URL.Query().Get("lineage")
limit := r.URL.Query().Get("limit")
plans := db.GetPlans(lineage, limit)
page := r.URL.Query().Get("page")
plans, currentPage, total := db.GetPlans(lineage, limit, page)

j, err := json.Marshal(plans)
response := make(map[string]interface{})
response["plans"] = plans
response["page"] = currentPage
response["total"] = total
j, err := json.Marshal(response)
if err != nil {
log.Errorf("Failed to marshal plans: %v", err)
JSONError(w, "Failed to marshal plans", err)
Expand Down
33 changes: 30 additions & 3 deletions db/db.go
Expand Up @@ -620,7 +620,19 @@ func (db *Database) InsertPlan(plan []byte) error {
}

// GetPlans retrieves all Plan of a lineage from the database
func (db *Database) GetPlans(lineage, limitStr string) (plans []types.Plan) {
func (db *Database) GetPlans(lineage, limitStr, pageStr string) (plans []types.Plan, page int, total int) {
var whereClause []interface{}
var whereClauseTotal string
if lineage != "" {
whereClause = append(whereClause, `"Lineage"."value" = ?`, lineage)
whereClauseTotal = ` JOIN lineages on lineages.id=t.lineage_id WHERE lineages.value = ?`
}

row := db.Raw("SELECT count(*) FROM plans AS t"+whereClauseTotal, lineage).Row()
if err := row.Scan(&total); err != nil {
log.Error(err.Error())
}

var limit int
if limitStr == "" {
limit = -1
Expand All @@ -633,7 +645,20 @@ func (db *Database) GetPlans(lineage, limitStr string) (plans []types.Plan) {
}
}

db.Joins("JOIN lineages on plans.lineage_id=lineages.id").
var offset int
if pageStr == "" {
offset = -1
} else {
var err error
page, err = strconv.Atoi(pageStr)
if err != nil {
log.Warnf("GetPlans offset ignored: %v", err)
} else {
offset = (page - 1) * pageSize
}
}

db.Joins("Lineage").
Preload("ParsedPlan").
Preload("ParsedPlan.PlanStateValue").
Preload("ParsedPlan.PlanStateValue.PlanStateOutputs").
Expand All @@ -655,7 +680,9 @@ func (db *Database) GetPlans(lineage, limitStr string) (plans []types.Plan) {
Preload("ParsedPlan.PlanState.PlanStateValue.PlanStateModule.PlanStateModules").
Order("created_at desc").
Limit(limit).
Find(&plans, "lineages.value = ?", lineage)
Offset(offset).
Find(&plans, whereClause...)

return
}

Expand Down
37 changes: 15 additions & 22 deletions db/logger.go
Expand Up @@ -18,22 +18,15 @@ import (

// GormLogger is a wrapper class that implement Gorm logger interface
type GormLogger struct {
GormLoggerConfig
}

// GormLoggerConfig handle GormLogger config (log level, slow threshold)
type GormLoggerConfig struct {
LogLevel logger.LogLevel
SlowThreshold time.Duration
}

var (
// LogrusGormLogger default GormLogger instance for Gorm logging through Logrus
LogrusGormLogger = GormLogger{
GormLoggerConfig{
LogLevel: logger.Warn,
SlowThreshold: 200 * time.Millisecond,
},
LogLevel: logger.Warn,
SlowThreshold: 200 * time.Millisecond,
}
)

Expand All @@ -45,52 +38,52 @@ func (l *GormLogger) LogMode(level logger.LogLevel) logger.Interface {
}

// Info print info
func (l *GormLogger) Info(_ context.Context, msg string, data ...interface{}) {
func (l *GormLogger) Info(ctx context.Context, msg string, data ...interface{}) {
if l.LogLevel >= logger.Info {
logrus.Info(msg, append([]interface{}{utils.FileWithLineNum()}, data...))
logrus.WithContext(ctx).Info(msg, append([]interface{}{utils.FileWithLineNum()}, data...))
}
}

// Warn print warn messages
func (l *GormLogger) Warn(_ context.Context, msg string, data ...interface{}) {
func (l *GormLogger) Warn(ctx context.Context, msg string, data ...interface{}) {
if l.LogLevel >= logger.Warn {
logrus.Warn(msg, append([]interface{}{utils.FileWithLineNum()}, data...))
logrus.WithContext(ctx).Warn(msg, append([]interface{}{utils.FileWithLineNum()}, data...))
}
}

// Error print error messages
func (l *GormLogger) Error(_ context.Context, msg string, data ...interface{}) {
func (l *GormLogger) Error(ctx context.Context, msg string, data ...interface{}) {
if l.LogLevel >= logger.Error {
logrus.Warn(msg, append([]interface{}{utils.FileWithLineNum()}, data...))
logrus.WithContext(ctx).Error(msg, append([]interface{}{utils.FileWithLineNum()}, data...))
}
}

// Trace print sql message
func (l *GormLogger) Trace(_ context.Context, begin time.Time, fc func() (string, int64), err error) {
func (l *GormLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
if l.LogLevel > 0 {
elapsed := time.Since(begin)
switch {
case err != nil && l.LogLevel >= logger.Error:
sql, rows := fc()
if rows == -1 {
logrus.Trace(utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, "-", sql)
logrus.WithContext(ctx).Error(utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, "-", sql)
} else {
logrus.Trace(utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, rows, sql)
logrus.WithContext(ctx).Error(utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, rows, sql)
}
case elapsed > l.SlowThreshold && l.SlowThreshold != 0 && l.LogLevel >= logger.Warn:
sql, rows := fc()
slowLog := fmt.Sprintf("SLOW SQL >= %v", l.SlowThreshold)
if rows == -1 {
logrus.Trace(utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, "-", sql)
logrus.WithContext(ctx).Warn(utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, "-", sql)
} else {
logrus.Trace(utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, rows, sql)
logrus.WithContext(ctx).Warn(utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, rows, sql)
}
case l.LogLevel >= logger.Info:
sql, rows := fc()
if rows == -1 {
logrus.Trace(utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, "-", sql)
logrus.WithContext(ctx).Debug(utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, "-", sql)
} else {
logrus.Trace(utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, rows, sql)
logrus.WithContext(ctx).Debug(utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, rows, sql)
}
}
}
Expand Down