mirror of
https://gitee.com/johng/gf
synced 2026-06-07 02:12:11 +08:00
改进glog & gfilepool
This commit is contained in:
@ -12,10 +12,10 @@ import (
|
||||
"time"
|
||||
"sync"
|
||||
"strconv"
|
||||
"sync/atomic"
|
||||
"gitee.com/johng/gf/g/os/gtime"
|
||||
"gitee.com/johng/gf/g/container/gmap"
|
||||
"gitee.com/johng/gf/g/container/glist"
|
||||
"gitee.com/johng/gf/g/container/gtype"
|
||||
)
|
||||
|
||||
// 文件指针池
|
||||
@ -23,23 +23,23 @@ type Pool struct {
|
||||
path string // 文件绝对路径
|
||||
flag int // 文件打开标识
|
||||
list *glist.List // 可用/闲置的文件指针链表
|
||||
idlemax int // 闲置最大时间,超过该时间则被系统回收(秒)
|
||||
closed bool // 连接池是否已关闭
|
||||
idle int // 闲置最大时间,超过该时间则被系统回收(秒)
|
||||
closed *gtype.Bool // 连接池是否已关闭
|
||||
}
|
||||
|
||||
// 文件指针池指针
|
||||
type File struct {
|
||||
sync.RWMutex
|
||||
pool *Pool // 所属池
|
||||
file *os.File // 指针对象
|
||||
expire int64 // 过期时间(秒)
|
||||
type PoolItem struct {
|
||||
mu sync.RWMutex
|
||||
pool *Pool // 所属池
|
||||
file *os.File // 指针对象
|
||||
expire *gtype.Int64 // 过期时间(秒)
|
||||
}
|
||||
|
||||
// 全局指针池,expire < 0表示不过期,expire = 0表示使用完立即回收,expire > 0表示超时回收
|
||||
var pools *gmap.StringInterfaceMap = gmap.NewStringInterfaceMap()
|
||||
var pools = gmap.NewStringInterfaceMap()
|
||||
|
||||
// 获得文件对象,并自动创建指针池
|
||||
func OpenWithPool(path string, flag int, expire int) (*File, error) {
|
||||
func OpenWithPool(path string, flag int, expire int) (*PoolItem, error) {
|
||||
key := path + strconv.Itoa(flag) + strconv.Itoa(expire)
|
||||
result := pools.Get(key)
|
||||
if result != nil {
|
||||
@ -56,21 +56,22 @@ func New(path string, flag int, expire int) *Pool {
|
||||
path : path,
|
||||
flag : flag,
|
||||
list : glist.New(),
|
||||
idlemax : expire,
|
||||
idle : expire,
|
||||
}
|
||||
// 独立的线程执行过期清理工作
|
||||
if expire != -1 {
|
||||
go func(p *Pool) {
|
||||
// 遍历可用指针列表,判断是否过期
|
||||
for !p.closed {
|
||||
r := p.list.Front()
|
||||
if r != nil && r.Value != nil {
|
||||
f := r.Value.(*File)
|
||||
for !p.closed.Val() {
|
||||
if r := p.list.PopFront(); r != nil {
|
||||
f := r.(*PoolItem)
|
||||
// 必须小于,中间有1秒的缓存时间,防止同时获取和判断过期时冲突
|
||||
if f.getExpire() < gtime.Second() {
|
||||
if f.expire.Val() < gtime.Second() {
|
||||
f.destroy()
|
||||
p.list.Remove(r)
|
||||
continue
|
||||
} else {
|
||||
// 重新推回去
|
||||
p.list.PushFront(f)
|
||||
break
|
||||
}
|
||||
}
|
||||
time.Sleep(3 * time.Second)
|
||||
@ -81,21 +82,19 @@ func New(path string, flag int, expire int) *Pool {
|
||||
}
|
||||
|
||||
// 获得一个文件打开指针
|
||||
func (p *Pool) File() (*File, error) {
|
||||
func (p *Pool) File() (*PoolItem, error) {
|
||||
if p.list.Len() > 0 {
|
||||
// 遍历可用指针列表,返回一个未过期的指针
|
||||
for {
|
||||
r := p.list.PopBack()
|
||||
if r != nil {
|
||||
f := r.(*File)
|
||||
// 必须大于
|
||||
if f.getExpire() > gtime.Second() {
|
||||
// 从队列头依次查找,返回一个未过期的指针
|
||||
if r := p.list.PopFront(); r != nil {
|
||||
f := r.(*PoolItem)
|
||||
if f.expire.Val() > gtime.Second() {
|
||||
return f, nil
|
||||
} else if f.file != nil {
|
||||
f.destroy()
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -103,44 +102,30 @@ func (p *Pool) File() (*File, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &File {
|
||||
pool : p,
|
||||
file : file,
|
||||
return &PoolItem {
|
||||
pool : p,
|
||||
file : file,
|
||||
expire : gtype.NewInt64(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 关闭指针池
|
||||
func (p *Pool) Close() {
|
||||
p.closed = true
|
||||
p.closed.Set(true)
|
||||
}
|
||||
|
||||
// 获得底层文件指针
|
||||
func (f *File) File() *os.File {
|
||||
func (f *PoolItem) File() *os.File {
|
||||
return f.file
|
||||
}
|
||||
|
||||
// 关闭指针链接(软关闭),放回池中重复使用
|
||||
func (f *File) Close() {
|
||||
f.setExpire(gtime.Second() + int64(f.pool.idlemax))
|
||||
f.pool.list.PushFront(f)
|
||||
func (f *PoolItem) Close() {
|
||||
f.expire.Set(gtime.Second() + int64(f.pool.idle))
|
||||
f.pool.list.PushBack(f)
|
||||
}
|
||||
|
||||
// 销毁指针
|
||||
func (f *File) destroy() {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
if f.file != nil {
|
||||
f.file.Close()
|
||||
f.file = nil
|
||||
}
|
||||
}
|
||||
|
||||
// 获取指针过期时间
|
||||
func (f *File) setExpire(expire int64) {
|
||||
atomic.StoreInt64(&f.expire, expire)
|
||||
}
|
||||
|
||||
// 获取指针过期时间
|
||||
func (f *File) getExpire() int64 {
|
||||
return atomic.LoadInt64(&f.expire)
|
||||
func (f *PoolItem) destroy() {
|
||||
f.file.Close()
|
||||
}
|
||||
@ -9,27 +9,16 @@
|
||||
package glog
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"os"
|
||||
"io"
|
||||
"time"
|
||||
"fmt"
|
||||
"errors"
|
||||
"strings"
|
||||
"path/filepath"
|
||||
"gitee.com/johng/gf/g/os/gfile"
|
||||
"gitee.com/johng/gf/g/os/gfilepool"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"gitee.com/johng/gf/g/util/gregx"
|
||||
"sync"
|
||||
"gitee.com/johng/gf/g/container/gtype"
|
||||
)
|
||||
|
||||
type Logger struct {
|
||||
mutex sync.RWMutex
|
||||
logio io.Writer
|
||||
debug bool // 是否允许输出DEBUG信息
|
||||
logpath string // 日志写入的目录路径
|
||||
lastlogdate string // 上一次写入日志的日期,例如: 2006-01-02
|
||||
mu sync.RWMutex
|
||||
io io.Writer // 日志内容写入的IO接口
|
||||
path *gtype.String // 日志写入的目录路径
|
||||
debug *gtype.Bool // 是否允许输出DEBUG信息
|
||||
}
|
||||
|
||||
// 默认的日志对象
|
||||
@ -37,14 +26,16 @@ var logger = New()
|
||||
|
||||
// 新建自定义的日志操作对象
|
||||
func New() *Logger {
|
||||
return &Logger{
|
||||
debug : true,
|
||||
return &Logger {
|
||||
io : nil,
|
||||
path : gtype.NewString(),
|
||||
debug : gtype.NewBool(true),
|
||||
}
|
||||
}
|
||||
|
||||
// 日志日志目录绝对路径
|
||||
func SetLogPath(path string) {
|
||||
logger.SetLogPath(path)
|
||||
func SetPath(path string) {
|
||||
logger.SetPath(path)
|
||||
}
|
||||
|
||||
// 设置是否允许输出DEBUG信息
|
||||
@ -53,8 +44,8 @@ func SetDebug(debug bool) {
|
||||
}
|
||||
|
||||
// 获取日志目录绝对路径
|
||||
func GetLogPath() string {
|
||||
return logger.GetLogPath()
|
||||
func GetPath() string {
|
||||
return logger.path.Val()
|
||||
}
|
||||
|
||||
func Print(v ...interface{}) {
|
||||
@ -176,274 +167,3 @@ func Errorfln(format string, v ...interface{}) {
|
||||
func Criticalfln(format string, v ...interface{}) {
|
||||
logger.Criticalfln(format, v...)
|
||||
}
|
||||
|
||||
func (l *Logger) GetLogIO() io.Writer {
|
||||
l.mutex.RLock()
|
||||
r := l.logio
|
||||
l.mutex.RUnlock()
|
||||
return r
|
||||
}
|
||||
|
||||
func (l *Logger) GetDebug() bool {
|
||||
l.mutex.RLock()
|
||||
r := l.debug
|
||||
l.mutex.RUnlock()
|
||||
return r
|
||||
}
|
||||
|
||||
func (l *Logger) GetLogPath() string {
|
||||
l.mutex.RLock()
|
||||
r := l.logpath
|
||||
l.mutex.RUnlock()
|
||||
return r
|
||||
}
|
||||
|
||||
func (l *Logger) GetLastLogDate() string {
|
||||
l.mutex.RLock()
|
||||
r := l.lastlogdate
|
||||
l.mutex.RUnlock()
|
||||
return r
|
||||
}
|
||||
|
||||
func (l *Logger) SetLogIO(w io.Writer) {
|
||||
l.mutex.RLock()
|
||||
l.logio = w
|
||||
l.mutex.RUnlock()
|
||||
}
|
||||
|
||||
func (l *Logger) SetDebug(debug bool) {
|
||||
l.mutex.Lock()
|
||||
l.debug = debug
|
||||
l.mutex.Unlock()
|
||||
}
|
||||
|
||||
// 设置日志文件的存储目录路径
|
||||
func (l *Logger) SetLogPath(path string) error {
|
||||
// 检测目录权限
|
||||
if !gfile.Exists(path) {
|
||||
if err := gfile.Mkdir(path); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
if !gfile.IsWritable(path) {
|
||||
errstr := path + " is no writable for current user"
|
||||
fmt.Fprintln(os.Stderr, errstr)
|
||||
return errors.New(errstr)
|
||||
}
|
||||
l.mutex.Lock()
|
||||
l.logpath = strings.TrimRight(path, string(filepath.Separator))
|
||||
l.mutex.Unlock()
|
||||
// 重新检查日志io对象
|
||||
l.checkLogIO()
|
||||
return nil
|
||||
}
|
||||
|
||||
// 检查文件名称是否已经过期,如果过期那么需要新建一个日志文件(默认按照日期分隔)
|
||||
func (l *Logger) checkLogIO() {
|
||||
date := time.Now().Format("2006-01-02")
|
||||
if date != l.GetLastLogDate() {
|
||||
if path := l.GetLogPath(); path != "" {
|
||||
fname := date + ".log"
|
||||
fpath := path + string(filepath.Separator) + fname
|
||||
if fp, err := gfilepool.OpenWithPool(fpath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 600); err == nil {
|
||||
l.SetLogIO(fp.File())
|
||||
fp.Close()
|
||||
} else {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 这里的互斥锁保证统一时刻只会写入一行日志,防止串日志的情况
|
||||
func (l *Logger) print(logio io.Writer, s string) {
|
||||
l.mutex.Lock()
|
||||
fmt.Fprint(logio, l.format(s))
|
||||
l.mutex.Unlock()
|
||||
}
|
||||
|
||||
// 核心打印数据方法(标准输出)
|
||||
func (l *Logger) stdPrint(s string) {
|
||||
l.checkLogIO()
|
||||
logio := l.GetLogIO()
|
||||
if logio == nil {
|
||||
logio = os.Stdout
|
||||
}
|
||||
l.print(logio, s)
|
||||
}
|
||||
|
||||
// 核心打印数据方法(标准错误)
|
||||
func (l *Logger) errPrint(s string) {
|
||||
l.checkLogIO()
|
||||
logio := l.GetLogIO()
|
||||
if logio == nil {
|
||||
logio = os.Stderr
|
||||
}
|
||||
// 记录调用回溯信息
|
||||
backtrace := l.backtrace()
|
||||
if s[len(s) - 1] == byte('\n') {
|
||||
s = s + backtrace + "\n"
|
||||
} else {
|
||||
s = s + "\n" + backtrace + "\n"
|
||||
}
|
||||
l.print(logio, s)
|
||||
}
|
||||
|
||||
// 调用回溯字符串
|
||||
func (l *Logger) backtrace() string {
|
||||
backtrace := "Trace:\n"
|
||||
for i := 1; i < 10000; i++ {
|
||||
if _, cfile, cline, ok := runtime.Caller(i + 3); ok {
|
||||
// 不打印出go源码路径
|
||||
if !gregx.IsMatchString("^" + runtime.GOROOT(), cfile) {
|
||||
backtrace += strconv.Itoa(i) + ". " + cfile + ":" + strconv.Itoa(cline) + "\n"
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
return backtrace
|
||||
}
|
||||
|
||||
func (l *Logger) format(s string) string {
|
||||
return time.Now().Format("2006-01-02 15:04:05.000 ") + s
|
||||
}
|
||||
|
||||
func (l *Logger) Print(v ...interface{}) {
|
||||
l.stdPrint(fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Printf(format string, v ...interface{}) {
|
||||
l.stdPrint(fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Println(v ...interface{}) {
|
||||
l.stdPrint(fmt.Sprintln(v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Printfln(format string, v ...interface{}) {
|
||||
l.stdPrint(fmt.Sprintf(format + "\n", v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Fatal(v ...interface{}) {
|
||||
l.errPrint(fmt.Sprint(v...))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func (l *Logger) Fatalf(format string, v ...interface{}) {
|
||||
l.errPrint(fmt.Sprintf(format, v...))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func (l *Logger) Fatalln(v ...interface{}) {
|
||||
l.errPrint(fmt.Sprintln(v...))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func (l *Logger) Fatalfln(format string, v ...interface{}) {
|
||||
l.errPrint(fmt.Sprintf(format + "\n", v...))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func (l *Logger) Panic(v ...interface{}) {
|
||||
s := fmt.Sprint(v...)
|
||||
l.errPrint(s)
|
||||
panic(s)
|
||||
}
|
||||
|
||||
func (l *Logger) Panicf(format string, v ...interface{}) {
|
||||
s := fmt.Sprintf(format, v...)
|
||||
l.errPrint(s)
|
||||
panic(s)
|
||||
}
|
||||
|
||||
func (l *Logger) Panicln(v ...interface{}) {
|
||||
s := fmt.Sprintln(v...)
|
||||
l.errPrint(s)
|
||||
panic(s)
|
||||
}
|
||||
|
||||
func (l *Logger) Panicfln(format string, v ...interface{}) {
|
||||
s := fmt.Sprintf(format + "\n", v...)
|
||||
l.errPrint(s)
|
||||
panic(s)
|
||||
}
|
||||
|
||||
func (l *Logger) Info(v ...interface{}) {
|
||||
l.stdPrint("[INFO] " + fmt.Sprintln(v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Debug(v ...interface{}) {
|
||||
if l.GetDebug() {
|
||||
l.stdPrint("[DEBU] " + fmt.Sprintln(v...))
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logger) Notice(v ...interface{}) {
|
||||
l.errPrint("[NOTI] " + fmt.Sprintln(v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Warning(v ...interface{}) {
|
||||
l.errPrint("[WARN] " + fmt.Sprintln(v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Error(v ...interface{}) {
|
||||
l.errPrint("[ERRO] " + fmt.Sprintln(v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Critical(v ...interface{}) {
|
||||
l.errPrint("[CRIT] " + fmt.Sprintln(v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Infof(format string, v ...interface{}) {
|
||||
l.stdPrint("[INFO] " + fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Debugf(format string, v ...interface{}) {
|
||||
if l.GetDebug() {
|
||||
l.stdPrint("[DEBU] " + fmt.Sprintf(format, v...))
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logger) Noticef(format string, v ...interface{}) {
|
||||
l.errPrint("[NOTI] " + fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Warningf(format string, v ...interface{}) {
|
||||
l.errPrint("[WARN] " + fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Errorf(format string, v ...interface{}) {
|
||||
l.errPrint("[ERRO] " + fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Criticalf(format string, v ...interface{}) {
|
||||
l.errPrint("[CRIT] " + fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Infofln(format string, v ...interface{}) {
|
||||
l.stdPrint("[INFO] " + fmt.Sprintf(format, v...) + "\n")
|
||||
}
|
||||
|
||||
func (l *Logger) Debugfln(format string, v ...interface{}) {
|
||||
if l.GetDebug() {
|
||||
l.stdPrint("[DEBU] " + fmt.Sprintf(format, v...) + "\n")
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logger) Noticefln(format string, v ...interface{}) {
|
||||
l.errPrint("[NOTI] " + fmt.Sprintf(format, v...) + "\n")
|
||||
}
|
||||
|
||||
func (l *Logger) Warningfln(format string, v ...interface{}) {
|
||||
l.errPrint("[WARN] " + fmt.Sprintf(format, v...) + "\n")
|
||||
}
|
||||
|
||||
func (l *Logger) Errorfln(format string, v ...interface{}) {
|
||||
l.errPrint("[ERRO] " + fmt.Sprintf(format, v...) + "\n")
|
||||
}
|
||||
|
||||
func (l *Logger) Criticalfln(format string, v ...interface{}) {
|
||||
l.errPrint("[CRIT] " + fmt.Sprintf(format, v...) + "\n")
|
||||
}
|
||||
270
g/os/glog/glog_logger.go
Normal file
270
g/os/glog/glog_logger.go
Normal file
@ -0,0 +1,270 @@
|
||||
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://gitee.com/johng/gf.
|
||||
|
||||
package glog
|
||||
|
||||
import (
|
||||
"os"
|
||||
"io"
|
||||
"time"
|
||||
"fmt"
|
||||
"errors"
|
||||
"strings"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"gitee.com/johng/gf/g/os/gfile"
|
||||
"gitee.com/johng/gf/g/util/gregx"
|
||||
"gitee.com/johng/gf/g/os/gfilepool"
|
||||
)
|
||||
|
||||
const (
|
||||
gDEFAULT_FILE_POOL_FLAGS = os.O_CREATE|os.O_WRONLY|os.O_APPEND
|
||||
)
|
||||
|
||||
// 可自定义IO接口
|
||||
func (l *Logger) SetIO(w io.Writer) {
|
||||
l.mu.RLock()
|
||||
l.io = w
|
||||
l.mu.RUnlock()
|
||||
}
|
||||
|
||||
// 返回自定义IO
|
||||
func (l *Logger) GetIO() io.Writer {
|
||||
l.mu.RLock()
|
||||
r := l.io
|
||||
l.mu.RUnlock()
|
||||
return r
|
||||
}
|
||||
|
||||
// 获取默认的文件IO
|
||||
func (l *Logger) getFileByPool() *gfilepool.PoolItem {
|
||||
if path := l.path.Val(); path != "" {
|
||||
fpath := path + gfile.Separator + time.Now().Format("2006-01-02.log")
|
||||
if fp, err := gfilepool.OpenWithPool(fpath, gDEFAULT_FILE_POOL_FLAGS, 86400); err == nil {
|
||||
return fp
|
||||
} else {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *Logger) GetDebug() bool {
|
||||
return l.debug.Val()
|
||||
}
|
||||
|
||||
func (l *Logger) SetDebug(debug bool) {
|
||||
l.debug.Set(debug)
|
||||
}
|
||||
|
||||
// 设置日志文件的存储目录路径
|
||||
func (l *Logger) SetPath(path string) error {
|
||||
// 检测目录权限
|
||||
if !gfile.Exists(path) {
|
||||
if err := gfile.Mkdir(path); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
if !gfile.IsWritable(path) {
|
||||
errstr := path + " is no writable for current user"
|
||||
fmt.Fprintln(os.Stderr, errstr)
|
||||
return errors.New(errstr)
|
||||
}
|
||||
l.path.Set(strings.TrimRight(path, gfile.Separator))
|
||||
return nil
|
||||
}
|
||||
|
||||
// 这里的写锁保证统一时刻只会写入一行日志,防止串日志的情况
|
||||
func (l *Logger) print(defaultIO io.Writer, s string) {
|
||||
w := l.GetIO()
|
||||
if w == nil {
|
||||
if v := l.getFileByPool(); v != nil {
|
||||
w = v.File()
|
||||
defer v.Close()
|
||||
} else {
|
||||
w = defaultIO
|
||||
}
|
||||
}
|
||||
l.mu.Lock()
|
||||
fmt.Fprint(w, l.format(s))
|
||||
l.mu.Unlock()
|
||||
}
|
||||
|
||||
// 核心打印数据方法(标准输出)
|
||||
func (l *Logger) stdPrint(s string) {
|
||||
l.print(os.Stdout, s)
|
||||
}
|
||||
|
||||
// 核心打印数据方法(标准错误)
|
||||
func (l *Logger) errPrint(s string) {
|
||||
// 记录调用回溯信息
|
||||
backtrace := l.backtrace()
|
||||
if s[len(s) - 1] == byte('\n') {
|
||||
s = s + backtrace + "\n"
|
||||
} else {
|
||||
s = s + "\n" + backtrace + "\n"
|
||||
}
|
||||
l.print(os.Stderr, s)
|
||||
}
|
||||
|
||||
// 调用回溯字符串
|
||||
func (l *Logger) backtrace() string {
|
||||
backtrace := "Trace:\n"
|
||||
for i := 1; i < 10000; i++ {
|
||||
if _, cfile, cline, ok := runtime.Caller(i + 3); ok {
|
||||
// 不打印出go源码路径
|
||||
if !gregx.IsMatchString("^" + runtime.GOROOT(), cfile) {
|
||||
backtrace += strconv.Itoa(i) + ". " + cfile + ":" + strconv.Itoa(cline) + "\n"
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
return backtrace
|
||||
}
|
||||
|
||||
func (l *Logger) format(s string) string {
|
||||
return time.Now().Format("2006-01-02 15:04:05.000 ") + s
|
||||
}
|
||||
|
||||
func (l *Logger) Print(v ...interface{}) {
|
||||
l.stdPrint(fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Printf(format string, v ...interface{}) {
|
||||
l.stdPrint(fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Println(v ...interface{}) {
|
||||
l.stdPrint(fmt.Sprintln(v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Printfln(format string, v ...interface{}) {
|
||||
l.stdPrint(fmt.Sprintf(format + "\n", v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Fatal(v ...interface{}) {
|
||||
l.errPrint(fmt.Sprint(v...))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func (l *Logger) Fatalf(format string, v ...interface{}) {
|
||||
l.errPrint(fmt.Sprintf(format, v...))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func (l *Logger) Fatalln(v ...interface{}) {
|
||||
l.errPrint(fmt.Sprintln(v...))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func (l *Logger) Fatalfln(format string, v ...interface{}) {
|
||||
l.errPrint(fmt.Sprintf(format + "\n", v...))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func (l *Logger) Panic(v ...interface{}) {
|
||||
s := fmt.Sprint(v...)
|
||||
l.errPrint(s)
|
||||
panic(s)
|
||||
}
|
||||
|
||||
func (l *Logger) Panicf(format string, v ...interface{}) {
|
||||
s := fmt.Sprintf(format, v...)
|
||||
l.errPrint(s)
|
||||
panic(s)
|
||||
}
|
||||
|
||||
func (l *Logger) Panicln(v ...interface{}) {
|
||||
s := fmt.Sprintln(v...)
|
||||
l.errPrint(s)
|
||||
panic(s)
|
||||
}
|
||||
|
||||
func (l *Logger) Panicfln(format string, v ...interface{}) {
|
||||
s := fmt.Sprintf(format + "\n", v...)
|
||||
l.errPrint(s)
|
||||
panic(s)
|
||||
}
|
||||
|
||||
func (l *Logger) Info(v ...interface{}) {
|
||||
l.stdPrint("[INFO] " + fmt.Sprintln(v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Debug(v ...interface{}) {
|
||||
if l.GetDebug() {
|
||||
l.stdPrint("[DEBU] " + fmt.Sprintln(v...))
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logger) Notice(v ...interface{}) {
|
||||
l.errPrint("[NOTI] " + fmt.Sprintln(v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Warning(v ...interface{}) {
|
||||
l.errPrint("[WARN] " + fmt.Sprintln(v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Error(v ...interface{}) {
|
||||
l.errPrint("[ERRO] " + fmt.Sprintln(v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Critical(v ...interface{}) {
|
||||
l.errPrint("[CRIT] " + fmt.Sprintln(v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Infof(format string, v ...interface{}) {
|
||||
l.stdPrint("[INFO] " + fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Debugf(format string, v ...interface{}) {
|
||||
if l.GetDebug() {
|
||||
l.stdPrint("[DEBU] " + fmt.Sprintf(format, v...))
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logger) Noticef(format string, v ...interface{}) {
|
||||
l.errPrint("[NOTI] " + fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Warningf(format string, v ...interface{}) {
|
||||
l.errPrint("[WARN] " + fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Errorf(format string, v ...interface{}) {
|
||||
l.errPrint("[ERRO] " + fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Criticalf(format string, v ...interface{}) {
|
||||
l.errPrint("[CRIT] " + fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func (l *Logger) Infofln(format string, v ...interface{}) {
|
||||
l.stdPrint("[INFO] " + fmt.Sprintf(format, v...) + "\n")
|
||||
}
|
||||
|
||||
func (l *Logger) Debugfln(format string, v ...interface{}) {
|
||||
if l.GetDebug() {
|
||||
l.stdPrint("[DEBU] " + fmt.Sprintf(format, v...) + "\n")
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logger) Noticefln(format string, v ...interface{}) {
|
||||
l.errPrint("[NOTI] " + fmt.Sprintf(format, v...) + "\n")
|
||||
}
|
||||
|
||||
func (l *Logger) Warningfln(format string, v ...interface{}) {
|
||||
l.errPrint("[WARN] " + fmt.Sprintf(format, v...) + "\n")
|
||||
}
|
||||
|
||||
func (l *Logger) Errorfln(format string, v ...interface{}) {
|
||||
l.errPrint("[ERRO] " + fmt.Sprintf(format, v...) + "\n")
|
||||
}
|
||||
|
||||
func (l *Logger) Criticalfln(format string, v ...interface{}) {
|
||||
l.errPrint("[CRIT] " + fmt.Sprintf(format, v...) + "\n")
|
||||
}
|
||||
@ -2,12 +2,19 @@ package main
|
||||
|
||||
import (
|
||||
"gitee.com/johng/gf/g/net/ghttp"
|
||||
"gitee.com/johng/gf/g/frame/gins"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s := ghttp.GetServer()
|
||||
s.SetServerRoot("/home/john/Documents")
|
||||
s.SetIndexFolder(true)
|
||||
s.SetPort(8199)
|
||||
s.BindHandler("/template2", func(r *ghttp.Request){
|
||||
tplcontent := `id:{{.id}}, name:{{.name}}`
|
||||
content, _ := gins.View().ParseContent(tplcontent, map[string]interface{}{
|
||||
"id" : 123,
|
||||
"name" : "john",
|
||||
})
|
||||
r.Response.Write(content)
|
||||
})
|
||||
//s.SetPort(8199)
|
||||
s.Run()
|
||||
}
|
||||
Reference in New Issue
Block a user