improve logging feature for ghttp.Server

This commit is contained in:
John
2019-11-08 19:52:49 +08:00
parent 21efde1a38
commit 8f2c62d444
11 changed files with 92 additions and 61 deletions

View File

@ -1,12 +1,17 @@
package main
import (
"bytes"
"fmt"
"regexp"
)
func main() {
replaceCharReg, err := regexp.Compile(`[\-\.\_\s]+`)
//b := make([]byte, 10)
r := bytes.NewBuffer(make([]byte, 1))
n, err := r.Write([]byte("12345"))
fmt.Println(n)
fmt.Println(err)
fmt.Println(replaceCharReg.ReplaceAllString("s--s.s.a b", ""))
fmt.Println(r.String())
}

View File

@ -48,7 +48,6 @@ type (
routesMap map[string][]registeredRouteItem // 已经注册的路由及对应的注册方法文件地址(用以路由重复注册判断)
statusHandlerMap map[string]HandlerFunc // 不同状态码下的注册处理方法(例如404状态时的处理方法)
sessionManager *gsession.Manager // Session管理器
logger *glog.Logger // 日志管理对象
}
// 路由对象
@ -223,7 +222,6 @@ func GetServer(name ...interface{}) *Server {
serveCache: gcache.New(),
routesMap: make(map[string][]registeredRouteItem),
servedCount: gtype.NewInt(),
logger: glog.New(),
}
// 初始化时使用默认配置
if err := s.SetConfig(c); err != nil {
@ -245,14 +243,19 @@ func (s *Server) Start() error {
// 当前Web Server状态判断
if s.Status() == SERVER_STATUS_RUNNING {
return errors.New("server is already running")
return errors.New("[ghttp] server is already running")
}
// 没有注册任何路由,且没有开启文件服务,那么提示错误
if len(s.routesMap) == 0 && !s.config.FileServerEnabled {
glog.Fatal("[ghttp] There's no route set or static feature enabled, did you forget import the router?")
return errors.New(`[ghttp] there's no route set or static feature enabled, did you forget import the router?`)
}
// Logging.
if s.config.LogPath != "" {
if err := s.config.Logger.SetPath(s.config.LogPath); err != nil {
return errors.New(fmt.Sprintf("[ghttp] set log path '%s' error: %v", s.config.LogPath, err))
}
}
// Default session storage.
if s.config.SessionStorage == nil {
path := ""
@ -260,7 +263,7 @@ func (s *Server) Start() error {
path = gfile.Join(s.config.SessionPath, s.name)
if !gfile.Exists(path) {
if err := gfile.Mkdir(path); err != nil {
glog.Fatalf("mkdir failed for '%s': %v", path, err)
return errors.New(fmt.Sprintf("[ghttp] mkdir failed for '%s': %v", path, err))
}
}
}
@ -421,7 +424,7 @@ func (s *Server) Run() {
// 阻塞等待服务执行完成
<-s.closeChan
glog.Printf("%d: all servers shutdown", gproc.Pid())
glog.Printf("[ghttp] %d: all servers shutdown", gproc.Pid())
}
// 阻塞等待所有Web Server停止常用于多Web Server场景以及需要将Web Server异步运行的场景
@ -430,7 +433,7 @@ func Wait() {
// 阻塞等待服务执行完成
<-allDoneChan
glog.Printf("%d: all servers shutdown", gproc.Pid())
glog.Printf("[ghttp] %d: all servers shutdown", gproc.Pid())
}
// 开启底层Web Server执行

View File

@ -32,9 +32,6 @@ const (
URI_TYPE_CAMEL = 3 // 采用驼峰命名方式
)
// LogHandler is the log handler function type.
type LogHandler func(r *Request, err ...error)
// HTTP Server configuration.
type ServerConfig struct {
Address string // Server listening address like ":port", multiple addresses separated using ','
@ -67,8 +64,8 @@ type ServerConfig struct {
DenyIps []string // Security: 不允许访问的ip列表支持ip前缀过滤如: 10 将不允许10开头的ip访问
AllowIps []string // Security: 仅允许访问的ip列表支持ip前缀过滤如: 10 将仅允许10开头的ip访问
DenyRoutes []string // Security: 不允许访问的路由规则列表
Logger *glog.Logger // Logging: Custom logger for server.
LogPath string // Logging: 存放日志的目录路径(默认为空,表示不写文件)
LogHandler LogHandler // Logging: 日志配置: 自定义日志处理回调方法(默认为空)
LogStdout bool // Logging: 是否打印日志到终端(默认开启)
ErrorStack bool // Logging: 当产生错误时打印调用链详细堆栈
ErrorLogEnabled bool // Logging: 是否开启error log(默认开启)
@ -106,6 +103,7 @@ var defaultServerConfig = ServerConfig{
SessionMaxAge: time.Hour * 24,
SessionIdName: "gfsessionid",
SessionPath: gsession.DefaultStorageFilePath,
Logger: glog.New(),
LogStdout: true,
ErrorStack: true,
ErrorLogEnabled: true,
@ -139,10 +137,6 @@ func (s *Server) SetConfig(c ServerConfig) error {
c.Handler = http.HandlerFunc(s.defaultHttpHandle)
}
s.config = c
// Logging.
if c.LogPath != "" {
return s.logger.SetPath(c.LogPath)
}
// HTTPS.
if c.TLSConfig == nil && c.HTTPSCertPath != "" {
s.EnableHTTPS(c.HTTPSCertPath, c.HTTPSKeyPath)

View File

@ -7,9 +7,6 @@
package ghttp
// 设置日志目录,只有在设置了日志目录的情况下才会输出日志到日志文件中。
// 日志文件路径格式为:
// 1. 请求日志: access/YYYY-MM-DD.log
// 2. 错误日志: error/YYYY-MM-DD.log
func (s *Server) SetLogPath(path string) {
if len(path) == 0 {
return
@ -17,7 +14,6 @@ func (s *Server) SetLogPath(path string) {
s.config.LogPath = path
s.config.ErrorLogEnabled = true
s.config.AccessLogEnabled = true
s.logger.SetPath(path)
}
// 设置日志内容是否输出到终端,默认情况下只有错误日志才会自动输出到终端。
@ -41,16 +37,6 @@ func (s *Server) SetErrorStack(enabled bool) {
s.config.ErrorStack = enabled
}
// 设置日志写入的回调函数
func (s *Server) SetLogHandler(handler LogHandler) {
s.config.LogHandler = handler
}
// 获取日志写入的回调函数
func (s *Server) GetLogHandler() LogHandler {
return s.config.LogHandler
}
// 获取日志目录
func (s *Server) GetLogPath() string {
return s.config.LogPath

View File

@ -46,7 +46,7 @@ func (s *Server) SetServerRoot(root string) {
realPath := root
if !gres.Contains(realPath) {
if p, err := gfile.Search(root); err != nil {
glog.Fatal(fmt.Sprintf(`[ghttp] SetServerRoot failed: %s`, err.Error()))
glog.Fatal(fmt.Sprintf(`[ghttp] SetServerRoot failed: %v`, err))
} else {
realPath = p
}
@ -61,7 +61,7 @@ func (s *Server) AddSearchPath(path string) {
realPath := path
if !gres.Contains(realPath) {
if p, err := gfile.Search(path); err != nil {
glog.Fatal(fmt.Sprintf(`[ghttp] AddSearchPath failed: %s`, err.Error()))
glog.Fatal(fmt.Sprintf(`[ghttp] AddSearchPath failed: %v`, err))
} else {
realPath = p
}
@ -75,7 +75,7 @@ func (s *Server) AddStaticPath(prefix string, path string) {
realPath := path
if !gres.Contains(realPath) {
if p, err := gfile.Search(path); err != nil {
glog.Fatal(fmt.Sprintf(`[ghttp] AddStaticPath failed: %s`, err.Error()))
glog.Fatal(fmt.Sprintf(`[ghttp] AddStaticPath failed: %v`, err))
} else {
realPath = p
}

View File

@ -54,7 +54,7 @@ func (s *Server) newHttpServer(itemFunc string) *http.Server {
WriteTimeout: s.config.WriteTimeout,
IdleTimeout: s.config.IdleTimeout,
MaxHeaderBytes: s.config.MaxHeaderBytes,
ErrorLog: log.New(&errorLogger{logger: s.logger}, "", 0),
ErrorLog: log.New(&errorLogger{logger: s.config.Logger}, "", 0),
}
server.SetKeepAlivesEnabled(s.config.KeepAlive)
return server

View File

@ -23,11 +23,6 @@ func (s *Server) handleAccessLog(r *Request) {
if !s.IsAccessLogEnabled() {
return
}
// 自定义错误处理
if v := s.GetLogHandler(); v != nil {
v(r)
return
}
scheme := "http"
if r.TLS != nil {
scheme = "https"
@ -38,7 +33,7 @@ func (s *Server) handleAccessLog(r *Request) {
)
content += fmt.Sprintf(` %.3f`, float64(r.LeaveTime-r.EnterTime)/1000)
content += fmt.Sprintf(`, %s, "%s", "%s"`, r.GetClientIp(), r.Referer(), r.UserAgent())
s.logger.File(s.config.AccessLogPattern).StackWithFilter(gPATH_FILTER_KEY).Stdout(s.config.LogStdout).Println(content)
s.config.Logger.File(s.config.AccessLogPattern).StackWithFilter(gPATH_FILTER_KEY).Stdout(s.config.LogStdout).Println(content)
}
// 处理服务错误信息主要是panichttp请求的status由access log进行管理
@ -48,12 +43,6 @@ func (s *Server) handleErrorLog(err error, r *Request) {
return
}
// 自定义错误处理
if v := s.GetLogHandler(); v != nil {
v(r, err)
return
}
// 错误日志信息
scheme := "http"
if r.TLS != nil {
@ -71,5 +60,5 @@ func (s *Server) handleErrorLog(err error, r *Request) {
content += "\n" + stack
}
}
s.logger.File(s.config.AccessLogPattern).Stack(false).Stdout(s.config.LogStdout).Error(content)
s.config.Logger.File(s.config.AccessLogPattern).Stack(false).Stdout(s.config.LogStdout).Error(content)
}

View File

@ -70,7 +70,6 @@ func Letters(n int) string {
b[i] = letters[Intn(52)]
}
return string(b)
}
// Perm returns, as a slice of n int numbers, a pseudo-random permutation of the integers [0,n).

View File

@ -9,6 +9,8 @@
package grand_test
import (
"crypto/rand"
"encoding/binary"
"testing"
"github.com/gogf/gf/util/grand"
@ -22,10 +24,10 @@ func Benchmark_Rand(b *testing.B) {
}
}
//func Benchmark_Buffer(b *testing.B) {
// for i := 0; i < b.N; i++ {
// if _, err := rand.Read(buffer); err == nil {
// binary.LittleEndian.Uint64(buffer)
// }
// }
//}
func Benchmark_Buffer(b *testing.B) {
for i := 0; i < b.N; i++ {
if _, err := rand.Read(buffer); err == nil {
binary.LittleEndian.Uint64(buffer)
}
}
}

View File

@ -0,0 +1,56 @@
// Copyright 2019 gf Author(https://github.com/gogf/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://github.com/gogf/gf.
// go test *.go -bench=".*" -benchmem
package guuid_test
import (
"github.com/gogf/gf/util/guuid"
"testing"
)
func Benchmark_New(b *testing.B) {
for i := 0; i < b.N; i++ {
guuid.New()
}
}
func Benchmark_NewUUID(b *testing.B) {
for i := 0; i < b.N; i++ {
guuid.NewUUID()
}
}
func Benchmark_NewDCEGroup(b *testing.B) {
for i := 0; i < b.N; i++ {
guuid.NewDCEGroup()
}
}
func Benchmark_NewDCEPerson(b *testing.B) {
for i := 0; i < b.N; i++ {
guuid.NewDCEPerson()
}
}
func Benchmark_NewRandom(b *testing.B) {
for i := 0; i < b.N; i++ {
guuid.NewRandom()
}
}
func Benchmark_NewMD5(b *testing.B) {
for i := 0; i < b.N; i++ {
guuid.NewMD5(guuid.UUID{}, []byte(""))
}
}
func Benchmark_NewSHA1(b *testing.B) {
for i := 0; i < b.N; i++ {
guuid.NewSHA1(guuid.UUID{}, []byte(""))
}
}

View File

@ -29,9 +29,6 @@ func Test_Basic(t *testing.T) {
uuid, _ = guuid.NewRandom()
gtest.Assert(len(uuid.String()), 36)
uuid, _ = guuid.NewRandom()
gtest.Assert(len(uuid.String()), 36)
gtest.Assert(len(guuid.NewMD5(guuid.UUID{}, []byte("")).String()), 36)
gtest.Assert(len(guuid.NewSHA1(guuid.UUID{}, []byte("")).String()), 36)
})