콘텐츠로 이동
무료 평가 시작

검증 도구

MQTT 문제는 대개 “누가 무엇을 어느 토픽에 보냈고, 브로커가 누구에게 전달했는가”를 확인하면 풀립니다. 이 문서는 그 질문에 답하는 도구를 정리합니다.

mosquitto_sub를 와일드카드 필터로 실행하면 브로커를 지나는 메시지를 볼 수 있습니다. MQTT 5.0 속성을 보려면 반드시 -V 5를 줍니다.

터미널 창
mosquitto_sub -V 5 -t 'opcua/#' -F '%t qos=%q retain=%r content-type=%C user-properties=%P %l bytes'
-F 코드 출력
%t 토픽
%q, %r 받은 QoS, RETAIN 플래그
%C Content Type 속성
%P 사용자 속성(이름:값, 쉼표로 구분)
%l 페이로드 길이(바이트)
%x 페이로드의 16진수
%p 페이로드 원문
%I 받은 시각(ISO 8601)
%j 메시지 전체를 JSON 한 줄로

-F '%j'는 속성까지 JSON으로 보여 줍니다.

{"tst":"2026-10-15T02:07:35.001558+0900","topic":"demo/a","qos":0,"retain":false,"payloadlen":2,"properties":{"content-type":"text/plain","user-properties":[{"k":"v"}]},"payload":"hi"}

자주 쓰는 다른 옵션은 다음과 같습니다.

옵션 뜻
-q 1 QoS 1로 구독합니다. 기본값은 QoS 0입니다.
-C <개수> 메시지를 그만큼 받으면 끝냅니다.
-W <초> 그 시간 안에 끝나지 않으면 Timed out을 출력하고 종료 코드 27로 끝납니다.
-N 페이로드 뒤에 줄바꿈을 붙이지 않습니다. 바이너리를 파일로 받을 때 씁니다.
-d 클라이언트가 주고받는 패킷을 출력합니다.

시뮬레이터 구독자가 받는지 시험하려면 mosquitto_pub에 OPC UA PubSub 속성을 붙입니다.

터미널 창
mosquitto_pub -V 5 -q 1 -t opcua/uadp/data/77/demo \
-D publish content-type application/opcua+uadp \
-D publish user-property UAMessageType ua-data \
-f dataset.bin

-f는 파일 내용을 그대로 페이로드로 보냅니다. UADP 페이로드를 만드는 방법은 시뮬레이터로 발행·구독에 있습니다.

mosquitto -v 또는 log_type all로 실행한 Mosquitto는 패킷마다 한 줄을 남깁니다.

New client connected from 127.0.0.1:64658 as pdcomm-opcua-sim-79619-17 (p5, c1, k30).
Received SUBSCRIBE from pdcomm-opcua-sim-79619-17
opcua/uadp/data/77/quickstart (QoS 1)
Received PUBLISH from pdcomm-opcua-sim-79619-17 (d0, q1, r0, m2, 'opcua/uadp/data/77/quickstart', ... (48 bytes))
Sending PUBLISH to pdcomm-opcua-sim-79619-17 (d0, q1, r0, m1, 'opcua/uadp/data/77/quickstart', ... (48 bytes))
Sending PUBACK to pdcomm-opcua-sim-79619-17 (m2, rc0)
표기 뜻
p5, c1, k30 MQTT 5.0, Clean Start 1, Keep Alive 30초. 인증서나 사용자 이름이 있으면 u'…'가 붙습니다.
d0, q1, r0, m2 DUP 0, QoS 1, RETAIN 0, 패킷 식별자 2
rc0 이유 코드 0x00(성공). rc135는 0x87(Not authorized)
Denied PUBLISH from … ACL이 발행을 거부했습니다.
disconnected: not authorised. 인증에 실패해 연결을 끊었습니다.

시뮬레이터의 클라이언트 식별자는 pdcomm-opcua-sim-<프로세스 ID>-<DataSetWriterId>이므로 로그에서 어느 시뮬레이터인지 구별할 수 있습니다.

Mosquitto는 $SYS/broker/ 아래에 브로커 정보를 발행합니다. 값은 sys_interval(기본 10초)마다 갱신됩니다.

터미널 창
mosquitto_sub -V 5 -t '$SYS/broker/version' -t '$SYS/broker/clients/connected' -t '$SYS/broker/messages/received' -v
$SYS/broker/version mosquitto version 2.1.2

#로 시작하는 필터는 $SYS와 일치하지 않으므로 $SYS 토픽은 따로 구독합니다.

시뮬레이터 상태 값으로 판단하기

섹션 제목: “시뮬레이터 상태 값으로 판단하기”

시뮬레이터의 PubSub 상태(GUI 상태 줄, 헤드리스 pubsub_status)만으로 많은 것을 알 수 있습니다.

관찰 뜻 다음 확인
sent가 acknowledged보다 계속 큼 브로커가 PUBACK을 보내지 않았거나 실패로 답했습니다. error의 MQTT publish refused: 0x.., 브로커 로그의 Denied PUBLISH
rejected가 늘어남 메시지를 받았지만 형식이나 속성이 맞지 않았습니다. error 값과 전달 문제
관찰자에는 보이는데 received가 그대로 토픽이 다르거나 브로커가 읽기 권한이 없어 전달하지 않았습니다. 시뮬레이터 토픽과 ACL
running이 false이고 error가 MQTT: … 브로커 연결이 끊겼습니다. 브로커 로그와 연결 문제
dropped가 늘어남 받은 메시지를 꺼내지 않아 대기열(256개)이 넘쳤습니다. pubsub_received나 Show received를 더 자주 실행

시뮬레이터는 실행한 동작을 추적(trace)에 남깁니다. GUI에서는 Trace & Diagnostics 탭의 Refresh trace, 헤드리스에서는 {"action":"trace"}로 봅니다. 실패한 동작에는 오류 문장이 함께 남습니다.

{"action":"pubsub_start","elapsed_us":112,"error":"MQTT broker connection failed: MQTT transport I/O: ConnectionRefused","ok":false,"sequence":2,"time_ms":0,"workspace":"pubsub"}

진단 로그 파일은 같은 탭의 **Diagnostic log (off by default)**와 Apply logging으로 켭니다. 헤드리스에서는 logging_configure를 씁니다.

{"action":"logging_configure","config":{"enabled":true,"file":"logs/opcua-simulator.jsonl"}}

로그 형식과 수준은 도구 섹션의 진단 로그 문서를 따릅니다.