MessagePack 뷰어
MessagePack hex 또는 base64를 붙여 넣으면 JSON으로 읽어줍니다. 인코딩은 자동 감지, 디코딩은 브라우저 안에서, 업로드 없음.
MessagePack 뷰어가 하는 일
Cloudflare Worker 로그에 찍힌 hex 덩어리를 보면서 "이거 안에 뭐가 들었지?" 싶었던 적이 있다면, 바로 이 페이지를 위한 거예요. MessagePack은 바이너리 직렬화 포맷이라 출력이 83a76f72646572496478a84f52442d37343231... 같은 모양으로 나옵니다. 전송 시엔 작지만 눈으로는 못 읽죠. 왼쪽 창에 hex(또는 base64 — 자동 감지합니다)를 붙이면 오른쪽 창에 디코딩된 JSON 트리가 나옵니다.
디코딩은 공식 라이브러리 @msgpack/msgpack으로 로컬에서 처리합니다. 대부분의 Node 및 브라우저 앱이 쓰는 그 라이브러리예요. 포맷은 공개된 MessagePack 와이어 포맷 스펙을 따르므로 msgpack-python, msgpack-c, msgpack-java 등 스펙을 지키는 어떤 구현으로 만든 페이로드도 여기서 동작합니다. 업로드 단계가 없어서 바이트가 브라우저를 떠나지 않아요. blob 안에 customer: 'Ava Chen'이나 내부용 subscriberId: 'SUB-1001' 같은 게 들어 있을 때 중요하죠.
디코딩은 300ms 디바운스가 걸려 있어서 붙이고, 고치고, 다시 붙이는 과정에서 아무것도 누를 필요가 없습니다. Convert 버튼도, 스피너도 없어요. 그냥 입력하면 보입니다.
MessagePack 페이로드를 보는 방법
세 단계입니다. 로그에서 복사한 hex 문자열, Kafka 메시지에서 빼낸 base64 필드, 디버거에서 붙여넣은 raw 바이트 모두에 통합니다.
왼쪽 창에 hex 또는 base64를 붙이세요
인코딩된 MessagePack을 왼쪽 에디터에 떨어뜨리세요. 자동 감지합니다. 공백, 콤마, 0x 접두사, \x 이스케이프를 제거한 뒤 hex로 깔끔하게 파싱되면 hex로 처리하고, 아니면 base64(RFC 4648)를 시도합니다. 둘 다 괜찮아요. hex로 인코딩된 주문 예시:
83a76f72646572496478a84f52442d37343231a56974656d739282a3736b75a7534b552d313031a37174790282a3736b75a7534b552d323434a37174790182a8637573746f6d6572a841766120436865 6e이 blob은 고객 Ava Chen의 주문, 라인 아이템 두 개(SKU-101 x2와 SKU-244 x1)로 디코딩됩니다.
오른쪽에서 디코딩된 JSON 읽기
오른쪽 창은 읽기 전용이고, 디코딩된 페이로드를 보기 좋게 정렬한 JSON으로 보여줍니다. 들여쓰기는 JSON.stringify(obj, null, 2)와 같아요. map은 객체, 배열은 배열, 정수/실수는 숫자, 바이너리 blob은 바이트 길이가 함께 표시되는 Uint8Array로 들어옵니다. timestamp 확장 타입에서 온 시각은 ISO 문자열로 렌더링됩니다.
클릭 없이 반복하기
입력을 수정하면 300ms 후에 JSON이 업데이트됩니다. 바이트가 유효한 MessagePack이 아니면 파싱된 척하지 않고 무엇이 잘못됐는지(잘린 버퍼, 예상 못 한 타입 바이트 등) 알려줍니다. 비교용으로 검증된 Order 페이로드를 불러오려면 예제 msgpack 버튼을 쓰세요.
실제로 쓸 만한 상황
로그에 박힌 MessagePack 메시지 들여다보기
서비스가 구조화 로그에 msgpack 페이로드를 hex로 적습니다(많은 경우 base64보다 짧으니까요). 운영에서 뭔가 깨졌을 때 로그 줄에서 hex를 복사해 여기 붙이면 프로듀서가 실제로 뭘 보냈는지 즉시 보입니다 — orderId ORD-7421, 맞는 아이템들, 잘못된 customer 필드, 뭐든.
Redis나 Kafka 페이로드 디버깅
핫 패스에서 JSON 대신 MessagePack을 쓰는 백엔드가 많아요. 30~50% 정도 작고 파싱도 빠르거든요. Redis에서 값을 꺼내거나 kcat -e로 Kafka 토픽을 살피면 바이트가 base64로 나옵니다. 여기 붙여서 컨슈머와 프로듀서가 스키마에 합의가 됐는지 확인하세요.
언어 간 라운드트립 검증
Python에서 msgpack.packb(...)로 인코딩하고 Go에서 msgpack.Unmarshal(...)로 디코딩한다고 칩시다. Go 쪽에서 타입이 틀리게 보이면 Python에서 바이트를 hex로 덤프해 이 뷰어에 통과시키세요. 인코더 버그인지 디코더 버그인지 오후 내내 토론하기 전에 알려줍니다.
저장된 파일에서 MessagePack 읽기
Jupyter 노트북 내보내기, 게임 세이브, 분석 덤프 같은 데서 나온 <code>.msgpack</code> 파일이 있어요. <code>xxd -p</code>로 hex를 뽑고, 붙이고, 읽으면 끝. 레코드 하나가 어떤지 보려고 새 Python REPL에 라이브러리를 끌어오는 것보다 빠릅니다.
자주 묻는 질문
내 데이터가 브라우저 밖으로 나가나요?
아니요. 디코딩은 페이지에 번들된 @msgpack/msgpack 라이브러리를 사용해 이 탭 안에서 모두 끝납니다. fetch도, 업로드도, 바이트에 대한 텔레메트리도 없습니다. 탭을 닫으면 데이터는 사라져요. 그렇긴 해도 — URL 바는 공공 공간으로 취급하고, 거기에 페이로드를 넣지 마세요. 클립보드에 비밀이 있었다면 비워두세요.
hex 대신 base64를 붙여도 되나요?
됩니다. 뷰어가 자동 감지해요. 공백, 콤마, 0x 접두사, Python 스타일 \x 이스케이프를 제거한 뒤 hex로 파싱되면 hex로 처리하고, 아니면 표준 base64를 시도합니다. 같은 페이로드에 대해 어느 쪽이든 동작합니다. 짧은 메시지는 hex, 긴 메시지는 base64를 로그에 쓰는 경우가 많아요.
바이너리 필드, 타임스탬프, 확장 타입은 어떻게 되나요?
바이너리(bin 패밀리)는 Uint8Array로 디코딩되고 JSON 트리에서는 { "0": 134, "1": 12, ... } 형태로 출력됩니다(표준 JSON에 네이티브 바이트 타입이 없기 때문 — Uint8Array 문서는 MDN 참고). timestamp 확장 타입에서 온 값은 네이티브 Date 객체로 디코딩되고 ISO 8601 문자열로 직렬화됩니다. 그 외 확장 타입은 { type, data } 튜플로 들어와서 타입 코드와 raw 바이트를 볼 수 있어요.
디코딩 결과가 서버가 보낸 것과 다른 이유는?
흔한 두 가지 범인이 있습니다. 하나: 입력이 잘렸어요 — 로그 트런케이션이 마지막 몇 바이트를 자르는 경우가 많고, msgpack은 길이 접두사 필드에 의존하니 꼬리가 빠지면 헷갈리는 에러나 부분 출력이 나옵니다. 둘: 프로듀서가 커스텀 확장 타입을 썼는데 수신 측이 그걸 모르는 거예요. 구조가 말이 안 돼 보이면 바이트를 공식 스펙과 대조해 보세요.
엄청 큰 페이로드도 디코딩되나요?
몇 MB짜리 hex는 요즘 브라우저에서 잘 붙여집니다. 그 이상이면 입력 쪽 Ace 에디터가 무거워지기 시작해요 — 그 정도면 Node 스크립트에서 라이브러리로 파일을 직접 읽는 편이 낫습니다. 병목은 디코더가 아니라 에디터예요.
예시 같은 hex는 어떻게 만드나요?
Python: import msgpack; msgpack.packb(obj).hex(). JS: Array.from(encode(obj)).map(b => b.toString(16).padStart(2, '0')).join(''). Go: fmt.Sprintf("%x", msgpack.Marshal(obj)). 거의 모든 언어에 한 줄짜리 방법이 있고, 결과 hex를 그대로 여기 붙이면 됩니다.
다른 MessagePack 도구
뷰잉은 한 면일 뿐입니다 — 아래 도구들은 전체 라운드트립과 인접 포맷을 다룹니다: