Skip to content

Commit

Permalink
feat(plans): add plans explorer and viewer (#193)
Browse files Browse the repository at this point in the history
* feat: add ListLineageStats api endpoint and model

* feat: update Terraboard overview to list by lineage

* feat: add last modified path on lineage overview

* feat: add lineage column on search view with filter

* refactor: remove obsolete lineage.html file

* feat(vuejs): init vue project + router config + icon and assets

* feat(vue): add dynamic title managing through mixin

* feat(vue): add navbar and footer components

* feat(vuejs): add overview with charts powered bu Chart.JS 3

* feat(vuejs): callback on state quick access selection
* add lock checking on every state in the overview list with display
* router enhancements
* others fixes / improvements

* feat(vuejs): compare view & controller

* feat(vuejs): search view / controller

* fix(vuejs): issue with dynamic title mixin + code cleanup

* fix(logger): trace method issue with logrus implementation for Gorm

* feat(plans): add plans explorer view
* feat(api): return pagination informations on GET /api/plans
* feat(api): make lineage field optional on GET /api/plans to be able to get all plans

* feat(plans): fetch & list latest plans on lineage view
feat(plans): view on lineage one to consult plan's informations
fix(plans): format date on PlansExplorer view

* feat(plan): dynamic links on PlansExplorer view
refactor(vuejs): simplify panel component selection on State view

* fix(vuejs): refresh issue on lineage change on state view
add key on router-view with refresh event to trigger re-render

* feat(plans): add parsed plan panel

* feat(plans): details tab on plan view
fix(plans): pagination issues on PlanExplorer
refactor(types): rawJson is now json string directly and no longuer Go map

* fix(vuejs): extraneous non-emits event listeners issue
fix(vuejs): plan component reloading issue

* chore: update package-lock.json with new npm version
+ delete old HelloWorld.vue component
+ remove unnecessary console.log

* fix(frontend): set role=button on plans explorer's carets
feat(frontend): use UTC fomat for plan's date
fix(frontend): remove localhost URLs

* feat(frontend): add lineage view to list associated states/views
feat(frontend): separate state and plan views and updated router

* feat(frontend): remove identifier and add workspace to lineage view
  • Loading branch information
hbollon committed Aug 30, 2021
1 parent cc707ea commit 35d73c0
Show file tree
Hide file tree
Showing 18 changed files with 1,412 additions and 16,977 deletions.
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

0 comments on commit 35d73c0

Please sign in to comment.