package blog4go

import (
"errors"
"fmt"
)

var (
// ErrFilePathNotFound 文件路径找不到
ErrFilePathNotFound = errors.New("File Path must be defined")
// ErrInvalidLevel  非法日志级别
ErrInvalidLevel = errors.New("Invalid level string")
// ErrInvalidRotateType 非法管理类型
ErrInvalidRotateType = errors.New("Invalid log rotate type")
)

// MultiWriter struct defines an instance for multi writers with different message level
//MultiWriter 定义一个多写结构  带着不同的日志级别
type MultiWriter struct {
level LevelType

// file writers  不同级别对应不同的写通道
writers map[LevelType]Writer
        //颜色设置
colored bool
      //连接是否关闭的标志
closed bool

//配置回调函数
hook Hook
//回调函数日志级别设置
hookLevel LevelType
//回调函数 是同步还是异步执行
hookAsync bool

//管理日志频率
timeRotated bool
       //耗时
retentions  int64
       //循环次数
rotateSize  int64
rotateLines int
}

// TimeRotated get timeRotated
func (writer *MultiWriter) TimeRotated() bool {
return writer.timeRotated
}

// SetTimeRotated toggle time base logrotate
func (writer *MultiWriter) SetTimeRotated(timeRotated bool) {
writer.timeRotated = timeRotated
for _, fileWriter := range writer.writers {
fileWriter.SetTimeRotated(timeRotated)
}
}

// Retentions get retentions
func (writer *MultiWriter) Retentions() int64 {
return writer.retentions
}

// SetRetentions set how many logs will keep after logrotate
func (writer *MultiWriter) SetRetentions(retentions int64) {
if retentions < 1 {
return
}

writer.retentions = retentions
for _, fileWriter := range writer.writers {
fileWriter.SetRetentions(retentions)
}
}

// RotateSize get rotateSize
func (writer *MultiWriter) RotateSize() int64 {
return writer.rotateSize
}

// SetRotateSize set size when logroatate
func (writer *MultiWriter) SetRotateSize(rotateSize int64) {
writer.rotateSize = rotateSize
for _, fileWriter := range writer.writers {
fileWriter.SetRotateSize(rotateSize)
}
}

// RotateLines get rotateLines
func (writer *MultiWriter) RotateLines() int {
return writer.rotateLines
}

// SetRotateLines set line number when logrotate
func (writer *MultiWriter) SetRotateLines(rotateLines int) {
writer.rotateLines = rotateLines
for _, fileWriter := range writer.writers {
fileWriter.SetRotateLines(rotateLines)
}
}

// Colored get colored
func (writer *MultiWriter) Colored() bool {
return writer.colored
}

// SetColored set logging color
func (writer *MultiWriter) SetColored(colored bool) {
writer.colored = colored
for _, fileWriter := range writer.writers {
fileWriter.SetColored(colored)
}
}

// SetHook set hook for every logging actions
func (writer *MultiWriter) SetHook(hook Hook) {
writer.hook = hook
}

// SetHookAsync set hook async for base file writer
func (writer *MultiWriter) SetHookAsync(async bool) {
writer.hookAsync = async
}

// SetHookLevel set when hook will be called
func (writer *MultiWriter) SetHookLevel(level LevelType) {
writer.hookLevel = level
}

// SetLevel set logging level threshold
func (writer *MultiWriter) SetLevel(level LevelType) {
writer.level = level
for _, fileWriter := range writer.writers {
fileWriter.SetLevel(level)
}
}

// Level return logging level threshold
func (writer *MultiWriter) Level() LevelType {
return writer.level
}

// Close close file writer
func (writer *MultiWriter) Close() {
for _, fileWriter := range writer.writers {
fileWriter.Close()
}
writer.closed = true
}

func (writer *MultiWriter) write(level LevelType, args ...interface{}) {
defer func() {
// 异步调用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...)
}
}
}()

