<commit_before>// Copyright 2015
// Author: <EMAIL>

package blog4go

import (
	"bufio"
	"errors"
	"fmt"
	"os"
	"strconv"
	"sync"
	"time"
)

// 各种日志结构接口
type LogWriter interface {
	// 关闭log writer的处理方法
	// 善后
	Close()

	// 用于内部写log的方法
	write(level Level, format string)
	writef(level Level, format string, args ...interface{})

	// 供用户强制刷日志到输出
	Flush()
}

var DefaultFileLogWriter *FileLogWriter = new(FileLogWriter)

const (
	// 好像buffer size 调大点benchmark效果更好
	DefaultBufferSize = 4096
)

// 装逼的logger
type FileLogWriter struct {
	level Level

	// log文件
	filename string
	file     *os.File
	writer   *bufio.Writer

	// TODO logrotate
	rotate bool

	lock   *sync.RWMutex
	closed bool
}

// 包初始化函数
func init() {
	timeCache.now = time.Now()
	timeCache.format = timeCache.now.Format("[2006/01/02:15:04:05]")
}

// 创建file writer
func NewFileLogWriter(filename string) (fileWriter *FileLogWriter, err error) {
	fileWriter = new(FileLogWriter)

	// 打开文件描述符
	file, err := os.OpenFile(filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, os.FileMode(0644))
	if nil != err {
		return nil, err
	}
	fileWriter.filename = filename
	fileWriter.file = file
	fileWriter.writer = bufio.NewWriterSize(file, DefaultBufferSize)
	fileWriter.lock = new(sync.RWMutex)
	fileWriter.closed = false

	go fileWriter.daemon()

	return fileWriter, nil
}

func (self *FileLogWriter) Close() {
	self.lock.Lock()
	self.writer.Flush()
	self.file.Close()
	self.writer = nil
	self.closed = false
	self.lock.Unlock()
}

func (self *FileLogWriter) Flush() {
	self.writer.Flush()
}

func (self *FileLogWriter) SetLevel(level Level) *FileLogWriter {
	self.level = level
	return self
}

func (self *FileLogWriter) GetLevel() Level {
	return self.level
}

// 时间格式化的cache
type timeFormatCacheType struct {
	now    time.Time
	format string
}

var timeCache = timeFormatCacheType{}

// 常驻goroutine, 更新格式化的时间及logrotate
func (self *FileLogWriter) daemon() {
	t := time.Tick(1 * time.Second)
	for {
		select {
		case <-t:
			now := time.Now()
			timeCache.now = now
			timeCache.format = now.Format("[2006/01/02:15:04:05]")

		}
	}

}

func (self *FileLogWriter) write(level Level, format string, args ...interface{}) {
	if level < self.level {<commit_msg>bug fix<commit_after>// Copyright 2015
// Author: <EMAIL>

package blog4go

import (
	"bufio"
	"errors"
	"os"
	"strconv"
	"sync"
	"time"
)

// 各种日志结构接口
type LogWriter interface {
	// 关闭log writer的处理方法
	// 善后
	Close()

	// 用于内部写log的方法
	write(level Level, format string)
	writef(level Level, format string, args ...interface{})

	// 供用户强制刷日志到输出
	Flush()
}

var DefaultFileLogWriter *FileLogWriter = new(FileLogWriter)

const (
	// 好像buffer size 调大点benchmark效果更好
	DefaultBufferSize = 4096
)

// 装逼的logger
type FileLogWriter struct {
	level Level

	// log文件
	filename string
	file     *os.File
	writer   *bufio.Writer

	// TODO logrotate
	rotate bool

	lock   *sync.RWMutex
	closed bool
}

// 时间格式化的cache
type timeFormatCacheType struct {
	now    time.Time
	format string
}

// 包初始化函数
func init() {
	timeCache.now = time.Now()
	timeCache.format = timeCache.now.Format("[2006/01/02:15:04:05]")
}

// 创建file writer
func NewFileLogWriter(filename string) (fileWriter *FileLogWriter, err error) {
	fileWriter = new(FileLogWriter)

	// 打开文件描述符
	file, err := os.OpenFile(filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, os.FileMode(0644))
	if nil != err {
		return nil, err
	}
	fileWriter.filename = filename
	fileWriter.file = file
	fileWriter.writer = bufio.NewWriterSize(file, DefaultBufferSize)
	fileWriter.lock = new(sync.RWMutex)
	fileWriter.closed = false

	go fileWriter.daemon()

	return fileWriter, nil
}

func (self *FileLogWriter) Close() {
	self.lock.Lock()
	self.writer.Flush()
	self.file.Close()
	self.writer = nil
	self.closed = false
	self.lock.Unlock()
}

func (self *FileLogWriter) Flush() {
	self.writer.Flush()
}

func (self *FileLogWriter) SetLevel(level Level) *FileLogWriter {
	self.level = level
	return self
}

func (self *FileLogWriter) GetLevel() Level {
	return self.level
}

var timeCache = timeFormatCacheType{}

// 常驻goroutine, 更新格式化的时间及logrotate
func (self *FileLogWriter) daemon() {
	t := time.Tick(1 * time.Second)
	for {
		select {
		case <-t:
			now := time.Now()
			timeCache.now = now
			timeCache.format = now.Format("[2006/01/02:15:04:05]")

		}
	}

}

func (self *FileLogWriter) write(level Level, format string, args ...interface{}) {
	if level < self.level {
{'fraction_non_alphanumeric': 0.12929660824038242, 'fraction_numerical': 0.01912132938766219, 'mean_word_length': 3.849889624724062, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1238119', 'n_tokens_mistral': 1815, 'n_tokens_neox': 1770, 'n_words': 378}