内外网分离日志方案 rsyslog logstash tencent oss rabbitMq

在公司的一周时间中,整理了一下咱们本身的日志方案python

需求

  1. 分为内网和外网
  2. 分为实时日志和非实时日志
  3. 实时日志经过消息队列通道传到内网中,处理后存储到ES中
  4. 非实时日志上传到腾讯云OSS,而后同步到内网中,做为后续的日志分析,处理后存储到ES和内网中CEPH对象存储中

技术选型

系统 ubuntu18.04,其余带有rsyslog8.x的系统便可,没有也能够安装一个docker

利用系统服务:rsyslog 8.4.20json

logstash 7.13.0ubuntu

elasticsearch 7.8.0vim

日志格式咱们使用了服务器

HOSTNAME PROGRAME JSON字符串
复制代码

为何使用JSON字符串,确定方便后续的程序去处理它,虽然增长了一些空间。markdown

工做流程

程序写rsyslog日志 -> rsyslog转发到logstash -> logstash对实时日志和非实时日志分流到消息队列和对象存储并发

一个简单的日志格式

data yq-data: {"type": "off-line", "time": "2021-06-23T07:03:55.122584Z", "msg": "I am a log message", "level": "DEBUG"}
复制代码

配置rsyslog

vim /etc/rsyslog.confelasticsearch

增长下面配置高并发

local7.* @@logstash-host:5514
复制代码

logstash-host:5514 为logstash启动syslog的IP和端口 local7为rsyslog的facility

增长一个rsyslog的配置,在/etc/rsyslog.d下面

vim /etc/rsyslog.d/20-default.conf,填入下面内容

template(name="DynaFile" type="string" string="/var/log/%programname%/%programname%.log")

local7.* action(type="omfile" dynaFile="DynaFile")
复制代码

配置完成后重启systemctl restart rsyslog

什么意思呢,就是从local7发过来的日志,都会存储到/var/log/日志格式中的PROGRAME/日志格式中的PROGRAME.log文件

为何要这样作呢?是为了避免仅仅咱们将日志发到logstash,还在咱们本地也存放一份,毕竟不能保证logstash彻底百分百分一直运转,当他出错的时候咱们能够经过filebeats重新抽取一遍,或者直接丢给咱们的日志程序去处理一下

python logging为例

# address rsyslog的IP和端口
SysLogHandler(facility=SysLogHandler.LOG_LOCAL7, address=("172.16.102.227", 514))
复制代码

再来配置logrotate

顾名思义,就是日志轮转,咱们配置天天轮转,保存30天的日志,具体的去看下logrotate的文档就好了

vim /etc/logrotate/custom-log

/var/log/yq*/*.log
{
    rotate 30
    daily
    missingok
    notifempty
    delaycompress
    nocompress
    postrotate
        systemctl kill -s HUP rsyslog.service
    endscript
}
复制代码

这里为何用yq*,由于项目太多了,因此咱们为全部的项目定一个前缀,固然你也能够本身处理它

配置 logstash

vim /etc/logstash/conf.d/my.conf

input {
    syslog {
        port => 5514
    }
}

filter {
    json {
        source => "message"
    }
    prune {
        whitelist_names => [ "msg", "logsource", "program", "time", "level", "type" ]
    }
    mutate {
        remove_field => ["@timestamp", "timestamp"]
    }
}

output {
    # 对于内网直接存储到ES
    if [type] == "off-line" {
        elasticsearch {
            hosts => ["ES-HOST"]
            index => "my-log"
        }
    }
    # 对于外网直接存储到腾讯云OSS 同上面的二者取其一
    if [type] == "off-line" {
        s3 {
            endpoint => "https://cos.ap-nanjing.myqcloud.com"
            access_key_id => "xxxx"
            secret_access_key => "xxxx"
            region => "ap-nanjing"
            bucket => "xxxx"
            # 10分钟
            time_file => 10
            codec => "json_lines"
            canned_acl => "public-read"
        }
    }
    
    if [type] == "real-time" {
        rabbitmq {
            exchange => "my-exchange"
            host => "localhost"
            exchange_type => "direct"
            key => "logstash"
            user => "admin"
            password => "admin"
        }
    }
    stdout {}
}
复制代码

调试模式 /user/share/logstash/bin/logstash -f /etc/logstash/conf.d/my.conf

生产环境下 去掉stdout {}

systemctl restart logstash

docker迁移方案

以docker-compose为例

logging:
    driver: "syslog"
    options:
        syslog-address: "udp://127.0.0.1:514"
        tag: yq-service-manager
        syslog-facility: local7
复制代码

后续的

本身能够从ES去查询或分析日志了。。。也能够从kibana可视查看

一些想聊得

  • logstash没必要每一个服务器都部署,平均多个节点,对应一个logstash节点就能够了
  • rsyslog服务不要使用远程host的方式,在高并发的日志写环境下,远程syslog并不能很好的处理它,甚至会丢弃一些数据
  • 处理离线日志时候可使用flink或者spark,

我用过得flink,在4核8G的一个服务器中,部署了一个10slot的集群,平均处理速度在1k多条数据每秒,这个速度能够随着slot数量的提高而加快,在不考虑ES性能的状况下。