<commit_before>package kiwi

import (
	"sync"
	"time"
)

type (
	// Logger keeps context and log record. There are many loggers initialized
	// in different places of application. Loggers are safe for
	// concurrent usage.
	Logger struct {
		sync.RWMutex
		contextSrc map[interface{}]interface{}
		context    map[string]value
		pairs      map[string]value
	}
	// Record allows log data from any custom types in they conform this interface.
	// Also types that conform fmt.Stringer can be used. But as they not have IsQuoted() check
	// they always treated as strings and displayed in quotes.
	Record interface {
		String() string
		IsQuoted() bool
	}
	value struct {
		Val    string
		Func   interface{}
		Type   uint8
		Quoted bool
	}
)

// NewLogger creates logger instance.
func NewLogger() *Logger {
	return &Logger{
		contextSrc: make(map[interface{}]interface{}),
		context:    make(map[string]value),
		pairs:      make(map[string]value)}
}

// Log is the most common method for flushing previously added key-val pairs to an output.
// After current record is flushed all pairs removed from a record except contextSrc pairs.
func (l *Logger) Log(keyVals ...interface{}) {
	if len(keyVals) > 0 {
		l.Add(keyVals...)
	}
	l.Lock()
	record := l.pairs
	l.pairs = make(map[string]value)
	for key, val := range l.context {
		// pairs override context
		if _, ok := record[key]; !ok {
			record[key] = val
		}
	}
	l.Unlock()
	passRecordToOutput(record)
}

// Add a new key-value pairs to the log record. If a key already added then value will be
// updated. If a key already exists in a contextSrc then it will be overriden by a new
// value for a current record only. After flushing a record with Log() old context value
// will be restored.
func (l *Logger) Add(keyVals ...interface{}) *Logger {
	var key string
	l.Lock()
	for i, val := range keyVals {
		if i%2 == 0 {
			key = toRecordKey(val)
			continue
		}
		l.pairs[key] = toRecordValue(val)
	}
	// for odd number of key-val pairs just add label without value
	if len(keyVals)%2 == 1 {
		l.pairs[key] = value{"", nil, voidVal, false}
	}
	l.Unlock()
	return l
}

// With defines a context for the logger.
func (l *Logger) With(keyVals ...interface{}) *Logger {
	var (
		keySrc interface{}
		key    string
	)
	l.Lock()
	for i, val := range keyVals {
		if i%2 == 0 {
			keySrc = val
			key = toRecordKey(val)
			continue
		}
		l.contextSrc[keySrc] = val
		l.context[key] = toRecordValue(val)
	}
	// for odd number of key-val pairs just add label without value
	if len(keyVals)%2 == 1 {
		l.contextSrc[keySrc] = nil
		l.context[key] = value{"", nil, voidVal, false}
	}
	l.Unlock()
	return l
}

// Without drops some keys from a context for the logger.
func (l *Logger) Without(keys ...interface{}) *Logger {
	l.Lock()
	for _, key := range keys {
		if _, ok := l.contextSrc[key]; ok {
			delete(l.contextSrc, key)
			delete(l.context, toRecordKey(key))
		}
	}
	l.Unlock()
	return l
}

// WithTimestamp adds "timestamp" field to the context.
func (l *Logger) WithTimestamp(format string) *Logger {
	l.Lock()
	l.contextSrc["timestamp"] = func() string { return time.Now().Format(format) }
	l.context["timestamp"] = value{"", func() string { return time.Now().Format(format) }, stringVal, true}
	l.Unlock()
	return l
}

// Reset logger values added after last Log() call. It keeps contextSrc untouched.
func (l *Logger) Reset() *Logger {
	l.Lock()
	l.pairs = make(map[string]value)
	l.Unlock()
	return l
}

// ResetContext resets the context of the logger.
func (l *Logger) ResetContext() *Logger {
	l.Lock()
	l.contextSrc = make(map[interface{}]interface{})
	l.context = make(map[string]value)
	l.Unlock()
	return l
}

// GetContext returns copy of the context saved in the logger.
func (l *Logger) GetContext() map[interface{}]interface{} {
	var contextSrc = make(map[interface{}]interface{})
	l.RLock()
	for k, v := range l.contextSrc {
		contextSrc[k] = v
	}
	l.RUnlock()
	return contextSrc
}

// GetContextValue returns single context value for the key.
func (l *Logger) GetContextValue(key string) interface{} {
	l.RLock()
	value := l.contextSrc[key]
	l.RUnlock()
	return value
}

// GetRecord returns copy of current set of keys and values prepared for logging
// as strings. With context key-vals included.
// The most of Logger operations return *Logger itself but it made for operations
// chaining only. If you need get log pairs use GelRecord() for it.
func (l *Logger) GetRecord() map[string]string {
	var merged = make(map[string]string)
	l.RLock()
	for k, v := range l.context {
		merged[k] = v.Val
	}
	for k, v := range l.pairs {
		merged[k] = v.Val
	}
	l.RUnlock()
	return merged
}

// Flush confirms that all outputs got the last logged record.
func (l *Logger) Flush() {
	// XXX
	time.Sleep(100 * time.Millisecond)
}
<commit_msg>Use better locking.<commit_after>package kiwi

import (
	"sync"
	"time"
)

type (
	// Logger keeps context and log record. There are many loggers initialized
	// in different places of application. Loggers are safe for
	// concurrent usage.
	Logger struct {
		sync.RWMutex
		contextSrc map[interface{}]interface{}
		context    map[string]value
		pairs      map[string]value
	}
	// Record allows log data from any custom types in they conform this interface.
	// Also types that conform fmt.Stringer can be used. But as they not have IsQuoted() check
	// they always treated as strings and displayed in quotes.
	Record interface {
		String() string
		IsQuoted() bool
	}
	value struct {
		Val    string
		Func   interface{}
		Type   uint8
		Quoted bool
	}
)

// NewLogger creates logger instance.
func NewLogger() *Logger {
	return &Logger{
		contextSrc: make(map[interface{}]interface{}),
		context:    make(map[string]value),
		pairs:      make(map[string]value)}
}

// Log is the most common method for flushing previously added key-val pairs to an output.
// After current record is flushed all pairs removed from a record except contextSrc pairs.
func (l *Logger) Log(keyVals ...interface{}) {
	if len(keyVals) > 0 {
		l.Add(keyVals...)
	}
	l.Lock()
	record := l.pairs
	l.pairs = make(map[string]value)
	l.Unlock()
	var key string
	for i, val := range keyVals {
		if i%2 == 0 {
			key = toRecordKey(val)
			continue
		}
		record[key] = toRecordValue(val)
	}
	// for odd number of key-val pairs just add label without value
	if len(keyVals)%2 == 1 {
		record[key] = value{"", nil, voidVal, false}
	}
	l.RLock()
	for key, val := range l.context {
		// pairs override context
		if _, ok := record[key]; !ok {
			record[key] = val
		}
	}
	l.RUnlock()
	passRecordToOutput(record)
}

// Add a new key-value pairs to the log record. If a key already added then value will be
// updated. If a key already exists in a contextSrc then it will be overriden by a new
// value for a current record only. After flushing a record with Log() old context value
// will be restored.
func (l *Logger) Add(keyVals ...interface{}) *Logger {
	var key string
	l.Lock()
	for i, val := range keyVals {
		if i%2 == 0 {
			key = toRecordKey(val)
			continue
		}
		l.pairs[key] = toRecordValue(val)
	}
	// for odd number of key-val pairs just add label without value
	if len(keyVals)%2 == 1 {
		l.pairs[key] = value{"", nil, voidVal, false}
	}
	l.Unlock()
	return l
}

// With defines a context for the logger.
func (l *Logger) With(keyVals ...interface{}) *Logger {
	var (
		keySrc interface{}
		key    string
	)
	l.Lock()
	for i, val := range keyVals {
		if i%2 == 0 {
			keySrc = val
			key = toRecordKey(val)
			continue
		}
		l.contextSrc[keySrc] = val
		l.context[key] = toRecordValue(val)
	}
	// for odd number of key-val pairs just add label without value
	if len(keyVals)%2 == 1 {
		l.contextSrc[keySrc] = nil
		l.context[key] = value{"", nil, voidVal, false}
	}
	l.Unlock()
	return l
}

// Without drops some keys from a context for the logger.
func (l *Logger) Without(keys ...interface{}) *Logger {
	l.Lock()
	for _, key := range keys {
		if _, ok := l.contextSrc[key]; ok {
			delete(l.contextSrc, key)
			delete(l.context, toRecordKey(key))
		}
	}
	l.Unlock()
	return l
}

// WithTimestamp adds "timestamp" field to the context.
func (l *Logger) WithTimestamp(format string) *Logger {
	l.Lock()
	l.contextSrc["timestamp"] = func() string { return time.Now().Format(format) }
	l.context["timestamp"] = value{"", func() string { return time.Now().Format(format) }, stringVal, true}
	l.Unlock()
	return l
}

// Reset logger values added after last Log() call. It keeps contextSrc untouched.
func (l *Logger) Reset() *Logger {
	l.Lock()
	l.pairs = make(map[string]value)
	l.Unlock()
	return l
}

// ResetContext resets the context of the logger.
func (l *Logger) ResetContext() *Logger {
	l.Lock()
	l.contextSrc = make(map[interface{}]interface{})
	l.context = make(map[string]value)
	l.Unlock()
	return l
}

// GetContext returns copy of the context saved in the logger.
func (l *Logger) GetContext() map[interface{}]interface{} {
	var contextSrc = make(map[interface{}]interface{})
	l.RLock()
	for k, v := range l.contextSrc {
		contextSrc[k] = v
	}
	l.RUnlock()
	return contextSrc
}

// GetContextValue returns single context value for the key.
func (l *Logger) GetContextValue(key string) interface{} {
	l.RLock()
	value := l.contextSrc[key]
	l.RUnlock()
	return value
}

// GetRecord returns copy of current set of keys and values prepared for logging
// as strings. With context key-vals included.
// The most of Logger operations return *Logger itself but it made for operations
// chaining only. If you need get log pairs use GelRecord() for it.
func (l *Logger) GetRecord() map[string]string {
	var merged = make(map[string]string)
	l.RLock()
	for k, v := range l.context {
		merged[k] = v.Val
	}
	for k, v := range l.pairs {
		merged[k] = v.Val
	}
	l.RUnlock()
	return merged
}

// Flush confirms that all outputs got the last logged record.
func (l *Logger) Flush() {
	// XXX
	time.Sleep(100 * time.Millisecond)
}
<|endoftext|>


<commit_before>package httplog

import (
	"fmt"
	"github.com/dustin/go-humanize"
	"github.com/miolini/datacounter"
	"io"
	"net/http"
	"os"
	"time"
)

// FormatterFunc user defined formatter func
type FormatterFunc func(w io.Writer, r *http.Request, sentBytes uint64, elapsedTime time.Duration)

// DefaultFormatter default formatter func
var DefaultFormatter FormatterFunc = func(w io.Writer, r *http.Request, sentBytes uint64, elapsedTime time.Duration) {
	fmt.Fprintf(w, "%s [%.2fms %s] %s %s", time.Now().String(), elapsedTime.Seconds()*1000, humanize.Bytes(sentBytes), r.Method, r.URL.Path)
}

// Logger simple func for wrapping http.Handler and log to stderr
func Logger(h http.Handler) http.Handler {
	return LoggerWithWriterAndFormatter(h, os.Stderr, DefaultFormatter)
}

// LoggerWithFormatter wrapping func with user defined formatter
func LoggerWithFormatter(h http.Handler, formatter FormatterFunc) http.Handler {
	return LoggerWithWriterAndFormatter(h, os.Stderr, formatter)
}

// LoggerWithWriter func for wrapping http.Handler and user defined output io.Writer
func LoggerWithWriter(h http.Handler, w io.Writer) http.Handler {
	return LoggerWithWriterAndFormatter(h, w, DefaultFormatter)
}

