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:
zeripath
2019-04-22 21:40:51 +01:00
committed by Lauris BH
parent b83114f140
commit be666b03ee
17 changed files with 418 additions and 12 deletions

View File

@ -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))

View File

@ -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 {