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. .net framework 4 线程安全概述

    线程安全:如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码.如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的.早期的时候, ...

  2. Django(二)如何在IIS中部署django项目

    环境配置 windows7 Django 2.0 python 3.6 wfastcgi 3.0 关键步骤 打开CGI功能 控制面板/程序和功能/打开或关闭windwos功能,如图: 安装wfastc ...

  3. Eclipse两种部署web项目方法

    一).首先使用J2EE的Eclipse的Servers(可以从show view中取出). 1).通过Eclipse建立一个Dynamic Web Project 2).通过Servers视图来创建一 ...

  4. java 垃圾回收总结(1)

    java 垃圾回收总结(1)   以前看过很多次关于垃圾回收相关的文章,都只是看过就忘记了,没有好好的整理一下,发现写文章可以强化自己的记忆. java与C,c++有很大的不同就是java语言开发者不 ...

  5. AOP事务解决方案和分布式事务方案

    http://www.cnblogs.com/jianxuanbing/p/7242254.html http://www.cnblogs.com/jianxuanbing/p/7199457.htm ...

  6. python函数与装饰器

    一.名字空间与作用域 1.名字空间 名字空间:赋值语句创建了约束,用来存储约束的dict被称为名字空间      赋值语句的行为:1.分别在堆和栈中创建obj与name                 ...

  7. 爬虫之proxy(代理)

    proxy简介 proxy即为代理,我们爬虫的时候肯定会有频繁访问某一网站的情况,这个时候有些服务器会识别到我们是非正常访问,就会把我们的IP禁掉,这个时候就需要用代理了. 就好比现实生活中,我需要向 ...

  8. 深入理解javascript 匿名函数和闭包

    代码如下: (function(){ //这里忽略jQuery所有实现 })(); (function(){ //这里忽略jQuery所有实现 })();  半年前初次接触jQuery的时候,我也像其 ...

  9. node.js,express入门看详细篇

    先最简单的代码 安装 npm install express app.js 代码内容 const express = require('express') const app = express() ...

  10. c# 事件和EventManager

    事件 基本用法 关键字event,声明格式为: public event <委托类型> <事件对象> 事件的处理方法:适用于该委托的方法 数据的触发: 绑定同类事件,绑定时,可 ...