|
|
@ -1,15 +1,19 @@ |
|
|
|
package logkit |
|
|
|
package logkit |
|
|
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
import ( |
|
|
|
|
|
|
|
"flag" |
|
|
|
"fmt" |
|
|
|
"fmt" |
|
|
|
"io" |
|
|
|
"io" |
|
|
|
"path" |
|
|
|
"path" |
|
|
|
"runtime" |
|
|
|
"runtime" |
|
|
|
|
|
|
|
"strconv" |
|
|
|
|
|
|
|
"strings" |
|
|
|
"time" |
|
|
|
"time" |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
var ( |
|
|
|
var ( |
|
|
|
inited bool |
|
|
|
inited bool |
|
|
|
|
|
|
|
auto bool |
|
|
|
logWriter io.Writer |
|
|
|
logWriter io.Writer |
|
|
|
logLevel = LevelInfo |
|
|
|
logLevel = LevelInfo |
|
|
|
logLevelName string |
|
|
|
logLevelName string |
|
|
@ -42,8 +46,35 @@ const ( |
|
|
|
LevelFatal |
|
|
|
LevelFatal |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (l *Level) String() string { |
|
|
|
|
|
|
|
return levelToNames[*l] |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Get is part of the flag.Value interface.
|
|
|
|
|
|
|
|
func (l *Level) Get() interface{} { |
|
|
|
|
|
|
|
return *l |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (l *Level) Set(value string) error { |
|
|
|
|
|
|
|
for i, name := range levelToNames { |
|
|
|
|
|
|
|
if strings.ToUpper(value) == name { |
|
|
|
|
|
|
|
*l = i |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if *l == Default { |
|
|
|
|
|
|
|
v, err := strconv.Atoi(value) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
*l = Level(v) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if *l == Default { |
|
|
|
|
|
|
|
*l = LevelDebug |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
type Channel byte |
|
|
|
type Channel byte |
|
|
|
type Caller byte |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const ( |
|
|
|
const ( |
|
|
|
FIlE Channel = iota |
|
|
|
FIlE Channel = iota |
|
|
@ -51,6 +82,29 @@ const ( |
|
|
|
KAFKA |
|
|
|
KAFKA |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (c *Channel) String() string { |
|
|
|
|
|
|
|
switch *c { |
|
|
|
|
|
|
|
case FIlE: |
|
|
|
|
|
|
|
return "file" |
|
|
|
|
|
|
|
case SYSLOG: |
|
|
|
|
|
|
|
return "syslog" |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return "file" |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
func (c *Channel) Set(value string) error { |
|
|
|
|
|
|
|
switch value { |
|
|
|
|
|
|
|
case "file": |
|
|
|
|
|
|
|
*c = FIlE |
|
|
|
|
|
|
|
case "syslog": |
|
|
|
|
|
|
|
*c = SYSLOG |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
*c = FIlE |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type Caller byte |
|
|
|
|
|
|
|
|
|
|
|
const ( |
|
|
|
const ( |
|
|
|
_ Caller = iota |
|
|
|
_ Caller = iota |
|
|
|
NONE |
|
|
|
NONE |
|
|
@ -59,6 +113,33 @@ const ( |
|
|
|
BasePath |
|
|
|
BasePath |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (c *Caller) String() string { |
|
|
|
|
|
|
|
switch *c { |
|
|
|
|
|
|
|
case NONE: |
|
|
|
|
|
|
|
return "none" |
|
|
|
|
|
|
|
case FullPATHFunc: |
|
|
|
|
|
|
|
return "full" |
|
|
|
|
|
|
|
case BasePathFunc: |
|
|
|
|
|
|
|
return "file_func" |
|
|
|
|
|
|
|
case BasePath: |
|
|
|
|
|
|
|
return "file" |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return "file" |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
func (c *Caller) Set(value string) error { |
|
|
|
|
|
|
|
switch value { |
|
|
|
|
|
|
|
case "file": |
|
|
|
|
|
|
|
*c = BasePath |
|
|
|
|
|
|
|
case "file_func": |
|
|
|
|
|
|
|
*c = BasePathFunc |
|
|
|
|
|
|
|
case "full": |
|
|
|
|
|
|
|
*c = FullPATHFunc |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
*c = BasePathFunc |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
type Writer interface { |
|
|
|
type Writer interface { |
|
|
|
//Write 写日志
|
|
|
|
//Write 写日志
|
|
|
|
Write(msg []byte) (int, error) |
|
|
|
Write(msg []byte) (int, error) |
|
|
@ -66,10 +147,31 @@ type Writer interface { |
|
|
|
Close() error |
|
|
|
Close() error |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func GetWriter() io.Closer { |
|
|
|
|
|
|
|
return logWriter.(io.Closer) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func Exit() { |
|
|
|
func Exit() { |
|
|
|
logWriter.(io.Closer).Close() |
|
|
|
logWriter.(io.Closer).Close() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func init() { |
|
|
|
|
|
|
|
flag.Var(&logLevel, "log.level", "log level, default `INFO`, it can be `DEBUG, INFO, WARN, ERROR, FATAL`") |
|
|
|
|
|
|
|
flag.Var(&withCaller, "log.withcaller", "call context, by default filename and func name, it can be `file, file_func, full`") |
|
|
|
|
|
|
|
flag.Var(&channel, "log.channel", "write to , it can be `file syslog`") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
flag.BoolVar(&alsoStdout, "log.alsostdout", false, "log out to stand error as well, default `false`") |
|
|
|
|
|
|
|
flag.StringVar(&logName, "log.name", "", "log name, by default log will out to `/data/logs/{name}.log`") |
|
|
|
|
|
|
|
flag.BoolVar(&auto, "log.autoinit", true, "log will be init automatic") |
|
|
|
|
|
|
|
if auto { |
|
|
|
|
|
|
|
println("----", logLevel) |
|
|
|
|
|
|
|
_, err := Init(channel, logName, logLevel, alsoStdout, withCaller) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
println("logkit init fail, ", err.Error()) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func Init(_channel Channel, name string, level Level, _alsoStdout bool, _withCaller Caller) (writer io.Writer, err error) { |
|
|
|
func Init(_channel Channel, name string, level Level, _alsoStdout bool, _withCaller Caller) (writer io.Writer, err error) { |
|
|
|
if inited { |
|
|
|
if inited { |
|
|
|
return nil, fmt.Errorf("logkit has been inited") |
|
|
|
return nil, fmt.Errorf("logkit has been inited") |
|
|
|