2014-02-12 23:54:09 +04:00
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package log
import (
2014-05-26 04:11:25 +04:00
"os"
2014-07-26 08:24:27 +04:00
"runtime"
"strings"
2019-09-17 12:39:37 +03:00
"sync"
2014-02-12 23:54:09 +04:00
)
2019-09-17 12:39:37 +03:00
type loggerMap struct {
sync . Map
}
func ( m * loggerMap ) Load ( k string ) ( * Logger , bool ) {
v , ok := m . Map . Load ( k )
if ! ok {
return nil , false
}
l , ok := v . ( * Logger )
return l , ok
}
func ( m * loggerMap ) Store ( k string , v * Logger ) {
m . Map . Store ( k , v )
}
func ( m * loggerMap ) Delete ( k string ) {
m . Map . Delete ( k )
}
2014-03-25 15:47:04 +04:00
var (
2019-04-02 10:48:31 +03:00
// DEFAULT is the name of the default logger
DEFAULT = "default"
// NamedLoggers map of named loggers
2019-09-17 12:39:37 +03:00
NamedLoggers loggerMap
2019-06-01 18:00:21 +03:00
prefix string
2014-03-25 15:47:04 +04:00
)
2014-02-12 23:54:09 +04:00
2019-04-02 10:48:31 +03:00
// NewLogger create a logger for the default logger
func NewLogger ( bufLen int64 , name , provider , config string ) * Logger {
err := NewNamedLogger ( DEFAULT , bufLen , name , provider , config )
if err != nil {
CriticalWithSkip ( 1 , "Unable to create default logger: %v" , err )
panic ( err )
2014-05-11 22:37:12 +04:00
}
2019-09-17 12:39:37 +03:00
l , _ := NamedLoggers . Load ( DEFAULT )
return l
2019-04-02 10:48:31 +03:00
}
// NewNamedLogger creates a new named logger for a given configuration
func NewNamedLogger ( name string , bufLen int64 , subname , provider , config string ) error {
2019-09-17 12:39:37 +03:00
logger , ok := NamedLoggers . Load ( name )
2019-04-02 10:48:31 +03:00
if ! ok {
logger = newLogger ( name , bufLen )
2019-09-17 12:39:37 +03:00
NamedLoggers . Store ( name , logger )
2014-05-11 22:37:12 +04:00
}
2019-04-02 10:48:31 +03:00
return logger . SetLogger ( subname , provider , config )
}
// DelNamedLogger closes and deletes the named logger
func DelNamedLogger ( name string ) {
2019-09-17 12:39:37 +03:00
l , ok := NamedLoggers . Load ( name )
2019-04-02 10:48:31 +03:00
if ok {
2019-09-17 12:39:37 +03:00
NamedLoggers . Delete ( name )
2019-04-02 10:48:31 +03:00
l . Close ( )
2014-06-20 08:25:23 +04:00
}
2014-02-12 23:54:09 +04:00
}
2019-04-02 10:48:31 +03:00
// DelLogger removes the named sublogger from the default logger
func DelLogger ( name string ) error {
2019-09-17 12:39:37 +03:00
logger , _ := NamedLoggers . Load ( DEFAULT )
2019-04-02 10:48:31 +03:00
found , err := logger . DelLogger ( name )
if ! found {
Trace ( "Log %s not found, no need to delete" , name )
2017-01-17 09:02:35 +03:00
}
2019-04-02 10:48:31 +03:00
return err
}
2017-04-03 05:22:26 +03:00
2019-04-02 10:48:31 +03:00
// GetLogger returns either a named logger or the default logger
func GetLogger ( name string ) * Logger {
2019-09-17 12:39:37 +03:00
logger , ok := NamedLoggers . Load ( name )
2019-04-02 10:48:31 +03:00
if ok {
return logger
}
2019-09-17 12:39:37 +03:00
logger , _ = NamedLoggers . Load ( DEFAULT )
return logger
2017-01-17 09:02:35 +03:00
}
2019-04-02 10:48:31 +03:00
// GetLevel returns the minimum logger level
func GetLevel ( ) Level {
2019-09-17 12:39:37 +03:00
l , _ := NamedLoggers . Load ( DEFAULT )
return l . GetLevel ( )
2019-04-02 10:48:31 +03:00
}
// GetStacktraceLevel returns the minimum logger level
func GetStacktraceLevel ( ) Level {
2019-09-17 12:39:37 +03:00
l , _ := NamedLoggers . Load ( DEFAULT )
return l . GetStacktraceLevel ( )
2014-06-20 09:14:54 +04:00
}
2016-11-26 14:53:29 +03:00
// Trace records trace log
2014-02-19 02:48:02 +04:00
func Trace ( format string , v ... interface { } ) {
2019-04-02 10:48:31 +03:00
Log ( 1 , TRACE , format , v ... )
}
// IsTrace returns true if at least one logger is TRACE
func IsTrace ( ) bool {
return GetLevel ( ) <= TRACE
2014-02-19 02:48:02 +04:00
}
2016-11-26 14:53:29 +03:00
// Debug records debug log
2014-03-23 20:16:17 +04:00
func Debug ( format string , v ... interface { } ) {
2019-04-02 10:48:31 +03:00
Log ( 1 , DEBUG , format , v ... )
2014-03-23 20:16:17 +04:00
}
2019-04-02 10:48:31 +03:00
// IsDebug returns true if at least one logger is DEBUG
func IsDebug ( ) bool {
return GetLevel ( ) <= DEBUG
2014-02-12 23:54:09 +04:00
}
2014-02-19 02:31:16 +04:00
2019-04-02 10:48:31 +03:00
// Info records info log
func Info ( format string , v ... interface { } ) {
Log ( 1 , INFO , format , v ... )
2014-02-19 02:31:16 +04:00
}
2019-04-02 10:48:31 +03:00
// IsInfo returns true if at least one logger is INFO
func IsInfo ( ) bool {
return GetLevel ( ) <= INFO
2014-02-19 02:31:16 +04:00
}
2014-02-19 02:48:02 +04:00
2019-04-02 10:48:31 +03:00
// Warn records warning log
func Warn ( format string , v ... interface { } ) {
Log ( 1 , WARN , format , v ... )
2014-02-19 02:48:02 +04:00
}
2014-05-26 04:11:25 +04:00
2019-04-02 10:48:31 +03:00
// IsWarn returns true if at least one logger is WARN
func IsWarn ( ) bool {
return GetLevel ( ) <= WARN
2014-07-26 08:24:27 +04:00
}
2019-04-02 10:48:31 +03:00
// Error records error log
func Error ( format string , v ... interface { } ) {
Log ( 1 , ERROR , format , v ... )
2014-09-23 01:30:58 +04:00
}
2019-04-02 10:48:31 +03:00
// ErrorWithSkip records error log from "skip" calls back from this function
func ErrorWithSkip ( skip int , format string , v ... interface { } ) {
Log ( skip + 1 , ERROR , format , v ... )
2014-07-26 08:24:27 +04:00
}
2019-04-02 10:48:31 +03:00
// IsError returns true if at least one logger is ERROR
func IsError ( ) bool {
return GetLevel ( ) <= ERROR
2019-02-06 06:06:41 +03:00
}
2019-04-02 10:48:31 +03:00
// Critical records critical log
func Critical ( format string , v ... interface { } ) {
Log ( 1 , CRITICAL , format , v ... )
2019-02-06 06:06:41 +03:00
}
2019-04-02 10:48:31 +03:00
// CriticalWithSkip records critical log from "skip" calls back from this function
func CriticalWithSkip ( skip int , format string , v ... interface { } ) {
Log ( skip + 1 , CRITICAL , format , v ... )
2019-02-06 06:06:41 +03:00
}
2019-04-02 10:48:31 +03:00
// IsCritical returns true if at least one logger is CRITICAL
func IsCritical ( ) bool {
return GetLevel ( ) <= CRITICAL
2019-02-06 06:06:41 +03:00
}
2019-04-02 10:48:31 +03:00
// Fatal records fatal log and exit process
func Fatal ( format string , v ... interface { } ) {
Log ( 1 , FATAL , format , v ... )
Close ( )
os . Exit ( 1 )
2014-07-26 08:24:27 +04:00
}
2019-04-02 10:48:31 +03:00
// FatalWithSkip records fatal log from "skip" calls back from this function
func FatalWithSkip ( skip int , format string , v ... interface { } ) {
Log ( skip + 1 , FATAL , format , v ... )
Close ( )
os . Exit ( 1 )
2014-07-26 08:24:27 +04:00
}
2019-04-02 10:48:31 +03:00
// IsFatal returns true if at least one logger is FATAL
func IsFatal ( ) bool {
return GetLevel ( ) <= FATAL
2014-07-26 08:24:27 +04:00
}
2019-04-02 10:48:31 +03:00
// Close closes all the loggers
func Close ( ) {
2019-09-17 12:39:37 +03:00
l , ok := NamedLoggers . Load ( DEFAULT )
2019-04-02 10:48:31 +03:00
if ! ok {
return
2014-07-26 08:24:27 +04:00
}
2019-09-17 12:39:37 +03:00
NamedLoggers . Delete ( DEFAULT )
2019-04-02 10:48:31 +03:00
l . Close ( )
2014-07-26 08:24:27 +04:00
}
2019-04-02 10:48:31 +03:00
// Log a message with defined skip and at logging level
// A skip of 0 refers to the caller of this command
func Log ( skip int , level Level , format string , v ... interface { } ) {
2019-09-17 12:39:37 +03:00
l , ok := NamedLoggers . Load ( DEFAULT )
2019-04-02 10:48:31 +03:00
if ok {
l . Log ( skip + 1 , level , format , v ... )
2014-07-26 08:24:27 +04:00
}
}
2019-04-02 10:48:31 +03:00
// LoggerAsWriter is a io.Writer shim around the gitea log
type LoggerAsWriter struct {
ourLoggers [ ] * Logger
level Level
2014-07-26 08:24:27 +04:00
}
2019-04-02 10:48:31 +03:00
// NewLoggerAsWriter creates a Writer representation of the logger with setable log level
func NewLoggerAsWriter ( level string , ourLoggers ... * Logger ) * LoggerAsWriter {
if len ( ourLoggers ) == 0 {
2019-09-17 12:39:37 +03:00
l , _ := NamedLoggers . Load ( DEFAULT )
ourLoggers = [ ] * Logger { l }
2014-07-26 08:24:27 +04:00
}
2019-04-02 10:48:31 +03:00
l := & LoggerAsWriter {
ourLoggers : ourLoggers ,
level : FromString ( level ) ,
2014-07-26 08:24:27 +04:00
}
2019-04-02 10:48:31 +03:00
return l
2014-07-26 08:24:27 +04:00
}
2019-04-02 10:48:31 +03:00
// Write implements the io.Writer interface to allow spoofing of macaron
func ( l * LoggerAsWriter ) Write ( p [ ] byte ) ( int , error ) {
for _ , logger := range l . ourLoggers {
// Skip = 3 because this presumes that we have been called by log.Println()
// If the caller has used log.Output or the like this will be wrong
logger . Log ( 3 , l . level , string ( p ) )
2014-07-26 08:24:27 +04:00
}
2019-04-02 10:48:31 +03:00
return len ( p ) , nil
2014-07-26 08:24:27 +04:00
}
2019-04-02 10:48:31 +03:00
// Log takes a given string and logs it at the set log-level
func ( l * LoggerAsWriter ) Log ( msg string ) {
for _ , logger := range l . ourLoggers {
// Set the skip to reference the call just above this
2019-06-12 22:41:28 +03:00
_ = logger . Log ( 1 , l . level , msg )
2019-04-02 10:48:31 +03:00
}
2014-07-26 08:24:27 +04:00
}
2019-04-02 10:48:31 +03:00
func init ( ) {
_ , filename , _ , _ := runtime . Caller ( 0 )
prefix = strings . TrimSuffix ( filename , "modules/log/log.go" )
2014-05-26 04:11:25 +04:00
}