diff options
| author | Christine Dodrill <me@christine.website> | 2017-03-29 00:26:50 -0700 |
|---|---|---|
| committer | Christine Dodrill <me@christine.website> | 2017-03-29 00:26:50 -0700 |
| commit | b89387f6bbb010907dfa85ee0c0bab0cf8b34dfb (patch) | |
| tree | 91deef87b78892c30839a99088362b70bf78eee4 /vendor/github.com/Xe | |
| parent | a59e48d9485f6c80f397df3bbcbe9b09ac54a435 (diff) | |
| download | xesite-b89387f6bbb010907dfa85ee0c0bab0cf8b34dfb.tar.xz xesite-b89387f6bbb010907dfa85ee0c0bab0cf8b34dfb.zip | |
support RSS feed generation
Diffstat (limited to 'vendor/github.com/Xe')
| -rw-r--r-- | vendor/github.com/Xe/ln/filter.go | 66 | ||||
| -rw-r--r-- | vendor/github.com/Xe/ln/formatter.go | 100 | ||||
| -rw-r--r-- | vendor/github.com/Xe/ln/logger.go | 141 | ||||
| -rw-r--r-- | vendor/github.com/Xe/ln/stack.go | 44 |
4 files changed, 351 insertions, 0 deletions
diff --git a/vendor/github.com/Xe/ln/filter.go b/vendor/github.com/Xe/ln/filter.go new file mode 100644 index 0000000..586efef --- /dev/null +++ b/vendor/github.com/Xe/ln/filter.go @@ -0,0 +1,66 @@ +package ln + +import ( + "io" + "sync" +) + +// Filter interface for defining chain filters +type Filter interface { + Apply(Event) bool + Run() + Close() +} + +// FilterFunc allows simple functions to implement the Filter interface +type FilterFunc func(e Event) bool + +// Apply implements the Filter interface +func (ff FilterFunc) Apply(e Event) bool { + return ff(e) +} + +// Run implements the Filter interface +func (ff FilterFunc) Run() {} + +// Close implements the Filter interface +func (ff FilterFunc) Close() {} + +// WriterFilter implements a filter, which arbitrarily writes to an io.Writer +type WriterFilter struct { + sync.Mutex + Out io.Writer + Formatter Formatter +} + +// NewWriterFilter creates a filter to add to the chain +func NewWriterFilter(out io.Writer, format Formatter) *WriterFilter { + if format == nil { + format = DefaultFormatter + } + return &WriterFilter{ + Out: out, + Formatter: format, + } +} + +// Apply implements the Filter interface +func (w *WriterFilter) Apply(e Event) bool { + output, err := w.Formatter.Format(e) + if err == nil { + w.Lock() + w.Out.Write(output) + w.Unlock() + } + + return true +} + +// Run implements the Filter interface +func (w *WriterFilter) Run() {} + +// Close implements the Filter interface +func (w *WriterFilter) Close() {} + +// NilFilter is safe to return as a Filter, but does nothing +var NilFilter = FilterFunc(func(e Event) bool { return true }) diff --git a/vendor/github.com/Xe/ln/formatter.go b/vendor/github.com/Xe/ln/formatter.go new file mode 100644 index 0000000..9d67139 --- /dev/null +++ b/vendor/github.com/Xe/ln/formatter.go @@ -0,0 +1,100 @@ +package ln + +import ( + "bytes" + "fmt" + "time" +) + +var ( + // DefaultTimeFormat represents the way in which time will be formatted by default + DefaultTimeFormat = time.RFC3339 +) + +// Formatter defines the formatting of events +type Formatter interface { + Format(Event) ([]byte, error) +} + +// DefaultFormatter is the default way in which to format events +var DefaultFormatter Formatter + +func init() { + DefaultFormatter = NewTextFormatter() +} + +// TextFormatter formats events as key value pairs. +// Any remaining text not wrapped in an instance of `F` will be +// placed at the end. +type TextFormatter struct { + TimeFormat string +} + +// NewTextFormatter returns a Formatter that outputs as text. +func NewTextFormatter() Formatter { + return &TextFormatter{TimeFormat: DefaultTimeFormat} +} + +// Format implements the Formatter interface +func (t *TextFormatter) Format(e Event) ([]byte, error) { + var writer bytes.Buffer + + writer.WriteString("time=\"") + writer.WriteString(e.Time.Format(t.TimeFormat)) + writer.WriteString("\"") + + for k, v := range e.Data { + writer.WriteByte(' ') + if shouldQuote(k) { + writer.WriteString(fmt.Sprintf("%q", k)) + } else { + writer.WriteString(k) + } + + writer.WriteByte('=') + + switch v.(type) { + case string: + vs, _ := v.(string) + if shouldQuote(vs) { + fmt.Fprintf(&writer, "%q", vs) + } else { + writer.WriteString(vs) + } + case error: + tmperr, _ := v.(error) + es := tmperr.Error() + + if shouldQuote(es) { + fmt.Fprintf(&writer, "%q", es) + } else { + writer.WriteString(es) + } + case time.Time: + tmptime, _ := v.(time.Time) + writer.WriteString(tmptime.Format(time.RFC3339)) + default: + fmt.Fprint(&writer, v) + } + } + + if len(e.Message) > 0 { + fmt.Fprintf(&writer, " _msg=%q", e.Message) + } + + writer.WriteByte('\n') + return writer.Bytes(), nil +} + +func shouldQuote(s string) bool { + for _, b := range s { + if !((b >= 'A' && b <= 'Z') || + (b >= 'a' && b <= 'z') || + (b >= '0' && b <= '9') || + (b == '-' || b == '.' || b == '#' || + b == '/' || b == '_')) { + return true + } + } + return false +} diff --git a/vendor/github.com/Xe/ln/logger.go b/vendor/github.com/Xe/ln/logger.go new file mode 100644 index 0000000..cdfe89e --- /dev/null +++ b/vendor/github.com/Xe/ln/logger.go @@ -0,0 +1,141 @@ +package ln + +import ( + "fmt" + "os" + "time" + + "github.com/pkg/errors" +) + +// Logger holds the current priority and list of filters +type Logger struct { + Filters []Filter +} + +// DefaultLogger is the default implementation of Logger +var DefaultLogger *Logger + +func init() { + var defaultFilters []Filter + + // Default to STDOUT for logging, but allow LN_OUT to change it. + out := os.Stdout + if os.Getenv("LN_OUT") == "<stderr>" { + out = os.Stderr + } + + defaultFilters = append(defaultFilters, NewWriterFilter(out, nil)) + + DefaultLogger = &Logger{ + Filters: defaultFilters, + } + +} + +// F is a key-value mapping for structured data. +type F map[string]interface{} + +type Fer interface { + F() map[string]interface{} +} + +// Event represents an event +type Event struct { + Time time.Time + Data F + Message string +} + +// Log is the generic logging method. +func (l *Logger) Log(xs ...interface{}) { + var bits []interface{} + event := Event{Time: time.Now()} + + addF := func(bf F) { + if event.Data == nil { + event.Data = bf + } else { + for k, v := range bf { + event.Data[k] = v + } + } + } + + // Assemble the event + for _, b := range xs { + if bf, ok := b.(F); ok { + addF(bf) + } else if fer, ok := b.(Fer); ok { + addF(F(fer.F())) + } else { + bits = append(bits, b) + } + } + + event.Message = fmt.Sprint(bits...) + + if os.Getenv("LN_DEBUG_ALL_EVENTS") == "1" { + frame := callersFrame() + if event.Data == nil { + event.Data = make(F) + } + event.Data["_lineno"] = frame.lineno + event.Data["_function"] = frame.function + event.Data["_filename"] = frame.filename + } + + l.filter(event) +} + +func (l *Logger) filter(e Event) { + for _, f := range l.Filters { + if !f.Apply(e) { + return + } + } +} + +// Error logs an error and information about the context of said error. +func (l *Logger) Error(err error, xs ...interface{}) { + data := F{} + frame := callersFrame() + + data["_lineno"] = frame.lineno + data["_function"] = frame.function + data["_filename"] = frame.filename + data["err"] = err + + cause := errors.Cause(err) + if cause != nil { + data["cause"] = cause.Error() + } + + xs = append(xs, data) + + l.Log(xs...) +} + +// Fatal logs this set of values, then exits with status code 1. +func (l *Logger) Fatal(xs ...interface{}) { + l.Log(xs...) + + os.Exit(1) +} + +// Default Implementation + +// Log is the generic logging method. +func Log(xs ...interface{}) { + DefaultLogger.Log(xs...) +} + +// Error logs an error and information about the context of said error. +func Error(err error, xs ...interface{}) { + DefaultLogger.Error(err, xs...) +} + +// Fatal logs this set of values, then exits with status code 1. +func Fatal(xs ...interface{}) { + DefaultLogger.Fatal(xs...) +} diff --git a/vendor/github.com/Xe/ln/stack.go b/vendor/github.com/Xe/ln/stack.go new file mode 100644 index 0000000..1cf1e7a --- /dev/null +++ b/vendor/github.com/Xe/ln/stack.go @@ -0,0 +1,44 @@ +package ln + +import ( + "os" + "runtime" + "strings" +) + +type frame struct { + filename string + function string + lineno int +} + +// skips 2 frames, since Caller returns the current frame, and we need +// the caller's caller. +func callersFrame() frame { + var out frame + pc, file, line, ok := runtime.Caller(3) + if !ok { + return out + } + srcLoc := strings.LastIndex(file, "/src/") + if srcLoc >= 0 { + file = file[srcLoc+5:] + } + out.filename = file + out.function = functionName(pc) + out.lineno = line + + return out +} + +func functionName(pc uintptr) string { + fn := runtime.FuncForPC(pc) + if fn == nil { + return "???" + } + name := fn.Name() + beg := strings.LastIndex(name, string(os.PathSeparator)) + return name[beg+1:] + // end := strings.LastIndex(name, string(os.PathSeparator)) + // return name[end+1 : len(name)] +} |
