pinpoint inspector
Pinpoint의 Inspector를 달아서 좀 풍성하게 모니터링을 해보자.
먼저, 만약 3.x 이전 버전을 사용한다면 flink를 사용해서 inspector를 구성해주면 된다. (이걸 못봐서 flink로 삽질했었다.)
난 3.0.0 버전을 사용하니 Pinot이라는 친구를 써야 한다..
Pinot 연동하기
맘같아선 docker 그대로 땡겨와서 띄우고싶지만
내가 필요한 것 훨씬 이상의 성능을 내줄 것 같은 사양이 필요해서 수동으로 설치하기로 했다.
https://docs.pinot.apache.org/basics/getting-started/running-pinot-locally
Pinot 공식 문서대로 따라해도 되지만..
https://startree.ai/blog/apache-pinot-tutorial-for-getting-started-a-step-by-step-guide
난 이 가이드가 더 편해 이거대로 따라해봤다.
PINOT_VERSION=1.1.0 #set to the Pinot version you decide to use
wget https://downloads.apache.org/pinot/apache-pinot-$PINOT_VERSION/apache-pinot-$PINOT_VERSION-bin.tar.gz
pinot 다운 받고 압축풀고 보기 편하게 pinot으로 폴더 이름 바꿔주자
가이드 쭉 따라하기전에
기본으로 힙이 미니멈 4기가 잡혀있으니 512메가로 낮춰주고 시작하자.
실행하는건 정말 별거없다.. 그냥
./pinot-admin.sh StartZookeeper &
얘 먼저 띄워주고 (공식 문서 보면 얘가 애들끼리 소통하게 가운데에 위치한 역할을 한다, 뭐 관제탑 느낌이랄까)
./pinot-admin.sh StartController -zkAddress zkip:port &
./pinot-admin.sh StartBroker -zkAddress zkip:port &
./pinot-admin.sh StartServer -zkAddress zkip:port &
그다음엔 3개 다 올려주면 끝이다.
그다음 localhost:9000 으로 들어가보면
잘 떠있는 걸 볼 수 있다.
Pinpoint용 테이블 만들기
사실 정말 별거아니라 생각했는데 (kafka table도 별말없이 그냥 2개 생성하면 된다길래..)
거의 2시간 삽질했다..
2.2.B Create Pinot Tables
- Create 2 tables with the snames below:
- inspectorStatAgent00: This table stores agent inspector data. The script file to create the table is provided in our github repository.
- inspectorStatApp: This table stores application inspector data.
- Refer to the github repository for table schema and configuration settings.
핀포인트 가이드 문서에 이렇게 나와있듯이 첫 테이블은 스크립트 실행하면 만들어지고 두번째테이블은 깃헙 참고해서 만들면된다. (아니다)
스크립트 실행은 사실 2번째 테이블 만들 수 있는 상태면 그냥 실행해주면 끝나는거니 깃헙을 보며 inspectorStatApp 테이블을 만들어주자
여기서 밑에 2개가 스키마, 테이블 생성 파일이다.
pinot의 Real time 은 kafka를 사용하기에 카프카와 연결은 필수적으로 되어야 한다.
뭐, 카프카는 잘 켜져있고 동작도 하니 테이블을 바로 만들어보자
bin/pinot-admin.sh AddTable \
-schemaFile examples/stream/airlineStats/airlineStats_schema.json \
-tableConfigFile examples/stream/airlineStats/airlineStats_realtime_table_config.json \
-exec
저기서 스키마파일, tableConfigFile 부분은 당연히 github에서 받아온걸로 바꿔주면 된다.(위 코드는 pinot 공식 문서에 테이블 생성하는 예문이다)
(추가로, 동일 스키마에 offline 테이블을 또 추가하는 경우 HTTP 방식으로 넣는게 편하다 !)
이렇게 되면 짠 하고 테이블이 생기면 좋겠지만
INFO [AddTableCommand] [main] {"code":500,"error":"org.apache.pinot.spi.stream.TransientConsumerException: org.apache.pinot.shaded.org.apache.kafka.common.errors.TimeoutException: Timeout expired while fetching topic metadata"}
이런 오류가 떴다.
연결이 안되는데 주키퍼가 머리 역할을 하니 주키퍼 모드로 실행해야 서로를 알아보는건가 싶어 kafka를 주키퍼 모드로 실행하고 다시 해봤는데
(반드시, 주키퍼의 설정 파일(conf/zoo.cfg) 의 dataDir을 새로 지정해주자, 기본 값이 /tmp다. 즉, 재부팅하면 열심히 저장해둔거 다 증발한다. 내가 그랬다)
동일한 오류가 뜨고 실행이 되지 않는다.
카프카 서버 연결이 문제인가 싶어 로컬에서 telnet으로 포트를 찍어봤는데 잘 연결이 됐고, 인스턴스 내부에서 연결이 안되나 싶어 연결을 찍어봤는데 잘 연결이 됐다.
kafka 보안 설정이 문제가 되어 metadata를 못 읽을 수 있다는 글을 봐서 이것도 설정 확인했고 다시 해봤는데 똑같았다..
그러다 pinot web gui에서 table을 생성할 수 있으니 이거로 테이블을 만드는건 어떻게 되는건가 싶어 열어봤고
이런식의 창이 열렸다.
당연하게 broker.list에 localhost:9092 입력하던 순간에 설마 싶어 테이블 설정 json 파일을 열어보니
19092를 잡고있다
여태까지 했던 짓이 사실상 남의집에 대고 문열어달라고 소리친 꼴이니 당연히 될리가 없었다..
여튼, 9092로 바꿔주고 다시 테이블을 생성해보면
"code":500,"error":"There are less instances: 1 in instance partitions: inspectorStatApp_CONSUMING than the table replication: 3"
파티션 복제 수가 3이란다. 난 설정 파일을 안건드렸으니 1로 잡혀있을거니 얘도 1로 바꿔주면 된다.
그 후, 다시 테이블 생성을 해보면
정상적으로 테이블이 생성된 것을 확인할 수 있다.
마찬가지로 얘도 9092, replica 1로 바꿔주고 주어진 스크립트를 돌려주면 Inspector는 추가가 다 되었다.
이제 동일한 방식으로 나머지 3개에 대해서도 추가해주자
그러고 난 뒤, 기존 실행파일이 아닌 Starter 가 달린 collector와 web을 다운 받아주자
wget https://repo1.maven.org/maven2/com/navercorp/pinpoint/pinpoint-collector-starter/3.0.0/pinpoint-collector-starter-3.0.1-exec.jar
wget https://repo1.maven.org/maven2/com/navercorp/pinpoint/pinpoint-web-starter/3.0.0/pinpoint-web-starter-3.0.1-exec.jar
그리고, 가이드대로 설정 파일을 만들어주자 (난 pinot에 다른 auth 설정을 안해놨기에 username, password 부분은 없이 진행했다)
collector-starter-application.yml
pinpoint:
zookeeper:
address: 주키퍼주소
metric:
kafka:
bootstrap:
servers: 카프카주소:9092
spring:
pinot-datasource:
pinot:
jdbc-url: jdbc:pinot://localhost:9000
username: --username--
password: --password--
web-starter-application.yml
pinpoint:
zookeeper:
address: 주키퍼주소
spring:
pinot-datasource:
pinot:
jdbc-url: jdbc:pinot://localhost:9000
username: --username--
password: --password--
그 뒤, 컬렉터를 실행해보자
java -jar -Dspring.config.additional-location=collector-starter-application.yml pinpoint-collector-starter-boot-3.0.0.jar
오류가 떠서 뭔가 싶었는데 레디스 관련된 빈을 못만들었단다..
공식문서엔 안나와있지만 redis를 사용하나보다..
sudo apt-get install lsb-release curl gpg
curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
sudo chmod 644 /usr/share/keyrings/redis-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list
sudo apt-get update
sudo apt-get install redis
깔고 돌려보면
뭐 경고,오류 로그가 엄청나게 쏟아진다
또, 이상한 점은 16020포트로 접근을 실패했다는 로그가 떴다.
찾아보니..
Service | Servers | Default Ports Used | Protocol | Description | Need End User Access? | Configuration Parameters |
---|---|---|---|---|---|---|
HMaster | Master Nodes (HBase Master Node and any back-up HBase Master node) | 16000 | TCP | The port used by HBase client to connect to the HBase Master. | Yes | hbase.master.port |
HMaster Info Web UI | Master Nodes (HBase master Node and back up HBase Master node if any) | 16010 | HTTP | The port for the HBaseMaster web UI. Set to -1 if you do not want the info server to run. | Yes | hbase.master.info.port |
RegionServer | All Slave Nodes | 16020 | TCP | The port used by HBase client to connect to the HBase RegionServer. | Yes (Typically admins, dev/support teams) | hbase.regionserver.port |
RegionServer | All Slave Nodes | 16030 | HTTP | The port used by HBase client to connect to the HBase RegionServer. | Yes (Typically admins, dev/support teams) | hbase.regionserver.info.port |
HBase REST Server (optional) | All REST Servers | 8080 | HTTP | The port used by HBase Rest Servers. REST servers are optional, and not installed by default | Yes | hbase.rest.port |
HBase REST Server Web UI (optional) | All REST Servers | 8085 | HTTP | The port used by HBase Rest Servers web UI. REST servers are optional, and not installed by default | Yes (Typically admins, dev/support teams) | hbase.rest.info.port |
HBase Thrift Server (optional) | All Thrift Servers | 9090 | TCP | The port used by HBase Thrift Servers. Thrift servers are optional, and not installed by default | Yes | N/A |
HBase Thrift Server Web UI (optional) | All Thrift Servers | 9095 | TCP | The port used by HBase Thrift Servers web UI. Thrift servers are optional, and not installed by default | Yes (Typically admins, dev/support teams) | hbase.thrift.info.port |
16020은 hbase의 region server가 사용하고
공식 문서에서도 알 수 있듯이 region server는 데이터의 읽기,쓰기를 담당한다.
이걸 수동으로 켜야 하는 거라면 pinpoint 공식 문서에도 적혀있을 것이라 생각해 열심히 찾아봤지만 16020포트나 regionserver에 대한 언급은 없었다. 또한, 소스코드 전체에서도 16020포트에 대한 내용은 없다..
심지어, jps로 hbase가 돌아가고 있는 지 확인해봐도 정상적으로 동작하고 있었다.
포트에 대한 접근을 왜 못하는 지 생각해보다 표출되는 ip와 호스트 이름이 내부 IP란 사실을 알게 되었고, 로컬 방화벽 조건에 내부IP를 예외로 추가하여 재부팅을 해봤다.
다시 hbase를 켜주면 아래처럼 region server도 잘 붙어서 켜지는 걸 알 수 있다.
서버도 잘 올라간 걸 확인했으면 다시 시도해보자.
java -jar -Dspring.config.additional-location=collector-starter-application.yml pinpoint-collector~.jar
2024-09-01T08:30:32.473Z, org.apache.hadoop.hbase.ipc.FailedServerException: Call to address=***(인스턴스이름).internal:16020 failed on local exception: org.ap
또, 연결을 못했다.
그런데, 막상 확인해보면 16020포트가 안열려있다.
다시 확인해보면 RegionServer가 사라진 걸 알 수 있다.
이번엔 일반 계정으로 다시 hbase를 돌려주고 확인해보면
regionsserver가 다시 등록됐다.
16020도 열려있으니 다시 시도해보니.. 성공이다
이제 collector, web을 돌려놓고
nohup sudo java -jar -Dspring.config.additional-location=collector-starter-appliaction.yml pinpoint-collector-starter-3.0.1-exec.jar >> ../logs/pinpoint-collector.log &
nohup sudo java -jar -Dspring.config.additional-location=web-starter-application.yml pinpoint-web-starter-3.0.1-exec.jar >> ../logs/pinpoint-web.log &
web을 확인해보면
잘 뜬다..!
메트릭 수집
컬렉터 소스 코드를 보면 시작 시점에 인자로 Collector type을 받아 실행 모드를 설정하게 되는데
ALL인 경우 둘 다 잘 시작되는거니 Collector와 web에 별다른 수정 없이 telegraf만 설치하면 메트릭 수집까지 될 것 같다.
이제 telegraf를 백엔드 인스턴스에 설치하여 시스템 메트릭 데이터를 수집해보자.
wget -q https://repos.influxdata.com/influxdata-archive_compat.key
echo '393e8779c89ac8d958f81f942f9ad7fb82a25e133faddaf92e15b16e6ac9ce4c influxdata-archive_compat.key' | sha256sum -c && cat influxdata-archive_compat.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg > /dev/null
echo 'deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main' | sudo tee /etc/apt/sources.list.d/influxdata.list
sudo apt-get update && sudo apt-get install telegraf
be인스턴스는 둘 다 Ubuntu니 위 명령어로 설치를 해주자
telegraf config > telegraf.conf
설정 파일을 default로 우선 만들어주고 편집을 해주자
설정 파일이 매우 기니 outputs.http로 검색을 해주자
[[outputs.http]]
url = "http://{PINPOINT_COLLECTOR_IP}:15200/telegraf"
[outputs.http.headers]
hostGroupName = {applicationName}
Content-Type = "application/json"
위와 같이 설정을 추가해주고
sudo systemctl start telegraf
telegraf를 실행해주자
또한, 컬렉터에 15200포트로 정보를 전달하니 15200도 열어주자
그 후, 웹에서 확인해보면
못찾겠단다..
천천히 살펴보자
15200 포트가 안열렸나 ?
- 열려있다.
telegraf 설정이 잘못되었나 ?
요청이 가긴하는데 400이 왔다.
실제 코드에선 telegraf 설정을 아래와 같이 되어 있으니 동일하게 맞추고 다시 돌려보면
똑같다.
그러면 컨트롤러 코드를 직접 확인해보자
TelegrafMetrics
란 객체를 body로 받는다
얘는 TelegrafMetric이란 객체의 컬렉션이고
해당 객체는 위와 같다.
name, timestamp까진 뭐 바로 치면 되지만 Fields, Tags가 그리 단순하게 노가다로 따라 치기엔 어려워 보이니 이번엔 Telegraf에서 RESTAPI는 어떻게 값을 보내는 지 확인해보자
{
"fields": {
"field_1": 30,
"field_2": 4,
"field_N": 59,
"n_images": 660
},
"name": "docker",
"tags": {
"host": "raynor"
},
"timestamp": 1458229140
}
공식 문서를 보니 되게 단순하게 보낸다.
그대로 다시 요청을 보내보면,
똑같이 파싱 에러가 뜬다.
실제로는 어떻게 보내고 있는 지 확인해자.
telegraf --config /etc/telegraf/telegraf.conf --debug
로그 레벨을 debug로 바꿔서 출력을 확인해보면.. 아쉽게도 body내용이 찍히진 않는다.
다음으로 시도했던건 테스트 코드다.
이정도 규모면 테스트 커버리지도 신경쓸테니 이 api에 대한 테스트코드도 있을 것이라 생각했고 찾아보니
이런 테스트 코드가 있었고 저기 json파일을 열어보면
..?
너무 낯익은 친구가 나왔다.
공식문서에서 봤던 그친구가 그대로 들어있다..
그대로 넣어서 요청을 보내면 정상 처리된 걸 확인할 수 있다..
뭔가 처리도 잘 된거같고..
헤더에 넣어줬던 이름도 들어갔다.
근데 뭔가 이상한게, postman으로 로컬에서 보냈을 땐 400에러 로그가 collector에도 계속 찍혔는데
be 인스턴스들에서 보내는 값들에 대해선 전혀 반응을 하지 않는다.
그렇다는 뜻은 애초에 컨트롤러에서 Validation하는 과정에서 에러가 생긴게 아니라는 뜻이 된다.
그러면, be1, be2에서 보내는 요청이 다 씹히는걸까 ?
확인해보기 위해 curl을 보내보면
정상적으로 처리되고 응답도 잘 받았다..?
그렇다는 뜻은 telegraf에 설정된 값이 뭐가 잘못된건데..
혹시나 설정 파일 반영이 안되나싶어 설정파일에서 ip를 바꿔 봤는데, 잘못된 ip로 보내니 응답시간 초과에 걸린걸 보아 설정 파일 반영은 잘 되는걸 알 수 있었다.
만약, 네트워크 이슈라고 가정했을 때 동일 인스턴스 내부에선 동작해야 정상일테니 컬렉터가 있는 gcp에서 telegraf를 깔아 다시 해보자. conf 파일은 pinpoint 문서에 있던걸 그대로 복붙해서 사용했다.
아무 설정 없이 바로 잡혔다..
혹시나 싶어 pinpoint에 달린 conf에서 ip와 group name만 바꿔서 be 인스턴스에 넣고 돌려봤더니
된다..
뭐가 문제인지 찾아보려 했지만 default conf파일을 찾기도 힘들고 그렇다고 복사해서 diff를 떠보기엔 너무 빡세고, 그렇게 의미있진 않을 것 같아서 그냥 그러려니 하고 넘기련다.
여튼 핀포인트에서 제공하는 conf 파일은 아래와 같다
# Telegraf Configuration
#
# Telegraf is entirely plugin driven. All metrics are gathered from the
# declared inputs, and sent to the declared outputs.
#
# Plugins must be declared in here to be active.
# To deactivate a plugin, comment out the name and any variables.
#
# Use 'telegraf -config telegraf.conf -test' to see what metrics a config
# file would generate.
#
# Environment variables can be used anywhere in this config file, simply surround
# them with ${}. For strings the variable must be within quotes (ie, "${STR_VAR}"),
# for numbers and booleans they should be plain (ie, ${INT_VAR}, ${BOOL_VAR})
# Global tags can be specified here in key="value" format.
[global_tags]
# dc = "us-east-1" # will tag all metrics with dc=us-east-1
# rack = "1a"
## Environment variables can be used as tags, and throughout the config file
# user = "$USER"
# Configuration for telegraf agent
[agent]
## Default data collection interval for all inputs
interval = "10s"
## Rounds collection interval to 'interval'
## ie, if interval="10s" then always collect on :00, :10, :20, etc.
round_interval = true
## Telegraf will send metrics to outputs in batches of at most
## metric_batch_size metrics.
## This controls the size of writes that Telegraf sends to output plugins.
metric_batch_size = 1000
## Maximum number of unwritten metrics per output. Increasing this value
## allows for longer periods of output downtime without dropping metrics at the
## cost of higher maximum memory usage.
metric_buffer_limit = 10000
## Collection jitter is used to jitter the collection by a random amount.
## Each plugin will sleep for a random time within jitter before collecting.
## This can be used to avoid many plugins querying things like sysfs at the
## same time, which can have a measurable effect on the system.
collection_jitter = "0s"
## Default flushing interval for all outputs. Maximum flush_interval will be
## flush_interval + flush_jitter
flush_interval = "10s"
## Jitter the flush interval by a random amount. This is primarily to avoid
## large write spikes for users running a large number of telegraf instances.
## ie, a jitter of 5s and interval 10s means flushes will happen every 10-15s
flush_jitter = "0s"
## By default or when set to "0s", precision will be set to the same
## timestamp order as the collection interval, with the maximum being 1s.
## ie, when interval = "10s", precision will be "1s"
## when interval = "250ms", precision will be "1ms"
## Precision will NOT be used for service inputs. It is up to each individual
## service input to set the timestamp at the appropriate precision.
## Valid time units are "ns", "us" (or "µs"), "ms", "s".
precision = ""
## Log at debug level.
# debug = false
## Log only error level messages.
# quiet = false
## Log target controls the destination for logs and can be one of "file",
## "stderr" or, on Windows, "eventlog". When set to "file", the output file
## is determined by the "logfile" setting.
# logtarget = "file"
## Name of the file to be logged to when using the "file" logtarget. If set to
## the empty string then logs are written to stderr.
# logfile = ""
## The logfile will be rotated after the time interval specified. When set
## to 0 no time based rotation is performed. Logs are rotated only when
## written to, if there is no log activity rotation may be delayed.
# logfile_rotation_interval = "0d"
## The logfile will be rotated when it becomes larger than the specified
## size. When set to 0 no size based rotation is performed.
# logfile_rotation_max_size = "0MB"
## Maximum number of rotated archives to keep, any older logs are deleted.
## If set to -1, no archives are removed.
# logfile_rotation_max_archives = 5
## Override default hostname, if empty use os.Hostname()
hostname = ""
## If set to true, do no set the "host" tag in the telegraf agent.
omit_hostname = false
###############################################################################
# OUTPUT PLUGINS #
###############################################################################
# A plugin that can transmit metrics over HTTP
[[outputs.http]]
## URL is the address to send metrics to
url = "http://127.0.0.1:15200/telegraf"
#
# ## Timeout for HTTP message
timeout = "5s"
#
# ## HTTP method, one of: "POST" or "PUT"
method = "POST"
#
# ## HTTP Basic Auth credentials
# # username = "username"
# # password = "pa$$word"
#
# ## OAuth2 Client Credentials Grant
# # client_id = "clientid"
# # client_secret = "secret"
# # token_url = "https://indentityprovider/oauth2/v1/token"
# # scopes = ["urn:opc:idm:__myscopes__"]
#
# ## Optional TLS Config
# # tls_ca = "/etc/telegraf/ca.pem"
# # tls_cert = "/etc/telegraf/cert.pem"
# # tls_key = "/etc/telegraf/key.pem"
# ## Use TLS but skip chain & host verification
# # insecure_skip_verify = false
#
# ## Data format to output.
# ## Each data format has it's own unique set of configuration options, read
# ## more about them here:
# ## https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_OUTPUT.md
data_format = "json"
#
# ## HTTP Content-Encoding for write request body, can be set to "gzip" to
# ## compress body or "identity" to apply no encoding.
# # content_encoding = "identity"
#
# ## Additional HTTP headers
[outputs.http.headers]
# # Should be set manually to "application/json" for json data_format
# Agent-Id = "Metric-Test-Aegent"
hostGroupName = "Metric-Test-APP"
Content-Type = "application/json"
# # Configuration for sending metrics to InfluxDB
# # Configuration for the Kafka server to send metrics to
# [[outputs.kafka]]
# ## URLs of kafka brokers
# brokers = ["localhost:9092"]
# ## Kafka topic for producer messages
# topic = "telegraf"
#
# ## The value of this tag will be used as the topic. If not set the 'topic'
# ## option is used.
# # topic_tag = ""
#
# ## If true, the 'topic_tag' will be removed from to the metric.
# # exclude_topic_tag = false
#
# ## Optional Client id
# # client_id = "Telegraf"
#
# ## Set the minimal supported Kafka version. Setting this enables the use of new
# ## Kafka features and APIs. Of particular interest, lz4 compression
# ## requires at least version 0.10.0.0.
# ## ex: version = "1.1.0"
# # version = ""
#
# ## Optional topic suffix configuration.
# ## If the section is omitted, no suffix is used.
# ## Following topic suffix methods are supported:
# ## measurement - suffix equals to separator + measurement's name
# ## tags - suffix equals to separator + specified tags' values
# ## interleaved with separator
#
# ## Suffix equals to "_" + measurement name
# # [outputs.kafka.topic_suffix]
# # method = "measurement"
# # separator = "_"
#
# ## Suffix equals to "__" + measurement's "foo" tag value.
# ## If there's no such a tag, suffix equals to an empty string
# # [outputs.kafka.topic_suffix]
# # method = "tags"
# # keys = ["foo"]
# # separator = "__"
#
# ## Suffix equals to "_" + measurement's "foo" and "bar"
# ## tag values, separated by "_". If there is no such tags,
# ## their values treated as empty strings.
# # [outputs.kafka.topic_suffix]
# # method = "tags"
# # keys = ["foo", "bar"]
# # separator = "_"
#
# ## The routing tag specifies a tagkey on the metric whose value is used as
# ## the message key. The message key is used to determine which partition to
# ## send the message to. This tag is preferred over the routing_key option.
# routing_tag = "host"
#
# ## The routing key is set as the message key and used to determine which
# ## partition to send the message to. This value is only used when no
# ## routing_tag is set or as a fallback when the tag specified in routing tag
# ## is not found.
# ##
# ## If set to "random", a random value will be generated for each message.
# ##
# ## When unset, no message key is added and each message is routed to a random
# ## partition.
# ##
# ## ex: routing_key = "random"
# ## routing_key = "telegraf"
# # routing_key = ""
#
# ## CompressionCodec represents the various compression codecs recognized by
# ## Kafka in messages.
# ## 0 : No compression
# ## 1 : Gzip compression
# ## 2 : Snappy compression
# ## 3 : LZ4 compression
# # compression_codec = 0
#
# ## RequiredAcks is used in Produce Requests to tell the broker how many
# ## replica acknowledgements it must see before responding
# ## 0 : the producer never waits for an acknowledgement from the broker.
# ## This option provides the lowest latency but the weakest durability
# ## guarantees (some data will be lost when a server fails).
# ## 1 : the producer gets an acknowledgement after the leader replica has
# ## received the data. This option provides better durability as the
# ## client waits until the server acknowledges the request as successful
# ## (only messages that were written to the now-dead leader but not yet
# ## replicated will be lost).
# ## -1: the producer gets an acknowledgement after all in-sync replicas have
# ## received the data. This option provides the best durability, we
# ## guarantee that no messages will be lost as long as at least one in
# ## sync replica remains.
# # required_acks = -1
#
# ## The maximum number of times to retry sending a metric before failing
# ## until the next flush.
# # max_retry = 3
#
# ## The maximum permitted size of a message. Should be set equal to or
# ## smaller than the broker's 'message.max.bytes'.
# # max_message_bytes = 1000000
#
# ## Optional TLS Config
# # enable_tls = true
# # tls_ca = "/etc/telegraf/ca.pem"
# # tls_cert = "/etc/telegraf/cert.pem"
# # tls_key = "/etc/telegraf/key.pem"
# ## Use TLS but skip chain & host verification
# # insecure_skip_verify = false
#
# ## Optional SASL Config
# # sasl_username = "kafka"
# # sasl_password = "secret"
#
# ## SASL protocol version. When connecting to Azure EventHub set to 0.
# # sasl_version = 1
#
# ## Data format to output.
# ## Each data format has its own unique set of configuration options, read
# ## more about them here:
# ## https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_OUTPUT.md
# # data_format = "influx"
###############################################################################
# PROCESSOR PLUGINS #
###############################################################################
# # Convert values to another metric value type
# [[processors.converter]]
# ## Tags to convert
# ##
# ## The table key determines the target type, and the array of key-values
# ## select the keys to convert. The array may contain globs.
# ## <target-type> = [<tag-key>...]
# [processors.converter.tags]
# measurement = []
# string = []
# integer = []
# unsigned = []
# boolean = []
# float = []
#
# ## Fields to convert
# ##
# ## The table key determines the target type, and the array of key-values
# ## select the keys to convert. The array may contain globs.
# ## <target-type> = [<field-key>...]
# [processors.converter.fields]
# measurement = []
# tag = []
# string = []
# integer = []
# unsigned = []
# boolean = []
# float = []
# # Filter metrics with repeating field values
# [[processors.dedup]]
# ## Maximum time to suppress output
# dedup_interval = "600s"
# # Print all metrics that pass through this filter.
# [[processors.printer]]
# order = 3
###############################################################################
# INPUT PLUGINS #
###############################################################################
# Read metrics about cpu usage
[[inputs.cpu]]
## Whether to report per-cpu stats or not
percpu = true
## Whether to report total system cpu stats or not
totalcpu = true
## If true, collect raw CPU time metrics.
collect_cpu_time = false
## If true, compute and report the sum of all non-idle CPU states.
report_active = false
# Read metrics about disk usage by mount point
[[inputs.disk]]
## By default stats will be gathered for all mount points.
## Set mount_points will restrict the stats to only the specified mount points.
# mount_points = ["/"]
## Ignore mount points by filesystem type.
ignore_fs = ["tmpfs", "devtmpfs", "devfs", "iso9660", "overlay", "aufs", "squashfs"]
# Read metrics about disk IO by device
[[inputs.diskio]]
## By default, telegraf will gather stats for all devices including
## disk partitions.
## Setting devices will restrict the stats to the specified devices.
# devices = ["sda", "sdb", "vd*"]
## Uncomment the following line if you need disk serial numbers.
# skip_serial_number = false
#
## On systems which support it, device metadata can be added in the form of
## tags.
## Currently only Linux is supported via udev properties. You can view
## available properties for a device by running:
## 'udevadm info -q property -n /dev/sda'
## Note: Most, but not all, udev properties can be accessed this way. Properties
## that are currently inaccessible include DEVTYPE, DEVNAME, and DEVPATH.
# device_tags = ["ID_FS_TYPE", "ID_FS_USAGE"]
#
## Using the same metadata source as device_tags, you can also customize the
## name of the device via templates.
## The 'name_templates' parameter is a list of templates to try and apply to
## the device. The template may contain variables in the form of '$PROPERTY' or
## '${PROPERTY}'. The first template which does not contain any variables not
## present for the device is used as the device name tag.
## The typical use case is for LVM volumes, to get the VG/LV name instead of
## the near-meaningless DM-0 name.
# name_templates = ["$ID_FS_LABEL","$DM_VG_NAME/$DM_LV_NAME"]
# Get kernel statistics from /proc/stat
[[inputs.kernel]]
# no configuration
# Read metrics about memory usage
[[inputs.mem]]
# no configuration
# Get the number of processes and group them by status
[[inputs.processes]]
# no configuration
# Read metrics about swap memory usage
[[inputs.swap]]
# no configuration
# Read metrics about system load & uptime
[[inputs.system]]
## Uncomment to remove deprecated metrics.
fielddrop = ["uptime_format"]
혹시 따라하려면 이 파일을 그냥 쓰자.
여튼, 사진처럼 메트릭도 잘 잡히니
마지막으로 Error Analysis만 정상 구동시켜주면 끝이다.
에러 핸들링 2차전
기분좋게 error analysis만 붙이고 끝내려했더니
뭐가 또 불만이란다
collector로그를 보니
피놋 관련된 오류가 뜨고있었고
테이블들이 많이 아픈 상태였고
오류의 대상인 세그먼트는 아주 슬퍼하고 있었다.
우선 만병통치약인 리붓부터 해보자
ERROR [MessageGenerationPhase] [HelixController-pipeline-default-PinotCluster-(bf0de293_DEFAULT)] Event bf0de293_DEFAULT : Unable to find a next state for resource: uriStat_REALTIME partition: uriStat__0__3__20240903T0838Z from stateModelDefinitionclass org.apache.helix.model.StateModelDefinition from:ERROR to:ONLINE
아무런 해결은 되지 않았다.
확실한건 계속 segment들이 아프다는거같았고, REALTIME 테이블에 있는 고장난 세그먼트들을 모두 지워 줬다.
그랬더니
돌아왔다.
be 인스턴스에서 telegraf를 켜보면 (hostGroup을 Main-Backend로 묶어줬다)
이제 진짜 Error Analysis를 수정해보자
Error Analysis 붙이기
뭐가 문제인가 싶어 찾아보다 보니..
https://github.com/pinpoint-apm/pinpoint/issues/11170
요런 이슈가 등록되어 있었다
뭔가 싶어 찾아가봤는데..
https://github.com/pinpoint-apm/pinpoint/commit/402c27ff64e1512d76a5249f6c066bf68f051a06
요 이슈 때문에 테이블, 스키마 이름에서 V1을 뺐는데
문제는 실제 코드(3.0.0)에선 ExceptionTrace 시점에 V1을 사용하는 듯 했다..!
Caused by: java.sql.SQLException: Failed to execute query : SELECT
arraySliceInt(
HISTOGRAM("timestamp", 1731158040000, 1731158340000, 11), 0, 11
) as "values"
FROM
exceptionTraceV1
WHERE
tenantId = 'pinpoint'
AND applicationName = 'Main-Backend'
AND "timestamp" BETWEEN 1731158040000 AND 1731158340000
AND agentId = 'be-2'
GROUP BY applicationName
ORDER BY count(*) desc
LIMIT 10
web 로그에 요런 sql 오류가 떴고, V1이 달린 테이블을 기준으로 조회하길래 찾아보니..
지금 코드 상에선 exceptionTrace가 맞다..;
그럼 쟤는 언제 바뀐걸까 ? 3.0.0에 반영된게 맞나 ?
https://github.com/pinpoint-apm/pinpoint/commit/f5ff79945627b23158e4c76e646a03dccc1df38e
아니다..
https://github.com/pinpoint-apm/pinpoint/issues/11276
이제보니 수동으로 값을 덮어씌워줘야 한다..
.. 뭐 메이저 버전 업이니 다들 디테일하게 신경쓰진 못하셨던거같다.
여튼 이걸 반영하고 나니
얘도 잘 된다 !
회사일, 이직 준비 때문에 갠플젝에 쓸 시간이 너무 없었다… 내일도 출근해야 하긴 하지만 짬나는 시간 있을때마다 본격적으로 프로젝트 기능을 정리하고 기능 구현에 들어가보자..!
참고
https://tcp-udp-ports.com/port-16020.htm
https://o.onslip.net/HDPDocuments/HDP3/HDP-3.1.4/administration/content/hbase-ports.html
https://pinpoint-apm.gitbook.io/pinpoint/getting-started/installation#profiles-2
'Gyunpang' 카테고리의 다른 글
9. pinpoint로 서버를 모니터링해보자 (0) | 2024.08.17 |
---|---|
프로젝트 구조 중간점검 (0) | 2024.07.27 |
8. Gateway 로깅 및 인증 기능 구현하기(2) (0) | 2024.07.23 |
7. Gateway 로깅 및 인증 기능 구현하기(1) (1) | 2024.07.23 |
(번외) docker container scale 조정 시 github action에서만 recreate된다.. (0) | 2024.04.13 |