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. VueJs(5)---V-bind指令

    V-bind指令 一.概述 v-bind  主要用于属性绑定,比方你的class属性,style属性,value属性,href属性等等,只要是属性,就可以用v-bind指令进行绑定. 示例: < ...

  2. Java数据结构面试题,输出 最后一个 出现次数为1的字符

    今天去面试,遇到一个数据结构题,给定一个字符串,输出 最后一个 出现次数为1的字符 回来研究了下,代码如下: package com.pine.interview.test; import java. ...

  3. 多线程编程 NSOperation

     前言 1.NSThread的使用,虽然也可以实现多线程编程,但是需要我们去管理线程的生命周期,还要考虑线程同步.加锁问题,造成一些性能上的开销.我们也可以配合使用NSOperation和NSOper ...

  4. SVN服务器搭建和配置使用详解

    SVN服务器搭建和使用(一) Subversion是优秀的版本控制工具,其具体的的优点和详细介绍,这里就不再多说. 首先来下载和搭建SVN服务器. 现在Subversion已经迁移到apache网站上 ...

  5. TensorFlow学习记录(一)

    windows下的安装: 首先访问https://storage.googleapis.com/tensorflow/ 找到对应操作系统下,对应python版本,对应python位数的whl,下载. ...

  6. Java 中遇到null 和为空的情况,使用Optional来解决。

    Java 中遇到null 和为空的情况,使用Optional来解决 示例代码: package crazy; import java.util.Optional; class Company { pr ...

  7. 终端字形logo

    网上有很多的项目都有一个自己的字形logo,而我也在开发一个小的项目,也想要生成一个终端字形的logo,于是找到这款小工具,分享给大家:FIGlet “FIGlet is a program for ...

  8. Docker快速入门(二)

    上篇文章<Docker快速入门(一)>介绍了docker的基本概念和image的相关操作,本篇将进一步介绍image,容器和Dockerfile. 1 image文件 (1)Docker ...

  9. 专业、稳定的微信域名被封检测API平台!

    裂变程序最佳配套api,实时检测域名在微信中是否被封,防止见红  还在手动测试域名在微信是否可用?你OUT了! API文档:最简单的GET接口调用方式 API响应:毫秒级响应效率,100%准确率 AP ...

  10. 浏览器选择最新IE渲染

    <meta http-equiv="X-UA-Compatible" content="IE=edge" />