package blog4go

import (
"fmt"
"os"
"time"
)

// ConsoleWriter is a console logger
type ConsoleWriter struct {
blog *BLog
// for stderr
errblog *BLog

redirected bool

closed bool

colored bool

// log hook
hook      Hook
hookLevel LevelType
hookAsync bool
}

// NewConsoleWriter initialize a console writer, singlton
func NewConsoleWriter(redirected bool) (err error) {
singltonLock.Lock()
defer singltonLock.Unlock()
if nil != blog {
return ErrAlreadyInit
}

consoleWriter, err := newConsoleWriter(redirected)
if nil != err {
return err
}

blog = consoleWriter
go consoleWriter.daemon()
return nil
}

// newConsoleWriter initialize a console writer, not singlton
// if redirected, stderr will be redirected to stdout
func newConsoleWriter(redirected bool) (consoleWriter *ConsoleWriter, err error) {
consoleWriter = new(ConsoleWriter)
consoleWriter.blog = NewBLog(os.Stdout)
consoleWriter.redirected = redirected
if !redirected {
consoleWriter.errblog = NewBLog(os.Stderr)
}

consoleWriter.closed = false

consoleWriter.colored = false

// log hook
consoleWriter.hook = nil
consoleWriter.hookLevel = DEBUG
consoleWriter.hookAsync = true

go consoleWriter.daemon()

blog = consoleWriter
return consoleWriter, nil
}

func (writer *ConsoleWriter) daemon() {
f := time.Tick(1 * time.Second)

DaemonLoop:
for {
select {
case <-f:
if writer.closed {
break DaemonLoop
}

writer.flush()
}
}
}

func (writer *ConsoleWriter) write(level LevelType, args ...interface{}) {
if writer.closed {
return
}
defer func() {
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...)
}
}
}()

if !writer.redirected && level >= WARNING {
writer.errblog.write(level, args...)
return
}

writer.blog.write(level, args...)
}

func (writer *ConsoleWriter) writef(level LevelType, format string, args ...interface{}) {
if writer.closed {
return
}

defer func() {

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...))
}
}
}()

if !writer.redirected && level >= WARNING {
writer.errblog.writef(level, format, args...)
return
}

writer.blog.writef(level, format, args...)
}

// Level get level
func (writer *ConsoleWriter) Level() LevelType {
return writer.blog.Level()
}

// SetLevel set logger level
func (writer *ConsoleWriter) SetLevel(level LevelType) {
writer.blog.SetLevel(level)
}

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

// SetColored set logging color
func (writer *ConsoleWriter) SetColored(colored bool) {
if colored == writer.colored {
return
}

writer.colored = colored

initPrefix(colored)
}

// SetHook set hook for logging action
func (writer *ConsoleWriter) SetHook(hook Hook) {
writer.hook = hook
}

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

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

// Close close console writer
func (writer *ConsoleWriter) Close() {
if writer.closed {
return
}

writer.blog.flush()
writer.blog = nil
writer.closed = true
}

// TimeRotated do nothing
func (writer *ConsoleWriter) TimeRotated() bool {
return false
}

// SetTimeRotated do nothing
func (writer *ConsoleWriter) SetTimeRotated(timeRotated bool) {
return
}

// Retentions do nothing
func (writer *ConsoleWriter) Retentions() int64 {
return 0
}

// SetRetentions do nothing
func (writer *ConsoleWriter) SetRetentions(retentions int64) {
return
}

// RotateSize do nothing
func (writer *ConsoleWriter) RotateSize() int64 {
return 0
}

// SetRotateSize do nothing
func (writer *ConsoleWriter) SetRotateSize(rotateSize int64) {
return
}

// RotateLines do nothing
func (writer *ConsoleWriter) RotateLines() int {
return 0
}

// SetRotateLines do nothing
func (writer *ConsoleWriter) SetRotateLines(rotateLines int) {
return
}

// flush buffer to disk
func (writer *ConsoleWriter) flush() {
writer.blog.flush()
}

