github.com/pingcap/br@v5.3.0-alpha.0.20220125034240-ec59c7b6ce30+incompatible/pkg/lightning/restore/check_template.go (about) 1 // Copyright 2020 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package restore 15 16 import ( 17 "fmt" 18 19 "github.com/jedib0t/go-pretty/v6/table" 20 "github.com/jedib0t/go-pretty/v6/text" 21 ) 22 23 type CheckType string 24 25 const ( 26 Critical CheckType = "critical" 27 Warn CheckType = "performance" 28 ) 29 30 type Template interface { 31 // Collect mainly collect performance related checks' results and critical level checks' results. 32 // If the performance is not as expect. It will output a warn to user and it won't break the whole import task. 33 // if one of critical check not passed. it will stop import task. 34 Collect(t CheckType, passed bool, msg string) 35 36 // Success represents the whole check has passed or not. 37 Success() bool 38 39 // FailedCount represents (the warn check failed count, the critical check failed count) 40 FailedCount(t CheckType) int 41 42 // Output print all checks results. 43 Output() string 44 } 45 46 type SimpleTemplate struct { 47 count int 48 warnFailedCount int 49 criticalFailedCount int 50 t table.Writer 51 } 52 53 func NewSimpleTemplate() Template { 54 t := table.NewWriter() 55 t.AppendHeader(table.Row{"#", "Check Item", "Type", "Passed"}) 56 t.SetColumnConfigs([]table.ColumnConfig{ 57 {Name: "#", WidthMax: 6}, 58 {Name: "Check Item", WidthMax: 130}, 59 {Name: "Type", WidthMax: 20}, 60 {Name: "Passed", WidthMax: 6}, 61 }) 62 return &SimpleTemplate{ 63 0, 64 0, 65 0, 66 t, 67 } 68 } 69 70 func (c *SimpleTemplate) Collect(t CheckType, passed bool, msg string) { 71 c.count++ 72 if !passed { 73 switch t { 74 case Critical: 75 { 76 c.criticalFailedCount++ 77 } 78 case Warn: 79 c.warnFailedCount++ 80 } 81 } 82 c.t.AppendRow(table.Row{c.count, msg, t, passed}) 83 c.t.AppendSeparator() 84 } 85 86 func (c *SimpleTemplate) Success() bool { 87 return c.warnFailedCount+c.criticalFailedCount == 0 88 } 89 90 func (c *SimpleTemplate) FailedCount(t CheckType) int { 91 if t == Warn { 92 return c.warnFailedCount 93 } 94 if t == Critical { 95 return c.criticalFailedCount 96 } 97 return 0 98 } 99 100 func (c *SimpleTemplate) Output() string { 101 c.t.SetAllowedRowLength(170) 102 c.t.SetRowPainter(table.RowPainter(func(row table.Row) text.Colors { 103 if passed, ok := row[3].(bool); ok { 104 if !passed { 105 if typ, ok := row[2].(CheckType); ok { 106 if typ == Warn { 107 return text.Colors{text.FgYellow} 108 } 109 if typ == Critical { 110 return text.Colors{text.FgRed} 111 } 112 } 113 } 114 } 115 return nil 116 })) 117 res := c.t.Render() 118 summary := "\n" 119 if c.criticalFailedCount > 0 { 120 summary += fmt.Sprintf("%d critical check failed", c.criticalFailedCount) 121 } 122 if c.warnFailedCount > 0 { 123 msg := fmt.Sprintf("%d performance check failed", c.warnFailedCount) 124 if len(summary) > 1 { 125 msg = "," + msg 126 } 127 summary += msg 128 } 129 return res + summary 130 }