github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/databases/orm/orm_log.go (about) 1 // The original package is migrated from beego and modified, you can find orignal from following link: 2 // "github.com/beego/beego/" 3 // 4 // Copyright 2023 IAC. All Rights Reserved. 5 // 6 // Licensed under the Apache License, Version 2.0 (the "License"); 7 // you may not use this file except in compliance with the License. 8 // You may obtain a copy of the License at 9 // 10 // http://www.apache.org/licenses/LICENSE-2.0 11 // 12 // Unless required by applicable law or agreed to in writing, software 13 // distributed under the License is distributed on an "AS IS" BASIS, 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 // See the License for the specific language governing permissions and 16 // limitations under the License. 17 18 package orm 19 20 import ( 21 "context" 22 "database/sql" 23 "fmt" 24 "io" 25 "log" 26 "strings" 27 "time" 28 ) 29 30 // Log implement the log.Logger 31 type Log struct { 32 *log.Logger 33 } 34 35 // costomer log func 36 var LogFunc func(query map[string]interface{}) 37 38 // NewLog set io.Writer to create a Logger. 39 func NewLog(out io.Writer) *Log { 40 d := new(Log) 41 d.Logger = log.New(out, "[ORM]", log.LstdFlags) 42 return d 43 } 44 45 func debugLogQueies(alias *alias, operaton, query string, t time.Time, err error, args ...interface{}) { 46 logMap := make(map[string]interface{}) 47 sub := time.Since(t) / 1e5 48 elsp := float64(int(sub)) / 10.0 49 logMap["cost_time"] = elsp 50 flag := " OK" 51 if err != nil { 52 flag = "FAIL" 53 } 54 logMap["flag"] = flag 55 con := fmt.Sprintf(" -[Queries/%s] - [%s / %11s / %7.1fms] - [%s]", alias.Name, flag, operaton, elsp, query) 56 cons := make([]string, 0, len(args)) 57 for _, arg := range args { 58 cons = append(cons, fmt.Sprintf("%v", arg)) 59 } 60 if len(cons) > 0 { 61 con += fmt.Sprintf(" - `%s`", strings.Join(cons, "`, `")) 62 } 63 if err != nil { 64 con += " - " + err.Error() 65 } 66 logMap["sql"] = fmt.Sprintf("%s-`%s`", query, strings.Join(cons, "`, `")) 67 if LogFunc != nil { 68 LogFunc(logMap) 69 } 70 DebugLog.Println(con) 71 } 72 73 // statement query logger struct. 74 // if dev mode, use stmtQueryLog, or use stmtQuerier. 75 type stmtQueryLog struct { 76 alias *alias 77 query string 78 stmt stmtQuerier 79 } 80 81 var _ stmtQuerier = new(stmtQueryLog) 82 83 func (d *stmtQueryLog) Close() error { 84 a := time.Now() 85 err := d.stmt.Close() 86 debugLogQueies(d.alias, "st.Close", d.query, a, err) 87 return err 88 } 89 90 func (d *stmtQueryLog) Exec(args ...interface{}) (sql.Result, error) { 91 return d.ExecContext(context.Background(), args...) 92 } 93 94 func (d *stmtQueryLog) ExecContext(ctx context.Context, args ...interface{}) (sql.Result, error) { 95 a := time.Now() 96 res, err := d.stmt.ExecContext(ctx, args...) 97 debugLogQueies(d.alias, "st.Exec", d.query, a, err, args...) 98 return res, err 99 } 100 101 func (d *stmtQueryLog) Query(args ...interface{}) (*sql.Rows, error) { 102 return d.QueryContext(context.Background(), args...) 103 } 104 105 func (d *stmtQueryLog) QueryContext(ctx context.Context, args ...interface{}) (*sql.Rows, error) { 106 a := time.Now() 107 res, err := d.stmt.QueryContext(ctx, args...) 108 debugLogQueies(d.alias, "st.Query", d.query, a, err, args...) 109 return res, err 110 } 111 112 func (d *stmtQueryLog) QueryRow(args ...interface{}) *sql.Row { 113 return d.QueryRowContext(context.Background(), args...) 114 } 115 116 func (d *stmtQueryLog) QueryRowContext(ctx context.Context, args ...interface{}) *sql.Row { 117 a := time.Now() 118 res := d.stmt.QueryRow(args...) 119 debugLogQueies(d.alias, "st.QueryRow", d.query, a, nil, args...) 120 return res 121 } 122 123 func newStmtQueryLog(alias *alias, stmt stmtQuerier, query string) stmtQuerier { 124 d := new(stmtQueryLog) 125 d.stmt = stmt 126 d.alias = alias 127 d.query = query 128 return d 129 } 130 131 // database query logger struct. 132 // if dev mode, use dbQueryLog, or use dbQuerier. 133 type dbQueryLog struct { 134 alias *alias 135 db dbQuerier 136 tx txer 137 txe txEnder 138 } 139 140 var ( 141 _ dbQuerier = new(dbQueryLog) 142 _ txer = new(dbQueryLog) 143 _ txEnder = new(dbQueryLog) 144 ) 145 146 func (d *dbQueryLog) Prepare(query string) (*sql.Stmt, error) { 147 return d.PrepareContext(context.Background(), query) 148 } 149 150 func (d *dbQueryLog) PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) { 151 a := time.Now() 152 stmt, err := d.db.PrepareContext(ctx, query) 153 debugLogQueies(d.alias, "db.Prepare", query, a, err) 154 return stmt, err 155 } 156 157 func (d *dbQueryLog) Exec(query string, args ...interface{}) (sql.Result, error) { 158 return d.ExecContext(context.Background(), query, args...) 159 } 160 161 func (d *dbQueryLog) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) { 162 a := time.Now() 163 res, err := d.db.ExecContext(ctx, query, args...) 164 debugLogQueies(d.alias, "db.Exec", query, a, err, args...) 165 return res, err 166 } 167 168 func (d *dbQueryLog) Query(query string, args ...interface{}) (*sql.Rows, error) { 169 return d.QueryContext(context.Background(), query, args...) 170 } 171 172 func (d *dbQueryLog) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) { 173 a := time.Now() 174 res, err := d.db.QueryContext(ctx, query, args...) 175 debugLogQueies(d.alias, "db.Query", query, a, err, args...) 176 return res, err 177 } 178 179 func (d *dbQueryLog) QueryRow(query string, args ...interface{}) *sql.Row { 180 return d.QueryRowContext(context.Background(), query, args...) 181 } 182 183 func (d *dbQueryLog) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row { 184 a := time.Now() 185 res := d.db.QueryRowContext(ctx, query, args...) 186 debugLogQueies(d.alias, "db.QueryRow", query, a, nil, args...) 187 return res 188 } 189 190 func (d *dbQueryLog) Begin() (*sql.Tx, error) { 191 return d.BeginTx(context.Background(), nil) 192 } 193 194 func (d *dbQueryLog) BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error) { 195 a := time.Now() 196 tx, err := d.db.(txer).BeginTx(ctx, opts) 197 debugLogQueies(d.alias, "db.BeginTx", "START TRANSACTION", a, err) 198 return tx, err 199 } 200 201 func (d *dbQueryLog) Commit() error { 202 a := time.Now() 203 err := d.db.(txEnder).Commit() 204 debugLogQueies(d.alias, "tx.Commit", "COMMIT", a, err) 205 return err 206 } 207 208 func (d *dbQueryLog) Rollback() error { 209 a := time.Now() 210 err := d.db.(txEnder).Rollback() 211 debugLogQueies(d.alias, "tx.Rollback", "ROLLBACK", a, err) 212 return err 213 } 214 215 func (d *dbQueryLog) RollbackUnlessCommit() error { 216 a := time.Now() 217 err := d.db.(txEnder).RollbackUnlessCommit() 218 debugLogQueies(d.alias, "tx.RollbackUnlessCommit", "ROLLBACK UNLESS COMMIT", a, err) 219 return err 220 } 221 222 func (d *dbQueryLog) SetDB(db dbQuerier) { 223 d.db = db 224 } 225 226 func newDbQueryLog(alias *alias, db dbQuerier) dbQuerier { 227 d := new(dbQueryLog) 228 d.alias = alias 229 d.db = db 230 return d 231 }