flink日志实时采集写入Kafka/ElasticSearch

背景

由于公司想要基于flink的日志做实时预警功能,故需要实时接入,并刷入es进行分析。

注意点

日志接入必须异步,不能影响服务性能

kafka集群宕机,依旧能够提交flink任务且运行任务

kafka集群挂起恢复,可以依旧续写实时运行日志

自定义Appender

在类上加上@Plugin注解,标记为自定义appender

@Plugin(name = "KafkaAppender", category = "Core", elementType = "appender", printObject = true)
public final class KafkaAppender extends AbstractAppender {}

在类加上@PluginFactory和@PluginAttribute来配合log4j.properties来传递参数

@PluginFactory
    public static KafkaAppender createAppender(
            /** 发送到的Topic */
            @PluginAttribute("topic") String topic,
            /** Kafka地址 */
            @PluginAttribute("kafkaBroker") String kafkaBroker,
            /** 设置的数据格式Layout */
            @PluginElement("Layout") Layout<? extends Serializable> layout,
            @PluginAttribute("name") String name,
            @PluginAttribute("append") boolean append,
            /** 日志等级 */
            @PluginAttribute("level") String level,
            /** 设置打印包含的包名,前缀匹配,逗号分隔多个 */
            @PluginAttribute("includes") String includes,
            /** 设置打印不包含的包名,前缀匹配,同时存在会被排除,逗号分隔多个 */
            @PluginAttribute("excludes") String excludes) {
        return new KafkaAppender(name, topic, kafkaBroker, null, layout, append, level, includes, excludes);
    }

在append中对每一条日志进行处理

    @Override
    public void append(LogEvent event) {
        if (event.getLevel().isMoreSpecificThan(this.level)) {
            if (filterPackageName(event)) {
                return;
            }
            try {
                if (producer != null) {
                    CompletableFuture.runAsync(() -> {
                        producer.send(new ProducerRecord<String, String>(topic, getLayout().toSerializable(event).toString()));
                    }, executorService);
                }
            } catch (Exception e) {
                LOGGER.error("Unable to write to kafka for appender [{}].", this.getName(), e);
                LOGGER.error("Unable to write to kafka in appender: " + e.getMessage(), e);
            } finally {
            }
        }
    }

源码地址https://gitee.com/czshh0628/realtime-log-appender

log4j配置文件

日志接入kafka

在flink的conf目录的log4j.properties里添加如下配置

# 自定义的Kafka配置
rootLogger.appenderRef.kafka.ref=KafkaAppender
appender.kafka.type=KafkaAppender
appender.kafka.name=KafkaAppender
# 日志发送到的Topic
appender.kafka.topic=cdc
# Kafka Broker
appender.kafka.kafkaBroker=xxx:9092,xxx:9092
# kerberos认证
http://appender.kafka.keyTab=xxx
http://appender.kafka.principal=xxx
# 发送到Kafka日志等级
appender.kafka.level=info
# 过滤指定包名的文件
appender.kafka.includes=com.*,org.apache.hadoop.yarn.client.*,org.*
## kafka的输出的日志pattern
appender.kafka.layout.type=PatternLayout
appender.kafka.layout.pattern={"logFile":"${sys:log.file}","taskId":"${sys:taskId}","taskVersion":"${sys:taskVersion}","logTime":"%d{yyyy-MM-dd'T'HH:mm:ss,SSS'Z'}","logMsg":"%-5p %-60c %x - %m","logThrow":"%throwable"}

日志接入elasticsearch

# 自定义的es的配置
rootLogger.appenderRef.es.ref=EsAppender
appender.es.type=EsAppender
appender.es.name=EsAppender
appender.es.hostname=bigdata
appender.es.port=9200
appender.es.index=flink_logs
appender.es.fetchSize=100
appender.es.fetchTime=5000
appender.es.level=info
appender.es.includes=com.*,org.apache.hadoop.yarn.client.*,org.*
appender.es.layout.type=PatternLayout
appender.es.layout.pattern={"logFile":"${sys:log.file}","taskId":"${sys:taskId}","taskVersion":"${sys:taskVersion}","logTime":"%d{yyyy-MM-dd'T'HH:mm:ss,SSS'Z'}","logMsg":"%-5p %-60c %x - %m","logThrow":"%throwable"}

启动脚本

bin/flink run -m yarn-cluster -p 1 -yjm 1024 -ytm 1024 -ys 1 -yD env.java.opts="-DtaskId=1000 -DtaskVersion=1.0" -c czs.study.flinkcdc.mysql.MySqlCdcStream test.jar

实现效果

image-20230425153320114

image-20230425153344392

image-20230425154607978

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
如果您想使用Flink 1.12将Kafka数据写入Elasticsearch中,可以按照以下步骤操作: 1. 首先,您需要在项目中添加FlinkKafkaElasticsearch依赖,例如: ```xml <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-connector-kafka_2.11</artifactId> <version>1.12.0</version> </dependency> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-connector-elasticsearch7_2.11</artifactId> <version>1.12.0</version> </dependency> ``` 2. 创建一个Flink Streaming Job,并使用Kafka作为数据源,例如: ```java Properties props = new Properties(); props.setProperty("bootstrap.servers", "localhost:9092"); props.setProperty("group.id", "test"); DataStream<String> stream = env.addSource(new FlinkKafkaConsumer<>("my-topic", new SimpleStringSchema(), props)); ``` 3. 将数据转换为Elasticsearch的数据格式,并将其写入Elasticsearch中,例如: ```java List<HttpHost> httpHosts = new ArrayList<>(); httpHosts.add(new HttpHost("localhost", 9200, "http")); stream.map(new MapFunction<String, Map<String, Object>>() { @Override public Map<String, Object> map(String value) throws Exception { // 将数据转换为Elasticsearch的数据格式 Map<String, Object> data = new HashMap<>(); data.put("message", value); data.put("@timestamp", new Date()); return data; } }).addSink(new ElasticsearchSink.Builder<>(httpHosts, new ElasticsearchSinkFunction<Map<String, Object>>() { @Override public void process(Map<String, Object> element, RuntimeContext ctx, RequestIndexer indexer) { // 将数据写入Elasticsearch中 IndexRequest request = Requests.indexRequest() .index("my-index") .source(element); indexer.add(request); } }).build()); ``` 上述代码中,我们将Kafka中的数据转换为Elasticsearch的数据格式,然后使用ElasticsearchSinkFunction将数据写入Elasticsearch中。 希望这些能够帮到您!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值