writer.writers[level].write(level, args...)
}

func (writer *MultiWriter) writef(level LevelType, format string, args ...interface{}) {
defer func() {
// 异步调用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...))

}
}
}()

writer.writers[level].writef(level, format, args...)
}

// flush flush logs to disk
func (writer *MultiWriter) flush() {
for _, writer := range writer.writers {
writer.flush()
}
}

// Trace trace
func (writer *MultiWriter) Trace(args ...interface{}) {
_, ok := writer.writers[TRACE]
if !ok || TRACE < writer.level {
return
}

writer.write(TRACE, args...)
}

// Tracef tracef
func (writer *MultiWriter) Tracef(format string, args ...interface{}) {
_, ok := writer.writers[TRACE]
if !ok || TRACE < writer.level {
return
}

writer.writef(TRACE, format, args...)
}

// Debug debug
func (writer *MultiWriter) Debug(args ...interface{}) {
_, ok := writer.writers[DEBUG]
if !ok || DEBUG < writer.level {
return
}

writer.write(DEBUG, args...)
}

// Debugf debugf
func (writer *MultiWriter) Debugf(format string, args ...interface{}) {
_, ok := writer.writers[DEBUG]
if !ok || DEBUG < writer.level {
return
}

writer.writef(DEBUG, format, args...)
}

// Info info
func (writer *MultiWriter) Info(args ...interface{}) {
_, ok := writer.writers[INFO]
if !ok || INFO < writer.level {
return
}

writer.write(INFO, args...)
}

// Infof infof
func (writer *MultiWriter) Infof(format string, args ...interface{}) {
_, ok := writer.writers[INFO]
if !ok || INFO < writer.level {
return
}

writer.writef(INFO, format, args...)
}

// Warn warn
func (writer *MultiWriter) Warn(args ...interface{}) {
_, ok := writer.writers[WARNING]
if !ok || WARNING < writer.level {
return
}

writer.write(WARNING, args...)
}

// Warnf warnf
func (writer *MultiWriter) Warnf(format string, args ...interface{}) {
_, ok := writer.writers[WARNING]
if !ok || WARNING < writer.level {
return
}

writer.writef(WARNING, format, args...)
}

// Error error
func (writer *MultiWriter) Error(args ...interface{}) {
_, ok := writer.writers[ERROR]
if !ok || ERROR < writer.level {
return
}

writer.write(ERROR, args...)
}

// Errorf error
func (writer *MultiWriter) Errorf(format string, args ...interface{}) {
_, ok := writer.writers[ERROR]
if !ok || ERROR < writer.level {
return
}

writer.writef(ERROR, format, args...)
}

// Critical critical
func (writer *MultiWriter) Critical(args ...interface{}) {
_, ok := writer.writers[CRITICAL]
if !ok || CRITICAL < writer.level {
return
}

writer.write(CRITICAL, args...)
}

// Criticalf criticalf
func (writer *MultiWriter) Criticalf(format string, args ...interface{}) {
_, ok := writer.writers[CRITICAL]
if !ok || CRITICAL < writer.level {
return
}

writer.writef(CRITICAL, format, args...)
}

