Update Logger
This commit is contained in:
		
							parent
							
								
									1684bf726e
								
							
						
					
					
						commit
						48cf28258f
					
				
							
								
								
									
										118
									
								
								logger.go
									
									
									
									
									
								
							
							
						
						
									
										118
									
								
								logger.go
									
									
									
									
									
								
							@ -1,119 +1 @@
 | 
			
		||||
package gorm
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"database/sql/driver"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"log"
 | 
			
		||||
	"os"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"time"
 | 
			
		||||
	"unicode"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	defaultLogger            = Logger{log.New(os.Stdout, "\r\n", 0)}
 | 
			
		||||
	sqlRegexp                = regexp.MustCompile(`\?`)
 | 
			
		||||
	numericPlaceHolderRegexp = regexp.MustCompile(`\$\d+`)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func isPrintable(s string) bool {
 | 
			
		||||
	for _, r := range s {
 | 
			
		||||
		if !unicode.IsPrint(r) {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var LogFormatter = func(values ...interface{}) (messages []interface{}) {
 | 
			
		||||
	if len(values) > 1 {
 | 
			
		||||
		var (
 | 
			
		||||
			sql             string
 | 
			
		||||
			formattedValues []string
 | 
			
		||||
			level           = values[0]
 | 
			
		||||
			currentTime     = "\n\033[33m[" + NowFunc().Format("2006-01-02 15:04:05") + "]\033[0m"
 | 
			
		||||
			source          = fmt.Sprintf("\033[35m(%v)\033[0m", values[1])
 | 
			
		||||
		)
 | 
			
		||||
 | 
			
		||||
		messages = []interface{}{source, currentTime}
 | 
			
		||||
 | 
			
		||||
		if level == "sql" {
 | 
			
		||||
			// duration
 | 
			
		||||
			messages = append(messages, fmt.Sprintf(" \033[36;1m[%.2fms]\033[0m ", float64(values[2].(time.Duration).Nanoseconds()/1e4)/100.0))
 | 
			
		||||
			// sql
 | 
			
		||||
 | 
			
		||||
			for _, value := range values[4].([]interface{}) {
 | 
			
		||||
				indirectValue := reflect.Indirect(reflect.ValueOf(value))
 | 
			
		||||
				if indirectValue.IsValid() {
 | 
			
		||||
					value = indirectValue.Interface()
 | 
			
		||||
					if t, ok := value.(time.Time); ok {
 | 
			
		||||
						formattedValues = append(formattedValues, fmt.Sprintf("'%v'", t.Format("2006-01-02 15:04:05")))
 | 
			
		||||
					} else if b, ok := value.([]byte); ok {
 | 
			
		||||
						if str := string(b); isPrintable(str) {
 | 
			
		||||
							formattedValues = append(formattedValues, fmt.Sprintf("'%v'", str))
 | 
			
		||||
						} else {
 | 
			
		||||
							formattedValues = append(formattedValues, "'<binary>'")
 | 
			
		||||
						}
 | 
			
		||||
					} else if r, ok := value.(driver.Valuer); ok {
 | 
			
		||||
						if value, err := r.Value(); err == nil && value != nil {
 | 
			
		||||
							formattedValues = append(formattedValues, fmt.Sprintf("'%v'", value))
 | 
			
		||||
						} else {
 | 
			
		||||
							formattedValues = append(formattedValues, "NULL")
 | 
			
		||||
						}
 | 
			
		||||
					} else {
 | 
			
		||||
						formattedValues = append(formattedValues, fmt.Sprintf("'%v'", value))
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					formattedValues = append(formattedValues, "NULL")
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// differentiate between $n placeholders or else treat like ?
 | 
			
		||||
			if numericPlaceHolderRegexp.MatchString(values[3].(string)) {
 | 
			
		||||
				sql = values[3].(string)
 | 
			
		||||
				for index, value := range formattedValues {
 | 
			
		||||
					placeholder := fmt.Sprintf(`\$%d([^\d]|$)`, index+1)
 | 
			
		||||
					sql = regexp.MustCompile(placeholder).ReplaceAllString(sql, value+"$1")
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				formattedValuesLength := len(formattedValues)
 | 
			
		||||
				for index, value := range sqlRegexp.Split(values[3].(string), -1) {
 | 
			
		||||
					sql += value
 | 
			
		||||
					if index < formattedValuesLength {
 | 
			
		||||
						sql += formattedValues[index]
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			messages = append(messages, sql)
 | 
			
		||||
			messages = append(messages, fmt.Sprintf(" \n\033[36;31m[%v]\033[0m ", strconv.FormatInt(values[5].(int64), 10)+" rows affected or returned "))
 | 
			
		||||
		} else {
 | 
			
		||||
			messages = append(messages, "\033[31;1m")
 | 
			
		||||
			messages = append(messages, values[2:]...)
 | 
			
		||||
			messages = append(messages, "\033[0m")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type logger interface {
 | 
			
		||||
	Print(v ...interface{})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LogWriter log writer interface
 | 
			
		||||
type LogWriter interface {
 | 
			
		||||
	Println(v ...interface{})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Logger default logger
 | 
			
		||||
type Logger struct {
 | 
			
		||||
	LogWriter
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Print format & print log
 | 
			
		||||
func (logger Logger) Print(values ...interface{}) {
 | 
			
		||||
	logger.Println(LogFormatter(values...)...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										88
									
								
								logger/formatter.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								logger/formatter.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,88 @@
 | 
			
		||||
package logger
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"database/sql/driver"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"time"
 | 
			
		||||
	"unicode"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	sqlRegexp                = regexp.MustCompile(`\?`)
 | 
			
		||||
	numericPlaceHolderRegexp = regexp.MustCompile(`\$\d+`)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func isPrintable(s string) bool {
 | 
			
		||||
	for _, r := range s {
 | 
			
		||||
		if !unicode.IsPrint(r) {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SQLFormatter(values ...interface{}) (messages []interface{}) {
 | 
			
		||||
	if len(values) > 1 {
 | 
			
		||||
		var (
 | 
			
		||||
			sql             string
 | 
			
		||||
			formattedValues []string
 | 
			
		||||
			currentTime     = time.Now().Format("2006-01-02 15:04:05")
 | 
			
		||||
		)
 | 
			
		||||
 | 
			
		||||
		messages = []interface{}{currentTime}
 | 
			
		||||
 | 
			
		||||
		// duration
 | 
			
		||||
		messages = append(messages, fmt.Sprintf(" [%.2fms]", float64(values[0].(time.Duration).Nanoseconds()/1e4)/100.0))
 | 
			
		||||
 | 
			
		||||
		for _, value := range values[2].([]interface{}) {
 | 
			
		||||
			indirectValue := reflect.Indirect(reflect.ValueOf(value))
 | 
			
		||||
			if indirectValue.IsValid() {
 | 
			
		||||
				value = indirectValue.Interface()
 | 
			
		||||
				if t, ok := value.(time.Time); ok {
 | 
			
		||||
					formattedValues = append(formattedValues, fmt.Sprintf("'%v'", t.Format("2006-01-02 15:04:05")))
 | 
			
		||||
				} else if b, ok := value.([]byte); ok {
 | 
			
		||||
					if str := string(b); isPrintable(str) {
 | 
			
		||||
						formattedValues = append(formattedValues, fmt.Sprintf("'%v'", str))
 | 
			
		||||
					} else {
 | 
			
		||||
						formattedValues = append(formattedValues, "'<binary>'")
 | 
			
		||||
					}
 | 
			
		||||
				} else if r, ok := value.(driver.Valuer); ok {
 | 
			
		||||
					if value, err := r.Value(); err == nil && value != nil {
 | 
			
		||||
						formattedValues = append(formattedValues, fmt.Sprintf("'%v'", value))
 | 
			
		||||
					} else {
 | 
			
		||||
						formattedValues = append(formattedValues, "NULL")
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					formattedValues = append(formattedValues, fmt.Sprintf("'%v'", value))
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				formattedValues = append(formattedValues, "NULL")
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// differentiate between $n placeholders or else treat like ?
 | 
			
		||||
		if numericPlaceHolderRegexp.MatchString(values[1].(string)) {
 | 
			
		||||
			sql = values[1].(string)
 | 
			
		||||
			for index, value := range formattedValues {
 | 
			
		||||
				placeholder := fmt.Sprintf(`\$%d([^\d]|$)`, index+1)
 | 
			
		||||
				sql = regexp.MustCompile(placeholder).ReplaceAllString(sql, value+"$1")
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			formattedValuesLength := len(formattedValues)
 | 
			
		||||
			for index, value := range sqlRegexp.Split(values[1].(string), -1) {
 | 
			
		||||
				sql += value
 | 
			
		||||
				if index < formattedValuesLength {
 | 
			
		||||
					sql += formattedValues[index]
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		messages = append(messages, sql)
 | 
			
		||||
		messages = append(messages, fmt.Sprintf(" \n[%v]", strconv.FormatInt(values[3].(int64), 10)+" rows affected or returned "))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
@ -1,9 +1,17 @@
 | 
			
		||||
package logger
 | 
			
		||||
 | 
			
		||||
import "os"
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"log"
 | 
			
		||||
	"os"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Interface logger interface
 | 
			
		||||
type Interface interface {
 | 
			
		||||
	SQL(data ...interface{})
 | 
			
		||||
	Info(data ...interface{})
 | 
			
		||||
	Warn(data ...interface{})
 | 
			
		||||
	Error(data ...interface{})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LogLevel log level
 | 
			
		||||
@ -12,9 +20,12 @@ type LogLevel int
 | 
			
		||||
// DefaultLogLevel default log level
 | 
			
		||||
var DefaultLogLevel LogLevel
 | 
			
		||||
 | 
			
		||||
// DefaultLogger default logger
 | 
			
		||||
var DefaultLogger = Logger{log.New(os.Stdout, "\r\n", 0)}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// Info print SQL, warn messages and errors
 | 
			
		||||
	Info LogLevel = 1 << iota
 | 
			
		||||
	Info LogLevel = iota - 1
 | 
			
		||||
	// Warn print warn messages and errors
 | 
			
		||||
	Warn
 | 
			
		||||
	// Error print errors
 | 
			
		||||
@ -33,3 +44,35 @@ func init() {
 | 
			
		||||
		DefaultLogLevel = Error
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LogWriter log writer interface
 | 
			
		||||
type LogWriter interface {
 | 
			
		||||
	Println(v ...interface{})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Logger logger
 | 
			
		||||
type Logger struct {
 | 
			
		||||
	LogWriter
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SQL print SQL statements
 | 
			
		||||
func (logger Logger) SQL(data ...interface{}) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Info print info
 | 
			
		||||
func (logger Logger) Info(message string, data ...interface{}) {
 | 
			
		||||
	// TODO show file line number
 | 
			
		||||
	logger.Println(fmt.Sprintf("[info] %v", fmt.Sprintf(message, data...)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Warn print warn messages
 | 
			
		||||
func (logger Logger) Warn(message string, data ...interface{}) {
 | 
			
		||||
	// TODO show file line number
 | 
			
		||||
	logger.Println(fmt.Sprintf("[warn] %v", fmt.Sprintf(message, data...)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Error print error messages
 | 
			
		||||
func (logger Logger) Error(message string, data ...interface{}) {
 | 
			
		||||
	// TODO show file line number
 | 
			
		||||
	logger.Println(fmt.Sprintf("[error] %v", fmt.Sprintf(message, data...)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								main.go
									
									
									
									
									
								
							@ -18,8 +18,6 @@ type DB struct {
 | 
			
		||||
	// single db
 | 
			
		||||
	db                SQLCommon
 | 
			
		||||
	blockGlobalUpdate bool
 | 
			
		||||
	logMode           int
 | 
			
		||||
	logger            logger
 | 
			
		||||
	search            *search
 | 
			
		||||
	values            map[string]interface{}
 | 
			
		||||
 | 
			
		||||
@ -711,8 +709,6 @@ func (s *DB) clone() *DB {
 | 
			
		||||
	db := &DB{
 | 
			
		||||
		db:                s.db,
 | 
			
		||||
		parent:            s.parent,
 | 
			
		||||
		logger:            s.logger,
 | 
			
		||||
		logMode:           s.logMode,
 | 
			
		||||
		values:            map[string]interface{}{},
 | 
			
		||||
		Value:             s.Value,
 | 
			
		||||
		Error:             s.Error,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user