전체 행 인덱스¶
전체 행 인덱스란?¶
전체 행 인덱스는 로그 전문 검색 방식 중 하나입니다. 활성화하면 시스템이 로그의 모든 비즈니스 필드를 전문 인덱스에 포함합니다. 쿼리 시 필드 이름을 미리 지정할 필요 없이 임의의 비즈니스 필드 값을 입력하면 해당 값이 포함된 로그를 검색할 수 있습니다.
예를 들어, 다음 필드를 포함하는 로그가 있다고 가정합니다.
전체 행 인덱스를 활성화하면 8d4f2a, O-1001, 128.5를 직접 검색해도 이 로그를 찾을 수 있습니다.
전체 행 인덱스는 다음 사용 사례에 적합합니다.
- 로그가 이미 여러 구조화된 필드로 추출되어 더 이상
message한 덩어리에 의존하지 않는 경우 trace_id, 주문 번호, 사용자 ID 등 다양한 비즈니스 필드에서 빠르게 검색해야 하는 경우- 같은 로그 인덱스에 여러 로그 구조가 섞여 있어 모든 로그에 공통된 검색 필드를 미리 정할 수 없는 경우
- 필드 기반 쿼리 기능을 유지하면서도 비즈니스 필드 전반의 전문 검색을 지원하려는 경우
message 전용 인덱스와의 차이점¶
| 비교 항목 | message 전용 인덱스 |
전체 행 인덱스 |
|---|---|---|
| 전문 검색 범위 | message 필드만 |
존재하는 message를 포함한 모든 비즈니스 필드 |
| 원본 로그 보존 여부 | message 보존 필요 |
필수 아님. 보존할 수도 있고, 필드 추출 후 삭제할 수도 있음 |
| 적합한 데이터 | 일반 텍스트 로그, 비구조화 로그 | JSON 로그, Pipeline으로 추출한 구조화 로그 |
| 전문 인덱스 필드 | message |
variant |
전체 행 인덱스는 전문 검색 범위만 변경할 뿐 필드 필터링을 대체하지 않습니다. 이미 추출된 필드에 대해서는 계속 service:order-api 등의 필드 조건으로 정밀 필터링, 집계, 분석을 수행할 수 있습니다.
동작 방식¶
시스템은 variant를 통해 전체 행 인덱스의 비즈니스 필드를 통합 저장하고 variant에 대해서만 전문 인덱스를 생성합니다.
구체적인 규칙은 다음과 같습니다.
- 전체 행 인덱스는 로그의 비즈니스 필드를 포함하며 시스템 필드는 포함하지 않습니다.
- 로그에
message가 없는 경우에도 다른 비즈니스 필드는 전문 검색에 참여할 수 있습니다. - 로그에
message가 있으면 시스템은 해당 필드를 삭제하지 않고 일반 비즈니스 필드로variant에 기록합니다. - 시스템은
message와variant에 대해 두 개의 전문 인덱스를 동시에 생성하지 않습니다. - 같은 로그 인덱스에
message가 있는 로그와 없는 로그를 함께 저장할 수 있습니다.
message 존재 여부는 로그 원본 내용과 DataKit, Pipeline의 실제 처리 결과에 따라 결정됩니다. 전체 행 인덱스를 활성화해도 message를 반드시 삭제할 필요는 없습니다.
전체 행 인덱스 사용 또는 전환¶
새 로그 인덱스를 생성할 때 시스템은 기본적으로 전체 행 인덱스를 사용하므로 별도로 활성화할 필요가 없습니다.
여전히 message 전용 인덱스 필드를 사용하는 기존 로그 인덱스는 다음 작업을 수행할 수 있습니다.
- 로그 > 인덱스로 이동합니다.
- 대상 로그 인덱스를 편집합니다.
- 고급 옵션을 펼칩니다.
- 전문 인덱스 필드에서 전체 행 인덱스를 선택합니다.
- 영향 범위를 확인한 후 구성을 저장합니다.
주의
message 전용 인덱스에서 전체 행 인덱스로의 전환은 단방향 작업입니다. 저장 후에는 message 전용 인덱스로 되돌릴 수 없으므로 작업 전 관련 쿼리 및 데이터 사용 방식을 확인하시기 바랍니다.
전제 조건
현재 워크스페이스에서 전체 행 인덱스를 지원해야 합니다. 페이지에 이 옵션이 표시되지 않으면 워크스페이스 버전 및 관련 기능 권한을 확인하세요.
전체 행 인덱스 쿼리¶
구성을 완료하고 로그를 기록한 후 로그 > 탐색기로 이동하여 해당 로그 인덱스를 선택합니다.
탐색기에서는 텍스트 검색, 필드 필터링, 조합 검색, JSON 검색, DQL 쿼리 등의 방식을 지원합니다. 전체 검색 문법 및 사용 방법은 탐색기 검색을 참조하세요.
전문 검색¶
검색창에 비즈니스 필드 값을 입력하면 필드 이름을 지정하지 않고도 모든 비즈니스 필드에서 검색할 수 있습니다.
위의 주문 로그를 예로 들면 다음과 같습니다.
O-1001을 입력하면order_id와 일치합니다.8d4f2a를 입력하면trace_id와 일치합니다.order-api를 입력하면service와 일치합니다.message가 보존된 로그에서는message의 내용도 검색할 수 있습니다.
텍스트 검색은 입력 내용을 토큰화합니다. 완전하고 연속된 내용을 일치시키려면 영문 반각 큰따옴표로 검색어를 감싸면 됩니다. 자세한 내용은 텍스트 검색을 참조하세요.
필드 필터링¶
필드 이름을 이미 알고 있다면 필드 조건으로 쿼리 범위를 좁힐 수 있습니다. 예를 들어:
전문 검색은 '내용이 어느 필드에 있는지 확실하지 않은' 상황에 적합합니다. 필드 필터링은 필드 이름을 알고 있고 정밀 필터링이나 집계 분석이 필요한 상황에 적합합니다. 둘을 함께 사용할 수 있습니다. 필드 필터링의 전체 문법은 필터링을 참조하세요.
쿼리 유의 사항¶
- 전체 행 전문 검색은 시스템 필드가 아닌 비즈니스 필드만 일치합니다.
- 로그에
message가 없으면 탐색기가 현재 로그의 비즈니스 필드를 조합하여 로그 내용을 표시합니다. - 시스템 필드는 전체 행 인덱스에서 로그 내용의 일부로 포함되지 않습니다.
- 비즈니스 필드가 아직 원본 로그에서 추출되지 않은 경우 전체 행 인덱스는 현재 실제로 존재하는 필드만 검색할 수 있습니다. 따라서 JSON 또는 일반 텍스트 로그라면 아래 방법으로 필요한 필드를 먼저 추출할 수 있습니다.
로그 필드 추출¶
전체 행 인덱스는 로그에 이미 존재하는 비즈니스 필드를 인덱스 대상에 포함하지만 message의 내용을 자동으로 이해하거나 분리하지는 않습니다. 원본 로그가 여전히 JSON 또는 일반 텍스트 한 덩어리라면 DataKit 또는 Pipeline을 사용하여 내용을 구조화된 필드로 추출할 수 있습니다.
필드 추출을 완료한 후 원본 message의 보존 여부는 실제 요구 사항에 따라 결정됩니다.
- 전체 원문을 확인해야 하거나 기존 사용 방식과의 호환이 필요한 경우
message를 보존할 수 있습니다. - 이미 충분한 구조화 필드가 있고 더 이상 원문을 저장할 필요가 없는 경우
message를 삭제할 수 있습니다. message보존 여부와 관계없이 추출된 비즈니스 필드는 모두 전체 행 전문 인덱스에 참여할 수 있습니다.
DataKit으로 JSON 필드 추출¶
각 행이 표준 JSON 객체이고 모든 최상위 필드를 직접 추출하려는 로그에 적합합니다. DataKit 2.9.0 이상 버전에서 json_as_fields를 활성화할 수 있습니다.
활성화하면 DataKit은 문자 디코딩, ANSI 정리, 멀티라인 병합 후 JSON 루트 객체의 최상위 속성을 로그 필드로 변환한 다음 Pipeline을 실행합니다.
호스트 로그 수집¶
logging.conf를 편집합니다.
[[inputs.logging]]
logfiles = ["/var/log/order/*.json"]
source = "order"
service = "order-api"
json_as_fields = true
구성을 저장한 후 DataKit 재시작을 수행합니다.
Kubernetes 컨테이너 로그 수집¶
Pod Annotation을 통해 지정 컨테이너의 JSON 필드 모드를 활성화할 수 있습니다.
metadata:
annotations:
datakit/order-api.logs: >-
[{"source":"order","service":"order-api","json_as_fields":true}]
여기서 order-api는 컨테이너 이름입니다. 컨테이너 환경 변수 DATAKIT_LOGS_CONFIG에서도 동일한 JSON 구성을 사용할 수 있습니다.
컨테이너 구성 제한
json_as_fields는 현재 컨테이너 환경 변수 및 Pod Annotation/Label의 JSON 로그 구성만 지원하며 ClusterLoggingConfig CRD는 아직 지원하지 않습니다.
Log Streaming¶
logstreaming.conf에서 활성화합니다.
json_as_fields는 수집기 구성이지 HTTP URL 파라미터가 아닙니다. 이 구성은 influxdb, firelens, firehose 유형에는 적용되지 않습니다.
추출 결과¶
원본 로그:
{"timestamp":"2026-08-18T10:00:00+08:00","level":"INFO","service":"order-api","trace_id":"8d4f2a","order_id":"O-1001","amount":128.5,"labels":{"channel":"web"}}
변환에 성공하면:
timestamp,level,service,trace_id,order_id,amount는 개별 필드가 됩니다.labels객체는 컴팩트 JSON 문자열로 저장됩니다.- DataKit은 원본 JSON 전체를 저장하는 추가
message를 더 이상 생성하지 않습니다. - 원본 JSON에
message가 포함되어 있으면 해당 필드는 정상적으로 유지됩니다.
주요 필드 변환 규칙은 다음과 같습니다.
- 최상위 문자열, 불리언, 정수, 소수는 타입이 유지됩니다. 객체와 배열은 컴팩트 JSON 문자열로 저장되고
null은 무시됩니다. - 잘못된 JSON이거나 루트 노드가 객체가 아니거나 유효한 필드가 없는 경우 원본
message로 폴백됩니다. - 필드 이름의
.는_로 변환되고, 줄바꿈 문자는 공백으로 변환되며, 필드 이름은 최대 256바이트입니다. - tag를 제외하고 로그당 최대 1024개의 field가 유지됩니다.
- JSON 필드는 수집기의 동일한 이름의 tag 또는 field를 덮어씁니다.
- JSON의
time,source,date,storage_index는 각각json_time,json_source,json_date,json_storage_index로 이름이 변경됩니다.
전체 규칙은 JSON 필드 모드를 참조하세요.
Pipeline으로 필드 추출¶
다음과 같은 경우에 적합합니다.
- 일부 필드만 추출해야 하는 경우
- 필드 이름을 변경하거나 변환해야 하는 경우
- 로그가 표준 JSON이 아닌 경우
- 기존 Pipeline 정제 프로세스를 계속 사용해야 하는 경우
모든 최상위 스칼라 필드 추출¶
DataKit 2.2.0 이상 버전에서 json_all()을 사용할 수 있습니다.
# 원본 데이터:
# {"service":"order-api","status":"info","trace_id":"8d4f2a","order_id":"O-1001","amount":128.5}
json_all(_, key_patterns=["*"])
처리 후 service, status, trace_id, order_id, amount 등 개별 필드가 생성됩니다.
json_all()은 최상위 문자열, 숫자, 불리언만 추출하며 객체나 배열은 재귀적으로 펼치지 않고 null도 저장하지 않습니다. include_keys와 key_patterns가 모두 구성되지 않으면 어떤 필드도 추출하지 않습니다. 모든 최상위 스칼라 필드를 추출하려면 key_patterns=["*"]를 명시적으로 설정해야 합니다.
지정 필드만 추출¶
이 방식은 전체 행 인덱스에 포함되는 필드 범위를 제어할 수 있고, 서로 다른 로그의 필드를 동일한 이름으로 통일할 수도 있습니다.
객체나 배열은 json_all()로 추출되지 않습니다. 이러한 내용을 유지해야 한다면 json()으로 필드를 지정해 추출할 수 있으며, 추출 결과는 JSON 문자열로 저장됩니다.
필드 추출 후 message 삭제¶
Pipeline으로 필드를 추출해도 원본 로그는 기본적으로 message에 계속 저장됩니다. 구조화된 필드가 이미 표시 및 쿼리 요구를 충족할 수 있다면 필드 추출을 완료한 후 drop_origin_data()를 호출해 원본 내용을 저장하지 않을 수 있습니다.
지정 필드를 추출한 뒤에도 삭제할 수 있습니다.
json(_, service)
json(_, level, status)
json(_, trace_id)
json(_, order_id)
json(_, amount)
drop_origin_data()
JSON에 message가 포함되어 있고 해당 필드도 추출된 경우 필요에 따라 보존하거나 삭제할 수 있습니다. 명확히 필요하지 않을 때는 다음을 사용합니다.
세 함수의 역할은 서로 다릅니다.
drop_origin_data(): 초기화 시 저장된 원본 텍스트를 더 이상 출력하지 않습니다. 로그 전체는 계속 업로드됩니다.drop_key(message): 이미 추출된message필드를 삭제합니다.drop(): 로그 전체를 버립니다. 로그는 업로드되지 않으며message삭제에는 사용할 수 없습니다.
drop()으로 message를 삭제하지 마세요
drop()은 현재 로그를 삭제 대상으로 표시합니다. Pipeline 실행이 끝나면 로그 전체가 업로드되지 않습니다.
더 자세한 문법은 json(), json_all(), drop_origin_data() 및 drop_key()을 참조하세요.
Pipeline 로컬 검증¶
Pipeline 스크립트를 저장한 후 DataKit이 설치된 호스트에서 다음을 실행할 수 있습니다.
datakit pipeline -P full_line_json.p \
-T '{"service":"order-api","status":"info","trace_id":"8d4f2a","order_id":"O-1001","amount":128.5}'
출력이 다음 기대 사항에 부합하는지 확인합니다.
- 검색에 필요한 필드가 모두 추출되었습니다.
drop_origin_data()를 구성한 경우 원본message가 삭제되었습니다.- 로그가
drop: true로 표시되지 않았습니다. status및 로그 시간 등 필드가 비즈니스 기대 사항에 부합합니다.
자주 묻는 질문¶
전체 행 인덱스에서 message를 반드시 삭제해야 하나요?¶
아닙니다. message가 있으면 시스템은 이를 일반 비즈니스 필드로 variant에 기록하며 message를 위한 별도의 전문 인덱스를 생성하지 않습니다. message 삭제 여부는 원본 내용 보존 및 표시 요구 사항에 따라 결정해야 합니다.
전체 행 인덱스를 활성화해도 message 안의 JSON 필드가 검색되지 않는 이유는 무엇인가요?¶
JSON 전체가 여전히 message의 문자열 내용일 뿐이라면 그 안의 속성은 독립적인 비즈니스 필드가 아닙니다. message의 텍스트를 검색할 수는 있지만 이러한 속성을 필드 필터링이나 집계에 직접 사용할 수는 없습니다. DataKit 또는 Pipeline으로 필요한 필드를 먼저 추출하는 것을 권장합니다.
message가 없을 때 로그 탐색기는 내용을 어떻게 표시하나요?¶
로그에 message가 없으면 로그 탐색기가 현재 로그의 비즈니스 필드를 조합하여 로그 내용을 표시합니다. 시스템 필드는 로그 내용의 일부로 포함되지 않습니다.
같은 인덱스에 message가 있는 로그와 없는 로그를 동시에 저장할 수 있나요?¶
가능합니다. 두 유형의 로그 모두 동일한 규칙으로 비즈니스 필드를 variant에 기록하며, variant가 전문 인덱스에 참여합니다.
전체 행 인덱스로 시스템 필드를 검색할 수 있나요?¶
아닙니다. 전체 행 인덱스는 비즈니스 필드만 포함하며 시스템 필드는 포함하지 않습니다. 시스템 필드는 필드 필터링 등을 통해 계속 조회할 수 있습니다.
전체 행 인덱스로 전환한 후 message 인덱스로 복원할 수 있나요?¶
아닙니다. message 전용 인덱스에서 전체 행 인덱스로의 전환은 단방향 작업이므로 저장 후에는 복원할 수 없습니다. 기존 message 인덱스는 전환하지 않으면 기존 방식 그대로 계속 사용할 수 있습니다.