// LoggerWithWriterAndFormatter func for wrapping http.Handler and user defined output io.Writer and FormatterFunc
func LoggerWithWriterAndFormatter(h http.Handler, lw io.Writer, formatter FormatterFunc) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		wcounter := datacounter.NewResponseWriterCounter(w)
		defer func(t time.Time) {
			formatter(lw, r, wcounter.Count(), time.Since(t))
		}(time.Now())
		h.ServeHTTP(wcounter, r)
	})
}
<commit_msg>add newline<commit_after>package httplog

import (
	"fmt"
	"github.com/dustin/go-humanize"
	"github.com/miolini/datacounter"
	"io"
	"net/http"
	"os"
	"time"
)

// FormatterFunc user defined formatter func
type FormatterFunc func(w io.Writer, r *http.Request, sentBytes uint64, elapsedTime time.Duration)

// DefaultFormatter default formatter func
var DefaultFormatter FormatterFunc = func(w io.Writer, r *http.Request, sentBytes uint64, elapsedTime time.Duration) {
	fmt.Fprintf(w, "%s [%.2fms %s] %s %s\n", time.Now().String(), elapsedTime.Seconds()*1000, humanize.Bytes(sentBytes), r.Method, r.URL.Path)
}

// Logger simple func for wrapping http.Handler and log to stderr
func Logger(h http.Handler) http.Handler {
	return LoggerWithWriterAndFormatter(h, os.Stderr, DefaultFormatter)
}

// LoggerWithFormatter wrapping func with user defined formatter
func LoggerWithFormatter(h http.Handler, formatter FormatterFunc) http.Handler {
	return LoggerWithWriterAndFormatter(h, os.Stderr, formatter)
}

// LoggerWithWriter func for wrapping http.Handler and user defined output io.Writer
func LoggerWithWriter(h http.Handler, w io.Writer) http.Handler {
	return LoggerWithWriterAndFormatter(h, w, DefaultFormatter)
}

// LoggerWithWriterAndFormatter func for wrapping http.Handler and user defined output io.Writer and FormatterFunc
func LoggerWithWriterAndFormatter(h http.Handler, lw io.Writer, formatter FormatterFunc) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		wcounter := datacounter.NewResponseWriterCounter(w)
		defer func(t time.Time) {
			formatter(lw, r, wcounter.Count(), time.Since(t))
		}(time.Now())
		h.ServeHTTP(wcounter, r)
	})
}
<|endoftext|>


<commit_before>// Package logger encargado de respaldar en archivos de texto mensajes y mostrar en consola
package logger

import (
	"fmt"
	"os"
	"os/user"
	"strings"
	"time"
)

// Logger estructura encargada de almacenar la instancia para almacenamiento de mensajes
type Logger struct {
	FileName string
	FilePath string
	Output   bool
}

// openFile open/create file for loggin
func openFile(filePath, fileName string) (*os.File, error) {

	if strings.Contains(filePath, "\\") && !strings.HasSuffix(filePath, "\\") {
		filePath += "\\"
	} else if strings.Contains(filePath, "/") && !strings.HasSuffix(filePath, "/") {
		filePath += "/"
	}

	// Creamos directorio
	err := os.MkdirAll(filePath, 0777)
	if err != nil {
		return nil, err
	}

	// Abrimos archivo
	file, err := os.OpenFile(filePath+fileName, os.O_RDWR|os.O_APPEND, 0660)
	if err != nil {
		// Creamos archivo
		file, err = os.Create(filePath + fileName)
		if err != nil {
			return nil, err
		}
		initText := "#version: 0.1\n"
		initText += "#creation: " + time.Now().String() + "\n"
		initText += "#config: [datetime][userid:username][alert/error/info/etc] message\n"

		// Cerramos archivo
		defer file.Close()

		// Escribimos encabezado
		if _, err := file.WriteString(initText); err != nil {
			return nil, err
		}
	}

	return file, nil
}

// WriteLine write message in log file
func (log *Logger) WriteLine(message string, kind ...string) (int, error) {

	// Abrimos archivo
	file, err := openFile(log.FilePath, log.FileName)
	if err != nil {
		return 0, nil
	}
	// Cerramos archivo
	defer file.Close()

	// Obtenemos la información del usuario del Sistema Operativo
	user, err := user.Current()
	if err != nil {
		return 0, err
	}

	userMessage := user.Uid + ":" + user.Username
	timeMessage := time.Now().Format("02/01/2006 15:04:05.99999")

	kinds := "info"
	if len(kind) > 0 {
		kinds = strings.Join(kind, ",")
	}

	// Guardamos mensaje
	newLine := fmt.Sprintf("[%s][%s][%s] %s\n", timeMessage, userMessage, kinds, message)
	n, err := file.WriteString(newLine)
	if err != nil {
		return 0, err
	}

	// Imprimitmos mensaje
	if log.Output {
		fmt.Printf("[%s][%s][%s] %s\n", timeMessage, userMessage, kind, message)
	}
	return n, nil
}

// New create instance for loggin messages
func New(filePath, fileName string, output bool) (*Logger, error) {
	log := &Logger{fileName, filePath, output}
	if _, err := openFile(filePath, fileName); err != nil {
		return nil, err
	}
	return log, nil
}
<commit_msg>FORMAT OUTPUT MESSAGE<commit_after>// Package logger encargado de respaldar en archivos de texto mensajes y mostrar en consola
package logger

import (
	"fmt"
	"os"
	"os/user"
	"strings"
	"time"
)

// Logger estructura encargada de almacenar la instancia para almacenamiento de mensajes
type Logger struct {
	FileName string
	FilePath string
	Output   bool
}

// openFile open/create file for loggin
func openFile(filePath, fileName string) (*os.File, error) {

	if strings.Contains(filePath, "\\") && !strings.HasSuffix(filePath, "\\") {
		filePath += "\\"
	} else if strings.Contains(filePath, "/") && !strings.HasSuffix(filePath, "/") {
		filePath += "/"
	}

	// Creamos directorio
	err := os.MkdirAll(filePath, 0777)
	if err != nil {
		return nil, err
	}

	// Abrimos archivo
	file, err := os.OpenFile(filePath+fileName, os.O_RDWR|os.O_APPEND, 0660)
	if err != nil {
		// Creamos archivo
		file, err = os.Create(filePath + fileName)
		if err != nil {
			return nil, err
		}
		initText := "#version: 0.1\n"
		initText += "#creation: " + time.Now().String() + "\n"
		initText += "#config: [datetime][userid:username][alert/error/info/etc] message\n"

		// Cerramos archivo
		defer file.Close()

		// Escribimos encabezado
		if _, err := file.WriteString(initText); err != nil {
			return nil, err
		}
	}

	return file, nil
}

// WriteLine write message in log file
func (log *Logger) WriteLine(message string, kind ...string) (int, error) {

	// Abrimos archivo
	file, err := openFile(log.FilePath, log.FileName)
	if err != nil {
		return 0, nil
	}
	// Cerramos archivo
	defer file.Close()

	// Obtenemos la información del usuario del Sistema Operativo
	user, err := user.Current()
	if err != nil {
		return 0, err
	}

	userMessage := user.Uid + ":" + user.Username
	timeMessage := time.Now().Format("02/01/2006 15:04:05.99999")

	kinds := "info"
	if len(kind) > 0 {
		kinds = strings.Join(kind, ",")
	}

	// Guardamos mensaje
	newLine := fmt.Sprintf("[%s][%s][%s] %s\n", timeMessage, userMessage, kinds, message)
	n, err := file.WriteString(newLine)
	if err != nil {
		return 0, err
	}

	// Imprimitmos mensaje
	if log.Output {
		fmt.Printf("[%s] %s\n", timeMessage, message)
	}
	return n, nil
}

// New create instance for loggin messages
func New(filePath, fileName string, output bool) (*Logger, error) {
	log := &Logger{fileName, filePath, output}
	if _, err := openFile(filePath, fileName); err != nil {
		return nil, err
	}
	return log, nil
}
<|endoftext|>


