This commit is contained in:
john
2018-08-28 17:06:49 +08:00
parent a526d1cbb0
commit c2fb9443ac
18 changed files with 176 additions and 92 deletions

View File

@ -26,7 +26,11 @@ func NewBool(value...bool) *Bool {
return t
}
func (t *Bool)Set(value bool) {
func (t *Bool) Clone() *Bool {
return NewBool(t.Val())
}
func (t *Bool) Set(value bool) {
if value {
atomic.StoreInt32(&t.val, 1)
} else {
@ -34,6 +38,6 @@ func (t *Bool)Set(value bool) {
}
}
func (t *Bool)Val() bool {
func (t *Bool) Val() bool {
return atomic.LoadInt32(&t.val) > 0
}

View File

@ -21,14 +21,18 @@ func NewByte(value...byte) *Byte {
return &Byte{}
}
func (t *Byte)Set(value byte) {
func (t *Byte) Clone() *Byte {
return NewByte(t.Val())
}
func (t *Byte) Set(value byte) {
atomic.StoreInt32(&t.val, int32(value))
}
func (t *Byte)Val() byte {
func (t *Byte) Val() byte {
return byte(atomic.LoadInt32(&t.val))
}
func (t *Byte)Add(delta int) byte {
func (t *Byte) Add(delta int) byte {
return byte(atomic.AddInt32(&t.val, int32(delta)))
}

View File

@ -22,13 +22,17 @@ func NewBytes(value...[]byte) *Bytes {
return &Bytes{}
}
func (t *Bytes)Set(value []byte) {
func (t *Bytes) Clone() *Bytes {
return NewBytes(t.Val())
}
func (t *Bytes) Set(value []byte) {
t.mu.Lock()
t.val = value
t.mu.Unlock()
}
func (t *Bytes)Val() []byte {
func (t *Bytes) Val() []byte {
t.mu.RLock()
b := t.val
t.mu.RUnlock()

View File

@ -22,15 +22,19 @@ func NewFloat32(value...float32) *Float32 {
return &Float32{}
}
func (t *Float32)Set(value float32) {
func (t *Float32) Clone() *Float32 {
return NewFloat32(t.Val())
}
func (t *Float32) Set(value float32) {
atomic.StoreUint32(&t.val, float32ToUint32InBits(value) )
}
func (t *Float32)Val() float32 {
func (t *Float32) Val() float32 {
return uint32ToFloat32InBits(atomic.LoadUint32(&t.val))
}
func (t *Float32)Add(delta float32) float32 {
func (t *Float32) Add(delta float32) float32 {
return uint32ToFloat32InBits(atomic.AddUint32(&t.val, float32ToUint32InBits(delta)))
}

View File

@ -22,15 +22,19 @@ func NewFloat64(value...float64) *Float64 {
return &Float64{}
}
func (t *Float64)Set(value float64) {
func (t *Float64) Clone() *Float64 {
return NewFloat64(t.Val())
}
func (t *Float64) Set(value float64) {
atomic.StoreUint64(&t.val, float64ToUint64InBits(value) )
}
func (t *Float64)Val() float64 {
func (t *Float64) Val() float64 {
return uint64ToFloat64InBits(atomic.LoadUint64(&t.val))
}
func (t *Float64)Add(delta float64) float64 {
func (t *Float64) Add(delta float64) float64 {
return uint64ToFloat64InBits(atomic.AddUint64(&t.val, float64ToUint64InBits(delta)))
}

View File

@ -6,3 +6,9 @@
// 并发安全的基本类型.
package gtype
type Type = Interface
func New(value ... interface{}) *Type {
return NewInterface(value...)
}

View File

@ -21,14 +21,18 @@ func NewInt(value...int) *Int {
return &Int{}
}
func (t *Int)Set(value int) {
func (t *Int) Clone() *Int {
return NewInt(t.Val())
}
func (t *Int) Set(value int) {
atomic.StoreInt64(&t.val, int64(value))
}
func (t *Int)Val() int {
func (t *Int) Val() int {
return int(atomic.LoadInt64(&t.val))
}
func (t *Int)Add(delta int) int {
func (t *Int) Add(delta int) int {
return int(atomic.AddInt64(&t.val, int64(delta)))
}

View File

@ -21,14 +21,18 @@ func NewInt32(value...int32) *Int32 {
return &Int32{}
}
func (t *Int32)Set(value int32) {
func (t *Int32) Clone() *Int32 {
return NewInt32(t.Val())
}
func (t *Int32) Set(value int32) {
atomic.StoreInt32(&t.val, value)
}
func (t *Int32)Val() int32 {
func (t *Int32) Val() int32 {
return atomic.LoadInt32(&t.val)
}
func (t *Int32)Add(delta int32) int32 {
func (t *Int32) Add(delta int32) int32 {
return atomic.AddInt32(&t.val, delta)
}

View File

@ -21,14 +21,18 @@ func NewInt64(value...int64) *Int64 {
return &Int64{}
}
func (t *Int64)Set(value int64) {
func (t *Int64) Clone() *Int64 {
return NewInt64(t.Val())
}
func (t *Int64) Set(value int64) {
atomic.StoreInt64(&t.val, value)
}
func (t *Int64)Val() int64 {
func (t *Int64) Val() int64 {
return atomic.LoadInt64(&t.val)
}
func (t *Int64)Add(delta int64) int64 {
func (t *Int64) Add(delta int64) int64 {
return atomic.AddInt64(&t.val, delta)
}

View File

@ -23,13 +23,17 @@ func NewInterface(value...interface{}) *Interface {
return &Interface{}
}
func (t *Interface)Set(value interface{}) {
func (t *Interface) Clone() *Interface{
return NewInterface(t.Val())
}
func (t *Interface) Set(value interface{}) {
t.mu.Lock()
t.val = value
t.mu.Unlock()
}
func (t *Interface)Val() interface{} {
func (t *Interface) Val() interface{} {
t.mu.RLock()
b := t.val
t.mu.RUnlock()

View File

@ -22,13 +22,17 @@ func NewString(value...string) *String {
return &String{}
}
func (t *String)Set(value string) {
func (t *String) Clone() *String {
return NewString(t.Val())
}
func (t *String) Set(value string) {
t.mu.Lock()
t.val = value
t.mu.Unlock()
}
func (t *String)Val() string {
func (t *String) Val() string {
t.mu.RLock()
s := t.val
t.mu.RUnlock()

View File

@ -21,14 +21,18 @@ func NewUint(value...uint) *Uint {
return &Uint{}
}
func (t *Uint)Set(value uint) {
func (t *Uint) Clone() *Uint {
return NewUint(t.Val())
}
func (t *Uint) Set(value uint) {
atomic.StoreUint64(&t.val, uint64(value))
}
func (t *Uint)Val() uint {
func (t *Uint) Val() uint {
return uint(atomic.LoadUint64(&t.val))
}
func (t *Uint)Add(delta uint) int {
func (t *Uint) Add(delta uint) int {
return int(atomic.AddUint64(&t.val, uint64(delta)))
}

View File

@ -21,14 +21,18 @@ func NewUint32(value...uint32) *Uint32 {
return &Uint32{}
}
func (t *Uint32)Set(value uint32) {
func (t *Uint32) Clone() *Uint32 {
return NewUint32(t.Val())
}
func (t *Uint32) Set(value uint32) {
atomic.StoreUint32(&t.val, value)
}
func (t *Uint32)Val() uint32 {
func (t *Uint32) Val() uint32 {
return atomic.LoadUint32(&t.val)
}
func (t *Uint32)Add(delta uint32) uint32 {
func (t *Uint32) Add(delta uint32) uint32 {
return atomic.AddUint32(&t.val, delta)
}

View File

@ -21,14 +21,18 @@ func NewUint64(value...uint64) *Uint64 {
return &Uint64{}
}
func (t *Uint64)Set(value uint64) {
func (t *Uint64) Clone() *Uint64 {
return NewUint64(t.Val())
}
func (t *Uint64) Set(value uint64) {
atomic.StoreUint64(&t.val, value)
}
func (t *Uint64)Val() uint64 {
func (t *Uint64) Val() uint64 {
return atomic.LoadUint64(&t.val)
}
func (t *Uint64)Add(delta uint64) uint64 {
func (t *Uint64) Add(delta uint64) uint64 {
return atomic.AddUint64(&t.val, delta)
}

View File

@ -12,38 +12,24 @@ import (
"io"
"sync"
"gitee.com/johng/gf/g/container/gtype"
"gitee.com/johng/gf/g/container/gmap"
)
type Logger struct {
mu sync.RWMutex
pr *Logger // 父级Logger
io io.Writer // 日志内容写入的IO接口
path *gtype.String // 日志写入的目录路径
debug *gtype.Bool // 是否允许输出DEBUG信息
btSkip *gtype.Int // 错误产生时的backtrace回调信息skip条数
stdprint *gtype.Bool // 控制台打印开关,当输出到文件时也同时打印到终端
// @author zseeker,john
mu sync.RWMutex
pr *Logger // 父级Logger
io io.Writer // 日志内容写入的IO接口
path *gtype.String // 日志写入的目录路径
debug *gtype.Bool // 是否允许输出DEBUG信息
btSkip *gtype.Int // 错误产生时的backtrace回调信息skip条数
btEnabled *gtype.Bool // 是否当打印错误时同时开启backtrace打印
allowMulti *gtype.Bool // 控制台打印开关,当输出到文件时也同时打印到终端
}
var (
// 默认的日志对象
logger = New()
// 基于文件路径的logger对象集合用于对象复用
loggerMap = gmap.NewStringInterfaceMap()
logger = New()
)
// 新建自定义的日志操作对象
func New() *Logger {
return &Logger {
io : nil,
path : gtype.NewString(),
debug : gtype.NewBool(true),
btSkip : gtype.NewInt(),
stdprint : gtype.NewBool(true),
}
}
// 日志日志目录绝对路径
func SetPath(path string) {
logger.SetPath(path)

View File

@ -37,33 +37,29 @@ func init() {
}
}
// Logger浅拷贝除了path其他都是父对象属性的指针
func (l *Logger) Clone() *Logger {
// 新建自定义的日志操作对象
func New() *Logger {
return &Logger {
pr : l,
io : l.GetIO(),
path : gtype.NewString(l.path.Val()),
debug : l.debug,
btSkip : l.btSkip,
stdprint : l.stdprint,
io : nil,
path : gtype.NewString(),
debug : gtype.NewBool(true),
btSkip : gtype.NewInt(),
btEnabled : gtype.NewBool(true),
allowMulti : gtype.NewBool(true),
}
}
// 设置下一次输出的日志分类(可以按照文件目录层级设置)在当前logpath或者当前工作目录下创建category目录
// 这是一个链式操作,可以设置多个分类,将会创建层级的日志分类目录。
func (l *Logger) Cat(category string) *Logger {
path := l.path.Val()
if path == "" {
path = gfile.Pwd()
}
path += gfile.Separator + category
if v := loggerMap.Get(path); v != nil {
return v.(*Logger)
} else {
logger := l.Clone()
logger.SetPath(path)
loggerMap.Set(path, logger)
return logger
// Logger深拷贝
func (l *Logger) Clone() *Logger {
return &Logger {
pr : l,
io : l.GetIO(),
path : l.path.Clone(),
debug : l.debug.Clone(),
btSkip : l.btSkip.Clone(),
btEnabled : l.btEnabled.Clone(),
allowMulti : l.allowMulti.Clone(),
}
}
@ -84,9 +80,6 @@ func (l *Logger) GetIO() io.Writer {
l.mu.RLock()
r := l.io
l.mu.RUnlock()
if r == nil && l.pr != nil {
return l.pr.GetIO()
}
return r
}
@ -107,6 +100,10 @@ func (l *Logger) GetDebug() bool {
return l.debug.Val()
}
func (l *Logger) SetBacktrace(enabled bool) {
l.btEnabled.Set(enabled)
}
func (l *Logger) SetDebug(debug bool) {
l.debug.Set(debug)
}
@ -133,7 +130,7 @@ func (l *Logger) SetPath(path string) error {
// @author zseeker
// @date 2018-05-24
func (l *Logger) SetStdPrint(open bool) {
l.stdprint.Set(open)
l.allowMulti.Set(open)
}
// 这里的写锁保证统一时刻只会写入一行日志,防止串日志的情况
@ -146,7 +143,7 @@ func (l *Logger) print(def io.Writer, s string) {
writer = f
// 如果有文件设置那么需要判断是否同时输出到文件和终端
// @author zseeker
if l.stdprint.Val() {
if l.allowMulti.Val() {
writer = io.MultiWriter(writer, def)
}
defer f.Close()
@ -167,11 +164,13 @@ func (l *Logger) stdPrint(s string) {
// 核心打印数据方法(标准错误)
func (l *Logger) errPrint(s string) {
// 记录调用回溯信息
backtrace := l.GetBacktrace(3)
if s[len(s) - 1] == byte('\n') {
s = s + backtrace + ln
} else {
s = s + ln + backtrace + ln
if l.btEnabled.Val() {
backtrace := l.GetBacktrace(3)
if s[len(s) - 1] == byte('\n') {
s = s + backtrace + ln
} else {
s = s + ln + backtrace + ln
}
}
l.print(os.Stderr, s)
}

View File

@ -0,0 +1,41 @@
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://gitee.com/johng/gf.
package glog
import "gitee.com/johng/gf/g/os/gfile"
// 链式操作,设置下一次输出的日志分类(可以按照文件目录层级设置)在当前logpath或者当前工作目录下创建category目录
// 这是一个链式操作,可以设置多个分类,将会创建层级的日志分类目录。
func (l *Logger) Cat(category string) *Logger {
logger := (*Logger)(nil)
if l.pr == nil {
logger = l.Clone()
} else {
logger = l
}
path := l.path.Val()
if path == "" {
path = gfile.Pwd()
}
logger.SetPath(path + gfile.Separator + category)
return logger
}
// 设置文件调用回溯信息
func (l *Logger) Backtrace(enabled bool, skip...int) *Logger {
logger := (*Logger)(nil)
if l.pr == nil {
logger = l.Clone()
} else {
logger = l
}
logger.SetBacktrace(enabled)
if len(skip) > 0 {
logger.SetBacktraceSkip(skip[0])
}
return logger
}

View File

@ -10,7 +10,7 @@ func main() {
Host: "127.0.0.1",
Port: "3306",
User: "root",
Pass: "8692651",
Pass: "123456",
Name: "test",
Type: "mysql",
Role: "master",