ConsoleWriter: fix race condition (#120)
Alternative approach to #118: fix the race condition by replacing the package-level customization settings with curried functions.
This commit is contained in:
parent
7179aeef58
commit
c482b20623
115
console.go
115
console.go
|
@ -35,19 +35,10 @@ var (
|
||||||
return bytes.NewBuffer(make([]byte, 0, 100))
|
return bytes.NewBuffer(make([]byte, 0, 100))
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
consoleDefaultTimeFormat = time.Kitchen
|
consoleDefaultTimeFormat = time.Kitchen
|
||||||
consoleDefaultPartsOrder = func() []string {
|
|
||||||
return []string{
|
|
||||||
TimestampFieldName,
|
|
||||||
LevelFieldName,
|
|
||||||
CallerFieldName,
|
|
||||||
MessageFieldName,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
consoleNoColor = false
|
|
||||||
consoleTimeFormat = consoleDefaultTimeFormat
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Formatter transforms the input into a formatted string.
|
// Formatter transforms the input into a formatted string.
|
||||||
|
@ -98,18 +89,6 @@ func (w ConsoleWriter) Write(p []byte) (n int, err error) {
|
||||||
if w.PartsOrder == nil {
|
if w.PartsOrder == nil {
|
||||||
w.PartsOrder = consoleDefaultPartsOrder()
|
w.PartsOrder = consoleDefaultPartsOrder()
|
||||||
}
|
}
|
||||||
if w.TimeFormat == "" && consoleTimeFormat != consoleDefaultTimeFormat {
|
|
||||||
consoleTimeFormat = consoleDefaultTimeFormat
|
|
||||||
}
|
|
||||||
if w.TimeFormat != "" && consoleTimeFormat != w.TimeFormat {
|
|
||||||
consoleTimeFormat = w.TimeFormat
|
|
||||||
}
|
|
||||||
if w.NoColor == false && consoleNoColor != false {
|
|
||||||
consoleNoColor = false
|
|
||||||
}
|
|
||||||
if w.NoColor == true && consoleNoColor != w.NoColor {
|
|
||||||
consoleNoColor = w.NoColor
|
|
||||||
}
|
|
||||||
|
|
||||||
var buf = consoleBufPool.Get().(*bytes.Buffer)
|
var buf = consoleBufPool.Get().(*bytes.Buffer)
|
||||||
defer func() {
|
defer func() {
|
||||||
|
@ -177,19 +156,19 @@ func (w ConsoleWriter) writeFields(evt map[string]interface{}, buf *bytes.Buffer
|
||||||
|
|
||||||
if field == ErrorFieldName {
|
if field == ErrorFieldName {
|
||||||
if w.FormatErrFieldName == nil {
|
if w.FormatErrFieldName == nil {
|
||||||
fn = consoleDefaultFormatErrFieldName
|
fn = consoleDefaultFormatErrFieldName(w.NoColor)
|
||||||
} else {
|
} else {
|
||||||
fn = w.FormatErrFieldName
|
fn = w.FormatErrFieldName
|
||||||
}
|
}
|
||||||
|
|
||||||
if w.FormatErrFieldValue == nil {
|
if w.FormatErrFieldValue == nil {
|
||||||
fv = consoleDefaultFormatErrFieldValue
|
fv = consoleDefaultFormatErrFieldValue(w.NoColor)
|
||||||
} else {
|
} else {
|
||||||
fv = w.FormatErrFieldValue
|
fv = w.FormatErrFieldValue
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if w.FormatFieldName == nil {
|
if w.FormatFieldName == nil {
|
||||||
fn = consoleDefaultFormatFieldName
|
fn = consoleDefaultFormatFieldName(w.NoColor)
|
||||||
} else {
|
} else {
|
||||||
fn = w.FormatFieldName
|
fn = w.FormatFieldName
|
||||||
}
|
}
|
||||||
|
@ -234,13 +213,13 @@ func (w ConsoleWriter) writePart(buf *bytes.Buffer, evt map[string]interface{},
|
||||||
switch p {
|
switch p {
|
||||||
case LevelFieldName:
|
case LevelFieldName:
|
||||||
if w.FormatLevel == nil {
|
if w.FormatLevel == nil {
|
||||||
f = consoleDefaultFormatLevel
|
f = consoleDefaultFormatLevel(w.NoColor)
|
||||||
} else {
|
} else {
|
||||||
f = w.FormatLevel
|
f = w.FormatLevel
|
||||||
}
|
}
|
||||||
case TimestampFieldName:
|
case TimestampFieldName:
|
||||||
if w.FormatTimestamp == nil {
|
if w.FormatTimestamp == nil {
|
||||||
f = consoleDefaultFormatTimestamp
|
f = consoleDefaultFormatTimestamp(w.TimeFormat, w.NoColor)
|
||||||
} else {
|
} else {
|
||||||
f = w.FormatTimestamp
|
f = w.FormatTimestamp
|
||||||
}
|
}
|
||||||
|
@ -252,7 +231,7 @@ func (w ConsoleWriter) writePart(buf *bytes.Buffer, evt map[string]interface{},
|
||||||
}
|
}
|
||||||
case CallerFieldName:
|
case CallerFieldName:
|
||||||
if w.FormatCaller == nil {
|
if w.FormatCaller == nil {
|
||||||
f = consoleDefaultFormatCaller
|
f = consoleDefaultFormatCaller(w.NoColor)
|
||||||
} else {
|
} else {
|
||||||
f = w.FormatCaller
|
f = w.FormatCaller
|
||||||
}
|
}
|
||||||
|
@ -294,49 +273,65 @@ func colorize(s interface{}, c int, disabled bool) string {
|
||||||
|
|
||||||
// ----- DEFAULT FORMATTERS ---------------------------------------------------
|
// ----- DEFAULT FORMATTERS ---------------------------------------------------
|
||||||
|
|
||||||
var (
|
func consoleDefaultPartsOrder() []string {
|
||||||
consoleDefaultFormatTimestamp = func(i interface{}) string {
|
return []string{
|
||||||
|
TimestampFieldName,
|
||||||
|
LevelFieldName,
|
||||||
|
CallerFieldName,
|
||||||
|
MessageFieldName,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func consoleDefaultFormatTimestamp(timeFormat string, noColor bool) Formatter {
|
||||||
|
if timeFormat == "" {
|
||||||
|
timeFormat = consoleDefaultTimeFormat
|
||||||
|
}
|
||||||
|
return func(i interface{}) string {
|
||||||
t := "<nil>"
|
t := "<nil>"
|
||||||
switch tt := i.(type) {
|
switch tt := i.(type) {
|
||||||
case string:
|
case string:
|
||||||
ts, err := time.Parse(time.RFC3339, tt)
|
ts, err := time.Parse(TimeFieldFormat, tt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t = tt
|
t = tt
|
||||||
} else {
|
} else {
|
||||||
t = ts.Format(consoleTimeFormat)
|
t = ts.Format(timeFormat)
|
||||||
}
|
}
|
||||||
case json.Number:
|
case json.Number:
|
||||||
t = tt.String()
|
t = tt.String()
|
||||||
}
|
}
|
||||||
return colorize(t, colorFaint, consoleNoColor)
|
return colorize(t, colorFaint, noColor)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
consoleDefaultFormatLevel = func(i interface{}) string {
|
func consoleDefaultFormatLevel(noColor bool) Formatter {
|
||||||
|
return func(i interface{}) string {
|
||||||
var l string
|
var l string
|
||||||
if ll, ok := i.(string); ok {
|
if ll, ok := i.(string); ok {
|
||||||
switch ll {
|
switch ll {
|
||||||
case "debug":
|
case "debug":
|
||||||
l = colorize("DBG", colorYellow, consoleNoColor)
|
l = colorize("DBG", colorYellow, noColor)
|
||||||
case "info":
|
case "info":
|
||||||
l = colorize("INF", colorGreen, consoleNoColor)
|
l = colorize("INF", colorGreen, noColor)
|
||||||
case "warn":
|
case "warn":
|
||||||
l = colorize("WRN", colorRed, consoleNoColor)
|
l = colorize("WRN", colorRed, noColor)
|
||||||
case "error":
|
case "error":
|
||||||
l = colorize(colorize("ERR", colorRed, consoleNoColor), colorBold, consoleNoColor)
|
l = colorize(colorize("ERR", colorRed, noColor), colorBold, noColor)
|
||||||
case "fatal":
|
case "fatal":
|
||||||
l = colorize(colorize("FTL", colorRed, consoleNoColor), colorBold, consoleNoColor)
|
l = colorize(colorize("FTL", colorRed, noColor), colorBold, noColor)
|
||||||
case "panic":
|
case "panic":
|
||||||
l = colorize(colorize("PNC", colorRed, consoleNoColor), colorBold, consoleNoColor)
|
l = colorize(colorize("PNC", colorRed, noColor), colorBold, noColor)
|
||||||
default:
|
default:
|
||||||
l = colorize("???", colorBold, consoleNoColor)
|
l = colorize("???", colorBold, noColor)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
l = strings.ToUpper(fmt.Sprintf("%s", i))[0:3]
|
l = strings.ToUpper(fmt.Sprintf("%s", i))[0:3]
|
||||||
}
|
}
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
consoleDefaultFormatCaller = func(i interface{}) string {
|
func consoleDefaultFormatCaller(noColor bool) Formatter {
|
||||||
|
return func(i interface{}) string {
|
||||||
var c string
|
var c string
|
||||||
if cc, ok := i.(string); ok {
|
if cc, ok := i.(string); ok {
|
||||||
c = cc
|
c = cc
|
||||||
|
@ -347,28 +342,34 @@ var (
|
||||||
c = strings.TrimPrefix(c, cwd)
|
c = strings.TrimPrefix(c, cwd)
|
||||||
c = strings.TrimPrefix(c, "/")
|
c = strings.TrimPrefix(c, "/")
|
||||||
}
|
}
|
||||||
c = colorize(c, colorBold, consoleNoColor) + colorize(" >", colorFaint, consoleNoColor)
|
c = colorize(c, colorBold, noColor) + colorize(" >", colorFaint, noColor)
|
||||||
}
|
}
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
consoleDefaultFormatMessage = func(i interface{}) string {
|
func consoleDefaultFormatMessage(i interface{}) string {
|
||||||
return fmt.Sprintf("%s", i)
|
return fmt.Sprintf("%s", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
consoleDefaultFormatFieldName = func(i interface{}) string {
|
func consoleDefaultFormatFieldName(noColor bool) Formatter {
|
||||||
return colorize(fmt.Sprintf("%s=", i), colorFaint, consoleNoColor)
|
return func(i interface{}) string {
|
||||||
|
return colorize(fmt.Sprintf("%s=", i), colorFaint, noColor)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
consoleDefaultFormatFieldValue = func(i interface{}) string {
|
func consoleDefaultFormatFieldValue(i interface{}) string {
|
||||||
return fmt.Sprintf("%s", i)
|
return fmt.Sprintf("%s", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
consoleDefaultFormatErrFieldName = func(i interface{}) string {
|
func consoleDefaultFormatErrFieldName(noColor bool) Formatter {
|
||||||
return colorize(fmt.Sprintf("%s=", i), colorRed, consoleNoColor)
|
return func(i interface{}) string {
|
||||||
|
return colorize(fmt.Sprintf("%s=", i), colorRed, noColor)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
consoleDefaultFormatErrFieldValue = func(i interface{}) string {
|
func consoleDefaultFormatErrFieldValue(noColor bool) Formatter {
|
||||||
return colorize(fmt.Sprintf("%s", i), colorRed, consoleNoColor)
|
return func(i interface{}) string {
|
||||||
|
return colorize(fmt.Sprintf("%s", i), colorRed, noColor)
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
Loading…
Reference in New Issue