Logstash は ELK テクノロジー スタックの重要なメンバーです。この記事では、Logstash のいくつかの使用法を紹介します。
公式ウェブサイト Logstash: ログの収集、解析、変換 | Elastic
以下に、Logstash ドキュメント 、Logstash フォーラム 、およびダウンロードへのリンクがあります。
1 はじめに
Logstash は、オープンソースのデータ収集エンジンです。リアルタイムのデータ送信機能を備えており、カスタマイズされた仕様に従ってデータを収集、分析、保存できます。つまり、Logstash には、データ収集、データ分析、データ ダンピングという 3 つのコア コンポーネントがあります。これら 3 つの部分はパイプラインと同様のデータ フローを形成し、入力側でデータを収集し、パイプライン自体がデータのフィルタリングと分析を実行し、出力側でフィルタリングおよび分析されたデータをターゲット データベースに出力します。
公式マニュアルをざっと見てみると、その機能は依然として非常に強力であることがわかります。Logstash リファレンス [8.4] | Elastic
elasticsearch/redis/file/http/kafka/tcp/udp/stdout/websocket/mongodb など、使用できるものが多数あります。
#Input有如下插件
Input plugins
azure_event_hubs
beats
cloudwatch
couchdb_changes
dead_letter_queue
elastic_agent
elasticsearch
exec
file
ganglia
gelf
generator
github
google_cloud_storage
google_pubsub
graphite
heartbeat
http
http_poller
imap
irc
java_generator
java_stdin
jdbc
jms
jmx
kafka
kinesis
log4j
lumberjack
meetup
pipe
puppet_facter
rabbitmq
redis
relp
rss
s3
s3-sns-sqs
salesforce
snmp
snmptrap
sqlite
sqs
stdin
stomp
syslog
tcp
twitter
udp
unix
varnishlog
websocket
wmi
xmpp
#output有如下插件
Output plugins
boundary
circonus
cloudwatch
csv
datadog
datadog_metrics
dynatrace
elastic_app_search
elastic_workplace_search
elasticsearch
email
exec
file
ganglia
gelf
google_bigquery
google_cloud_storage
google_pubsub
graphite
graphtastic
http
influxdb
irc
java_stdout
juggernaut
kafka
librato
loggly
lumberjack
metriccatcher
mongodb
nagios
nagios_nsca
opentsdb
pagerduty
pipe
rabbitmq
redis
redmine
riak
riemann
s3
sink
sns
solr_http
sqs
statsd
stdout
stomp
syslog
tcp
timber
udp
webhdfs
websocket
xmpp
zabbix
https://www.elastic.co/guide/en/logstash/current/index.html
2. Logstash のインストール
1. Java環境をインストールする
ここでは特に言うことはありませんが、次のように Java 環境が正常であることを確認してください。
2. ダウンロードしてインストールします
curl -L -O https://artifacts.elastic.co/downloads/logstash/logstash-7.3.0.tar.gz
tar -xzvf logstash-7.3.0.tar.gz
3. 起動と検証
cd logstash-7.3.0
#启动logstash,-e选项指定输入输出;这里输入采用标准输入,标准输出作为输出。
./bin/logstash -e 'input { stdin { } } output { stdout {} }'
起動完了後、文字列を入力すると以下のような出力が得られればインストールは成功です。
その他のインストール方法については、「 Elastic スタックに Logstash をインストールする方法」を参照してください_Elastic China Community 公式ブログ Blog-CSDN Blog
3. Logstashの使用
Logstash パイプラインには、入力と出力という 2 つの必須要素と、オプションの要素フィルターがあります。
3.1. config/logstash.yml の設定
config.reload.automatic オプションを true に変更します。利点は、構成ファイルが変更されるたびに Logstash を再起動する必要がなく、変更された構成ファイルが自動的にロードされることです。
3.2、実践 - TCP ポートデータを受け入れる
config ディレクトリ (実際にはどのディレクトリでも問題ありません) に、次の内容の test.conf ファイルを作成します。
input 监听9900端口的的tcp数据
output 打印到标准输出
input {
tcp {
port => 9900
}
}
output {
stdout {
codec => rubydebug #以rubydebug格式在控制台输出
#codec => json #以json格式在控制台输出
}
}
ログスタッシュを実行する
./bin/logstash -f ./config/test.conf
さらに、ターミナルを起動し、nc コマンドを使用してポート 9900 にデータを送信します。
echo 'hello logstash!!!!!!!' | nc localhost 9900
#注:别的机器发也行,ip位置指定为logstash所在的ip即可
効果は次のとおりです。
以下の図に示すように、上の部分は設定ファイルを変更した後に自動的に読み込まれるログレコードであり、下の部分は json 形式に変更した後の出力です。
3.3. 実践 - Grok フィルターのデータ処理
input {
tcp {
port => 9900
}
}
filter {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}" }
}
}
output {
stdout {
codec => rubydebug #以rubydebug格式在控制台输出
}
}
次の内容のテキスト ファイル test.log を作成します。
14.49.42.25 - - [12/May/2019:01:24:44 +0000] "GET /articles/ppp-over-ssh/ HTTP/1.1" 200 18586 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2b1) Gecko/20091014 Firefox/3.6b1 GTB5"
14.49.42.25 - - [12/May/2019:01:24:15 +0000] "GET /articles/openldap-with-saslauthd/ HTTP/1.1" 200 12700 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2b1) Gecko/20091014 Firefox/3.6b1 GTB5"
14.49.42.25 - - [12/May/2019:01:24:06 +0000] "GET /articles/dynamic-dns-with-dhcp/ HTTP/1.1" 200 18848 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2b1) Gecko/20091014 Firefox/3.6b1 GTB5"
14.49.42.25 - - [12/May/2019:01:24:54 +0000] "GET /articles/ssh-security/ HTTP/1.1" 200 16543 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2b1) Gecko/20091014 Firefox/3.6b1 GTB5"
14.49.42.25 - - [12/May/2019:01:25:25 +0000] "GET /articles/week-of-unix-tools/ HTTP/1.1" 200 9313 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2b1) Gecko/20091014 Firefox/3.6b1 GTB5"
14.49.42.25 - - [12/May/2019:01:25:33 +0000] "GET /blog/geekery/headless-wrapper-for-ephemeral-xservers.html HTTP/1.1" 200 11902 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2b1) Gecko/20091014 Firefox/3.6b1 GTB5"
66.249.73.135 - - [12/May/2019:01:25:58 +0000] "GET /misc/nmh/replcomps HTTP/1.1" 200 891 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
114.80.81.51 - - [12/May/2019:01:26:10 +0000] "GET /blog/geekery/xvfb-firefox.html HTTP/1.1" 200 10975 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2b1) Gecko/20091014 Firefox/3.6b1 GTB5"
46.105.14.53 - - [12/May/2019:01:26:18 +0000] "GET /blog/tags/puppet?flav=rss20 HTTP/1.1" 200 14872 "-" "UniversalFeedParser/4.2-pre-314-svn +http://feedparser.org/"
61.55.141.10 - - [12/May/2019:01:26:17 +0000] "GET /blog/tags/boredom-induced-research HTTP/1.0" 200 17808 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2b1) Gecko/20091014 Firefox/3.6b1 GTB5"
注文の実行
head -n 1 test.log | nc localhost 9900
効果は次のとおりです。
つまり、Grok フィルターを使用して、入力した非構造化データを正規表現マッチングを通じて構造化データに照合します。上記から、request、port、host、clientip などのフィールドが抽出されていることがわかります。
Grok フィルターの詳細については、 「Logstash: Grok フィルター入門_Elastic China Community 公式ブログ ブログ - CSDN ブログ」を参照してください。
3.4. 実践 - Geoip フィルター
clientip については以前から知っていましたが、この IP がどこから来たのか、つまり特定の国、経度、緯度の地理情報がわかりません。これには、Geoip フィルターを使用できます。
input {
tcp {
port => 9900
}
}
filter {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}" }
}
geoip {
source => "clientip"
}
}
output {
stdout { }
}
埋め込む
head -n 1 test.log | nc localhost 9900
効果は以下の通りです
3.5. 実践 - Useragent フィルター
エージェントフィールドが比較的長いことに気付きました。ただし、ブラウザや言語などの分野は明確に区別されていません。これは、usergent フィルターを使用してさらに強化できます。
3.6. 練習 - フィルタの変更/変換
bytes は文字列型ですが、実際には数値であることが期待される場合があることに注意してください。これには、mutate:convert フィルターを使用できます。
input {
tcp {
port => 9900
}
}
filter {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}" }
}
mutate {
convert => {
"bytes" => "integer"
}
}
geoip {
source => "clientip"
}
useragent {
source => "agent"
target => "useragent"
}
}
output {
stdout { }
}
ただし、エージェントは対応するフィールドを抽出していないようです
3.7、実践 - データを Elastic にインポートする
以前の出力はすべて stdout であり、Logstash が実行されるコンソール (コンソール) に出力されます。以下は、Elasticsearch へのデータの出力を示しています。
注: Elasticsearch と kibana はこのマシンにデプロイされており、正常に起動して使用可能になっています。
input {
tcp {
port => 9900
}
}
filter {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}" }
}
mutate {
convert => {
"bytes" => "integer"
}
}
geoip {
source => "clientip"
}
useragent {
source => "agent"
target => "useragent"
}
date {
match => ["timestamp", "dd/MMM/yyyy:HH:mm:ss Z"]
}
}
output {
stdout { }
elasticsearch {
hosts => ["localhost:9200"]
#user => "elastic"
#password => "changeme"
}
}
关于输入我们保留了stdout和elasticsearch,前者主要是为了方便调试。
注文の実行
head -n 1 test.log | nc localhost 9900
kibana で次のコマンドを実行して、es に書き込まれたデータを表示します。
#统计数据条数
GET logstash/_count
#访问数据
GET logstash/_search
#也可以看到对应的logstash命名的索引
GET _cat/aliases
3.8. 実践 - ES データの移行
注: 一部の ES インスタンスの IP では ping が禁止されている場合があります。curl コマンドを使用して、logstash が配置されているマシンが ES インスタンスに正常にアクセスできるかどうかを確認できます。ES(elasticsearch)でよく使われるcurlコマンドを参照してください 。
設定方法については、入力、出力などに対応する elasticsearch プラグインを公式ドキュメントで見つけて例を参照してください。
Elasticsearch 入力プラグイン | Logstash リファレンス [8.4] | 弾性のある
(1) 入力設定 elasticsearch
公式マニュアルによると、よく使用されるパラメータがいくつかリストされています。
1、hosts:指定一个或多个你要查询的ES的主机。每个主机可以是 IP,HOST,IP:port,或者 HOSY:port。默认的端口是9200.
2、index:指定作用的索引。所有索引 "*" 即可
3、query:指定查询语句
4、proxy:设置为正向的http代理。空的话默认为没有设置代理。
5、request_timeout_seconds:秒单位的单次请求ES的最大时间,当单次请求的数量十分巨大的时候,超时极易发生。数值默认为60s。
6、schedule:顾名思义 定期的运行cron格式的时间表,例如 "* * * * *" 表示每分钟执行一次查询。默认情况认为无时间表,此时仅执行一次。
7、scroll: 参数控制scroll请求两次间隔间的保活时间(单位是秒),并且启动scroll过程。超时适用于每次往返即上一次滚动请求到下一个滚动请求之间. 默认值1m
8、size:设置每次scroll返回的最大消息条数。默认 1000
9、docinfo:如果设置的话在事件中就会包括诸如index,type,docid等文档信息。bool值默认为false
10、docinfo_fields: 如已经通过设置docinfo为true执行需要元数据存储,此字段列出事件中需要保存的元数据字段有哪些。默认值是 ["_index", "_type", "_id"]。
11、docinfo_target:如已经通过设置docinfo为true执行需要元数据存储,则此选项将在其下存储元数据字段的字段命名为子字段。
es_sync.conf ファイルを作成します。
#好用的
input {
elasticsearch {
hosts => ["http://11.168.176.227:9200"]
index => "es_qidian_flow_oa_20220906"
query => '{"query":{"bool":{ "must":[{"term":{"session_id": "webim_2852199659_240062447027410_1662447030899"}}]}}}'
}
}
output {
stdout { }
}
#最好有缩进,看起来更舒服。这个也是可以的
input {
elasticsearch {
hosts => ["http://11.168.176.227:9200"]
index => "es_qidian_flow_oa_20220906"
query => '{
"query":{
"bool":{
"must":[
{
"term":{"session_id": "webim_2852199659_240062447027410_1662447030899"}
}
]
}
}
}'
}
}
output {
stdout { }
}
#其中的type感觉不用指定也是ok的。
注: この時点で修飾されたデータをソース ES に書き込み続ける場合、増分同期は行われません (1 回のみ実行されます)。
スケジュールされたタスクを設定します。以下は1分に1回クエリを実行し、結果をコンソールの標準出力に出力する構成です。
input {
elasticsearch {
hosts => ["http://11.168.xxx.227:9200"]
index => "es_qidian_flow_oa_20220906"
query => '{
"query":{
"bool":{
"must":[
{
"term":{"session_id": "webim_2852199659_240062447027410_1662447030899"}
}
]
}
}
}'
scroll => "1m"
docinfo => true
size => 2000
schedule => "* * * * *" #定时任务,每分钟1次
}
}
filter {
mutate {
remove_field => ["flow_type", "source", "@version", "@timestamp"]
}
}
output {
stdout { }
}
Q: 増分同期を実現するにはどうすればよいですか?
大: スケジュールを使用してタイミング タスクを実行し、出力で docid 重複排除を構成します。これだけでは不十分な場合があります。クエリ ステートメントでは、同期のために過去 t 分間のデータをフィルタリングするように指定されています。t の値はスクロール間隔と一致する必要があります。次の構成では、データが失われないように、過去 3 分間のデータを 1 分ごとに同期します。さらに、docid を通じて重複排除も実現できます。
注: elasticsearch からデータをエクスポートするために logstash を調べたところ、増分同期はこの方法で実装されているようです。
input {
elasticsearch {
hosts => "1.1.1.1:9200"
index => "es-runlog-2019.11.20"
query => '{"query":{"range":{"@timestamp":{"gte":"now-3m","lte":"now/m"}}}}'
size => 5000
scroll => "1m"
docinfo => true
schedule => "* * * * *" #定时任务,每分钟执行一次
}
}
filter {
mutate {
remove_field => ["source", "@version"]
}
}
output {
stdout {}
}
(2)フィルタープラグイン
機能もたくさんありますので、いくつか紹介します。Mutate フィルター プラグイン | Logstash リファレンス [8.4] | Elastic
date プラグイン、grok プラグイン、geoip プラグインについては以前に簡単に説明しましたが、ここではmutate (突然変異) プラグインについて特別に紹介します。
すべてのフィルター プラグインに適用できる共通のオプション:
1、add_field:在事件中添加任意字段。字段名称可以是动态的,并使用%{Field}包含事件的各个部分。
filter {
mutate {
add_field => { "foo_%{somefield}" => "Hello world, from %{host}" }
}
}
2、remove_field:从此事件中删除任意字段。字段名称可以是动态的,并使用%{field}包含事件的各个部分示例。
filter {
mutate {
remove_field => [ "foo_%{somefield}" ]
}
}
3、add_tag:
4、remove_tag:
mutate プラグインのいくつかのオプション
1、convert:将字段的值转换为其他类型,如将字符串转换为整数。如果字段值是数组,则将转换所有成员。如果字段是散列,则不会采取任何操作。
filter {
mutate {
convert => {
"fieldname" => "integer"
"booleanfield" => "boolean"
}
}
}
2、copy:将现有字段复制到其他字段。现有目标字段将被覆盖。
filter {
mutate {
copy => { "source_field" => "dest_field" }
}
}
3、merge:
4、rename:
5、replace:
6、update:
上記の conf に mutate→remove_field を追加すると、remove にリストされているフィールドが出力に含まれていないことがわかります。
(3)出力プラグイン設定 elasticsearch
公式ウェブサイトを参照 出力プラグイン | Logstash Reference [8.4] | Elastic
ある ES のデータを別の ES にインポートすると、インデックス、タイプ、docid は変更されず、同時にスケジュール タイミング タスクも設定されます。次のように。
input {
elasticsearch {
hosts => ["http://11.168.xxx.227:9200"]
index => "es_qidian_flow_oa_20220906"
query => '{
"query":{
"bool":{
"must":[
{
"term":{"session_id": "webim_2852199659_240062447027410_1662447030899"}
}
]
}
}
}'
scroll => "1m"
docinfo => true
size => 2000
schedule => "* * * * *"
}
}
filter {
mutate {
remove_field => ["flow_type", "source", "@version", "@timestamp"]
}
}
output {
elasticsearch {
hosts => ["http://10.101.xxx.15:9200"]
index => "%{[@metadata][_index]}"
document_type => "%{[@metadata][_type]}"
document_id => "%{[@metadata][_id]}"
}
stdout { }
}
テスト後の効果は完全に期待通りでした。
イベントにターゲット インデックスのプレフィックスを含むフィールドがない場合はどうすればよいでしょうか?
このとき、mutate フィルターと条件を使用して [@metadata] フィールドを追加し、各イベントのターゲット インデックスを設定できます。[@metadata] フィールドは Elasticsearch には送信されません。
input {
elasticsearch {
hosts => ["http://11.168.176.227:9200"]
index => "es_qidian_flow_oa_20220906"
query => '{
"query":{
"bool":{
"must":[
{
"term":{"session_id": "webim_2852199659_240062447027410_1662447030899"}
}
]
}
}
}'
scroll => "1m"
docinfo => true
size => 2000
schedule => "* * * * *"
}
}
filter {
mutate {
remove_field => ["flow_type", "source", "@version", "@timestamp"]
add_field => { "[@metadata][new_index]" => "es_qidian_flow_oa_zs_%{+YYYY_MM}"}
}
}
output {
elasticsearch {
hosts => ["http://10.101.203.15:9200"]
index => "%{[@metadata][new_index]}"
document_type => "%{[@metadata][_type]}"
document_id => "%{[@metadata][_id]}"
}
stdout { }
}
このとき出てくるインデックス名は以下の通りです。
別の例を挙げてください。つまり、あらゆる種類のスプライシングが可能です。
filter {
if [log_type] in [ "test", "staging" ] {
mutate { add_field => { "[@metadata][target_index]" => "test-%{+YYYY.MM}" } }
} else if [log_type] == "production" {
mutate { add_field => { "[@metadata][target_index]" => "prod-%{+YYYY.MM.dd}" } }
} else {
mutate { add_field => { "[@metadata][target_index]" => "unknown-%{+YYYY}" } }
}
}
output {
elasticsearch {
index => "%{[@metadata][target_index]}"
}
}
増分移行については、次のプラクティスを参照してください。
ES データをオンラインでクラスター間で一度移行することを忘れないでください - Tencent Cloud Developer Community - Tencent Cloud