Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
L
logtransfer
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
谢宇轩
logtransfer
Commits
65e7f2e2
Commit
65e7f2e2
authored
Feb 13, 2023
by
李世星
Browse files
Options
Browse Files
Download
Plain Diff
fix(合并): 20230213
parents
154ec724
b1573403
Pipeline
#16300
passed with stage
in 0 seconds
Changes
14
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
135 additions
and
77 deletions
+135
-77
Dockerfile
Dockerfile
+1
-1
README.md
README.md
+17
-6
setting.go
conf/setting.go
+9
-4
format.go
entity/format.go
+10
-2
matedata.go
entity/matedata.go
+9
-3
pool.go
entity/pool.go
+6
-3
main.go
main.go
+1
-1
alarm.go
plugin/alarm.go
+12
-25
dump.go
plugin/dump.go
+25
-12
pipeline.go
plugin/pipeline.go
+2
-0
register.go
plugin/register.go
+32
-6
savees.go
plugin/savees.go
+1
-1
collector.go
source/collector.go
+6
-7
topic.go
source/topic.go
+4
-6
No files found.
Dockerfile
View file @
65e7f2e2
FROM
golang:1.16.3
-alpine3.13
as build
FROM
golang:1.16.3 as build
RUN
set
-ex
\
&&
go
env
-w
GO111MODULE
=
on
\
...
...
README.md
View file @
65e7f2e2
### LogTransfer Customer
# LogTransfer Customer
## 原理
# 原理
从Etcd中获取所有在注册的配置,收集需要消费的Topic和对应信息。
# 版本
## 版本
### 1.0.0
1.
从kafka消费数据
2.
管道的形式处理数据
3.
提供数据同步到ES的插件
### 2.0.0
1.
支持动态的安装卸载插件
### 2.1.0
1.
添加动态的配置监控
2.
添加ES消息存储的协程池
### 2.1.1
1.
优化退出信号的监听
2.
修改ES Save的Deadline
# 安装
```
### 2.1.3
1.
更好的支持插件的参数
## 安装
```
shell
docker build
-t
logtransfer:version
.
docker run -
d --name=LTF logtransfer:version
docker run
-
-rm
-d
-v
~/logtransfer/logtransfer.conf:/app/logtransfer.conf
-v
~/logtransfer/transfer.log:/app/log/runtime.log
-v
/etc/localtime:/etc/localtime
--name
=
logtransfer_ijiwei docker.ijiwei.com/logagent/logtransfer:latest
```
conf/setting.go
View file @
65e7f2e2
...
...
@@ -4,6 +4,7 @@ type LogTransferConf struct {
Kafka
`ini:"kafka"`
Etcd
`ini:"etcd"`
Es
`ini:"es"`
Log
`ini:"log"`
}
// kafka 配置
...
...
@@ -22,6 +23,10 @@ type Es struct {
BulkSize
int
`ini:"bulk_size"`
}
type
Log
struct
{
Keywords
string
`ini:"service_keyword"`
}
var
(
APPConfig
=
new
(
LogTransferConf
)
)
entity/format.go
View file @
65e7f2e2
...
...
@@ -6,6 +6,8 @@ import (
"regexp"
"strings"
"time"
"github.com/y7ut/logtransfer/conf"
)
type
Formater
func
(
string
,
string
)
(
Matedata
,
error
)
...
...
@@ -24,10 +26,14 @@ func FormatServiceWfLog(sourceKey string, message string) (Matedata, error) {
mateItem
.
Level
=
message
[
:
levelIndex
]
message
=
message
[
levelIndex
:
]
if
!
strings
.
Contains
(
message
,
"["
)
{
return
*
mateItem
,
fmt
.
Errorf
(
"message format error without time"
)
}
// 给时间调回UTC+8
logTime
,
_
:=
time
.
ParseInLocation
(
": 06-01-02 15:04:05 "
,
message
[
:
strings
.
Index
(
message
,
"["
)],
time
.
FixedZone
(
"UTC"
,
8
*
3600
))
mateItem
.
create
=
logTime
keyword
:=
s
erviceWfLogKeyWord
keyword
:=
s
trings
.
Split
(
conf
.
APPConfig
.
Log
.
Keywords
,
","
)
for
_
,
word
:=
range
keyword
{
flysnowRegexp
:=
regexp
.
MustCompile
(
fmt
.
Sprintf
(
`%s\[(?s:(.*?))\]`
,
word
))
...
...
@@ -60,7 +66,7 @@ func DefaultLog(sourceKey string, message string) (Matedata, error) {
mateItem
.
Topic
=
sourceKey
mateItem
.
Index
=
sourceKey
mateItem
.
Data
=
map
[
string
]
interface
{}{
"message"
:
message
}
mateItem
.
Data
[
"message"
]
=
message
result
:=
*
mateItem
MatePool
.
Put
(
vMateItem
)
...
...
@@ -78,6 +84,8 @@ func DefaultJsonLog(sourceKey string, message string) (Matedata, error) {
if
err
!=
nil
{
return
*
mateItem
,
err
}
mateItem
.
Topic
=
sourceKey
mateItem
.
Data
=
data
result
:=
*
mateItem
...
...
entity/matedata.go
View file @
65e7f2e2
...
...
@@ -13,7 +13,6 @@ import (
var
(
contentRegexp
=
regexp
.
MustCompile
(
`\[(?s:(.*?))\]`
)
serviceWfLogKeyWord
=
[]
string
{
"errno"
,
"logId"
,
"uri"
,
"refer"
,
"cookie"
,
"ua"
,
"host"
,
"clientIp"
,
"optime"
,
"request_params"
,
"errmsg"
}
MatePool
=
sync
.
Pool
{
New
:
func
()
interface
{}
{
return
&
Matedata
{
Data
:
make
(
map
[
string
]
interface
{})}
}}
messages
=
make
(
chan
*
Matedata
,
conf
.
APPConfig
.
Es
.
BulkSize
)
)
...
...
@@ -55,6 +54,7 @@ func MatedateSender(ctx context.Context) {
wp
:=
&
ESWorkPool
{
WorkerFunc
:
func
(
matedatas
[]
*
Matedata
)
bool
{
bulkRequest
:=
esClient
.
Bulk
()
defer
bulkRequest
.
Reset
()
for
_
,
m
:=
range
matedatas
{
indexRequest
:=
elastic
.
NewBulkIndexRequest
()
.
Index
(
m
.
Index
)
.
Doc
(
m
.
Data
)
bulkRequest
.
Add
(
indexRequest
)
...
...
@@ -70,6 +70,14 @@ func MatedateSender(ctx context.Context) {
return
false
}
for
_
,
item
:=
range
response
.
Failed
()
{
if
item
.
Error
==
nil
{
continue
}
log
.
Printf
(
"Find Error in ES Result in (%s): %s"
,
item
.
Index
,
item
.
Error
.
Reason
)
return
false
}
for
_
,
v
:=
range
response
.
Items
{
for
_
,
item
:=
range
v
{
if
item
.
Error
!=
nil
{
...
...
@@ -78,8 +86,6 @@ func MatedateSender(ctx context.Context) {
}
}
}
bulkRequest
.
Reset
()
}
return
true
},
...
...
entity/pool.go
View file @
65e7f2e2
...
...
@@ -63,14 +63,17 @@ func (wp *ESWorkPool) Start() {
go
func
()
{
var
scrath
[]
*
workerChan
for
{
// 清理未使用的时间超过 最大空闲时间的WorkerChan
// 不干活的就得死!
// 因每个worker上存在上次工作时间的标记,因此可以得出协程空闲时间
// 整理时按照空闲时间为协程排序, 将空闲时间大的排到前面
// 清理未使用的时间超过最大空闲时间的Worker,
// 同时记得要清理在Pool中的注册信息, 办理离职手续,不干活的就得死!
wp
.
clean
(
&
scrath
)
// 每隔一段时间检查一次 去进行清理操作,直到下班
select
{
case
<-
stopCh
:
// 工作结束,下班,停止检查摸鱼协程
return
default
:
// 每隔一段时间检查一次 去进行清理操作,直到结束工作,下班
time
.
Sleep
(
wp
.
MaxIdleWorkerDuration
)
}
}
...
...
main.go
View file @
65e7f2e2
...
...
@@ -10,7 +10,7 @@ import (
"github.com/y7ut/logtransfer/transfer"
)
const
version
=
"2.1.
2
"
const
version
=
"2.1.
5
"
var
c
=
flag
.
String
(
"c"
,
"./logtransfer.conf"
,
"使用配置文件启动"
)
var
v
=
flag
.
Bool
(
"v"
,
false
,
"查看当前程序版本"
)
...
...
plugin/alarm.go
View file @
65e7f2e2
package
plugin
import
(
"fmt"
"log"
"time"
"github.com/y7ut/logtransfer/entity"
)
// 打印插件
type
Dump
Plugin
func
(
dump
*
Dump
)
HandleFunc
(
m
*
entity
.
Matedata
)
error
{
log
.
Println
(
"DUMP:"
)
for
k
,
v
:=
range
(
*
m
)
.
Data
{
if
k
==
"timestamp"
{
// 这里需要回显 假设现在是UTC-8
loc
:=
time
.
FixedZone
(
"UTC"
,
-
8
*
3600
)
createdAt
,
err
:=
time
.
ParseInLocation
(
"2006-01-02 15:04:05 "
,
fmt
.
Sprintf
(
"%s"
,
v
),
loc
)
if
err
!=
nil
{
continue
}
// UTC时间就是+8小时
v
=
createdAt
.
UTC
()
.
Format
(
"2006-01-02 15:04:05"
)
}
fmt
.
Printf
(
"%s : %s
\n
"
,
k
,
v
)
}
// 警报与监测
type
Alarm
Plugin
fmt
.
Println
(
"------------"
)
func
(
alarm
*
Alarm
)
HandleFunc
(
m
*
entity
.
Matedata
)
error
{
return
nil
}
func
(
dump
*
Dump
)
SetParams
(
params
string
)
error
{
return
nil
func
(
alarm
*
Alarm
)
SetParams
(
params
string
)
error
{
paramsValue
,
err
:=
checkParams
(
params
,
"hit"
,
"idle_time"
)
if
err
!=
nil
{
return
err
}
alarm
.
params
=
&
paramsValue
return
err
}
plugin/dump.go
View file @
65e7f2e2
package
plugin
import
(
"fmt"
"log"
"time"
"github.com/y7ut/logtransfer/entity"
)
// 警报与监测
type
Alarm
Plugin
func
(
alarm
*
Alarm
)
HandleFunc
(
m
*
entity
.
Matedata
)
error
{
return
nil
}
func
(
alarm
*
Alarm
)
SetParams
(
params
string
)
error
{
// 打印插件
type
Dump
Plugin
paramsValue
,
err
:=
checkParams
(
params
,
"hit"
,
"idle_time"
)
func
(
dump
*
Dump
)
HandleFunc
(
m
*
entity
.
Matedata
)
error
{
log
.
Println
(
"DUMP:"
)
for
k
,
v
:=
range
(
*
m
)
.
Data
{
if
k
==
"timestamp"
{
// 这里需要回显 假设现在是UTC-8
loc
:=
time
.
FixedZone
(
"UTC"
,
-
8
*
3600
)
createdAt
,
err
:=
time
.
ParseInLocation
(
"2006-01-02 15:04:05 "
,
fmt
.
Sprintf
(
"%s"
,
v
),
loc
)
if
err
!=
nil
{
return
err
continue
}
// UTC时间就是+8小时
v
=
createdAt
.
UTC
()
.
Format
(
"2006-01-02 15:04:05"
)
}
fmt
.
Printf
(
"%s : %s
\n
"
,
k
,
v
)
}
alarm
.
params
=
&
paramsValue
return
err
fmt
.
Println
(
"------------"
)
return
nil
}
func
(
dump
*
Dump
)
SetParams
(
params
string
)
error
{
return
nil
}
plugin/pipeline.go
View file @
65e7f2e2
...
...
@@ -14,6 +14,8 @@ type Handler interface {
SetParams
(
string
)
error
}
type
HandlerConstruct
func
()
Handler
type
Plugin
struct
{
params
*
map
[
string
]
interface
{}
// error error
...
...
plugin/register.go
View file @
65e7f2e2
package
plugin
var
RegistedPlugins
=
map
[
string
]
Handler
{
"Dump"
:
&
Dump
{},
"Edit"
:
&
Edit
{},
"SaveES"
:
&
SaveES
{},
"Alarm"
:
&
Alarm
{},
"DingRobot"
:
&
Ding
{},
import
"fmt"
var
RegistedPlugins
=
getRegistedPlugins
()
// 获取注册过的插件插件列表
func
getRegistedPlugins
()
map
[
string
]
HandlerConstruct
{
return
map
[
string
]
HandlerConstruct
{
"Dump"
:
func
()
Handler
{
return
&
Dump
{}
},
"Edit"
:
func
()
Handler
{
return
&
Edit
{}
},
"SaveES"
:
func
()
Handler
{
return
&
SaveES
{}
},
"Alarm"
:
func
()
Handler
{
return
&
Alarm
{}
},
"DingRobot"
:
func
()
Handler
{
return
&
Ding
{}
},
}
}
// 加载当前注册过的插件
func
LoadRegistedPlugins
(
plugin
string
)
(
Handler
,
error
)
{
if
getRegistedPlugins
()[
plugin
]
==
nil
{
return
nil
,
fmt
.
Errorf
(
"not support plugin 【%s】"
,
plugin
)
}
return
getRegistedPlugins
()[
plugin
](),
nil
}
plugin/savees.go
View file @
65e7f2e2
...
...
@@ -11,7 +11,7 @@ import (
type
SaveES
Plugin
func
(
saveEs
*
SaveES
)
HandleFunc
(
m
*
entity
.
Matedata
)
error
{
log
.
Print
ln
(
"SaveES:"
)
log
.
Print
f
(
"SaveES: %s"
,
(
*
saveEs
.
params
)[
"index"
]
)
m
.
Index
=
fmt
.
Sprintf
(
"%s"
,
(
*
saveEs
.
params
)[
"index"
])
m
.
Data
[
"topic"
]
=
m
.
Topic
m
.
Data
[
"level"
]
=
m
.
Level
...
...
source/collector.go
View file @
65e7f2e2
...
...
@@ -90,17 +90,17 @@ func ChooseTopic() (map[*Topic]bool, error) {
// 收集全部的agent的collector信息
ableTopics
:=
make
(
map
[
*
Topic
]
bool
)
// 所有当前
// 所有当前
的收集任务
collectors
,
err
:=
LoadCollectors
()
if
err
!=
nil
{
return
ableTopics
,
fmt
.
Errorf
(
"
L
oad Collector error: %s"
,
err
)
return
ableTopics
,
fmt
.
Errorf
(
"
l
oad Collector error: %s"
,
err
)
}
// 获取所有可用的Topic,用Topic的名字作为索引
topics
,
err
:=
loadTopics
()
if
err
!=
nil
{
return
ableTopics
,
fmt
.
Errorf
(
"
L
oad Topic error: %s"
,
err
)
return
ableTopics
,
fmt
.
Errorf
(
"
l
oad Topic error: %s"
,
err
)
}
// 遍历全部的收集任务,取出全部的使用的topic放入集合中
for
_
,
v
:=
range
collectors
{
currentTopic
:=
topics
[
v
.
Topic
]
ableTopics
[
currentTopic
]
=
true
...
...
@@ -127,7 +127,6 @@ func loadTopics() (map[string]*Topic, error) {
if
err
!=
nil
{
return
topics
,
err
}
topics
[
currentTopicConfig
.
Name
]
=
generateTopic
(
currentTopicConfig
)
}
return
topics
,
nil
...
...
@@ -493,7 +492,7 @@ func getCollectorChangeWithEvent(confResp clientv3.WatchResponse) (different Col
func
getStatusChangeWithEvent
(
confResp
clientv3
.
WatchResponse
)
(
collectors
[]
Collector
,
changeType
string
,
err
error
)
{
changeStatus
:=
fmt
.
Sprintf
(
"%s"
,
confResp
.
Events
[
0
]
.
Kv
.
Value
)
changeStatus
:=
string
(
confResp
.
Events
[
0
]
.
Kv
.
Value
)
// 先对比一下
oldKey
:=
confResp
.
Events
[
0
]
.
Kv
.
Key
...
...
source/topic.go
View file @
65e7f2e2
...
...
@@ -15,14 +15,12 @@ func generateTopic(config TopicConfig) *Topic {
p
:=
plugin
.
PipeLine
{}
// log.Println("get config", currentTopic.PipelineConfig)
for
_
,
v
:=
range
config
.
PipelineConfig
{
currentPlugin
,
ok
:=
plugin
.
RegistedPlugins
[
v
.
Name
]
if
!
ok
{
log
.
Printf
(
"get RegistedPlugins error:%s "
,
v
.
Name
)
continue
currentPlugin
,
err
:=
plugin
.
LoadRegistedPlugins
(
v
.
Name
)
if
err
!=
nil
{
log
.
Panicln
(
"load plugin error:"
,
err
)
}
err
:
=
currentPlugin
.
SetParams
(
v
.
Params
)
err
=
currentPlugin
.
SetParams
(
v
.
Params
)
if
err
!=
nil
{
log
.
Panicln
(
"plugin encode params error:"
,
err
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment