logstash对接kafka,推送ES库,根据数据时间生成ES索引

本文介绍如何在Kafka接收到乱序数据的情况下,通过Logstash配置更新,使用自定义时间字段生成按日期划分的Elasticsearch索引,确保数据有序存储。

情况:
这边对接了kafka,但是,kafka里面数据是乱序的,比如,5月20号,可能里面包含了,17号,18号,19号的数据,而且,队列里数据,是只能向前消费,无法回到之前的offset进行消费。

于是,以前按照系统当前时间,创建索引的方式,不能使用了。

index => "ods_harmful_%{+YYYY-MM-dd}"

修改:
注意字段对应关系:

	mutate{
		split => ["message","^"]
		add_field =>   {
            "my_time" => "%{[message][8]}"
            "my_timest" => "%{[message][8]}"
        }
	}
	date {
		match => ["my_time","yyyyMMddHHmmss"]
		target => "my_time"
	}
	date {
		match => ["my_timest","yyyyMMddHHmmss"]
		target => "my_timest"
	}
	ruby {
		code => "event.set('my_time', (event.get('my_time').time.localtime).strftime('%Y-%m-%d %H:%M:%S'))"
    }
	
	ruby {
        code => "event.set('my_timest', (event.get('my_timest').time.localtime).strftime('%Y-%m-%d'))"
    }
    
	elasticsearch {
		hosts => "127.0.0.1:9200"
		index => "whitelist_message_%{my_timest}"
		retry_on_conflict => 5
		document_id => "%{acc_num}"
		codec => plain { charset => "UTF-8" }
	}

完整配置如下:

input{
  
  file{
        path => "C:/Users/Administrator/Desktop/logstash_7.12.0_kafka_test/alldata/*"
		type => "default"
		add_field => {"flag"=>"topic1"}
		start_position => "beginning"
		type => "default"
		codec => plain { charset => "UTF-8" }
  
  }
}

filter {

	mutate{
		split => ["message","^"]
		add_field =>   {
            "my_time" => "%{[message][8]}"
            "my_timest" => "%{[message][8]}"
        }
	}
	date {
		match => ["my_time","yyyyMMddHHmmss"]
		target => "my_time"
	}
	date {
		match => ["my_timest","yyyyMMddHHmmss"]
		target => "my_timest"
	}
	ruby {
		code => "event.set('my_time', (event.get('my_time').time.localtime).strftime('%Y-%m-%d %H:%M:%S'))"
    }
	
	ruby {
        code => "event.set('my_timest', (event.get('my_timest').time.localtime).strftime('%Y-%m-%d'))"
    }

	if [message][0] {
        mutate {                
            add_field =>   {
              "acc_num" => "%{[message][0]}"
            }
        }
    } else {
    	mutate {                
            add_field =>   {
                "acc_num" => ""
            }
        }
    }
	
	if [message][1] {
        mutate {                
            add_field =>   {
              "province" => "%{[message][1]}"
            }
        }
    } else {
    	mutate {                
            add_field =>   {
                "province" => ""
            }
        }
    }
	
	if [message][2] {
        mutate {                
            add_field =>   {
              "city_name" => "%{[message][2]}"
            }
        }
    } else {
    	mutate {                
            add_field =>   {
                "city_name" => ""
            }
        }
    } 

	if [message][3] {
        mutate {                
            add_field =>   {
              "area_code" => "%{[message][3]}"
            }
        }
    } else {
    	mutate {                
            add_field =>   {
                "area_code" => ""
            }
        }
    } 

	if [message][4] {
        mutate {                
            add_field =>   {
              "application" => "%{[message][4]}"
            }
        }
    } else {
    	mutate {                
            add_field =>   {
                "application" => ""
            }
        }
    } 
	
	if [message][5] {
        mutate {                
            add_field =>   {
              "channel_name" => "%{[message][5]}"
            }
        }
    } else {
    	mutate {                
            add_field =>   {
                "channel_name" => ""
            }
        }
    }

	if [message][6] {
        mutate {                
            add_field =>   {
              "channel_type" => "%{[message][6]}"
            }
        }
    } else {
    	mutate {                
            add_field =>   {
                "channel_type" => ""
            }
        }
    }
	
	if [message][7] {
        mutate {                
            add_field =>   {
              "violation_type" => "%{[message][7]}"
            }
        }
    } else {
    	mutate {                
            add_field =>   {
                "violation_type" => ""
            }
        }
    } 
	if [message][8] {
        mutate {       	
            add_field =>   {
              "violation_time" => "%{my_time}"
            }
        }
    } else {
    	mutate {                
            add_field =>   {
                "violation_time" => ""
            }
        }
    }  	
	
	if [message][9] {
        mutate {                
            add_field =>   {
              "exceed_orient_note_number" => "%{[message][9]}"
            }
        }
    } else {
    	mutate {                
            add_field =>   {
                "exceed_orient_note_number" => ""
            }
        }
    } 
	
	mutate{
	   add_field =>   {
            "scene_name" => "WHITELIST_MESSAGE"
			"violation_type_code" => "21"
			"kafka_topic" => "topic1"
       }
	   remove_field=>["message"] 
	   remove_field=>["@version"] 
	   remove_field=>["my_time"] 
	}	              
}


