bingo_log

package module
v0.0.0-...-57f0179 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 22, 2018 License: Apache-2.0 Imports: 9 Imported by: 0

README

bingo-log

基于Go语言的日志处理包

简介

bingo-log 是为了 Bingo 框架而制作的日志模块,我将其单独抽出来,使其可以单独使用而不依赖 Bingo 框架

bingo-log 不依赖官方日志包,完全依靠自己的逻辑实现

Features:

  • 完整的单元测试,覆盖率超过90%
  • 支持5种日志级别( Fatal,Error,Warning,Debug,Info )
  • 同步写入日志
  • 通过协程池异步写入日志
  • 自定义日志命名格式
  • 自定义日志文件分片存储
  • 自定义输出日志或调试信息的抬头
  • 可以自定义连接器,实现日志输出的定制化
  • 内置常见的日志输出以及分片格式,开箱即用(目前实现两种连接器 BaseConnectorKirinConnector)

安装

  go get -u github.com/silsuer/bingo-log

使用

组成

日志结构体如下:

 type Log struct {
	 Connector // 内嵌连接器,用来定制化功能
	 sync.Mutex
	 initialized     bool         // 该日志对象是否初始化
	 mode            int          // 日志记录模式  同步记录 或 协程池记录
	 pool            *grpool.Pool // 协程池
	 poolExpiredTime int          // 协程池模式下,每个空闲协程的存活时间(秒)
	 poolWorkerNum   int          // 协程池模式下,允许的最高协程数
 }

该结构体的 mode 属性目前支持两种模式: LogSyncMode(同步记录模式)和 LogPoolMode(异步协程池记录模式)

当使用 LogSyncMode 的时候,所有日志会同步打印在控制台和输出文件中

当使用 LogPoolMode 时,需指定协程池中的协程数量poolWorkerNum(默认是100) 和 每个空闲协程的存活时间poolExpiredTime(默认是50秒)

主要逻辑的实现都在日志结构体中内嵌的那个 Connector 接口中,所有实现了该接口的结构体都可以通过 Log 结构体的 LoadConnector 方法加载进来,实现自定义自己的日志格式