multiWriter.go的更多相关文章

  1. tee MultiWriter creates a writer that duplicates its writes to all the // provided writers, similar to the Unix tee(1) command.

    https://zh.wikipedia.org/wiki/Tee 在计算机科学中,tee是一个常见的指令,它能够将某个指令的标准输出,导向.存入某个档案中.许多不同的命令行界面(Shell)都提供这 ...

  2. Spike Notes on Lock based Concurrency Concepts

    Motivation 承并发编程笔记Outline,这篇文章专注于记录学习基于锁的并发概念的过程中出现的一些知识点,为并发高层抽象做必要的准备. 尽管存在Doug Lee开山之作Concurrent ...

  3. Golang学习 - io 包

    ------------------------------------------------------------ 先说一下接口,Go 语言中的接口很简单,在 Go 语言的 io 包中有这样一个 ...

  4. c++ freelockquque

    http://www.boost.org/doc/libs/1_56_0/doc/html/boost/lockfree/queue.html Class template queue boost:: ...

  5. boost 无锁队列

    一哥们翻译的boost的无锁队列的官方文档 原文地址:http://blog.csdn.net/great3779/article/details/8765103 Boost_1_53_0终于迎来了久 ...

  6. log4go的输出优化

    又看了一些golang的日志包和相关的文章,仔细阅读了go 1.9.2系统提供的log和go-log,产生了对log4go的日志输出进行优化的想法. 结构化与multiwriter log使用mult ...

  7. nxlog4go 简介 - 基于log4go的下一代go语言日志系统

    nxlog4go的项目网址: https://github.com/ccpaging/nxlog4go 项目历史 ccpaging's log4go forked from https://githu ...

  8. nxlog4go 按天或按文件大小分割日志

    Building a new rotate file writer: rfw := l4g.NewRotateFileWriter("_rfw.log").SetMaxSize(1 ...

  9. Go语言标准库_输入/输出

    Go语言标准库_输入/输出 转载节选自<Go语言标准库> Reader 接口 type Reader interface { Read(p []byte) (n int, err erro ...

随机推荐

  1. DB Query Analyzer 5.02 is distributed, 53 articles concerned have been published

    DB Query Analyzer is presented by Master Gen feng, Ma from Chinese Mainland. It has English version ...

  2. CDH安装系统环境准备——系统版本和安装包下载地址指南

    由于Hadoop深受客户欢迎,许多公司都推出了各自版本的Hadoop,也有一些公司则围绕Hadoop开发产品.在Hadoop生态系统中,规模最大.知名度最高的公司则是Cloudera.接下来的日子里, ...

  3. Spring Boot 添加jersey-mvc-freemarker依赖后内置tomcat启动不了解决方案

    我在我的Spring Boot 项目的pom.xml中添加了jersey-mvc-freemarker依赖后,内置tomcat启动不了. 报错信息如下: org.springframework.con ...

  4. N-Queens(N皇后问题)

    题目: The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two que ...

  5. x&(x-1)

    x&(x-1)可以用来求出x是否为2幂次方数:当&的结果为0时,x原值是2幂次方数,否则就不是2幂次方数: x=x&(x-1)即把x从低位开始的第一个1改成0.如1000,把1 ...

  6. 《深入理解java虚拟机》读书笔记1--java内存区域

    Java内存管理 本文主要介绍Java虚拟机运行时的内存区域是如何划分的.Java对象的创建过程.Java对象的内存布局.Java对象的访问定位 一:运行时区域划分 主要可以分为以下 几个: 程序计数 ...

  7. 多台或者集群环境下如何保证spring定时器只执行一个

    先说一下我们的系统, 在65和66上分别部署有weblogic节点,共计四个,在项目中我们的定时器会隔一段时间就从其它的五个系统中取数据,这时就出现了问题,本来取一次数据就可以的,现在重复执行了三次, ...

  8. CSS的应用下

    样式继承: 就是父类的颜色如果变了,子类下的div(或者其他属性)会继承父类的. 参考代码: <!DOCTYPE html> <html lang="en"> ...

  9. Fiddler - 工具配置及在ios抓取不了https的解决方法

    一.首先,官网下载最新版fiddler工具: https://www.telerik.com/fiddler 二.打开fiddler,点击Tools - Options 我电脑上的各项配置如下图(也可 ...

  10. (二)SpringBoot基础篇- 静态资源的访问及Thymeleaf模板引擎的使用

    一.描述 在应用系统开发的过程中,不可避免的需要使用静态资源(浏览器看的懂,他可以有变量,例:HTML页面,css样式文件,文本,属性文件,图片等): 并且SpringBoot内置了Thymeleaf ...