์๊ฐ
๋ค๋ฅธ ์์คํ ์ ๋ฐฐํฌํ๋ ๋์ ์ฐ๋ฆฌ๋ ๋ง์ ์์ ๋ค์ํ ๋ก๊ทธ๋ฅผ ์ฒ๋ฆฌํด์ผ ํ๋ ํ์์ฑ์ ์ง๋ฉดํ์ต๋๋ค. ELK๊ฐ ๋๊ตฌ๋ก ์ ํ๋์์ต๋๋ค. ์ด ๊ธฐ์ฌ์์๋ ์ด ์คํ์ ์ค์ ํ ๊ฒฝํ์ ๋ํด ์ค๋ช ํฉ๋๋ค.
๋ชจ๋ ๊ธฐ๋ฅ์ ์ค๋ช
ํ๋ ๋ชฉํ๋ฅผ ์ค์ ํ์ง๋ ์์ง๋ง ์ค์ง์ ์ธ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐ ์ง์คํ๊ณ ์ถ์ต๋๋ค. ์ด๊ฒ์ ์ถฉ๋ถํ ๋ง์ ์์ ๋ฌธ์์ ๊ธฐ์ฑ ์ด๋ฏธ์ง๋ก ์ธํด ๋ง์ ํจ์ ์ด ์๋ค๋ ์ฌ์ค ๋๋ฌธ์
๋๋ค. ์ ์ด๋ ์ฐ๋ฆฌ๋ ๊ทธ๊ฒ๋ค์ ๋ฐ๊ฒฌํ์ต๋๋ค.
docker-compose๋ฅผ ํตํด ์คํ์ ๋ฐฐํฌํ์ต๋๋ค. ๋ํ ์ ์์ฑ๋ docker-compose.yml์ ์ฌ์ฉํ์ฌ ๊ฑฐ์ ๋ฌธ์ ์์ด ์คํ์ ์ฌ๋ฆด ์ ์์์ต๋๋ค. ์น๋ฆฌ๊ฐ ์ด๋ฏธ ๊ฐ๊น์์ง ๊ฒ ๊ฐ์์ต๋๋ค. ์ด์ ์ฐ๋ฆฌ์ ํ์์ ๋ง๊ฒ ์ฝ๊ฐ ๋นํ๋ฉด ๊ทธ๊ฒ ๋ค์
๋๋ค.
์ํ๊น๊ฒ๋ ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ก๊ทธ๋ฅผ ์์ ํ๊ณ ์ฒ๋ฆฌํ๋๋ก ์์คํ ์ ์กฐ์ ํ๋ ค๋ ์๋๋ ๋ฐ๋ก ์ฑ๊ณตํ์ง ๋ชปํ์ต๋๋ค. ๋ฐ๋ผ์ ๊ฐ ๊ตฌ์ฑ ์์๋ฅผ ๊ฐ๋ณ์ ์ผ๋ก ์ฐ๊ตฌํ ๋ค์ ํด๋น ์ฐ๊ฒฐ๋ก ๋์๊ฐ ๊ฐ์น๊ฐ ์๋ค๊ณ ๊ฒฐ์ ํ์ต๋๋ค.
์ด์ logstash๋ถํฐ ์์ํ๊ฒ ์ต๋๋ค.
ํ๊ฒฝ, ๋ฐฐํฌ, ์ปจํ ์ด๋์์ Logstash ์คํ
๋ฐฐํฌ๋ฅผ ์ํด docker-compose๋ฅผ ์ฌ์ฉํ๋ฉฐ ์ฌ๊ธฐ์ ์ค๋ช ๋ ์คํ์ MacOS ๋ฐ Ubuntu 18.0.4์์ ์ํ๋์์ต๋๋ค.
์๋ docker-compose.yml์ ์๋ logstash ์ด๋ฏธ์ง๋ docker.elastic.co/logstash/logstash:6.3.2์ ๋๋ค.
์ฐ๋ฆฌ๋ ๊ทธ๊ฒ์ ์คํ์ ์ฌ์ฉํ ๊ฒ์ ๋๋ค.
logstash๋ฅผ ์คํํ๊ธฐ ์ํด ๋ณ๋์ docker-compose.yml์ ์์ฑํ์ต๋๋ค. ๋ฌผ๋ก ๋ช ๋ น ์ค์์ ์ด๋ฏธ์ง๋ฅผ ์์ํ ์ ์์์ง๋ง ๊ฒฐ๊ตญ docker-compose์ ๋ชจ๋ ๊ฒ์ด ์์๋๋ ํน์ ์์ ์ ํด๊ฒฐํ์ต๋๋ค.
๊ตฌ์ฑ ํ์ผ์ ๋ํ ๊ฐ๋ตํ ์ค๋ช
์ค๋ช
์์ ๋ค์๊ณผ ๊ฐ์ด logstash๋ ํ๋์ ์ฑ๋์ ๋ํด ์คํ๋ ์ ์์ผ๋ฉฐ ์ด ๊ฒฝ์ฐ *.conf ํ์ผ์ ์ ์กํด์ผ ํ๊ฑฐ๋ ์ฌ๋ฌ ์ฑ๋์ ๋ํด ์คํ๋ ๊ฒฝ์ฐ pipelines.yml ํ์ผ์ ์ ์กํด์ผ ํฉ๋๋ค. , ๊ฐ ์ฑ๋์ ๋ํ .conf ํ์ผ์ ์ฐธ์กฐํฉ๋๋ค.
์ฐ๋ฆฌ๋ ๋ ๋ฒ์งธ ๊ธธ์ ํํ์ต๋๋ค. ๊ทธ๊ฒ์ ์ฐ๋ฆฌ์๊ฒ ๋ ๋ค์ฌ๋ค๋ฅํ๊ณ ํ์ฅ ๊ฐ๋ฅํ ๊ฒ์ฒ๋ผ ๋ณด์์ต๋๋ค. ๋ฐ๋ผ์ ์ฐ๋ฆฌ๋ pipelines.yml์ ์์ฑํ๊ณ ๊ฐ ์ฑ๋์ ๋ํ .conf ํ์ผ์ ๋ฃ์ ํ์ดํ๋ผ์ธ ๋๋ ํฐ๋ฆฌ๋ฅผ ๋ง๋ค์์ต๋๋ค.
์ปจํ ์ด๋ ๋ด๋ถ์๋ ๋ ๋ค๋ฅธ ๊ตฌ์ฑ ํ์ผ์ธ logstash.yml์ด ์์ต๋๋ค. ์ฐ๋ฆฌ๋ ๊ทธ๊ฒ์ ๋ง์ง์ง ์๊ณ ๊ทธ๋๋ก ์ฌ์ฉํฉ๋๋ค.
๋ฐ๋ผ์ ์ฐ๋ฆฌ์ ๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
๋น๋ถ๊ฐ ์
๋ ฅ ๋ฐ์ดํฐ๋ฅผ ์์ ํ๊ธฐ ์ํด ํฌํธ 5046์ tcp๋ผ๊ณ ๊ฐ์ ํ๊ณ ์ถ๋ ฅ์ stdout์ ์ฌ์ฉํฉ๋๋ค.
๋ค์์ ์ฒซ ๋ฒ์งธ ์คํ์ ์ํ ๊ฐ๋จํ ๊ตฌ์ฑ์ ๋๋ค. ์ด๊ธฐ ์์ ์ ์์ํ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๋๋ค.
๊ทธ๋์ ์ฐ๋ฆฌ๋ ์ด docker-compose.yml์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
version: '3'
networks:
elk:
volumes:
elasticsearch:
driver: local
services:
logstash:
container_name: logstash_one_channel
image: docker.elastic.co/logstash/logstash:6.3.2
networks:
- elk
ports:
- 5046:5046
volumes:
- ./config/pipelines.yml:/usr/share/logstash/config/pipelines.yml:ro
- ./config/pipelines:/usr/share/logstash/config/pipelines:ro
์ฌ๊ธฐ์ ๋ฌด์์ ๋ณผ ์ ์์ต๋๊น?
- ๋คํธ์ํฌ์ ๋ณผ๋ฅจ์ ์๋ docker-compose.yml(์ ์ฒด ์คํ์ด ์คํ๋๋ ๊ณณ)์์ ๊ฐ์ ธ์์ผ๋ฉฐ ์ฌ๊ธฐ์ ์ ์ฒด ๊ทธ๋ฆผ์ ํฐ ์ํฅ์ ๋ฏธ์น์ง ์๋๋ค๊ณ ์๊ฐํฉ๋๋ค.
- docker.elastic.co/logstash/logstash:6.3.2 ์ด๋ฏธ์ง์์ ํ๋์ ์๋น์ค(services) logstash๋ฅผ ์์ฑํ๊ณ ์ด๋ฆ์ logstash_one_channel๋ก ์ง์ ํฉ๋๋ค.
- ์ปจํ ์ด๋ ๋ด๋ถ์ ํฌํธ 5046์ ๋์ผํ ๋ด๋ถ ํฌํธ๋ก ์ ๋ฌํ๊ณ ์์ต๋๋ค.
- ์ฐ๋ฆฌ๋ ./config/pipelines.yml ํ์ดํ ๊ตฌ์ฑ ํ์ผ์ ์ปจํ ์ด๋ ๋ด๋ถ์ /usr/share/logstash/config/pipelines.yml ํ์ผ์ ๋งคํํฉ๋๋ค. ์ฌ๊ธฐ์ logstash๋ ๋ง์ผ์ ๋๋นํ์ฌ ์ด๋ฅผ ์ ํํ๊ณ ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ๋ง๋ญ๋๋ค.
- ํ์ดํ ๊ตฌ์ฑ ํ์ผ์ด ์๋ ./config/pipelines ๋๋ ํฐ๋ฆฌ๋ฅผ /usr/share/logstash/config/pipelines ๋๋ ํฐ๋ฆฌ์ ๋งคํํ๊ณ ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ๋ง๋ญ๋๋ค.
ํ์ดํ.yml ํ์ผ
- pipeline.id: HABR
pipeline.workers: 1
pipeline.batch.size: 1
path.config: "./config/pipelines/habr_pipeline.conf"
HABR ์๋ณ์์ ํด๋น ๊ตฌ์ฑ ํ์ผ์ ๊ฒฝ๋ก๊ฐ ์๋ ํ๋์ ์ฑ๋์ ์ค๋ช ํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋ง์ง๋ง์ผ๋ก "./config/pipelines/habr_pipeline.conf" ํ์ผ
input {
tcp {
port => "5046"
}
}
filter {
mutate {
add_field => [ "habra_field", "Hello Habr" ]
}
}
output {
stdout {
}
}
์ง๊ธ์ ์ค๋ช ์ ๋ค์ด๊ฐ์ง ์๊ณ ๋ค์์ ์คํํด ๋ด ๋๋ค.
docker-compose up
์ฐ๋ฆฌ๋ ๋ฌด์์ ๋ณด๋์?
์ปจํ ์ด๋๊ฐ ์์๋์์ต๋๋ค. ์์ ์ ํ์ธํ ์ ์์ต๋๋ค.
echo '13123123123123123123123213123213' | nc localhost 5046
๊ทธ๋ฆฌ๊ณ ์ปจํ ์ด๋ ์ฝ์์ ์๋ต์ด ํ์๋ฉ๋๋ค.
๊ทธ๋ฌ๋ ๋์์ ๋ค์๊ณผ ๊ฐ์ ๊ฒ๋ ๋ณผ ์ ์์ต๋๋ค.
logstash_one_channel | [2019-04-29T11:28:59,790][์ค๋ฅ][logstash.licensechecker.licensereader] Unable to retrieve license information from license server {:message=>"Elasticsearch Unreachable: [http://elasticsearch:9200/][Manticore ::ํด๊ฒฐ์คํจ]elasticsearch", ...
logstash_one_channel | [2019-04-29T11:28:59,894][INFO ][logstash.pipeline ] ํ์ดํ๋ผ์ธ์ด {:pipeline_id=>".monitoring-logstash", :thread=>"# ยป}
logstash_one_channel | [2019-04-29T11:28:59,988][INFO ][logstash.agent ] {:count=>2, :running_pipelines=>[:HABR, :".monitoring-logstash"], :non_running_pipelines=>[๋ฅผ ์คํํ๋ ํ์ดํ๋ผ์ธ ]}
logstash_one_channel | [2019-04-29T11:29:00,015][ERROR][logstash.inputs.metrics ] X-Pack์ด Logstash์๋ ์ค์น๋์ง๋ง Elasticsearch์๋ ์ค์น๋์ง ์์ต๋๋ค. ๋ชจ๋ํฐ๋ง ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ค๋ฉด Elasticsearch์ X-Pack์ ์ค์นํ์ธ์. ๋ค๋ฅธ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
logstash_one_channel | [2019-04-29T11:29:00,526][INFO ][logstash.agent ] Logstash API ์๋ํฌ์ธํธ {:port=>9600} ์์ ์ฑ๊ณต
logstash_one_channel | [2019-04-29T11:29:04,478][INFO ][logstash.outputs.elasticsearch] Elasticsearch ์ฐ๊ฒฐ์ด ์๋ํ๋์ง ํ์ธํ๊ธฐ ์ํด ์ํ ํ์ธ ์คํ {:healthcheck_url=>http://elasticsearch:9200/, :path=> "/"}
logstash_one_channel | [2019-04-29T11:29:04,487][WARN ][logstash.outputs.elasticsearch] ์ฃฝ์ ES ์ธ์คํด์ค์ ๋ํ ์ฐ๊ฒฐ์ ๋ค์ ์๋ํ์ง๋ง ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค. {:URL=>"
logstash_one_channel | [2019-04-29T11:29:04,704][INFO ][logstash.licensechecker.licensereader] Elasticsearch ์ฐ๊ฒฐ์ด ์๋ํ๋์ง ํ์ธํ๊ธฐ ์ํด ์ํ ํ์ธ ์คํ {:healthcheck_url=>http://elasticsearch:9200/, :path=> "/"}
logstash_one_channel | [2019-04-29T11:29:04,710][WARN ][logstash.licensechecker.licensereader] ์ฃฝ์ ES ์ธ์คํด์ค์ ๋ํ ์ฐ๊ฒฐ์ ๋ค์ ์๋ํ์ง๋ง ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค. {:URL=>"
๊ทธ๋ฆฌ๊ณ ์ฐ๋ฆฌ ๋ก๊ทธ๋ ํญ์ ํฌ๋กค๋ง๋ฉ๋๋ค.
์ฌ๊ธฐ์์ ํ์ดํ๋ผ์ธ์ด ์ฑ๊ณต์ ์ผ๋ก ์์๋์๋ค๋ ๋ฉ์์ง๋ฅผ ๋
น์์ผ๋ก, ์ค๋ฅ ๋ฉ์์ง๋ฅผ ๋นจ๊ฐ์์ผ๋ก, ์ฐ๊ฒฐ ์๋์ ๋ํ ๋ฉ์์ง๋ฅผ ๋
ธ๋์์ผ๋ก ๊ฐ์กฐ ํ์ํ์ต๋๋ค.
์ด๋ ์ด๋ฏธ์ง์ ํฌํจ๋ logstash.conf์ elasticsearch์ ๊ฐ์ฉ์ฑ์ ๋ํ ํ์ธ์ด ์๊ธฐ ๋๋ฌธ์ ๋ฐ์ํฉ๋๋ค. ๊ฒฐ๊ตญ logstash๋ Elk ์คํ์ ์ผ๋ถ๋ก ์๋ํ๋ค๊ณ ๊ฐ์ ํ๊ณ ๋ถ๋ฆฌํ์ต๋๋ค.
์ผํ ์๋ ์์ง๋ง ํธ๋ฆฌํ์ง๋ ์์ต๋๋ค.
ํด๊ฒฐ์ฑ ์ XPACK_MONITORING_ENABLED ํ๊ฒฝ ๋ณ์๋ฅผ ํตํด ์ด ๊ฒ์ฌ๋ฅผ ๋นํ์ฑํํ๋ ๊ฒ์ ๋๋ค.
docker-compose.yml์ ๋ณ๊ฒฝํ๊ณ ๋ค์ ์คํํด ๋ณด๊ฒ ์ต๋๋ค.
version: '3'
networks:
elk:
volumes:
elasticsearch:
driver: local
services:
logstash:
container_name: logstash_one_channel
image: docker.elastic.co/logstash/logstash:6.3.2
networks:
- elk
environment:
XPACK_MONITORING_ENABLED: "false"
ports:
- 5046:5046
volumes:
- ./config/pipelines.yml:/usr/share/logstash/config/pipelines.yml:ro
- ./config/pipelines:/usr/share/logstash/config/pipelines:ro
์ด์ ๋ชจ๋ ๊ฒ์ด ๊ด์ฐฎ์ต๋๋ค. ์ปจํ ์ด๋๋ ์คํ ์ค๋น๊ฐ ๋์์ต๋๋ค.
์ธ์ ํ ์ฝ์์ ๋ค์ ์ ๋ ฅํ ์ ์์ต๋๋ค.
echo '13123123123123123123123213123213' | nc localhost 5046
๊ทธ๋ฆฌ๊ณ ๋ด๋ผ:
logstash_one_channel | {
logstash_one_channel | "message" => "13123123123123123123123213123213",
logstash_one_channel | "@timestamp" => 2019-04-29T11:43:44.582Z,
logstash_one_channel | "@version" => "1",
logstash_one_channel | "habra_field" => "Hello Habr",
logstash_one_channel | "host" => "gateway",
logstash_one_channel | "port" => 49418
logstash_one_channel | }
ํ๋์ ์ฑ๋ ๋ด์์ ์์
๊ทธ๋์ ์ฐ๋ฆฌ๋ ์์ํ์ต๋๋ค. ์ด์ ์ค์ ๋ก ์๊ฐ์ ๋ค์ฌ logstash๋ฅผ ์ง์ ๊ตฌ์ฑํ ์ ์์ต๋๋ค. ์ง๊ธ์ pipelines.yml ํ์ผ์ ๊ฑด๋๋ฆฌ์ง ๋ง๊ณ ํ๋์ ์ฑ๋๋ก ์์ ํ์ฌ ๋ฌด์์ ์ป์ ์ ์๋์ง ๋ด ์๋ค.
์ฑ๋ ๊ตฌ์ฑ ํ์ผ ์์
์ ์ผ๋ฐ์ ์ธ ์์น์ ์ฌ๊ธฐ ๊ณต์ ๋งค๋ด์ผ์ ์ ์ค๋ช
๋์ด ์์ต๋๋ค.
๋ฌ์์์ด๋ก ์ฝ๊ณ ์ถ๋ค๋ฉด ์ด๊ฒ์ ์ฌ์ฉํ์ต๋๋ค.
์ ๋ ฅ ๋ถ๋ถ๋ถํฐ ์์ฐจ์ ์ผ๋ก ๊ฐ๋ณด๊ฒ ์ต๋๋ค. ์ฐ๋ฆฌ๋ ์ด๋ฏธ tcp์ ๋ํ ์์ ์ ๋ณด์์ต๋๋ค. ์ฌ๊ธฐ์ ๋ ๋ฌด์์ด ํฅ๋ฏธ๋ก์ธ ์ ์์ต๋๊น?
ํํธ๋นํธ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฉ์์ง ํ ์คํธ
์๋ ํ
์คํธ ๋ฉ์์ง๋ฅผ ์์ฑํ ์ ์๋ ํฅ๋ฏธ๋ก์ด ๊ฐ๋ฅ์ฑ์ด ์์ต๋๋ค.
์ด๋ ๊ฒ ํ๋ ค๋ฉด ์
๋ ฅ ์น์
์ heartbean ํ๋ฌ๊ทธ์ธ์ ํฌํจํด์ผ ํฉ๋๋ค.
input {
heartbeat {
message => "HeartBeat!"
}
}
์ ์์ ์ผ๋ฉด XNUMX๋ถ์ ํ ๋ฒ์ฉ ๋ฐ๊ธฐ ์์ํฉ๋๋ค.
logstash_one_channel | {
logstash_one_channel | "@timestamp" => 2019-04-29T13:52:04.567Z,
logstash_one_channel | "habra_field" => "Hello Habr",
logstash_one_channel | "message" => "HeartBeat!",
logstash_one_channel | "@version" => "1",
logstash_one_channel | "host" => "a0667e5c57ec"
logstash_one_channel | }
๋ ์์ฃผ ์์ ํ๋ ค๋ฉด ๊ฐ๊ฒฉ ๋งค๊ฐ๋ณ์๋ฅผ ์ถ๊ฐํด์ผ ํฉ๋๋ค.
์ด๊ฒ์ด ์ฐ๋ฆฌ๊ฐ 10์ด๋ง๋ค ๋ฉ์์ง๋ฅผ ๋ฐ๋ ๋ฐฉ๋ฒ์
๋๋ค.
input {
heartbeat {
message => "HeartBeat!"
interval => 10
}
}
ํ์ผ์์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ
ํ์ผ ๋ชจ๋๋ ์ดํด๋ณด๊ธฐ๋ก ํ์ต๋๋ค. ํ์ผ์์ ์ ๋๋ก ์๋ํ๋ ๊ฒฝ์ฐ ์ ์ด๋ ๋ก์ปฌ ์ฌ์ฉ์๋ ์์ด์ ํธ๊ฐ ํ์ํ์ง ์์ ์ ์์ต๋๋ค.
์ค๋ช ์ ๋ฐ๋ฅด๋ฉด ์๋ ๋ชจ๋๋ tail -f์ ์ ์ฌํด์ผ ํฉ๋๋ค. ๊ฐํ์ ์ฝ๊ฑฐ๋ ์ ํ์ ์ผ๋ก ์ ์ฒด ํ์ผ์ ์ฝ์ต๋๋ค.
๊ทธ๋์ ์ฐ๋ฆฌ๊ฐ ์ป๊ณ ์ ํ๋ ๊ฒ:
- ํ๋์ ๋ก๊ทธ ํ์ผ์ ์ถ๊ฐ๋ ํ์ ์์ ํ๋ ค๊ณ ํฉ๋๋ค.
- ์ฐ๋ฆฌ๋ ์ฌ๋ฌ ๋ก๊ทธ ํ์ผ์ ๊ธฐ๋ก๋ ๋ฐ์ดํฐ๋ฅผ ์์ ํ๋ฉด์ ์์ ๋ ๋ด์ฉ์ ๋ถ๋ฆฌํ ์ ์๊ธฐ๋ฅผ ์ํฉ๋๋ค.
- ์ฐ๋ฆฌ๋ logstash๊ฐ ๋ค์ ์์๋ ๋ ์ด ๋ฐ์ดํฐ๋ฅผ ๋ค์ ์์ ํ์ง ์๋๋ก ํ๊ณ ์ถ์ต๋๋ค.
- logstash๊ฐ ๋นํ์ฑํ๋์ด ์๊ณ ๋ฐ์ดํฐ๊ฐ ํ์ผ์ ๊ณ์ ๊ธฐ๋ก๋๋์ง ํ์ธํ๊ณ ์คํํ๋ฉด ์ด ๋ฐ์ดํฐ๋ฅผ ์์ ํ๊ฒ ๋ฉ๋๋ค.
์คํ์ ์ํํ๊ธฐ ์ํด docker-compose.yml์ ํ ์ค์ ๋ ์ถ๊ฐํ์ฌ ํ์ผ์ ์ ์ฅํ ๋๋ ํฐ๋ฆฌ๋ฅผ ์ฝ๋๋ค.
version: '3'
networks:
elk:
volumes:
elasticsearch:
driver: local
services:
logstash:
container_name: logstash_one_channel
image: docker.elastic.co/logstash/logstash:6.3.2
networks:
- elk
environment:
XPACK_MONITORING_ENABLED: "false"
ports:
- 5046:5046
volumes:
- ./config/pipelines.yml:/usr/share/logstash/config/pipelines.yml:ro
- ./config/pipelines:/usr/share/logstash/config/pipelines:ro
- ./logs:/usr/share/logstash/input
๊ทธ๋ฆฌ๊ณ habr_pipeline.conf์ ์ ๋ ฅ ์น์ ์ ๋ณ๊ฒฝํฉ๋๋ค.
input {
file {
path => "/usr/share/logstash/input/*.log"
}
}
์ฐ๋ฆฌ๋ ์์ํ๋ค:
docker-compose up
๋ก๊ทธ ํ์ผ์ ๋ง๋ค๊ณ ์ฐ๋ ค๋ฉด ๋ค์ ๋ช ๋ น์ ์ฌ์ฉํฉ๋๋ค.
โจecho '1' >> logs/number1.log
{
logstash_one_channel | "host" => "ac2d4e3ef70f",
logstash_one_channel | "habra_field" => "Hello Habr",
logstash_one_channel | "@timestamp" => 2019-04-29T14:28:53.876Z,
logstash_one_channel | "@version" => "1",
logstash_one_channel | "message" => "1",
logstash_one_channel | "path" => "/usr/share/logstash/input/number1.log"
logstash_one_channel | }
๋ค, ์๋ํฉ๋๋ค!
๋์์ ๊ฒฝ๋ก ํ๋๊ฐ ์๋์ผ๋ก ์ถ๊ฐ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ์์ผ๋ก๋ ์ด๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ ์ฝ๋๋ฅผ ํํฐ๋งํ ์ ์์ต๋๋ค.
๋ค์ ํด๋ณด์:
echo '2' >> logs/number1.log
{
logstash_one_channel | "host" => "ac2d4e3ef70f",
logstash_one_channel | "habra_field" => "Hello Habr",
logstash_one_channel | "@timestamp" => 2019-04-29T14:28:59.906Z,
logstash_one_channel | "@version" => "1",
logstash_one_channel | "message" => "2",
logstash_one_channel | "path" => "/usr/share/logstash/input/number1.log"
logstash_one_channel | }
์ด์ ๋ค๋ฅธ ํ์ผ๋ก ์ด๋:
echo '1' >> logs/number2.log
{
logstash_one_channel | "host" => "ac2d4e3ef70f",
logstash_one_channel | "habra_field" => "Hello Habr",
logstash_one_channel | "@timestamp" => 2019-04-29T14:29:26.061Z,
logstash_one_channel | "@version" => "1",
logstash_one_channel | "message" => "1",
logstash_one_channel | "path" => "/usr/share/logstash/input/number2.log"
logstash_one_channel | }
์์ฒญ๋! ํ์ผ์ด ์ ํ๋์๊ณ ๊ฒฝ๋ก๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์ง์ ๋์์ผ๋ฉฐ ๋ชจ๋ ๊ฒ์ด ์ ์์ ๋๋ค.
logstash๋ฅผ ์ค์งํ๊ณ ๋ค์ ์์ํ์ญ์์ค. ๊ธฐ๋ค๋ฆฌ ์. ๊ณ ์. ์ ๊ฒ๋ค. ์ฐ๋ฆฌ๋ ์ด๋ฌํ ๊ธฐ๋ก์ ๋ค์ ๋ฐ์ง ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ์ด์ ๊ฐ์ฅ ๋๋ดํ ์คํ์ ๋๋ค.
logstash๋ฅผ ๋ฃ๊ณ ๋ค์์ ์คํํฉ๋๋ค.
echo '3' >> logs/number2.log
echo '4' >> logs/number1.log
logstash๋ฅผ ๋ค์ ์คํํ๊ณ ๋ค์์ ํ์ธํ์ญ์์ค.
logstash_one_channel | {
logstash_one_channel | "host" => "ac2d4e3ef70f",
logstash_one_channel | "habra_field" => "Hello Habr",
logstash_one_channel | "message" => "3",
logstash_one_channel | "@version" => "1",
logstash_one_channel | "path" => "/usr/share/logstash/input/number2.log",
logstash_one_channel | "@timestamp" => 2019-04-29T14:48:50.589Z
logstash_one_channel | }
logstash_one_channel | {
logstash_one_channel | "host" => "ac2d4e3ef70f",
logstash_one_channel | "habra_field" => "Hello Habr",
logstash_one_channel | "message" => "4",
logstash_one_channel | "@version" => "1",
logstash_one_channel | "path" => "/usr/share/logstash/input/number1.log",
logstash_one_channel | "@timestamp" => 2019-04-29T14:48:50.856Z
logstash_one_channel | }
๋ง์ธ! ๋ชจ๋ ๊ฒ์ด ํฝ์ ๋์์ต๋๋ค.
๊ทธ๋ฌ๋ ๋ค์ ์ฌํญ์ ๋ํด ๊ฒฝ๊ณ ํ ํ์๊ฐ ์์ต๋๋ค. logstash ์ปจํ ์ด๋๊ฐ ์ ๊ฑฐ๋๋ฉด(docker stop logstash_one_channel && docker rm logstash_one_channel) ์๋ฌด๊ฒ๋ ์ ํ๋์ง ์์ต๋๋ค. ์ฝ์ ํ์ผ์ ์์น๋ ์ปจํ ์ด๋ ๋ด๋ถ์ ์ ์ฅ๋์์ต๋๋ค. ์ฒ์๋ถํฐ ์์ํ๋ฉด ์ ์ค๋ง ํ์ฉ๋ฉ๋๋ค.
๊ธฐ์กด ํ์ผ ์ฝ๊ธฐ
์ฒ์์ผ๋ก logstash๋ฅผ ์คํํ๊ณ ์์ง๋ง ์ด๋ฏธ ๋ก๊ทธ๊ฐ ์๊ณ ์ด๋ฅผ ์ฒ๋ฆฌํ๊ณ ์ถ๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค.
์์์ ์ฌ์ฉํ ์
๋ ฅ ์น์
์ผ๋ก logstash๋ฅผ ์คํํ๋ฉด ์๋ฌด ๊ฒ๋ ์ป์ ์ ์์ต๋๋ค. ๊ฐํ๋ง logstash์์ ์ฒ๋ฆฌ๋ฉ๋๋ค.
๊ธฐ์กด ํ์ผ์์ ์ค์ ๊ฐ์ ธ์ค๋ ค๋ฉด ์ ๋ ฅ ์น์ ์ ์ถ๊ฐ ์ค์ ์ถ๊ฐํฉ๋๋ค.
input {
file {
start_position => "beginning"
path => "/usr/share/logstash/input/*.log"
}
}
๋ํ ๋์์ค๊ฐ ์์ต๋๋ค. ์ด๊ฒ์ logstash๊ฐ ์์ง ๋ณด์ง ๋ชปํ ์ ํ์ผ์๋ง ์ํฅ์ ๋ฏธ์นฉ๋๋ค. logstash์ ์์ผ์ ์ด๋ฏธ ์๋ ๋์ผํ ํ์ผ์ ๊ฒฝ์ฐ ์ด๋ฏธ ํฌ๊ธฐ๋ฅผ ๊ธฐ์ตํ๊ณ ์์ผ๋ฉฐ ์ด์ ์ ๋ ์ฝ๋๋ง ๊ฐ์ ธ์ต๋๋ค.
์ ๋ ฅ ์น์ ์ ๊ณต๋ถํ๋ฉด์ ์ด๊ฒ์ ๋ํด ๋ฉ์ถ์. ๋ ๋ง์ ์ต์ ์ด ์์ง๋ง ์ง๊ธ์ ์ถ๊ฐ ์คํ์ ์ถฉ๋ถํฉ๋๋ค.
๋ผ์ฐํ ๋ฐ ๋ฐ์ดํฐ ๋ณํ
๋ค์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด ๋ด ์๋ค. ํ ์ฑ๋์์ ์จ ๋ฉ์์ง๊ฐ ์๊ณ ์ผ๋ถ๋ ์ ๋ณด์ฉ์ด๊ณ ์ผ๋ถ๋ ์ค๋ฅ ๋ฉ์์ง๋ผ๊ณ ๊ฐ์ ํด ๋ด ์๋ค. ํ๊ทธ๊ฐ ๋ค๋ฆ ๋๋ค. ์ผ๋ถ๋ INFO์ด๊ณ ๋ค๋ฅธ ์ผ๋ถ๋ ERROR์ ๋๋ค.
์ถ๊ตฌ์์ ๋ถ๋ฆฌํด์ผ ํฉ๋๋ค. ์ ๊ฒ๋ค. ํ ์ฑ๋์๋ ์ ๋ณด ๋ฉ์์ง๋ฅผ ์์ฑํ๊ณ ๋ค๋ฅธ ์ฑ๋์๋ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์์ฑํฉ๋๋ค.
์ด๋ ๊ฒ ํ๋ ค๋ฉด ์ ๋ ฅ ์น์ ์์ ํํฐ ๋ฐ ์ถ๋ ฅ์ผ๋ก ์ด๋ํฉ๋๋ค.
ํํฐ ์น์ ์ ์ฌ์ฉํ์ฌ ๋ค์ด์ค๋ ๋ฉ์์ง๋ฅผ ๊ตฌ๋ฌธ ๋ถ์ํ์ฌ ์ด๋ฏธ ์์ ํ ์ ์๋ ํด์(ํค-๊ฐ ์)๋ฅผ ์ป์ต๋๋ค. ์กฐ๊ฑด์ ๋ฐ๋ผ ํ์ฑํฉ๋๋ค. ์ถ๋ ฅ ์น์ ์์ ๋ฉ์์ง๋ฅผ ์ ํํ๊ณ ๊ฐ ๋ฉ์์ง๋ฅผ ์์ฒด ์ฑ๋๋ก ๋ณด๋ ๋๋ค.
grok์ผ๋ก ๋ฉ์์ง ๊ตฌ๋ฌธ ๋ถ์
ํ ์คํธ ๋ฌธ์์ด์ ๊ตฌ๋ฌธ ๋ถ์ํ๊ณ ํ๋ ์งํฉ์ ๊ฐ์ ธ์ค๊ธฐ ์ํด ํํฐ ์น์ ์ ํน์ ํ๋ฌ๊ทธ์ธ์ธ grok๊ฐ ์์ต๋๋ค.
์ฌ๊ธฐ์ ์์ธํ ์ค๋ช
์ ์ ๊ณตํ๋ ค๋ ๋ชฉํ๋ฅผ ์ค์ ํ์ง ์๊ณ (์ด์ ๋ํด์๋
์ด๋ ๊ฒ ํ๋ ค๋ฉด ์ ๋ ฅ ๋ผ์ธ์ ํ์์ ๊ฒฐ์ ํด์ผ ํฉ๋๋ค. ๋๋ ๊ทธ๊ฒ๋ค์ ๋ค์๊ณผ ๊ฐ์ด ๊ฐ์ง๊ณ ์์ต๋๋ค :
1 ์ ๋ณด ๋ฉ์์ง1
2 ์ค๋ฅ ๋ฉ์์ง2
์ ๊ฒ๋ค. ๋จผ์ ์๋ณ์, INFO/ERROR, ๊ณต๋ฐฑ ์๋ ๋จ์ด.
์ด๋ ต์ง๋ ์์ง๋ง ์๋ ์๋ฆฌ๋ฅผ ์ดํดํ๊ธฐ์ ์ถฉ๋ถํฉ๋๋ค.
๋ฐ๋ผ์ ํํฐ ์น์ ์ grok ํ๋ฌ๊ทธ์ธ์์ ๋ฌธ์์ด์ ๊ตฌ๋ฌธ ๋ถ์ํ๊ธฐ ์ํ ํจํด์ ์ ์ํด์ผ ํฉ๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ํ์๋ฉ๋๋ค.
filter {
grok {
match => { "message" => ["%{INT:message_id} %{LOGLEVEL:message_type} %{WORD:message_text}"] }
}
}
๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ท ํํ์์
๋๋ค. INT, LOGLEVEL, WORD์ ๊ฐ์ ๊ธฐ์ฑํ ํจํด์ด ์ฌ์ฉ๋ฉ๋๋ค. ๊ทธ๋ค์ ์ค๋ช
๊ณผ ๋ค๋ฅธ ํจํด์ ์ฌ๊ธฐ์์ ๋ณผ ์ ์์ต๋๋ค.
์ด์ ์ด ํํฐ๋ฅผ ํต๊ณผํ๋ฉด ๋ฌธ์์ด์ด message_id, message_type, message_text๋ผ๋ ์ธ ํ๋์ ํด์๋ก ๋ฐ๋๋๋ค.
์ถ๋ ฅ ์น์ ์ ํ์๋ฉ๋๋ค.
if ๋ช ๋ น์ ์ฌ์ฉํ์ฌ ์ถ๋ ฅ ์น์ ์ ๋ฉ์์ง ๋ผ์ฐํ
์ฐ๋ฆฌ๊ฐ ๊ธฐ์ตํ๋ ๊ฒ์ฒ๋ผ ์ถ๋ ฅ ์น์ ์์ ๋ฉ์์ง๋ฅผ ๋ ๊ฐ์ ์คํธ๋ฆผ์ผ๋ก ๋ถํ ํ๋ ค๊ณ ํ์ต๋๋ค. ์ผ๋ถ - iNFO์ธ ๊ฒฝ์ฐ ์ฝ์์ ์ถ๋ ฅํ๊ณ ์ค๋ฅ๊ฐ ์๋ ๊ฒฝ์ฐ ํ์ผ๋ก ์ถ๋ ฅํฉ๋๋ค.
์ด ๋ฉ์์ง๋ฅผ ์ด๋ป๊ฒ ๊ณต์ ํ ์ ์์ต๋๊น? ๋ฌธ์ ์ ์กฐ๊ฑด์ ์ด๋ฏธ ํด๊ฒฐ์ฑ ์ ์ ์ํฉ๋๋ค. ๊ฒฐ๊ตญ ์ฐ๋ฆฌ๋ ์ด๋ฏธ INFO์ ERROR์ ๋ ๊ฐ๋ง ์ฌ์ฉํ ์ ์๋ ์ ์ฉ message_type ํ๋๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค. if ๋ฌธ์ ์ฌ์ฉํ์ฌ ์ ํํ ๊ฒ์ ๋๋ค.
if [message_type] == "ERROR" {
# ะะดะตัั ะฒัะฒะพะดะธะผ ะฒ ัะฐะนะป
} else
{
# ะะดะตัั ะฒัะฒะพะดะธะผ ะฒ stdout
}
ํ๋ ๋ฐ ์ฐ์ฐ์ ์์
์ ๋ํ ์ค๋ช
์ ์ด ์น์
์์ ์ฐพ์ ์ ์์ต๋๋ค.
์ด์ ๊ฒฐ๋ก ์์ฒด์ ๋ํด.
์ฝ์ ์ถ๋ ฅ, ์ฌ๊ธฐ์์ ๋ชจ๋ ๊ฒ์ด ๋ช ํํฉ๋๋ค - stdout {}
๊ทธ๋ฌ๋ ํ์ผ์ ๋ํ ์ถ๋ ฅ - ์ปจํ ์ด๋์์ ์ด ๋ชจ๋ ๊ฒ์ ์คํํ๊ณ ์์ผ๋ฉฐ ๊ฒฐ๊ณผ๋ฅผ ์์ฑํ๋ ํ์ผ์ ์ธ๋ถ์์ ์ก์ธ์คํ ์ ์๋๋ก ํ๋ ค๋ฉด docker-compose.yml์์ ์ด ๋๋ ํฐ๋ฆฌ๋ฅผ ์ด์ด์ผ ํฉ๋๋ค.
์ด๊ณ :
ํ์ผ์ ์ถ๋ ฅ ์น์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
โจoutput {
if [message_type] == "ERROR" {
file {
path => "/usr/share/logstash/output/test.log"
codec => line { format => "custom format: %{message}"}
}
} else
{stdout {
}
}
}
์ถ๋ ฅ์ ์ํด docker-compose.yml์ ๋ณผ๋ฅจ์ ํ๋ ๋ ์ถ๊ฐํฉ๋๋ค.
version: '3'
networks:
elk:
volumes:
elasticsearch:
driver: local
services:
logstash:
container_name: logstash_one_channel
image: docker.elastic.co/logstash/logstash:6.3.2
networks:
- elk
environment:
XPACK_MONITORING_ENABLED: "false"
ports:
- 5046:5046
volumes:
- ./config/pipelines.yml:/usr/share/logstash/config/pipelines.yml:ro
- ./config/pipelines:/usr/share/logstash/config/pipelines:ro
- ./logs:/usr/share/logstash/input
- ./output:/usr/share/logstash/output
์ฐ๋ฆฌ๋ ์์ํ๊ณ , ์๋ํ๊ณ , ๋ ํ๋ฆ์ผ๋ก ๋๋๋ ๊ฒ์ ๋ด
๋๋ค.
์ถ์ฒ : habr.com