Skip to content

Commit

Permalink
text_formatter: detect tty based on fd
Browse files Browse the repository at this point in the history
  • Loading branch information
sirupsen committed Feb 7, 2017
1 parent 61e43dc commit 1726e17
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 18 deletions.
2 changes: 1 addition & 1 deletion terminal_appengine.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
package logrus

// IsTerminal returns true if stderr's file descriptor is a terminal.
func IsTerminal() bool {
func IsTerminal(f io.Writer) bool {
return true
}
14 changes: 10 additions & 4 deletions terminal_notwindows.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,20 @@
package logrus

import (
"io"
"os"
"syscall"
"unsafe"
)

// IsTerminal returns true if stderr's file descriptor is a terminal.
func IsTerminal() bool {
fd := syscall.Stderr
func IsTerminal(f io.Writer) bool {
var termios Termios
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
return err == 0
switch v := f.(type) {
case *os.File:
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(v.Fd()), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
return err == 0
default:
return false
}
}
12 changes: 9 additions & 3 deletions terminal_solaris.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@ import (
)

// IsTerminal returns true if the given file descriptor is a terminal.
func IsTerminal() bool {
_, err := unix.IoctlGetTermios(int(os.Stdout.Fd()), unix.TCGETA)
return err == nil
func IsTerminal(f io.Writer) bool {
var termios Termios
switch v := f.(type) {
case *os.File:
_, err := unix.IoctlGetTermios(int(f.Fd()), unix.TCGETA)
return err == nil
default:
return false
}
}
14 changes: 9 additions & 5 deletions terminal_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,13 @@ var (
)

// IsTerminal returns true if stderr's file descriptor is a terminal.
func IsTerminal() bool {
fd := syscall.Stderr
var st uint32
r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
return r != 0 && e == 0
func IsTerminal(f io.Writer) bool {
switch v := f.(type) {
case *os.File:
var st uint32
r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(v.Fd()), uintptr(unsafe.Pointer(&st)), 0)
return r != 0 && e == 0
default:
return false
}
}
15 changes: 10 additions & 5 deletions text_formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package logrus
import (
"bytes"
"fmt"
"runtime"
"sort"
"strings"
"time"
Expand All @@ -20,12 +19,10 @@ const (

var (
baseTimestamp time.Time
isTerminal bool
)

func init() {
baseTimestamp = time.Now()
isTerminal = IsTerminal()
}

type TextFormatter struct {
Expand All @@ -50,6 +47,10 @@ type TextFormatter struct {
// that log extremely frequently and don't use the JSON formatter this may not
// be desired.
DisableSorting bool

// Whether the logger's out is to a terminal
isTerminal bool
terminalDetermined bool
}

func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
Expand All @@ -70,8 +71,12 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {

prefixFieldClashes(entry.Data)

isColorTerminal := isTerminal && (runtime.GOOS != "windows")
isColored := (f.ForceColors || isColorTerminal) && !f.DisableColors
if !f.terminalDetermined {
f.isTerminal = IsTerminal(entry.Logger.Out)
f.terminalDetermined = true
}

isColored := (f.ForceColors || f.isTerminal) && !f.DisableColors

timestampFormat := f.TimestampFormat
if timestampFormat == "" {
Expand Down

0 comments on commit 1726e17

Please sign in to comment.