[Elasticsearch] ELK쿼리로 API 호출 건수 집계해보기 (+Kibana Dev tools aggs field)
Why
API 호출 추이를 Whatap 필터링으로도 확인 가능하나,
특정 조건을 걸거나, 집계를 하고싶어서
ELK 쿼리로 직접 작성해보았다.
https://www.whatap.io/
SaaS 모니터링 No.1 와탭 모니터링 | 와탭 | WhaTap
와탭으로 IT 서비스를 완성하세요. 클라우드 최적화. 15일간 무료 사용. 쉽고 빠른 설치. 특허로 인정받은 분석력. 통합 모니터링. 실시간 모니터링. 마이크로 아키텍처. 유연하고 안정적인 확장
whatap.io
내가 원했던 쿼리는
1. 메뉴 검색 API 관련, 호출 건수 집계
2. 시나리오 구분
2.1 검색바에서 Enter 치는 경우 : "/api/common/v1/search-menu-list?*"
2.2 검색바에서 입력값 변경되는 경우(interval로 작동) : "/api/common/v1/search-menu-list-by-typing?*"
3. 날짜 범위 설정
4. 실행 환경 구분 : prd, stage, dev, local
5. 주기별 집계 (일별/주별/월별/년별)
/* API 호출건수 조회 쿼리 (url별 환경별 날짜별) */
GET api-log-index/_search
{
"size" : 0,
"query": {
"bool": {
"should": [
{
"wildcard": {
"request_uri": "/api/common/v1/search-menu-list-by-typing?*"
}
},
{
"wildcard": {
"request_uri": "/api/common/v1/search-menu-list?*"
}
}
]
}
},
"aggs": {
"custom_field_1_timestamp": {
"date_range": {
"field": "@timestamp",
"format":"yyyy-MM-dd-HH:mm:ss",
"time_zone":"+09:00",
"ranges": [
{
"from": "2024-09-01-00:00:00",
"to": "2025-10-17-00:00:00"
}
]
},
"aggs": {
"custom_field_2_uri": {
"terms": {
"script": {
"source": "def uri = doc['request_uri'].value; if (uri.startsWith('/api/common/v1/search-menu-list-by-typing?')){ return 'typing'; } else { return 'enter';}"
},
"min_doc_count": 1
},
"aggs": {
"custom_field_3_env": {
"terms": {
"field": "fields.env"
},
"aggs": {
"custom_field_4_day_count": {
"date_histogram": {
"field": "@timestamp",
"calendar_interval": "day"
}
},
"custom_field_5_week_count": {
"date_histogram": {
"field": "@timestamp",
"calendar_interval": "week"
}
},
"custom_field_6_month_count": {
"date_histogram": {
"field": "@timestamp",
"calendar_interval": "month"
}
},
"custom_field_7_year_count": {
"date_histogram": {
"field": "@timestamp",
"calendar_interval": "year"
}
}
}
}
}
}
}
}
}
}
결과 분석
- 24년9월1일부터 ~ 24년10월17일 오늘까지
- 총 19055번의 메뉴API가 호출되었고
- 그중 타이핑이 약 1만번, 타이핑 후 엔터동작이 약 9천번 발생. (천번정도는 타이핑 후 enter를 치지 않았다는 뜻)
- 24년10월15일날 오후늦게 API url을 수정했기 때문에, day_count가 15일부터 시작.
/* 결과 */
{
"took": 54,
"timed_out": false,
"_shards": {
"total": 6,
"successful": 6,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 10000,
"relation": "gte"
},
"max_score": null,
"hits": []
},
"aggregations": {
"custom_field_1_timestamp": {
"buckets": [
{
"key": "2024-09-01-00:00:00-2025-10-17-00:00:00",
"from": 1725116400000,
"from_as_string": "2024-09-01-00:00:00",
"to": 1760626800000,
"to_as_string": "2025-10-17-00:00:00",
"doc_count": 19055,
"custom_field_2_uri": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "typing",
"doc_count": 10036,
"custom_field_3_env": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "prd",
"doc_count": 10036,
"custom_field_5_week_count": {
"buckets": [
{
"key_as_string": "2024-10-14T00:00:00.000Z",
"key": 1728864000000,
"doc_count": 10036
}
]
},
"custom_field_6_month_count": {
"buckets": [
{
"key_as_string": "2024-10-01T00:00:00.000Z",
"key": 1727740800000,
"doc_count": 10036
}
]
},
"custom_field_4_day_count": {
"buckets": [
{
"key_as_string": "2024-10-15T00:00:00.000Z",
"key": 1728950400000,
"doc_count": 170
},
{
"key_as_string": "2024-10-16T00:00:00.000Z",
"key": 1729036800000,
"doc_count": 8568
},
{
"key_as_string": "2024-10-17T00:00:00.000Z",
"key": 1729123200000,
"doc_count": 1298
}
]
},
"custom_field_7_year_count": {
"buckets": [
{
"key_as_string": "2024-01-01T00:00:00.000Z",
"key": 1704067200000,
"doc_count": 10036
}
]
}
}
]
}
},
{
"key": "enter",
"doc_count": 9019,
"custom_field_3_env": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "prd",
"doc_count": 9019,
"custom_field_5_week_count": {
"buckets": [
{
"key_as_string": "2024-10-14T00:00:00.000Z",
"key": 1728864000000,
"doc_count": 9019
}
]
},
"custom_field_6_month_count": {
"buckets": [
{
"key_as_string": "2024-10-01T00:00:00.000Z",
"key": 1727740800000,
"doc_count": 9019
}
]
},
"custom_field_4_day_count": {
"buckets": [
{
"key_as_string": "2024-10-15T00:00:00.000Z",
"key": 1728950400000,
"doc_count": 136
},
{
"key_as_string": "2024-10-16T00:00:00.000Z",
"key": 1729036800000,
"doc_count": 7763
},
{
"key_as_string": "2024-10-17T00:00:00.000Z",
"key": 1729123200000,
"doc_count": 1120
}
]
},
"custom_field_7_year_count": {
"buckets": [
{
"key_as_string": "2024-01-01T00:00:00.000Z",
"key": 1704067200000,
"doc_count": 9019
}
]
}
}
]
}
}
]
}
}
]
}
}
}
고도화 포인트
API url을 기준으로
호출 시간대나, 호출 건수, 딥하게는 파라미터까지 분석이 가능하고
이를 활용할 수도 있을 것 같다.
예를들면 다음과 같다.
- 갑작스럽게 호출 건수 급증 => 대용량 트래픽 감지
- 관리 목록에 없는 url 포함 => 비정상접근 알림 발송
- 특정 호출건 추적
- 특정 시간대 건수 알림 => 정기적 모니터링 수행
ex.
(트래픽 집중 시간대에만) 짧은 집계 주기 적용 (초/분/시 단위) => 1초에 1000건 이상 api 호출되는 경우 => 카카오톡,SMS,팀즈 등 Alert 발송
+ 날짜 동적 필터링
ex. 어제 23시59분59초까지의 데이터만 필터
GET api-log-index/_search
{
"size": 0,
"query": {
// 비즈니스 로직
},
"aggs": {
"custom_field_1_timestamp": {
"date_range": {
"field": "@timestamp",
"format": "yyyy-MM-dd-HH:mm:ss",
"time_zone": "+09:00",
"ranges": [
{
"from": "1970-01-01-00:00:00", // 대과거
"to": "now-1d/d+23h+59m+59s" // 어제 23시 59분 59초
}
]
}
}
}
}
'IT > Elasticsearch' 카테고리의 다른 글
[Elasticsearch] ELK Query Count Filter (aggs Field) (0) | 2024.07.31 |
---|---|
[Elasticsearch] 쿠버네티스 워커노드 CPU 100% 장애 복기 (8) | 2024.07.24 |
[Elasticsearch] Elastic Contributor Program 이란? (0) | 2024.07.10 |
[Elasticsearch] ILM - Cluster 성능 개선 (0) | 2024.07.10 |
[Elasticsearch] 백엔드 장애 감지 알림 시스템 구축 (ELK 기반 준실시간 서버 로그 모니터링) (0) | 2024.07.06 |