Commit 93ac6680 by stuart nelson Committed by Torkel Ödegaard

update log15 (#9622)

* Update log15 and go-isatty

* Update usage in pkg log
parent 9e697a1f
......@@ -14,7 +14,7 @@ import (
"github.com/go-stack/stack"
"github.com/inconshreveable/log15"
"github.com/inconshreveable/log15/term"
isatty "github.com/mattn/go-isatty"
"github.com/grafana/grafana/pkg/util"
)
......@@ -157,7 +157,7 @@ func getFilters(filterStrArray []string) map[string]log15.Lvl {
func getLogFormat(format string) log15.Format {
switch format {
case "console":
if term.IsTty(os.Stdout.Fd()) {
if isatty.IsTerminal(os.Stdout.Fd()) {
return log15.TerminalFormat()
}
return log15.LogfmtFormat()
......
Contributors to log15:
- Aaron L
- Alan Shreve
- Chris Hines
- Ciaran Downey
- Dmitry Chestnykh
- Evan Shaw
- Péter Szilágyi
- Trevor Gattis
- Vincent Vanackere
Aaron L <aaron@bettercoder.net>
Alan Shreve <alan@inconshreveable.com>
Andy Walker <walkeraj@gmail.com>
Andy Watson <andrewmoorewatson@gmail.com>
Carl Veazey <Carl_Veazey@cable.comcast.com>
Chris Hines <github@cs-guy.com>
Christoph Hack <christoph@tux21b.org>
Ciaran Downey <me@ciarand.me>
Dmitry Chestnykh <dmitry@codingrobots.com>
Evan Shaw <edsrzf@gmail.com>
Gonzalo Serrano <boikot@gmail.com>
Jeremy <jrbudnack@starkandwayne.com>
Jonathan Rudenberg <jonathan@titanous.com>
Kang Seong-Min <kang.seongmin@gmail.com>
Kevin Burke <kev@inburke.com>
Marc Abramowitz <marc@marc-abramowitz.com>
Nathan Baulch <nathan.baulch@gmail.com>
NotZippy <notzippy@gmail.com>
Péter Szilágyi <peterke@gmail.com>
Robert Egorov <robert.egorov@gmail.com>
Robert Starbuck <robstarbuck@gmail.com>
Robert Zaremba <robert.zaremba@scale-it.pl>
Sean Chittenden <sean@chittenden.org>
Spencer Nelson <s@spenczar.com>
Tomasz Grodzki <tg@users.noreply.github.com>
Trevor Gattis <github@trevorgattis.com>
Vincent Vanackere <vincent.vanackere@gmail.com>
Will McGovern <will@brkt.com>
......@@ -73,5 +73,12 @@ srvlog := log.New(log.Ctx{"module": "app/server"})
srvlog.Warn("abnormal conn rate", log.Ctx{"rate": curRate, "low": lowRate, "high": highRate})
```
### Regenerating the CONTRIBUTORS file
```
go get -u github.com/kevinburke/write_mailmap
write_mailmap > CONTRIBUTORS
```
## License
Apache
......@@ -23,7 +23,7 @@ To get started, you'll want to import the library:
Now you're ready to start logging:
func main() {
log.Info("Program starting", "args", os.Args())
log.Info("Program starting", "args", os.Args)
}
......
......@@ -18,6 +18,7 @@ const (
termMsgJust = 40
)
// Format is the interface implemented by StreamHandler formatters.
type Format interface {
Format(r *Record) []byte
}
......@@ -147,7 +148,7 @@ func JsonFormatEx(pretty, lineSeparated bool) Format {
if !ok {
props[errorKey] = fmt.Sprintf("%+v is not a string key", r.Ctx[i])
}
props[k] = formatJsonValue(r.Ctx[i+1])
props[k] = formatJSONValue(r.Ctx[i+1])
}
b, err := jsonMarshal(props)
......@@ -192,7 +193,7 @@ func formatShared(value interface{}) (result interface{}) {
}
}
func formatJsonValue(value interface{}) interface{} {
func formatJSONValue(value interface{}) interface{} {
value = formatShared(value)
switch value.(type) {
case int, int8, int16, int32, int64, float32, float64, uint, uint8, uint16, uint32, uint64, string:
......
......@@ -11,8 +11,8 @@ import (
"github.com/go-stack/stack"
)
// A Logger prints its log records by writing to a Handler.
// The Handler interface defines where and how log records are written.
// Handler interface defines where and how log records are written.
// A logger prints its log records by writing to a Handler.
// Handlers are composable, providing you great flexibility in combining
// them to achieve the logging structure that suits your applications.
type Handler interface {
......@@ -188,7 +188,7 @@ func LvlFilterHandler(maxLvl Lvl, h Handler) Handler {
}, h)
}
// A MultiHandler dispatches any write to each of its handlers.
// MultiHandler dispatches any write to each of its handlers.
// This is useful for writing different types of log information
// to different locations. For example, to log to a file and
// standard error:
......@@ -207,7 +207,7 @@ func MultiHandler(hs ...Handler) Handler {
})
}
// A FailoverHandler writes all log records to the first handler
// FailoverHandler writes all log records to the first handler
// specified, but will failover and write to the second handler if
// the first handler has failed, and so on for all handlers specified.
// For example you might want to log to a network socket, but failover
......@@ -229,11 +229,9 @@ func FailoverHandler(hs ...Handler) Handler {
err = h.Log(r)
if err == nil {
return nil
} else {
r.Ctx = append(r.Ctx, fmt.Sprintf("failover_err_%d", i), err)
}
r.Ctx = append(r.Ctx, fmt.Sprintf("failover_err_%d", i), err)
}
return err
})
}
......@@ -315,13 +313,12 @@ func evaluateLazy(lz Lazy) (interface{}, error) {
results := value.Call([]reflect.Value{})
if len(results) == 1 {
return results[0].Interface(), nil
} else {
values := make([]interface{}, len(results))
for i, v := range results {
values[i] = v.Interface()
}
return values, nil
}
values := make([]interface{}, len(results))
for i, v := range results {
values[i] = v.Interface()
}
return values, nil
}
// DiscardHandler reports success for all writes but does nothing.
......@@ -333,7 +330,7 @@ func DiscardHandler() Handler {
})
}
// The Must object provides the following Handler creation functions
// Must object provides the following Handler creation functions
// which instead of returning an error parameter only return a Handler
// and panic on failure: FileHandler, NetHandler, SyslogHandler, SyslogNetHandler
var Must muster
......
......@@ -12,8 +12,10 @@ const lvlKey = "lvl"
const msgKey = "msg"
const errorKey = "LOG15_ERROR"
// Lvl is a type for predefined log levels.
type Lvl int
// List of predefined log Levels
const (
LvlCrit Lvl = iota
LvlError
......@@ -40,7 +42,7 @@ func (l Lvl) String() string {
}
}
// Returns the appropriate Lvl from a string name.
// LvlFromString returns the appropriate Lvl from a string name.
// Useful for parsing command line args and configuration files.
func LvlFromString(lvlString string) (Lvl, error) {
switch lvlString {
......@@ -69,6 +71,7 @@ type Record struct {
KeyNames RecordKeyNames
}
// RecordKeyNames are the predefined names of the log props used by the Logger interface.
type RecordKeyNames struct {
Time string
Msg string
......
......@@ -3,10 +3,11 @@ package log15
import (
"os"
"github.com/inconshreveable/log15/term"
"github.com/mattn/go-colorable"
isatty "github.com/mattn/go-isatty"
)
// Predefined handlers
var (
root *logger
StdoutHandler = StreamHandler(os.Stdout, LogfmtFormat())
......@@ -14,11 +15,11 @@ var (
)
func init() {
if term.IsTty(os.Stdout.Fd()) {
if isatty.IsTerminal(os.Stdout.Fd()) {
StdoutHandler = StreamHandler(colorable.NewColorableStdout(), TerminalFormat())
}
if term.IsTty(os.Stderr.Fd()) {
if isatty.IsTerminal(os.Stderr.Fd()) {
StderrHandler = StreamHandler(colorable.NewColorableStderr(), TerminalFormat())
}
......
# go-isatty
[![Godoc Reference](https://godoc.org/github.com/mattn/go-isatty?status.svg)](http://godoc.org/github.com/mattn/go-isatty)
[![Build Status](https://travis-ci.org/mattn/go-isatty.svg?branch=master)](https://travis-ci.org/mattn/go-isatty)
[![Coverage Status](https://coveralls.io/repos/github/mattn/go-isatty/badge.svg?branch=master)](https://coveralls.io/github/mattn/go-isatty?branch=master)
[![Go Report Card](https://goreportcard.com/badge/mattn/go-isatty)](https://goreportcard.com/report/mattn/go-isatty)
isatty for golang
## Usage
......@@ -16,6 +21,8 @@ import (
func main() {
if isatty.IsTerminal(os.Stdout.Fd()) {
fmt.Println("Is Terminal")
} else if isatty.IsCygwinTerminal(os.Stdout.Fd()) {
fmt.Println("Is Cygwin/MSYS2 Terminal")
} else {
fmt.Println("Is Not Terminal")
}
......@@ -28,10 +35,16 @@ func main() {
$ go get github.com/mattn/go-isatty
```
# License
## License
MIT
# Author
## Author
Yasuhiro Matsumoto (a.k.a mattn)
## Thanks
* k-takata: base idea for IsCygwinTerminal
https://github.com/k-takata/go-iscygpty
......@@ -7,3 +7,9 @@ package isatty
func IsTerminal(fd uintptr) bool {
return false
}
// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2
// terminal. This is also always false on this environment.
func IsCygwinTerminal(fd uintptr) bool {
return false
}
// +build darwin freebsd openbsd netbsd
// +build darwin freebsd openbsd netbsd dragonfly
// +build !appengine
package isatty
......
// +build linux
// +build !appengine
// +build !appengine,!ppc64,!ppc64le
package isatty
......
// +build linux
// +build ppc64 ppc64le
package isatty
import (
"unsafe"
syscall "golang.org/x/sys/unix"
)
const ioctlReadTermios = syscall.TCGETS
// IsTerminal return true if the file descriptor is terminal.
func IsTerminal(fd uintptr) bool {
var termios syscall.Termios
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
return err == 0
}
// +build !windows
// +build !appengine
package isatty
// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2
// terminal. This is also always false on this environment.
func IsCygwinTerminal(fd uintptr) bool {
return false
}
......@@ -4,12 +4,30 @@
package isatty
import (
"strings"
"syscall"
"unicode/utf16"
"unsafe"
)
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
var procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
const (
fileNameInfo uintptr = 2
fileTypePipe = 3
)
var (
kernel32 = syscall.NewLazyDLL("kernel32.dll")
procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
procGetFileInformationByHandleEx = kernel32.NewProc("GetFileInformationByHandleEx")
procGetFileType = kernel32.NewProc("GetFileType")
)
func init() {
// Check if GetFileInformationByHandleEx is available.
if procGetFileInformationByHandleEx.Find() != nil {
procGetFileInformationByHandleEx = nil
}
}
// IsTerminal return true if the file descriptor is terminal.
func IsTerminal(fd uintptr) bool {
......@@ -17,3 +35,60 @@ func IsTerminal(fd uintptr) bool {
r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0)
return r != 0 && e == 0
}
// Check pipe name is used for cygwin/msys2 pty.
// Cygwin/MSYS2 PTY has a name like:
// \{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master
func isCygwinPipeName(name string) bool {
token := strings.Split(name, "-")
if len(token) < 5 {
return false
}
if token[0] != `\msys` && token[0] != `\cygwin` {
return false
}
if token[1] == "" {
return false
}
if !strings.HasPrefix(token[2], "pty") {
return false
}
if token[3] != `from` && token[3] != `to` {
return false
}
if token[4] != "master" {
return false
}
return true
}
// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2
// terminal.
func IsCygwinTerminal(fd uintptr) bool {
if procGetFileInformationByHandleEx == nil {
return false
}
// Cygwin/msys's pty is a pipe.
ft, _, e := syscall.Syscall(procGetFileType.Addr(), 1, fd, 0, 0)
if ft != fileTypePipe || e != 0 {
return false
}
var buf [2 + syscall.MAX_PATH]uint16
r, _, e := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(),
4, fd, fileNameInfo, uintptr(unsafe.Pointer(&buf)),
uintptr(len(buf)*2), 0, 0)
if r == 0 || e != 0 {
return false
}
l := *(*uint32)(unsafe.Pointer(&buf))
return isCygwinPipeName(string(utf16.Decode(buf[2 : 2+l/2])))
}
......@@ -443,10 +443,10 @@
"revisionTime": "2016-12-15T22:53:35Z"
},
{
"checksumSHA1": "mrmfY0cVu7jvgoIuTRaR8yVVh/M=",
"checksumSHA1": "W7WyVSrJNaQNQt2R9O4DxrK58cs=",
"path": "github.com/inconshreveable/log15",
"revision": "39bacc234bf1afd0b68573e95b45871f67ba2cd4",
"revisionTime": "2017-02-16T22:56:31Z"
"revision": "0decfc6c20d9ca0ad143b0e89dcaa20f810b4fb3",
"revisionTime": "2016-11-12T20:41:34Z"
},
{
"checksumSHA1": "oVIIInZXKkcRozJfuH2vWJsAS7s=",
......@@ -468,26 +468,30 @@
},
{
"checksumSHA1": "jaCQF1par6Jl8g+V2Cgp0n/0wSc=",
"origin": "github.com/grafana/grafana/vendor/github.com/lib/pq/hstore",
"path": "github.com/lib/pq/hstore",
"revision": "23da1db4f16d9658a86ae9b717c245fc078f10f1",
"revisionTime": "2017-09-18T17:50:43Z"
},
{
"checksumSHA1": "mJHrY33tDs2MRhHt+XunkRF/5ek=",
"origin": "github.com/grafana/grafana/vendor/github.com/lib/pq/listen_example",
"path": "github.com/lib/pq/listen_example",
"revision": "23da1db4f16d9658a86ae9b717c245fc078f10f1",
"revisionTime": "2017-09-18T17:50:43Z"
},
{
"checksumSHA1": "AU3fA8Sm33Vj9PBoRPSeYfxLRuE=",
"origin": "github.com/grafana/grafana/vendor/github.com/lib/pq/oid",
"path": "github.com/lib/pq/oid",
"revision": "23da1db4f16d9658a86ae9b717c245fc078f10f1",
"revisionTime": "2017-09-18T17:50:43Z"
},
{
"checksumSHA1": "y/A5iuvwjytQE2CqVuphQRXR2nI=",
"origin": "github.com/grafana/grafana/vendor/github.com/mattn/go-isatty",
"path": "github.com/mattn/go-isatty",
"revision": "a5cdd64afdee435007ee3e9f6ed4684af949d568",
"revisionTime": "2017-09-25T05:49:04Z"
},
{
"checksumSHA1": "bKMZjd2wPw13VwoE7mBeSv5djFA=",
"path": "github.com/matttproud/golang_protobuf_extensions/pbutil",
"revision": "c12348ce28de40eed0136aa2b644d0ee0650e56c",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment