* 2023.12.21 업데이트 - Docker ELK로 PostgreSQL과 Elastic Stack 연동 포스팅
[Docker + ELK] Docker ELK를 사용해서 PostgreSQL DB 모니터링 하기
이번 포스팅에서는 이전에 elasticsearch, kibana, logstash를 별도로 실행하여 PostgreSQL DB를 모니터링했던 것을 Docker을 통해서 구현해본다. 로컬 환경에서 elk를 구성했던 포스트는 아래 링크에서 확인할
dnai-deny.tistory.com
이전 포스팅에 먼저 언급했다싶이 RDBMS에 Elasticsearch를 적용하기 위한 방법을 검색했을 때 가장 많이 추천하는 방법이 Logstash를 이용한 모니터링이었다.
[Elasticsearch] Logstash 사용해보기
제목만 썼는데 어제의 삽질이 올라오는 기분.... 곧장 시작해보겠다. elasticsearch 설치에 관련된 내용은 이전 포스팅 참고. [Elasticsearch] Elasticsearch 기본 개념 및 설치, kibana 연동하기 최신 한국어 자
dnai-deny.tistory.com
RDBMS의 변화를 주기적으로 모니터링해서 Elastic Stack에 올려주면 Elasticsearch를 그 안에서 사용할 수 있도록 하는 방법인 것 같다. 따라서 이번 포스팅에서는 JDBC input plugin을 logstash에 사용해서 RDBMS의 데이터를 주기적으로 받아와서! kibana에서 데이터를 확인하는 것까지 달려보도록 하겠다.
미리 말씀드리지만 거의 삽질로그이다.
1. RDBMS 설정
데이터를 가져올 RDBMS가 있어야한다. 나는 postgres를 사용하고 있으므로, 데모로 만들어둔 게시판 DB를 사용할 것이다. 별로 데이터가 많지는 않다.
pgAdmin에서 새 데이터베이스를 만들어준다.

데이터베이스 이름만 정하면 된다. 그리고 나서shemes 하위의 Tables에서 우클릭해서 table을 하나 만들어준다. 내가 사용하고 있는 테이블은 간단한 포스팅된 글의 데이터를 표현하고 있다. column 설정은 사진처럼 했다.

그리고 대충 데이터 몇 개를 넣어준다.

이 데이터베이스는 fastapi로 간단하게 만든 웹 서비스랑 연동이 되어 있어서

이 몹시 대충만든 localhost 사이트에서 add new 누르고 posting하면 데이터가 쌓인다. 나중에 모니터링 테스트할 때 확인해보도록 하겠다.
2. JDBC 드라이버 설치
사용하려는 RDBMS에 맞는 JDBC 드라이버를 설치해야한다. 나는 postgreSQL을 사용하므로 postgreSQL JDBC driver라고 치면 설치할 수 있는 사이트가 나온다.
Download | pgJDBC
Download Binary JAR file downloads of the JDBC driver are available here and the current version with Maven Repository. Because Java is platform neutral, it is a simple process of just downloading the appropriate JAR file and dropping it into your classpat
jdbc.postgresql.org
JDK 17을 사용중인 내 기준 42.6.0 버전을 사용하고 있다. jar 파일 다운로드가 완료되면, logstash 설치경로의 logstash-core\lib\jars 에 옮겨준다. 혹시나 jar 파일이 비어있지는 않은지 잘 보고 넣어줘야한다.
이러면 드라이브 설치는 끝이다. 압축풀거나 할 필요 없다. 이제 config 파일을 작성해보자.
3. Logstash config 파일 작성
input {
jdbc {
jdbc_driver_library => "C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/logstash-core/lib/jars/postgresql-42.6.0.jar"
jdbc_driver_class => "org.postgresql.Driver"
jdbc_connection_string => "jdbc:postgresql://localhost:5432/{database_name}"
jdbc_user => "{username}"
jdbc_password => "{password}"
schedule => "* * * * *"
statement => "select * from contents"
}
}
output {
elasticsearch {
hosts => ["https://localhost:9200"]
}
stdout { codec => rubydebug }
}
냅다 코드부터 던지고 설명하기.
a. input
우선 input은 jdbc input plugin을 활용해서 postgres에서 데이터를 읽어오는 것이 input이 될 것이다.
- jdbc_driver_library에 아까 다운로드한 JDBC Driver의 절대경로를 넣어준다.
- 절대경로로 잡아주지 않으면 아래와 같은 길고 무시무시한 에러를 만난다.
- 요약하면 unable to load postgresql-42.6.0.jar from :jdbc_driver_library, file not readable. 못 읽어온다는 거다.
[2023-06-27T16:57:08,718][ERROR][logstash.javapipeline ][main]
Pipeline error {
:pipeline_id=>"main",
:exception=>#<LogStash::PluginLoadingError:
unable to load postgresql-42.6.0.jar from :jdbc_driver_library,
file not readable (please check user and group permissions for the path)>,
:backtrace=>[
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/logstash-integration-jdbc-5.4.3/lib/logstash/plugin_mixins/jdbc/common.rb:59:in `block in load_driver_jars'",
"org/jruby/RubyArray.java:1865:in `each'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/logstash-integration-jdbc-5.4.3/lib/logstash/plugin_mixins/jdbc/common.rb:54:in `load_driver_jars'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/logstash-integration-jdbc-5.4.3/lib/logstash/plugin_mixins/jdbc/common.rb:34:in `load_driver'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/logstash-integration-jdbc-5.4.3/lib/logstash/inputs/jdbc.rb:307:in `register'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/logstash-mixin-ecs_compatibility_support-1.3.0-java/lib/logstash/plugin_mixins/ecs_compatibility_support/target_check.rb:48:in `register'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/logstash-core/lib/logstash/java_pipeline.rb:237:in `block in register_plugins'",
"org/jruby/RubyArray.java:1865:in `each'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/logstash-core/lib/logstash/java_pipeline.rb:236:in `register_plugins'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/logstash-core/lib/logstash/java_pipeline.rb:395:in `start_inputs'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/logstash-core/lib/logstash/java_pipeline.rb:320:in `start_workers'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/logstash-core/lib/logstash/java_pipeline.rb:194:in `run'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/logstash-core/lib/logstash/java_pipeline.rb:146:in `block in start'"],
"pipeline.sources"=>["C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/bin/test.conf"],
:thread=>"#<Thread:0x33d68228@C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/logstash-core/lib/logstash/java_pipeline.rb:134 run>"}
- jdbc_driver_class는 각 RDBMS에 맞는 driver class를 넣어준다.
- jdbc_connection_string은 데이터베이스 주소를 넣어주는데, postgres는 5432 port이다.
- jdbc_user과 jdbc_password는 pgAdmin 들어갔을 때 제일 먼저 치는 admin user이름과 비밀번호로 설정해준다.
- schedule은 지금은 신경쓸 거 없다.
- statement는 query문을 작성해준다.
b. output
output은 elasticsearch와 console 표준 출력으로 넣어서 데이터가 잘 뽑혀나오는지 확인해볼 것이다. elasticsearch의 host 서버 주소를 넣어준다.
여기까지 쓰고 실행해보자.
.\bin\logstash.bat -f .\config\test.conf
실행해보면 높은 확률로 실행이 에러를 만난다. 휴.. 디버깅의 시작이다.
C. DisallowedClass: Tried to load unspecified class: Time 해결 방법
- data/plugins/inputs/jdbc 경로 아래 logstash_jdbc_last_run 파일을 지워주고 새로 실행해야 한다. 혹시나해서...
[2023-06-28T11:47:21,480][ERROR][logstash.javapipeline ][main]
Pipeline error {
:pipeline_id=>"main",
:exception=>#<Psych::DisallowedClass: Tried to load unspecified class: Time>,
:backtrace=>[
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/psych-5.1.0-java/lib/psych/class_loader.rb:99:in `find'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/psych-5.1.0-java/lib/psych/class_loader.rb:28:in `load'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/psych-5.1.0-java/lib/psych/scalar_scanner.rb:116:in `parse_time'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/psych-5.1.0-java/lib/psych/scalar_scanner.rb:59:in `tokenize'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/psych-5.1.0-java/lib/psych/visitors/to_ruby.rb:69:in `deserialize'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/psych-5.1.0-java/lib/psych/visitors/to_ruby.rb:130:in `visit_Psych_Nodes_Scalar'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/venpt'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/psych-5.1.0-java/lib/psych/visitors/to_ruby.rb:35:in `accept'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/psych-5.1.0-java/lib/psych/visitors/to_ruby.rb:320:in `visit_Psych_Nodes_Document'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/psych-5.1.0-java/lib/psych/visitors/visitor.rb:30:in `visit'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/psych-5.1.0-java/lib/psych/visitors/visitor.rb:6:in `accept'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/psych-5.1.0-java/lib/psych/visitors/to_ruby.rb:35:in `accept'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/psych-5.1.0-java/lib/psych.rb:334:in `safe_load'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/psych-5.1.0-java/lib/psych.rb:369:in `load'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/logstash-integration-jdbc-5.4.3/lib/logstash/plugin_mixins/jdbc/value_tracking.rb:115:in `read'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/logstash-integration-jdbc-5.4.3/lib/logstash/plugin_mixins/jdbc/value_tracking.rb:48:in `common_set_initial'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/logstash-integration-jdbc-5.4.3/lib/logstash/plugin_mixins/jdbc/value_tracking.rb:87:in `set_initial'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/logstash-integration-jdbc-5.4.3/lib/logstash/plugin_mixins/jdbc/value_tracking.rb:31:in `initialize'",
"org/jruby/RubyClass.java:890:in `new'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/logstash-integration-jdbc-5.4.3/lib/logstash/plugin_mixins/jdbc/value_tracking.rb:19:in `build_last_value_tracker'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/logstash-integration-jdbc-5.4.3/lib/logstash/inputs/jdbc.rb:285:in `register'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/logstash-mixin-ecs_compatibility_support-1.3.0-java/lib/logstash/plugin_mixins/ecs_compatibility_support/target_check.rb:48:in `register'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/logstash-core/lib/logstash/java_pipeline.rb:237:in `block in register_plugins'",
"org/jruby/RubyArray.java:1865:in `each'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/logstash-core/lib/logstash/java_pipeline.rb:236:in `register_plugins'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/logstash-core/lib/logstash/java_pipeline.rb:395:in `start_inputs'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/logstash-core/lib/logstash/java_pipeline.rb:320:in `start_workers'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/logstash-core/lib/logstash/java_pipeline.rb:194:in `run'",
"C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/logstash-core/lib/logstash/java_pipeline.rb:146:in `block in start'"],
"pipeline.sources"=>["C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/config/test.conf"],
:thread=>"#<Thread:0x276aa43a@C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/logstash-core/lib/logstash/java_pipeline.rb:134 run>"}
4. Logstash 와 Elastic 사이의 보안 기능(authentication and TLS) 문제 해결하기
두 가지 에러가 발생할 수 있다.
- elasticsearch.yml 파일의 xpack security 항목을 전부 false로 실행하는 경우
- elasticsearch.yml 파일의 xpack security 항목을 전부 true로 실행하는 경우
1번의 경우 kibana에서 문제가 생긴다.
FATAL Error: [config validation of [server].ssl]: must specify [certificate] and [key] -- or [keystore.path] -- when ssl is enabled
2번의 경우 logstash에서 문제가 생긴다.
[2023-06-28T14:26:08,204][INFO ][logstash.outputs.elasticsearch][main] Failed to perform request {:message=>"localhost:9200 failed to respond", :exception=>Manticore::ClientProtocolException, :cause=>#<Java::OrgApacheHttp::NoHttpResponseException: localhost:9200 failed to respond>}
[2023-06-28T14:26:08,205][WARN ][logstash.outputs.elasticsearch][main] Attempted to resurrect connection to dead ES instance, but got an error {:url=>"http://elastic:xxxxxx@localhost:9200/", :exception=>LogStash::Outputs::ElasticSearch::HttpClient::Pool::HostUnreachableError, :message=>"Elasticsearch Unreachable: [http://localhost:9200/][Manticore::ClientProtocolException] localhost:9200 failed to respond"}
2번의 경우에는 kibana와 elastic 사이에서는 문제가 없다. localhost:5601로 접속하면 kibana에 들어갈 수 있다. 이 상태를 기준으로! logstash에 권한을 주어야한다. Logstash 공식문서에 해결 방법이 써있기는 하다. 찬찬히 따라가보도록 하겠다.
Secure your connection to Elasticsearch | Logstash Reference [8.8] | Elastic
Hosted Elasticsearch Service simplifies security. This configuration step is not necessary for hosted Elasticsearch Service on Elastic Cloud. Our hosted Elasticsearch Service is available on AWS, GCP, and Azure, and you can try it for free.
www.elastic.co
A. 현재 yaml 파일 점검
- kibana.yml
server.port: 5601
server.host: "localhost"
server.publicBaseUrl: "<https://{ip_address}:5601>"
elasticsearch.hosts: ["<https://{ip_address}:9200>"]
elasticsearch.serviceAccountToken: {service token}
elasticsearch.ssl.certificateAuthorities:
['C:\\kibana\\kibana-8.8.1\\data\\ca_1687845426792.crt']
xpack.fleet.outputs:
[
{
id: fleet-default-output,
name: default,
is_default: true,
is_default_monitoring: true,
type: elasticsearch,
hosts: ["<https://{ip_address}:9200>"],
ca_trusted_fingerprint: {fingerprint},
},
]
- elasticsearch.yml
xpack.security.enabled: true
xpack.security.enrollment.enabled: true
xpack.security.http.ssl:
enabled: true
keystore.path: certs/http.p12
xpack.security.transport.ssl:
enabled: true
verification_mode: certificate
keystore.path: certs/transport.p12
truststore.path: certs/transport.p12
cluster.initial_master_nodes: ["DESKTOP-85ERSCL"]
http.host: 0.0.0.0
- logstash.yml
xpack.monitoring.enabled: false
xpack.monitoring.elasticsearch.username: elastic
xpack.monitoring.elasticsearch.password: elastic
xpack.monitoring.elasticsearch.ssl.certificate_authority: "C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/config/certs/http_ca.crt"
- xpack.monitoring.enabled 옵션을 fasle로 지정했는데 뒤가 작동하냐…라고 물으시면 아직 나도 잘 모르겠다.
[찍어먹기] Spring Boot 부터 ELK Stack 까지 :: 데이터 수집해서 시각화 하기 (2)
이전 포스팅에서 ELK Stack을 어찌저찌 원하는대로 돌아가게끔 구성했습니다. 이번 포스팅에서는 구성 후 받은 피드백과 오류 파티를 해결한 내용을 정리해보고자 합니다. X-Pack 문제 어느 순간부
logical-code.tistory.com
B. elasticsearch의 security certificates and keys 를 따라 xpack 관련 keystore 얻기
Start the Elastic Stack with security enabled automatically | Elasticsearch Guide [8.8] | Elastic
Start the Elastic Stack with security enabled automatically | Elasticsearch Guide [8.8] | Elastic
If you redirect Elasticsearch output to a file, security autoconfiguration is skipped. Autoconfigured credentials can only be viewed on the terminal the first time you start Elasticsearch. If you need to redirect output to a file, start Elasticsearch witho
www.elastic.co
- http.p12
bin/elasticsearch-keystore show xpack.security.http.ssl.keystore.secure_password
- transport.p12
bin/elasticsearch-keystore show xpack.security.transport.ssl.keystore.secure_password
위 두 개를 실행하면 elasticsearch/config에 인증서가 생성된다. http.p12와 transport.p12 인증서 + http_ca.crt를 elastic/config/certs로 이동시킨다.
그리고 logstash의 elasticsearch output plugin에서 cacert에 인증서 경로를 추가한다.
input {
jdbc {
jdbc_driver_library => "C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/logstash-core/lib/jars/postgresql-42.6.0.jar"
jdbc_driver_class => "org.postgresql.Driver"
jdbc_connection_string => "jdbc:postgresql://localhost:5432/postgres"
jdbc_user => "postgres"
jdbc_password => "keti1234"
schedule => "* * * * *"
statement => "select test1, test2, test3 from tn_test"
}
}
output {
elasticsearch {
hosts => ["https://localhost:9200"]
cacert => 'C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/config/certs/http_ca.crt'
ssl => true
}
stdout { codec => rubydebug }
}
다시 logstash를 실행해보면 에러 메세지가 바뀌었다.
[2023-06-28T15:07:36,086][WARN ][logstash.outputs.elasticsearch]
[main] Attempted to resurrect connection to dead ES instance, but got an error {
:url=>"https://localhost:9200/",
:exception=>LogStash::Outputs::ElasticSearch::HttpClient::Pool::BadResponseCodeError, :message=>"Got response code '401' contacting Elasticsearch at URL 'https://localhost:9200/'"}
Attempted to resurrect connection to dead ES instance / Got response code '401' contacting Elasticsearch at URL 'https://localhost:9200/', 올바른 요청이 아니라는 것 같다. 어찌되었든 계속 단계를 진행해보자.
C. kibana에서 logstash 권한 설정해주기
1. kibana의 roles에서 새 role api를 생성
- 검색창에 roles치면 나온다.
- 맞게한 건지는 모르겠으나 일단 해봄…

- cluster privileges에 manage_index_templates와 monitor를 추가한다.
- Index privileges에 Indices를 기본으로 logstash-*로 넣고, write, create, create_index, manage, manage_lim 권한을 주어서 생성한다.
2. logstash_internal 유저 생성

Username과 password, full name은 적당히 생성하고 roles에 방금 생성한 logstash_write라는 role을 준다.
elasticsearch를 실행하고 있는 프롬프트를 보면 유저 생성 등의 로그가 있다.

D. 생성한 유저를 logstash config 파일에 추가
input {
jdbc {
jdbc_driver_library => "C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/logstash-core/lib/jars/postgresql-42.6.0.jar"
jdbc_driver_class => "org.postgresql.Driver"
jdbc_connection_string => "jdbc:postgresql://localhost:5432/{database_name}"
jdbc_user => "{username}"
jdbc_password => "{password}"
schedule => "* * * * *"
statement => "select test1, test2, test3 from tn_test"
}
}
output {
elasticsearch {
hosts => ["https://localhost:9200"]
cacert => 'C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/config/certs/http_ca.crt'
ssl => true
user => "logstash_internal"
password => "x-pack-test-password"
}
stdout { codec => rubydebug }
}
다시 실행을 해보면, 뭔가 에러메세지가 또 바뀌었다. 그래도 일단 데이터베이스에서 뭔가를 잡아오고 있는 것 같기는 하다.
[2023-06-28T15:28:14,291][INFO ][logstash.outputs.elasticsearch][main][a519652ef2db6cf2dbe5a0a521b676ed993c53d55dd2601c5ee833499749c4e1]
Retrying individual bulk actions that failed or were rejected by the previous bulk request {:count=>1}
[2023-06-28T15:28:26,542][ERROR][logstash.licensechecker.licensereader]
Unable to retrieve license information from license server {:message=>"No Available connections"}
[2023-06-28T15:28:30,300][INFO ][logstash.outputs.elasticsearch][main][a519652ef2db6cf2dbe5a0a521b676ed993c53d55dd2601c5ee833499749c4e1]
Retrying failed action {:status=>403, :action=>["create", {:_id=>nil, :_index=>"logs-generic-default", :routing=>nil}, {"test1"=>"?뚯뒪??-3", "test2"=>"?뚯뒪??-3", "@timestamp"=>2023-06-28T06:28:00.118973Z, "test3"=>"?뚯뒪??-3", "@version"=>"1", "data_stream"=>{"type"=>"logs", "dataset"=>"generic", "namespace"=>"default"}}], :error=>{"type"=>"security_exception", "reason"=>"action [indices:data/write/bulk[s]] is unauthorized for user [logstash_internal] with effective roles [logstash_writer] on indices [logs-generic-default], this action is granted by the index privileges [create_doc,create,delete,index,write,all]"}}
여기에서 Retrying failed action 부분을 잘 읽어보면, :_index=>"logs-generic-default" 부분이 있고, user [logstash_internal 에게는 indices [logs-generic-default]에 대한 권한이 없다고 한다.
어라
그래서 role을 다시 살펴봤다.
이유를 알았다!
이전에 나는 미리 Discover 에서 새 view를 만들어뒀었다. my-data-view라는 이름으로!

오른쪽을 보면 log-generic-default 라는 source가 보이는데, 얘가 logstash였다.
data view를 생성할 때 Index Pattern이라는 것을 만드는데, 나는 logs-generic-default에 맞춰 logs-generic-* 으로 설정했다. 그러니 roles에 접근권한을 줄 indices도 저 친구한테 줘야했던 것이다!!!!!!!!!!!!
곧장 logstash-writer role의 indices를 logs-generic-* 로 변경해주었다.

로그에 떴던 권한들도 전부 추가해주었다.
그랬더니!
[2023-06-29T11:45:33,371][INFO ][logstash.javapipeline ][main] Pipeline started {"pipeline.id"=>"main"}
[2023-06-29T11:45:33,385][INFO ][logstash.agent ] Pipelines running {:count=>1, :running_pipelines=>[:main], :non_running_pipelines=>[]}
[2023-06-29T11:46:00,466][INFO ][logstash.inputs.jdbc ][main][9f22664126814c4ea4b60ab70187a8c440fb2fa44c66183ec9c5d1aa937200be] (0.009056s) select * from contents
C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/manticore-0.9.1-java/lib/manticore/client.rb:284: warning: already initialized constant Manticore::Client::HttpPost
C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/manticore-0.9.1-java/lib/manticore/client.rb:284: warning: already initialized constant Manticore::Client::HttpPost
C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/manticore-0.9.1-java/lib/manticore/client.rb:284: warning: already initialized constant Manticore::Client::HttpPost
C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/manticore-0.9.1-java/lib/manticore/client.rb:284: warning: already initialized constant Manticore::Client::HttpPost
C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/manticore-0.9.1-java/lib/manticore/client.rb:536: warning: already initialized constant Manticore::Client::StringEntity
C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/manticore-0.9.1-java/lib/manticore/client.rb:536: warning: already initialized constant Manticore::Client::StringEntity
C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/manticore-0.9.1-java/lib/manticore/client.rb:536: warning: already initialized constant Manticore::Client::StringEntity
C:/Users/dk866/Downloads/logstash-8.8.1/logstash-8.8.1/vendor/bundle/jruby/2.6.0/gems/manticore-0.9.1-java/lib/manticore/client.rb:536: warning: already initialized constant Manticore::Client::StringEntity
{
"@timestamp" => 2023-06-29T02:46:00.473770200Z,
"id" => 1,
"content" => "test post",
"time" => 2023-06-27T01:05:41.000Z,
"title" => "hello",
"writer" => "admin",
"@version" => "1"
}
{
"@timestamp" => 2023-06-29T02:46:00.475770400Z,
"id" => 4,
"content" => "not admin / test ",
"time" => 2023-06-27T04:28:06.000Z,
"title" => "hello world this is test account",
"writer" => "test",
"@version" => "1"
}
{
"@timestamp" => 2023-06-29T02:46:00.475770400Z,
"id" => 5,
"content" => "did you get this? ",
"time" => 2023-06-28T07:46:48.000Z,
"title" => "elastic search",
"writer" => "admin",
"@version" => "1"
}
{
"@timestamp" => 2023-06-29T02:46:00.475770400Z,
"id" => 3,
"content" => "test1 ",
"time" => 2023-06-27T04:11:36.000Z,
"title" => "test",
"writer" => "admin",
"@version" => "1"
}
{
"@timestamp" => 2023-06-29T02:46:00.474768600Z,
"id" => 2,
"content" => "this is test post 2 ",
"time" => 2023-06-27T01:49:12.000Z,
"title" => "test post 2",
"writer" => "admin",
"@version" => "1"
}
으아아아 console에 데이터가 출력되고 있다!
바로 kibana에서도 확인해보자. dataview를 만들지 않았다면 규칙에 따라 하나 만들어주고, discover를 확인해본다.

!!!!!!!!! 된다!!!!!!!!!! 1분에 한 번씩 업데이트한 데이터를 올려주는 것이 보인다.... 감격 그 자체
실시간 모니터링이 맞는지 확인차 새 데이터를 하나 db에 추가해본다.

저렴한 데이터 추가... 그리고 이제 로그를 보면!


올라온다!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
휴 여전히 데이터 중복 적재 등의 문제가 존재하고는 있지만, 일단 실시간 모니터링이 된다는 것부터 감격 그 자체... 이 삽질 로그가 elasticsearch를 시도하는 누군가에게 도움이 되길 바란다........................
다음 포스팅에서는 데이터 중복적재를 막아보도록 하겠...다....
'🐥 Web > ❔ Back-end | etc.' 카테고리의 다른 글
[Elasticsearch] Index Template 구성하기 with Kibana & Logstash (2) - Mapping 기초 (0) | 2023.07.14 |
---|---|
[Elasticsearch] Index Template 구성하기 with Kibana & Logstash (1) - Setting (0) | 2023.07.06 |
[Elasticsearch] Logstash 사용해보기 (0) | 2023.06.29 |
[Elasticsearch] Elasticsearch 기본 개념 및 설치, kibana 연동하기 (1) | 2023.06.29 |
[SQL] SQL 중급 (0) | 2021.08.22 |