<commit_before>// Package termlog provides facilities for logging to a terminal geared towards
// interactive use.
package termlog

import (
	"io"
	"os"
	"sync"
	"time"

	"github.com/fatih/color"
	"golang.org/x/crypto/ssh/terminal"
	"golang.org/x/net/context"
)

const defaultTimeFmt = "15:04:05"
const indent = "  "

// Palette defines the colour of output
type Palette struct {
	Timestamp *color.Color
	Say       *color.Color
	Notice    *color.Color
	Warn      *color.Color
	Shout     *color.Color
}

// DefaultPalette is a sensbile default palette, with the following foreground
// colours:
//
// 	Say: Terminal default
// 	Notice: Blue
// 	Warn: Yellow
// 	Shout: Red
// 	Timestamp: Cyan
var DefaultPalette = Palette{
	Say:       color.New(),
	Notice:    color.New(color.FgBlue),
	Warn:      color.New(color.FgYellow),
	Shout:     color.New(color.FgRed),
	Timestamp: color.New(color.FgCyan),
}

// Logger logs things
type Logger interface {
	Say(format string, args ...interface{})
	Notice(format string, args ...interface{})
	Warn(format string, args ...interface{})
	Shout(format string, args ...interface{})

	SayAs(name string, format string, args ...interface{})
	NoticeAs(name string, format string, args ...interface{})
	WarnAs(name string, format string, args ...interface{})
	ShoutAs(name string, format string, args ...interface{})

	Done()
	Quiet()
	Group() Logger
}

type line struct {
	name   string
	color  *color.Color
	format string
	args   []interface{}
}

// Log is the top-level log structure
type Log struct {
	mu      sync.Mutex
	Palette *Palette
	TimeFmt string
	enabled map[string]bool
	quiet   bool
}

// NewLog creates a new Log instance and initialises it with a set of defaults.
func NewLog() *Log {
	l := &Log{
		Palette: &DefaultPalette,
		enabled: make(map[string]bool),
		TimeFmt: defaultTimeFmt,
	}
	l.enabled[""] = true
	if !terminal.IsTerminal(int(os.Stdout.Fd())) {
		l.Color(false)
	}
	return l
}

// Color sets the state of colour output - true to turn on, false to disable.
func (*Log) Color(state bool) {
	color.NoColor = !state
}

// Enable logging for a specified name
func (l *Log) Enable(name string) {
	l.enabled[name] = true
}

// Quiet disables all output
func (l *Log) Quiet() {
	l.quiet = true
}

func (l *Log) output(quiet bool, lines ...*line) {
	if quiet {
		return
	}
	l.mu.Lock()
	defer l.mu.Unlock()
	if len(lines) == 0 {
		return
	}
	first := true
	for _, line := range lines {
		if _, ok := l.enabled[line.name]; !ok {
			continue
		}
		var format string
		if first {
			l.Palette.Timestamp.Printf(
				"%s", time.Now().Format(l.TimeFmt),
			)
			l.Palette.Say.Print(": ")
			first = false
			format = line.format + "\n"
		} else {
			format = indent + line.format + "\n"
		}
		line.color.Printf(format, line.args...)
	}
}

// Say logs a line
func (l *Log) Say(format string, args ...interface{}) {
	l.output(l.quiet, &line{"", l.Palette.Say, format, args})
}

// Notice logs a line with the Notice color
func (l *Log) Notice(format string, args ...interface{}) {
	l.output(l.quiet, &line{"", l.Palette.Notice, format, args})
}

// Warn logs a line with the Warn color
func (l *Log) Warn(format string, args ...interface{}) {
	l.output(l.quiet, &line{"", l.Palette.Warn, format, args})
}
<commit_msg>Timestamp format controls entire preamble, including colons<commit_after>// Package termlog provides facilities for logging to a terminal geared towards
// interactive use.
package termlog

import (
	"io"
	"os"
	"sync"
	"time"

	"github.com/fatih/color"
	"golang.org/x/crypto/ssh/terminal"
	"golang.org/x/net/context"
)

const defaultTimeFmt = "15:04:05: "
const indent = "  "

// Palette defines the colour of output
type Palette struct {
	Timestamp *color.Color
	Say       *color.Color
	Notice    *color.Color
	Warn      *color.Color
	Shout     *color.Color
}

// DefaultPalette is a sensbile default palette, with the following foreground
// colours:
//
// 	Say: Terminal default
// 	Notice: Blue
// 	Warn: Yellow
// 	Shout: Red
// 	Timestamp: Cyan
var DefaultPalette = Palette{
	Say:       color.New(),
	Notice:    color.New(color.FgBlue),
	Warn:      color.New(color.FgYellow),
	Shout:     color.New(color.FgRed),
	Timestamp: color.New(color.FgCyan),
}

// Logger logs things
type Logger interface {
	Say(format string, args ...interface{})
	Notice(format string, args ...interface{})
	Warn(format string, args ...interface{})
	Shout(format string, args ...interface{})

	SayAs(name string, format string, args ...interface{})
	NoticeAs(name string, format string, args ...interface{})
	WarnAs(name string, format string, args ...interface{})
	ShoutAs(name string, format string, args ...interface{})

	Done()
	Quiet()
	Group() Logger
}

type line struct {
	name   string
	color  *color.Color
	format string
	args   []interface{}
}

// Log is the top-level log structure
type Log struct {
	mu      sync.Mutex
	Palette *Palette
	TimeFmt string
	enabled map[string]bool
	quiet   bool
}

// NewLog creates a new Log instance and initialises it with a set of defaults.
func NewLog() *Log {
	l := &Log{
		Palette: &DefaultPalette,
		enabled: make(map[string]bool),
		TimeFmt: defaultTimeFmt,
	}
	l.enabled[""] = true
	if !terminal.IsTerminal(int(os.Stdout.Fd())) {
		l.Color(false)
	}
	return l
}

// Color sets the state of colour output - true to turn on, false to disable.
func (*Log) Color(state bool) {
	color.NoColor = !state
}

// Enable logging for a specified name
func (l *Log) Enable(name string) {
	l.enabled[name] = true
}

// Quiet disables all output
func (l *Log) Quiet() {
	l.quiet = true
}

func (l *Log) output(quiet bool, lines ...*line) {
	if quiet {
		return
	}
	l.mu.Lock()
	defer l.mu.Unlock()
	if len(lines) == 0 {
		return
	}
	first := true
	for _, line := range lines {
		if _, ok := l.enabled[line.name]; !ok {
			continue
		}
		var format string
		if first {
			l.Palette.Timestamp.Printf(
				"%s", time.Now().Format(l.TimeFmt),
			)
			first = false
			format = line.format + "\n"
		} else {
			format = indent + line.format + "\n"
		}
		line.color.Printf(format, line.args...)
	}
}

// Say logs a line
func (l *Log) Say(format string, args ...interface{}) {
	l.output(l.quiet, &line{"", l.Palette.Say, format, args})
}

// Notice logs a line with the Notice color
func (l *Log) Notice(format string, args ...interface{}) {
	l.output(l.quiet, &line{"", l.Palette.Notice, format, args})
}

// Warn logs a line with the Warn color
func (l *Log) Warn(format string, args ...interface{}) {
	l.output(l.quiet, &line{"", l.Palette.Warn, format, args})
}

{'fraction_non_alphanumeric': 0.14589386756384767, 'fraction_numerical': 0.0021410001529285822, 'mean_word_length': 3.2801047120418847, 'pattern_counts': {'":': 1, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '164193', 'n_tokens_mistral': 2400, 'n_tokens_neox': 2285, 'n_words': 691}