package blog4go
import (
"bytes"
"fmt"
"net"
"sync"
)
// SocketWriter 是一个socket日志结构体
type SocketWriter struct {
level LevelType //日志级别
closed bool //链接是否关闭
// log hook
hook Hook //回调函数
hookLevel LevelType //回调函数 对应的日志级别
hookAsync bool //日志是否异步记录
// socket
writer net.Conn //网络链接
lock *sync.Mutex //读写锁
}
// NewSocketWriter 创建一个单例线程写
func NewSocketWriter(network string, address string) (err error) {
singltonLock.Lock()
defer singltonLock.Unlock()
if nil != blog {
return ErrAlreadyInit
}
socketWriter, err := newSocketWriter(network, address)
if nil != err {
return err
}
blog = socketWriter
return nil
}
// newSocketWriter 创建一个写socket 但是不是单例
func newSocketWriter(network string, address string) (socketWriter *SocketWriter, err error) {
socketWriter = new(SocketWriter)
socketWriter.level = DEBUG
socketWriter.closed = false
socketWriter.lock = new(sync.Mutex)
// log hook
socketWriter.hook = nil
socketWriter.hookLevel = DEBUG
conn, err := net.Dial(network, address)
if nil != err {
return nil, err
}
socketWriter.writer = conn
blog = socketWriter
return socketWriter, nil
}
//写日志 并设置日志级别 如果链接是关闭的 直接返回
func (writer *SocketWriter) write(level LevelType, args ...interface{}) {
writer.lock.Lock()
defer writer.lock.Unlock()
if writer.closed {
return
}
defer func() {
// call log hook
if nil != writer.hook && !(level < writer.hookLevel) {
if writer.hookAsync {
go func(level LevelType, args ...interface{}) {
writer.hook.Fire(level, args...)
}(level, args...)
} else {
writer.hook.Fire(level, args...)
}
}
}()
buffer := bytes.NewBuffer(timeCache.Format())
buffer.WriteString(level.prefix())
buffer.WriteString(fmt.Sprint(args...))
writer.writer.Write(buffer.Bytes())
}
//写日志
func (writer *SocketWriter) writef(level LevelType, format string, args ...interface{}) {
writer.lock.Lock()
defer writer.lock.Unlock()
if writer.closed {
return
}
defer func() {
// call log hook
if nil != writer.hook && !(level < writer.hookLevel) {
if writer.hookAsync {
go func(level LevelType, format string, args ...interface{}) {
writer.hook.Fire(level, fmt.Sprintf(format, args...))
}(level, format, args...)
} else {
writer.hook.Fire(level, fmt.Sprintf(format, args...))
}
}
}()
buffer := bytes.NewBuffer(timeCache.Format())
buffer.WriteString(level.prefix())
buffer.WriteString(fmt.Sprintf(format, args...))
writer.writer.Write(buffer.Bytes())
}
// 获取日志级别
func (writer *SocketWriter) Level() LevelType {
return writer.level
}
//设置日志级别
func (writer *SocketWriter) SetLevel(level LevelType) {
writer.level = level
}
//设置回调函数
func (writer *SocketWriter) SetHook(hook Hook) {
writer.hook = hook
}
//设置同步书写文件 如果为真的话
func (writer *SocketWriter) SetHookAsync(async bool) {
writer.hookAsync = async
}
//设置回调函数对应日志级别
func (writer *SocketWriter) SetHookLevel(level LevelType) {
writer.hookLevel = level
}
// TimeRotated暂时什么都不做
func (writer *SocketWriter) TimeRotated() bool {
return false
}
// SetTimeRotated暂时什么都不做
func (writer *SocketWriter) SetTimeRotated(timeRotated bool) {
return
}
// Retentions暂时什么都不做
func (writer *SocketWriter) Retentions() int64 {
return 0
}
// SetRetentions暂时什么都不做
func (writer *SocketWriter) SetRetentions(retentions int64) {
return
}
// RotateSize暂时什么都不做
func (writer *SocketWriter) RotateSize() int64 {
return 0
}
// SetRotateSize暂时什么都不做
func (writer *SocketWriter) SetRotateSize(rotateSize int64) {
return
}
// RotateLines暂时什么都不做
func (writer *SocketWriter) RotateLines() int {
return 0
}
// SetRotateLines暂时什么都不做
func (writer *SocketWriter) SetRotateLines(rotateLines int) {
return
}
// Colored 暂时什么都不做
func (writer *SocketWriter) Colored() bool {
return false
}
// SetColored 暂时什么都不做
func (writer *SocketWriter) SetColored(colored bool) {
return
}
// Close将关闭写流
func (writer *SocketWriter) Close() {
writer.lock.Lock()
defer writer.lock.Unlock()
if writer.closed {
return
}
writer.writer.Close()
writer.writer = nil
writer.closed = true
}
// flush暂时什么都不做
func (writer *SocketWriter) flush() {
return
}
// Trace 日志级别
func (writer *SocketWriter) Trace(args ...interface{}) {
if nil == writer.writer || TRACE < writer.level {
return
}
writer.write(TRACE, args...)
}
// Trac 日志级别
func (writer *SocketWriter) Tracef(format string, args ...interface{}) {
if nil == writer.writer || TRACE < writer.level {
return
}
writer.writef(TRACE, format, args...)
}
// Debug日志级别
func (writer *SocketWriter) Debug(args ...interface{}) {
if nil == writer.writer || DEBUG < writer.level {
return
}
writer.write(DEBUG, args...)
}
// Debugf日志级别
func (writer *SocketWriter) Debugf(format string, args ...interface{}) {
if nil == writer.writer || DEBUG < writer.level {
return
}
writer.writef(DEBUG, format, args...)
}
// Info日志级别
func (writer *SocketWriter) Info(args ...interface{}) {
if nil == writer.writer || INFO < writer.level {
return
}
writer.write(INFO, args...)
}
// Infof日志级别
func (writer *SocketWriter) Infof(format string, args ...interface{}) {
if nil == writer.writer || INFO < writer.level {
return
}
writer.writef(INFO, format, args...)
}
// Warn日志级别
func (writer *SocketWriter) Warn(args ...interface{}) {
if nil == writer.writer || WARNING < writer.level {
return
}
writer.write(WARNING, args...)
}
// Warnf日志级别
func (writer *SocketWriter) Warnf(format string, args ...interface{}) {
if nil == writer.writer || WARNING < writer.level {
return
}
writer.writef(WARNING, format, args...)
}
// Error 日志级别
func (writer *SocketWriter) Error(args ...interface{}) {
if nil == writer.writer || ERROR < writer.level {
return
}
writer.write(ERROR, args...)
}
// Errorf日志级别
func (writer *SocketWriter) Errorf(format string, args ...interface{}) {
if nil == writer.writer || ERROR < writer.level {
return
}
writer.writef(ERROR, format, args...)
}
// Critical日志级别
func (writer *SocketWriter) Critical(args ...interface{}) {
if nil == writer.writer || CRITICAL < writer.level {
return
}
writer.write(CRITICAL, args...)
}
// Criticalf 日志级别
func (writer *SocketWriter) Criticalf(format string, args ...interface{}) {
if nil == writer.writer || CRITICAL < writer.level {
return
}
writer.writef(CRITICAL, format, args...)
}