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. 春天JDBC事务管理

    JDBC事务管理 春天提供编程式的事务管理(编程式事务管理)与声明式的事务管理(声明式事务management),为不同的事务实现提供了一致的编程模型,这节以JDBC事务为例,介绍Spring的事务管 ...

  2. SQL 经典语句

    15题需要再分析.没弄懂 使用scott/tiger用户下的emp表和dept表完成下列练习, 表的结构说明如下 emp员工表(empno员工号/ename员工姓名/job工作/mgr上级编号/hir ...

  3. Python中的函数与变量

    本节内容 函数的定义方法 函数功能 函数的返回值 函数的形参与实参 全局变量与局部变量 递归 函数的作用域 匿名函数lambda 函数式编程 常用内置函数 其他内置函数 函数 函数的定义方法 函数就相 ...

  4. sql server求分组最大值,最小值,最大值对应时间,和最小值对应时间

    先创建数据库 CREATE TABLE [dbo].[Students]( [Id] [int] IDENTITY(1,1) NOT NULL, [age] [int] NULL, [name] [n ...

  5. pydev 下Django 1.7 undefined variables from import问题的解决

    参考:http://stackoverflow.com/questions/24951029/pydev-django-undefined-variables-from-import 参考上面的帖子认 ...

  6. Java并发-对象共享

    我们不仅希望防止某个线程正在使用对象状态而其他的线程正在修改该状态,而且希望当一个线程修改了对象状态后,其他的线程能够看到发生的状态变化. 可见性:当读操作和写操作在不同的线程中进行时,他们的动作是共 ...

  7. MQTT入手笔记

    MQTT服务官网:http://mosquitto.org/download/ 在unix系统按照以下步骤运行并启动mqtt服务: 1. # 下载源代码包wget http://mosquitto.o ...

  8. unix中的rm,rmdir的使用

    一.rm的使用 1.基本用法:用于删除文件 rm filename 2.可加属性值 (1)-v rm -v filename 作用:提示删除的情况 (2)-f  rm -f filename 作用:删 ...

  9. JavaScript高级程序设计(二)

    一.函数 1.1 JS中函数无重载,同一作用域下定义两个函数,而不会引发错误,但真正调用的是后面定义的函数.例如: function doAdd(iNum){ alert(iNum+100); } f ...

  10. Intellij-Idea Maven SSH项目的搭建

    添加阿里云镜像 在.m2/settings.xml中, <mirror> <id>nexus-aliyun</id> <name>Nexus aliyu ...