MULTISEARCH 명령어
MULTISEARCH 명령어
multisearch 명령어는 여러 서브서치를 실행하고 그 결과를 병합해요. 시간 기반 데이터 작업 시 타임스탬프 기반 결과 인터리빙을 지원해요.
출처: 문서
본문
multisearch 명령어는 여러 서브서치를 실행하고 그 결과를 병합해요. 동일하거나 다른 소스에 대한 다양한 쿼리의 데이터를 결합할 수 있어요. 결합된 결과에 집계나 정렬 같은 후속 처리를 선택적으로 적용할 수 있어요. 각 서브서치는 서로 다른 필터링 기준, 데이터 변환, 필드 선택을 가질 수 있어요.
multisearch 명령어는 비교 분석, 합집합(union) 작업, 여러 검색 기준에서 종합적인 데이터셋을 만들 때 특히 유용해요. 이 명령어는 시계열 데이터 작업 시 타임스탬프 기반 결과 인터리빙을 지원해요.
다음과 같은 경우 multisearch를 사용해요:
구문 (Syntax)
multisearch 명령어의 구문은 다음과 같아요:
multisearch <subsearch1> <subsearch2> [<subsearch3> ...]
다음은 multisearch 명령어 구문의 예시예요:
| multisearch [search source=table | where condition1] [search source=table | where condition2]
| multisearch [search source=index1 | fields field1, field2] [search source=index2 | fields field1, field2]
| multisearch [search source=table | where status="success"] [search source=table | where status="error"]
매개변수 (Parameters)
multisearch 명령어는 다음 매개변수를 지원해요.
| 매개변수 | 필수/선택 | 설명 |
|---|---|---|
<subsearchN> |
필수 | 최소 두 개의 서브서치가 필요해요. 각 서브서치는 대괄호로 묶고 search 키워드로 시작해야 해요 (`[search source=index |
<result-processing> |
선택 | multisearch 작업 후 병합된 결과에 적용되는 명령어예요 (예: stats, sort, head). |
예제 1: 오류를 디버그 로그와 비교하기
이 예제는 오류 로그와 디버그 로그를 나란히 병합해요. 같은 서비스의 디버그 수준 로그가 오류의 근본 원인에 대한 단서를 제공하는지 조사할 때 유용해요:
| multisearch [search source=otellogs
| where severityText = 'ERROR'
| eval env = 'errors'
| fields env, `resource.attributes.service.name`, body] [search source=otellogs
| where severityText = 'DEBUG'
| eval env = 'debug'
| fields env, `resource.attributes.service.name`, body]
| sort env, `resource.attributes.service.name`
쿼리는 다음과 같은 결과를 반환해요:
| env | resource.attributes.service.name | body |
|---|---|---|
| debug | cart | Cache miss for key user:session:U200 in Valkey cluster |
| debug | cart | Valkey SETEX user:session:U300 3600 - session refreshed |
| debug | product-catalog | gRPC call /ProductCatalogService/GetProduct completed in 12ms |
| errors | checkout | NullPointerException in CheckoutService.placeOrder at line 142 |
| errors | checkout | Kafka producer delivery failed: message too large for topic order-events (max 1048576 bytes) |
| errors | frontend-proxy | [2024-02-01T09:20:00.456Z] “POST /api/checkout HTTP/1.1” 503 - 0 30000 checkout-8d4f7b-mk2p9 |
| errors | payment | Payment failed: connection timeout to payment gateway after 30000ms |
| errors | payment | Out of memory: Java heap space - shutting down pod payment-6f8d4b-ht7q3 |
| errors | product-catalog | Database primary node unreachable: connection refused to db-primary-01:5432 |
| errors | recommendation | Failed to process recommendation request: invalid product ID from 203.0.113.50 |
예제 2: severity 계층별로 로그 구분하기
이 예제는 비교 분석을 위해 중요(critical) 로그와 중요하지 않은 로그를 분리해요:
| multisearch [search source=otellogs
| where severityNumber >= 17
| eval tier = "critical"
| fields severityText, severityNumber, tier] [search source=otellogs
| where severityNumber < 17 AND severityNumber >= 13
| eval tier = "warning"
| fields severityText, severityNumber, tier]
| sort - severityNumber
쿼리는 다음과 같은 결과를 반환해요:
| severityText | severityNumber | tier |
|---|---|---|
| ERROR | 17 | critical |
| ERROR | 17 | critical |
| ERROR | 17 | critical |
| ERROR | 17 | critical |
| ERROR | 17 | critical |
| ERROR | 17 | critical |
| ERROR | 17 | critical |
| WARN | 13 | warning |
| WARN | 13 | warning |
| WARN | 13 | warning |
| WARN | 13 | warning |
예제 3: 여러 소스의 시계열 데이터 병합하기
이 예제는 시간순을 유지하면서 서로 다른 소스의 시계열 데이터를 결합하는 방법을 보여줘요. 결과는 통합 타임라인을 만들기 위해 타임스탬프 기준으로 자동 정렬돼요:
| multisearch [search source=time_data
| where category IN ("A", "B")] [search source=time_data2
| where category IN ("E", "F")]
| fields @timestamp, category, value, timestamp
| head 5
쿼리는 다음과 같은 결과를 반환해요:
| @timestamp | category | value | timestamp |
|---|---|---|---|
| 2025-08-01 04:00:00 | E | 2001 | 2025-08-01 04:00:00 |
| 2025-08-01 03:47:41 | A | 8762 | 2025-08-01 03:47:41 |
| 2025-08-01 02:30:00 | F | 2002 | 2025-08-01 02:30:00 |
| 2025-08-01 01:14:11 | B | 9015 | 2025-08-01 01:14:11 |
| 2025-08-01 01:00:00 | E | 2003 | 2025-08-01 01:00:00 |
예제 4: 서브서치 간 누락된 필드 처리하기
이 예제는 서브서치가 서로 다른 필드를 반환할 때 multisearch가 스키마 차이를 처리하는 방법을 보여줘요. 한 서브서치에 다른 서브서치가 갖지 못한 필드가 포함되면 누락된 값은 자동으로 null 값으로 채워져요:
| multisearch [search source=otellogs
| where severityText = 'ERROR'
| eval needs_page = "yes"
| fields severityText, `resource.attributes.service.name`, needs_page] [search source=otellogs
| where severityText = 'WARN'
| fields severityText, `resource.attributes.service.name`]
| sort `resource.attributes.service.name`
| head 5
쿼리는 다음과 같은 결과를 반환해요:
| severityText | resource.attributes.service.name | needs_page |
|---|---|---|
| ERROR | checkout | yes |
| ERROR | checkout | yes |
| ERROR | frontend-proxy | yes |
| WARN | frontend-proxy | null |
| WARN | frontend-proxy | null |
제한 사항 (Limitations)
multisearch 명령어는 다음과 같은 제한 사항이 있어요:
- 최소 두 개의 서브서치를 지정해야 해요.
- 서브서치에 같은 이름의 필드가 존재하지만 호환되지 않는 타입을 가질 때, 시스템은 충돌하는 필드 이름을 바꿔 충돌을 자동으로 해결해요. 첫 번째 항목은 원래 이름을 유지하고, 이후 충돌하는 필드는 숫자 접미사를 사용해 이름이 바뀌어요 (예:
age는age0,age1등이 됨). 이렇게 하면 스키마 일관성을 유지하면서 모든 데이터가 보존돼요.