Trace Logging on Permission Denied & ColorFormat (#6618)
* Add log.ColorFormat and log.ColorFormatted Structs can now implement log.ColorFormatted to provide their own colored format when logged with `%-v` or additional flags. Signed-off-by: Andrew Thornton <art27@cantab.net> * Add basic ColorFormat to repository and user Signed-off-by: Andrew Thornton <art27@cantab.net> * Add basic ColorFormat to access and unit Signed-off-by: Andrew Thornton <art27@cantab.net> * Add ColorFormat to permission and on trace log it Signed-off-by: Andrew Thornton <art27@cantab.net> * Add log.NewColoredIDValue to make ID value coloring consistent Signed-off-by: Andrew Thornton <art27@cantab.net> * formatting changes * Add some better tracing to permission denied for read issues/pulls Signed-off-by: Andrew Thornton <art27@cantab.net> * Add Trace logging on permission denied Signed-off-by: Andrew Thornton <art27@cantab.net> * Remove isTrace() check from deferred func * Adjust repo and allow logging of team * use FormatInt instead of Itoa * Add blank line Signed-off-by: Andrew Thornton <art27@cantab.net> * Update access.go
This commit is contained in:
@ -7,6 +7,7 @@ package log
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
@ -195,11 +196,12 @@ normalLoop:
|
||||
lasti := i
|
||||
|
||||
if c.mode == escapeAll {
|
||||
for i < end && (bytes[i] >= ' ' || bytes[i] == '\n') {
|
||||
for i < end && (bytes[i] >= ' ' || bytes[i] == '\n' || bytes[i] == '\t') {
|
||||
i++
|
||||
}
|
||||
} else {
|
||||
for i < end && bytes[i] >= ' ' {
|
||||
// Allow tabs if we're not escaping everything
|
||||
for i < end && (bytes[i] >= ' ' || bytes[i] == '\t') {
|
||||
i++
|
||||
}
|
||||
}
|
||||
@ -266,6 +268,39 @@ normalLoop:
|
||||
return totalWritten, nil
|
||||
}
|
||||
|
||||
// ColorSprintf returns a colored string from a format and arguments
|
||||
// arguments will be wrapped in ColoredValues to protect against color spoofing
|
||||
func ColorSprintf(format string, args ...interface{}) string {
|
||||
if len(args) > 0 {
|
||||
v := make([]interface{}, len(args))
|
||||
for i := 0; i < len(v); i++ {
|
||||
v[i] = NewColoredValuePointer(&args[i])
|
||||
}
|
||||
return fmt.Sprintf(format, v...)
|
||||
}
|
||||
return fmt.Sprintf(format)
|
||||
}
|
||||
|
||||
// ColorFprintf will write to the provided writer similar to ColorSprintf
|
||||
func ColorFprintf(w io.Writer, format string, args ...interface{}) (int, error) {
|
||||
if len(args) > 0 {
|
||||
v := make([]interface{}, len(args))
|
||||
for i := 0; i < len(v); i++ {
|
||||
v[i] = NewColoredValuePointer(&args[i])
|
||||
}
|
||||
return fmt.Fprintf(w, format, v...)
|
||||
}
|
||||
return fmt.Fprintf(w, format)
|
||||
}
|
||||
|
||||
// ColorFormatted structs provide their own colored string when formatted with ColorSprintf
|
||||
type ColorFormatted interface {
|
||||
// ColorFormat provides the colored representation of the value
|
||||
ColorFormat(s fmt.State)
|
||||
}
|
||||
|
||||
var colorFormattedType = reflect.TypeOf((*ColorFormatted)(nil)).Elem()
|
||||
|
||||
// ColoredValue will Color the provided value
|
||||
type ColoredValue struct {
|
||||
colorBytes *[]byte
|
||||
@ -316,8 +351,33 @@ func NewColoredValueBytes(value interface{}, colorBytes *[]byte) *ColoredValue {
|
||||
}
|
||||
}
|
||||
|
||||
// Format will format the provided value and protect against ANSI spoofing within the value
|
||||
// NewColoredIDValue is a helper function to create a ColoredValue from a Value
|
||||
// The Value will be colored with FgCyan
|
||||
// If a ColoredValue is provided it is not changed
|
||||
func NewColoredIDValue(value interface{}) *ColoredValue {
|
||||
return NewColoredValueBytes(&value, &fgCyanBytes)
|
||||
}
|
||||
|
||||
// Format will format the provided value and protect against ANSI color spoofing within the value
|
||||
// If the wrapped value is ColorFormatted and the format is "%-v" then its ColorString will
|
||||
// be used. It is presumed that this ColorString is safe.
|
||||
func (cv *ColoredValue) Format(s fmt.State, c rune) {
|
||||
if c == 'v' && s.Flag('-') {
|
||||
if val, ok := (*cv.Value).(ColorFormatted); ok {
|
||||
val.ColorFormat(s)
|
||||
return
|
||||
}
|
||||
v := reflect.ValueOf(*cv.Value)
|
||||
t := v.Type()
|
||||
|
||||
if reflect.PtrTo(t).Implements(colorFormattedType) {
|
||||
vp := reflect.New(t)
|
||||
vp.Elem().Set(v)
|
||||
val := vp.Interface().(ColorFormatted)
|
||||
val.ColorFormat(s)
|
||||
return
|
||||
}
|
||||
}
|
||||
s.Write([]byte(*cv.colorBytes))
|
||||
fmt.Fprintf(&protectedANSIWriter{w: s}, fmtString(s, c), *(cv.Value))
|
||||
s.Write([]byte(*cv.resetBytes))
|
||||
|
@ -69,11 +69,7 @@ func (l *Logger) Log(skip int, level Level, format string, v ...interface{}) err
|
||||
}
|
||||
msg := format
|
||||
if len(v) > 0 {
|
||||
args := make([]interface{}, len(v))
|
||||
for i := 0; i < len(args); i++ {
|
||||
args[i] = NewColoredValuePointer(&v[i])
|
||||
}
|
||||
msg = fmt.Sprintf(format, args...)
|
||||
msg = ColorSprintf(format, v...)
|
||||
}
|
||||
stack := ""
|
||||
if l.GetStacktraceLevel() <= level {
|
||||
|
Reference in New Issue
Block a user