output {
	elasticsearch {
		hosts => "127.0.0.1:9200"
		index => "whitelist_message_%{my_timest}"
		retry_on_conflict => 5
		document_id => "%{acc_num}"
		codec => plain { charset => "UTF-8" }
	}
	stdout { codec => rubydebug }
}

这样配置后,就一次性生成多个索引

### Logstash.conf 文件格式及配置示例 Logstash 是一个开源的数据收集引擎,支持动态地从不同数据源采集数据并将其传输到指定的目标存储中。其核心功能依赖于配置文件 `logstash.conf` 来定义输入、过滤器输出。 #### 配置文件结构 Logstash 的配置文件由三个主要部分组成:`input`, `filter`, `output`。每一部分的功能如下: 1. **Input**: 定义数据的来源。可以是从文件读取、网络监听或其他方式获取数据。 2. **Filter**: 对接收到的数据进行处理转换。常见的操作包括解析日志字段、删除无用字段等。 3. **Output**: 将处理后的数据发送到目标位置,比如 Elasticsearch 或其他数据。 以下是各部分的具体说明以及一个完整的配置示例[^2]。 --- #### 输入 (Input) 输入插件用于接收来自各种来源的日志或事件流。常用的输入插件有 `file`, `beats`, `syslog`, `tcp`, `udp` 等。 ```plaintext input { file { path => "/data/nginx/logs/access.log" start_position => "beginning" } } ``` 在此示例中,`file` 插件被用来监控 `/data/nginx/logs/access.log` 路径中的新内容,并从头开始读取文件的内容。 --- #### 过滤器 (Filter) 过滤器插件负责对原始数据进行加工清洗。例如,可以通过正则表达式提取特定字段或将时间戳标准化。 ```plaintext filter { mutate { add_field => { "[fields][path]" => "%{[path]}" } add_field => { "[message]" => "%{[message]}" } } grok { match => { "message" => "%{COMBINEDAPACHELOG}" } } date { match => [ "timestamp", "yyyy-MM-dd HH:mm:ss" ] target => "@timestamp" } } ``` 在这个例子中: - 使用 `mutate` 添加自定义字段; - 利用 `grok` 解析 Apache 日志格式; - 设置日期解析规则以确保时间戳一致性[^2]。 --- #### 输出 (Output) 最后一步是指定如何导出经过处理的数据Elasticsearch 是最常见的目的地之一,但也支持 Kafka, Redis, MySQL 等多种选项。 ```plaintext output { elasticsearch { hosts => ["http://192.168.153.7:9200"] index => "test-logstash-%{+YYYY.MM.dd}" } stdout { codec => rubydebug } } ``` 此片段展示了向远程 Elasticsearch 实例写入索引的同时,在控制台打印调试信息。 --- ### 完整配置示例 下面是一个综合性的 `logstash.conf` 示例,涵盖了输入、过滤输出三大部分: ```plaintext input { beats { port => 5044 } } filter { if [type] == "nginx-access" { grok { match => { "message" => '%{IPORHOST:http_host} %{USER:remote_user} \[%{HTTPDATE:time_local}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:http_version})?|-)" %{NUMBER:response:int} (?:%{NUMBER:bytes:int}|-) "(?:"(?:%{URI:referrer})?"|%{"(?<agent>[^"]+)")"' } } geoip { source => "client_ip" } } } output { elasticsearch { hosts => ["http://localhost:9200"] index => "nginx_logs_%{+YYYY.MM.dd}" } kafka { bootstrap_servers => "broker1:9092,broker2:9092" topic_id => "processed_logs" } } ``` 该脚本实现了以下功能: - 接收 Filebeat 发送过来的数据; - 提取 Nginx 访问日志的关键字段; - 增加地理位置信息; - 同步至本地 Elasticsearch推送副本给 Kafka 主题[^2]。 --- ### 注意事项 当管理多个配置文件时(如位于 `/etc/logstash/conf.d/`),需注意每份单独的 `.conf` 应具备独立逻辑且不冲突[^1]。启动服务前可通过命令验证语法正确性: ```bash sudo /opt/logstash/bin/logstash --config.test_and_exit -f /etc/logstash/conf.d/ ``` 如果一切正常,则会显示成功消息;反之提示错误详情以便调整设置[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值