new starlog
This commit is contained in:
parent
6c5ebcf61f
commit
4f2eb0c238
504
starlog.go
504
starlog.go
@ -2,280 +2,294 @@ package starlog
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/fatih/color"
|
|
||||||
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Path string
|
const (
|
||||||
var LogPar *os.File
|
BLUE = color.FgBlue
|
||||||
var CSpace bool = false
|
BLACK = color.FgBlack
|
||||||
|
CYAN = color.FgCyan
|
||||||
|
GREEN = color.FgGreen
|
||||||
|
MAGENTA = color.FgMagenta
|
||||||
|
RED = color.FgRed
|
||||||
|
WHITE = color.FgWhite
|
||||||
|
YELLOW = color.FgYellow
|
||||||
|
GREY = color.FgHiYellow
|
||||||
|
BOLD = color.Bold
|
||||||
|
)
|
||||||
|
|
||||||
func CreateLog(logpath, prefix string) string {
|
const (
|
||||||
logname := strconv.FormatInt(time.Now().Unix(), 10)
|
LvDebug = iota
|
||||||
logpath, _ = filepath.Abs(logpath)
|
LvInfo
|
||||||
_, exs := os.Stat(logpath)
|
LvNotice
|
||||||
if exs != nil && os.IsNotExist(exs) {
|
LvWarning
|
||||||
os.MkdirAll(logpath, 0755)
|
LvError
|
||||||
}
|
LvCritical
|
||||||
logname = logpath + `/` + prefix + logname + ".log"
|
LvPanic
|
||||||
LogPar, _ = os.Create(logname)
|
LvFatal
|
||||||
strpath, _ := filepath.Abs(logname)
|
)
|
||||||
return strpath
|
|
||||||
}
|
|
||||||
|
|
||||||
func WriteError(err error, other string) {
|
var (
|
||||||
now := time.Now().Format("2006-01-02 15:04:05")
|
levels = map[int]string{
|
||||||
strlog := now + ": " + other + ":" + err.Error() + "\n"
|
LvDebug: "DEBUG",
|
||||||
LogPar.Write([]byte(strlog))
|
LvInfo: "INFO",
|
||||||
|
LvNotice: "NOTICE",
|
||||||
|
LvWarning: "WARNING",
|
||||||
|
LvError: "ERROR",
|
||||||
|
LvCritical: "CRITICAL",
|
||||||
|
LvPanic: "PANIC",
|
||||||
|
LvFatal: "FATAL",
|
||||||
}
|
}
|
||||||
|
Colors = map[int][]color.Attribute{
|
||||||
func WriteLog(strs string) {
|
LvDebug: []color.Attribute{WHITE},
|
||||||
now := time.Now().Format("2006-01-02 15:04:05")
|
LvInfo: []color.Attribute{GREEN},
|
||||||
strlog := now + ": " + strs + "\n"
|
LvNotice: []color.Attribute{BLUE},
|
||||||
LogPar.Write([]byte(strlog))
|
LvWarning: []color.Attribute{YELLOW},
|
||||||
|
LvError: []color.Attribute{MAGENTA},
|
||||||
|
LvCritical: []color.Attribute{RED, BOLD},
|
||||||
|
LvPanic: []color.Attribute{RED, BOLD},
|
||||||
|
LvFatal: []color.Attribute{RED},
|
||||||
}
|
}
|
||||||
|
LogLevel int = 0
|
||||||
|
ShowLine, ShowLevel, DoWrite, switching bool = true, true, true, false
|
||||||
|
loghandle *os.File = nil
|
||||||
|
)
|
||||||
|
|
||||||
func PrintError(sakura ...interface{}) {
|
func write(logs string) {
|
||||||
var mycolor, bold string
|
for switching {
|
||||||
lens := len(sakura)
|
time.Sleep(time.Millisecond * 100)
|
||||||
if lens < 2 {
|
}
|
||||||
|
if loghandle == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if lens >= 3 {
|
loghandle.WriteString(logs)
|
||||||
mycolor, _ = sakura[2].(string)
|
|
||||||
if lens == 4 {
|
|
||||||
bold, _ = sakura[3].(string)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
err, _ := sakura[0].(error)
|
func output(level int, showline, showlv, dowrite bool, strlog string) {
|
||||||
other, _ := sakura[1].(string)
|
var logs string
|
||||||
now := time.Now().Format("2006-01-02 15:04:05")
|
if level < LogLevel {
|
||||||
strlog := now + ": " + other + ":" + err.Error()
|
|
||||||
switch strings.ToLower(mycolor) {
|
|
||||||
case "blue":
|
|
||||||
color.Set(color.FgBlue)
|
|
||||||
case "black":
|
|
||||||
color.Set(color.FgBlack)
|
|
||||||
case "cyan":
|
|
||||||
color.Set(color.FgCyan)
|
|
||||||
case "green":
|
|
||||||
color.Set(color.FgGreen)
|
|
||||||
case "magenta":
|
|
||||||
color.Set(color.FgMagenta)
|
|
||||||
case "red":
|
|
||||||
color.Set(color.FgRed)
|
|
||||||
case "white":
|
|
||||||
color.Set(color.FgWhite)
|
|
||||||
case "yellow":
|
|
||||||
color.Set(color.FgYellow)
|
|
||||||
case "grey":
|
|
||||||
color.Set(color.FgHiYellow)
|
|
||||||
default:
|
|
||||||
color.Set(color.Reset)
|
|
||||||
}
|
|
||||||
for _, v := range []byte(bold) {
|
|
||||||
switch string([]byte{v}) {
|
|
||||||
case "b":
|
|
||||||
color.Set(color.Bold)
|
|
||||||
case "l":
|
|
||||||
color.Set(color.BlinkRapid)
|
|
||||||
case "u":
|
|
||||||
color.Set(color.Underline)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if CSpace {
|
|
||||||
strlog += "\n"
|
|
||||||
}
|
|
||||||
fmt.Println(strlog)
|
|
||||||
color.Set(color.Reset)
|
|
||||||
LogPar.Write([]byte(strlog + "\n"))
|
|
||||||
}
|
|
||||||
func Println(sakura ...interface{}) {
|
|
||||||
var mycolor, bold string
|
|
||||||
lens := len(sakura)
|
|
||||||
if lens < 2 {
|
|
||||||
fmt.Println(sakura)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if lens >= 2 {
|
_, fname, line, _ := runtime.Caller(2)
|
||||||
mycolor, _ = sakura[lens-2].(string)
|
fname = filepath.Base(fname)
|
||||||
if lens == 3 {
|
date := time.Now().Format("2006-01-02 15:04:05 Mon")
|
||||||
bold, _ = sakura[lens-1].(string)
|
if showline && showlv {
|
||||||
}
|
logs = fmt.Sprintf("%s %s %s %s", date, fname+":"+strconv.Itoa(line), `[`+levels[level]+`]`, strlog)
|
||||||
}
|
} else if showline && !showlv {
|
||||||
switch strings.ToLower(mycolor) {
|
logs = fmt.Sprintf("%s %s %s", date, fname+":"+strconv.Itoa(line), strlog)
|
||||||
case "blue":
|
} else if !showline && showlv {
|
||||||
color.Set(color.FgBlue)
|
logs = fmt.Sprintf("%s %s %s", date, `[`+levels[level]+`]`, strlog)
|
||||||
case "black":
|
|
||||||
color.Set(color.FgBlack)
|
|
||||||
case "cyan":
|
|
||||||
color.Set(color.FgCyan)
|
|
||||||
case "green":
|
|
||||||
color.Set(color.FgGreen)
|
|
||||||
case "magenta":
|
|
||||||
color.Set(color.FgMagenta)
|
|
||||||
case "red":
|
|
||||||
color.Set(color.FgRed)
|
|
||||||
case "white":
|
|
||||||
color.Set(color.FgWhite)
|
|
||||||
case "yellow":
|
|
||||||
color.Set(color.FgYellow)
|
|
||||||
case "grey":
|
|
||||||
color.Set(color.FgHiYellow)
|
|
||||||
default:
|
|
||||||
color.Set(color.Reset)
|
|
||||||
}
|
|
||||||
for _, v := range []byte(bold) {
|
|
||||||
switch string([]byte{v}) {
|
|
||||||
case "b":
|
|
||||||
color.Set(color.Bold)
|
|
||||||
case "l":
|
|
||||||
color.Set(color.BlinkRapid)
|
|
||||||
case "u":
|
|
||||||
color.Set(color.Underline)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var hoe []interface{}
|
|
||||||
for i := 0; i < lens-2; i++ {
|
|
||||||
hoe = append(hoe, sakura[i])
|
|
||||||
}
|
|
||||||
if len(hoe) == 1 {
|
|
||||||
fmt.Println(hoe[0])
|
|
||||||
} else {
|
} else {
|
||||||
fmt.Println(hoe)
|
logs = fmt.Sprintf("%s %s", date, strlog)
|
||||||
}
|
}
|
||||||
|
for _, v := range Colors[level] {
|
||||||
|
color.Set(v)
|
||||||
|
}
|
||||||
|
fmt.Print(logs)
|
||||||
color.Set(color.Reset)
|
color.Set(color.Reset)
|
||||||
|
if dowrite {
|
||||||
|
go write(logs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
func StdPrint(c1, c2 color.Attribute, str ...interface{}) {
|
||||||
func Print(sakura ...interface{}) {
|
color.Set(c1)
|
||||||
var mycolor, bold string
|
color.Set(c2)
|
||||||
lens := len(sakura)
|
fmt.Print(str...)
|
||||||
if lens < 2 {
|
|
||||||
fmt.Print(sakura)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if lens >= 2 {
|
|
||||||
mycolor, _ = sakura[lens-2].(string)
|
|
||||||
if lens == 3 {
|
|
||||||
bold, _ = sakura[lens-1].(string)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
switch strings.ToLower(mycolor) {
|
|
||||||
case "blue":
|
|
||||||
color.Set(color.FgBlue)
|
|
||||||
case "black":
|
|
||||||
color.Set(color.FgBlack)
|
|
||||||
case "cyan":
|
|
||||||
color.Set(color.FgCyan)
|
|
||||||
case "green":
|
|
||||||
color.Set(color.FgGreen)
|
|
||||||
case "magenta":
|
|
||||||
color.Set(color.FgMagenta)
|
|
||||||
case "red":
|
|
||||||
color.Set(color.FgRed)
|
|
||||||
case "white":
|
|
||||||
color.Set(color.FgWhite)
|
|
||||||
case "yellow":
|
|
||||||
color.Set(color.FgYellow)
|
|
||||||
case "grey":
|
|
||||||
color.Set(color.FgHiYellow)
|
|
||||||
default:
|
|
||||||
color.Set(color.Reset)
|
|
||||||
}
|
|
||||||
for _, v := range []byte(bold) {
|
|
||||||
switch string([]byte{v}) {
|
|
||||||
case "b":
|
|
||||||
color.Set(color.Bold)
|
|
||||||
case "l":
|
|
||||||
color.Set(color.BlinkRapid)
|
|
||||||
case "u":
|
|
||||||
color.Set(color.Underline)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var hoe []interface{}
|
|
||||||
for i := 0; i < lens-2; i++ {
|
|
||||||
hoe = append(hoe, sakura[i])
|
|
||||||
}
|
|
||||||
if len(hoe) == 1 {
|
|
||||||
fmt.Println(hoe[0])
|
|
||||||
} else {
|
|
||||||
fmt.Println(hoe)
|
|
||||||
}
|
|
||||||
color.Set(color.Reset)
|
color.Set(color.Reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
func PrintLog(sakura ...interface{}) {
|
func StdPrintf(c1, c2 color.Attribute, format string, str ...interface{}) {
|
||||||
|
color.Set(c1)
|
||||||
var mycolor, bold string
|
color.Set(c2)
|
||||||
lens := len(sakura)
|
fmt.Printf(format, str...)
|
||||||
if lens < 1 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if lens >= 2 {
|
|
||||||
mycolor, _ = sakura[1].(string)
|
|
||||||
if lens == 3 {
|
|
||||||
bold, _ = sakura[2].(string)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
strs, _ := sakura[0].(string)
|
|
||||||
now := time.Now().Format("2006-01-02 15:04:05")
|
|
||||||
strlog := now + ": " + strs
|
|
||||||
switch strings.ToLower(mycolor) {
|
|
||||||
case "blue":
|
|
||||||
color.Set(color.FgBlue)
|
|
||||||
case "black":
|
|
||||||
color.Set(color.FgBlack)
|
|
||||||
case "cyan":
|
|
||||||
color.Set(color.FgCyan)
|
|
||||||
case "green":
|
|
||||||
color.Set(color.FgGreen)
|
|
||||||
case "magenta":
|
|
||||||
color.Set(color.FgMagenta)
|
|
||||||
case "red":
|
|
||||||
color.Set(color.FgRed)
|
|
||||||
case "white":
|
|
||||||
color.Set(color.FgWhite)
|
|
||||||
case "yellow":
|
|
||||||
color.Set(color.FgYellow)
|
|
||||||
case "grey":
|
|
||||||
color.Set(color.FgHiYellow)
|
|
||||||
default:
|
|
||||||
color.Set(color.Reset)
|
color.Set(color.Reset)
|
||||||
}
|
}
|
||||||
for _, v := range []byte(bold) {
|
|
||||||
switch string([]byte{v}) {
|
func StdPrintln(c1, c2 color.Attribute, str ...interface{}) {
|
||||||
case "b":
|
color.Set(c1)
|
||||||
color.Set(color.Bold)
|
color.Set(c2)
|
||||||
case "l":
|
fmt.Println(str...)
|
||||||
color.Set(color.BlinkRapid)
|
|
||||||
case "u":
|
|
||||||
color.Set(color.Underline)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if CSpace {
|
|
||||||
strlog += "\n"
|
|
||||||
}
|
|
||||||
fmt.Println(strlog)
|
|
||||||
color.Set(color.Reset)
|
color.Set(color.Reset)
|
||||||
LogPar.Write([]byte(strlog + "\n"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func End() {
|
func Print(c1, c2 color.Attribute, str ...interface{}) {
|
||||||
LogPar.Close()
|
color.Set(c1)
|
||||||
|
color.Set(c2)
|
||||||
|
strs := fmt.Sprint(str...)
|
||||||
|
fmt.Print(strs)
|
||||||
|
color.Set(color.Reset)
|
||||||
|
write(strs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ThrowError(err error, other string) {
|
func Printf(c1, c2 color.Attribute, format string, str ...interface{}) {
|
||||||
if err != nil {
|
color.Set(c1)
|
||||||
PrintError(err, other)
|
color.Set(c2)
|
||||||
|
strs := fmt.Sprintf(format, str...)
|
||||||
|
fmt.Print(strs)
|
||||||
|
color.Set(color.Reset)
|
||||||
|
write(strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Println(c1, c2 color.Attribute, str ...interface{}) {
|
||||||
|
color.Set(c1)
|
||||||
|
color.Set(c2)
|
||||||
|
strs := fmt.Sprintln(str...)
|
||||||
|
fmt.Print(strs)
|
||||||
|
color.Set(color.Reset)
|
||||||
|
write(strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Debug(str ...interface{}) {
|
||||||
|
strs := fmt.Sprint(str...)
|
||||||
|
output(LvDebug, ShowLine, ShowLevel, DoWrite, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Debugf(format string, str ...interface{}) {
|
||||||
|
strs := fmt.Sprintf(format, str...)
|
||||||
|
output(LvDebug, ShowLine, ShowLevel, DoWrite, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Debugln(str ...interface{}) {
|
||||||
|
strs := fmt.Sprintln(str...)
|
||||||
|
output(LvDebug, ShowLine, ShowLevel, DoWrite, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Info(str ...interface{}) {
|
||||||
|
strs := fmt.Sprint(str...)
|
||||||
|
output(LvInfo, ShowLine, ShowLevel, DoWrite, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Infof(format string, str ...interface{}) {
|
||||||
|
strs := fmt.Sprintf(format, str...)
|
||||||
|
output(LvInfo, ShowLine, ShowLevel, DoWrite, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Infoln(str ...interface{}) {
|
||||||
|
strs := fmt.Sprintln(str...)
|
||||||
|
output(LvInfo, ShowLine, ShowLevel, DoWrite, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Notice(str ...interface{}) {
|
||||||
|
strs := fmt.Sprint(str...)
|
||||||
|
output(LvNotice, ShowLine, ShowLevel, DoWrite, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Noticef(format string, str ...interface{}) {
|
||||||
|
strs := fmt.Sprintf(format, str...)
|
||||||
|
output(LvNotice, ShowLine, ShowLevel, DoWrite, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Noticeln(str ...interface{}) {
|
||||||
|
strs := fmt.Sprintln(str...)
|
||||||
|
output(LvNotice, ShowLine, ShowLevel, DoWrite, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Warning(str ...interface{}) {
|
||||||
|
strs := fmt.Sprint(str...)
|
||||||
|
output(LvWarning, ShowLine, ShowLevel, DoWrite, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Warningf(format string, str ...interface{}) {
|
||||||
|
strs := fmt.Sprintf(format, str...)
|
||||||
|
output(LvWarning, ShowLine, ShowLevel, DoWrite, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Warningln(str ...interface{}) {
|
||||||
|
strs := fmt.Sprintln(str...)
|
||||||
|
output(LvWarning, ShowLine, ShowLevel, DoWrite, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Error(str ...interface{}) {
|
||||||
|
strs := fmt.Sprint(str...)
|
||||||
|
output(LvError, ShowLine, ShowLevel, DoWrite, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Errorf(format string, str ...interface{}) {
|
||||||
|
strs := fmt.Sprintf(format, str...)
|
||||||
|
output(LvError, ShowLine, ShowLevel, DoWrite, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Errorln(str ...interface{}) {
|
||||||
|
strs := fmt.Sprintln(str...)
|
||||||
|
output(LvError, ShowLine, ShowLevel, DoWrite, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Critical(str ...interface{}) {
|
||||||
|
strs := fmt.Sprint(str...)
|
||||||
|
output(LvCritical, ShowLine, ShowLevel, DoWrite, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Criticalf(format string, str ...interface{}) {
|
||||||
|
strs := fmt.Sprintf(format, str...)
|
||||||
|
output(LvCritical, ShowLine, ShowLevel, DoWrite, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Criticalln(str ...interface{}) {
|
||||||
|
strs := fmt.Sprintln(str...)
|
||||||
|
output(LvCritical, ShowLine, ShowLevel, DoWrite, strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Fatal(str ...interface{}) {
|
||||||
|
strs := fmt.Sprint(str...)
|
||||||
|
output(LvFatal, ShowLine, ShowLevel, DoWrite, strs)
|
||||||
|
CloseLog()
|
||||||
|
os.Exit(9)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Fatalf(format string, str ...interface{}) {
|
||||||
|
strs := fmt.Sprintf(format, str...)
|
||||||
|
output(LvFatal, ShowLine, ShowLevel, DoWrite, strs)
|
||||||
|
CloseLog()
|
||||||
|
os.Exit(9)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Fatalln(str ...interface{}) {
|
||||||
|
strs := fmt.Sprintln(str...)
|
||||||
|
output(LvFatal, ShowLine, ShowLevel, DoWrite, strs)
|
||||||
|
CloseLog()
|
||||||
|
os.Exit(9)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Panic(str ...interface{}) {
|
||||||
|
strs := fmt.Sprint(str...)
|
||||||
|
output(LvPanic, ShowLine, ShowLevel, DoWrite, strs)
|
||||||
|
panic(str)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Panicf(format string, str ...interface{}) {
|
||||||
|
strs := fmt.Sprintf(format, str...)
|
||||||
|
output(LvPanic, ShowLine, ShowLevel, DoWrite, strs)
|
||||||
|
panic(strs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Panicln(str ...interface{}) {
|
||||||
|
strs := fmt.Sprintln(str...)
|
||||||
|
output(LvPanic, ShowLine, ShowLevel, DoWrite, strs)
|
||||||
|
panic(str)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetLogFile(path string) error {
|
||||||
|
var err error
|
||||||
|
loghandle, err = os.Create(path)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func SwitchFile(path string) error {
|
||||||
|
if loghandle != nil {
|
||||||
|
loghandle.Close()
|
||||||
|
}
|
||||||
|
return SetLogFile(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CloseLog() {
|
||||||
|
if loghandle != nil {
|
||||||
|
loghandle.Close()
|
||||||
}
|
}
|
||||||
End()
|
|
||||||
time.Sleep(time.Second * 8)
|
|
||||||
panic(err)
|
|
||||||
os.Exit(233)
|
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,18 @@
|
|||||||
package starlog
|
package starlog
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"errors"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
func Test_StarLog(t *testing.T) {
|
func Test_LOG(t *testing.T) {
|
||||||
CreateLog("./sakura", "suki")
|
SetLogFile("./okk.log")
|
||||||
Println("suki!", "blue", "b")
|
Debugln("这是一个Debug事项")
|
||||||
|
Infoln("这是一个通知")
|
||||||
|
err := errors.New("NBM")
|
||||||
|
Errorln("你牛逼", err)
|
||||||
|
LogLevel = 1
|
||||||
|
Debugln("你看不到我了!")
|
||||||
|
Panicln("我要下线了")
|
||||||
|
CloseLog()
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user