커스텀 · 처음 보는 로그 형식
애플리케이션 로그는 표준을 거의 따르지 않습니다. 그래도 보드는 한 줄에서 어디가 시각이고, 어디가 상태나 수준이고, 어디가 걸린 시간인지 알아야 합니다. 이 페이지는 그것을 어떻게 알아내는지, 짐작이 틀렸을 때 어떻게 고치는지 설명합니다.
모든 일은 브라우저 안에서 일어납니다. 저장한 형식은 「레시피」이며 해석 규칙만 담고 로그 줄은 담지 않습니다.
설정 없이 읽는 로그
알려진 형식(nginx · Apache · HAProxy)은 첫 줄들을 보고 알아봅니다. 일반적인 모양 두 가지도 바로 읽습니다.
{"ts":"2026-10-18T10:02:03Z","level":"error","route":"/api/upload","status":504,"duration_ms":60001}ts=2026-10-18T10:02:03Z level=error method=POST path=/api/upload status=504 duration_ms=60001JSON 줄과 key=value 로그에서는 키마다 칸이 됩니다(JSON 은 한 단계 아래 키도 a.b 로). 흔한 키 이름은 역할을 정합니다. time · ts · @timestamp → 시각, status · status_code → 상태, level · severity → 수준, path · url · route → 경로, duration · duration_ms · latency · request_time → 지연, msg · message → 메시지입니다. 나머지 키는 값을 보고 시각 · 숫자 · 범주로 나눕니다.
형식 탭: 나누고, 이름 붙이기
그 밖의 로그는 형식 탭을 엽니다. 이런 자바식 줄을 예로 듭니다.
2026-10-18T10:02:03.120Z ERROR [http-nio-8080-exec-7] c.e.UploadController - upload failed: timeout after 60000 ms- 첫 줄들을 공백, 따옴표, 대괄호,
key=value쌍, JSON 으로 칸을 나눕니다. 나눈 결과는 첫 줄 위의 색 띠로 보입니다. - 칸마다 종류를 짐작합니다. ISO 8601 · epoch · syslog 시각, IP 주소, HTTP 상태, 걸린 시간(
123ms·0.412·1.2s), 수준, 숫자, 경로, 글. - 칸을 눌러 역할을 정하거나 바꿉니다. 시각, 상태, 경로, 지연, 수준, 사용자, 값, 무시.
- 적용합니다. 카드는 역할을 따릅니다. 시각 칸은 시간축과 열지도, 상태나 수준은 오류율, 숫자는 분포와 분위수, 범주는 상위 목록, 자유 글은 숫자와 ID 를 가린 메시지 모양으로 묶입니다.
- 레시피로 저장하면 같은 종류의 다음 파일도 같은 방식으로 읽습니다.
예시에서는 시각, 수준 ERROR, 대괄호 안 스레드, 로거 이름, 메시지가 각각 칸으로 잡힙니다. 대개 수준 칸에 「수준」을 표시하는 한 번이면 됩니다.
형식 정의 붙여 넣기
로그를 만든 설정 줄이 있다면 그것이 배치를 정확히 말해 줍니다. 형식 탭의 「형식 정의 붙여 넣기」에 그 줄을 넣고 적용하십시오.
# nginx
log_format timed '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_time';
# Apache
LogFormat "%h %l %u %t \"%r\" %>s %b %D" timed
# HAProxy
log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %tsc"변수가 곧 역할입니다. $request_time · %D · %Ta 는 지연(각각 초, 마이크로초, 밀리초), $status · %>s · %ST 는 상태, $time_local · %t · %tr 은 시각입니다. 가상 호스트, 요청 ID, 업스트림 주소처럼 가운데에 칸을 더 넣은 형식도 이름 붙이기 없이 읽습니다.
이름 붙은 그룹을 쓴 정규식
칸 나누기로 안 되는 배치는 형식 탭에 이름 붙은 그룹을 쓴 정규식을 넣으십시오. 그룹 이름이 칸 이름이 되고, 역할 이름과 같으면 역할도 됩니다.
^(?<time>\S+) (?<level>[A-Z]+) \[(?<thread>[^\]]+)\] (?<logger>\S+) - (?<message>.*)$time · status · level · path · latency 같은 그룹 이름은 그 역할을 자동으로 받고, 다른 이름은 보통 칸이 됩니다.
레시피: 로컬에 저장, 파일로 공유
- 레시피에는 나누는 규칙, 칸 이름, 역할이 들어 있고 로그 줄은 들어 있지 않습니다.
- 레시피는 이 브라우저의 로컬 저장소에 저장됩니다. 기기 밖으로 나가지 않고 계정에 묶이지도 않습니다(계정이 없습니다).
- 레시피를 작은 JSON 파일로 내보내 동료에게 보내면, 동료는 형식 탭에서 가져옵니다. 페이지가 직접 올리는 일은 없습니다.
- 링크로 공유할 수도 있습니다. 레시피는 압축되어 주소의
#뒤에 실리고,#뒤는 브라우저가 서버로 보내지 않습니다. 링크를 열면 요청 없이 그 브라우저에 레시피가 더해집니다. - 저장한 레시피는 놓은 파일이 그 모양과 맞으면(같은 나누기, 같은 칸 수, 시각 칸이 해석됨) 저절로 적용됩니다.
- 브라우저에서 사이트 데이터를 지우면 저장한 레시피도 지워집니다. 중요한 레시피는 내보낸 파일을 보관하십시오.
key=value · JSON 줄용 한 줄 명령
서버에 jq 가 없을 때도 구조화된 줄은 grep 과 cut 으로 꽤 많이 볼 수 있습니다. 작은 key=value · JSON 줄 표본으로 확인했습니다.
key=value: 상태별 건수
grep -oE 'status=[0-9]+' app.log | sort | uniq -c | sort -rnkey=value: duration_ms 로 본 가장 느린 요청 3개
awk '{delete f; for (i = 1; i <= NF; i++) {split($i, kv, "="); f[kv[1]] = kv[2]} print f["duration_ms"], f["path"]}' app.log | sort -rn | head -3JSON 줄: 수준별 건수
grep -oE '"level":"[a-z]+"' app.jsonl | sort | uniq -c | sort -rnJSON 줄: route 값별 건수
grep -oE '"route":"[^"]*"' app.jsonl | cut -d'"' -f4 | sort | uniq -c | sort -rn
키와 값이 한 줄에 있고 값에 이스케이프된 따옴표가 없을 때만 됩니다. 중첩 JSON 은 보드나 jq 를 쓰십시오.
자주 묻는 질문
목록에 없는 로그 형식도 분석할 수 있나요?
한 줄에 기록 하나라면 됩니다. JSON 줄과 key=value 로그는 바로 되고, 다른 배치는 형식 탭에서 나눈 결과를 확인하고 어느 칸이 시각 · 상태 · 경로 · 지연인지 표시하면 됩니다.
레시피가 업로드되나요?
아닙니다. 레시피는 브라우저의 로컬 저장소에 저장되고, 보낼지는 내보낸 파일로 직접 정합니다. 페이지가 네트워크 요청을 할 수 없으므로 올리려 해도 올릴 수 없습니다.
스택 트레이스처럼 여러 줄인 기록은요?
시각으로 시작하지 않는 줄은 앞 줄에 속합니다. 형식 탭에서 「이어지는 줄 묶기」를 켜면 한 기록으로 묶고, 끄면 줄마다 따로 셉니다.
nginx log_format 을 붙여 넣어 형식을 정할 수 있나요?
됩니다. 형식 탭에 log_format · LogFormat · log-format 줄을 붙여 넣으면 변수에서 칸 이름과 종류를 정합니다.
정규식은 어떤 문법을 받나요?
(?<이름>…) 꼴의 이름 붙은 그룹입니다. 그룹 이름이 칸 이름이 되고, time · status · level · path · latency 같은 이름은 역할도 정합니다.
CSV 나 TSV 도 되나요?
구분자로 나뉜 파일은 형식 탭에서 칸이 깔끔하게 나뉩니다. 열 이름을 한 번 붙이고 레시피로 저장하십시오.