<commit_before>// Copyright (C) 2015 <NAME>.
//
// Licensed onder the MIT license that can be found in the LICENSE file.

// Package logger provides multiple ways to log information of different levels
// of importance. No default logger is created, but Get is provided to get any
// logger at any location. See the provided examples, both in the documentation
// and the _examples directory (for complete examples).
package logger

import (
	"errors"
	"fmt"
	"runtime"
	"time"
)

const (
	defaultStackSize = 8192
	defaultLogsSize  = 1024
)

// MsgWriter takes a msg and writes it to the output.
type MsgWriter interface {
	Write(Msg) error
	Close() error
}

// Collection of all created loggers by name, used by the Get function.
var loggers = map[string]*Logger{}

// The Logger is an logging object which logs to a MsgWriter. Each logging
// operation makes a single call to the Writer's Write method, but not
// necessarily at the same time a Log operation is called. A Logger can be
// used simultaneously from multiple goroutines, it guarantees to serialize
// access to the MsgWriter.
//
// There are six different log levels (from higher to lower): Fatal, Error,
// Warn, Info, Thumb, Debug and Trace.
//
// Note: Log operations (Fatal, Error etc.) don't instally write to the
// MsgWriter, before closing the application call Logger.Close to ensure that
// all log operations are written to the MsgWriter.
type Logger struct {
	Name string

	// Wether or not to write Debug and Trace logs.
	ShowDebug bool

	// All errors, which can be read after Logger.Close is called, NOT THREAT
	// SAFE.
	Errors []error

	mw     MsgWriter
	logs   chan Msg
	closed chan struct{}
}

// Fatal logs a recovered error which could have killed the application.
func (l *Logger) Fatal(tags Tags, recv interface{}) {
	// Capture the stack trace.
	buf := make([]byte, defaultStackSize)
	n := runtime.Stack(buf, false)
	buf = buf[:n]

	// Try to make some sense of the recoverd value.
	var item string
	switch v := recv.(type) {
	case string:
		item = v
	case error:
		item = v.Error()
	default:
		item = fmt.Sprintf("%v", recv)
	}

	item += "\n" + string(buf)
	l.logs <- Msg{Fatal, item, tags, time.Now()}
}

// Error logs a recoverable error.
func (l *Logger) Error(tags Tags, err error) {
	l.logs <- Msg{Error, err.Error(), tags, time.Now()}
}

// Warn logs a warning.
func (l *Logger) Warn(tags Tags, format string, v ...interface{}) {
	l.logs <- Msg{Warn, fmt.Sprintf(format, v...), tags, time.Now()}
}

// Info logs an informational message.
func (l *Logger) Info(tags Tags, format string, v ...interface{}) {
	l.logs <- Msg{Info, fmt.Sprintf(format, v...), tags, time.Now()}
}

// Debug logs the lowest level of information, only usefull when debugging
// the application. Only shows when Logger.ShowDebug is set to true, which
// defaults to false.
func (l *Logger) Debug(tags Tags, format string, v ...interface{}) {
	if l.ShowDebug {
		l.logs <- Msg{Debug, fmt.Sprintf(format, v...), tags, time.Now()}
	}
}

// Thumbstone indicates a function is still used in production. When developing
// software it's possible to introduce dead code with updates and new features.<commit_msg>Cleanup Logger.Fatal<commit_after>// Copyright (C) 2015 <NAME>.
//
// Licensed onder the MIT license that can be found in the LICENSE file.

// Package logger provides multiple ways to log information of different levels
// of importance. No default logger is created, but Get is provided to get any
// logger at any location. See the provided examples, both in the documentation
// and the _examples directory (for complete examples).
package logger

import (
	"errors"
	"fmt"
	"runtime"
	"time"
)

const (
	defaultStackSize = 8192
	defaultLogsSize  = 1024
)

// MsgWriter takes a msg and writes it to the output.
type MsgWriter interface {
	Write(Msg) error
	Close() error
}

// Collection of all created loggers by name, used by the Get function.
var loggers = map[string]*Logger{}

// The Logger is an logging object which logs to a MsgWriter. Each logging
// operation makes a single call to the Writer's Write method, but not
// necessarily at the same time a Log operation is called. A Logger can be
// used simultaneously from multiple goroutines, it guarantees to serialize
// access to the MsgWriter.
//
// There are six different log levels (from higher to lower): Fatal, Error,
// Warn, Info, Thumb, Debug and Trace.
//
// Note: Log operations (Fatal, Error etc.) don't instally write to the
// MsgWriter, before closing the application call Logger.Close to ensure that
// all log operations are written to the MsgWriter.
type Logger struct {
	Name string

	// Wether or not to write Debug and Trace logs.
	ShowDebug bool

	// All errors, which can be read after Logger.Close is called, NOT THREAT
	// SAFE.
	Errors []error

	mw     MsgWriter
	logs   chan Msg
	closed chan struct{}
}

// Fatal logs a recovered error which could have killed the application.
func (l *Logger) Fatal(tags Tags, recv interface{}) {
	// Capture the stack trace.
	stackTrace := make([]byte, defaultStackSize)
	n := runtime.Stack(stackTrace, false)
	stackTrace = stackTrace[:n]

	// Try to make some sense of the recoverd value.
	var msg string
	switch v := recv.(type) {
	case string:
		msg = v
	case error:
		msg = v.Error()
	default:
		msg = fmt.Sprintf("%v", recv)
	}

	msg += "\n" + string(stackTrace)
	l.logs <- Msg{Fatal, msg, tags, time.Now()}
}

// Error logs a recoverable error.
func (l *Logger) Error(tags Tags, err error) {
	l.logs <- Msg{Error, err.Error(), tags, time.Now()}
}

// Warn logs a warning.
func (l *Logger) Warn(tags Tags, format string, v ...interface{}) {
	l.logs <- Msg{Warn, fmt.Sprintf(format, v...), tags, time.Now()}
}

// Info logs an informational message.
func (l *Logger) Info(tags Tags, format string, v ...interface{}) {
	l.logs <- Msg{Info, fmt.Sprintf(format, v...), tags, time.Now()}
}

// Debug logs the lowest level of information, only usefull when debugging
// the application. Only shows when Logger.ShowDebug is set to true, which
// defaults to false.
func (l *Logger) Debug(tags Tags, format string, v ...interface{}) {
	if l.ShowDebug {
		l.logs <- Msg{Debug, fmt.Sprintf(format, v...), tags, time.Now()}
	}
}

// Thumbstone indicates a function is still used in production. When developing
// software it's possible to introduce dead code with updates and new features.
{'fraction_non_alphanumeric': 0.111024115252114, 'fraction_numerical': 0.003758221108675227, 'mean_word_length': 3.488404778636683, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 5, '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': '279260', 'n_tokens_mistral': 1964, 'n_tokens_neox': 1900, 'n_words': 860}