270 lines
4.4 KiB
Go
270 lines
4.4 KiB
Go
|
|
package esLogUtil
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"fmt"
|
|||
|
|
"sync"
|
|||
|
|
"time"
|
|||
|
|
|
|||
|
|
"github.com/elastic/go-elasticsearch/v8"
|
|||
|
|
"goutil/logUtil"
|
|||
|
|
"goutil/stringUtil"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
var (
|
|||
|
|
serverModuleName = "esLog"
|
|||
|
|
esClient *elasticsearch.Client
|
|||
|
|
indexName string //Index名
|
|||
|
|
strServerGroupId string //区服
|
|||
|
|
isStop bool
|
|||
|
|
logChan = make(chan EsLog, 2048)
|
|||
|
|
warnCount = 2000
|
|||
|
|
closedChan = make(chan struct{})
|
|||
|
|
logPool = sync.Pool{
|
|||
|
|
New: func() interface{} {
|
|||
|
|
return &EsLog{}
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// 启动ES日志系统
|
|||
|
|
// 参数:
|
|||
|
|
//
|
|||
|
|
// esUrls:ES地址(多个地址使用,分割)
|
|||
|
|
// name:IndexName
|
|||
|
|
// serverGroupId:服务器组Id
|
|||
|
|
//
|
|||
|
|
// 返回值:
|
|||
|
|
//
|
|||
|
|
// 结果状态
|
|||
|
|
func Start(esUrls string, name string, serverGroupId int32) {
|
|||
|
|
if stringUtil.IsEmpty(esUrls) {
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//构造Es客户端
|
|||
|
|
var err error
|
|||
|
|
esClient, err = elasticsearch.NewClient(elasticsearch.Config{
|
|||
|
|
Addresses: stringUtil.Split(esUrls, []string{","}),
|
|||
|
|
// Retry on 429 TooManyRequests statuses
|
|||
|
|
//
|
|||
|
|
RetryOnStatus: []int{502, 503, 504, 429},
|
|||
|
|
|
|||
|
|
// A simple incremental backoff function
|
|||
|
|
//
|
|||
|
|
RetryBackoff: func(i int) time.Duration { return time.Duration(i) * 100 * time.Millisecond },
|
|||
|
|
|
|||
|
|
// Retry up to 5 attempts
|
|||
|
|
//
|
|||
|
|
MaxRetries: 5,
|
|||
|
|
})
|
|||
|
|
if err != nil {
|
|||
|
|
panic(fmt.Sprintf("构造es对象出错,err:%s", err.Error()))
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
indexName = name
|
|||
|
|
strServerGroupId = fmt.Sprintf("%d", serverGroupId)
|
|||
|
|
|
|||
|
|
//初始化ES
|
|||
|
|
newIndexer(getIndexName())
|
|||
|
|
|
|||
|
|
timedReindex()
|
|||
|
|
|
|||
|
|
startSendProcessor()
|
|||
|
|
|
|||
|
|
guardProcessor()
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 停止服务
|
|||
|
|
func Stop() {
|
|||
|
|
//停止接受日志
|
|||
|
|
isStop = true
|
|||
|
|
|
|||
|
|
if indexer == nil {
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if len(logChan) == 0 {
|
|||
|
|
close(logChan)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
<-closedChan
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//#region 内部方法
|
|||
|
|
|
|||
|
|
func guardProcessor() {
|
|||
|
|
go func() {
|
|||
|
|
defer func() {
|
|||
|
|
if r := recover(); r != nil {
|
|||
|
|
logUtil.LogUnknownError(r)
|
|||
|
|
|
|||
|
|
time.Sleep(1 * time.Second)
|
|||
|
|
guardProcessor()
|
|||
|
|
}
|
|||
|
|
}()
|
|||
|
|
|
|||
|
|
for {
|
|||
|
|
time.Sleep(5 * time.Second)
|
|||
|
|
|
|||
|
|
count := len(logChan)
|
|||
|
|
if count < warnCount {
|
|||
|
|
continue
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
logUtil.NormalLog(fmt.Sprintf("ES日志通道中当前有%d条消息待消费。", count), logUtil.Warn)
|
|||
|
|
}
|
|||
|
|
}()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func startSendProcessor() {
|
|||
|
|
go func() {
|
|||
|
|
defer func() {
|
|||
|
|
if r := recover(); r != nil {
|
|||
|
|
logUtil.LogUnknownError(r)
|
|||
|
|
|
|||
|
|
time.Sleep(1 * time.Second)
|
|||
|
|
startSendProcessor()
|
|||
|
|
}
|
|||
|
|
}()
|
|||
|
|
|
|||
|
|
for {
|
|||
|
|
select {
|
|||
|
|
case logObj, ok := <-logChan:
|
|||
|
|
if ok {
|
|||
|
|
bulkSendHandler(logObj) // 执行刷新
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if len(logChan) == 0 && isStop {
|
|||
|
|
// is closed
|
|||
|
|
closeIndex()
|
|||
|
|
|
|||
|
|
closedChan <- struct{}{}
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func getIndexName() string {
|
|||
|
|
//获取当天日期
|
|||
|
|
return fmt.Sprintf("%s_%s", indexName, time.Now().Format("20060102"))
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 写入在线日志
|
|||
|
|
// 参数:
|
|||
|
|
//
|
|||
|
|
// 日志信息对象
|
|||
|
|
//
|
|||
|
|
// 返回值:
|
|||
|
|
//
|
|||
|
|
// 无
|
|||
|
|
func writeLog(logObj *EsLog) {
|
|||
|
|
if isStop || indexer == nil {
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
logChan <- *logObj
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 组装ES日志对象
|
|||
|
|
// 参数:
|
|||
|
|
//
|
|||
|
|
// logType 日志类型
|
|||
|
|
// format 日志格式
|
|||
|
|
// args 参数列表
|
|||
|
|
//
|
|||
|
|
// 返回值:
|
|||
|
|
//
|
|||
|
|
// 结果状态
|
|||
|
|
func buildLog(logType, format string, args ...interface{}) (newLogObj *EsLog) {
|
|||
|
|
msg := format
|
|||
|
|
if len(args) > 0 {
|
|||
|
|
msg = fmt.Sprintf(format, args...)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//构造新的日志对象
|
|||
|
|
newLogObj = new(logType, msg, strServerGroupId)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//#endregion
|
|||
|
|
|
|||
|
|
//#region 外部方法
|
|||
|
|
|
|||
|
|
// 日志记录
|
|||
|
|
//
|
|||
|
|
// format:日志格式
|
|||
|
|
// logType:日志类型
|
|||
|
|
// args:参数列表
|
|||
|
|
//
|
|||
|
|
// 返回值
|
|||
|
|
//
|
|||
|
|
// 无
|
|||
|
|
func NormalLog(format string, logType logUtil.LogType, args ...interface{}) {
|
|||
|
|
writeLog(buildLog(logType.String(), format, args...))
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 消息日志记录
|
|||
|
|
//
|
|||
|
|
// format:日志格式
|
|||
|
|
// args:参数列表
|
|||
|
|
//
|
|||
|
|
// 返回值
|
|||
|
|
//
|
|||
|
|
// 无
|
|||
|
|
func InfoLog(format string, args ...interface{}) {
|
|||
|
|
writeLog(buildLog("Info", format, args...))
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 警告日志记录
|
|||
|
|
//
|
|||
|
|
// format:日志格式
|
|||
|
|
// args:参数列表
|
|||
|
|
//
|
|||
|
|
// 返回值
|
|||
|
|
//
|
|||
|
|
// 无
|
|||
|
|
func WarnLog(format string, args ...interface{}) {
|
|||
|
|
writeLog(buildLog("Warn", format, args...))
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 调试日志记录
|
|||
|
|
//
|
|||
|
|
// format:日志格式
|
|||
|
|
// args:参数列表
|
|||
|
|
//
|
|||
|
|
// 返回值
|
|||
|
|
//
|
|||
|
|
// 无
|
|||
|
|
func DebugLog(format string, args ...interface{}) {
|
|||
|
|
writeLog(buildLog("Debug", format, args...))
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 错误日志记录
|
|||
|
|
//
|
|||
|
|
// format:日志格式
|
|||
|
|
// args:参数列表
|
|||
|
|
//
|
|||
|
|
// 返回值
|
|||
|
|
//
|
|||
|
|
// 无
|
|||
|
|
func ErrorLog(format string, args ...interface{}) {
|
|||
|
|
writeLog(buildLog("Error", format, args...))
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 致命错误日志记录
|
|||
|
|
//
|
|||
|
|
// format:日志格式
|
|||
|
|
// args:参数列表
|
|||
|
|
//
|
|||
|
|
// 返回值
|
|||
|
|
//
|
|||
|
|
// 无
|
|||
|
|
func FatalLog(format string, args ...interface{}) {
|
|||
|
|
writeLog(buildLog("Fatal", format, args...))
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//#endregion
|