refract package ghttp/gredis/glog

This commit is contained in:
John Guo 2021-09-27 21:27:24 +08:00
parent 5904a1e7c0
commit df09d8c604
87 changed files with 922 additions and 1174 deletions

View File

@ -679,9 +679,9 @@ func (c *Core) writeSqlToLogger(ctx context.Context, sql *Sql) {
s := fmt.Sprintf("[%3d ms] [%s] %s%s", sql.End-sql.Start, sql.Group, transactionIdStr, sql.Format)
if sql.Error != nil {
s += "\nError: " + sql.Error.Error()
c.logger.Ctx(ctx).Error(s)
c.logger.Error(ctx, s)
} else {
c.logger.Ctx(ctx).Debug(s)
c.logger.Debug(ctx, s)
}
}

View File

@ -17,9 +17,6 @@ type Adapter interface {
// Note that you should call Close function manually if you do not use this connection any further.
Conn(ctx context.Context) (conn Conn, err error)
// Config returns the configuration that used in current redis object.
Config(ctx context.Context) (config *Config, err error)
// Close closes current redis client, closes its connection pool and releases all its related resources.
Close(ctx context.Context) (err error)
}

View File

@ -50,11 +50,6 @@ func NewAdapterGoRedis(config *Config) *AdapterGoRedis {
}
}
// Config returns the configuration that used in current redis object.
func (r *AdapterGoRedis) Config(ctx context.Context) (config *Config, err error) {
return r.config, nil
}
// Close closes the redis connection pool, which will release all connections reserved by this pool.
// It is commonly not necessary to call Close manually.
func (r *AdapterGoRedis) Close(ctx context.Context) error {

View File

@ -22,7 +22,6 @@ type localAdapterGoRedisConn struct {
// Do sends a command to the server and returns the received reply.
// It uses json.Marshal for struct/slice/map type values before committing them to redis.
func (c *localAdapterGoRedisConn) Do(ctx context.Context, command string, args ...interface{}) (reply *gvar.Var, err error) {
switch gstr.ToLower(command) {
case `subscribe`:
c.ps = c.redis.client.Subscribe(ctx, gconv.Strings(args)...)

View File

@ -1,31 +0,0 @@
// Copyright GoFrame Author(https://goframe.org). 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.
package gredis
import "github.com/go-redis/redis/v8"
// localAdapterGoRedisPoolStats is statistics of redis connection pool.
type localAdapterGoRedisPoolStats struct {
*redis.PoolStats
}
// ActiveCount is the number of connections in the pool. The count includes
// idle connections and connections in use.
func (s *localAdapterGoRedisPoolStats) ActiveCount() int64 {
if s == nil {
return -1
}
return int64(s.PoolStats.TotalConns)
}
// IdleCount is the number of idle connections in the pool.
func (s *localAdapterGoRedisPoolStats) IdleCount() int64 {
if s == nil {
return -1
}
return int64(s.PoolStats.IdleConns)
}

View File

@ -56,10 +56,10 @@ func (c *RedisConn) addTracingItem(ctx context.Context, item *tracingItem) {
span.SetAttributes(gtrace.CommonLabels()...)
if config, _ := c.redis.adapter.Config(ctx); config == nil {
if adapter, ok := c.redis.GetAdapter().(*AdapterGoRedis); ok {
span.SetAttributes(
attribute.String(tracingAttrRedisAddress, config.Address),
attribute.Int(tracingAttrRedisDb, config.Db),
attribute.String(tracingAttrRedisAddress, adapter.config.Address),
attribute.Int(tracingAttrRedisDb, adapter.config.Db),
)
}

View File

@ -60,7 +60,7 @@ func Example_newFromStructWithTag() {
Score: 100,
Title: "engineer",
}
// The parameter <tags> specifies custom priority tags for struct conversion to map,
// The parameter `tags` specifies custom priority tags for struct conversion to map,
// multiple tags joined with char ','.
j := gjson.NewWithTag(me, "tag")
fmt.Println(j.Get("name"))

View File

@ -138,16 +138,10 @@ func (r *Request) doParse(pointer interface{}, requestType int) error {
// Get is alias of GetRequest, which is one of the most commonly used functions for
// retrieving parameter.
// See r.GetRequest.
func (r *Request) Get(key string, def ...interface{}) interface{} {
func (r *Request) Get(key string, def ...interface{}) *gvar.Var {
return r.GetRequest(key, def...)
}
// GetVar is alis of GetRequestVar.
// See GetRequestVar.
func (r *Request) GetVar(key string, def ...interface{}) *gvar.Var {
return r.GetRequestVar(key, def...)
}
// GetRaw is alias of GetBody.
// See GetBody.
// Deprecated, use GetBody instead.
@ -184,96 +178,6 @@ func (r *Request) GetJson() (*gjson.Json, error) {
return gjson.LoadJson(r.GetBody())
}
// GetString is an alias and convenient function for GetRequestString.
// See GetRequestString.
func (r *Request) GetString(key string, def ...interface{}) string {
return r.GetRequestString(key, def...)
}
// GetBool is an alias and convenient function for GetRequestBool.
// See GetRequestBool.
func (r *Request) GetBool(key string, def ...interface{}) bool {
return r.GetRequestBool(key, def...)
}
// GetInt is an alias and convenient function for GetRequestInt.
// See GetRequestInt.
func (r *Request) GetInt(key string, def ...interface{}) int {
return r.GetRequestInt(key, def...)
}
// GetInt32 is an alias and convenient function for GetRequestInt32.
// See GetRequestInt32.
func (r *Request) GetInt32(key string, def ...interface{}) int32 {
return r.GetRequestInt32(key, def...)
}
// GetInt64 is an alias and convenient function for GetRequestInt64.
// See GetRequestInt64.
func (r *Request) GetInt64(key string, def ...interface{}) int64 {
return r.GetRequestInt64(key, def...)
}
// GetInts is an alias and convenient function for GetRequestInts.
// See GetRequestInts.
func (r *Request) GetInts(key string, def ...interface{}) []int {
return r.GetRequestInts(key, def...)
}
// GetUint is an alias and convenient function for GetRequestUint.
// See GetRequestUint.
func (r *Request) GetUint(key string, def ...interface{}) uint {
return r.GetRequestUint(key, def...)
}
// GetUint32 is an alias and convenient function for GetRequestUint32.
// See GetRequestUint32.
func (r *Request) GetUint32(key string, def ...interface{}) uint32 {
return r.GetRequestUint32(key, def...)
}
// GetUint64 is an alias and convenient function for GetRequestUint64.
// See GetRequestUint64.
func (r *Request) GetUint64(key string, def ...interface{}) uint64 {
return r.GetRequestUint64(key, def...)
}
// GetFloat32 is an alias and convenient function for GetRequestFloat32.
// See GetRequestFloat32.
func (r *Request) GetFloat32(key string, def ...interface{}) float32 {
return r.GetRequestFloat32(key, def...)
}
// GetFloat64 is an alias and convenient function for GetRequestFloat64.
// See GetRequestFloat64.
func (r *Request) GetFloat64(key string, def ...interface{}) float64 {
return r.GetRequestFloat64(key, def...)
}
// GetFloats is an alias and convenient function for GetRequestFloats.
// See GetRequestFloats.
func (r *Request) GetFloats(key string, def ...interface{}) []float64 {
return r.GetRequestFloats(key, def...)
}
// GetArray is an alias and convenient function for GetRequestArray.
// See GetRequestArray.
func (r *Request) GetArray(key string, def ...interface{}) []string {
return r.GetRequestArray(key, def...)
}
// GetStrings is an alias and convenient function for GetRequestStrings.
// See GetRequestStrings.
func (r *Request) GetStrings(key string, def ...interface{}) []string {
return r.GetRequestStrings(key, def...)
}
// GetInterfaces is an alias and convenient function for GetRequestInterfaces.
// See GetRequestInterfaces.
func (r *Request) GetInterfaces(key string, def ...interface{}) []interface{} {
return r.GetRequestInterfaces(key, def...)
}
// GetMap is an alias and convenient function for GetRequestMap.
// See GetRequestMap.
func (r *Request) GetMap(def ...map[string]interface{}) map[string]interface{} {

View File

@ -22,115 +22,19 @@ func (r *Request) SetForm(key string, value interface{}) {
// GetForm retrieves and returns parameter <key> from form.
// It returns <def> if <key> does not exist in the form and <def> is given, or else it returns nil.
func (r *Request) GetForm(key string, def ...interface{}) interface{} {
func (r *Request) GetForm(key string, def ...interface{}) *gvar.Var {
r.parseForm()
if len(r.formMap) > 0 {
if v, ok := r.formMap[key]; ok {
return v
return gvar.New(v)
}
}
if len(def) > 0 {
return def[0]
return gvar.New(def[0])
}
return nil
}
// GetFormVar retrieves and returns parameter <key> from form as Var.
// It returns <def> if <key> does not exist in the form and <def> is given, or else it returns nil.
func (r *Request) GetFormVar(key string, def ...interface{}) *gvar.Var {
return gvar.New(r.GetForm(key, def...))
}
// GetFormString retrieves and returns parameter <key> from form as string.
// It returns <def> if <key> does not exist in the form and <def> is given, or else it returns nil.
func (r *Request) GetFormString(key string, def ...interface{}) string {
return r.GetFormVar(key, def...).String()
}
// GetFormBool retrieves and returns parameter <key> from form as bool.
// It returns <def> if <key> does not exist in the form and <def> is given, or else it returns nil.
func (r *Request) GetFormBool(key string, def ...interface{}) bool {
return r.GetFormVar(key, def...).Bool()
}
// GetFormInt retrieves and returns parameter <key> from form as int.
// It returns <def> if <key> does not exist in the form and <def> is given, or else it returns nil.
func (r *Request) GetFormInt(key string, def ...interface{}) int {
return r.GetFormVar(key, def...).Int()
}
// GetFormInt32 retrieves and returns parameter <key> from form as int32.
// It returns <def> if <key> does not exist in the form and <def> is given, or else it returns nil.
func (r *Request) GetFormInt32(key string, def ...interface{}) int32 {
return r.GetFormVar(key, def...).Int32()
}
// GetFormInt64 retrieves and returns parameter <key> from form as int64.
// It returns <def> if <key> does not exist in the form and <def> is given, or else it returns nil.
func (r *Request) GetFormInt64(key string, def ...interface{}) int64 {
return r.GetFormVar(key, def...).Int64()
}
// GetFormInts retrieves and returns parameter <key> from form as []int.
// It returns <def> if <key> does not exist in the form and <def> is given, or else it returns nil.
func (r *Request) GetFormInts(key string, def ...interface{}) []int {
return r.GetFormVar(key, def...).Ints()
}
// GetFormUint retrieves and returns parameter <key> from form as uint.
// It returns <def> if <key> does not exist in the form and <def> is given, or else it returns nil.
func (r *Request) GetFormUint(key string, def ...interface{}) uint {
return r.GetFormVar(key, def...).Uint()
}
// GetFormUint32 retrieves and returns parameter <key> from form as uint32.
// It returns <def> if <key> does not exist in the form and <def> is given, or else it returns nil.
func (r *Request) GetFormUint32(key string, def ...interface{}) uint32 {
return r.GetFormVar(key, def...).Uint32()
}
// GetFormUint64 retrieves and returns parameter <key> from form as uint64.
// It returns <def> if <key> does not exist in the form and <def> is given, or else it returns nil.
func (r *Request) GetFormUint64(key string, def ...interface{}) uint64 {
return r.GetFormVar(key, def...).Uint64()
}
// GetFormFloat32 retrieves and returns parameter <key> from form as float32.
// It returns <def> if <key> does not exist in the form and <def> is given, or else it returns nil.
func (r *Request) GetFormFloat32(key string, def ...interface{}) float32 {
return r.GetFormVar(key, def...).Float32()
}
// GetFormFloat64 retrieves and returns parameter <key> from form as float64.
// It returns <def> if <key> does not exist in the form and <def> is given, or else it returns nil.
func (r *Request) GetFormFloat64(key string, def ...interface{}) float64 {
return r.GetFormVar(key, def...).Float64()
}
// GetFormFloats retrieves and returns parameter <key> from form as []float64.
// It returns <def> if <key> does not exist in the form and <def> is given, or else it returns nil.
func (r *Request) GetFormFloats(key string, def ...interface{}) []float64 {
return r.GetFormVar(key, def...).Floats()
}
// GetFormArray retrieves and returns parameter <key> from form as []string.
// It returns <def> if <key> does not exist in the form and <def> is given, or else it returns nil.
func (r *Request) GetFormArray(key string, def ...interface{}) []string {
return r.GetFormVar(key, def...).Strings()
}
// GetFormStrings retrieves and returns parameter <key> from form as []string.
// It returns <def> if <key> does not exist in the form and <def> is given, or else it returns nil.
func (r *Request) GetFormStrings(key string, def ...interface{}) []string {
return r.GetFormVar(key, def...).Strings()
}
// GetFormInterfaces retrieves and returns parameter <key> from form as []interface{}.
// It returns <def> if <key> does not exist in the form and <def> is given, or else it returns nil.
func (r *Request) GetFormInterfaces(key string, def ...interface{}) []interface{} {
return r.GetFormVar(key, def...).Interfaces()
}
// GetFormMap retrieves and returns all form parameters passed from client as map.
// The parameter <kvMap> specifies the keys retrieving from client parameters,
// the associated values are the default values if the client does not pass.
@ -158,10 +62,10 @@ func (r *Request) GetFormMap(kvMap ...map[string]interface{}) map[string]interfa
// The parameter <kvMap> specifies the keys retrieving from client parameters, the associated values
// are the default values if the client does not pass.
func (r *Request) GetFormMapStrStr(kvMap ...map[string]interface{}) map[string]string {
postMap := r.GetFormMap(kvMap...)
if len(postMap) > 0 {
m := make(map[string]string, len(postMap))
for k, v := range postMap {
formMap := r.GetFormMap(kvMap...)
if len(formMap) > 0 {
m := make(map[string]string, len(formMap))
for k, v := range formMap {
m[k] = gconv.String(v)
}
return m
@ -173,10 +77,10 @@ func (r *Request) GetFormMapStrStr(kvMap ...map[string]interface{}) map[string]s
// The parameter <kvMap> specifies the keys retrieving from client parameters, the associated values
// are the default values if the client does not pass.
func (r *Request) GetFormMapStrVar(kvMap ...map[string]interface{}) map[string]*gvar.Var {
postMap := r.GetFormMap(kvMap...)
if len(postMap) > 0 {
m := make(map[string]*gvar.Var, len(postMap))
for k, v := range postMap {
formMap := r.GetFormMap(kvMap...)
if len(formMap) > 0 {
m := make(map[string]*gvar.Var, len(formMap))
for k, v := range formMap {
m[k] = gvar.New(v)
}
return m

View File

@ -67,5 +67,5 @@ func (r *Request) GetPage(totalSize, pageSize int) *gpage.Page {
urlTemplate += "?" + url.RawQuery
}
return gpage.New(totalSize, pageSize, r.GetInt(gpage.DefaultPageName), urlTemplate)
return gpage.New(totalSize, pageSize, r.Get(gpage.DefaultPageName).Int(), urlTemplate)
}

View File

@ -19,19 +19,12 @@ func (r *Request) SetParam(key string, value interface{}) {
// GetParam returns custom parameter with given name <key>.
// It returns <def> if <key> does not exist.
// It returns nil if <def> is not passed.
func (r *Request) GetParam(key string, def ...interface{}) interface{} {
func (r *Request) GetParam(key string, def ...interface{}) *gvar.Var {
if r.paramsMap != nil {
return r.paramsMap[key]
return gvar.New(r.paramsMap[key])
}
if len(def) > 0 {
return def[0]
return gvar.New(def[0])
}
return nil
}
// GetParamVar returns custom parameter with given name <key> as gvar.Var.
// It returns <def> if <key> does not exist.
// It returns nil if <def> is not passed.
func (r *Request) GetParamVar(key string, def ...interface{}) *gvar.Var {
return gvar.New(r.GetParam(key, def...))
}

View File

@ -27,11 +27,11 @@ func (r *Request) SetQuery(key string, value interface{}) {
//
// Note that if there are multiple parameters with the same name, the parameters are retrieved
// and overwrote in order of priority: query > body.
func (r *Request) GetQuery(key string, def ...interface{}) interface{} {
func (r *Request) GetQuery(key string, def ...interface{}) *gvar.Var {
r.parseQuery()
if len(r.queryMap) > 0 {
if v, ok := r.queryMap[key]; ok {
return v
return gvar.New(v)
}
}
if r.Method == "GET" {
@ -39,79 +39,15 @@ func (r *Request) GetQuery(key string, def ...interface{}) interface{} {
}
if len(r.bodyMap) > 0 {
if v, ok := r.bodyMap[key]; ok {
return v
return gvar.New(v)
}
}
if len(def) > 0 {
return def[0]
return gvar.New(def[0])
}
return nil
}
func (r *Request) GetQueryVar(key string, def ...interface{}) *gvar.Var {
return gvar.New(r.GetQuery(key, def...))
}
func (r *Request) GetQueryString(key string, def ...interface{}) string {
return r.GetQueryVar(key, def...).String()
}
func (r *Request) GetQueryBool(key string, def ...interface{}) bool {
return r.GetQueryVar(key, def...).Bool()
}
func (r *Request) GetQueryInt(key string, def ...interface{}) int {
return r.GetQueryVar(key, def...).Int()
}
func (r *Request) GetQueryInt32(key string, def ...interface{}) int32 {
return r.GetQueryVar(key, def...).Int32()
}
func (r *Request) GetQueryInt64(key string, def ...interface{}) int64 {
return r.GetQueryVar(key, def...).Int64()
}
func (r *Request) GetQueryInts(key string, def ...interface{}) []int {
return r.GetQueryVar(key, def...).Ints()
}
func (r *Request) GetQueryUint(key string, def ...interface{}) uint {
return r.GetQueryVar(key, def...).Uint()
}
func (r *Request) GetQueryUint32(key string, def ...interface{}) uint32 {
return r.GetQueryVar(key, def...).Uint32()
}
func (r *Request) GetQueryUint64(key string, def ...interface{}) uint64 {
return r.GetQueryVar(key, def...).Uint64()
}
func (r *Request) GetQueryFloat32(key string, def ...interface{}) float32 {
return r.GetQueryVar(key, def...).Float32()
}
func (r *Request) GetQueryFloat64(key string, def ...interface{}) float64 {
return r.GetQueryVar(key, def...).Float64()
}
func (r *Request) GetQueryFloats(key string, def ...interface{}) []float64 {
return r.GetQueryVar(key, def...).Floats()
}
func (r *Request) GetQueryArray(key string, def ...interface{}) []string {
return r.GetQueryVar(key, def...).Strings()
}
func (r *Request) GetQueryStrings(key string, def ...interface{}) []string {
return r.GetQueryVar(key, def...).Strings()
}
func (r *Request) GetQueryInterfaces(key string, def ...interface{}) []interface{} {
return r.GetQueryVar(key, def...).Interfaces()
}
// GetQueryMap retrieves and returns all parameters passed from client using HTTP GET method
// as map. The parameter <kvMap> specifies the keys retrieving from client parameters,
// the associated values are the default values if the client does not pass.

View File

@ -22,7 +22,7 @@ import (
//
// Note that if there are multiple parameters with the same name, the parameters are
// retrieved and overwrote in order of priority: router < query < body < form < custom.
func (r *Request) GetRequest(key string, def ...interface{}) interface{} {
func (r *Request) GetRequest(key string, def ...interface{}) *gvar.Var {
value := r.GetParam(key)
if value == nil {
value = r.GetForm(key)
@ -30,134 +30,24 @@ func (r *Request) GetRequest(key string, def ...interface{}) interface{} {
if value == nil {
r.parseBody()
if len(r.bodyMap) > 0 {
value = r.bodyMap[key]
if v := r.bodyMap[key]; v != nil {
value = gvar.New(v)
}
}
}
if value == nil {
value = r.GetQuery(key)
}
if value == nil {
value = r.GetRouterValue(key)
value = r.GetRouter(key)
}
if value != nil {
return value
}
if len(def) > 0 {
return def[0]
return gvar.New(def[0])
}
return value
}
// GetRequestVar retrieves and returns the parameter named <key> passed from client and
// custom params as gvar.Var, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestVar(key string, def ...interface{}) *gvar.Var {
return gvar.New(r.GetRequest(key, def...))
}
// GetRequestString retrieves and returns the parameter named <key> passed from client and
// custom params as string, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestString(key string, def ...interface{}) string {
return r.GetRequestVar(key, def...).String()
}
// GetRequestBool retrieves and returns the parameter named <key> passed from client and
// custom params as bool, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestBool(key string, def ...interface{}) bool {
return r.GetRequestVar(key, def...).Bool()
}
// GetRequestInt retrieves and returns the parameter named <key> passed from client and
// custom params as int, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestInt(key string, def ...interface{}) int {
return r.GetRequestVar(key, def...).Int()
}
// GetRequestInt32 retrieves and returns the parameter named <key> passed from client and
// custom params as int32, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestInt32(key string, def ...interface{}) int32 {
return r.GetRequestVar(key, def...).Int32()
}
// GetRequestInt64 retrieves and returns the parameter named <key> passed from client and
// custom params as int64, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestInt64(key string, def ...interface{}) int64 {
return r.GetRequestVar(key, def...).Int64()
}
// GetRequestInts retrieves and returns the parameter named <key> passed from client and
// custom params as []int, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestInts(key string, def ...interface{}) []int {
return r.GetRequestVar(key, def...).Ints()
}
// GetRequestUint retrieves and returns the parameter named <key> passed from client and
// custom params as uint, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestUint(key string, def ...interface{}) uint {
return r.GetRequestVar(key, def...).Uint()
}
// GetRequestUint32 retrieves and returns the parameter named <key> passed from client and
// custom params as uint32, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestUint32(key string, def ...interface{}) uint32 {
return r.GetRequestVar(key, def...).Uint32()
}
// GetRequestUint64 retrieves and returns the parameter named <key> passed from client and
// custom params as uint64, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestUint64(key string, def ...interface{}) uint64 {
return r.GetRequestVar(key, def...).Uint64()
}
// GetRequestFloat32 retrieves and returns the parameter named <key> passed from client and
// custom params as float32, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestFloat32(key string, def ...interface{}) float32 {
return r.GetRequestVar(key, def...).Float32()
}
// GetRequestFloat64 retrieves and returns the parameter named <key> passed from client and
// custom params as float64, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestFloat64(key string, def ...interface{}) float64 {
return r.GetRequestVar(key, def...).Float64()
}
// GetRequestFloats retrieves and returns the parameter named <key> passed from client and
// custom params as []float64, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestFloats(key string, def ...interface{}) []float64 {
return r.GetRequestVar(key, def...).Floats()
}
// GetRequestArray retrieves and returns the parameter named <key> passed from client and
// custom params as []string, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestArray(key string, def ...interface{}) []string {
return r.GetRequestVar(key, def...).Strings()
}
// GetRequestStrings retrieves and returns the parameter named <key> passed from client and
// custom params as []string, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestStrings(key string, def ...interface{}) []string {
return r.GetRequestVar(key, def...).Strings()
}
// GetRequestInterfaces retrieves and returns the parameter named <key> passed from client
// and custom params as []interface{}, no matter what HTTP method the client is using. The
// parameter <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestInterfaces(key string, def ...interface{}) []interface{} {
return r.GetRequestVar(key, def...).Interfaces()
return nil
}
// GetRequestMap retrieves and returns all parameters passed from client and custom params
@ -173,7 +63,9 @@ func (r *Request) GetRequestMap(kvMap ...map[string]interface{}) map[string]inte
r.parseQuery()
r.parseForm()
r.parseBody()
var ok, filter bool
var (
ok, filter bool
)
var length int
if len(kvMap) > 0 && kvMap[0] != nil {
length = len(kvMap[0])

View File

@ -20,28 +20,16 @@ func (r *Request) GetRouterMap() map[string]string {
return nil
}
// GetRouterValue retrieves and returns the router value with given key name <key>.
// GetRouter retrieves and returns the router value with given key name <key>.
// It returns <def> if <key> does not exist.
func (r *Request) GetRouterValue(key string, def ...interface{}) interface{} {
func (r *Request) GetRouter(key string, def ...interface{}) *gvar.Var {
if r.routerMap != nil {
if v, ok := r.routerMap[key]; ok {
return v
return gvar.New(v)
}
}
if len(def) > 0 {
return def[0]
return gvar.New(def[0])
}
return nil
}
// GetRouterVar retrieves and returns the router value as gvar.Var with given key name <key>.
// It returns <def> if <key> does not exist.
func (r *Request) GetRouterVar(key string, def ...interface{}) *gvar.Var {
return gvar.New(r.GetRouterValue(key, def...))
}
// GetRouterString retrieves and returns the router value as string with given key name <key>.
// It returns <def> if <key> does not exist.
func (r *Request) GetRouterString(key string, def ...interface{}) string {
return r.GetRouterVar(key, def...).String()
}

View File

@ -82,7 +82,7 @@ func (r *Response) buildInVars(params ...map[string]interface{}) map[string]inte
gutil.MapMerge(m, params[0])
}
// Retrieve custom template variables from request object.
sessionMap := gconv.MapDeep(r.Request.Session.Map())
sessionMap := gconv.MapDeep(r.Request.Session.MustData())
gutil.MapMerge(m, map[string]interface{}{
"Form": r.Request.GetFormMap(),
"Query": r.Request.GetQueryMap(),

View File

@ -147,7 +147,7 @@ func (r *Response) WriteJsonP(content interface{}) error {
return err
} else {
//r.Header().Set("Content-Type", "application/json")
if callback := r.Request.GetString("callback"); callback != "" {
if callback := r.Request.Get("callback").String(); callback != "" {
buffer := []byte(callback)
buffer = append(buffer, byte('('))
buffer = append(buffer, b...)

View File

@ -52,6 +52,9 @@ func SetGraceful(enabled bool) {
// serverProcessInit initializes some process configurations, which can only be done once.
func serverProcessInit() {
var (
ctx = context.TODO()
)
if !serverProcessInitialized.Cas(false, true) {
return
}
@ -62,7 +65,7 @@ func serverProcessInit() {
p.Kill()
p.Wait()
} else {
glog.Error(e)
glog.Error(ctx, e)
}
}
@ -72,10 +75,10 @@ func serverProcessInit() {
// Process message handler.
// It's enabled only graceful feature is enabled.
if gracefulEnabled {
intlog.Printf(context.TODO(), "%d: graceful reload feature is enabled", gproc.Pid())
intlog.Printf(ctx, "%d: graceful reload feature is enabled", gproc.Pid())
go handleProcessMessage()
} else {
intlog.Printf(context.TODO(), "%d: graceful reload feature is disabled", gproc.Pid())
intlog.Printf(ctx, "%d: graceful reload feature is disabled", gproc.Pid())
}
// It's an ugly calling for better initializing the main package path
@ -118,8 +121,12 @@ func GetServer(name ...interface{}) *Server {
// Start starts listening on configured port.
// This function does not block the process, you can use function Wait blocking the process.
func (s *Server) Start() error {
var (
ctx = context.TODO()
)
// Register group routes.
s.handlePreBindItems()
s.handlePreBindItems(ctx)
// Server process initialization, which can only be initialized once.
serverProcessInit()
@ -167,11 +174,11 @@ func (s *Server) Start() error {
// Install external plugins.
for _, p := range s.plugins {
if err := p.Install(s); err != nil {
s.Logger().Fatal(err)
s.Logger().Fatal(ctx, err)
}
}
// Check the group routes again.
s.handlePreBindItems()
s.handlePreBindItems(ctx)
// If there's no route registered and no static service enabled,
// it then returns an error of invalid usage of server.
@ -210,6 +217,9 @@ func (s *Server) Start() error {
// DumpRouterMap dumps the router map to the log.
func (s *Server) dumpRouterMap() {
var (
ctx = context.TODO()
)
if s.config.DumpRouterMap && len(s.routesMap) > 0 {
buffer := bytes.NewBuffer(nil)
table := tablewriter.NewWriter(buffer)
@ -230,7 +240,7 @@ func (s *Server) dumpRouterMap() {
table.Append(data)
}
table.Render()
s.config.Logger.Header(false).Printf("\n%s", buffer.String())
s.config.Logger.Header(false).Printf(ctx, "\n%s", buffer.String())
}
}
@ -312,8 +322,11 @@ func (s *Server) GetRouterArray() []RouterItem {
// Run starts server listening in blocking way.
// It's commonly used for single server situation.
func (s *Server) Run() {
var (
ctx = context.TODO()
)
if err := s.Start(); err != nil {
s.Logger().Fatal(err)
s.Logger().Fatal(ctx, err)
}
// Blocking using channel.
<-s.closeChan
@ -326,30 +339,38 @@ func (s *Server) Run() {
}
}
}
s.Logger().Printf("%d: all servers shutdown", gproc.Pid())
s.Logger().Printf(ctx, "%d: all servers shutdown", gproc.Pid())
}
// Wait blocks to wait for all servers done.
// It's commonly used in multiple servers situation.
func Wait() {
var (
ctx = context.TODO()
)
<-allDoneChan
// Remove plugins.
serverMapping.Iterator(func(k string, v interface{}) bool {
s := v.(*Server)
if len(s.plugins) > 0 {
for _, p := range s.plugins {
intlog.Printf(context.TODO(), `remove plugin: %s`, p.Name())
p.Remove()
intlog.Printf(ctx, `remove plugin: %s`, p.Name())
if err := p.Remove(); err != nil {
intlog.Error(ctx, err)
}
}
}
return true
})
glog.Printf("%d: all servers shutdown", gproc.Pid())
glog.Printf(ctx, "%d: all servers shutdown", gproc.Pid())
}
// startServer starts the underlying server listening.
func (s *Server) startServer(fdMap listenerFdMap) {
var httpsEnabled bool
var (
ctx = context.TODO()
httpsEnabled bool
)
// HTTPS
if s.config.TLSConfig != nil || (s.config.HTTPSCertPath != "" && s.config.HTTPSKeyPath != "") {
if len(s.config.HTTPSAddr) == 0 {
@ -376,7 +397,7 @@ func (s *Server) startServer(fdMap listenerFdMap) {
array := strings.Split(v, "#")
if len(array) > 1 {
itemFunc = array[0]
// The windows OS does not support socket file descriptor passing
// The Windows OS does not support socket file descriptor passing
// from parent process.
if runtime.GOOS != "windows" {
fd = gconv.Int(array[1])
@ -409,7 +430,7 @@ func (s *Server) startServer(fdMap listenerFdMap) {
array := strings.Split(v, "#")
if len(array) > 1 {
itemFunc = array[0]
// The windows OS does not support socket file descriptor passing
// The Windows OS does not support socket file descriptor passing
// from parent process.
if runtime.GOOS != "windows" {
fd = gconv.Int(array[1])
@ -434,7 +455,7 @@ func (s *Server) startServer(fdMap listenerFdMap) {
}
// The process exits if the server is closed with none closing error.
if err != nil && !strings.EqualFold(http.ErrServerClosed.Error(), err.Error()) {
s.Logger().Fatal(err)
s.Logger().Fatal(ctx, err)
}
// If all the underlying servers shutdown, the process exits.
if s.serverCount.Add(-1) < 1 {

View File

@ -7,6 +7,7 @@
package ghttp
import (
"context"
"github.com/gogf/gf/os/gfile"
"strings"
"time"
@ -44,16 +45,19 @@ func (p *utilAdmin) Index(r *Request) {
// Restart restarts all the servers in the process.
func (p *utilAdmin) Restart(r *Request) {
var err error = nil
var (
ctx = r.Context()
err error
)
// Custom start binary path when this process exits.
path := r.GetQueryString("newExeFilePath")
path := r.GetQuery("newExeFilePath").String()
if path == "" {
path = gfile.SelfPath()
}
if len(path) > 0 {
err = RestartAllServer(path)
err = RestartAllServer(ctx, path)
} else {
err = RestartAllServer()
err = RestartAllServer(ctx)
}
if err == nil {
r.Response.WriteExit("server restarted")
@ -84,10 +88,13 @@ func (s *Server) EnableAdmin(pattern ...string) {
// Shutdown shuts down current server.
func (s *Server) Shutdown() error {
var (
ctx = context.TODO()
)
// Only shut down current servers.
// It may have multiple underlying http servers.
for _, v := range s.servers {
v.close()
v.close(ctx)
}
return nil
}

View File

@ -40,18 +40,20 @@ const (
adminGProcCommGroup = "GF_GPROC_HTTP_SERVER"
)
// serverActionLocker is the locker for server administration operations.
var serverActionLocker sync.Mutex
var (
// serverActionLocker is the locker for server administration operations.
serverActionLocker sync.Mutex
// serverActionLastTime is timestamp in milliseconds of last administration operation.
var serverActionLastTime = gtype.NewInt64(gtime.TimestampMilli())
// serverActionLastTime is timestamp in milliseconds of last administration operation.
serverActionLastTime = gtype.NewInt64(gtime.TimestampMilli())
// serverProcessStatus is the server status for operation of current process.
var serverProcessStatus = gtype.NewInt()
// serverProcessStatus is the server status for operation of current process.
serverProcessStatus = gtype.NewInt()
)
// RestartAllServer restarts all the servers of the process.
// The optional parameter <newExeFilePath> specifies the new binary file for creating process.
func RestartAllServer(newExeFilePath ...string) error {
func RestartAllServer(ctx context.Context, newExeFilePath ...string) error {
if !gracefulEnabled {
return gerror.NewCode(gcode.CodeInvalidOperation, "graceful reload feature is disabled")
}
@ -63,11 +65,11 @@ func RestartAllServer(newExeFilePath ...string) error {
if err := checkActionFrequency(); err != nil {
return err
}
return restartWebServers("", newExeFilePath...)
return restartWebServers(ctx, "", newExeFilePath...)
}
// ShutdownAllServer shuts down all servers of current process.
func ShutdownAllServer() error {
func ShutdownAllServer(ctx context.Context) error {
serverActionLocker.Lock()
defer serverActionLocker.Unlock()
if err := checkProcessStatus(); err != nil {
@ -76,7 +78,7 @@ func ShutdownAllServer() error {
if err := checkActionFrequency(); err != nil {
return err
}
shutdownWebServers()
shutdownWebServers(ctx)
return nil
}
@ -111,8 +113,10 @@ func checkActionFrequency() error {
}
// forkReloadProcess creates a new child process and copies the fd to child process.
func forkReloadProcess(newExeFilePath ...string) error {
path := os.Args[0]
func forkReloadProcess(ctx context.Context, newExeFilePath ...string) error {
var (
path = os.Args[0]
)
if len(newExeFilePath) > 0 {
path = newExeFilePath[0]
}
@ -141,24 +145,36 @@ func forkReloadProcess(newExeFilePath ...string) error {
buffer, _ := gjson.Encode(sfm)
p.Env = append(p.Env, adminActionReloadEnvKey+"="+string(buffer))
if _, err := p.Start(); err != nil {
glog.Errorf("%d: fork process failed, error:%s, %s", gproc.Pid(), err.Error(), string(buffer))
glog.Errorf(
ctx,
"%d: fork process failed, error:%s, %s",
gproc.Pid(), err.Error(), string(buffer),
)
return err
}
return nil
}
// forkRestartProcess creates a new server process.
func forkRestartProcess(newExeFilePath ...string) error {
path := os.Args[0]
func forkRestartProcess(ctx context.Context, newExeFilePath ...string) error {
var (
path = os.Args[0]
)
if len(newExeFilePath) > 0 {
path = newExeFilePath[0]
}
os.Unsetenv(adminActionReloadEnvKey)
if err := os.Unsetenv(adminActionReloadEnvKey); err != nil {
intlog.Error(ctx, err)
}
env := os.Environ()
env = append(env, adminActionRestartEnvKey+"=1")
p := gproc.NewProcess(path, os.Args, env)
if _, err := p.Start(); err != nil {
glog.Errorf(`%d: fork process failed, error:%s, are you running using "go run"?`, gproc.Pid(), err.Error())
glog.Errorf(
ctx,
`%d: fork process failed, error:%s, are you running using "go run"?`,
gproc.Pid(), err.Error(),
)
return err
}
return nil
@ -192,76 +208,79 @@ func bufferToServerFdMap(buffer []byte) map[string]listenerFdMap {
}
// restartWebServers restarts all servers.
func restartWebServers(signal string, newExeFilePath ...string) error {
func restartWebServers(ctx context.Context, signal string, newExeFilePath ...string) error {
serverProcessStatus.Set(adminActionRestarting)
if runtime.GOOS == "windows" {
if len(signal) > 0 {
// Controlled by signal.
forceCloseWebServers()
forkRestartProcess(newExeFilePath...)
forceCloseWebServers(ctx)
if err := forkRestartProcess(ctx, newExeFilePath...); err != nil {
intlog.Error(ctx, err)
}
} else {
// Controlled by web page.
// It should ensure the response wrote to client and then close all servers gracefully.
gtimer.SetTimeout(time.Second, func() {
forceCloseWebServers()
forkRestartProcess(newExeFilePath...)
forceCloseWebServers(ctx)
if err := forkRestartProcess(ctx, newExeFilePath...); err != nil {
intlog.Error(ctx, err)
}
})
}
} else {
if err := forkReloadProcess(newExeFilePath...); err != nil {
glog.Printf("%d: server restarts failed", gproc.Pid())
if err := forkReloadProcess(ctx, newExeFilePath...); err != nil {
glog.Printf(ctx, "%d: server restarts failed", gproc.Pid())
serverProcessStatus.Set(adminActionNone)
return err
} else {
if len(signal) > 0 {
glog.Printf("%d: server restarting by signal: %s", gproc.Pid(), signal)
glog.Printf(ctx, "%d: server restarting by signal: %s", gproc.Pid(), signal)
} else {
glog.Printf("%d: server restarting by web admin", gproc.Pid())
glog.Printf(ctx, "%d: server restarting by web admin", gproc.Pid())
}
}
}
return nil
}
// shutdownWebServers shuts down all servers.
func shutdownWebServers(signal ...string) {
func shutdownWebServers(ctx context.Context, signal ...string) {
serverProcessStatus.Set(adminActionShuttingDown)
if len(signal) > 0 {
glog.Printf("%d: server shutting down by signal: %s", gproc.Pid(), signal[0])
forceCloseWebServers()
glog.Printf(ctx, "%d: server shutting down by signal: %s", gproc.Pid(), signal[0])
forceCloseWebServers(ctx)
allDoneChan <- struct{}{}
} else {
glog.Printf("%d: server shutting down by api", gproc.Pid())
glog.Printf(ctx, "%d: server shutting down by api", gproc.Pid())
gtimer.SetTimeout(time.Second, func() {
forceCloseWebServers()
forceCloseWebServers(ctx)
allDoneChan <- struct{}{}
})
}
}
// shutdownWebServersGracefully gracefully shuts down all servers.
func shutdownWebServersGracefully(signal ...string) {
func shutdownWebServersGracefully(ctx context.Context, signal ...string) {
if len(signal) > 0 {
glog.Printf("%d: server gracefully shutting down by signal: %s", gproc.Pid(), signal[0])
glog.Printf(ctx, "%d: server gracefully shutting down by signal: %s", gproc.Pid(), signal[0])
} else {
glog.Printf("%d: server gracefully shutting down by api", gproc.Pid())
glog.Printf(ctx, "%d: server gracefully shutting down by api", gproc.Pid())
}
serverMapping.RLockFunc(func(m map[string]interface{}) {
for _, v := range m {
for _, s := range v.(*Server).servers {
s.shutdown()
s.shutdown(ctx)
}
}
})
}
// forceCloseWebServers forced shuts down all servers.
func forceCloseWebServers() {
func forceCloseWebServers(ctx context.Context) {
serverMapping.RLockFunc(func(m map[string]interface{}) {
for _, v := range m {
for _, s := range v.(*Server).servers {
s.close()
s.close(ctx)
}
}
})
@ -270,13 +289,16 @@ func forceCloseWebServers() {
// handleProcessMessage receives and handles the message from processes,
// which are commonly used for graceful reloading feature.
func handleProcessMessage() {
var (
ctx = context.TODO()
)
for {
if msg := gproc.Receive(adminGProcCommGroup); msg != nil {
if bytes.EqualFold(msg.Data, []byte("exit")) {
intlog.Printf(context.TODO(), "%d: process message: exit", gproc.Pid())
shutdownWebServersGracefully()
intlog.Printf(ctx, "%d: process message: exit", gproc.Pid())
shutdownWebServersGracefully(ctx)
allDoneChan <- struct{}{}
intlog.Printf(context.TODO(), "%d: process message: exit done", gproc.Pid())
intlog.Printf(ctx, "%d: process message: exit done", gproc.Pid())
return
}
}

View File

@ -21,7 +21,10 @@ var procSignalChan = make(chan os.Signal)
// handleProcessSignal handles all signal from system.
func handleProcessSignal() {
var sig os.Signal
var (
ctx = context.TODO()
sig os.Signal
)
signal.Notify(
procSignalChan,
syscall.SIGINT,
@ -34,23 +37,23 @@ func handleProcessSignal() {
)
for {
sig = <-procSignalChan
intlog.Printf(context.TODO(), `signal received: %s`, sig.String())
intlog.Printf(ctx, `signal received: %s`, sig.String())
switch sig {
// Shutdown the servers.
case syscall.SIGINT, syscall.SIGQUIT, syscall.SIGKILL, syscall.SIGABRT:
shutdownWebServers(sig.String())
shutdownWebServers(ctx, sig.String())
return
// Shutdown the servers gracefully.
// Especially from K8S when running server in POD.
case syscall.SIGTERM:
shutdownWebServersGracefully(sig.String())
shutdownWebServersGracefully(ctx, sig.String())
return
// Restart the servers.
case syscall.SIGUSR1:
if err := restartWebServers(sig.String()); err != nil {
intlog.Error(context.TODO(), err)
if err := restartWebServers(ctx, sig.String()); err != nil {
intlog.Error(ctx, err)
}
return

View File

@ -9,7 +9,6 @@ package ghttp
import (
"context"
"crypto/tls"
"fmt"
"github.com/gogf/gf/internal/intlog"
"github.com/gogf/gf/os/gres"
"github.com/gogf/gf/util/gutil"
@ -388,6 +387,9 @@ func (s *Server) SetHTTPSPort(port ...int) {
// EnableHTTPS enables HTTPS with given certification and key files for the server.
// The optional parameter <tlsConfig> specifies custom TLS configuration.
func (s *Server) EnableHTTPS(certFile, keyFile string, tlsConfig ...*tls.Config) {
var (
ctx = context.TODO()
)
certFileRealPath := gfile.RealPath(certFile)
if certFileRealPath == "" {
certFileRealPath = gfile.RealPath(gfile.Pwd() + gfile.Separator + certFile)
@ -400,7 +402,7 @@ func (s *Server) EnableHTTPS(certFile, keyFile string, tlsConfig ...*tls.Config)
certFileRealPath = certFile
}
if certFileRealPath == "" {
s.Logger().Fatal(fmt.Sprintf(`EnableHTTPS failed: certFile "%s" does not exist`, certFile))
s.Logger().Fatalf(ctx, `EnableHTTPS failed: certFile "%s" does not exist`, certFile)
}
keyFileRealPath := gfile.RealPath(keyFile)
if keyFileRealPath == "" {
@ -414,7 +416,7 @@ func (s *Server) EnableHTTPS(certFile, keyFile string, tlsConfig ...*tls.Config)
keyFileRealPath = keyFile
}
if keyFileRealPath == "" {
s.Logger().Fatal(fmt.Sprintf(`EnableHTTPS failed: keyFile "%s" does not exist`, keyFile))
s.Logger().Fatal(ctx, `EnableHTTPS failed: keyFile "%s" does not exist`, keyFile)
}
s.config.HTTPSCertPath = certFileRealPath
s.config.HTTPSKeyPath = keyFileRealPath

View File

@ -9,7 +9,7 @@
package ghttp
import (
"fmt"
"context"
"strings"
"github.com/gogf/gf/os/gres"
@ -50,25 +50,31 @@ func (s *Server) SetFileServerEnabled(enabled bool) {
// SetServerRoot sets the document root for static service.
func (s *Server) SetServerRoot(root string) {
realPath := root
var (
ctx = context.TODO()
realPath = root
)
if !gres.Contains(realPath) {
if p, err := gfile.Search(root); err != nil {
s.Logger().Fatal(fmt.Sprintf(`SetServerRoot failed: %v`, err))
s.Logger().Fatal(ctx, `SetServerRoot failed: %v`, err)
} else {
realPath = p
}
}
s.Logger().Debug("SetServerRoot path:", realPath)
s.Logger().Debug(ctx, "SetServerRoot path:", realPath)
s.config.SearchPaths = []string{strings.TrimRight(realPath, gfile.Separator)}
s.config.FileServerEnabled = true
}
// AddSearchPath add searching directory path for static file service.
func (s *Server) AddSearchPath(path string) {
realPath := path
var (
ctx = context.TODO()
realPath = path
)
if !gres.Contains(realPath) {
if p, err := gfile.Search(path); err != nil {
s.Logger().Fatal(fmt.Sprintf(`AddSearchPath failed: %v`, err))
s.Logger().Fatalf(ctx, `AddSearchPath failed: %v`, err)
} else {
realPath = p
}
@ -79,10 +85,13 @@ func (s *Server) AddSearchPath(path string) {
// AddStaticPath sets the uri to static directory path mapping for static file service.
func (s *Server) AddStaticPath(prefix string, path string) {
realPath := path
var (
ctx = context.TODO()
realPath = path
)
if !gres.Contains(realPath) {
if p, err := gfile.Search(path); err != nil {
s.Logger().Fatal(fmt.Sprintf(`AddStaticPath failed: %v`, err))
s.Logger().Fatalf(ctx, `AddStaticPath failed: %v`, err)
} else {
realPath = p
}

View File

@ -7,6 +7,7 @@
package ghttp
import (
"github.com/gogf/gf/container/gvar"
"net/http"
"time"
)
@ -89,7 +90,7 @@ func (c *Cookie) Set(key, value string) {
)
}
// SetCookie sets cookie item given given domain, path and expiration age.
// SetCookie sets cookie item with given domain, path and expiration age.
// The optional parameter <httpOnly> specifies if the cookie item is only available in HTTP,
// which is usually empty.
func (c *Cookie) SetCookie(key, value, domain, path string, maxAge time.Duration, httpOnly ...bool) {
@ -123,7 +124,7 @@ func (c *Cookie) SetHttpCookie(httpCookie *http.Cookie) {
// GetSessionId retrieves and returns the session id from cookie.
func (c *Cookie) GetSessionId() string {
return c.Get(c.server.GetSessionIdName())
return c.Get(c.server.GetSessionIdName()).String()
}
// SetSessionId sets session id in the cookie.
@ -139,17 +140,17 @@ func (c *Cookie) SetSessionId(id string) {
// Get retrieves and returns the value with specified key.
// It returns <def> if specified key does not exist and <def> is given.
func (c *Cookie) Get(key string, def ...string) string {
func (c *Cookie) Get(key string, def ...string) *gvar.Var {
c.init()
if r, ok := c.data[key]; ok {
if r.Expires.IsZero() || r.Expires.After(time.Now()) {
return r.Value
return gvar.New(r.Value)
}
}
if len(def) > 0 {
return def[0]
return gvar.New(def[0])
}
return ""
return nil
}
// Remove deletes specified key and its value from cookie using default domain and path.

View File

@ -7,6 +7,7 @@
package ghttp
import (
"context"
"strings"
)
@ -34,9 +35,9 @@ func (d *Domain) BindHandler(pattern string, handler interface{}) {
}
}
func (d *Domain) doBindHandler(pattern string, funcInfo handlerFuncInfo, middleware []HandlerFunc, source string) {
func (d *Domain) doBindHandler(ctx context.Context, pattern string, funcInfo handlerFuncInfo, middleware []HandlerFunc, source string) {
for domain, _ := range d.domains {
d.server.doBindHandler(pattern+"@"+domain, funcInfo, middleware, source)
d.server.doBindHandler(ctx, pattern+"@"+domain, funcInfo, middleware, source)
}
}
@ -46,9 +47,9 @@ func (d *Domain) BindObject(pattern string, obj interface{}, methods ...string)
}
}
func (d *Domain) doBindObject(pattern string, obj interface{}, methods string, middleware []HandlerFunc, source string) {
func (d *Domain) doBindObject(ctx context.Context, pattern string, obj interface{}, methods string, middleware []HandlerFunc, source string) {
for domain, _ := range d.domains {
d.server.doBindObject(pattern+"@"+domain, obj, methods, middleware, source)
d.server.doBindObject(ctx, pattern+"@"+domain, obj, methods, middleware, source)
}
}
@ -59,11 +60,12 @@ func (d *Domain) BindObjectMethod(pattern string, obj interface{}, method string
}
func (d *Domain) doBindObjectMethod(
ctx context.Context,
pattern string, obj interface{}, method string,
middleware []HandlerFunc, source string,
) {
for domain, _ := range d.domains {
d.server.doBindObjectMethod(pattern+"@"+domain, obj, method, middleware, source)
d.server.doBindObjectMethod(ctx, pattern+"@"+domain, obj, method, middleware, source)
}
}
@ -73,9 +75,9 @@ func (d *Domain) BindObjectRest(pattern string, obj interface{}) {
}
}
func (d *Domain) doBindObjectRest(pattern string, obj interface{}, middleware []HandlerFunc, source string) {
func (d *Domain) doBindObjectRest(ctx context.Context, pattern string, obj interface{}, middleware []HandlerFunc, source string) {
for domain, _ := range d.domains {
d.server.doBindObjectRest(pattern+"@"+domain, obj, middleware, source)
d.server.doBindObjectRest(ctx, pattern+"@"+domain, obj, middleware, source)
}
}
@ -85,9 +87,9 @@ func (d *Domain) BindHookHandler(pattern string, hook string, handler HandlerFun
}
}
func (d *Domain) doBindHookHandler(pattern string, hook string, handler HandlerFunc, source string) {
func (d *Domain) doBindHookHandler(ctx context.Context, pattern string, hook string, handler HandlerFunc, source string) {
for domain, _ := range d.domains {
d.server.doBindHookHandler(pattern+"@"+domain, hook, handler, source)
d.server.doBindHookHandler(ctx, pattern+"@"+domain, hook, handler, source)
}
}

View File

@ -8,6 +8,7 @@ package ghttp
import (
"bytes"
"context"
"github.com/gogf/gf/os/glog"
)
@ -18,6 +19,6 @@ type errorLogger struct {
// Write implements the io.Writer interface.
func (l *errorLogger) Write(p []byte) (n int, err error) {
l.logger.Skip(1).Error(string(bytes.TrimRight(p, "\r\n")))
l.logger.Skip(1).Error(context.TODO(), string(bytes.TrimRight(p, "\r\n")))
return len(p), nil
}

View File

@ -73,7 +73,7 @@ func (s *gracefulServer) ListenAndServe() error {
}
s.listener = ln
s.rawListener = ln
return s.doServe()
return s.doServe(context.TODO())
}
// Fd retrieves and returns the file descriptor of current server.
@ -97,7 +97,10 @@ func (s *gracefulServer) setFd(fd int) {
// The parameter <certFile> and <keyFile> specify the necessary certification and key files for HTTPS.
// The optional parameter <tlsConfig> specifies the custom TLS configuration.
func (s *gracefulServer) ListenAndServeTLS(certFile, keyFile string, tlsConfig ...*tls.Config) error {
var config *tls.Config
var (
ctx = context.TODO()
config *tls.Config
)
if len(tlsConfig) > 0 && tlsConfig[0] != nil {
config = tlsConfig[0]
} else if s.httpServer.TLSConfig != nil {
@ -131,7 +134,7 @@ func (s *gracefulServer) ListenAndServeTLS(certFile, keyFile string, tlsConfig .
s.listener = tls.NewListener(ln, config)
s.rawListener = ln
return s.doServe()
return s.doServe(ctx)
}
// getProto retrieves and returns the proto string of current server.
@ -143,13 +146,14 @@ func (s *gracefulServer) getProto() string {
return proto
}
// doServe does staring the serving.
func (s *gracefulServer) doServe() error {
// doServe starts the serving.
func (s *gracefulServer) doServe(ctx context.Context) error {
action := "started"
if s.fd != 0 {
action = "reloaded"
}
s.server.Logger().Printf(
ctx,
"%d: %s server %s listening on [%s]",
gproc.Pid(), s.getProto(), action, s.address,
)
@ -182,12 +186,13 @@ func (s *gracefulServer) getNetListener() (net.Listener, error) {
}
// shutdown shuts down the server gracefully.
func (s *gracefulServer) shutdown() {
func (s *gracefulServer) shutdown(ctx context.Context) {
if s.status == ServerStatusStopped {
return
}
if err := s.httpServer.Shutdown(context.Background()); err != nil {
s.server.Logger().Errorf(
ctx,
"%d: %s server [%s] shutdown error: %v",
gproc.Pid(), s.getProto(), s.address, err,
)
@ -195,12 +200,13 @@ func (s *gracefulServer) shutdown() {
}
// close shuts down the server forcibly.
func (s *gracefulServer) close() {
func (s *gracefulServer) close(ctx context.Context) {
if s.status == ServerStatusStopped {
return
}
if err := s.httpServer.Close(); err != nil {
s.server.Logger().Errorf(
ctx,
"%d: %s server [%s] closed error: %v",
gproc.Pid(), s.getProto(), s.address, err,
)

View File

@ -184,8 +184,8 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// and SessionCookieOutput is enabled.
if s.config.SessionCookieOutput &&
request.Session.IsDirty() &&
request.Session.Id() != request.GetSessionId() {
request.Cookie.SetSessionId(request.Session.Id())
request.Session.MustId() != request.GetSessionId() {
request.Cookie.SetSessionId(request.Session.MustId())
}
// Output the cookie content to client.
request.Cookie.Flush()

View File

@ -20,9 +20,10 @@ func (s *Server) handleAccessLog(r *Request) {
if r.TLS != nil {
scheme = "https"
}
s.Logger().Ctx(r.Context()).File(s.config.AccessLogPattern).
s.Logger().File(s.config.AccessLogPattern).
Stdout(s.config.LogStdout).
Printf(
r.Context(),
`%d "%s %s %s %s %s" %.3f, %s, "%s", "%s"`,
r.Response.Status,
r.Method, scheme, r.Host, r.URL.String(), r.Proto,
@ -57,8 +58,7 @@ func (s *Server) handleErrorLog(err error, r *Request) {
} else {
content += ", " + err.Error()
}
s.Logger().Ctx(r.Context()).
File(s.config.ErrorLogPattern).
s.Logger().File(s.config.ErrorLogPattern).
Stdout(s.config.LogStdout).
Print(content)
Print(r.Context(), content)
}

View File

@ -7,6 +7,7 @@
package ghttp
import (
"github.com/gogf/gf/internal/intlog"
netpprof "net/http/pprof"
runpprof "runtime/pprof"
"strings"
@ -55,12 +56,15 @@ func (d *Domain) EnablePProf(pattern ...string) {
// Index shows the PProf index page.
func (p *utilPProf) Index(r *Request) {
profiles := runpprof.Profiles()
action := r.GetString("action")
data := map[string]interface{}{
"uri": strings.TrimRight(r.URL.Path, "/") + "/",
"profiles": profiles,
}
var (
ctx = r.Context()
profiles = runpprof.Profiles()
action = r.Get("action").String()
data = map[string]interface{}{
"uri": strings.TrimRight(r.URL.Path, "/") + "/",
"profiles": profiles,
}
)
if len(action) == 0 {
buffer, _ := gview.ParseContent(r.Context(), `
<html>
@ -87,7 +91,9 @@ func (p *utilPProf) Index(r *Request) {
}
for _, p := range profiles {
if p.Name() == action {
p.WriteTo(r.Response.Writer, r.GetRequestInt("debug"))
if err := p.WriteTo(r.Response.Writer, r.GetRequest("debug").Int()); err != nil {
intlog.Error(ctx, err)
}
break
}
}

View File

@ -7,6 +7,7 @@
package ghttp
import (
"context"
"fmt"
"github.com/gogf/gf/container/gtype"
"github.com/gogf/gf/errors/gcode"
@ -65,8 +66,8 @@ func (s *Server) parsePattern(pattern string) (domain, method, path string, err
// setHandler creates router item with given handler and pattern and registers the handler to the router tree.
// The router tree can be treated as a multilayer hash table, please refer to the comment in following codes.
// This function is called during server starts up, which cares little about the performance. What really cares
// is the well designed router storage structure for router searching when the request is under serving.
func (s *Server) setHandler(pattern string, handler *handlerItem) {
// is the well-designed router storage structure for router searching when the request is under serving.
func (s *Server) setHandler(ctx context.Context, pattern string, handler *handlerItem) {
handler.Id = handlerIdGenerator.Add(1)
if handler.Source == "" {
_, file, line := gdebug.CallerWithFilter(stackFilterKey)
@ -74,11 +75,11 @@ func (s *Server) setHandler(pattern string, handler *handlerItem) {
}
domain, method, uri, err := s.parsePattern(pattern)
if err != nil {
s.Logger().Fatal("invalid pattern:", pattern, err)
s.Logger().Fatal(ctx, "invalid pattern:", pattern, err)
return
}
if len(uri) == 0 || uri[0] != '/' {
s.Logger().Fatal("invalid pattern:", pattern, "URI should lead with '/'")
s.Logger().Fatal(ctx, "invalid pattern:", pattern, "URI should lead with '/'")
return
}
@ -89,6 +90,7 @@ func (s *Server) setHandler(pattern string, handler *handlerItem) {
case handlerTypeHandler, handlerTypeObject, handlerTypeController:
if item, ok := s.routesMap[routerKey]; ok {
s.Logger().Fatalf(
ctx,
`duplicated route registry "%s" at %s , already registered at %s`,
pattern, handler.Source, item[0].Source,
)

View File

@ -7,6 +7,7 @@
package ghttp
import (
"context"
"fmt"
"github.com/gogf/gf/debug/gdebug"
"reflect"
@ -55,7 +56,7 @@ var (
)
// handlePreBindItems is called when server starts, which does really route registering to the server.
func (s *Server) handlePreBindItems() {
func (s *Server) handlePreBindItems(ctx context.Context) {
if len(preBindItems) == 0 {
return
}
@ -70,7 +71,7 @@ func (s *Server) handlePreBindItems() {
if item.group.domain != nil && item.group.domain.server != s {
continue
}
item.group.doBindRoutersToServer(item)
item.group.doBindRoutersToServer(ctx, item)
item.bound = true
}
}
@ -153,10 +154,13 @@ func (g *RouterGroup) Clone() *RouterGroup {
// Bind does batch route registering feature for router group.
func (g *RouterGroup) Bind(items []GroupItem) *RouterGroup {
group := g.Clone()
var (
ctx = context.TODO()
group = g.Clone()
)
for _, item := range items {
if len(item) < 3 {
g.server.Logger().Fatalf("invalid router item: %s", item)
g.server.Logger().Fatalf(ctx, "invalid router item: %s", item)
}
bindType := gstr.ToUpper(gconv.String(item[0]))
switch bindType {
@ -288,7 +292,7 @@ func (g *RouterGroup) getPrefix() string {
}
// doBindRoutersToServer does really register for the group.
func (g *RouterGroup) doBindRoutersToServer(item *preBindItem) *RouterGroup {
func (g *RouterGroup) doBindRoutersToServer(ctx context.Context, item *preBindItem) *RouterGroup {
var (
bindType = item.bindType
pattern = item.pattern
@ -301,7 +305,7 @@ func (g *RouterGroup) doBindRoutersToServer(item *preBindItem) *RouterGroup {
if len(prefix) > 0 {
domain, method, path, err := g.server.parsePattern(pattern)
if err != nil {
g.server.Logger().Fatalf("invalid pattern: %s", pattern)
g.server.Logger().Fatalf(ctx, "invalid pattern: %s", pattern)
}
// If there is already a domain, unset the domain field in the pattern.
if g.domain != nil {
@ -330,63 +334,63 @@ func (g *RouterGroup) doBindRoutersToServer(item *preBindItem) *RouterGroup {
if reflect.ValueOf(object).Kind() == reflect.Func {
funcInfo, err := g.server.checkAndCreateFuncInfo(object, "", "", "")
if err != nil {
g.server.Logger().Error(err.Error())
g.server.Logger().Error(ctx, err.Error())
return g
}
if g.server != nil {
g.server.doBindHandler(pattern, funcInfo, g.middleware, source)
g.server.doBindHandler(ctx, pattern, funcInfo, g.middleware, source)
} else {
g.domain.doBindHandler(pattern, funcInfo, g.middleware, source)
g.domain.doBindHandler(ctx, pattern, funcInfo, g.middleware, source)
}
} else {
if len(extras) > 0 {
if g.server != nil {
if gstr.Contains(extras[0], ",") {
g.server.doBindObject(
pattern, object, extras[0], g.middleware, source,
ctx, pattern, object, extras[0], g.middleware, source,
)
} else {
g.server.doBindObjectMethod(
pattern, object, extras[0], g.middleware, source,
ctx, pattern, object, extras[0], g.middleware, source,
)
}
} else {
if gstr.Contains(extras[0], ",") {
g.domain.doBindObject(
pattern, object, extras[0], g.middleware, source,
ctx, pattern, object, extras[0], g.middleware, source,
)
} else {
g.domain.doBindObjectMethod(
pattern, object, extras[0], g.middleware, source,
ctx, pattern, object, extras[0], g.middleware, source,
)
}
}
} else {
// At last, it treats the `object` as Object registering type.
if g.server != nil {
g.server.doBindObject(pattern, object, "", g.middleware, source)
g.server.doBindObject(ctx, pattern, object, "", g.middleware, source)
} else {
g.domain.doBindObject(pattern, object, "", g.middleware, source)
g.domain.doBindObject(ctx, pattern, object, "", g.middleware, source)
}
}
}
case groupBindTypeRest:
if g.server != nil {
g.server.doBindObjectRest(pattern, object, g.middleware, source)
g.server.doBindObjectRest(ctx, pattern, object, g.middleware, source)
} else {
g.domain.doBindObjectRest(pattern, object, g.middleware, source)
g.domain.doBindObjectRest(ctx, pattern, object, g.middleware, source)
}
case groupBindTypeHook:
if h, ok := object.(HandlerFunc); ok {
if g.server != nil {
g.server.doBindHookHandler(pattern, extras[0], h, source)
g.server.doBindHookHandler(ctx, pattern, extras[0], h, source)
} else {
g.domain.doBindHookHandler(pattern, extras[0], h, source)
g.domain.doBindHookHandler(ctx, pattern, extras[0], h, source)
}
} else {
g.server.Logger().Fatalf("invalid hook handler for pattern: %s", pattern)
g.server.Logger().Fatalf(ctx, "invalid hook handler for pattern: %s", pattern)
}
}
return g

View File

@ -7,6 +7,7 @@
package ghttp
import (
"context"
"github.com/gogf/gf/debug/gdebug"
"net/http"
"reflect"
@ -14,11 +15,11 @@ import (
// BindHookHandler registers handler for specified hook.
func (s *Server) BindHookHandler(pattern string, hook string, handler HandlerFunc) {
s.doBindHookHandler(pattern, hook, handler, "")
s.doBindHookHandler(context.TODO(), pattern, hook, handler, "")
}
func (s *Server) doBindHookHandler(pattern string, hook string, handler HandlerFunc, source string) {
s.setHandler(pattern, &handlerItem{
func (s *Server) doBindHookHandler(ctx context.Context, pattern string, hook string, handler HandlerFunc, source string) {
s.setHandler(ctx, pattern, &handlerItem{
Type: handlerTypeHook,
Name: gdebug.FuncPath(handler),
Info: handlerFuncInfo{

View File

@ -7,6 +7,7 @@
package ghttp
import (
"context"
"github.com/gogf/gf/debug/gdebug"
"reflect"
)
@ -21,8 +22,11 @@ const (
// before or after service handler. The parameter <pattern> specifies what route pattern the middleware intercepts,
// which is usually a "fuzzy" pattern like "/:name", "/*any" or "/{field}".
func (s *Server) BindMiddleware(pattern string, handlers ...HandlerFunc) {
var (
ctx = context.TODO()
)
for _, handler := range handlers {
s.setHandler(pattern, &handlerItem{
s.setHandler(ctx, pattern, &handlerItem{
Type: handlerTypeMiddleware,
Name: gdebug.FuncPath(handler),
Info: handlerFuncInfo{
@ -37,8 +41,11 @@ func (s *Server) BindMiddleware(pattern string, handlers ...HandlerFunc) {
// Global middleware can be used standalone without service handler, which intercepts all dynamic requests
// before or after service handler.
func (s *Server) BindMiddlewareDefault(handlers ...HandlerFunc) {
var (
ctx = context.TODO()
)
for _, handler := range handlers {
s.setHandler(defaultMiddlewarePattern, &handlerItem{
s.setHandler(ctx, defaultMiddlewarePattern, &handlerItem{
Type: handlerTypeMiddleware,
Name: gdebug.FuncPath(handler),
Info: handlerFuncInfo{

View File

@ -8,6 +8,7 @@ package ghttp
import (
"bytes"
"context"
"github.com/gogf/gf/debug/gdebug"
"github.com/gogf/gf/errors/gcode"
"github.com/gogf/gf/errors/gerror"
@ -25,19 +26,22 @@ import (
// func(context.Context,TypeRequest) error
// func(context.Context,TypeRequest)(TypeResponse,error)
func (s *Server) BindHandler(pattern string, handler interface{}) {
var (
ctx = context.TODO()
)
funcInfo, err := s.checkAndCreateFuncInfo(handler, "", "", "")
if err != nil {
s.Logger().Error(err.Error())
s.Logger().Error(ctx, err.Error())
return
}
s.doBindHandler(pattern, funcInfo, nil, "")
s.doBindHandler(ctx, pattern, funcInfo, nil, "")
}
// doBindHandler registers a handler function to server with given pattern.
// The parameter <pattern> is like:
// /user/list, put:/user, delete:/user, post:/user@goframe.org
func (s *Server) doBindHandler(pattern string, funcInfo handlerFuncInfo, middleware []HandlerFunc, source string) {
s.setHandler(pattern, &handlerItem{
func (s *Server) doBindHandler(ctx context.Context, pattern string, funcInfo handlerFuncInfo, middleware []HandlerFunc, source string) {
s.setHandler(ctx, pattern, &handlerItem{
Name: gdebug.FuncPath(funcInfo.Func),
Type: handlerTypeHandler,
Info: funcInfo,
@ -47,9 +51,9 @@ func (s *Server) doBindHandler(pattern string, funcInfo handlerFuncInfo, middlew
}
// bindHandlerByMap registers handlers to server using map.
func (s *Server) bindHandlerByMap(m map[string]*handlerItem) {
func (s *Server) bindHandlerByMap(ctx context.Context, m map[string]*handlerItem) {
for p, h := range m {
s.setHandler(p, h)
s.setHandler(ctx, p, h)
}
}

View File

@ -7,6 +7,7 @@
package ghttp
import (
"context"
"fmt"
"reflect"
"strings"
@ -19,36 +20,40 @@ import (
// BindObject registers object to server routes with given pattern.
//
// The optional parameter <method> is used to specify the method to be registered, which
// supports multiple method names, multiple methods are separated by char ',', case sensitive.
// supports multiple method names, multiple methods are separated by char ',', case-sensitive.
//
// Note that the route method should be defined as ghttp.HandlerFunc.
func (s *Server) BindObject(pattern string, object interface{}, method ...string) {
bindMethod := ""
var (
bindMethod = ""
)
if len(method) > 0 {
bindMethod = method[0]
}
s.doBindObject(pattern, object, bindMethod, nil, "")
s.doBindObject(context.TODO(), pattern, object, bindMethod, nil, "")
}
// BindObjectMethod registers specified method of object to server routes with given pattern.
//
// The optional parameter <method> is used to specify the method to be registered, which
// does not supports multiple method names but only one, case sensitive.
// does not supports multiple method names but only one, case-sensitive.
//
// Note that the route method should be defined as ghttp.HandlerFunc.
func (s *Server) BindObjectMethod(pattern string, object interface{}, method string) {
s.doBindObjectMethod(pattern, object, method, nil, "")
s.doBindObjectMethod(context.TODO(), pattern, object, method, nil, "")
}
// BindObjectRest registers object in REST API style to server with specified pattern.
// Note that the route method should be defined as ghttp.HandlerFunc.
func (s *Server) BindObjectRest(pattern string, object interface{}) {
s.doBindObjectRest(pattern, object, nil, "")
s.doBindObjectRest(context.TODO(), pattern, object, nil, "")
}
func (s *Server) doBindObject(pattern string, object interface{}, method string, middleware []HandlerFunc, source string) {
func (s *Server) doBindObject(ctx context.Context, pattern string, object interface{}, method string, middleware []HandlerFunc, source string) {
// Convert input method to map for convenience and high performance searching purpose.
var methodMap map[string]bool
var (
methodMap map[string]bool
)
if len(method) > 0 {
methodMap = make(map[string]bool)
for _, v := range strings.Split(method, ",") {
@ -59,7 +64,7 @@ func (s *Server) doBindObject(pattern string, object interface{}, method string,
// it removes for convenience for next statement control.
domain, method, path, err := s.parsePattern(pattern)
if err != nil {
s.Logger().Fatal(err)
s.Logger().Fatal(ctx, err)
return
}
if strings.EqualFold(method, defaultMethod) {
@ -104,7 +109,7 @@ func (s *Server) doBindObject(pattern string, object interface{}, method string,
funcInfo, err := s.checkAndCreateFuncInfo(v.Method(i).Interface(), pkgPath, objName, methodName)
if err != nil {
s.Logger().Error(err.Error())
s.Logger().Error(ctx, err.Error())
return
}
@ -142,10 +147,10 @@ func (s *Server) doBindObject(pattern string, object interface{}, method string,
}
}
}
s.bindHandlerByMap(m)
s.bindHandlerByMap(ctx, m)
}
func (s *Server) doBindObjectMethod(pattern string, object interface{}, method string, middleware []HandlerFunc, source string) {
func (s *Server) doBindObjectMethod(ctx context.Context, pattern string, object interface{}, method string, middleware []HandlerFunc, source string) {
var (
m = make(map[string]*handlerItem)
v = reflect.ValueOf(object)
@ -165,7 +170,7 @@ func (s *Server) doBindObjectMethod(pattern string, object interface{}, method s
methodName := strings.TrimSpace(method)
methodValue := v.MethodByName(methodName)
if !methodValue.IsValid() {
s.Logger().Fatal("invalid method name: " + methodName)
s.Logger().Fatal(ctx, "invalid method name: "+methodName)
return
}
if v.MethodByName("Init").IsValid() {
@ -183,7 +188,7 @@ func (s *Server) doBindObjectMethod(pattern string, object interface{}, method s
funcInfo, err := s.checkAndCreateFuncInfo(methodValue.Interface(), pkgPath, objName, methodName)
if err != nil {
s.Logger().Error(err.Error())
s.Logger().Error(ctx, err.Error())
return
}
@ -198,10 +203,10 @@ func (s *Server) doBindObjectMethod(pattern string, object interface{}, method s
Source: source,
}
s.bindHandlerByMap(m)
s.bindHandlerByMap(ctx, m)
}
func (s *Server) doBindObjectRest(pattern string, object interface{}, middleware []HandlerFunc, source string) {
func (s *Server) doBindObjectRest(ctx context.Context, pattern string, object interface{}, middleware []HandlerFunc, source string) {
var (
m = make(map[string]*handlerItem)
v = reflect.ValueOf(object)
@ -238,7 +243,7 @@ func (s *Server) doBindObjectRest(pattern string, object interface{}, middleware
funcInfo, err := s.checkAndCreateFuncInfo(v.Method(i).Interface(), pkgPath, objName, methodName)
if err != nil {
s.Logger().Error(err.Error())
s.Logger().Error(ctx, err.Error())
return
}
@ -253,5 +258,5 @@ func (s *Server) doBindObjectRest(pattern string, object interface{}, middleware
Source: source,
}
}
s.bindHandlerByMap(m)
s.bindHandlerByMap(ctx, m)
}

View File

@ -21,13 +21,13 @@ func Test_Cookie(t *testing.T) {
p, _ := ports.PopRand()
s := g.Server(p)
s.BindHandler("/set", func(r *ghttp.Request) {
r.Cookie.Set(r.GetString("k"), r.GetString("v"))
r.Cookie.Set(r.Get("k").String(), r.Get("v").String())
})
s.BindHandler("/get", func(r *ghttp.Request) {
r.Response.Write(r.Cookie.Get(r.GetString("k")))
r.Response.Write(r.Cookie.Get(r.Get("k").String()))
})
s.BindHandler("/remove", func(r *ghttp.Request) {
r.Cookie.Remove(r.GetString("k"))
r.Cookie.Remove(r.Get("k").String())
})
s.SetPort(p)
s.SetDumpRouterMap(false)
@ -65,15 +65,15 @@ func Test_SetHttpCookie(t *testing.T) {
s := g.Server(p)
s.BindHandler("/set", func(r *ghttp.Request) {
r.Cookie.SetHttpCookie(&http.Cookie{
Name: r.GetString("k"),
Value: r.GetString("v"),
Name: r.Get("k").String(),
Value: r.Get("v").String(),
})
})
s.BindHandler("/get", func(r *ghttp.Request) {
r.Response.Write(r.Cookie.Get(r.GetString("k")))
r.Response.Write(r.Cookie.Get(r.Get("k").String()))
})
s.BindHandler("/remove", func(r *ghttp.Request) {
r.Cookie.Remove(r.GetString("k"))
r.Cookie.Remove(r.Get("k").String())
})
s.SetPort(p)
s.SetDumpRouterMap(false)

View File

@ -577,7 +577,7 @@ func Test_Hook_Middleware_Basic1(t *testing.T) {
}
func MiddlewareAuth(r *ghttp.Request) {
token := r.Get("token")
token := r.Get("token").String()
if token == "123456" {
r.Middleware.Next()
} else {

View File

@ -30,7 +30,7 @@ func Test_Params_File_Single(t *testing.T) {
r.Response.WriteExit("upload file cannot be empty")
}
if name, err := file.Save(dstDirPath, r.GetBool("randomlyRename")); err == nil {
if name, err := file.Save(dstDirPath, r.Get("randomlyRename").Bool()); err == nil {
r.Response.WriteExit(name)
}
r.Response.WriteExit("upload failed")
@ -84,7 +84,7 @@ func Test_Params_File_CustomName(t *testing.T) {
r.Response.WriteExit("upload file cannot be empty")
}
file.Filename = "my.txt"
if name, err := file.Save(dstDirPath, r.GetBool("randomlyRename")); err == nil {
if name, err := file.Save(dstDirPath, r.Get("randomlyRename").Bool()); err == nil {
r.Response.WriteExit(name)
}
r.Response.WriteExit("upload failed")
@ -120,7 +120,7 @@ func Test_Params_File_Batch(t *testing.T) {
if files == nil {
r.Response.WriteExit("upload file cannot be empty")
}
if names, err := files.Save(dstDirPath, r.GetBool("randomlyRename")); err == nil {
if names, err := files.Save(dstDirPath, r.Get("randomlyRename").Bool()); err == nil {
r.Response.WriteExit(gstr.Join(names, ","))
}
r.Response.WriteExit("upload failed")

View File

@ -38,22 +38,22 @@ func Test_Params_Basic(t *testing.T) {
r.Response.Write(r.GetQuery("slice"))
}
if r.GetQuery("bool") != nil {
r.Response.Write(r.GetQueryBool("bool"))
r.Response.Write(r.GetQuery("bool").Bool())
}
if r.GetQuery("float32") != nil {
r.Response.Write(r.GetQueryFloat32("float32"))
r.Response.Write(r.GetQuery("float32").Float32())
}
if r.GetQuery("float64") != nil {
r.Response.Write(r.GetQueryFloat64("float64"))
r.Response.Write(r.GetQuery("float64").Float64())
}
if r.GetQuery("int") != nil {
r.Response.Write(r.GetQueryInt("int"))
r.Response.Write(r.GetQuery("int").Int())
}
if r.GetQuery("uint") != nil {
r.Response.Write(r.GetQueryUint("uint"))
r.Response.Write(r.GetQuery("uint").Uint())
}
if r.GetQuery("string") != nil {
r.Response.Write(r.GetQueryString("string"))
r.Response.Write(r.GetQuery("string").String())
}
if r.GetQuery("map") != nil {
r.Response.Write(r.GetQueryMap()["map"].(map[string]interface{})["b"])
@ -71,22 +71,22 @@ func Test_Params_Basic(t *testing.T) {
r.Response.Write(r.Get("slice"))
}
if r.Get("bool") != nil {
r.Response.Write(r.GetBool("bool"))
r.Response.Write(r.Get("bool").Bool())
}
if r.Get("float32") != nil {
r.Response.Write(r.GetFloat32("float32"))
r.Response.Write(r.Get("float32").Float32())
}
if r.Get("float64") != nil {
r.Response.Write(r.GetFloat64("float64"))
r.Response.Write(r.Get("float64").Float64())
}
if r.Get("int") != nil {
r.Response.Write(r.GetInt("int"))
r.Response.Write(r.Get("int").Int())
}
if r.Get("uint") != nil {
r.Response.Write(r.GetUint("uint"))
r.Response.Write(r.Get("uint").Uint())
}
if r.Get("string") != nil {
r.Response.Write(r.GetString("string"))
r.Response.Write(r.Get("string").String())
}
if r.Get("map") != nil {
r.Response.Write(r.GetMap()["map"].(map[string]interface{})["b"])
@ -105,22 +105,22 @@ func Test_Params_Basic(t *testing.T) {
r.Response.Write(r.Get("slice"))
}
if r.Get("bool") != nil {
r.Response.Write(r.GetBool("bool"))
r.Response.Write(r.Get("bool").Bool())
}
if r.Get("float32") != nil {
r.Response.Write(r.GetFloat32("float32"))
r.Response.Write(r.Get("float32").Float32())
}
if r.Get("float64") != nil {
r.Response.Write(r.GetFloat64("float64"))
r.Response.Write(r.Get("float64").Float64())
}
if r.Get("int") != nil {
r.Response.Write(r.GetInt("int"))
r.Response.Write(r.Get("int").Int())
}
if r.Get("uint") != nil {
r.Response.Write(r.GetUint("uint"))
r.Response.Write(r.Get("uint").Uint())
}
if r.Get("string") != nil {
r.Response.Write(r.GetString("string"))
r.Response.Write(r.Get("string").String())
}
if r.Get("map") != nil {
r.Response.Write(r.GetMap()["map"].(map[string]interface{})["b"])
@ -138,22 +138,22 @@ func Test_Params_Basic(t *testing.T) {
r.Response.Write(r.Get("slice"))
}
if r.Get("bool") != nil {
r.Response.Write(r.GetBool("bool"))
r.Response.Write(r.Get("bool").Bool())
}
if r.Get("float32") != nil {
r.Response.Write(r.GetFloat32("float32"))
r.Response.Write(r.Get("float32").Float32())
}
if r.Get("float64") != nil {
r.Response.Write(r.GetFloat64("float64"))
r.Response.Write(r.Get("float64").Float64())
}
if r.Get("int") != nil {
r.Response.Write(r.GetInt("int"))
r.Response.Write(r.Get("int").Int())
}
if r.Get("uint") != nil {
r.Response.Write(r.GetUint("uint"))
r.Response.Write(r.Get("uint").Uint())
}
if r.Get("string") != nil {
r.Response.Write(r.GetString("string"))
r.Response.Write(r.Get("string").String())
}
if r.Get("map") != nil {
r.Response.Write(r.GetMap()["map"].(map[string]interface{})["b"])
@ -171,22 +171,22 @@ func Test_Params_Basic(t *testing.T) {
r.Response.Write(r.GetForm("slice"))
}
if r.Get("bool") != nil {
r.Response.Write(r.GetFormBool("bool"))
r.Response.Write(r.GetForm("bool").Bool())
}
if r.Get("float32") != nil {
r.Response.Write(r.GetFormFloat32("float32"))
r.Response.Write(r.GetForm("float32").Float32())
}
if r.Get("float64") != nil {
r.Response.Write(r.GetFormFloat64("float64"))
r.Response.Write(r.GetForm("float64").Float64())
}
if r.Get("int") != nil {
r.Response.Write(r.GetFormInt("int"))
r.Response.Write(r.GetForm("int").Int())
}
if r.Get("uint") != nil {
r.Response.Write(r.GetFormUint("uint"))
r.Response.Write(r.GetForm("uint").Uint())
}
if r.Get("string") != nil {
r.Response.Write(r.GetFormString("string"))
r.Response.Write(r.GetForm("string").String())
}
if r.Get("map") != nil {
r.Response.Write(r.GetFormMap()["map"].(map[string]interface{})["b"])

View File

@ -77,10 +77,10 @@ func Test_Router_Value(t *testing.T) {
p, _ := ports.PopRand()
s := g.Server(p)
s.BindHandler("/{hash}", func(r *ghttp.Request) {
r.Response.Write(r.GetRouterString("hash"))
r.Response.Write(r.GetRouter("hash").String())
})
s.BindHandler("/{hash}.{type}", func(r *ghttp.Request) {
r.Response.Write(r.GetRouterString("type"))
r.Response.Write(r.GetRouter("type").String())
})
s.BindHandler("/{hash}.{type}.map", func(r *ghttp.Request) {
r.Response.Write(r.GetRouterMap()["type"])

View File

@ -20,16 +20,16 @@ func Test_Session_Cookie(t *testing.T) {
p, _ := ports.PopRand()
s := g.Server(p)
s.BindHandler("/set", func(r *ghttp.Request) {
r.Session.Set(r.GetString("k"), r.GetString("v"))
r.Session.Set(r.Get("k").String(), r.Get("v").String())
})
s.BindHandler("/get", func(r *ghttp.Request) {
r.Response.Write(r.Session.Get(r.GetString("k")))
r.Response.Write(r.Session.Get(r.Get("k").String()))
})
s.BindHandler("/remove", func(r *ghttp.Request) {
r.Session.Remove(r.GetString("k"))
r.Session.Remove(r.Get("k").String())
})
s.BindHandler("/clear", func(r *ghttp.Request) {
r.Session.Clear()
r.Session.RemoveAll()
})
s.SetPort(p)
s.SetDumpRouterMap(false)
@ -67,16 +67,16 @@ func Test_Session_Header(t *testing.T) {
p, _ := ports.PopRand()
s := g.Server(p)
s.BindHandler("/set", func(r *ghttp.Request) {
r.Session.Set(r.GetString("k"), r.GetString("v"))
r.Session.Set(r.Get("k").String(), r.Get("v").String())
})
s.BindHandler("/get", func(r *ghttp.Request) {
r.Response.Write(r.Session.Get(r.GetString("k")))
r.Response.Write(r.Session.Get(r.Get("k").String()))
})
s.BindHandler("/remove", func(r *ghttp.Request) {
r.Session.Remove(r.GetString("k"))
r.Session.Remove(r.Get("k").String())
})
s.BindHandler("/clear", func(r *ghttp.Request) {
r.Session.Clear()
r.Session.RemoveAll()
})
s.SetPort(p)
s.SetDumpRouterMap(false)
@ -118,11 +118,11 @@ func Test_Session_StorageFile(t *testing.T) {
p, _ := ports.PopRand()
s := g.Server(p)
s.BindHandler("/set", func(r *ghttp.Request) {
r.Session.Set(r.GetString("k"), r.GetString("v"))
r.Response.Write(r.GetString("k"), "=", r.GetString("v"))
r.Session.Set(r.Get("k").String(), r.Get("v").String())
r.Response.Write(r.Get("k").String(), "=", r.Get("v").String())
})
s.BindHandler("/get", func(r *ghttp.Request) {
r.Response.Write(r.Session.Get(r.GetString("k")))
r.Response.Write(r.Session.Get(r.Get("k").String()))
})
s.SetPort(p)
s.SetDumpRouterMap(false)

View File

@ -20,29 +20,29 @@ func init() {
group.GET("/", func(r *ghttp.Request) {
r.Response.Writef(
"GET: query: %d, %s",
r.GetQueryInt("id"),
r.GetQueryString("name"),
r.GetQuery("id").Int(),
r.GetQuery("name").String(),
)
})
group.PUT("/", func(r *ghttp.Request) {
r.Response.Writef(
"PUT: form: %d, %s",
r.GetFormInt("id"),
r.GetFormString("name"),
r.GetForm("id").Int(),
r.GetForm("name").String(),
)
})
group.POST("/", func(r *ghttp.Request) {
r.Response.Writef(
"POST: form: %d, %s",
r.GetFormInt("id"),
r.GetFormString("name"),
r.GetForm("id").Int(),
r.GetForm("name").String(),
)
})
group.DELETE("/", func(r *ghttp.Request) {
r.Response.Writef(
"DELETE: form: %d, %s",
r.GetFormInt("id"),
r.GetFormString("name"),
r.GetForm("id").Int(),
r.GetForm("name").String(),
)
})
group.HEAD("/", func(r *ghttp.Request) {
@ -71,7 +71,7 @@ func init() {
r.Response.Writef(
"Content-Type: %s, id: %d",
r.Header.Get("Content-Type"),
r.GetInt("id"),
r.Get("id").Int(),
)
})
})

View File

@ -7,6 +7,7 @@
package gtcp
import (
"context"
"crypto/tls"
"github.com/gogf/gf/errors/gcode"
"github.com/gogf/gf/errors/gerror"
@ -74,7 +75,7 @@ func NewServerTLS(address string, tlsConfig *tls.Config, handler func(*Conn), na
func NewServerKeyCrt(address, crtFile, keyFile string, handler func(*Conn), name ...string) *Server {
s := NewServer(address, handler, name...)
if err := s.SetTLSKeyCrt(crtFile, keyFile); err != nil {
glog.Error(err)
glog.Error(context.TODO(), err)
}
return s
}
@ -116,9 +117,12 @@ func (s *Server) Close() error {
// Run starts running the TCP Server.
func (s *Server) Run() (err error) {
var (
ctx = context.TODO()
)
if s.handler == nil {
err = gerror.NewCode(gcode.CodeMissingConfiguration, "start running failed: socket handler not defined")
glog.Error(err)
glog.Error(ctx, err)
return
}
if s.tlsConfig != nil {
@ -127,21 +131,21 @@ func (s *Server) Run() (err error) {
s.listen, err = tls.Listen("tcp", s.address, s.tlsConfig)
s.mu.Unlock()
if err != nil {
glog.Error(err)
glog.Error(ctx, err)
return
}
} else {
// Normal Server
addr, err := net.ResolveTCPAddr("tcp", s.address)
if err != nil {
glog.Error(err)
glog.Error(ctx, err)
return err
}
s.mu.Lock()
s.listen, err = net.ListenTCP("tcp", addr)
s.mu.Unlock()
if err != nil {
glog.Error(err)
glog.Error(ctx, err)
return err
}
}

View File

@ -7,6 +7,7 @@
package gudp
import (
"context"
"github.com/gogf/gf/errors/gcode"
"github.com/gogf/gf/errors/gerror"
"net"
@ -78,19 +79,22 @@ func (s *Server) Close() error {
// Run starts listening UDP connection.
func (s *Server) Run() error {
var (
ctx = context.TODO()
)
if s.handler == nil {
err := gerror.NewCode(gcode.CodeMissingConfiguration, "start running failed: socket handler not defined")
glog.Error(err)
glog.Error(ctx, err)
return err
}
addr, err := net.ResolveUDPAddr("udp", s.address)
if err != nil {
glog.Error(err)
glog.Error(ctx, err)
return err
}
conn, err := net.ListenUDP("udp", addr)
if err != nil {
glog.Error(err)
glog.Error(ctx, err)
return err
}
s.conn = NewConnByNetConn(conn)

View File

@ -26,12 +26,12 @@ func Set(ctx context.Context, key interface{}, value interface{}, duration time.
return defaultCache.Set(ctx, key, value, duration)
}
// Sets batch sets cache with key-value pairs by `data` map, which is expired after `duration`.
// SetMap batch sets cache with key-value pairs by `data` map, which is expired after `duration`.
//
// It does not expire if `duration` == 0.
// It deletes the keys of `data` if `duration` < 0 or given `value` is nil.
func Sets(ctx context.Context, data map[interface{}]interface{}, duration time.Duration) error {
return defaultCache.Sets(ctx, data, duration)
func SetMap(ctx context.Context, data map[interface{}]interface{}, duration time.Duration) error {
return defaultCache.SetMap(ctx, data, duration)
}
// SetIfNotExist sets cache with `key`-`value` pair which is expired after `duration`

View File

@ -22,11 +22,11 @@ type Adapter interface {
// It deletes the keys of `data` if `duration` < 0 or given `value` is nil.
Set(ctx context.Context, key interface{}, value interface{}, duration time.Duration) error
// Sets batch sets cache with key-value pairs by `data` map, which is expired after `duration`.
// SetMap batch sets cache with key-value pairs by `data` map, which is expired after `duration`.
//
// It does not expire if `duration` == 0.
// It deletes the keys of `data` if `duration` < 0 or given `value` is nil.
Sets(ctx context.Context, data map[interface{}]interface{}, duration time.Duration) error
SetMap(ctx context.Context, data map[interface{}]interface{}, duration time.Duration) error
// SetIfNotExist sets cache with `key`-`value` pair which is expired after `duration`
// if `key` does not exist in the cache. It returns true the `key` does not exist in the

View File

@ -87,14 +87,14 @@ func (c *AdapterMemory) Set(ctx context.Context, key interface{}, value interfac
return nil
}
// Sets batch sets cache with key-value pairs by `data` map, which is expired after `duration`.
// SetMap batch sets cache with key-value pairs by `data` map, which is expired after `duration`.
//
// It does not expire if `duration` == 0.
// It deletes the keys of `data` if `duration` < 0 or given `value` is nil.
func (c *AdapterMemory) Sets(ctx context.Context, data map[interface{}]interface{}, duration time.Duration) error {
func (c *AdapterMemory) SetMap(ctx context.Context, data map[interface{}]interface{}, duration time.Duration) error {
var (
expireTime = c.getInternalExpire(duration)
err = c.data.Sets(data, expireTime)
err = c.data.SetMap(data, expireTime)
)
if err != nil {
return err

View File

@ -156,7 +156,7 @@ func (d *adapterMemoryData) Set(key interface{}, value adapterMemoryItem) {
//
// It does not expire if `duration` == 0.
// It deletes the keys of `data` if `duration` < 0 or given `value` is nil.
func (d *adapterMemoryData) Sets(data map[interface{}]interface{}, expireTime int64) error {
func (d *adapterMemoryData) SetMap(data map[interface{}]interface{}, expireTime int64) error {
d.mu.Lock()
for k, v := range data {
d.data[k] = adapterMemoryItem{

View File

@ -323,15 +323,15 @@ func TestCache_SetIfNotExistFuncLock(t *testing.T) {
})
}
func TestCache_Sets(t *testing.T) {
func TestCache_SetMap(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
cache := gcache.New()
t.AssertNil(cache.Sets(ctx, g.MapAnyAny{1: 11, 2: 22}, 0))
t.AssertNil(cache.SetMap(ctx, g.MapAnyAny{1: 11, 2: 22}, 0))
v, _ := cache.Get(ctx, 1)
t.Assert(v, 11)
gcache.Remove(ctx, g.Slice{1, 2, 3}...)
t.AssertNil(gcache.Sets(ctx, g.MapAnyAny{1: 11, 2: 22}, 0))
t.AssertNil(gcache.SetMap(ctx, g.MapAnyAny{1: 11, 2: 22}, 0))
v, _ = cache.Get(ctx, 1)
t.Assert(v, 11)
})
@ -438,7 +438,7 @@ func TestCache_GetOrSetFuncLock(t *testing.T) {
func TestCache_Clear(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
cache := gcache.New()
cache.Sets(ctx, g.MapAnyAny{1: 11, 2: 22}, 0)
cache.SetMap(ctx, g.MapAnyAny{1: 11, 2: 22}, 0)
cache.Clear(ctx)
n, _ := cache.Size(ctx)
t.Assert(n, 0)
@ -479,7 +479,7 @@ func TestCache_Basic(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
{
cache := gcache.New()
cache.Sets(ctx, g.MapAnyAny{1: 11, 2: 22}, 0)
cache.SetMap(ctx, g.MapAnyAny{1: 11, 2: 22}, 0)
b, _ := cache.Contains(ctx, 1)
t.Assert(b, true)
v, _ := cache.Get(ctx, 1)
@ -508,7 +508,7 @@ func TestCache_Basic(t *testing.T) {
gcache.Remove(ctx, g.Slice{1, 2, 3}...)
{
gcache.Sets(ctx, g.MapAnyAny{1: 11, 2: 22}, 0)
gcache.SetMap(ctx, g.MapAnyAny{1: 11, 2: 22}, 0)
b, _ := gcache.Contains(ctx, 1)
t.Assert(b, true)
v, _ := gcache.Get(ctx, 1)

View File

@ -15,6 +15,7 @@ import (
"github.com/gogf/gf/internal/intlog"
)
// Config is the configuration management object.
type Config struct {
adapter Adapter
dataMap *gmap.StrAnyMap

View File

@ -44,6 +44,16 @@ func Test_GEnv_Get(t *testing.T) {
})
}
func Test_GEnv_GetVar(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
value := gconv.String(gtime.TimestampNano())
key := "TEST_ENV_" + value
err := os.Setenv(key, "TEST")
t.Assert(err, nil)
t.AssertEQ(genv.GetVar(key).String(), "TEST")
})
}
func Test_GEnv_Contains(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
value := gconv.String(gtime.TimestampNano())

View File

@ -6,108 +6,110 @@
package glog
import "context"
// Print prints `v` with newline using fmt.Sprintln.
// The parameter `v` can be multiple variables.
func Print(v ...interface{}) {
logger.Print(v...)
func Print(ctx context.Context, v ...interface{}) {
logger.Print(ctx, v...)
}
// Printf prints `v` with format `format` using fmt.Sprintf.
// The parameter `v` can be multiple variables.
func Printf(format string, v ...interface{}) {
logger.Printf(format, v...)
func Printf(ctx context.Context, format string, v ...interface{}) {
logger.Printf(ctx, format, v...)
}
// Println is alias of Print.
// See Print.
func Println(v ...interface{}) {
logger.Println(v...)
func Println(ctx context.Context, v ...interface{}) {
logger.Println(ctx, v...)
}
// Fatal prints the logging content with [FATA] header and newline, then exit the current process.
func Fatal(v ...interface{}) {
logger.Fatal(v...)
func Fatal(ctx context.Context, v ...interface{}) {
logger.Fatal(ctx, v...)
}
// Fatalf prints the logging content with [FATA] header, custom format and newline, then exit the current process.
func Fatalf(format string, v ...interface{}) {
logger.Fatalf(format, v...)
func Fatalf(ctx context.Context, format string, v ...interface{}) {
logger.Fatalf(ctx, format, v...)
}
// Panic prints the logging content with [PANI] header and newline, then panics.
func Panic(v ...interface{}) {
logger.Panic(v...)
func Panic(ctx context.Context, v ...interface{}) {
logger.Panic(ctx, v...)
}
// Panicf prints the logging content with [PANI] header, custom format and newline, then panics.
func Panicf(format string, v ...interface{}) {
logger.Panicf(format, v...)
func Panicf(ctx context.Context, format string, v ...interface{}) {
logger.Panicf(ctx, format, v...)
}
// Info prints the logging content with [INFO] header and newline.
func Info(v ...interface{}) {
logger.Info(v...)
func Info(ctx context.Context, v ...interface{}) {
logger.Info(ctx, v...)
}
// Infof prints the logging content with [INFO] header, custom format and newline.
func Infof(format string, v ...interface{}) {
logger.Infof(format, v...)
func Infof(ctx context.Context, format string, v ...interface{}) {
logger.Infof(ctx, format, v...)
}
// Debug prints the logging content with [DEBU] header and newline.
func Debug(v ...interface{}) {
logger.Debug(v...)
func Debug(ctx context.Context, v ...interface{}) {
logger.Debug(ctx, v...)
}
// Debugf prints the logging content with [DEBU] header, custom format and newline.
func Debugf(format string, v ...interface{}) {
logger.Debugf(format, v...)
func Debugf(ctx context.Context, format string, v ...interface{}) {
logger.Debugf(ctx, format, v...)
}
// Notice prints the logging content with [NOTI] header and newline.
// It also prints caller stack info if stack feature is enabled.
func Notice(v ...interface{}) {
logger.Notice(v...)
func Notice(ctx context.Context, v ...interface{}) {
logger.Notice(ctx, v...)
}
// Noticef prints the logging content with [NOTI] header, custom format and newline.
// It also prints caller stack info if stack feature is enabled.
func Noticef(format string, v ...interface{}) {
logger.Noticef(format, v...)
func Noticef(ctx context.Context, format string, v ...interface{}) {
logger.Noticef(ctx, format, v...)
}
// Warning prints the logging content with [WARN] header and newline.
// It also prints caller stack info if stack feature is enabled.
func Warning(v ...interface{}) {
logger.Warning(v...)
func Warning(ctx context.Context, v ...interface{}) {
logger.Warning(ctx, v...)
}
// Warningf prints the logging content with [WARN] header, custom format and newline.
// It also prints caller stack info if stack feature is enabled.
func Warningf(format string, v ...interface{}) {
logger.Warningf(format, v...)
func Warningf(ctx context.Context, format string, v ...interface{}) {
logger.Warningf(ctx, format, v...)
}
// Error prints the logging content with [ERRO] header and newline.
// It also prints caller stack info if stack feature is enabled.
func Error(v ...interface{}) {
logger.Error(v...)
func Error(ctx context.Context, v ...interface{}) {
logger.Error(ctx, v...)
}
// Errorf prints the logging content with [ERRO] header, custom format and newline.
// It also prints caller stack info if stack feature is enabled.
func Errorf(format string, v ...interface{}) {
logger.Errorf(format, v...)
func Errorf(ctx context.Context, format string, v ...interface{}) {
logger.Errorf(ctx, format, v...)
}
// Critical prints the logging content with [CRIT] header and newline.
// It also prints caller stack info if stack feature is enabled.
func Critical(v ...interface{}) {
logger.Critical(v...)
func Critical(ctx context.Context, v ...interface{}) {
logger.Critical(ctx, v...)
}
// Criticalf prints the logging content with [CRIT] header, custom format and newline.
// It also prints caller stack info if stack feature is enabled.
func Criticalf(format string, v ...interface{}) {
logger.Criticalf(format, v...)
func Criticalf(ctx context.Context, format string, v ...interface{}) {
logger.Criticalf(ctx, format, v...)
}

View File

@ -7,7 +7,6 @@
package glog
import (
"context"
"io"
)
@ -16,13 +15,6 @@ func Expose() *Logger {
return logger
}
// Ctx is a chaining function,
// which sets the context for current logging.
// The parameter `keys` specifies the context keys for retrieving values.
func Ctx(ctx context.Context, keys ...interface{}) *Logger {
return logger.Ctx(ctx, keys...)
}
// To is a chaining function,
// which redirects current logging content output to the sepecified `writer`.
func To(writer io.Writer) *Logger {

View File

@ -7,6 +7,7 @@
package glog
import (
"context"
"io"
)
@ -114,8 +115,8 @@ func GetCtxKeys() []interface{} {
// PrintStack prints the caller stack,
// the optional parameter `skip` specify the skipped stack offset from the end point.
func PrintStack(skip ...int) {
logger.PrintStack(skip...)
func PrintStack(ctx context.Context, skip ...int) {
logger.PrintStack(ctx, skip...)
}
// GetStack returns the caller stack content,

View File

@ -33,10 +33,9 @@ import (
// Logger is the struct for logging management.
type Logger struct {
ctx context.Context // Context for logging.
init *gtype.Bool // Initialized.
parent *Logger // Parent logger, if it is not empty, it means the logger is used in chaining function.
config Config // Logger configuration.
init *gtype.Bool // Initialized.
parent *Logger // Parent logger, if it is not empty, it means the logger is used in chaining function.
config Config // Logger configuration.
}
const (
@ -79,7 +78,6 @@ func NewWithWriter(writer io.Writer) *Logger {
// It's commonly used for chaining operations.
func (l *Logger) Clone() *Logger {
newLogger := New()
newLogger.ctx = l.ctx
newLogger.config = l.config
newLogger.parent = l
return newLogger
@ -300,7 +298,7 @@ func (l *Logger) printToFile(ctx context.Context, t time.Time, in *HandlerInput)
// Rotation file size checks.
if l.config.RotateSize > 0 {
if gfile.Size(logFilePath) > l.config.RotateSize {
l.rotateFileBySize(t)
l.rotateFileBySize(ctx, t)
}
}
// Logging content outputting to disk file.
@ -332,29 +330,20 @@ func (l *Logger) getFilePointer(ctx context.Context, path string) *gfpool.File {
return file
}
// getCtx returns the context which is set through chaining operations.
// It returns an empty context if no context set previously.
func (l *Logger) getCtx() context.Context {
if l.ctx != nil {
return l.ctx
}
return context.TODO()
}
// printStd prints content `s` without stack.
func (l *Logger) printStd(level int, value ...interface{}) {
l.print(l.getCtx(), level, value...)
func (l *Logger) printStd(ctx context.Context, level int, value ...interface{}) {
l.print(ctx, level, value...)
}
// printStd prints content `s` with stack check.
func (l *Logger) printErr(level int, value ...interface{}) {
func (l *Logger) printErr(ctx context.Context, level int, value ...interface{}) {
if l.config.StStatus == 1 {
if s := l.GetStack(); s != "" {
value = append(value, "\nStack:\n"+s)
}
}
// In matter of sequence, do not use stderr here, but use the same stdout.
l.print(l.getCtx(), level, value...)
l.print(ctx, level, value...)
}
// format formats `values` using fmt.Sprintf.
@ -364,11 +353,11 @@ func (l *Logger) format(format string, value ...interface{}) string {
// PrintStack prints the caller stack,
// the optional parameter `skip` specify the skipped stack offset from the end point.
func (l *Logger) PrintStack(skip ...int) {
func (l *Logger) PrintStack(ctx context.Context, skip ...int) {
if s := l.GetStack(skip...); s != "" {
l.Println("Stack:\n" + s)
l.Println(ctx, "Stack:\n"+s)
} else {
l.Println()
l.Println(ctx)
}
}

View File

@ -7,141 +7,142 @@
package glog
import (
"context"
"fmt"
"os"
)
// Print prints `v` with newline using fmt.Sprintln.
// The parameter `v` can be multiple variables.
func (l *Logger) Print(v ...interface{}) {
l.printStd(LEVEL_NONE, v...)
func (l *Logger) Print(ctx context.Context, v ...interface{}) {
l.printStd(ctx, LEVEL_NONE, v...)
}
// Printf prints `v` with format `format` using fmt.Sprintf.
// The parameter `v` can be multiple variables.
func (l *Logger) Printf(format string, v ...interface{}) {
l.printStd(LEVEL_NONE, l.format(format, v...))
func (l *Logger) Printf(ctx context.Context, format string, v ...interface{}) {
l.printStd(ctx, LEVEL_NONE, l.format(format, v...))
}
// Println is alias of Print.
// See Print.
func (l *Logger) Println(v ...interface{}) {
l.Print(v...)
func (l *Logger) Println(ctx context.Context, v ...interface{}) {
l.Print(ctx, v...)
}
// Fatal prints the logging content with [FATA] header and newline, then exit the current process.
func (l *Logger) Fatal(v ...interface{}) {
l.printErr(LEVEL_FATA, v...)
func (l *Logger) Fatal(ctx context.Context, v ...interface{}) {
l.printErr(ctx, LEVEL_FATA, v...)
os.Exit(1)
}
// Fatalf prints the logging content with [FATA] header, custom format and newline, then exit the current process.
func (l *Logger) Fatalf(format string, v ...interface{}) {
l.printErr(LEVEL_FATA, l.format(format, v...))
func (l *Logger) Fatalf(ctx context.Context, format string, v ...interface{}) {
l.printErr(ctx, LEVEL_FATA, l.format(format, v...))
os.Exit(1)
}
// Panic prints the logging content with [PANI] header and newline, then panics.
func (l *Logger) Panic(v ...interface{}) {
l.printErr(LEVEL_PANI, v...)
func (l *Logger) Panic(ctx context.Context, v ...interface{}) {
l.printErr(ctx, LEVEL_PANI, v...)
panic(fmt.Sprint(v...))
}
// Panicf prints the logging content with [PANI] header, custom format and newline, then panics.
func (l *Logger) Panicf(format string, v ...interface{}) {
l.printErr(LEVEL_PANI, l.format(format, v...))
func (l *Logger) Panicf(ctx context.Context, format string, v ...interface{}) {
l.printErr(ctx, LEVEL_PANI, l.format(format, v...))
panic(l.format(format, v...))
}
// Info prints the logging content with [INFO] header and newline.
func (l *Logger) Info(v ...interface{}) {
func (l *Logger) Info(ctx context.Context, v ...interface{}) {
if l.checkLevel(LEVEL_INFO) {
l.printStd(LEVEL_INFO, v...)
l.printStd(ctx, LEVEL_INFO, v...)
}
}
// Infof prints the logging content with [INFO] header, custom format and newline.
func (l *Logger) Infof(format string, v ...interface{}) {
func (l *Logger) Infof(ctx context.Context, format string, v ...interface{}) {
if l.checkLevel(LEVEL_INFO) {
l.printStd(LEVEL_INFO, l.format(format, v...))
l.printStd(ctx, LEVEL_INFO, l.format(format, v...))
}
}
// Debug prints the logging content with [DEBU] header and newline.
func (l *Logger) Debug(v ...interface{}) {
func (l *Logger) Debug(ctx context.Context, v ...interface{}) {
if l.checkLevel(LEVEL_DEBU) {
l.printStd(LEVEL_DEBU, v...)
l.printStd(ctx, LEVEL_DEBU, v...)
}
}
// Debugf prints the logging content with [DEBU] header, custom format and newline.
func (l *Logger) Debugf(format string, v ...interface{}) {
func (l *Logger) Debugf(ctx context.Context, format string, v ...interface{}) {
if l.checkLevel(LEVEL_DEBU) {
l.printStd(LEVEL_DEBU, l.format(format, v...))
l.printStd(ctx, LEVEL_DEBU, l.format(format, v...))
}
}
// Notice prints the logging content with [NOTI] header and newline.
// It also prints caller stack info if stack feature is enabled.
func (l *Logger) Notice(v ...interface{}) {
func (l *Logger) Notice(ctx context.Context, v ...interface{}) {
if l.checkLevel(LEVEL_NOTI) {
l.printStd(LEVEL_NOTI, v...)
l.printStd(ctx, LEVEL_NOTI, v...)
}
}
// Noticef prints the logging content with [NOTI] header, custom format and newline.
// It also prints caller stack info if stack feature is enabled.
func (l *Logger) Noticef(format string, v ...interface{}) {
func (l *Logger) Noticef(ctx context.Context, format string, v ...interface{}) {
if l.checkLevel(LEVEL_NOTI) {
l.printStd(LEVEL_NOTI, l.format(format, v...))
l.printStd(ctx, LEVEL_NOTI, l.format(format, v...))
}
}
// Warning prints the logging content with [WARN] header and newline.
// It also prints caller stack info if stack feature is enabled.
func (l *Logger) Warning(v ...interface{}) {
func (l *Logger) Warning(ctx context.Context, v ...interface{}) {
if l.checkLevel(LEVEL_WARN) {
l.printStd(LEVEL_WARN, v...)
l.printStd(ctx, LEVEL_WARN, v...)
}
}
// Warningf prints the logging content with [WARN] header, custom format and newline.
// It also prints caller stack info if stack feature is enabled.
func (l *Logger) Warningf(format string, v ...interface{}) {
func (l *Logger) Warningf(ctx context.Context, format string, v ...interface{}) {
if l.checkLevel(LEVEL_WARN) {
l.printStd(LEVEL_WARN, l.format(format, v...))
l.printStd(ctx, LEVEL_WARN, l.format(format, v...))
}
}
// Error prints the logging content with [ERRO] header and newline.
// It also prints caller stack info if stack feature is enabled.
func (l *Logger) Error(v ...interface{}) {
func (l *Logger) Error(ctx context.Context, v ...interface{}) {
if l.checkLevel(LEVEL_ERRO) {
l.printErr(LEVEL_ERRO, v...)
l.printErr(ctx, LEVEL_ERRO, v...)
}
}
// Errorf prints the logging content with [ERRO] header, custom format and newline.
// It also prints caller stack info if stack feature is enabled.
func (l *Logger) Errorf(format string, v ...interface{}) {
func (l *Logger) Errorf(ctx context.Context, format string, v ...interface{}) {
if l.checkLevel(LEVEL_ERRO) {
l.printErr(LEVEL_ERRO, l.format(format, v...))
l.printErr(ctx, LEVEL_ERRO, l.format(format, v...))
}
}
// Critical prints the logging content with [CRIT] header and newline.
// It also prints caller stack info if stack feature is enabled.
func (l *Logger) Critical(v ...interface{}) {
func (l *Logger) Critical(ctx context.Context, v ...interface{}) {
if l.checkLevel(LEVEL_CRIT) {
l.printErr(LEVEL_CRIT, v...)
l.printErr(ctx, LEVEL_CRIT, v...)
}
}
// Criticalf prints the logging content with [CRIT] header, custom format and newline.
// It also prints caller stack info if stack feature is enabled.
func (l *Logger) Criticalf(format string, v ...interface{}) {
func (l *Logger) Criticalf(ctx context.Context, format string, v ...interface{}) {
if l.checkLevel(LEVEL_CRIT) {
l.printErr(LEVEL_CRIT, l.format(format, v...))
l.printErr(ctx, LEVEL_CRIT, l.format(format, v...))
}
}

View File

@ -7,32 +7,11 @@
package glog
import (
"context"
"github.com/gogf/gf/internal/intlog"
"io"
"github.com/gogf/gf/os/gfile"
)
// Ctx is a chaining function,
// which sets the context for current logging.
func (l *Logger) Ctx(ctx context.Context, keys ...interface{}) *Logger {
if ctx == nil {
return l
}
logger := (*Logger)(nil)
if l.parent == nil {
logger = l.Clone()
} else {
logger = l
}
logger.ctx = ctx
if len(keys) > 0 {
logger.SetCtxKeys(keys...)
}
return logger
}
// To is a chaining function,
// which redirects current logging content output to the specified `writer`.
func (l *Logger) To(writer io.Writer) *Logger {
@ -59,8 +38,7 @@ func (l *Logger) Path(path string) *Logger {
}
if path != "" {
if err := logger.SetPath(path); err != nil {
// panic(err)
intlog.Error(l.getCtx(), err)
panic(err)
}
}
return logger
@ -78,8 +56,7 @@ func (l *Logger) Cat(category string) *Logger {
}
if logger.config.Path != "" {
if err := logger.SetPath(gfile.Join(logger.config.Path, category)); err != nil {
// panic(err)
intlog.Error(l.getCtx(), err)
panic(err)
}
}
return logger
@ -121,8 +98,7 @@ func (l *Logger) LevelStr(levelStr string) *Logger {
logger = l
}
if err := logger.SetLevelStr(levelStr); err != nil {
// panic(err)
intlog.Error(l.getCtx(), err)
panic(err)
}
return logger
}

View File

@ -7,6 +7,7 @@
package glog
import (
"context"
"github.com/gogf/gf/errors/gcode"
"github.com/gogf/gf/os/gctx"
"io"
@ -73,11 +74,11 @@ func (l *Logger) SetConfig(config Config) error {
// Necessary validation.
if config.Path != "" {
if err := l.SetPath(config.Path); err != nil {
intlog.Error(l.ctx, err)
intlog.Error(context.TODO(), err)
return err
}
}
intlog.Printf(l.ctx, "SetConfig: %+v", l.config)
intlog.Printf(context.TODO(), "SetConfig: %+v", l.config)
return nil
}

View File

@ -7,6 +7,7 @@
package glog
import (
"context"
"fmt"
"github.com/gogf/gf/container/garray"
"github.com/gogf/gf/encoding/gcompress"
@ -25,28 +26,28 @@ const (
// rotateFileBySize rotates the current logging file according to the
// configured rotation size.
func (l *Logger) rotateFileBySize(now time.Time) {
func (l *Logger) rotateFileBySize(ctx context.Context, now time.Time) {
if l.config.RotateSize <= 0 {
return
}
if err := l.doRotateFile(l.getFilePath(now)); err != nil {
if err := l.doRotateFile(ctx, l.getFilePath(now)); err != nil {
// panic(err)
intlog.Error(l.ctx, err)
intlog.Error(ctx, err)
}
}
// doRotateFile rotates the given logging file.
func (l *Logger) doRotateFile(filePath string) error {
func (l *Logger) doRotateFile(ctx context.Context, filePath string) error {
memoryLockKey := "glog.doRotateFile:" + filePath
if !gmlock.TryLock(memoryLockKey) {
return nil
}
defer gmlock.Unlock(memoryLockKey)
intlog.PrintFunc(l.ctx, func() string {
intlog.PrintFunc(ctx, func() string {
return fmt.Sprintf(`start rotating file by size: %s, file: %s`, gfile.SizeFormat(filePath), filePath)
})
defer intlog.PrintFunc(l.ctx, func() string {
defer intlog.PrintFunc(ctx, func() string {
return fmt.Sprintf(`done rotating file by size: %s, size: %s`, gfile.SizeFormat(filePath), filePath)
})
@ -56,7 +57,7 @@ func (l *Logger) doRotateFile(filePath string) error {
return err
}
intlog.Printf(
l.ctx,
ctx,
`%d size exceeds, no backups set, remove original logging file: %s`,
l.config.RotateSize, filePath,
)
@ -94,10 +95,10 @@ func (l *Logger) doRotateFile(filePath string) error {
if !gfile.Exists(newFilePath) {
break
} else {
intlog.Printf(l.ctx, `rotation file exists, continue: %s`, newFilePath)
intlog.Printf(ctx, `rotation file exists, continue: %s`, newFilePath)
}
}
intlog.Printf(l.ctx, "rotating file by size from %s to %s", filePath, newFilePath)
intlog.Printf(ctx, "rotating file by size from %s to %s", filePath, newFilePath)
if err := gfile.Rename(filePath, newFilePath); err != nil {
return err
}
@ -108,10 +109,13 @@ func (l *Logger) doRotateFile(filePath string) error {
func (l *Logger) rotateChecksTimely() {
defer gtimer.AddOnce(l.config.RotateCheckInterval, l.rotateChecksTimely)
var (
ctx = context.TODO()
)
// Checks whether file rotation not enabled.
if l.config.RotateSize <= 0 && l.config.RotateExpire == 0 {
intlog.Printf(
l.ctx,
ctx,
"logging rotation ignore checks: RotateSize: %d, RotateExpire: %s",
l.config.RotateSize, l.config.RotateExpire.String(),
)
@ -131,9 +135,9 @@ func (l *Logger) rotateChecksTimely() {
files, err = gfile.ScanDirFile(l.config.Path, pattern, true)
)
if err != nil {
intlog.Error(l.ctx, err)
intlog.Error(ctx, err)
}
intlog.Printf(l.ctx, "logging rotation start checks: %+v", files)
intlog.Printf(ctx, "logging rotation start checks: %+v", files)
// =============================================================
// Rotation of expired file checks.
// =============================================================
@ -152,12 +156,12 @@ func (l *Logger) rotateChecksTimely() {
if subDuration > l.config.RotateExpire {
expireRotated = true
intlog.Printf(
l.ctx,
ctx,
`%v - %v = %v > %v, rotation expire logging file: %s`,
now, mtime, subDuration, l.config.RotateExpire, file,
)
if err := l.doRotateFile(file); err != nil {
intlog.Error(l.ctx, err)
if err := l.doRotateFile(ctx, file); err != nil {
intlog.Error(ctx, err)
}
}
}
@ -165,7 +169,7 @@ func (l *Logger) rotateChecksTimely() {
// Update the files array.
files, err = gfile.ScanDirFile(l.config.Path, pattern, true)
if err != nil {
intlog.Error(l.ctx, err)
intlog.Error(ctx, err)
}
}
}
@ -190,19 +194,19 @@ func (l *Logger) rotateChecksTimely() {
needCompressFileArray.Iterator(func(_ int, path string) bool {
err := gcompress.GzipFile(path, path+".gz")
if err == nil {
intlog.Printf(l.ctx, `compressed done, remove original logging file: %s`, path)
intlog.Printf(ctx, `compressed done, remove original logging file: %s`, path)
if err = gfile.Remove(path); err != nil {
intlog.Print(l.ctx, err)
intlog.Print(ctx, err)
}
} else {
intlog.Print(l.ctx, err)
intlog.Print(ctx, err)
}
return true
})
// Update the files array.
files, err = gfile.ScanDirFile(l.config.Path, pattern, true)
if err != nil {
intlog.Error(l.ctx, err)
intlog.Error(ctx, err)
}
}
}
@ -237,14 +241,14 @@ func (l *Logger) rotateChecksTimely() {
backupFilesMap[originalLoggingFilePath].Add(file)
}
}
intlog.Printf(l.ctx, `calculated backup files map: %+v`, backupFilesMap)
intlog.Printf(ctx, `calculated backup files map: %+v`, backupFilesMap)
for _, array := range backupFilesMap {
diff := array.Len() - l.config.RotateBackupLimit
for i := 0; i < diff; i++ {
path, _ := array.PopLeft()
intlog.Printf(l.ctx, `remove exceeded backup limit file: %s`, path)
intlog.Printf(ctx, `remove exceeded backup limit file: %s`, path)
if err := gfile.Remove(path.(string)); err != nil {
intlog.Error(l.ctx, err)
intlog.Error(ctx, err)
}
}
}
@ -261,12 +265,12 @@ func (l *Logger) rotateChecksTimely() {
subDuration = now.Sub(mtime)
if subDuration > l.config.RotateBackupExpire {
intlog.Printf(
l.ctx,
ctx,
`%v - %v = %v > %v, remove expired backup file: %s`,
now, mtime, subDuration, l.config.RotateBackupExpire, path,
)
if err := gfile.Remove(path); err != nil {
intlog.Error(l.ctx, err)
intlog.Error(ctx, err)
}
return true
} else {

View File

@ -6,11 +6,14 @@
package glog
import "bytes"
import (
"bytes"
"context"
)
// Write implements the io.Writer interface.
// It just prints the content using Print.
func (l *Logger) Write(p []byte) (n int, err error) {
l.Header(false).Print(string(bytes.TrimRight(p, "\r\n")))
l.Header(false).Print(context.TODO(), string(bytes.TrimRight(p, "\r\n")))
return len(p), nil
}

View File

@ -13,7 +13,7 @@ import (
func Example_context() {
ctx := context.WithValue(context.Background(), "Trace-Id", "123456789")
g.Log().Ctx(ctx).Error("runtime error")
g.Log().Error(ctx, "runtime error")
// May Output:
// 2020-06-08 20:17:03.630 [ERRO] {Trace-Id: 123456789} runtime error

View File

@ -8,18 +8,23 @@ package glog
import (
"bytes"
"context"
"github.com/gogf/gf/test/gtest"
"github.com/gogf/gf/text/gstr"
"testing"
)
var (
ctx = context.TODO()
)
func Test_Print(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
w := bytes.NewBuffer(nil)
l := NewWithWriter(w)
l.Print(1, 2, 3)
l.Println(1, 2, 3)
l.Printf("%d %d %d", 1, 2, 3)
l.Print(ctx, 1, 2, 3)
l.Println(ctx, 1, 2, 3)
l.Printf(ctx, "%d %d %d", 1, 2, 3)
t.Assert(gstr.Count(w.String(), "["), 0)
t.Assert(gstr.Count(w.String(), "1 2 3"), 3)
})
@ -29,8 +34,8 @@ func Test_Debug(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
w := bytes.NewBuffer(nil)
l := NewWithWriter(w)
l.Debug(1, 2, 3)
l.Debugf("%d %d %d", 1, 2, 3)
l.Debug(ctx, 1, 2, 3)
l.Debugf(ctx, "%d %d %d", 1, 2, 3)
t.Assert(gstr.Count(w.String(), defaultLevelPrefixes[LEVEL_DEBU]), 2)
t.Assert(gstr.Count(w.String(), "1 2 3"), 2)
})
@ -40,8 +45,8 @@ func Test_Info(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
w := bytes.NewBuffer(nil)
l := NewWithWriter(w)
l.Info(1, 2, 3)
l.Infof("%d %d %d", 1, 2, 3)
l.Info(ctx, 1, 2, 3)
l.Infof(ctx, "%d %d %d", 1, 2, 3)
t.Assert(gstr.Count(w.String(), defaultLevelPrefixes[LEVEL_INFO]), 2)
t.Assert(gstr.Count(w.String(), "1 2 3"), 2)
})
@ -51,8 +56,8 @@ func Test_Notice(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
w := bytes.NewBuffer(nil)
l := NewWithWriter(w)
l.Notice(1, 2, 3)
l.Noticef("%d %d %d", 1, 2, 3)
l.Notice(ctx, 1, 2, 3)
l.Noticef(ctx, "%d %d %d", 1, 2, 3)
t.Assert(gstr.Count(w.String(), defaultLevelPrefixes[LEVEL_NOTI]), 2)
t.Assert(gstr.Count(w.String(), "1 2 3"), 2)
})
@ -62,8 +67,8 @@ func Test_Warning(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
w := bytes.NewBuffer(nil)
l := NewWithWriter(w)
l.Warning(1, 2, 3)
l.Warningf("%d %d %d", 1, 2, 3)
l.Warning(ctx, 1, 2, 3)
l.Warningf(ctx, "%d %d %d", 1, 2, 3)
t.Assert(gstr.Count(w.String(), defaultLevelPrefixes[LEVEL_WARN]), 2)
t.Assert(gstr.Count(w.String(), "1 2 3"), 2)
})
@ -73,8 +78,8 @@ func Test_Error(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
w := bytes.NewBuffer(nil)
l := NewWithWriter(w)
l.Error(1, 2, 3)
l.Errorf("%d %d %d", 1, 2, 3)
l.Error(ctx, 1, 2, 3)
l.Errorf(ctx, "%d %d %d", 1, 2, 3)
t.Assert(gstr.Count(w.String(), defaultLevelPrefixes[LEVEL_ERRO]), 2)
t.Assert(gstr.Count(w.String(), "1 2 3"), 2)
})

View File

@ -20,8 +20,8 @@ import (
func Test_To(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
w := bytes.NewBuffer(nil)
To(w).Error(1, 2, 3)
To(w).Errorf("%d %d %d", 1, 2, 3)
To(w).Error(ctx, 1, 2, 3)
To(w).Errorf(ctx, "%d %d %d", 1, 2, 3)
t.Assert(gstr.Count(w.String(), defaultLevelPrefixes[LEVEL_ERRO]), 2)
t.Assert(gstr.Count(w.String(), "1 2 3"), 2)
})
@ -36,8 +36,8 @@ func Test_Path(t *testing.T) {
t.Assert(err, nil)
defer gfile.Remove(path)
Path(path).File(file).Stdout(false).Error(1, 2, 3)
Path(path).File(file).Stdout(false).Errorf("%d %d %d", 1, 2, 3)
Path(path).File(file).Stdout(false).Error(ctx, 1, 2, 3)
Path(path).File(file).Stdout(false).Errorf(ctx, "%d %d %d", 1, 2, 3)
content := gfile.GetContents(gfile.Join(path, file))
t.Assert(gstr.Count(content, defaultLevelPrefixes[LEVEL_ERRO]), 2)
t.Assert(gstr.Count(content, "1 2 3"), 2)
@ -54,8 +54,8 @@ func Test_Cat(t *testing.T) {
t.Assert(err, nil)
defer gfile.Remove(path)
Path(path).File(file).Cat(cat).Stdout(false).Error(1, 2, 3)
Path(path).File(file).Cat(cat).Stdout(false).Errorf("%d %d %d", 1, 2, 3)
Path(path).File(file).Cat(cat).Stdout(false).Error(ctx, 1, 2, 3)
Path(path).File(file).Cat(cat).Stdout(false).Errorf(ctx, "%d %d %d", 1, 2, 3)
content := gfile.GetContents(gfile.Join(path, cat, file))
t.Assert(gstr.Count(content, defaultLevelPrefixes[LEVEL_ERRO]), 2)
t.Assert(gstr.Count(content, "1 2 3"), 2)
@ -71,8 +71,8 @@ func Test_Level(t *testing.T) {
t.Assert(err, nil)
defer gfile.Remove(path)
Path(path).File(file).Level(LEVEL_PROD).Stdout(false).Debug(1, 2, 3)
Path(path).File(file).Level(LEVEL_PROD).Stdout(false).Debug("%d %d %d", 1, 2, 3)
Path(path).File(file).Level(LEVEL_PROD).Stdout(false).Debug(ctx, 1, 2, 3)
Path(path).File(file).Level(LEVEL_PROD).Stdout(false).Debug(ctx, "%d %d %d", 1, 2, 3)
content := gfile.GetContents(gfile.Join(path, file))
t.Assert(gstr.Count(content, defaultLevelPrefixes[LEVEL_DEBU]), 0)
t.Assert(gstr.Count(content, "1 2 3"), 0)
@ -88,8 +88,8 @@ func Test_Skip(t *testing.T) {
t.Assert(err, nil)
defer gfile.Remove(path)
Path(path).File(file).Skip(10).Stdout(false).Error(1, 2, 3)
Path(path).File(file).Stdout(false).Errorf("%d %d %d", 1, 2, 3)
Path(path).File(file).Skip(10).Stdout(false).Error(ctx, 1, 2, 3)
Path(path).File(file).Stdout(false).Errorf(ctx, "%d %d %d", 1, 2, 3)
content := gfile.GetContents(gfile.Join(path, file))
t.Assert(gstr.Count(content, defaultLevelPrefixes[LEVEL_ERRO]), 2)
t.Assert(gstr.Count(content, "1 2 3"), 2)
@ -106,8 +106,8 @@ func Test_Stack(t *testing.T) {
t.Assert(err, nil)
defer gfile.Remove(path)
Path(path).File(file).Stack(false).Stdout(false).Error(1, 2, 3)
Path(path).File(file).Stdout(false).Errorf("%d %d %d", 1, 2, 3)
Path(path).File(file).Stack(false).Stdout(false).Error(ctx, 1, 2, 3)
Path(path).File(file).Stdout(false).Errorf(ctx, "%d %d %d", 1, 2, 3)
content := gfile.GetContents(gfile.Join(path, file))
t.Assert(gstr.Count(content, defaultLevelPrefixes[LEVEL_ERRO]), 2)
t.Assert(gstr.Count(content, "1 2 3"), 2)
@ -124,13 +124,13 @@ func Test_StackWithFilter(t *testing.T) {
t.Assert(err, nil)
defer gfile.Remove(path)
Path(path).File(file).StackWithFilter("none").Stdout(false).Error(1, 2, 3)
Path(path).File(file).StackWithFilter("none").Stdout(false).Error(ctx, 1, 2, 3)
content := gfile.GetContents(gfile.Join(path, file))
t.Assert(gstr.Count(content, defaultLevelPrefixes[LEVEL_ERRO]), 1)
t.Assert(gstr.Count(content, "1 2 3"), 1)
t.Assert(gstr.Count(content, "Stack"), 1)
fmt.Println("Content:")
fmt.Println(content)
fmt.Println(ctx, "Content:")
fmt.Println(ctx, content)
})
gtest.C(t, func(t *gtest.T) {
path := gfile.TempDir(gtime.TimestampNanoStr())
@ -140,13 +140,13 @@ func Test_StackWithFilter(t *testing.T) {
t.Assert(err, nil)
defer gfile.Remove(path)
Path(path).File(file).StackWithFilter("/gf/").Stdout(false).Error(1, 2, 3)
Path(path).File(file).StackWithFilter("/gf/").Stdout(false).Error(ctx, 1, 2, 3)
content := gfile.GetContents(gfile.Join(path, file))
t.Assert(gstr.Count(content, defaultLevelPrefixes[LEVEL_ERRO]), 1)
t.Assert(gstr.Count(content, "1 2 3"), 1)
t.Assert(gstr.Count(content, "Stack"), 0)
fmt.Println("Content:")
fmt.Println(content)
fmt.Println(ctx, "Content:")
fmt.Println(ctx, content)
})
}
@ -159,7 +159,7 @@ func Test_Header(t *testing.T) {
t.Assert(err, nil)
defer gfile.Remove(path)
Path(path).File(file).Header(true).Stdout(false).Error(1, 2, 3)
Path(path).File(file).Header(true).Stdout(false).Error(ctx, 1, 2, 3)
content := gfile.GetContents(gfile.Join(path, file))
t.Assert(gstr.Count(content, defaultLevelPrefixes[LEVEL_ERRO]), 1)
t.Assert(gstr.Count(content, "1 2 3"), 1)
@ -172,7 +172,7 @@ func Test_Header(t *testing.T) {
t.Assert(err, nil)
defer gfile.Remove(path)
Path(path).File(file).Header(false).Stdout(false).Error(1, 2, 3)
Path(path).File(file).Header(false).Stdout(false).Error(ctx, 1, 2, 3)
content := gfile.GetContents(gfile.Join(path, file))
t.Assert(gstr.Count(content, defaultLevelPrefixes[LEVEL_ERRO]), 0)
t.Assert(gstr.Count(content, "1 2 3"), 1)
@ -188,7 +188,7 @@ func Test_Line(t *testing.T) {
t.Assert(err, nil)
defer gfile.Remove(path)
Path(path).File(file).Line(true).Stdout(false).Debug(1, 2, 3)
Path(path).File(file).Line(true).Stdout(false).Debug(ctx, 1, 2, 3)
content := gfile.GetContents(gfile.Join(path, file))
t.Assert(gstr.Count(content, defaultLevelPrefixes[LEVEL_DEBU]), 1)
t.Assert(gstr.Count(content, "1 2 3"), 1)
@ -203,7 +203,7 @@ func Test_Line(t *testing.T) {
t.Assert(err, nil)
defer gfile.Remove(path)
Path(path).File(file).Line(false).Stdout(false).Debug(1, 2, 3)
Path(path).File(file).Line(false).Stdout(false).Debug(ctx, 1, 2, 3)
content := gfile.GetContents(gfile.Join(path, file))
t.Assert(gstr.Count(content, defaultLevelPrefixes[LEVEL_DEBU]), 1)
t.Assert(gstr.Count(content, "1 2 3"), 1)
@ -221,7 +221,7 @@ func Test_Async(t *testing.T) {
t.Assert(err, nil)
defer gfile.Remove(path)
Path(path).File(file).Async().Stdout(false).Debug(1, 2, 3)
Path(path).File(file).Async().Stdout(false).Debug(ctx, 1, 2, 3)
content := gfile.GetContents(gfile.Join(path, file))
t.Assert(content, "")
time.Sleep(200 * time.Millisecond)
@ -239,7 +239,7 @@ func Test_Async(t *testing.T) {
t.Assert(err, nil)
defer gfile.Remove(path)
Path(path).File(file).Async(false).Stdout(false).Debug(1, 2, 3)
Path(path).File(file).Async(false).Stdout(false).Debug(ctx, 1, 2, 3)
content := gfile.GetContents(gfile.Join(path, file))
t.Assert(gstr.Count(content, defaultLevelPrefixes[LEVEL_DEBU]), 1)
t.Assert(gstr.Count(content, "1 2 3"), 1)

View File

@ -32,7 +32,7 @@ func Test_Concurrent(t *testing.T) {
go func() {
defer wg.Done()
<-ch
l.File(f).Stdout(false).Print(s)
l.File(f).Stdout(false).Print(ctx, s)
}()
}
close(ch)

View File

@ -42,8 +42,8 @@ func Test_SetConfigWithMap_LevelStr(t *testing.T) {
l.SetWriter(buffer)
l.Debug("test")
l.Warning("test")
l.Debug(ctx, "test")
l.Warning(ctx, "test")
t.Assert(strings.Contains(buffer.String(), "DEBU"), true)
t.Assert(strings.Contains(buffer.String(), "WARN"), true)
})
@ -57,8 +57,8 @@ func Test_SetConfigWithMap_LevelStr(t *testing.T) {
err := l.SetConfigWithMap(m)
t.Assert(err, nil)
l.SetWriter(buffer)
l.Debug("test")
l.Warning("test")
l.Debug(ctx, "test")
l.Warning(ctx, "test")
t.Assert(strings.Contains(buffer.String(), "DEBU"), false)
t.Assert(strings.Contains(buffer.String(), "WARN"), true)
})

View File

@ -25,7 +25,7 @@ func Test_Ctx(t *testing.T) {
ctx := context.WithValue(context.Background(), "Trace-Id", "1234567890")
ctx = context.WithValue(ctx, "Span-Id", "abcdefg")
l.Ctx(ctx).Print(1, 2, 3)
l.Print(ctx, 1, 2, 3)
t.Assert(gstr.Count(w.String(), "1234567890"), 1)
t.Assert(gstr.Count(w.String(), "abcdefg"), 1)
t.Assert(gstr.Count(w.String(), "1 2 3"), 1)
@ -44,7 +44,7 @@ func Test_Ctx_Config(t *testing.T) {
ctx := context.WithValue(context.Background(), "Trace-Id", "1234567890")
ctx = context.WithValue(ctx, "Span-Id", "abcdefg")
l.Ctx(ctx).Print(1, 2, 3)
l.Print(ctx, 1, 2, 3)
t.Assert(gstr.Count(w.String(), "1234567890"), 1)
t.Assert(gstr.Count(w.String(), "abcdefg"), 1)
t.Assert(gstr.Count(w.String(), "1 2 3"), 1)
@ -55,7 +55,7 @@ func Test_Ctx_CtxKey(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
w := bytes.NewBuffer(nil)
l := glog.NewWithWriter(w)
l.Ctx(gctx.WithValue(context.TODO(), "abcdefg")).Print(1, 2, 3)
l.Print(gctx.WithValue(context.TODO(), "abcdefg"), 1, 2, 3)
t.Assert(gstr.Count(w.String(), "abcdefg"), 1)
t.Assert(gstr.Count(w.String(), "1 2 3"), 1)
})

View File

@ -32,7 +32,7 @@ func TestLogger_SetHandlers1(t *testing.T) {
ctx := context.WithValue(context.Background(), "Trace-Id", "1234567890")
ctx = context.WithValue(ctx, "Span-Id", "abcdefg")
l.Ctx(ctx).Print(1, 2, 3)
l.Print(ctx, 1, 2, 3)
t.Assert(gstr.Count(w.String(), "1234567890"), 1)
t.Assert(gstr.Count(w.String(), "abcdefg"), 1)
t.Assert(gstr.Count(w.String(), "1 2 3"), 1)
@ -59,7 +59,7 @@ func TestLogger_SetHandlers2(t *testing.T) {
ctx := context.WithValue(context.Background(), "Trace-Id", "1234567890")
ctx = context.WithValue(ctx, "Span-Id", "abcdefg")
l.Ctx(ctx).Print(1, 2, 3)
l.Print(ctx, 1, 2, 3)
t.Assert(gstr.Count(w.String(), "1234567890"), 0)
t.Assert(gstr.Count(w.String(), "abcdefg"), 0)
t.Assert(gstr.Count(w.String(), "1 2 3"), 0)

View File

@ -38,13 +38,13 @@ func Test_LevelPrefix(t *testing.T) {
buffer := bytes.NewBuffer(nil)
l := New()
l.SetWriter(buffer)
l.Debug("test1")
l.Debug(ctx, "test1")
t.Assert(gstr.Contains(buffer.String(), defaultLevelPrefixes[LEVEL_DEBU]), true)
buffer.Reset()
l.SetLevelPrefix(LEVEL_DEBU, "debug")
l.Debug("test2")
l.Debug(ctx, "test2")
t.Assert(gstr.Contains(buffer.String(), defaultLevelPrefixes[LEVEL_DEBU]), false)
t.Assert(gstr.Contains(buffer.String(), "debug"), true)
@ -52,7 +52,7 @@ func Test_LevelPrefix(t *testing.T) {
l.SetLevelPrefixes(map[int]string{
LEVEL_ERRO: "error",
})
l.Error("test3")
l.Error(ctx, "test3")
t.Assert(gstr.Contains(buffer.String(), defaultLevelPrefixes[LEVEL_ERRO]), false)
t.Assert(gstr.Contains(buffer.String(), "error"), true)
})

View File

@ -7,6 +7,7 @@
package glog_test
import (
"context"
"fmt"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/os/gfile"
@ -18,6 +19,10 @@ import (
"time"
)
var (
ctx = context.TODO()
)
func Test_Rotate_Size(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
l := glog.New()
@ -37,8 +42,8 @@ func Test_Rotate_Size(t *testing.T) {
s := "1234567890abcdefg"
for i := 0; i < 10; i++ {
fmt.Println("logging content index:", i)
l.Print(s)
fmt.Println(ctx, "logging content index:", i)
l.Print(ctx, s)
}
time.Sleep(time.Second * 3)
@ -76,7 +81,7 @@ func Test_Rotate_Expire(t *testing.T) {
s := "1234567890abcdefg"
for i := 0; i < 10; i++ {
l.Print(s)
l.Print(ctx, s)
}
files, err := gfile.ScanDirFile(p, "*.gz")

View File

@ -7,6 +7,7 @@
package gproc
import (
"context"
"fmt"
"github.com/gogf/gf/internal/json"
"net"
@ -70,7 +71,7 @@ func receiveTcpListening() {
// Start listening.
for {
if conn, err := listen.Accept(); err != nil {
glog.Error(err)
glog.Error(context.TODO(), err)
} else if conn != nil {
go receiveTcpHandler(gtcp.NewConnByNetConn(conn))
}
@ -80,6 +81,7 @@ func receiveTcpListening() {
// receiveTcpHandler is the connection handler for receiving data.
func receiveTcpHandler(conn *gtcp.Conn) {
var (
ctx = context.TODO()
result []byte
response MsgResponse
)
@ -113,15 +115,15 @@ func receiveTcpHandler(conn *gtcp.Conn) {
if err == nil {
result, err = json.Marshal(response)
if err != nil {
glog.Error(err)
glog.Error(ctx, err)
}
if err := conn.SendPkg(result); err != nil {
glog.Error(err)
glog.Error(ctx, err)
}
} else {
// Just close the connection if any error occurs.
if err := conn.Close(); err != nil {
glog.Error(err)
glog.Error(ctx, err)
}
break
}

View File

@ -35,14 +35,18 @@ type Session struct {
// init does the lazy initialization for session.
// It here initializes real session if necessary.
func (s *Session) init() {
func (s *Session) init() error {
if s.start {
return
return nil
}
var err error
if s.id != "" {
// Retrieve memory session data from manager.
if r, _ := s.manager.sessionData.Get(s.ctx, s.id); r != nil {
r, err := s.manager.sessionData.Get(s.ctx, s.id)
if err != nil && err != ErrorDisabled {
return err
}
if r != nil {
s.data = r.Val().(*gmap.StrAnyMap)
intlog.Print(s.ctx, "session init data:", s.data)
}
@ -50,7 +54,7 @@ func (s *Session) init() {
if s.manager.storage != nil {
if s.data, err = s.manager.storage.GetSession(s.ctx, s.id, s.manager.ttl, s.data); err != nil && err != ErrorDisabled {
intlog.Errorf(s.ctx, "session restoring failed for id '%s': %v", s.id, err)
panic(err)
return err
}
}
}
@ -63,7 +67,7 @@ func (s *Session) init() {
s.id, err = s.manager.storage.New(s.ctx, s.manager.ttl)
if err != nil && err != ErrorDisabled {
intlog.Errorf(s.ctx, "create session id failed: %v", err)
panic(err)
return err
}
}
// Use default session id creating function.
@ -74,24 +78,24 @@ func (s *Session) init() {
s.data = gmap.NewStrAnyMap(true)
}
s.start = true
return nil
}
// Close closes current session and updates its ttl in the session manager.
// If this session is dirty, it also exports it to storage.
//
// NOTE that this function must be called ever after a session request done.
func (s *Session) Close() {
func (s *Session) Close() error {
if s.start && s.id != "" {
size := s.data.Size()
if s.manager.storage != nil {
if s.dirty {
if err := s.manager.storage.SetSession(s.ctx, s.id, s.data, s.manager.ttl); err != nil {
panic(err)
if err := s.manager.storage.SetSession(s.ctx, s.id, s.data, s.manager.ttl); err != nil && err != ErrorDisabled {
return err
}
} else if size > 0 {
if err := s.manager.storage.UpdateTTL(s.ctx, s.id, s.manager.ttl); err != nil {
panic(err)
if err := s.manager.storage.UpdateTTL(s.ctx, s.id, s.manager.ttl); err != nil && err != ErrorDisabled {
return err
}
}
}
@ -99,11 +103,14 @@ func (s *Session) Close() {
s.manager.UpdateSessionTTL(s.id, s.data)
}
}
return nil
}
// Set sets key-value pair to this session.
func (s *Session) Set(key string, value interface{}) error {
s.init()
if err := s.init(); err != nil {
return err
}
if err := s.manager.storage.Set(s.ctx, s.id, key, value, s.manager.ttl); err != nil {
if err == ErrorDisabled {
s.data.Set(key, value)
@ -115,15 +122,11 @@ func (s *Session) Set(key string, value interface{}) error {
return nil
}
// Sets batch sets the session using map.
// Deprecated, use SetMap instead.
func (s *Session) Sets(data map[string]interface{}) error {
return s.SetMap(data)
}
// SetMap batch sets the session using map.
func (s *Session) SetMap(data map[string]interface{}) error {
s.init()
if err := s.init(); err != nil {
return err
}
if err := s.manager.storage.SetMap(s.ctx, s.id, data, s.manager.ttl); err != nil {
if err == ErrorDisabled {
s.data.Sets(data)
@ -140,7 +143,9 @@ func (s *Session) Remove(keys ...string) error {
if s.id == "" {
return nil
}
s.init()
if err := s.init(); err != nil {
return err
}
for _, key := range keys {
if err := s.manager.storage.Remove(s.ctx, s.id, key); err != nil {
if err == ErrorDisabled {
@ -154,17 +159,14 @@ func (s *Session) Remove(keys ...string) error {
return nil
}
// Clear is alias of RemoveAll.
func (s *Session) Clear() error {
return s.RemoveAll()
}
// RemoveAll deletes all key-value pairs from this session.
func (s *Session) RemoveAll() error {
if s.id == "" {
return nil
}
s.init()
if err := s.init(); err != nil {
return err
}
if err := s.manager.storage.RemoveAll(s.ctx, s.id); err != nil {
if err == ErrorDisabled {
s.data.Clear()
@ -178,9 +180,11 @@ func (s *Session) RemoveAll() error {
// Id returns the session id for this session.
// It creates and returns a new session id if the session id is not passed in initialization.
func (s *Session) Id() string {
s.init()
return s.id
func (s *Session) Id() (string, error) {
if err := s.init(); err != nil {
return "", err
}
return s.id, nil
}
// SetId sets custom session before session starts.
@ -203,43 +207,53 @@ func (s *Session) SetIdFunc(f func(ttl time.Duration) string) error {
return nil
}
// Map returns all data as map.
// Data returns all data as map.
// Note that it's using value copy internally for concurrent-safe purpose.
func (s *Session) Map() map[string]interface{} {
func (s *Session) Data() (map[string]interface{}, error) {
if s.id != "" {
s.init()
data, err := s.manager.storage.GetMap(s.ctx, s.id)
if err := s.init(); err != nil {
return nil, err
}
data, err := s.manager.storage.Data(s.ctx, s.id)
if err != nil && err != ErrorDisabled {
intlog.Error(s.ctx, err)
}
if data != nil {
return data
return data, nil
}
return s.data.Map()
return s.data.Map(), nil
}
return nil
return map[string]interface{}{}, nil
}
// Size returns the size of the session.
func (s *Session) Size() int {
func (s *Session) Size() (int, error) {
if s.id != "" {
s.init()
if err := s.init(); err != nil {
return 0, err
}
size, err := s.manager.storage.GetSize(s.ctx, s.id)
if err != nil && err != ErrorDisabled {
intlog.Error(s.ctx, err)
}
if size >= 0 {
return size
return size, nil
}
return s.data.Size()
return s.data.Size(), nil
}
return 0
return 0, nil
}
// Contains checks whether key exist in the session.
func (s *Session) Contains(key string) bool {
s.init()
return !s.Get(key).IsNil()
func (s *Session) Contains(key string) (bool, error) {
if err := s.init(); err != nil {
return false, err
}
v, err := s.Get(key)
if err != nil {
return false, err
}
return !v.IsNil(), nil
}
// IsDirty checks whether there's any data changes in the session.
@ -250,23 +264,71 @@ func (s *Session) IsDirty() bool {
// Get retrieves session value with given key.
// It returns `def` if the key does not exist in the session if `def` is given,
// or else it returns nil.
func (s *Session) Get(key string, def ...interface{}) *gvar.Var {
func (s *Session) Get(key string, def ...interface{}) (*gvar.Var, error) {
if s.id == "" {
return nil
return nil, gerror.NewCode(gcode.CodeInvalidParameter, `session id cannot be empty`)
}
if err := s.init(); err != nil {
return nil, err
}
s.init()
v, err := s.manager.storage.Get(s.ctx, s.id, key)
if err != nil && err != ErrorDisabled {
intlog.Error(s.ctx, err)
return nil, err
}
if v != nil {
return gvar.New(v)
return gvar.New(v), nil
}
if v := s.data.Get(key); v != nil {
return gvar.New(v)
return gvar.New(v), nil
}
if len(def) > 0 {
return gvar.New(def[0])
return gvar.New(def[0]), nil
}
return nil
return nil, nil
}
// MustId performs as function Id, but it panics if any error occurs.
func (s *Session) MustId() string {
id, err := s.Id()
if err != nil {
panic(err)
}
return id
}
// MustGet performs as function Get, but it panics if any error occurs.
func (s *Session) MustGet(key string, def ...interface{}) *gvar.Var {
v, err := s.Get(key, def...)
if err != nil {
panic(err)
}
return v
}
// MustContains performs as function Contains, but it panics if any error occurs.
func (s *Session) MustContains(key string) bool {
b, err := s.Contains(key)
if err != nil {
panic(err)
}
return b
}
// MustData performs as function Data, but it panics if any error occurs.
func (s *Session) MustData() map[string]interface{} {
m, err := s.Data()
if err != nil {
panic(err)
}
return m
}
// MustSize performs as function Size, but it panics if any error occurs.
func (s *Session) MustSize() int {
size, err := s.Size()
if err != nil {
panic(err)
}
return size
}

View File

@ -22,12 +22,12 @@ type Storage interface {
// It returns nil if the key does not exist in the session.
Get(ctx context.Context, id string, key string) (value interface{}, err error)
// GetMap retrieves all key-value pairs as map from storage.
GetMap(ctx context.Context, id string) (data map[string]interface{}, err error)
// GetSize retrieves and returns the size of key-value pairs from storage.
GetSize(ctx context.Context, id string) (size int, err error)
// Data retrieves all key-value pairs as map from storage.
Data(ctx context.Context, id string) (data map[string]interface{}, err error)
// Set sets one key-value session pair to the storage.
// The parameter `ttl` specifies the TTL for the session id.
Set(ctx context.Context, id string, key string, value interface{}, ttl time.Duration) error

View File

@ -117,7 +117,7 @@ func (s *StorageFile) Get(ctx context.Context, id string, key string) (value int
}
// GetMap retrieves all key-value pairs as map from storage.
func (s *StorageFile) GetMap(ctx context.Context, id string) (data map[string]interface{}, err error) {
func (s *StorageFile) Data(ctx context.Context, id string) (data map[string]interface{}, err error) {
return nil, ErrorDisabled
}

View File

@ -33,7 +33,7 @@ func (s *StorageMemory) Get(ctx context.Context, id string, key string) (value i
}
// GetMap retrieves all key-value pairs as map from storage.
func (s *StorageMemory) GetMap(ctx context.Context, id string) (data map[string]interface{}, err error) {
func (s *StorageMemory) Data(ctx context.Context, id string) (data map[string]interface{}, err error) {
return nil, ErrorDisabled
}

View File

@ -78,7 +78,7 @@ func (s *StorageRedis) Get(ctx context.Context, id string, key string) (value in
}
// GetMap retrieves all key-value pairs as map from storage.
func (s *StorageRedis) GetMap(ctx context.Context, id string) (data map[string]interface{}, err error) {
func (s *StorageRedis) Data(ctx context.Context, id string) (data map[string]interface{}, err error) {
return nil, ErrorDisabled
}

View File

@ -57,7 +57,7 @@ func (s *StorageRedisHashTable) Get(ctx context.Context, id string, key string)
}
// GetMap retrieves all key-value pairs as map from storage.
func (s *StorageRedisHashTable) GetMap(ctx context.Context, id string) (data map[string]interface{}, err error) {
func (s *StorageRedisHashTable) Data(ctx context.Context, id string) (data map[string]interface{}, err error) {
v, err := s.redis.Do(ctx, "HGETALL", s.key(id))
if err != nil {
return nil, err

View File

@ -25,51 +25,51 @@ func Test_StorageFile(t *testing.T) {
defer s.Close()
s.Set("k1", "v1")
s.Set("k2", "v2")
s.Sets(g.Map{
s.SetMap(g.Map{
"k3": "v3",
"k4": "v4",
})
t.Assert(s.IsDirty(), true)
sessionId = s.Id()
sessionId = s.MustId()
})
time.Sleep(500 * time.Millisecond)
gtest.C(t, func(t *gtest.T) {
s := manager.New(context.TODO(), sessionId)
t.Assert(s.Get("k1"), "v1")
t.Assert(s.Get("k2"), "v2")
t.Assert(s.Get("k3"), "v3")
t.Assert(s.Get("k4"), "v4")
t.Assert(len(s.Map()), 4)
t.Assert(s.Map()["k1"], "v1")
t.Assert(s.Map()["k4"], "v4")
t.Assert(s.Id(), sessionId)
t.Assert(s.Size(), 4)
t.Assert(s.Contains("k1"), true)
t.Assert(s.Contains("k3"), true)
t.Assert(s.Contains("k5"), false)
t.Assert(s.MustGet("k1"), "v1")
t.Assert(s.MustGet("k2"), "v2")
t.Assert(s.MustGet("k3"), "v3")
t.Assert(s.MustGet("k4"), "v4")
t.Assert(len(s.MustData()), 4)
t.Assert(s.MustData()["k1"], "v1")
t.Assert(s.MustData()["k4"], "v4")
t.Assert(s.MustId(), sessionId)
t.Assert(s.MustSize(), 4)
t.Assert(s.MustContains("k1"), true)
t.Assert(s.MustContains("k3"), true)
t.Assert(s.MustContains("k5"), false)
s.Remove("k4")
t.Assert(s.Size(), 3)
t.Assert(s.Contains("k3"), true)
t.Assert(s.Contains("k4"), false)
t.Assert(s.MustSize(), 3)
t.Assert(s.MustContains("k3"), true)
t.Assert(s.MustContains("k4"), false)
s.RemoveAll()
t.Assert(s.Size(), 0)
t.Assert(s.Contains("k1"), false)
t.Assert(s.Contains("k2"), false)
s.Sets(g.Map{
t.Assert(s.MustSize(), 0)
t.Assert(s.MustContains("k1"), false)
t.Assert(s.MustContains("k2"), false)
s.SetMap(g.Map{
"k5": "v5",
"k6": "v6",
})
t.Assert(s.Size(), 2)
t.Assert(s.Contains("k5"), true)
t.Assert(s.Contains("k6"), true)
t.Assert(s.MustSize(), 2)
t.Assert(s.MustContains("k5"), true)
t.Assert(s.MustContains("k6"), true)
})
time.Sleep(1000 * time.Millisecond)
gtest.C(t, func(t *gtest.T) {
s := manager.New(context.TODO(), sessionId)
t.Assert(s.Size(), 0)
t.Assert(s.Get("k5"), nil)
t.Assert(s.Get("k6"), nil)
t.Assert(s.MustSize(), 0)
t.Assert(s.MustGet("k5"), nil)
t.Assert(s.MustGet("k6"), nil)
})
}

View File

@ -25,51 +25,51 @@ func Test_StorageMemory(t *testing.T) {
defer s.Close()
s.Set("k1", "v1")
s.Set("k2", "v2")
s.Sets(g.Map{
s.SetMap(g.Map{
"k3": "v3",
"k4": "v4",
})
t.Assert(s.IsDirty(), true)
sessionId = s.Id()
sessionId = s.MustId()
})
time.Sleep(500 * time.Millisecond)
gtest.C(t, func(t *gtest.T) {
s := manager.New(context.TODO(), sessionId)
t.Assert(s.Get("k1"), "v1")
t.Assert(s.Get("k2"), "v2")
t.Assert(s.Get("k3"), "v3")
t.Assert(s.Get("k4"), "v4")
t.Assert(len(s.Map()), 4)
t.Assert(s.Map()["k1"], "v1")
t.Assert(s.Map()["k4"], "v4")
t.Assert(s.Id(), sessionId)
t.Assert(s.Size(), 4)
t.Assert(s.Contains("k1"), true)
t.Assert(s.Contains("k3"), true)
t.Assert(s.Contains("k5"), false)
t.Assert(s.MustGet("k1"), "v1")
t.Assert(s.MustGet("k2"), "v2")
t.Assert(s.MustGet("k3"), "v3")
t.Assert(s.MustGet("k4"), "v4")
t.Assert(len(s.MustData()), 4)
t.Assert(s.MustData()["k1"], "v1")
t.Assert(s.MustData()["k4"], "v4")
t.Assert(s.MustId(), sessionId)
t.Assert(s.MustSize(), 4)
t.Assert(s.MustContains("k1"), true)
t.Assert(s.MustContains("k3"), true)
t.Assert(s.MustContains("k5"), false)
s.Remove("k4")
t.Assert(s.Size(), 3)
t.Assert(s.Contains("k3"), true)
t.Assert(s.Contains("k4"), false)
t.Assert(s.MustSize(), 3)
t.Assert(s.MustContains("k3"), true)
t.Assert(s.MustContains("k4"), false)
s.RemoveAll()
t.Assert(s.Size(), 0)
t.Assert(s.Contains("k1"), false)
t.Assert(s.Contains("k2"), false)
s.Sets(g.Map{
t.Assert(s.MustSize(), 0)
t.Assert(s.MustContains("k1"), false)
t.Assert(s.MustContains("k2"), false)
s.SetMap(g.Map{
"k5": "v5",
"k6": "v6",
})
t.Assert(s.Size(), 2)
t.Assert(s.Contains("k5"), true)
t.Assert(s.Contains("k6"), true)
t.Assert(s.MustSize(), 2)
t.Assert(s.MustContains("k5"), true)
t.Assert(s.MustContains("k6"), true)
})
time.Sleep(1000 * time.Millisecond)
gtest.C(t, func(t *gtest.T) {
s := manager.New(context.TODO(), sessionId)
t.Assert(s.Size(), 0)
t.Assert(s.Get("k5"), nil)
t.Assert(s.Get("k6"), nil)
t.Assert(s.MustSize(), 0)
t.Assert(s.MustGet("k5"), nil)
t.Assert(s.MustGet("k6"), nil)
})
}

View File

@ -34,51 +34,51 @@ func Test_StorageRedisHashTable(t *testing.T) {
defer s.Close()
s.Set("k1", "v1")
s.Set("k2", "v2")
s.Sets(g.Map{
s.SetMap(g.Map{
"k3": "v3",
"k4": "v4",
})
t.Assert(s.IsDirty(), true)
sessionId = s.Id()
sessionId = s.MustId()
})
gtest.C(t, func(t *gtest.T) {
s := manager.New(context.TODO(), sessionId)
t.Assert(s.Get("k1"), "v1")
t.Assert(s.Get("k2"), "v2")
t.Assert(s.Get("k3"), "v3")
t.Assert(s.Get("k4"), "v4")
t.Assert(len(s.Map()), 4)
t.Assert(s.Map()["k1"], "v1")
t.Assert(s.Map()["k4"], "v4")
t.Assert(s.Id(), sessionId)
t.Assert(s.Size(), 4)
t.Assert(s.Contains("k1"), true)
t.Assert(s.Contains("k3"), true)
t.Assert(s.Contains("k5"), false)
t.Assert(s.MustGet("k1"), "v1")
t.Assert(s.MustGet("k2"), "v2")
t.Assert(s.MustGet("k3"), "v3")
t.Assert(s.MustGet("k4"), "v4")
t.Assert(len(s.MustData()), 4)
t.Assert(s.MustData()["k1"], "v1")
t.Assert(s.MustData()["k4"], "v4")
t.Assert(s.MustId(), sessionId)
t.Assert(s.MustSize(), 4)
t.Assert(s.MustContains("k1"), true)
t.Assert(s.MustContains("k3"), true)
t.Assert(s.MustContains("k5"), false)
s.Remove("k4")
t.Assert(s.Size(), 3)
t.Assert(s.Contains("k3"), true)
t.Assert(s.Contains("k4"), false)
t.Assert(s.MustSize(), 3)
t.Assert(s.MustContains("k3"), true)
t.Assert(s.MustContains("k4"), false)
s.RemoveAll()
t.Assert(s.Size(), 0)
t.Assert(s.Contains("k1"), false)
t.Assert(s.Contains("k2"), false)
s.Sets(g.Map{
t.Assert(s.MustSize(), 0)
t.Assert(s.MustContains("k1"), false)
t.Assert(s.MustContains("k2"), false)
s.SetMap(g.Map{
"k5": "v5",
"k6": "v6",
})
t.Assert(s.Size(), 2)
t.Assert(s.Contains("k5"), true)
t.Assert(s.Contains("k6"), true)
t.Assert(s.MustSize(), 2)
t.Assert(s.MustContains("k5"), true)
t.Assert(s.MustContains("k6"), true)
s.Close()
})
time.Sleep(1500 * time.Millisecond)
gtest.C(t, func(t *gtest.T) {
s := manager.New(context.TODO(), sessionId)
t.Assert(s.Size(), 0)
t.Assert(s.Get("k5"), nil)
t.Assert(s.Get("k6"), nil)
t.Assert(s.MustSize(), 0)
t.Assert(s.MustGet("k5"), nil)
t.Assert(s.MustGet("k6"), nil)
})
}
@ -100,50 +100,50 @@ func Test_StorageRedisHashTablePrefix(t *testing.T) {
defer s.Close()
s.Set("k1", "v1")
s.Set("k2", "v2")
s.Sets(g.Map{
s.SetMap(g.Map{
"k3": "v3",
"k4": "v4",
})
t.Assert(s.IsDirty(), true)
sessionId = s.Id()
sessionId = s.MustId()
})
gtest.C(t, func(t *gtest.T) {
s := manager.New(context.TODO(), sessionId)
t.Assert(s.Get("k1"), "v1")
t.Assert(s.Get("k2"), "v2")
t.Assert(s.Get("k3"), "v3")
t.Assert(s.Get("k4"), "v4")
t.Assert(len(s.Map()), 4)
t.Assert(s.Map()["k1"], "v1")
t.Assert(s.Map()["k4"], "v4")
t.Assert(s.Id(), sessionId)
t.Assert(s.Size(), 4)
t.Assert(s.Contains("k1"), true)
t.Assert(s.Contains("k3"), true)
t.Assert(s.Contains("k5"), false)
t.Assert(s.MustGet("k1"), "v1")
t.Assert(s.MustGet("k2"), "v2")
t.Assert(s.MustGet("k3"), "v3")
t.Assert(s.MustGet("k4"), "v4")
t.Assert(len(s.MustData()), 4)
t.Assert(s.MustData()["k1"], "v1")
t.Assert(s.MustData()["k4"], "v4")
t.Assert(s.MustId(), sessionId)
t.Assert(s.MustSize(), 4)
t.Assert(s.MustContains("k1"), true)
t.Assert(s.MustContains("k3"), true)
t.Assert(s.MustContains("k5"), false)
s.Remove("k4")
t.Assert(s.Size(), 3)
t.Assert(s.Contains("k3"), true)
t.Assert(s.Contains("k4"), false)
t.Assert(s.MustSize(), 3)
t.Assert(s.MustContains("k3"), true)
t.Assert(s.MustContains("k4"), false)
s.RemoveAll()
t.Assert(s.Size(), 0)
t.Assert(s.Contains("k1"), false)
t.Assert(s.Contains("k2"), false)
s.Sets(g.Map{
t.Assert(s.MustSize(), 0)
t.Assert(s.MustContains("k1"), false)
t.Assert(s.MustContains("k2"), false)
s.SetMap(g.Map{
"k5": "v5",
"k6": "v6",
})
t.Assert(s.Size(), 2)
t.Assert(s.Contains("k5"), true)
t.Assert(s.Contains("k6"), true)
t.Assert(s.MustSize(), 2)
t.Assert(s.MustContains("k5"), true)
t.Assert(s.MustContains("k6"), true)
s.Close()
})
time.Sleep(1500 * time.Millisecond)
gtest.C(t, func(t *gtest.T) {
s := manager.New(context.TODO(), sessionId)
t.Assert(s.Size(), 0)
t.Assert(s.Get("k5"), nil)
t.Assert(s.Get("k6"), nil)
t.Assert(s.MustSize(), 0)
t.Assert(s.MustGet("k5"), nil)
t.Assert(s.MustGet("k6"), nil)
})
}

View File

@ -32,52 +32,52 @@ func Test_StorageRedis(t *testing.T) {
defer s.Close()
s.Set("k1", "v1")
s.Set("k2", "v2")
s.Sets(g.Map{
s.SetMap(g.Map{
"k3": "v3",
"k4": "v4",
})
t.Assert(s.IsDirty(), true)
sessionId = s.Id()
sessionId = s.MustId()
})
time.Sleep(500 * time.Millisecond)
gtest.C(t, func(t *gtest.T) {
s := manager.New(context.TODO(), sessionId)
t.Assert(s.Get("k1"), "v1")
t.Assert(s.Get("k2"), "v2")
t.Assert(s.Get("k3"), "v3")
t.Assert(s.Get("k4"), "v4")
t.Assert(len(s.Map()), 4)
t.Assert(s.Map()["k1"], "v1")
t.Assert(s.Map()["k4"], "v4")
t.Assert(s.Id(), sessionId)
t.Assert(s.Size(), 4)
t.Assert(s.Contains("k1"), true)
t.Assert(s.Contains("k3"), true)
t.Assert(s.Contains("k5"), false)
t.Assert(s.MustGet("k1"), "v1")
t.Assert(s.MustGet("k2"), "v2")
t.Assert(s.MustGet("k3"), "v3")
t.Assert(s.MustGet("k4"), "v4")
t.Assert(len(s.MustData()), 4)
t.Assert(s.MustData()["k1"], "v1")
t.Assert(s.MustData()["k4"], "v4")
t.Assert(s.MustId(), sessionId)
t.Assert(s.MustSize(), 4)
t.Assert(s.MustContains("k1"), true)
t.Assert(s.MustContains("k3"), true)
t.Assert(s.MustContains("k5"), false)
s.Remove("k4")
t.Assert(s.Size(), 3)
t.Assert(s.Contains("k3"), true)
t.Assert(s.Contains("k4"), false)
t.Assert(s.MustSize(), 3)
t.Assert(s.MustContains("k3"), true)
t.Assert(s.MustContains("k4"), false)
s.RemoveAll()
t.Assert(s.Size(), 0)
t.Assert(s.Contains("k1"), false)
t.Assert(s.Contains("k2"), false)
s.Sets(g.Map{
t.Assert(s.MustSize(), 0)
t.Assert(s.MustContains("k1"), false)
t.Assert(s.MustContains("k2"), false)
s.SetMap(g.Map{
"k5": "v5",
"k6": "v6",
})
t.Assert(s.Size(), 2)
t.Assert(s.Contains("k5"), true)
t.Assert(s.Contains("k6"), true)
t.Assert(s.MustSize(), 2)
t.Assert(s.MustContains("k5"), true)
t.Assert(s.MustContains("k6"), true)
})
time.Sleep(1000 * time.Millisecond)
gtest.C(t, func(t *gtest.T) {
s := manager.New(context.TODO(), sessionId)
t.Assert(s.Size(), 0)
t.Assert(s.Get("k5"), nil)
t.Assert(s.Get("k6"), nil)
t.Assert(s.MustSize(), 0)
t.Assert(s.MustGet("k5"), nil)
t.Assert(s.MustGet("k6"), nil)
})
}
@ -97,51 +97,51 @@ func Test_StorageRedisPrefix(t *testing.T) {
defer s.Close()
s.Set("k1", "v1")
s.Set("k2", "v2")
s.Sets(g.Map{
s.SetMap(g.Map{
"k3": "v3",
"k4": "v4",
})
t.Assert(s.IsDirty(), true)
sessionId = s.Id()
sessionId = s.MustId()
})
time.Sleep(500 * time.Millisecond)
gtest.C(t, func(t *gtest.T) {
s := manager.New(context.TODO(), sessionId)
t.Assert(s.Get("k1"), "v1")
t.Assert(s.Get("k2"), "v2")
t.Assert(s.Get("k3"), "v3")
t.Assert(s.Get("k4"), "v4")
t.Assert(len(s.Map()), 4)
t.Assert(s.Map()["k1"], "v1")
t.Assert(s.Map()["k4"], "v4")
t.Assert(s.Id(), sessionId)
t.Assert(s.Size(), 4)
t.Assert(s.Contains("k1"), true)
t.Assert(s.Contains("k3"), true)
t.Assert(s.Contains("k5"), false)
t.Assert(s.MustGet("k1"), "v1")
t.Assert(s.MustGet("k2"), "v2")
t.Assert(s.MustGet("k3"), "v3")
t.Assert(s.MustGet("k4"), "v4")
t.Assert(len(s.MustData()), 4)
t.Assert(s.MustData()["k1"], "v1")
t.Assert(s.MustData()["k4"], "v4")
t.Assert(s.MustId(), sessionId)
t.Assert(s.MustSize(), 4)
t.Assert(s.MustContains("k1"), true)
t.Assert(s.MustContains("k3"), true)
t.Assert(s.MustContains("k5"), false)
s.Remove("k4")
t.Assert(s.Size(), 3)
t.Assert(s.Contains("k3"), true)
t.Assert(s.Contains("k4"), false)
t.Assert(s.MustSize(), 3)
t.Assert(s.MustContains("k3"), true)
t.Assert(s.MustContains("k4"), false)
s.RemoveAll()
t.Assert(s.Size(), 0)
t.Assert(s.Contains("k1"), false)
t.Assert(s.Contains("k2"), false)
s.Sets(g.Map{
t.Assert(s.MustSize(), 0)
t.Assert(s.MustContains("k1"), false)
t.Assert(s.MustContains("k2"), false)
s.SetMap(g.Map{
"k5": "v5",
"k6": "v6",
})
t.Assert(s.Size(), 2)
t.Assert(s.Contains("k5"), true)
t.Assert(s.Contains("k6"), true)
t.Assert(s.MustSize(), 2)
t.Assert(s.MustContains("k5"), true)
t.Assert(s.MustContains("k6"), true)
})
time.Sleep(1000 * time.Millisecond)
gtest.C(t, func(t *gtest.T) {
s := manager.New(context.TODO(), sessionId)
t.Assert(s.Size(), 0)
t.Assert(s.Get("k5"), nil)
t.Assert(s.Get("k6"), nil)
t.Assert(s.MustSize(), 0)
t.Assert(s.MustGet("k5"), nil)
t.Assert(s.MustGet("k6"), nil)
})
}

View File

@ -65,7 +65,7 @@ var (
dayOfMonth = []int{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}
)
// Format formats and returns the formatted result with custom <format>.
// Format formats and returns the formatted result with custom `format`.
func (t *Time) Format(format string) string {
if t == nil {
return ""

View File

@ -4,7 +4,7 @@ import (
"database/sql/driver"
)
// Scanner is an interface used by Scan in package database/sql for Scanning value
// Scan implements interface used by Scan in package database/sql for Scanning value
// from database to local golang variable.
func (t *Time) Scan(value interface{}) error {
if t == nil {

View File

@ -63,6 +63,9 @@ func ParseContent(ctx context.Context, content string, params ...Params) (string
// New returns a new view object.
// The parameter `path` specifies the template directory path to load template files.
func New(path ...string) *View {
var (
ctx = context.TODO()
)
view := &View{
paths: garray.NewStrArray(),
data: make(map[string]interface{}),
@ -83,7 +86,7 @@ func New(path ...string) *View {
}
} else {
if errorPrint() {
glog.Errorf("Template directory path does not exist: %s", envPath)
glog.Errorf(ctx, "Template directory path does not exist: %s", envPath)
}
}
} else {

View File

@ -98,6 +98,7 @@ func (view *View) SetConfigWithMap(m map[string]interface{}) error {
// The parameter `path` can be absolute or relative path, but absolute path is suggested.
func (view *View) SetPath(path string) error {
var (
ctx = context.TODO()
isDir = false
realPath = ""
)
@ -126,7 +127,7 @@ func (view *View) SetPath(path string) error {
if realPath == "" {
err := gerror.NewCodef(gcode.CodeInvalidParameter, `[gview] SetPath failed: path "%s" does not exist`, path)
if errorPrint() {
glog.Error(err)
glog.Error(ctx, err)
}
return err
}
@ -134,7 +135,7 @@ func (view *View) SetPath(path string) error {
if !isDir {
err := gerror.NewCodef(gcode.CodeInvalidParameter, `[gview] SetPath failed: path "%s" should be directory type`, path)
if errorPrint() {
glog.Error(err)
glog.Error(ctx, err)
}
return err
}
@ -152,6 +153,7 @@ func (view *View) SetPath(path string) error {
// AddPath adds a absolute or relative path to the search paths.
func (view *View) AddPath(path string) error {
var (
ctx = context.TODO()
isDir = false
realPath = ""
)
@ -180,7 +182,7 @@ func (view *View) AddPath(path string) error {
if realPath == "" {
err := gerror.NewCodef(gcode.CodeInvalidParameter, `[gview] AddPath failed: path "%s" does not exist`, path)
if errorPrint() {
glog.Error(err)
glog.Error(ctx, err)
}
return err
}
@ -188,7 +190,7 @@ func (view *View) AddPath(path string) error {
if !isDir {
err := gerror.NewCodef(gcode.CodeInvalidParameter, `[gview] AddPath failed: path "%s" should be directory type`, path)
if errorPrint() {
glog.Error(err)
glog.Error(ctx, err)
}
return err
}

View File

@ -63,7 +63,7 @@ func (view *View) Parse(ctx context.Context, file string, params ...Params) (res
resource *gres.File
)
// Searching the absolute file path for `file`.
path, folder, resource, err = view.searchFile(file)
path, folder, resource, err = view.searchFile(ctx, file)
if err != nil {
return nil
}
@ -304,7 +304,7 @@ func (view *View) formatTemplateObjectCreatingError(filePath, tplName string, er
// searchFile returns the found absolute path for `file` and its template folder path.
// Note that, the returned `folder` is the template folder path, but not the folder of
// the returned template file `path`.
func (view *View) searchFile(file string) (path string, folder string, resource *gres.File, err error) {
func (view *View) searchFile(ctx context.Context, file string) (path string, folder string, resource *gres.File, err error) {
// Firstly checking the resource manager.
if !gres.IsEmpty() {
// Try folders.
@ -372,7 +372,7 @@ func (view *View) searchFile(file string) (path string, folder string, resource
buffer.WriteString(fmt.Sprintf("[gview] cannot find template file \"%s\" with no path set/add", file))
}
if errorPrint() {
glog.Error(buffer.String())
glog.Error(ctx, buffer.String())
}
err = gerror.NewCodef(gcode.CodeInvalidParameter, `template file "%s" not found`, file)
}

View File

@ -63,7 +63,7 @@ func (v *Validator) Bail() *Validator {
}
// Data is a chaining operation function, which sets validation data for current operation.
// The parameter `data` usually be type of map, which specifies the parameter map used in validation.
// The parameter `data` is usually type of map, which specifies the parameter map used in validation.
// Calling this function also sets `useDataInsteadOfObjectAttributes` true no mather the `data` is nil or not.
func (v *Validator) Data(data interface{}) *Validator {
newValidator := v.Clone()

View File

@ -9,6 +9,7 @@ package gvalid
import (
"github.com/gogf/gf/errors/gcode"
"github.com/gogf/gf/errors/gerror"
"github.com/gogf/gf/text/gstr"
"strconv"
"strings"
"time"
@ -306,7 +307,7 @@ func (v *Validator) doCheckBuildInRules(input doCheckBuildInRulesInput) (match b
// Field value should be in range of.
case "in":
array := strings.Split(input.RulePattern, ",")
array := gstr.SplitAndTrim(input.RulePattern, ",")
for _, v := range array {
if strings.Compare(valueStr, strings.TrimSpace(v)) == 0 {
match = true
@ -317,7 +318,7 @@ func (v *Validator) doCheckBuildInRules(input doCheckBuildInRulesInput) (match b
// Field value should not be in range of.
case "not-in":
match = true
array := strings.Split(input.RulePattern, ",")
array := gstr.SplitAndTrim(input.RulePattern, ",")
for _, v := range array {
if strings.Compare(valueStr, strings.TrimSpace(v)) == 0 {
match = false