Ken
다양한 데이터 소스의 메트릭과 로그를, 소스 시스템 변경 없이 OpenTelemetry Collector 하나로 ClickHouse Cloud에 수집하는 방법을 소개합니다.
들어가며
운영 환경에서 모니터링해야 할 대상은 다양합니다. Kafka 브로커의 JMX 메트릭, MySQL과 MSSQL의 데이터베이스 상태, AWS 클라우드 서비스 로그, 그리고 이미 운영 중인 Prometheus 타겟까지. 이 모든 텔레메트리 데이터를 한 곳에 모아서 보고 싶다면 어떻게 해야 할까요?
정답은 OpenTelemetry Collector입니다. OTel Collector는 CNCF가 관리하는 벤더 중립적인 텔레메트리 수집 에이전트로, 다양한 소스에서 데이터를 받아 원하는 백엔드로 보내주는 파이프라인 역할을 합니다. 그리고 그 백엔드로 ClickHouse Cloud를 사용하면, 초당 수백만 행의 insert 성능과 페타바이트 스케일의 분석 능력을 갖춘 통합 옵저버빌리티 스토리지를 구성할 수 있습니다.
이 글에서는 실제 엔터프라이즈 환경에서 자주 등장하는 6가지 데이터 소스를 OTel Collector로 수집하고, ClickHouse Cloud에 저장한 뒤, HyperDX(ClickStack)로 시각화하는 전체 과정을 다룹니다.
전체 아키텍처
구조는 단순합니다. 어떤 소스에서 왔든 OTel Collector 내부에서 표준 OTel 포맷으로 변환된 뒤, 하나의 ClickHouse exporter를 통해 ClickHouse Cloud로 들어갑니다. Receiver가 아무리 다양해도 Exporter는 하나입니다.
사전 준비: OTel Collector contrib 배포판
주의할 점이 하나 있습니다. 기본 OTel Collector에는 ClickHouse exporter, MySQL receiver, MSSQL receiver 등이 포함되어 있지 않습니다. 반드시 contrib 배포판 (otelcol-contrib)을 사용하거나, 필요한 컴포넌트만 포함한 커스텀 Collector를 빌드해야 합니다.
프로덕션에서는 커스텀 빌드를 권장합니다. OpenTelemetry Collector Builder(ocb)를 사용하면 필요한 receiver, processor, exporter만 선택해서 경량화된 바이너리를 만들 수 있습니다.
ocb --config builder-config.yamlClickHouse Cloud Exporter 설정
모든 소스에 공통으로 적용되는 export 설정부터 살펴보겠습니다. 소스가 무엇이든 이 부분은 동일합니다.
exporters:
clickhouse:
endpoint: tcp://<your-instance>.clickhouse.cloud:9440?secure=true
database: otel
username: default
password: ${env:CLICKHOUSE_PASSWORD}
create_schema: true
logs_table_name: otel_logs
traces_table_name: otel_traces
metrics_table_name: otel_metrics
ttl: 720h # 30일 보관
tls:
insecure: falseClickHouse Cloud에서 신경 써야 할 핵심 포인트는 다음과 같습니다.
TLS는 필수입니다. ClickHouse Cloud는 암호화된 연결만 허용합니다. Native protocol 포트는 9440, HTTP 포트는 8443을 사용합니다.
배치 처리는 반드시 적용해야 합니다. ClickHouse는 소량의 빈번한 insert에 최적화되어 있지 않습니다. ClickHouse 공식 문서에서도 최소 1,000행 이상의 배치 insert를 권장합니다. OTel Collector의 batch processor로 이를 보장할 수 있습니다.
processors:
batch:
timeout: 5s
send_batch_size: 10000
send_batch_max_size: 11000스키마 관리 전략을 결정해야 합니다. create_schema: true는 테스트에 편리하지만, 프로덕션에서는 직접 DDL을 관리하는 것이 좋습니다. 여러 Collector 인스턴스가 동시에 테이블을 생성하려고 경쟁하는 상황을 방지할 수 있고, TTL, 파티션 키, 인덱스를 워크로드에 맞게 최적화할 수 있습니다.
데이터 타입별 테이블 매핑을 이해해야 합니다. Exporter는 Receiver가 무엇이든 상관하지 않습니다. 단지 데이터가 metrics인지, logs인지, traces인지만 구분해서 해당 테이블에 insert합니다.
Receiver 출력 | ClickHouse 테이블 |
Kafka JMX → metrics | otel_metrics |
kafkametrics → metrics | otel_metrics |
mysql → metrics | otel_metrics |
sqlserver → metrics + logs | otel_metrics + otel_logs |
prometheus → metrics | otel_metrics |
filelog → logs | otel_logs |
소스별 Receiver 설정과 변경 사항
이제 각 데이터 소스를 하나씩 살펴보겠습니다. 핵심 질문은 하나입니다: 소스 시스템에서 뭘 바꿔야 하는가?
1. Kafka JMX 메트릭 (브로커 / 커넥트)
소스 쪽 변경: 브로커 시작 옵션에 Java Agent 1줄 추가
Kafka 브로커의 JMX 메트릭을 수집하는 방법은 여러 가지가 있지만, OTel Java Agent를 사용하는 push 방식을 권장합니다. JMX 포트를 외부에 노출할 필요가 없고, Kafka JVM 내부에서 직접 메트릭을 수집해서 Collector로 전송합니다.
브로커 시작 시 KAFKA_OPTS에 다음을 추가합니다:
export KAFKA_OPTS="\
-javaagent:/opt/opentelemetry-javaagent.jar \
-Dotel.metrics.exporter=otlp \
-Dotel.exporter.otlp.metrics.endpoint=http://<otel-collector>:4318/v1/metrics \
-Dotel.exporter.otlp.protocol=http/protobuf \
-Dotel.service.name=kafka-broker-1 \
-Dotel.jmx.target.system=kafka-broker"Kafka Connect도 동일한 패턴입니다. target.system만 kafka-connect로 변경하면 됩니다.
Collector 쪽에서는 OTLP receiver로 받으면 됩니다:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318추가로 토픽별 메시지 수, 컨슈머 랙 등 Kafka 클러스터 레벨 메트릭도 필요하다면, kafkametrics receiver를 함께 사용합니다. 이 receiver는 Kafka 브로커에 직접 접속해서 메트릭을 수집하므로 소스 쪽 변경이 전혀 필요 없습니다:
receivers:
kafkametrics:
brokers: kafka-1:9092,kafka-2:9092
protocol_version: 2.0.0
collection_interval: 10s
scrapers:
- brokers
- topics
- consumersJava Agent(JVM 레벨 JMX) + kafkametrics(클러스터 레벨) 조합이 가장 포괄적인 Kafka 모니터링을 제공합니다.
2. AWS 클라우드 로그
소스 쪽 변경: 없음
OTel Collector가 CloudWatch Logs API를 통해 직접 로그를 가져옵니다. IAM 권한만 설정되어 있으면 됩니다.
receivers:
awscloudwatchlogs:
region: ap-northeast-2
logs:
- log_group_name: /aws/lambda/my-function
- log_group_name: /aws/ecs/my-service
poll_interval: 1m대량 로그의 경우 Kinesis Data Firehose를 통해 push 방식으로 수집하는 것도 가능합니다:
receivers:
awsfirehose:
endpoint: 0.0.0.0:4433
record_type: cwlogs3. MySQL
소스 쪽 변경: 모니터링용 읽기 전용 유저 생성
CREATE USER 'otel'@'%' IDENTIFIED BY 'your_password';
GRANT SELECT, PROCESS, REPLICATION CLIENT ON *.* TO 'otel'@'%';
GRANT SELECT ON performance_schema.* TO 'otel'@'%';
FLUSH PRIVILEGES;이후 OTel Collector의 mysql receiver가 해당 유저로 접속해서 SHOW GLOBAL STATUS, InnoDB 메트릭, performance_schema 기반 쿼리 샘플을 수집합니다.
receivers:
mysql:
endpoint: mysql-host:3306
username: otel
password: ${env:MYSQL_PASSWORD}
collection_interval: 10s
statement_events:
digest_text_limit: 120
time_limit: 24h
limit: 250Error log나 Slow query log 같은 파일 기반 로그는 filelog receiver로 별도 수집합니다:
receivers:
filelog/mysql_error:
include:
- /var/log/mysql/error.log
filelog/mysql_slow:
include:
- /var/log/mysql/slow-query.log
multiline:
line_start_pattern: "^# Time:"4. MSSQL
소스 쪽 변경: 모니터링용 유저 생성 및 권한 부여
CREATE LOGIN otel_user WITH PASSWORD = 'your_password';
-- SQL Server 2022+
GRANT VIEW SERVER PERFORMANCE STATE TO otel_user;
-- 이전 버전
GRANT VIEW SERVER STATE TO otel_user;OTel Collector의 sqlserver receiver는 Windows Performance Counters 방식과 직접 연결 방식을 모두 지원합니다. Linux 환경에서는 직접 연결 방식을 사용합니다.
receivers:
sqlserver:
collection_interval: 10s
username: otel_user
password: ${env:MSSQL_PASSWORD}
server: mssql-host
port: 1433
events:
db.server.query_sample:
enabled: true
db.server.top_query:
enabled: true
top_query_collection:
lookback_time: 60s
top_query_count: 200
collection_interval: 60ssqlserver receiver의 흥미로운 점은 메트릭뿐 아니라, top query와 query sample을 로그 형태로도 export한다는 것입니다. 따라서 logs 파이프라인에도 이 receiver를 연결하면 쿼리 성능 분석 데이터까지 ClickHouse에 저장할 수 있습니다.
5. Prometheus 메트릭
소스 쪽 변경: 없음
이미 Prometheus를 운영 중이라면, 기존 scrape_config를 그대로 OTel Collector의 prometheus receiver에 넣으면 됩니다. 기존 Prometheus 서버를 대체하거나 병행할 수 있습니다.
receivers:
prometheus:
config:
scrape_configs:
- job_name: 'my-app'
scrape_interval: 15s
static_configs:
- targets: ['app-host:9090']
- job_name: 'node-exporter'
static_configs:
- targets: ['node-1:9100', 'node-2:9100']전체 통합 설정
지금까지의 모든 설정을 하나의 Collector 설정 파일로 합치면 다음과 같습니다:
소스별 변경 사항 총정리
소스 | 소스 쪽 변경 | OTel Collector 쪽 |
Kafka JMX | 브로커 시작 옵션에 -javaagent 1줄 추가 | otlp receiver로 수신 |
Kafka 토픽/컨슈머 | 변경 없음 | kafkametrics receiver가 브로커에 직접 접속 |
AWS 클라우드 로그 | 변경 없음 | awscloudwatchlogs receiver가 API로 pull |
MySQL | 모니터링용 DB 유저 생성 ( GRANT SELECT) | mysql receiver가 직접 접속 |
MSSQL | 모니터링용 DB 유저 생성 ( VIEW SERVER STATE) | sqlserver receiver가 직접 접속 |
Prometheus | 변경 없음 | prometheus receiver가 기존 타겟 스크래핑 |
대부분의 소스는 변경이 전혀 필요 없거나, 읽기 전용 유저를 하나 만들어주는 수준입니다. Kafka JMX만 유일하게 JVM 시작 옵션을 수정해야 하지만, 이것도 한 줄 추가에 불과합니다.
HyperDX(ClickStack)로 시각화
데이터가 ClickHouse Cloud에 들어오면, HyperDX를 연결해서 통합 UI로 조회할 수 있습니다. HyperDX는 OpenTelemetry 네이티브로 설계되어 있어, OTel 표준 스키마를 사용하면 별도 매핑 설정 없이 자동으로 로그, 메트릭, 트레이스를 인식합니다.
ClickStack(ClickHouse + HyperDX + OTel Collector 번들) 방식으로 배포할 수도 있고, 이미 운영 중인 ClickHouse Cloud 인스턴스에 HyperDX만 연결할 수도 있습니다.
주요 기능은 다음과 같습니다:
- Lucene 스타일 풀텍스트 검색으로 로그 탐색
- SQL 기반 메트릭 쿼리 및 대시보드 구성
- 로그-트레이스-메트릭 간 자동 상관관계(correlation) 분석
- Slack, Email, PagerDuty 알림 연동
마치며
OTel Collector + ClickHouse Cloud 조합의 가장 큰 장점은 관심사의 분리입니다. 데이터 수집은 OTel Collector가, 저장과 분석은 ClickHouse가, 시각화는 HyperDX가 담당합니다. 새로운 데이터 소스를 추가하고 싶다면 Collector 설정 파일에 receiver를 하나 추가하면 끝입니다. Exporter와 백엔드는 그대로입니다.
소스 시스템을 건드리지 않고도, 설정 파일 하나로 엔터프라이즈급 통합 모니터링을 구성할 수 있다는 것. 이것이 OpenTelemetry와 ClickHouse Cloud가 함께 만들어내는 가치입니다.
이 글에서 사용된 설정 예시와 아키텍처 다이어그램은 ClickHouse 공식 OTel 문서와 OTel Collector Contrib 저장소를 기반으로 작성되었습니다.