<commit_before>/*
Copyright 2016 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Package logger offers simple cross platform logging for Windows and Linux.
// Available logging endpoints are event log (Windows), syslog (Linux), and
// an io.Writer.
package logger

import (
	"fmt"
	"io"
	"log"
	"os"
	"sync"
)

type severity int

// Severity levels.
const (
	sInfo severity = iota
	sWarning
	sError
	sFatal
)

// Severity tags.
const (
	tagInfo    = "INFO : "
	tagWarning = "WARN : "
	tagError   = "ERROR: "
	tagFatal   = "FATAL: "
)

const (
	flags    = log.Ldate | log.Lmicroseconds | log.Lshortfile
	initText = "ERROR: Logging before logger.Init.\n"
)

var (
	logLock       sync.Mutex
	defaultLogger *Logger
)

// initialize resets defaultLogger.  Which allows tests to reset environment.
func initialize() {
	defaultLogger = &Logger{
		infoLog:    log.New(os.Stderr, initText+tagInfo, flags),
		warningLog: log.New(os.Stderr, initText+tagWarning, flags),
		errorLog:   log.New(os.Stderr, initText+tagError, flags),
		fatalLog:   log.New(os.Stderr, initText+tagFatal, flags),
	}
}

func init() {
	initialize()
}

// Init sets up logging and should be called before log functions, usually in
// the caller's main(). Default log functions can be called before Init(), but log
// output will only go to stderr (along with a warning).
// The first call to Init populates the default logger and returns the
// generated logger, subsequent calls to Init will only return the generated
// logger.
// If the logFile passed in also satisfies io.Closer, logFile.Close will be called
// when closing the logger.
func Init(name string, verbose, systemLog bool, logFile io.Writer) *Logger {
	var il, wl, el io.Writer
	if systemLog {
		var err error
		il, wl, el, err = setup(name)
		if err != nil {
			log.Fatal(err)
		}
	}

	iLogs := []io.Writer{logFile}
	wLogs := []io.Writer{logFile}
	eLogs := []io.Writer{logFile, os.Stderr}
	if verbose {
		iLogs = append(iLogs, os.Stdout)
		wLogs = append(wLogs, os.Stdout)
	}
	if il != nil {
		iLogs = append(iLogs, il)
	}
	if wl != nil {
		wLogs = append(wLogs, wl)
	}
	if el != nil {
		eLogs = append(eLogs, el)
	}

	l := Logger{
		infoLog:    log.New(io.MultiWriter(iLogs...), tagInfo, flags),
		warningLog: log.New(io.MultiWriter(wLogs...), tagWarning, flags),
		errorLog:   log.New(io.MultiWriter(eLogs...), tagError, flags),
		fatalLog:   log.New(io.MultiWriter(eLogs...), tagFatal, flags),
	}
	for _, w := range []io.Writer{logFile, il, wl, el} {
		if c, ok := w.(io.Closer); ok && c != nil {
			l.closers = append(l.closers, c)
		}
	}
	l.initialized = true

	logLock.Lock()
	defer logLock.Unlock()
	if !defaultLogger.initialized {
		defaultLogger = &l
	}

	return &l
}

// A Logger represents an active logging object. Multiple loggers can be used
// simultaneously even if they are using the same same writers.
type Logger struct {
	infoLog     *log.Logger
	warningLog  *log.Logger
	errorLog    *log.Logger
	fatalLog    *log.Logger
	closers     []io.Closer
	initialized bool
}

func (l *Logger) output(s severity, depth int, txt string) {
	logLock.Lock()
	defer logLock.Unlock()
	switch s {
	case sInfo:
		l.infoLog.Output(3+depth, txt)
	case sWarning:
		l.warningLog.Output(3+depth, txt)
	case sError:
		l.errorLog.Output(3+depth, txt)
	case sFatal:
		l.fatalLog.Output(3+depth, txt)
	default:
		panic(fmt.Sprintln("unrecognized severity:", s))
	}
}

// Close closes all the underlying log writers, which will flush any cached logs.
// Any errors from closing the underlying log writers will be printed to stderr.
// Once Close is called, all future calls to the logger will panic.
func (l *Logger) Close() {
	logLock.Lock()
	defer logLock.Unlock()
	for _, c := range l.closers {
		if err := c.Close(); err != nil {
			fmt.Fprintf(os.Stderr, "Failed to close log %v: %v\n", c, err)
		}
	}
}

// Info logs with the Info severity.
// Arguments are handled in the manner of fmt.Print.
func (l *Logger) Info(v ...interface{}) {
	l.output(sInfo, 0, fmt.Sprint(v...))
}

// InfoDepth acts as Info but uses depth to determine which call frame to log.
// InfoDepth(0, "msg") is the same as Info("msg").
func (l *Logger) InfoDepth(depth int, v ...interface{}) {
	l.output(sInfo, depth, fmt.Sprint(v...))
}

// Infoln logs with the Info severity.
// Arguments are handled in the manner of fmt.Println.
func (l *Logger) Infoln(v ...interface{}) {
	l.output(sInfo, 0, fmt.Sprintln(v...))
}

// Infof logs with the Info severity.
// Arguments are handled in the manner of fmt.Printf.
func (l *Logger) Infof(format string, v ...interface{}) {
	l.output(sInfo, 0, fmt.Sprintf(format, v...))
}

// Warning logs with the Warning severity.
// Arguments are handled in the manner of fmt.Print.
func (l *Logger) Warning(v ...interface{}) {
	l.output(sWarning, 0, fmt.Sprint(v...))
}

// WarningDepth acts as Warning but uses depth to determine which call frame to log.
// WarningDepth(0, "msg") is the same as Warning("msg").
func (l *Logger) WarningDepth(depth int, v ...interface{}) {
	l.output(sWarning, depth, fmt.Sprint(v...))
}

// Warningln logs with the Warning severity.
// Arguments are handled in the manner of fmt.Println.
func (l *Logger) Warningln(v ...interface{}) {
	l.output(sWarning, 0, fmt.Sprintln(v...))
}

// Warningf logs with the Warning severity.
// Arguments are handled in the manner of fmt.Printf.
func (l *Logger) Warningf(format string, v ...interface{}) {
	l.output(sWarning, 0, fmt.Sprintf(format, v...))
}

// Error logs with the ERROR severity.
// Arguments are handled in the manner of fmt.Print.
func (l *Logger) Error(v ...interface{}) {
	l.output(sError, 0, fmt.Sprint(v...))
}

// ErrorDepth acts as Error but uses depth to determine which call frame to log.
// ErrorDepth(0, "msg") is the same as Error("msg").
func (l *Logger) ErrorDepth(depth int, v ...interface{}) {
	l.output(sError, depth, fmt.Sprint(v...))
}

// Errorln logs with the ERROR severity.
// Arguments are handled in the manner of fmt.Println.
func (l *Logger) Errorln(v ...interface{}) {
	l.output(sError, 0, fmt.Sprintln(v...))
}

// Errorf logs with the Error severity.
// Arguments are handled in the manner of fmt.Printf.
func (l *Logger) Errorf(format string, v ...interface{}) {
	l.output(sError, 0, fmt.Sprintf(format, v...))
}

// Fatal logs with the Fatal severity, and ends with os.Exit(1).
// Arguments are handled in the manner of fmt.Print.
func (l *Logger) Fatal(v ...interface{}) {
	l.output(sFatal, 0, fmt.Sprint(v...))
	l.Close()
	os.Exit(1)
}

// FatalDepth acts as Fatal but uses depth to determine which call frame to log.
// FatalDepth(0, "msg") is the same as Fatal("msg").
func (l *Logger) FatalDepth(depth int, v ...interface{}) {
	l.output(sFatal, depth, fmt.Sprint(v...))
	l.Close()
	os.Exit(1)
}

// Fatalln logs with the Fatal severity, and ends with os.Exit(1).
// Arguments are handled in the manner of fmt.Println.
func (l *Logger) Fatalln(v ...interface{}) {
	l.output(sFatal, 0, fmt.Sprintln(v...))
	l.Close()
	os.Exit(1)
}

// Fatalf logs with the Fatal severity, and ends with os.Exit(1).
// Arguments are handled in the manner of fmt.Printf.
func (l *Logger) Fatalf(format string, v ...interface{}) {
	l.output(sFatal, 0, fmt.Sprintf(format, v...))
	l.Close()
	os.Exit(1)
}

// Info uses the default logger and logs with the Info severity.
// Arguments are handled in the manner of fmt.Print.
func Info(v ...interface{}) {
	defaultLogger.output(sInfo, 0, fmt.Sprint(v...))
}

// InfoDepth acts as Info but uses depth to determine which call frame to log.
// InfoDepth(0, "msg") is the same as Info("msg").
func InfoDepth(depth int, v ...interface{}) {
	defaultLogger.output(sInfo, depth, fmt.Sprint(v...))
}

// Infoln uses the default logger and logs with the Info severity.
// Arguments are handled in the manner of fmt.Println.
func Infoln(v ...interface{}) {
	defaultLogger.output(sInfo, 0, fmt.Sprintln(v...))
}

// Infof uses the default logger and logs with the Info severity.
// Arguments are handled in the manner of fmt.Printf.
func Infof(format string, v ...interface{}) {
	defaultLogger.output(sInfo, 0, fmt.Sprintf(format, v...))
}

// Warning uses the default logger and logs with the Warning severity.
// Arguments are handled in the manner of fmt.Print.
func Warning(v ...interface{}) {
	defaultLogger.output(sWarning, 0, fmt.Sprint(v...))
}

// WarningDepth acts as Warning but uses depth to determine which call frame to log.
// WarningDepth(0, "msg") is the same as Warning("msg").
func WarningDepth(depth int, v ...interface{}) {
	defaultLogger.output(sWarning, depth, fmt.Sprint(v...))
}

// Warningln uses the default logger and logs with the Warning severity.
// Arguments are handled in the manner of fmt.Println.
func Warningln(v ...interface{}) {
	defaultLogger.output(sWarning, 0, fmt.Sprintln(v...))
}

// Warningf uses the default logger and logs with the Warning severity.
// Arguments are handled in the manner of fmt.Printf.
func Warningf(format string, v ...interface{}) {
	defaultLogger.output(sWarning, 0, fmt.Sprintf(format, v...))
}

// Error uses the default logger and logs with the Error severity.
// Arguments are handled in the manner of fmt.Print.
func Error(v ...interface{}) {
	defaultLogger.output(sError, 0, fmt.Sprint(v...))
}

// ErrorDepth acts as Error but uses depth to determine which call frame to log.
// ErrorDepth(0, "msg") is the same as Error("msg").
func ErrorDepth(depth int, v ...interface{}) {
	defaultLogger.output(sError, depth, fmt.Sprint(v...))
}

// Errorln uses the default logger and logs with the Error severity.
// Arguments are handled in the manner of fmt.Println.
func Errorln(v ...interface{}) {
	defaultLogger.output(sError, 0, fmt.Sprintln(v...))
}

// Errorf uses the default logger and logs with the Error severity.
// Arguments are handled in the manner of fmt.Printf.
func Errorf(format string, v ...interface{}) {
	defaultLogger.output(sError, 0, fmt.Sprintf(format, v...))
}

// Fatalln uses the default logger, logs with the Fatal severity,
// and ends with os.Exit(1).
// Arguments are handled in the manner of fmt.Print.
func Fatal(v ...interface{}) {
	defaultLogger.output(sFatal, 0, fmt.Sprint(v...))
	defaultLogger.Close()
	os.Exit(1)
}

// FatalDepth acts as Fatal but uses depth to determine which call frame to log.
// FatalDepth(0, "msg") is the same as Fatal("msg").
func FatalDepth(depth int, v ...interface{}) {
	defaultLogger.output(sFatal, depth, fmt.Sprint(v...))
	defaultLogger.Close()
	os.Exit(1)
}

// Fatalln uses the default logger, logs with the Fatal severity,
// and ends with os.Exit(1).
// Arguments are handled in the manner of fmt.Println.
func Fatalln(v ...interface{}) {
	defaultLogger.output(sFatal, 0, fmt.Sprintln(v...))
	defaultLogger.Close()
	os.Exit(1)
}

// Fatalf uses the default logger, logs with the Fatal severity,
// and ends with os.Exit(1).
// Arguments are handled in the manner of fmt.Printf.
func Fatalf(format string, v ...interface{}) {
	defaultLogger.output(sFatal, 0, fmt.Sprintf(format, v...))
	defaultLogger.Close()
	os.Exit(1)
}
<commit_msg>fix error and verbose logging for windows services (#14)<commit_after>/*
Copyright 2016 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Package logger offers simple cross platform logging for Windows and Linux.
// Available logging endpoints are event log (Windows), syslog (Linux), and
// an io.Writer.
package logger

import (
	"fmt"
	"io"
	"log"
	"os"
	"sync"
)

type severity int

// Severity levels.
const (
	sInfo severity = iota
	sWarning
	sError
	sFatal
)

// Severity tags.
const (
	tagInfo    = "INFO : "
	tagWarning = "WARN : "
	tagError   = "ERROR: "
	tagFatal   = "FATAL: "
)

const (
	flags    = log.Ldate | log.Lmicroseconds | log.Lshortfile
	initText = "ERROR: Logging before logger.Init.\n"
)

var (
	logLock       sync.Mutex
	defaultLogger *Logger
)

// initialize resets defaultLogger.  Which allows tests to reset environment.
func initialize() {
	defaultLogger = &Logger{
		infoLog:    log.New(os.Stderr, initText+tagInfo, flags),
		warningLog: log.New(os.Stderr, initText+tagWarning, flags),
		errorLog:   log.New(os.Stderr, initText+tagError, flags),
		fatalLog:   log.New(os.Stderr, initText+tagFatal, flags),
	}
}

func init() {
	initialize()
}

// Init sets up logging and should be called before log functions, usually in
// the caller's main(). Default log functions can be called before Init(), but log
// output will only go to stderr (along with a warning).
// The first call to Init populates the default logger and returns the
// generated logger, subsequent calls to Init will only return the generated
// logger.
// If the logFile passed in also satisfies io.Closer, logFile.Close will be called
// when closing the logger.
func Init(name string, verbose, systemLog bool, logFile io.Writer) *Logger {
	var il, wl, el io.Writer
	if systemLog {
		var err error
		il, wl, el, err = setup(name)
		if err != nil {
			log.Fatal(err)
		}
	}

	iLogs := []io.Writer{logFile}
	wLogs := []io.Writer{logFile}
	eLogs := []io.Writer{logFile}
	if il != nil {
		iLogs = append(iLogs, il)
	}
	if wl != nil {
		wLogs = append(wLogs, wl)
	}
	if el != nil {
		eLogs = append(eLogs, el)
	}
	// Windows services don't have stdout/stderr. Writes will fail, so try them last.
	eLogs = append(eLogs, os.Stderr)
	if verbose {
		iLogs = append(iLogs, os.Stdout)
		wLogs = append(wLogs, os.Stdout)
	}

	l := Logger{
		infoLog:    log.New(io.MultiWriter(iLogs...), tagInfo, flags),
		warningLog: log.New(io.MultiWriter(wLogs...), tagWarning, flags),
		errorLog:   log.New(io.MultiWriter(eLogs...), tagError, flags),
		fatalLog:   log.New(io.MultiWriter(eLogs...), tagFatal, flags),
	}
	for _, w := range []io.Writer{logFile, il, wl, el} {
		if c, ok := w.(io.Closer); ok && c != nil {
			l.closers = append(l.closers, c)
		}
	}
	l.initialized = true

	logLock.Lock()
	defer logLock.Unlock()
	if !defaultLogger.initialized {
		defaultLogger = &l
	}

	return &l
}

// A Logger represents an active logging object. Multiple loggers can be used
// simultaneously even if they are using the same same writers.
type Logger struct {
	infoLog     *log.Logger
	warningLog  *log.Logger
	errorLog    *log.Logger
	fatalLog    *log.Logger
	closers     []io.Closer
	initialized bool
}

func (l *Logger) output(s severity, depth int, txt string) {
	logLock.Lock()
	defer logLock.Unlock()
	switch s {
	case sInfo:
		l.infoLog.Output(3+depth, txt)
	case sWarning:
		l.warningLog.Output(3+depth, txt)
	case sError:
		l.errorLog.Output(3+depth, txt)
	case sFatal:
		l.fatalLog.Output(3+depth, txt)
	default:
		panic(fmt.Sprintln("unrecognized severity:", s))
	}
}

// Close closes all the underlying log writers, which will flush any cached logs.
// Any errors from closing the underlying log writers will be printed to stderr.
// Once Close is called, all future calls to the logger will panic.
func (l *Logger) Close() {
	logLock.Lock()
	defer logLock.Unlock()
	for _, c := range l.closers {
		if err := c.Close(); err != nil {
			fmt.Fprintf(os.Stderr, "Failed to close log %v: %v\n", c, err)
		}
	}
}

// Info logs with the Info severity.
// Arguments are handled in the manner of fmt.Print.
func (l *Logger) Info(v ...interface{}) {
	l.output(sInfo, 0, fmt.Sprint(v...))
}

// InfoDepth acts as Info but uses depth to determine which call frame to log.
// InfoDepth(0, "msg") is the same as Info("msg").
func (l *Logger) InfoDepth(depth int, v ...interface{}) {
	l.output(sInfo, depth, fmt.Sprint(v...))
}

// Infoln logs with the Info severity.
// Arguments are handled in the manner of fmt.Println.
func (l *Logger) Infoln(v ...interface{}) {
	l.output(sInfo, 0, fmt.Sprintln(v...))
}

// Infof logs with the Info severity.
// Arguments are handled in the manner of fmt.Printf.
func (l *Logger) Infof(format string, v ...interface{}) {
	l.output(sInfo, 0, fmt.Sprintf(format, v...))
}

// Warning logs with the Warning severity.
// Arguments are handled in the manner of fmt.Print.
func (l *Logger) Warning(v ...interface{}) {
	l.output(sWarning, 0, fmt.Sprint(v...))
}

// WarningDepth acts as Warning but uses depth to determine which call frame to log.
// WarningDepth(0, "msg") is the same as Warning("msg").
func (l *Logger) WarningDepth(depth int, v ...interface{}) {
	l.output(sWarning, depth, fmt.Sprint(v...))
}

// Warningln logs with the Warning severity.
// Arguments are handled in the manner of fmt.Println.
func (l *Logger) Warningln(v ...interface{}) {
	l.output(sWarning, 0, fmt.Sprintln(v...))
}

// Warningf logs with the Warning severity.
// Arguments are handled in the manner of fmt.Printf.
func (l *Logger) Warningf(format string, v ...interface{}) {
	l.output(sWarning, 0, fmt.Sprintf(format, v...))
}

// Error logs with the ERROR severity.
// Arguments are handled in the manner of fmt.Print.
func (l *Logger) Error(v ...interface{}) {
	l.output(sError, 0, fmt.Sprint(v...))
}

// ErrorDepth acts as Error but uses depth to determine which call frame to log.
// ErrorDepth(0, "msg") is the same as Error("msg").
func (l *Logger) ErrorDepth(depth int, v ...interface{}) {
	l.output(sError, depth, fmt.Sprint(v...))
}

// Errorln logs with the ERROR severity.
// Arguments are handled in the manner of fmt.Println.
func (l *Logger) Errorln(v ...interface{}) {
	l.output(sError, 0, fmt.Sprintln(v...))
}

// Errorf logs with the Error severity.
// Arguments are handled in the manner of fmt.Printf.
func (l *Logger) Errorf(format string, v ...interface{}) {
	l.output(sError, 0, fmt.Sprintf(format, v...))
}

// Fatal logs with the Fatal severity, and ends with os.Exit(1).
// Arguments are handled in the manner of fmt.Print.
func (l *Logger) Fatal(v ...interface{}) {
	l.output(sFatal, 0, fmt.Sprint(v...))
	l.Close()
	os.Exit(1)
}

// FatalDepth acts as Fatal but uses depth to determine which call frame to log.
// FatalDepth(0, "msg") is the same as Fatal("msg").
func (l *Logger) FatalDepth(depth int, v ...interface{}) {
	l.output(sFatal, depth, fmt.Sprint(v...))
	l.Close()
	os.Exit(1)
}

// Fatalln logs with the Fatal severity, and ends with os.Exit(1).
// Arguments are handled in the manner of fmt.Println.
func (l *Logger) Fatalln(v ...interface{}) {
	l.output(sFatal, 0, fmt.Sprintln(v...))
	l.Close()
	os.Exit(1)
}

// Fatalf logs with the Fatal severity, and ends with os.Exit(1).
// Arguments are handled in the manner of fmt.Printf.
func (l *Logger) Fatalf(format string, v ...interface{}) {
	l.output(sFatal, 0, fmt.Sprintf(format, v...))
	l.Close()
	os.Exit(1)
}

// Info uses the default logger and logs with the Info severity.
// Arguments are handled in the manner of fmt.Print.
func Info(v ...interface{}) {
	defaultLogger.output(sInfo, 0, fmt.Sprint(v...))
}

// InfoDepth acts as Info but uses depth to determine which call frame to log.
// InfoDepth(0, "msg") is the same as Info("msg").
func InfoDepth(depth int, v ...interface{}) {
	defaultLogger.output(sInfo, depth, fmt.Sprint(v...))
}

// Infoln uses the default logger and logs with the Info severity.
// Arguments are handled in the manner of fmt.Println.
func Infoln(v ...interface{}) {
	defaultLogger.output(sInfo, 0, fmt.Sprintln(v...))
}

// Infof uses the default logger and logs with the Info severity.
// Arguments are handled in the manner of fmt.Printf.
func Infof(format string, v ...interface{}) {
	defaultLogger.output(sInfo, 0, fmt.Sprintf(format, v...))
}

// Warning uses the default logger and logs with the Warning severity.
// Arguments are handled in the manner of fmt.Print.
func Warning(v ...interface{}) {
	defaultLogger.output(sWarning, 0, fmt.Sprint(v...))
}

// WarningDepth acts as Warning but uses depth to determine which call frame to log.
// WarningDepth(0, "msg") is the same as Warning("msg").
func WarningDepth(depth int, v ...interface{}) {
	defaultLogger.output(sWarning, depth, fmt.Sprint(v...))
}

// Warningln uses the default logger and logs with the Warning severity.
// Arguments are handled in the manner of fmt.Println.
func Warningln(v ...interface{}) {
	defaultLogger.output(sWarning, 0, fmt.Sprintln(v...))
}

// Warningf uses the default logger and logs with the Warning severity.
// Arguments are handled in the manner of fmt.Printf.
func Warningf(format string, v ...interface{}) {
	defaultLogger.output(sWarning, 0, fmt.Sprintf(format, v...))
}

// Error uses the default logger and logs with the Error severity.
// Arguments are handled in the manner of fmt.Print.
func Error(v ...interface{}) {
	defaultLogger.output(sError, 0, fmt.Sprint(v...))
}

// ErrorDepth acts as Error but uses depth to determine which call frame to log.
// ErrorDepth(0, "msg") is the same as Error("msg").
func ErrorDepth(depth int, v ...interface{}) {
	defaultLogger.output(sError, depth, fmt.Sprint(v...))
}

// Errorln uses the default logger and logs with the Error severity.
// Arguments are handled in the manner of fmt.Println.
func Errorln(v ...interface{}) {
	defaultLogger.output(sError, 0, fmt.Sprintln(v...))
}

// Errorf uses the default logger and logs with the Error severity.
// Arguments are handled in the manner of fmt.Printf.
func Errorf(format string, v ...interface{}) {
	defaultLogger.output(sError, 0, fmt.Sprintf(format, v...))
}

// Fatalln uses the default logger, logs with the Fatal severity,
// and ends with os.Exit(1).
// Arguments are handled in the manner of fmt.Print.
func Fatal(v ...interface{}) {
	defaultLogger.output(sFatal, 0, fmt.Sprint(v...))
	defaultLogger.Close()
	os.Exit(1)
}

// FatalDepth acts as Fatal but uses depth to determine which call frame to log.
// FatalDepth(0, "msg") is the same as Fatal("msg").
func FatalDepth(depth int, v ...interface{}) {
	defaultLogger.output(sFatal, depth, fmt.Sprint(v...))
	defaultLogger.Close()
	os.Exit(1)
}

// Fatalln uses the default logger, logs with the Fatal severity,
// and ends with os.Exit(1).
// Arguments are handled in the manner of fmt.Println.
func Fatalln(v ...interface{}) {
	defaultLogger.output(sFatal, 0, fmt.Sprintln(v...))
	defaultLogger.Close()
	os.Exit(1)
}

// Fatalf uses the default logger, logs with the Fatal severity,
// and ends with os.Exit(1).
// Arguments are handled in the manner of fmt.Printf.
func Fatalf(format string, v ...interface{}) {
	defaultLogger.output(sFatal, 0, fmt.Sprintf(format, v...))
	defaultLogger.Close()
	os.Exit(1)
}
<|endoftext|>


<commit_before>package log4go

import (
	"fmt"
	"time"
)

type LogLevel uint16

const (
	LogAll   LogLevel = 0
	LogTrace LogLevel = 100
	LogDebug LogLevel = 200
	LogInfo  LogLevel = 300
	LogWarn  LogLevel = 400
	LogError LogLevel = 500
	LogFatal LogLevel = 600
)

const (
	TF_NCSA  = "02/Jan/2006:15:04:05 -0700"
	TF_GoStd = "2006/01/02 15:04:05"
)

type Log4Go interface {
	Log(level LogLevel, format string, a ...interface{})
	Trace(format string, a ...interface{})
	Debug(format string, a ...interface{})
	Info(format string, a ...interface{})
	Warn(format string, a ...interface{})
	Error(format string, a ...interface{})
	Fatal(format string, a ...interface{})
	GetLogLevel() LogLevel
	SetLogLevel(level LogLevel)
}

type stdLogger struct {
	appender   appender
	level      LogLevel
	timePrefix string
}

var levelMap = map[LogLevel]string{
	LogAll:   "LOG",
	LogTrace: "TRACE",
	LogDebug: "DEBUG",
	LogInfo:  "INFO",
	LogWarn:  "WARN",
	LogError: "ERROR",
	LogFatal: "FATAL",
}

func (l *stdLogger) Log(level LogLevel, format string, a ...interface{}) {
	tstamp := time.Now()
	if level >= l.level {
		msg := fmt.Sprintf(format, a...)
		if l.timePrefix != "" {
			timePrefix := tstamp.Format(l.timePrefix)
			msg = fmt.Sprintf("%s %s: %s\n", timePrefix, levelMap[level], msg)
		} else {
			msg = fmt.Sprintf("%s: %s\n", levelMap[level], msg)
		}

		l.appender.Append(msg, level, tstamp)
	}
}

func (l *stdLogger) Trace(format string, a ...interface{}) {
	l.Log(LogTrace, format, a...)
}

func (l *stdLogger) Debug(format string, a ...interface{}) {
	l.Log(LogDebug, format, a...)
}

func (l *stdLogger) Info(format string, a ...interface{}) {
	l.Log(LogInfo, format, a...)
}

func (l *stdLogger) Warn(format string, a ...interface{}) {
	l.Log(LogWarn, format, a...)
}

func (l *stdLogger) Error(format string, a ...interface{}) {
	l.Log(LogError, format, a...)
}

func (l *stdLogger) Fatal(format string, a ...interface{}) {
	l.Log(LogFatal, format, a...)
}

func (l *stdLogger) GetLogLevel() LogLevel {
	return l.level
}

func (l *stdLogger) SetLogLevel(level LogLevel) {
	l.level = level
}
<commit_msg>ability to add or override log level prefixes<commit_after>package log4go

import (
	"fmt"
	"time"
)

type LogLevel uint16

const (
	LogAll   LogLevel = 0
	LogTrace LogLevel = 100
	LogDebug LogLevel = 200
	LogInfo  LogLevel = 300
	LogWarn  LogLevel = 400
	LogError LogLevel = 500
	LogFatal LogLevel = 600
)

const (
	TF_NCSA  = "02/Jan/2006:15:04:05 -0700"
	TF_GoStd = "2006/01/02 15:04:05"
)

type Log4Go interface {
	Log(level LogLevel, format string, a ...interface{})
	Trace(format string, a ...interface{})
	Debug(format string, a ...interface{})
	Info(format string, a ...interface{})
	Warn(format string, a ...interface{})
	Error(format string, a ...interface{})
	Fatal(format string, a ...interface{})
	GetLogLevel() LogLevel
	SetLogLevel(level LogLevel)
}

type stdLogger struct {
	appender   appender
	level      LogLevel
	timePrefix string
}

var levelMap = map[LogLevel]string{
	LogAll:   "LOG",
	LogTrace: "TRACE",
	LogDebug: "DEBUG",
	LogInfo:  "INFO",
	LogWarn:  "WARN",
	LogError: "ERROR",
	LogFatal: "FATAL",
}

func (l *stdLogger) Log(level LogLevel, format string, a ...interface{}) {
	tstamp := time.Now()
	if level >= l.level {
		msg := fmt.Sprintf(format, a...)
		if l.timePrefix != "" {
			timePrefix := tstamp.Format(l.timePrefix)
			msg = fmt.Sprintf("%s %s: %s\n", timePrefix, levelMap[level], msg)
		} else {
			msg = fmt.Sprintf("%s: %s\n", levelMap[level], msg)
		}

		l.appender.Append(msg, level, tstamp)
	}
}

func (l *stdLogger) Trace(format string, a ...interface{}) {
	l.Log(LogTrace, format, a...)
}

func (l *stdLogger) Debug(format string, a ...interface{}) {
	l.Log(LogDebug, format, a...)
}

func (l *stdLogger) Info(format string, a ...interface{}) {
	l.Log(LogInfo, format, a...)
}

func (l *stdLogger) Warn(format string, a ...interface{}) {
	l.Log(LogWarn, format, a...)
}

func (l *stdLogger) Error(format string, a ...interface{}) {
	l.Log(LogError, format, a...)
}

func (l *stdLogger) Fatal(format string, a ...interface{}) {
	l.Log(LogFatal, format, a...)
}

func (l *stdLogger) GetLogLevel() LogLevel {
	return l.level
}

func (l *stdLogger) SetLogLevel(level LogLevel) {
	l.level = level
}

func RegisterLogLevel(level LogLevel, prefix string) {
  levelMap[level] = prefix
}
<|endoftext|>


<commit_before>// Copyright (c) 2015 Uber Technologies, Inc.

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package tchannel

import (
	"fmt"
	"io"
	"time"
)

import (
	"os"
)

// Logger provides an abstract interface for logging from TChannel.
// Applications can provide their own implementation of this interface to adapt
// TChannel logging to whatever logging library they prefer (stdlib log,
// logrus, go-logging, etc).  The SimpleLogger adapts to the standard go log
// package.
type Logger interface {
	// Enabled returns whether the given level is enabled.
	Enabled(level LogLevel) bool

	// Fatal logs a message, then exits with os.Exit(1).
	Fatal(msg string)

	// Error logs a message at error priority.
	Error(msg string)

	// Warn logs a message at warning priority.
	Warn(msg string)

	// Infof logs a message at info priority.
	Infof(msg string, args ...interface{})

	// Info logs a message at info priority.
	Info(msg string)

	// Debugf logs a message at debug priority.
	Debugf(msg string, args ...interface{})

	// Debug logs a message at debug priority.
	Debug(msg string)

	// Fields returns the fields that this logger contains.
	Fields() LogFields

	// WithFields returns a logger with the current logger's fields and fields.
	WithFields(fields ...LogField) Logger
}

// LogField is a single field of additional information passed to the logger.
type LogField struct {
	Key   string
	Value interface{}
}

func ErrField(err error) LogField {
	return LogField{"error", err.Error()}
}

// LogFields is a list of LogFields used to pass additional information to the logger.
type LogFields []LogField

// NullLogger is a logger that emits nowhere
var NullLogger Logger = nullLogger{}

type nullLogger struct{}

func (nullLogger) Enabled(_ LogLevel) bool                { return false }
func (nullLogger) Fatal(msg string)                       { os.Exit(1) }
func (nullLogger) Error(msg string)                       {}
func (nullLogger) Warn(msg string)                        {}
func (nullLogger) Infof(msg string, args ...interface{})  {}
func (nullLogger) Info(msg string)                        {}
func (nullLogger) Debugf(msg string, args ...interface{}) {}
func (nullLogger) Debug(msg string)                       {}
func (nullLogger) Fields() LogFields                      { return nil }
func (l nullLogger) WithFields(_ ...LogField) Logger      { return l }

// SimpleLogger prints logging information to standard out.
var SimpleLogger = NewLogger(os.Stdout)

type writerLogger struct {
	writer io.Writer
	fields LogFields
}

const writerLoggerStamp = "15:04:05.000000"

// NewLogger returns a Logger that writes to the given writer.
func NewLogger(writer io.Writer, fields ...LogField) Logger {
	return &writerLogger{writer, fields}
}

func (l writerLogger) Fatal(msg string) {
	l.printfn("F", msg)
	os.Exit(1)
}

func (l writerLogger) Enabled(_ LogLevel) bool                { return true }
func (l writerLogger) Error(msg string)                       { l.printfn("E", msg) }
func (l writerLogger) Warn(msg string)                        { l.printfn("W", msg) }
func (l writerLogger) Infof(msg string, args ...interface{})  { l.printfn("I", msg, args...) }
func (l writerLogger) Info(msg string)                        { l.printfn("I", msg) }
func (l writerLogger) Debugf(msg string, args ...interface{}) { l.printfn("D", msg, args...) }
func (l writerLogger) Debug(msg string)                       { l.printfn("D", msg) }
func (l writerLogger) printfn(prefix, msg string, args ...interface{}) {
	fmt.Fprintf(l.writer, "%s [%s] %s tags: %v\n", time.Now().Format(writerLoggerStamp), prefix, fmt.Sprintf(msg, args...), l.fields)
}

func (l writerLogger) Fields() LogFields {
	return l.fields
}

func (l writerLogger) WithFields(newFields ...LogField) Logger {
	existingFields := l.Fields()
	fields := make(LogFields, 0, len(existingFields)+1)
	fields = append(fields, existingFields...)
	fields = append(fields, newFields...)
	return writerLogger{l.writer, fields}
}

// LogLevel is the level of logging used by LevelLogger.
type LogLevel int

// The minimum level that will be logged. e.g. LogLevelError only logs errors and fatals.
const (
	LogLevelAll LogLevel = iota
	LogLevelDebug
	LogLevelInfo
	LogLevelWarn
	LogLevelError
	LogLevelFatal
)

type levelLogger struct {
	logger Logger
	level  LogLevel
}

// NewLevelLogger returns a logger that only logs messages with a minimum of level.
func NewLevelLogger(logger Logger, level LogLevel) Logger {
	return levelLogger{logger, level}
}

func (l levelLogger) Enabled(level LogLevel) bool {
	return l.level <= level
}

func (l levelLogger) Fatal(msg string) {
	if l.level <= LogLevelFatal {
		l.logger.Fatal(msg)
	}
}

func (l levelLogger) Error(msg string) {
	if l.level <= LogLevelError {
		l.logger.Error(msg)
	}
}

func (l levelLogger) Warn(msg string) {
	if l.level <= LogLevelWarn {
		l.logger.Warn(msg)
	}
}

func (l levelLogger) Infof(msg string, args ...interface{}) {
	if l.level <= LogLevelInfo {
		l.logger.Infof(msg, args...)
	}
}

func (l levelLogger) Info(msg string) {
	if l.level <= LogLevelInfo {
		l.logger.Info(msg)
	}
}

func (l levelLogger) Debugf(msg string, args ...interface{}) {
	if l.level <= LogLevelDebug {
		l.logger.Debugf(msg, args...)
	}
}

func (l levelLogger) Debug(msg string) {
	if l.level <= LogLevelDebug {
		l.logger.Debug(msg)
	}
}

func (l levelLogger) Fields() LogFields {
	return l.logger.Fields()
}

func (l levelLogger) WithFields(fields ...LogField) Logger {
	return levelLogger{
		logger: l.logger.WithFields(fields...),
		level:  l.level,
	}
}
<commit_msg>logger.go: add comment to ErrField<commit_after>// Copyright (c) 2015 Uber Technologies, Inc.

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package tchannel

import (
	"fmt"
	"io"
	"time"
)

import (
	"os"
)

// Logger provides an abstract interface for logging from TChannel.
// Applications can provide their own implementation of this interface to adapt
// TChannel logging to whatever logging library they prefer (stdlib log,
// logrus, go-logging, etc).  The SimpleLogger adapts to the standard go log
// package.
type Logger interface {
	// Enabled returns whether the given level is enabled.
	Enabled(level LogLevel) bool

	// Fatal logs a message, then exits with os.Exit(1).
	Fatal(msg string)

	// Error logs a message at error priority.
	Error(msg string)

	// Warn logs a message at warning priority.
	Warn(msg string)

	// Infof logs a message at info priority.
	Infof(msg string, args ...interface{})

	// Info logs a message at info priority.
	Info(msg string)

	// Debugf logs a message at debug priority.
	Debugf(msg string, args ...interface{})

	// Debug logs a message at debug priority.
	Debug(msg string)

	// Fields returns the fields that this logger contains.
	Fields() LogFields

	// WithFields returns a logger with the current logger's fields and fields.
	WithFields(fields ...LogField) Logger
}

// LogField is a single field of additional information passed to the logger.
type LogField struct {
	Key   string
	Value interface{}
}

// ErrField wraps an error string as a LogField named "error"
func ErrField(err error) LogField {
	return LogField{"error", err.Error()}
}

// LogFields is a list of LogFields used to pass additional information to the logger.
type LogFields []LogField

// NullLogger is a logger that emits nowhere
var NullLogger Logger = nullLogger{}

type nullLogger struct{}

func (nullLogger) Enabled(_ LogLevel) bool                { return false }
func (nullLogger) Fatal(msg string)                       { os.Exit(1) }
func (nullLogger) Error(msg string)                       {}
func (nullLogger) Warn(msg string)                        {}
func (nullLogger) Infof(msg string, args ...interface{})  {}
func (nullLogger) Info(msg string)                        {}
func (nullLogger) Debugf(msg string, args ...interface{}) {}
func (nullLogger) Debug(msg string)                       {}
func (nullLogger) Fields() LogFields                      { return nil }
func (l nullLogger) WithFields(_ ...LogField) Logger      { return l }

// SimpleLogger prints logging information to standard out.
var SimpleLogger = NewLogger(os.Stdout)

type writerLogger struct {
	writer io.Writer
	fields LogFields
}

const writerLoggerStamp = "15:04:05.000000"

// NewLogger returns a Logger that writes to the given writer.
func NewLogger(writer io.Writer, fields ...LogField) Logger {
	return &writerLogger{writer, fields}
}

func (l writerLogger) Fatal(msg string) {
	l.printfn("F", msg)
	os.Exit(1)
}

func (l writerLogger) Enabled(_ LogLevel) bool                { return true }
func (l writerLogger) Error(msg string)                       { l.printfn("E", msg) }
func (l writerLogger) Warn(msg string)                        { l.printfn("W", msg) }
func (l writerLogger) Infof(msg string, args ...interface{})  { l.printfn("I", msg, args...) }
func (l writerLogger) Info(msg string)                        { l.printfn("I", msg) }
func (l writerLogger) Debugf(msg string, args ...interface{}) { l.printfn("D", msg, args...) }
func (l writerLogger) Debug(msg string)                       { l.printfn("D", msg) }
func (l writerLogger) printfn(prefix, msg string, args ...interface{}) {
	fmt.Fprintf(l.writer, "%s [%s] %s tags: %v\n", time.Now().Format(writerLoggerStamp), prefix, fmt.Sprintf(msg, args...), l.fields)
}

func (l writerLogger) Fields() LogFields {
	return l.fields
}

func (l writerLogger) WithFields(newFields ...LogField) Logger {
	existingFields := l.Fields()
	fields := make(LogFields, 0, len(existingFields)+1)
	fields = append(fields, existingFields...)
	fields = append(fields, newFields...)
	return writerLogger{l.writer, fields}
}

// LogLevel is the level of logging used by LevelLogger.
type LogLevel int

// The minimum level that will be logged. e.g. LogLevelError only logs errors and fatals.
const (
	LogLevelAll LogLevel = iota
	LogLevelDebug
	LogLevelInfo
	LogLevelWarn
	LogLevelError
	LogLevelFatal
)

type levelLogger struct {
	logger Logger
	level  LogLevel
}

// NewLevelLogger returns a logger that only logs messages with a minimum of level.
func NewLevelLogger(logger Logger, level LogLevel) Logger {
	return levelLogger{logger, level}
}

func (l levelLogger) Enabled(level LogLevel) bool {
	return l.level <= level
}

func (l levelLogger) Fatal(msg string) {
	if l.level <= LogLevelFatal {
		l.logger.Fatal(msg)
	}
}

func (l levelLogger) Error(msg string) {
	if l.level <= LogLevelError {
		l.logger.Error(msg)
	}
}

func (l levelLogger) Warn(msg string) {
	if l.level <= LogLevelWarn {
		l.logger.Warn(msg)
	}
}

func (l levelLogger) Infof(msg string, args ...interface{}) {
	if l.level <= LogLevelInfo {
		l.logger.Infof(msg, args...)
	}
}

func (l levelLogger) Info(msg string) {
	if l.level <= LogLevelInfo {
		l.logger.Info(msg)
	}
}

func (l levelLogger) Debugf(msg string, args ...interface{}) {
	if l.level <= LogLevelDebug {
		l.logger.Debugf(msg, args...)
	}
}

func (l levelLogger) Debug(msg string) {
	if l.level <= LogLevelDebug {
		l.logger.Debug(msg)
	}
}

func (l levelLogger) Fields() LogFields {
	return l.logger.Fields()
}

func (l levelLogger) WithFields(fields ...LogField) Logger {
	return levelLogger{
		logger: l.logger.WithFields(fields...),
		level:  l.level,
	}
}
<|endoftext|>


<commit_before>package flotilla

import (
	"log"
	"os"
	"time"
)

var (
	green  = string([]byte{27, 91, 57, 55, 59, 52, 50, 109})
	white  = string([]byte{27, 91, 57, 48, 59, 52, 55, 109})
	yellow = string([]byte{27, 91, 57, 55, 59, 52, 51, 109})
	red    = string([]byte{27, 91, 57, 55, 59, 52, 49, 109})
	reset  = string([]byte{27, 91, 48, 109})
)

func Logger() HandlerFunc {
	stdlogger := log.New(os.Stdout, "", 0)

	return func(c *Ctx) {
		// Start timer
		start := time.Now()

		// Process request
		c.Next()

		req := c.Request

		// save the IP of the requester
		requester := req.Header.Get("X-Real-IP")

		// if the requester-header is empty, check the forwarded-header
		if len(requester) == 0 {
			requester = req.Header.Get("X-Forwarded-For")
		}

		// if the requester is still empty, use the hard-coded address from the socket
		if len(requester) == 0 {
			requester = req.RemoteAddr
		}

		var color string
		code := c.rw.Status()
		switch {
		case code >= 200 && code <= 299:
			color = green
		case code >= 300 && code <= 399:
			color = white
		case code >= 400 && code <= 499:
			color = yellow
		default:
			color = red
		}
		end := time.Now()
		latency := end.Sub(start)
		stdlogger.Printf("[FLOTILLA] %v |%s %3d %s| %12v | %s %4s %s\n%s",
			end.Format("2006/01/02 - 15:04:05"),
			color,
			code,
			reset,
			latency,
			requester,
			req.Method,
			req.URL.Path,
			c.Errors.String(),
		)
	}
}
<commit_msg>incorporate downstream logger changes<commit_after>package flotilla

import (
	"log"
	"os"
	"time"
)

var (
	green   = string([]byte{27, 91, 57, 55, 59, 52, 50, 109})
	white   = string([]byte{27, 91, 57, 48, 59, 52, 55, 109})
	yellow  = string([]byte{27, 91, 57, 55, 59, 52, 51, 109})
	red     = string([]byte{27, 91, 57, 55, 59, 52, 49, 109})
	blue    = string([]byte{27, 91, 57, 55, 59, 52, 52, 109})
	magenta = string([]byte{27, 91, 57, 55, 59, 52, 53, 109})
	cyan    = string([]byte{27, 91, 57, 55, 59, 52, 54, 109})
	reset   = string([]byte{27, 91, 48, 109})
)

func Logger() HandlerFunc {
	stdlogger := log.New(os.Stdout, "", 0)

	return func(c *Ctx) {
		// Start timer
		start := time.Now()

		// Process request
		c.Next()

		req := c.Request

		// save the IP of the requester
		requester := req.Header.Get("X-Real-IP")

		// if the requester-header is empty, check the forwarded-header
		if len(requester) == 0 {
			requester = req.Header.Get("X-Forwarded-For")
		}

		// if the requester is still empty, use the hard-coded address from the socket
		if len(requester) == 0 {
			requester = req.RemoteAddr
		}

		var color string
		code := c.rw.Status()
		switch {
		case code >= 200 && code <= 299:
			color = green
		case code >= 300 && code <= 399:
			color = white
		case code >= 400 && code <= 499:
			color = yellow
		default:
			color = red
		}
		var methodColor string
		method := c.Request.Method
		switch {
		case method == "GET":
			methodColor = blue
		case method == "POST":
			methodColor = cyan
		case method == "PUT":
			methodColor = yellow
		case method == "DELETE":
			methodColor = red
		case method == "PATCH":
			methodColor = green
		case method == "HEAD":
			methodColor = magenta
		case method == "OPTIONS":
			methodColor = white
		}
		end := time.Now()
		latency := end.Sub(start)
		stdlogger.Printf("[FLOTILLA] %v |%s %3d %s| %12v | %s |%s  %s %-7s %s\n%s",
			end.Format("2006/01/02 - 15:04:05"),
			color, code, reset,
			latency,
			requester,
			methodColor, reset, method,
			c.Request.URL.Path,
			c.Errors.String(),
		)
	}
}
<|endoftext|>


<commit_before>// Copyright 2013 Martini Authors
// Copyright 2014 Unknwon
//
// Licensed under the Apache License, Version 2.0 (the "License"): you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.

package macaron

import (
	"fmt"
	"log"
	"net/http"
	"runtime"
	"time"
)

var isWindows bool

func init() {
	isWindows = runtime.GOOS == "windows"
}

// Logger returns a middleware handler that logs the request as it goes in and the response as it goes out.
func Logger() Handler {
	return func(ctx *Context, log *log.Logger) {
		start := time.Now()

		log.Printf("Started %s %s for %s", ctx.Req.Method, ctx.Req.URL.Path, ctx.RemoteAddr())

		rw := ctx.Resp.(ResponseWriter)
		ctx.Next()

		content := fmt.Sprintf("Completed %s %v %s in %v", ctx.Req.URL.Path, rw.Status(), http.StatusText(rw.Status()), time.Since(start))
		if !isWindows {
			switch rw.Status() {
			case 200, 201, 202:
				content = fmt.Sprintf("\033[1;32m%s\033[0m", content)
			case 301, 302:
				content = fmt.Sprintf("\033[1;37m%s\033[0m", content)
			case 304:
				content = fmt.Sprintf("\033[1;33m%s\033[0m", content)
			case 401, 403:
				content = fmt.Sprintf("\033[4;31m%s\033[0m", content)
			case 404:
				content = fmt.Sprintf("\033[1;31m%s\033[0m", content)
			case 500:
				content = fmt.Sprintf("\033[1;36m%s\033[0m", content)
			}
		}
		log.Println(content)
	}
}
<commit_msg>log the entire "RequestURI", not only "URL.Path"<commit_after>// Copyright 2013 Martini Authors
// Copyright 2014 Unknwon
//
// Licensed under the Apache License, Version 2.0 (the "License"): you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.

package macaron

import (
	"fmt"
	"log"
	"net/http"
	"runtime"
	"time"
)

var isWindows bool

func init() {
	isWindows = runtime.GOOS == "windows"
}

// Logger returns a middleware handler that logs the request as it goes in and the response as it goes out.
func Logger() Handler {
	return func(ctx *Context, log *log.Logger) {
		start := time.Now()

		log.Printf("Started %s %s for %s", ctx.Req.Method, ctx.Req.URL.Path, ctx.RemoteAddr())

		rw := ctx.Resp.(ResponseWriter)
		ctx.Next()

		content := fmt.Sprintf("Completed %s %v %s in %v",  ctx.Req.RequestURI, rw.Status(), http.StatusText(rw.Status()), time.Since(start))
		if !isWindows {
			switch rw.Status() {
			case 200, 201, 202:
				content = fmt.Sprintf("\033[1;32m%s\033[0m", content)
			case 301, 302:
				content = fmt.Sprintf("\033[1;37m%s\033[0m", content)
			case 304:
				content = fmt.Sprintf("\033[1;33m%s\033[0m", content)
			case 401, 403:
				content = fmt.Sprintf("\033[4;31m%s\033[0m", content)
			case 404:
				content = fmt.Sprintf("\033[1;31m%s\033[0m", content)
			case 500:
				content = fmt.Sprintf("\033[1;36m%s\033[0m", content)
			}
		}
		log.Println(content)
	}
}
<|endoftext|>


<commit_before>package boil

import (
	"database/sql"
	"fmt"
	"reflect"
	"strings"
	"sync"

	"github.com/pkg/errors"
	"github.com/vattle/sqlboiler/strmangle"
)

var (
	bindAccepts = []reflect.Kind{reflect.Ptr, reflect.Slice, reflect.Ptr, reflect.Struct}

	mut         sync.RWMutex
	bindingMaps = make(map[string][]uint64)
	structMaps  = make(map[string]map[string]uint64)
)

// Identifies what kind of object we're binding to
type bindKind int

const (
	kindStruct bindKind = iota
	kindSliceStruct
	kindPtrSliceStruct
)

const (
	loadMethodPrefix       = "Load"
	relationshipStructName = "R"
	loaderStructName       = "L"
	sentinel               = uint64(255)
)

// BindP executes the query and inserts the
// result into the passed in object pointer.
// It panics on error. See boil.Bind() documentation.
func (q *Query) BindP(obj interface{}) {
	if err := q.Bind(obj); err != nil {
		panic(WrapErr(err))
	}
}

// Bind executes the query and inserts the
// result into the passed in object pointer
//
// Bind rules:
//   - Struct tags control bind, in the form of: `boil:"name,bind"`
//   - If "name" is omitted the sql column names that come back are TitleCased
//     and matched against the field name.
//   - If the "name" part of the struct tag is specified, the given name will
//     be used instead of the struct field name for binding.
//   - If the "name" of the struct tag is "-", this field will not be bound to.
//   - If the ",bind" option is specified on a struct field and that field
//     is a struct itself, it will be recursed into to look for fields for binding.
//
// Example Query:
//
//   type JoinStruct struct {
//     // User1 can have it's struct fields bound to since it specifies
//     // ,bind in the struct tag, it will look specifically for
//     // fields that are prefixed with "user." returning from the query.
//     // For example "user.id" column name will bind to User1.ID
//     User1      *models.User `boil:"user,bind"`
//     // User2 will follow the same rules as noted above except it will use
//     // "friend." as the prefix it's looking for.
//     User2      *models.User `boil:"friend,bind"`
//     // RandomData will not be recursed into to look for fields to
//     // bind and will not be bound to because of the - for the name.
//     RandomData myStruct     `boil:"-"`
//     // Date will not be recursed into to look for fields to bind because
//     // it does not specify ,bind in the struct tag. But it can be bound to
//     // as it does not specify a - for the name.
//     Date       time.Time
//   }
//
//   models.Users(qm.InnerJoin("users as friend on users.friend_id = friend.id")).Bind(&joinStruct)
//
// For custom objects that want to use eager loading, please see the
// loadRelationships function.
func Bind(rows *sql.Rows, obj interface{}) error {
	structType, sliceType, singular, err := bindChecks(obj)
	if err != nil {
		return err
	}

	return bind(rows, obj, structType, sliceType, singular)
}

// Bind executes the query and inserts the
// result into the passed in object pointer
//
// See documentation for boil.Bind()
func (q *Query) Bind(obj interface{}) error {
	structType, sliceType, bkind, err := bindChecks(obj)
	if err != nil {
		return err
	}

	rows, err := ExecQueryAll(q)
	if err != nil {
		return errors.Wrap(err, "bind failed to execute query")
	}
	defer rows.Close()
	if res := bind(rows, obj, structType, sliceType, bkind); res != nil {
		return res
	}

	if len(q.load) == 0 {
		return nil
	}

	state := loadRelationshipState{
		exec:   q.executor,
		loaded: map[string]struct{}{},
	}
	for _, toLoad := range q.load {
		state.toLoad = strings.Split(toLoad, ".")
		if err = state.loadRelationships(0, obj, bkind); err != nil {
			return err
		}
	}
	return nil
}

// bindChecks resolves information about the bind target, and errors if it's not an object
// we can bind to.
func bindChecks(obj interface{}) (structType reflect.Type, sliceType reflect.Type, bkind bindKind, err error) {
	typ := reflect.TypeOf(obj)
	kind := typ.Kind()

	setErr := func() {
		err = errors.Errorf("obj type should be *Type, *[]Type, or *[]*Type but was %q", reflect.TypeOf(obj).String())
	}

	for i := 0; ; i++ {
		switch i {
		case 0:
			if kind != reflect.Ptr {
				setErr()
				return
			}
		case 1:
			switch kind {
			case reflect.Struct:
				structType = typ
				bkind = kindStruct
				return
			case reflect.Slice:
				sliceType = typ
			default:
				setErr()
				return
			}
		case 2:
			switch kind {
			case reflect.Struct:
				structType = typ
				bkind = kindSliceStruct
				return
			case reflect.Ptr:
			default:
				setErr()
				return
			}
		case 3:
			if kind != reflect.Struct {
				setErr()
				return
			}
			structType = typ
			bkind = kindPtrSliceStruct
			return
		}

		typ = typ.Elem()
		kind = typ.Kind()
	}
}

func bind(rows *sql.Rows, obj interface{}, structType, sliceType reflect.Type, bkind bindKind) error {
	cols, err := rows.Columns()
	if err != nil {
		return errors.Wrap(err, "bind failed to get column names")
	}

	var ptrSlice reflect.Value
	switch bkind {
	case kindSliceStruct, kindPtrSliceStruct:
		ptrSlice = reflect.Indirect(reflect.ValueOf(obj))
	}

	var strMapping map[string]uint64
	var sok bool
	var mapping []uint64
	var ok bool

	typStr := structType.String()

	mapKey := makeCacheKey(typStr, cols)
	mut.RLock()
	mapping, ok = bindingMaps[mapKey]
	if !ok {
		if strMapping, sok = structMaps[typStr]; !sok {
			strMapping = MakeStructMapping(structType)
		}
	}
	mut.RUnlock()

	if !ok {
		mapping, err = BindMapping(structType, strMapping, cols)
		if err != nil {
			return err
		}

		mut.Lock()
		if !sok {
			structMaps[typStr] = strMapping
		}
		bindingMaps[mapKey] = mapping
		mut.Unlock()
	}

	var oneStruct reflect.Value
	if bkind == kindSliceStruct {
		oneStruct = reflect.Indirect(reflect.New(structType))
	}

	foundOne := false
	for rows.Next() {
		foundOne = true
		var newStruct reflect.Value
		var pointers []interface{}

		switch bkind {
		case kindStruct:
			pointers = PtrsFromMapping(reflect.Indirect(reflect.ValueOf(obj)), mapping)
		case kindSliceStruct:
			pointers = PtrsFromMapping(oneStruct, mapping)
		case kindPtrSliceStruct:
			newStruct = reflect.New(structType)
			pointers = PtrsFromMapping(reflect.Indirect(newStruct), mapping)
		}
		if err != nil {
			return err
		}

		if err := rows.Scan(pointers...); err != nil {
			return errors.Wrap(err, "failed to bind pointers to obj")
		}

		switch bkind {
		case kindSliceStruct:
			ptrSlice.Set(reflect.Append(ptrSlice, oneStruct))
		case kindPtrSliceStruct:
			ptrSlice.Set(reflect.Append(ptrSlice, newStruct))
		}
	}

	if bkind == kindStruct && !foundOne {
		return sql.ErrNoRows
	}

	return nil
}

// BindMapping creates a mapping that helps look up the pointer for the
// column given.
func BindMapping(typ reflect.Type, mapping map[string]uint64, cols []string) ([]uint64, error) {
	ptrs := make([]uint64, len(cols))

ColLoop:
	for i, c := range cols {
		name := strmangle.TitleCaseIdentifier(c)
		ptrMap, ok := mapping[name]
		if ok {
			ptrs[i] = ptrMap
			continue
		}

		suffix := "." + name
		for maybeMatch, mapping := range mapping {
			if strings.HasSuffix(maybeMatch, suffix) {
				ptrs[i] = mapping
				continue ColLoop
			}
		}

		return nil, errors.Errorf("could not find struct field name in mapping: %s", name)
	}

	return ptrs, nil
}

// PtrsFromMapping expects to be passed an addressable struct and a mapping
// of where to find things. It pulls the pointers out referred to by the mapping.
func PtrsFromMapping(val reflect.Value, mapping []uint64) []interface{} {
	ptrs := make([]interface{}, len(mapping))
	for i, m := range mapping {
		ptrs[i] = ptrFromMapping(val, m, true).Interface()
	}
	return ptrs
}

// ValuesFromMapping expects to be passed an addressable struct and a mapping
// of where to find things. It pulls the pointers out referred to by the mapping.
func ValuesFromMapping(val reflect.Value, mapping []uint64) []interface{} {
	ptrs := make([]interface{}, len(mapping))
	for i, m := range mapping {
		ptrs[i] = ptrFromMapping(val, m, false).Interface()
	}
	return ptrs
}

// ptrFromMapping expects to be passed an addressable struct that it's looking
// for things on.
func ptrFromMapping(val reflect.Value, mapping uint64, addressOf bool) reflect.Value {
	for i := 0; i < 8; i++ {
		v := (mapping >> uint(i*8)) & sentinel

		if v == sentinel {
			if val.Kind() != reflect.Ptr {
				return val.Addr()
			}
			return val
		}

		val = val.Field(int(v))
		if val.Kind() == reflect.Ptr {
			val = reflect.Indirect(val)
		}
	}

	panic("could not find pointer from mapping")
}

// MakeStructMapping creates a map of the struct to be able to quickly look
// up its pointers and values by name.
func MakeStructMapping(typ reflect.Type) map[string]uint64 {
	fieldMaps := make(map[string]uint64)
	makeStructMappingHelper(typ, "", 0, 0, fieldMaps)
	return fieldMaps
}

func makeStructMappingHelper(typ reflect.Type, prefix string, current uint64, depth uint, fieldMaps map[string]uint64) {
	if typ.Kind() == reflect.Ptr {
		typ = typ.Elem()
	}

	n := typ.NumField()
	for i := 0; i < n; i++ {
		f := typ.Field(i)

		tag, recurse := getBoilTag(f)
		if len(tag) == 0 {
			tag = f.Name
		} else if tag[0] == '-' {
			continue
		}

		if len(prefix) != 0 {
			tag = fmt.Sprintf("%s.%s", prefix, tag)
		}

		if recurse {
			makeStructMappingHelper(f.Type, tag, current|uint64(i)<<depth, depth+8, fieldMaps)
			continue
		}

		fieldMaps[tag] = current | (sentinel << (depth + 8)) | (uint64(i) << depth)
	}
}

func getBoilTag(field reflect.StructField) (name string, recurse bool) {
	tag := field.Tag.Get("boil")
	name = field.Name

	if len(tag) == 0 {
		return name, false
	}

	ind := strings.IndexByte(tag, ',')
	if ind == -1 {
		return strmangle.TitleCase(tag), false
	} else if ind == 0 {
		return name, true
	}

	nameFragment := tag[:ind]
	return strmangle.TitleCase(nameFragment), true
}

func makeCacheKey(typ string, cols []string) string {
	buf := strmangle.GetBuffer()
	buf.WriteString(typ)
	for _, s := range cols {
		buf.WriteString(s)
	}
	mapKey := buf.String()
	strmangle.PutBuffer(buf)

	return mapKey
}

// GetStructValues returns the values (as interface) of the matching columns in obj
func GetStructValues(obj interface{}, columns ...string) []interface{} {
	ret := make([]interface{}, len(columns))
	val := reflect.Indirect(reflect.ValueOf(obj))

	for i, c := range columns {
		fieldName := strmangle.TitleCase(c)
		field := val.FieldByName(fieldName)
		if !field.IsValid() {
			panic(fmt.Sprintf("unable to find field with name: %s\n%#v", fieldName, obj))
		}
		ret[i] = field.Interface()
	}

	return ret
}

// GetSliceValues returns the values (as interface) of the matching columns in obj.
func GetSliceValues(slice []interface{}, columns ...string) []interface{} {
	ret := make([]interface{}, len(slice)*len(columns))

	for i, obj := range slice {
		val := reflect.Indirect(reflect.ValueOf(obj))
		for j, c := range columns {
			fieldName := strmangle.TitleCase(c)
			field := val.FieldByName(fieldName)
			if !field.IsValid() {
				panic(fmt.Sprintf("unable to find field with name: %s\n%#v", fieldName, obj))
			}
			ret[i*len(columns)+j] = field.Interface()
		}
	}

	return ret
}

// GetStructPointers returns a slice of pointers to the matching columns in obj
func GetStructPointers(obj interface{}, columns ...string) []interface{} {
	val := reflect.ValueOf(obj).Elem()

	var ln int
	var getField func(reflect.Value, int) reflect.Value

	if len(columns) == 0 {
		ln = val.NumField()
		getField = func(v reflect.Value, i int) reflect.Value {
			return v.Field(i)
		}
	} else {
		ln = len(columns)
		getField = func(v reflect.Value, i int) reflect.Value {
			return v.FieldByName(strmangle.TitleCase(columns[i]))
		}
	}

	ret := make([]interface{}, ln)
	for i := 0; i < ln; i++ {
		field := getField(val, i)

		if !field.IsValid() {
			// Although this breaks the abstraction of getField above - we know that v.Field(i) can't actually
			// produce an Invalid value, so we make a hopefully safe assumption here.
			panic(fmt.Sprintf("Could not find field on struct %T for field %s", obj, strmangle.TitleCase(columns[i])))
		}

		ret[i] = field.Addr().Interface()
	}

	return ret
}
<commit_msg>ValuesFromMapping now gets values<commit_after>package boil

import (
	"database/sql"
	"fmt"
	"reflect"
	"strings"
	"sync"

	"github.com/pkg/errors"
	"github.com/vattle/sqlboiler/strmangle"
)

var (
	bindAccepts = []reflect.Kind{reflect.Ptr, reflect.Slice, reflect.Ptr, reflect.Struct}

	mut         sync.RWMutex
	bindingMaps = make(map[string][]uint64)
	structMaps  = make(map[string]map[string]uint64)
)

// Identifies what kind of object we're binding to
type bindKind int

const (
	kindStruct bindKind = iota
	kindSliceStruct
	kindPtrSliceStruct
)

const (
	loadMethodPrefix       = "Load"
	relationshipStructName = "R"
	loaderStructName       = "L"
	sentinel               = uint64(255)
)

// BindP executes the query and inserts the
// result into the passed in object pointer.
// It panics on error. See boil.Bind() documentation.
func (q *Query) BindP(obj interface{}) {
	if err := q.Bind(obj); err != nil {
		panic(WrapErr(err))
	}
}

// Bind executes the query and inserts the
// result into the passed in object pointer
//
// Bind rules:
//   - Struct tags control bind, in the form of: `boil:"name,bind"`
//   - If "name" is omitted the sql column names that come back are TitleCased
//     and matched against the field name.
//   - If the "name" part of the struct tag is specified, the given name will
//     be used instead of the struct field name for binding.
//   - If the "name" of the struct tag is "-", this field will not be bound to.
//   - If the ",bind" option is specified on a struct field and that field
//     is a struct itself, it will be recursed into to look for fields for binding.
//
// Example Query:
//
//   type JoinStruct struct {
//     // User1 can have it's struct fields bound to since it specifies
//     // ,bind in the struct tag, it will look specifically for
//     // fields that are prefixed with "user." returning from the query.
//     // For example "user.id" column name will bind to User1.ID
//     User1      *models.User `boil:"user,bind"`
//     // User2 will follow the same rules as noted above except it will use
//     // "friend." as the prefix it's looking for.
//     User2      *models.User `boil:"friend,bind"`
//     // RandomData will not be recursed into to look for fields to
//     // bind and will not be bound to because of the - for the name.
//     RandomData myStruct     `boil:"-"`
//     // Date will not be recursed into to look for fields to bind because
//     // it does not specify ,bind in the struct tag. But it can be bound to
//     // as it does not specify a - for the name.
//     Date       time.Time
//   }
//
//   models.Users(qm.InnerJoin("users as friend on users.friend_id = friend.id")).Bind(&joinStruct)
//
// For custom objects that want to use eager loading, please see the
// loadRelationships function.
func Bind(rows *sql.Rows, obj interface{}) error {
	structType, sliceType, singular, err := bindChecks(obj)
	if err != nil {
		return err
	}

	return bind(rows, obj, structType, sliceType, singular)
}

// Bind executes the query and inserts the
// result into the passed in object pointer
//
// See documentation for boil.Bind()
func (q *Query) Bind(obj interface{}) error {
	structType, sliceType, bkind, err := bindChecks(obj)
	if err != nil {
		return err
	}

	rows, err := ExecQueryAll(q)
	if err != nil {
		return errors.Wrap(err, "bind failed to execute query")
	}
	defer rows.Close()
	if res := bind(rows, obj, structType, sliceType, bkind); res != nil {
		return res
	}

	if len(q.load) == 0 {
		return nil
	}

	state := loadRelationshipState{
		exec:   q.executor,
		loaded: map[string]struct{}{},
	}
	for _, toLoad := range q.load {
		state.toLoad = strings.Split(toLoad, ".")
		if err = state.loadRelationships(0, obj, bkind); err != nil {
			return err
		}
	}
	return nil
}

// bindChecks resolves information about the bind target, and errors if it's not an object
// we can bind to.
func bindChecks(obj interface{}) (structType reflect.Type, sliceType reflect.Type, bkind bindKind, err error) {
	typ := reflect.TypeOf(obj)
	kind := typ.Kind()

	setErr := func() {
		err = errors.Errorf("obj type should be *Type, *[]Type, or *[]*Type but was %q", reflect.TypeOf(obj).String())
	}

	for i := 0; ; i++ {
		switch i {
		case 0:
			if kind != reflect.Ptr {
				setErr()
				return
			}
		case 1:
			switch kind {
			case reflect.Struct:
				structType = typ
				bkind = kindStruct
				return
			case reflect.Slice:
				sliceType = typ
			default:
				setErr()
				return
			}
		case 2:
			switch kind {
			case reflect.Struct:
				structType = typ
				bkind = kindSliceStruct
				return
			case reflect.Ptr:
			default:
				setErr()
				return
			}
		case 3:
			if kind != reflect.Struct {
				setErr()
				return
			}
			structType = typ
			bkind = kindPtrSliceStruct
			return
		}

		typ = typ.Elem()
		kind = typ.Kind()
	}
}

func bind(rows *sql.Rows, obj interface{}, structType, sliceType reflect.Type, bkind bindKind) error {
	cols, err := rows.Columns()
	if err != nil {
		return errors.Wrap(err, "bind failed to get column names")
	}

	var ptrSlice reflect.Value
	switch bkind {
	case kindSliceStruct, kindPtrSliceStruct:
		ptrSlice = reflect.Indirect(reflect.ValueOf(obj))
	}

	var strMapping map[string]uint64
	var sok bool
	var mapping []uint64
	var ok bool

	typStr := structType.String()

	mapKey := makeCacheKey(typStr, cols)
	mut.RLock()
	mapping, ok = bindingMaps[mapKey]
	if !ok {
		if strMapping, sok = structMaps[typStr]; !sok {
			strMapping = MakeStructMapping(structType)
		}
	}
	mut.RUnlock()

	if !ok {
		mapping, err = BindMapping(structType, strMapping, cols)
		if err != nil {
			return err
		}

		mut.Lock()
		if !sok {
			structMaps[typStr] = strMapping
		}
		bindingMaps[mapKey] = mapping
		mut.Unlock()
	}

	var oneStruct reflect.Value
	if bkind == kindSliceStruct {
		oneStruct = reflect.Indirect(reflect.New(structType))
	}

	foundOne := false
	for rows.Next() {
		foundOne = true
		var newStruct reflect.Value
		var pointers []interface{}

		switch bkind {
		case kindStruct:
			pointers = PtrsFromMapping(reflect.Indirect(reflect.ValueOf(obj)), mapping)
		case kindSliceStruct:
			pointers = PtrsFromMapping(oneStruct, mapping)
		case kindPtrSliceStruct:
			newStruct = reflect.New(structType)
			pointers = PtrsFromMapping(reflect.Indirect(newStruct), mapping)
		}
		if err != nil {
			return err
		}

		if err := rows.Scan(pointers...); err != nil {
			return errors.Wrap(err, "failed to bind pointers to obj")
		}

		switch bkind {
		case kindSliceStruct:
			ptrSlice.Set(reflect.Append(ptrSlice, oneStruct))
		case kindPtrSliceStruct:
			ptrSlice.Set(reflect.Append(ptrSlice, newStruct))
		}
	}

	if bkind == kindStruct && !foundOne {
		return sql.ErrNoRows
	}

	return nil
}

// BindMapping creates a mapping that helps look up the pointer for the
// column given.
func BindMapping(typ reflect.Type, mapping map[string]uint64, cols []string) ([]uint64, error) {
	ptrs := make([]uint64, len(cols))

ColLoop:
	for i, c := range cols {
		name := strmangle.TitleCaseIdentifier(c)
		ptrMap, ok := mapping[name]
		if ok {
			ptrs[i] = ptrMap
			continue
		}

		suffix := "." + name
		for maybeMatch, mapping := range mapping {
			if strings.HasSuffix(maybeMatch, suffix) {
				ptrs[i] = mapping
				continue ColLoop
			}
		}

		return nil, errors.Errorf("could not find struct field name in mapping: %s", name)
	}

	return ptrs, nil
}

// PtrsFromMapping expects to be passed an addressable struct and a mapping
// of where to find things. It pulls the pointers out referred to by the mapping.
func PtrsFromMapping(val reflect.Value, mapping []uint64) []interface{} {
	ptrs := make([]interface{}, len(mapping))
	for i, m := range mapping {
		ptrs[i] = ptrFromMapping(val, m, true).Interface()
	}
	return ptrs
}

// ValuesFromMapping expects to be passed an addressable struct and a mapping
// of where to find things. It pulls the pointers out referred to by the mapping.
func ValuesFromMapping(val reflect.Value, mapping []uint64) []interface{} {
	ptrs := make([]interface{}, len(mapping))
	for i, m := range mapping {
		ptrs[i] = ptrFromMapping(val, m, false).Interface()
	}
	return ptrs
}

// ptrFromMapping expects to be passed an addressable struct that it's looking
// for things on.
func ptrFromMapping(val reflect.Value, mapping uint64, addressOf bool) reflect.Value {
	for i := 0; i < 8; i++ {
		v := (mapping >> uint(i*8)) & sentinel

		if v == sentinel {
			if addressOf && val.Kind() != reflect.Ptr {
				return val.Addr()
			} else if !addressOf && val.Kind() == reflect.Ptr {
				return reflect.Indirect(val)
			}
			return val
		}

		val = val.Field(int(v))
		if val.Kind() == reflect.Ptr {
			val = reflect.Indirect(val)
		}
	}

	panic("could not find pointer from mapping")
}

// MakeStructMapping creates a map of the struct to be able to quickly look
// up its pointers and values by name.
func MakeStructMapping(typ reflect.Type) map[string]uint64 {
	fieldMaps := make(map[string]uint64)
	makeStructMappingHelper(typ, "", 0, 0, fieldMaps)
	return fieldMaps
}

func makeStructMappingHelper(typ reflect.Type, prefix string, current uint64, depth uint, fieldMaps map[string]uint64) {
	if typ.Kind() == reflect.Ptr {
		typ = typ.Elem()
	}

	n := typ.NumField()
	for i := 0; i < n; i++ {
		f := typ.Field(i)

		tag, recurse := getBoilTag(f)
		if len(tag) == 0 {
			tag = f.Name
		} else if tag[0] == '-' {
			continue
		}

		if len(prefix) != 0 {
			tag = fmt.Sprintf("%s.%s", prefix, tag)
		}

		if recurse {
			makeStructMappingHelper(f.Type, tag, current|uint64(i)<<depth, depth+8, fieldMaps)
			continue
		}

		fieldMaps[tag] = current | (sentinel << (depth + 8)) | (uint64(i) << depth)
	}
}

func getBoilTag(field reflect.StructField) (name string, recurse bool) {
	tag := field.Tag.Get("boil")
	name = field.Name

	if len(tag) == 0 {
		return name, false
	}

	ind := strings.IndexByte(tag, ',')
	if ind == -1 {
		return strmangle.TitleCase(tag), false
	} else if ind == 0 {
		return name, true
	}

	nameFragment := tag[:ind]
	return strmangle.TitleCase(nameFragment), true
}

func makeCacheKey(typ string, cols []string) string {
	buf := strmangle.GetBuffer()
	buf.WriteString(typ)
	for _, s := range cols {
		buf.WriteString(s)
	}
	mapKey := buf.String()
	strmangle.PutBuffer(buf)

	return mapKey
}

// GetStructValues returns the values (as interface) of the matching columns in obj
func GetStructValues(obj interface{}, columns ...string) []interface{} {
	ret := make([]interface{}, len(columns))
	val := reflect.Indirect(reflect.ValueOf(obj))

	for i, c := range columns {
		fieldName := strmangle.TitleCase(c)
		field := val.FieldByName(fieldName)
		if !field.IsValid() {
			panic(fmt.Sprintf("unable to find field with name: %s\n%#v", fieldName, obj))
		}
		ret[i] = field.Interface()
	}

	return ret
}

// GetSliceValues returns the values (as interface) of the matching columns in obj.
func GetSliceValues(slice []interface{}, columns ...string) []interface{} {
	ret := make([]interface{}, len(slice)*len(columns))

	for i, obj := range slice {
		val := reflect.Indirect(reflect.ValueOf(obj))
		for j, c := range columns {
			fieldName := strmangle.TitleCase(c)
			field := val.FieldByName(fieldName)
			if !field.IsValid() {
				panic(fmt.Sprintf("unable to find field with name: %s\n%#v", fieldName, obj))
			}
			ret[i*len(columns)+j] = field.Interface()
		}
	}

	return ret
}

// GetStructPointers returns a slice of pointers to the matching columns in obj
func GetStructPointers(obj interface{}, columns ...string) []interface{} {
	val := reflect.ValueOf(obj).Elem()

	var ln int
	var getField func(reflect.Value, int) reflect.Value

	if len(columns) == 0 {
		ln = val.NumField()
		getField = func(v reflect.Value, i int) reflect.Value {
			return v.Field(i)
		}
	} else {
		ln = len(columns)
		getField = func(v reflect.Value, i int) reflect.Value {
			return v.FieldByName(strmangle.TitleCase(columns[i]))
		}
	}

	ret := make([]interface{}, ln)
	for i := 0; i < ln; i++ {
		field := getField(val, i)

		if !field.IsValid() {
			// Although this breaks the abstraction of getField above - we know that v.Field(i) can't actually
			// produce an Invalid value, so we make a hopefully safe assumption here.
			panic(fmt.Sprintf("Could not find field on struct %T for field %s", obj, strmangle.TitleCase(columns[i])))
		}

		ret[i] = field.Addr().Interface()
	}

	return ret
}
<|endoftext|>