效果
  1. 使用 BaseConnector:

    将在程序运行目录下创建一个名为 bingo.log 的日志文件,格式为:[日志级别][打印时间][日志内容xxx]

    例如:

       [FATAL] [2018-10-20 00:28:32] fatal testing
       [ERROR] [2018-10-20 00:28:32] Error testing
       [WARNING][2018-10-20 00:28:32] Warning testing
       [DEBUG] [2018-10-20 00:28:32] Debug testing
       [INFO][2018-10-20 00:28:32] Info testing
       [FATAL] [2018-10-20 00:28:32] Fatal testing
       [ERROR] [2018-10-20 00:28:32] Error testing
       [WARNING][2018-10-20 00:28:32] Warning testing
       [DEBUG] [2018-10-20 00:28:32] Debug testing
       [INFO][2018-10-20 00:28:32] Info testing
    
  2. 使用 KirinConnector:

    将在程序运行目录下(或者是在你传入的配置map中指定的root目录下),根据你传入的日期格式(配置map中的 format 键对应的值,默认是 2006_01_02

    生成一个名为 bingo_年_月_日.log 的日志文件

    输出的日志较详细,例如:

       [DEBUG]
       [2018-10-20 00:28:32]
       [FILE] /Users/silsuer/go/src/github.com/silsuer/bingo-log/kirin_test.go
       [LINE] 15
       [CONTENT] KirinConnector Debug testing
    
基本使用过程
  1. 创建日志对象并指定写入模式

    
       log := bingo_log.NewLog(bingo_log.LogSyncMode)  // 同步写入模式
       log := bingo_log.NewLog(bingo_log.LogPoolMode)  // 异步协程池模式
    
    
  2. 如果指定模式为LogPoolMode,需要设置协程过期时间和协程池中的协程数量(当然,不设置使用默认值也可以)

     log.SetPoolExpiredTime(100)  // 设置协程过期时间
     log.SetPoolWorkerNum(100)    // 设置协程池中协程数量
  1. 创建日志连接器并做好初始化工作
  // 对于基础的连接器不需要做其他工作
  conn := new(bingo_log.BaseConnector)

  // 对于 KirinConnector连接器需要传入自定义的配置map
  config := make(map[string]string)
  config["root"] = "/set/any/path"
  config["format"] = "2006_01_02"
  conn := bingo_log.NewKirinConnector(config)

  // 对于你自己实现的连接器emmm你自己开心就好....
  1. 将连接器载入日志对象内
   log.LoadConnector(conn)
  1. 可以愉快的打印了...
  log.Info("testing")
  log.Debug("testing")
  log.Warning("testing")
  log.Error("testing")
  log.Fatal("testing")
进阶: 自定义自己的日志格式

此时我们就需要构建一个属于自己的连接器了,连接器接口 bingo_log.Connector 如下:

  type Connector interface {
  	Fatal(message ...interface{})
  	Error(message ...interface{})
  	Warning(message ...interface{})
  	Debug(message ...interface{})
  	Info(message ...interface{})                           // 打印
  	Output(message string)                                 // 将信息输出到文件中
  	GetMessage(degree int, message ...interface{}) string // 将输入的信息添加抬头(例如添加打印时间等)
  	GetFile(config map[string]string) *os.File             // 当前日志要输出到的文件位置,传入一个map 代表配置
  }

所以我就需要令一个结构体实现该接口的所有方法

例如,我想打印日志的时候,定义输出格式为 "[出错了...] xxxx",并输出在 "/Users/silsuer/go/error.log" 文件中

  1. 那么新建一个结构体:
  type ExampleConnector struct {

  }
  1. 先实现GetMessage方法,所有的打印方法(FatalError等)都会先调用这个方法将传入的参数进行包装
 func (e ExampleConnector) GetMessage(degree int, message ...interface{}) string {
     return "[出错了...]" + fmt.Sprint(message...)
 }
  1. 实现GetFile 方法,返回要写入到的文件指针

      func (e ExampleConnector) GetFile(config map[string]string) *os.File {
        return bingo_log.OpenOrCreateFile("/Users/silsuer/go/error.log")
      }
    
  2. 接下来就是实现其他接口中的其他方法了,基本上照着BaseConnector搬下来就可以:

    其中 Fatal,Error,Warning,Debug,Info 5种方法负责控制输出,在基础连接器中,就是根据不同的日志级别,包装成不同的日志信息,然后

    打印到控制台一份,输出到文件中一份,所以此处你可以对这5种方法进行不同的定制(如果你开心的话),这里我只写一个 Fatal 方法的实现

     func (e ExampleConnector) Fatal(message ...interface{}) {
    	  m := e.GetMessage(bingo_log.FATAL, message...)
    	  fmt.Print(m)
    	  e.Output(m)
     }
    

    再实现 Output 方法,这个方法就是上面那5种方法中调用的要输出到文件中的方法:

      func (e ExampleConnector) Output(message string) {
    	  // 获取到要输出的文件路径
    	  file := e.GetFile(make(map[string]string))
    	  defer file.Close()
    	  n, _ := file.Seek(0, os.SEEK_END)
    	  // 写入数据
    	  file.WriteAt([]byte(message), n)
    }
    
  3. 这样我们就实现了一个完整的连接器了,当然你可以通过结构体组合的形式,减少代码的书写,可以使用了

   func main(){
     log := bingo_log.NewLog(bingo_log.LogSyncMode)  // 同步写入模式
     e := new(ExampleConnector)  // 新建刚刚写好的连接器
     log.LoadConnector(e)        // 加载连接器

     log.Info("成功了...")
     log.Fatal("成功了...")
     // ......
   }

Documentation

Index

Constants

View Source
const (
	LogSyncMode = iota
	LogPoolMode
)
View Source
const (
	FATAL = iota
	ERROR
	WARNING
	DEBUG
	INFO
)

Variables

This section is empty.

Functions

func CreateFile

func CreateFile(path string) *os.File

创建文件 创建目录,如果以 / 号结尾,直接级联建立该目录 如果没有 / 号结尾,将最后一个 / 号后面的字符串作为文件忽略掉

func KirinGetFile

func KirinGetFile(config map[string]string) *os.File

配置一部分根目录 根目录的方式:给定一个根目录,按照当前日期创建文件 得到要输入的文件句柄

func KirinGetMessage

func KirinGetMessage(degree int, message ...interface{}) string

抬头 [时间]+文件+行数+消息

func OpenOrCreateFile

func OpenOrCreateFile(path string) *os.File

Types

type BaseConnector

type BaseConnector struct {
	sync.Mutex
}

基类连接器,实现简单的输出方法

func (BaseConnector) Debug

func (b BaseConnector) Debug(message ...interface{})

func (BaseConnector) Error

func (b BaseConnector) Error(message ...interface{})

func (BaseConnector) Fatal

func (b BaseConnector) Fatal(message ...interface{})

func (BaseConnector) GetFile

func (b BaseConnector) GetFile(config map[string]string) *os.File

返回一个文件句柄,用来写入数据

func (BaseConnector) GetMessage

func (b BaseConnector) GetMessage(degree int, message ...interface{}) string

func (BaseConnector) Info

func (b BaseConnector) Info(message ...interface{})

func (BaseConnector) Output

func (b BaseConnector) Output(message string)

func (BaseConnector) Warning

func (b BaseConnector) Warning(message ...interface{})

type Connector

type Connector interface {
	Fatal(message ...interface{})
	Error(message ...interface{})
	Warning(message ...interface{})
	Debug(message ...interface{})
	Info(message ...interface{})                          // 打印
	Output(message string)                                // 将信息输出到文件中
	GetMessage(degree int, message ...interface{}) string // 将输入的信息添加抬头(例如添加打印时间等)
	GetFile(config map[string]string) *os.File            // 当前日志要输出到的文件位置,传入一个map 代表配置
}

日志连接器接口,所有实现该接口的结构体都可以作为配置参数传入Log中,用来切割文件和异步执行等

type KirinConnector

type KirinConnector struct {
	BaseConnector
	// contains filtered or unexported fields
}

内置连接器

func NewKirinConnector

func NewKirinConnector(config map[string]string) *KirinConnector

func (KirinConnector) Debug

func (k KirinConnector) Debug(message ...interface{})

func (KirinConnector) Error

func (k KirinConnector) Error(message ...interface{})

func (KirinConnector) Fatal

func (k KirinConnector) Fatal(message ...interface{})

func (KirinConnector) GetFile

func (k KirinConnector) GetFile(config map[string]string) *os.File

func (KirinConnector) GetMessage

func (k KirinConnector) GetMessage(degree int, message ...interface{}) string

func (KirinConnector) Info

func (k KirinConnector) Info(message ...interface{})

func (KirinConnector) Output

func (k KirinConnector) Output(message string)

func (KirinConnector) Warning

func (k KirinConnector) Warning(message ...interface{})

type Log

type Log struct {
	Connector // 内嵌连接器,用来定制化功能
	sync.Mutex
	// contains filtered or unexported fields
}
var Logger Log // 全局log

func NewLog

func NewLog(mode int) *Log

func (*Log) AddWaitCount

func (l *Log) AddWaitCount(count int)

func (*Log) Debug

func (l *Log) Debug(message string)

func (*Log) Error

func (l *Log) Error(message string)

func (*Log) Fatal

func (l *Log) Fatal(message string)

重写5种日志级别的打印函数

func (*Log) GetPoolExpiredTime

func (l *Log) GetPoolExpiredTime() int

获取协程池中空闲协程的存活时间(秒)

func (*Log) GetPoolWorkerNum

func (l *Log) GetPoolWorkerNum() int

获取协程池中允许的协程数量

func (*Log) Info

func (l *Log) Info(message string)

func (*Log) IsInitialized

func (l *Log) IsInitialized() bool

判断该结构体是否被初始化

func (*Log) LoadConnector

func (l *Log) LoadConnector(conn Connector)

加载连接器

func (*Log) SetMode

func (l *Log) SetMode(m int)

设置模式

func (*Log) SetPoolExpiredTime

func (l *Log) SetPoolExpiredTime(t int)

设置协程存活时间

func (*Log) SetPoolWorkerNum

func (l *Log) SetPoolWorkerNum(num int)

设置协程数量

func (*Log) WaitAll

func (l *Log) WaitAll()

等待所有job执行完毕

func (*Log) Warning

func (l *Log) Warning(message string)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL