diff --git a/g/g_func.go b/g/g_func.go index 28751ca14..18ae4d887 100644 --- a/g/g_func.go +++ b/g/g_func.go @@ -39,11 +39,11 @@ func Dump(i...interface{}) { } // 抛出一个异常 -func Throw(err interface{}) { - gutil.Throw(err) +func Throw(exception interface{}) { + gutil.Throw(exception) } // try...catch... -func TryCatch(try func(), catch func(err interface{})) { - gutil.TryCatch(try, catch) +func TryCatch(try func(), catch ... func(exception interface{})) { + gutil.TryCatch(try, catch...) } \ No newline at end of file diff --git a/g/net/ghttp/ghttp_request.go b/g/net/ghttp/ghttp_request.go index 77260c3f0..6cbf9bbe8 100644 --- a/g/net/ghttp/ghttp_request.go +++ b/g/net/ghttp/ghttp_request.go @@ -154,6 +154,7 @@ func (r *Request) GetToStruct(object interface{}, mapping...map[string]string) { // 退出当前请求执行,原理是在Request.exit做标记,由服务逻辑流程做判断,自行停止 func (r *Request) Exit() { r.exit.Set(true) + panic(gEXCEPTION_EXIT) } // 判断当前请求是否停止执行 diff --git a/g/net/ghttp/ghttp_server.go b/g/net/ghttp/ghttp_server.go index 1ad12d116..60544ac21 100644 --- a/g/net/ghttp/ghttp_server.go +++ b/g/net/ghttp/ghttp_server.go @@ -52,6 +52,7 @@ const ( gROUTE_REGISTER_HANDLER = 1 gROUTE_REGISTER_OBJECT = 2 gROUTE_REGISTER_CONTROLLER = 3 + gEXCEPTION_EXIT = "exit" ) // ghttp.Server结构体 diff --git a/g/net/ghttp/ghttp_server_handler.go b/g/net/ghttp/ghttp_server_handler.go index ccab1a4c0..0c0606731 100644 --- a/g/net/ghttp/ghttp_server_handler.go +++ b/g/net/ghttp/ghttp_server_handler.go @@ -8,16 +8,16 @@ package ghttp import ( - "os" "fmt" - "sort" - "reflect" - "strings" - "net/url" - "net/http" + "gitee.com/johng/gf/g/encoding/ghtml" "gitee.com/johng/gf/g/os/gfile" "gitee.com/johng/gf/g/os/gtime" - "gitee.com/johng/gf/g/encoding/ghtml" + "net/http" + "net/url" + "os" + "reflect" + "sort" + "strings" ) // 默认HTTP Server处理入口,http包底层默认使用了gorutine异步处理请求,所以这里不再异步执行 @@ -118,6 +118,11 @@ func (s *Server)handleRequest(w http.ResponseWriter, r *http.Request) { // 初始化控制器 func (s *Server)callServeHandler(h *handlerItem, r *Request) { + defer func() { + if e := recover(); e != nil && e != gEXCEPTION_EXIT { + panic(e) + } + }() if h.faddr == nil { // 新建一个控制器对象处理请求 c := reflect.New(h.ctype) diff --git a/g/net/ghttp/ghttp_server_router_hook.go b/g/net/ghttp/ghttp_server_router_hook.go index 66b8a90c4..a1835e010 100644 --- a/g/net/ghttp/ghttp_server_router_hook.go +++ b/g/net/ghttp/ghttp_server_router_hook.go @@ -43,6 +43,11 @@ func (s *Server)BindHookHandlerByMap(pattern string, hookmap map[string]HandlerF func (s *Server) callHookHandler(hook string, r *Request) { hookItems := s.getHookHandlerWithCache(hook, r) if len(hookItems) > 0 { + defer func() { + if e := recover(); e != nil && e != gEXCEPTION_EXIT { + panic(e) + } + }() // 备份原有的router变量 oldRouterVars := r.routerVars for _, item := range hookItems { diff --git a/g/os/glog/glog.go b/g/os/glog/glog.go index 6198708bb..be23a5734 100644 --- a/g/os/glog/glog.go +++ b/g/os/glog/glog.go @@ -11,6 +11,7 @@ package glog import ( "gitee.com/johng/gf/g/container/gtype" + "io" ) const ( @@ -47,6 +48,16 @@ func SetLevel(level int) { defaultLevel.Set(level) } +// 可自定义IO接口,IO可以是文件输出、标准输出、网络输出 +func SetWriter(writer io.Writer) { + logger.SetWriter(writer) +} + +// 返回自定义的IO,默认为nil +func GetWriter() io.Writer { + return logger.GetWriter() +} + // 获取全局的日志记录等级 func GetLevel() int { return defaultLevel.Val() @@ -82,6 +93,11 @@ func SetBacktrace(enabled bool) { logger.SetBacktrace(enabled) } +// 链式操作,设置下一次写入日志内容的Writer +func To(writer io.Writer) *Logger { + return logger.To(writer) +} + // 设置下一次输出的分类,支持多级分类设置 func Cat(category string) *Logger { return logger.Cat(category) diff --git a/g/os/glog/glog_logger.go b/g/os/glog/glog_logger.go index 66e3fce16..ed2ea114f 100644 --- a/g/os/glog/glog_logger.go +++ b/g/os/glog/glog_logger.go @@ -112,9 +112,9 @@ func (l *Logger) SetBacktraceSkip(skip int) { } // 可自定义IO接口,IO可以是文件输出、标准输出、网络输出 -func (l *Logger) SetWriter(w io.Writer) { +func (l *Logger) SetWriter(writer io.Writer) { l.mu.Lock() - l.io = w + l.io = writer l.mu.Unlock() } @@ -191,13 +191,13 @@ func (l *Logger) print(std io.Writer, s string) { fmt.Fprintln(os.Stderr, err.Error()) } } + // 当没有设置writer时,需要判断是否允许输出到标准输出 + if l.alsoStdPrint.Val() { + l.doStdLockPrint(std, s) + } } else { l.doStdLockPrint(writer, s) } - // 是否允许输出到标准输出 - if l.alsoStdPrint.Val() { - l.doStdLockPrint(std, s) - } } // 并发安全打印到标准输出 diff --git a/g/os/glog/glog_logger_linkop.go b/g/os/glog/glog_logger_linkop.go index 4840486b3..0b4c87b4b 100644 --- a/g/os/glog/glog_logger_linkop.go +++ b/g/os/glog/glog_logger_linkop.go @@ -6,7 +6,22 @@ package glog -import "gitee.com/johng/gf/g/os/gfile" +import ( + "gitee.com/johng/gf/g/os/gfile" + "io" +) + +// 链式操作,设置下一次写入日志内容的Writer +func (l *Logger) To(writer io.Writer) *Logger { + logger := (*Logger)(nil) + if l.pr == nil { + logger = l.Clone() + } else { + logger = l + } + logger.SetWriter(writer) + return logger +} // 链式操作,设置下一次输出的日志分类(可以按照文件目录层级设置),在当前logpath或者当前工作目录下创建category目录, // 这是一个链式操作,可以设置多个分类,将会创建层级的日志分类目录。 diff --git a/g/util/gutil/gutil.go b/g/util/gutil/gutil.go index efdf3fc90..ff315f1ed 100644 --- a/g/util/gutil/gutil.go +++ b/g/util/gutil/gutil.go @@ -66,17 +66,19 @@ func PrintBacktrace() { } // 抛出一个异常 -func Throw(err interface{}) { - panic(err) +func Throw(exception interface{}) { + panic(exception) } // try...catch... -func TryCatch(try func(), catch func(err interface{})) { - defer func() { - if err := recover(); err != nil { - catch(err) - } - }() +func TryCatch(try func(), catch ... func(exception interface{})) { + if len(catch) > 0 { + defer func() { + if e := recover(); e != nil { + catch[0](e) + } + }() + } try() } diff --git a/geg/net/ghttp/server/exit.go b/geg/net/ghttp/server/exit.go new file mode 100644 index 000000000..b8bb3d957 --- /dev/null +++ b/geg/net/ghttp/server/exit.go @@ -0,0 +1,27 @@ +package main + +import ( + "gitee.com/johng/gf/g" + "gitee.com/johng/gf/g/os/glog" + "gitee.com/johng/gf/g/net/ghttp" +) + +func main() { + p := "/" + s := g.Server() + s.BindHandler(p, func(r *ghttp.Request) { + r.Response.Writeln("start") + r.Exit() + r.Response.Writeln("end") + }) + s.BindHookHandlerByMap(p, map[string]ghttp.HandlerFunc{ + "BeforeServe" : func(r *ghttp.Request){ + glog.To(r.Response.Writer).Println("BeforeServe") + }, + "AfterServe" : func(r *ghttp.Request){ + glog.To(r.Response.Writer).Println("AfterServe") + }, + }) + s.SetPort(8199) + s.Run() +} \ No newline at end of file diff --git a/geg/other/test.go b/geg/other/test.go index 469d4028c..668d76579 100644 --- a/geg/other/test.go +++ b/geg/other/test.go @@ -2,13 +2,17 @@ package main import ( "fmt" - "gitee.com/johng/gf/g/os/gtime" ) +type T struct { + +} func main() { - s := ` -172.20.1.198 - - [2018-11-06T16:26:09+08:00] "POST /passport HTTP/1.1" "OK" 1 200 0.000 0.035 0.035 0.035 448 "-" "-" "-" "{\x22jsonrpc\x22:\x222.0\x22,\x22method\x22:\x22getSessionInfo\x22,\x22params\x22:[\x2262703819__6augmxzV9f5c7o4MEimnMqPhoyKWPi8pXjs2VIj3T43vBfuGZOJ9DxrbRNsFB0ew\x22,true,{\x22platform\x22:\x22web-ph\x22}],\x22id\x22:1}" http unix:/var/run/php/php5.6-fpm.sock med3-svr [med3-svr-65494945bf-jppth] "" "" "" [med3-svr-65494945bf-jppth] -` + var i interface{} + i = "s" + i = make([]string, 100) - fmt.Println(gtime.ParseTimeFromContent(s)) + if i == "s" { + fmt.Println(1) + } } \ No newline at end of file