背景介绍
造轮子的原因?
- filebeat 在我司日志采集的时候 CPU 占用很高
- 采集日志到 clickhouse 需要 filebeat 和类似 kafka 的工具配合使用,维护成本变高
- 市面上没有其他 log 文件直接采集到 clickhouse 的工具
稳定性怎么样?
- 截至这篇文章发表,已经稳定在我司线上跑了一周了
log2ck
此工具能将monolog标准log直接通过tcp协议实时写入clickhouse。如果你会写正则,其他标准化log也能支持。
项目地址:https://github.com/hisune/log2ck 欢迎star
特性
- 极简代码
- 高性能(在线上业务中对比cpu占用仅为
filebeat
的1/20) - 无第三方服务依赖(例如队列等)
- 配置化
- 定制化(自定义正则、行处理回调函数)
- 支持读取按天分割的log
- 支持断点续传采集
使用规范
- 如果使用默认正则,则需要待读取的日志文件必须是标准的默认monolog日志格式文件,且monolog的
name
和group
名称不能包含空格 - 待读取的日志必须是一行一条,例如monolog需要设置formatter为:
allowInlineLineBreaks' => false
使用方法
composer require "hisune/log2ck"
# vim manager.php
use Hisune\Log2Ck\Manager;
require_once 'vendor/autoload.php';
(new Manager(__DIR__ . DIRECTORY_SEPARATOR . 'config.php'))->run();
# php manager.php
config.php配置举例
return [
'env' => [ // 系统环境变量
// 'bin' => [
// 'php' => '/usr/bin/php', // 可选配置,php bin文件所属路径
// ],
'clickhouse' => [ // 必须的配置
'server' => [
'host' => '192.168.37.205',
'port' => '8123',
'username' => 'default',
'password' => '',
],
'database' => 'logs', // 入库名称
'table' => 'repo', // 入库表
],
// 'worker' => [
// 'cache_path' => '/dev/shm/', // 可选配置,worker缓存目录
// ],
// 'logger' => [
// 'enable' => true, // 可选配置,是否记录日志
// 'path' => __DIR__ . DIRECTORY_SEPARATOR . 'logs' . DIRECTORY_SEPARATOR, // 指定记录日志的目录,可选配置,需要以/结尾
// ],
],
'tails' => [
'access' => [ // key为日志名称,对应于clickhouse的name
'repo' => 'api2', // 日志所属的项目名称
'path' => '/mnt/c/access.log', // 日志路径,固定文件名日志
// 'path' => '/mnt/c/access-{date}.log', // 日志路径,每日一个文件名的日志,当前只支持{date}一个宏变量,date格式举例:2022-02-22
// 'pattern' => '/\[(?P<created_at>.*)\] (?P<logger>\w+).(?P<level>\w+): (?P<message>.*[^ ]+) (?P<context>[^ ]+) (?P<extra>[^ ]+)/', // 可选配置,如果不需要正则处理,设置为false
// 'callback' => function($data) { // 可选配置,对这行数据按自定义回调方法进行处理,方法内容可以自行实现任何清洗此条流水的逻辑
// $data['message'] = 'xxoo'; // 举例,自定义处理这个数据
// return $data;
// }
],
],
];
supervisord
推荐使用supervisor管理你的manager进程。
[program:log2ck]
directory=/data/log2ck
command=php manager.php
user=root
autostart=true
autorestart=true
startretries=10
stderr_logfile=/data/logs/err.log
stdout_logfile=/data/logs/out.log
clickhouse日志表结构
如果使用monolog并且使用的是默认正则,可直接使用下面的表结构,如果是自定义正则,可以根据自己的正则匹配结果自定义自己的clickhouse表结构。
create table repo
(
repo LowCardinality(String) comment '项目名称',
name LowCardinality(String) comment '日志名称',
host LowCardinality(String) comment '日志产生的机器',
created_at DateTime,
logger LowCardinality(String),
level LowCardinality(String),
message String,
context String,
extra String
) engine = MergeTree()
PARTITION BY toDate(created_at)
ORDER BY (created_at, repo, host)
TTL created_at + INTERVAL 10 DAY;
如果你的message或context的内容是json
,可以参考clickhouse的json查询函数:https://clickhouse.com/docs/en/sql-reference/functions/json-functions/
TODO
- 进一步提升写入性能:单次插入改为批量插入
如果您觉得您在我这里学到了新姿势,博主支持转载,姿势本身就是用来相互学习的。同时,本站文章如未注明均为 hisune 原创 请尊重劳动成果 转载请注明 转自: 实时同步日志到clickhouse - hisune.com
0 Comments