// Trace trace
func (writer *ConsoleWriter) Trace(args ...interface{}) {
if nil == writer.blog || TRACE < writer.blog.Level() {
return
}

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

// Tracef tracef
func (writer *ConsoleWriter) Tracef(format string, args ...interface{}) {
if nil == writer.blog || TRACE < writer.blog.Level() {
return
}

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

// Debug debug
func (writer *ConsoleWriter) Debug(args ...interface{}) {
if nil == writer.blog || DEBUG < writer.blog.Level() {
return
}

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

// Debugf debugf
func (writer *ConsoleWriter) Debugf(format string, args ...interface{}) {
if nil == writer.blog || DEBUG < writer.blog.Level() {
return
}

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

// Info info
func (writer *ConsoleWriter) Info(args ...interface{}) {
if nil == writer.blog || INFO < writer.blog.Level() {
return
}

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

// Infof infof
func (writer *ConsoleWriter) Infof(format string, args ...interface{}) {
if nil == writer.blog || INFO < writer.blog.Level() {
return
}

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

// Warn warn
func (writer *ConsoleWriter) Warn(args ...interface{}) {
if nil == writer.blog || WARNING < writer.blog.Level() {
return
}

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

// Warnf warnf
func (writer *ConsoleWriter) Warnf(format string, args ...interface{}) {
if nil == writer.blog || WARNING < writer.blog.Level() {
return
}

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

// Error error
func (writer *ConsoleWriter) Error(args ...interface{}) {
if nil == writer.blog || ERROR < writer.blog.Level() {
return
}

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

// Errorf errorf
func (writer *ConsoleWriter) Errorf(format string, args ...interface{}) {
if nil == writer.blog || ERROR < writer.blog.Level() {
return
}

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

// Critical critical
func (writer *ConsoleWriter) Critical(args ...interface{}) {
if nil == writer.blog || CRITICAL < writer.blog.Level() {
return
}

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

// Criticalf criticalf
func (writer *ConsoleWriter) Criticalf(format string, args ...interface{}) {
if nil == writer.blog || CRITICAL < writer.blog.Level() {
return
}

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

consoleWriter.go的更多相关文章

  1. Using FreeMarker templates (FTL)- Tutorial

    Lars Vogel, (c) 2012, 2016 vogella GmbHVersion 1.4,06.10.2016 Table of Contents 1. Introduction to F ...

  2. go第三方日志系统-seelog-Basic sections

    https://github.com/cihub/seelog 文档学习:https://github.com/cihub/seelog/wiki 1.安装: go get github.com/ci ...

  3. go第三方日志系统-seelog-使用文档

    参考:https://godoc.org/github.com/cihub/seelog 导入方式: import "github.com/cihub/seelog" 包seelo ...

  4. Go第七篇之规范的接口

    接口本身是调用方和实现方均需要遵守的一种协议,大家按照统一的方法命名参数类型和数量来协调逻辑处理的过程. Go 语言中使用组合实现对象特性的描述.对象的内部使用结构体内嵌组合对象应该具有的特性,对外通 ...

  5. 07. Go 语言接口

    Go 语言接口 接口本身是调用方和实现方均需要遵守的一种协议,大家按照统一的方法命名参数类型和数量来协调逻辑处理的过程. Go 语言中使用组合实现对象特性的描述.对象的内部使用结构体内嵌组合对象应该具 ...

随机推荐

  1. SDWebImage底层实现原理

    SDWebImage底层实现有沙盒缓存机制,主要由三块组成 1.内存图片缓存2.内存操作缓存3.磁盘沙盒缓存内部实现过程:第一步,下载SDWebImage,导入工程. 第二步,在需要的地方导入头文件 ...

  2. oracle 数据库 date + 1 转载

    http://blog.csdn.net/yjp198713/article/details/18131871 oracle 求两个时间点直接的分钟.小时数 1.获得时间差毫秒数: select ce ...

  3. es6(四):Symbol,Set,Map

    1.Symbol: Symbol中文意思"象征" Symbol:这是一种新的原始类型的值,表示独一无二的值(可以保证不与其它属性名冲突) Symbol()函数前面不能使用new,因 ...

  4. Ubuntu 下命令安装 Java

    1. 使用 java -version 查看系统是否存在 jdk. 2. ubuntu使用的是openjdk,所以我们需要先找到合适的jdk版本.在命令行中输入命令:apt-cache search ...

  5. spring+spring mvc+mybatis 实现主从数据库配置

    一.配置文件 1.jdbc.properties master_driverUrl=jdbc:mysql://localhost:3306/shiro?useUnicode=true&char ...

  6. 启动SpringBoot的可执行jar 报错:target\spring-boot-hello-1.0-SNAPSHOT.jar中没有主清单属性

    打包成功,但是在执行时报错,没有主清单属性 解决: 增加红框内的依赖: <build> <plugins> <plugin> <groupId>org. ...

  7. Hibernate二级缓存简述及基于Spring4,Hibernate5,Ehcache3的二级缓存配置

    Hibernate L2缓存 缓存的分类 L2缓存工作原理 放入二级缓存的数据 Ehcache 依赖 ehcache.xml 常用的memoryStoreEvictionPolicy(缓存算法) eh ...

  8. flume安装及入门实例

    1. 如何安装? 1)将下载的flume包,解压到/home/hadoop目录中 2)修改 flume-env.sh 配置文件,主要是JAVA_HOME变量设置 root@m1:/home/hadoo ...

  9. ImportError: numpy.core.multiarray failed to import

    1. ImportError: numpy.core.multiarray failed to import pip install -U numpy http://stackoverflow.com ...

  10. STM32f030f4p6 内部flash 打包读写

    最近做到的项目在运行需要把一组uint8_t(unsigned char)的数据进行掉电储存,想到单片机STM32f030f4p6内部flash可以直接由程序操作,写了以下代码用于uint8_t数据打 ...