Broker testleri

İstemci hatalarını ayıklamak için MQTT broker loglarını okumak

Mosquitto ve EMQX loglarını okuyun: doğru log seviyelerini ayarlayın, bağlanma ve kopma satırlarını yorumlayın, tek bir istemciyi izleyin ve çözüme ulaşın.

Güncellendi · 9 dk okuma

İstemci hatalarını ayıklamak için MQTT broker loglarını okumak

Bir istemci connection lost dediğinde genellikle nedenini bilmez. Broker ise bilir. Reddedilen her giriş, her keep-alive zaman aşımı, her yinelenen client ID ve her reddedilen publish, broker logunda bir satır bırakır — loglama bu satırı tutacak şekilde yapılandırılmışsa. Bu satırları okumak, debugger bağlayamadığınız bir istemcide hata ayıklamanın çoğu zaman en hızlı yoludur.

Bu rehber logların nerede olduğunu, hangi log seviyelerini açmanız gerektiğini, Mosquitto'nun bağlanma ve kopma satırlarını nasıl okuyacağınızı, EMQX'te tek bir istemciyi nasıl izleyeceğinizi ve bir log satırını nasıl bir çözüme dönüştüreceğinizi gösteriyor.

Loglar nerede

KurulumNereye bakmalı
Linux paketinden Mosquitto/var/log/mosquitto/mosquitto.log veya journalctl -u mosquitto -f
Docker'da Mosquittodocker logs -f mosquitto (log_dest stdout ile)
EMQXDocker'da konsol çıktısı (docker logs -f emqx); kurulumun log/ dizinindeki dosyalar
HiveMQlog/hivemq.log, ayrıca istemci bağlanma ve kopma olayları için log/event.log
Yönetilen (managed) brokerGenellikle ham broker logu yoktur — reason code'lara ve izlemeye güvenin (aşağıya bakın)

Mosquitto log dosyası boş kalıyorsa başlangıç çıktısında Error: Unable to open log file /var/log/mosquitto/mosquitto.log for writing. satırını arayın — broker kullanıcısı dizine yazamıyordur. Loglama kurulumunun ayrıntıları Mosquitto loglama yazısında.

Doğru log seviyesini açın

Mosquitto'nun varsayılan loglaması, istemci hata ayıklaması için ihtiyacınız olan şeylerin çoğunu gizler. İnceleme sırasında işe yarayan bir yapılandırma:

mosquitto.conf — hata ayıklama sırasında loglama
log_dest stdout
log_dest file /var/log/mosquitto/mosquitto.log

log_type error
log_type warning
log_type notice
log_type information
log_type subscribe
log_type unsubscribe
# Giren ve çıkan her paket — çok ayrıntılı, yalnızca hata ayıklarken açın
log_type debug

connection_messages true
log_timestamp true
log_timestamp_format %Y-%m-%dT%H:%M:%S

Loglama seçeneklerini değiştirdikten sonra broker'ı yeniden başlatın. connection_messages true, bu rehberin büyük kısmının dayandığı bağlanma ve kopma satırlarını üretir; okunabilir bir zaman damgası biçimi de Unix saniyelerini elle çevirme zahmetinden kurtarır. Eksiksiz bir yapılandırmayı mosquitto.conf oluşturucu ile üretebilirsiniz.

EMQX 5'te bir container'ın konsol seviyesini EMQX_LOG__CONSOLE__LEVEL=debug ortam değişkeniyle yükseltin ya da çalışırken değiştirin:

EMQX: log seviyesini çalışırken değiştirin
emqx ctl log set-level debug
# ...sorunu yeniden üretin...
emqx ctl log set-level warning

Mosquitto bağlanma satırlarını okumak

Başarılı bir bağlantı iki satır üretir:

Başarılı bağlantı
2026-10-17T09:12:01: New connection from 192.168.1.20:52144 on port 1883.
2026-10-17T09:12:01: New client connected from 192.168.1.20:52144 as sensor-01 (p2, c1, k60, u'alice').

Sondaki parantez CONNECT paketini tanımlar:

AlanAnlamı
p2Protokol: p2 = MQTT 3.1.1, p5 = MQTT 5 (p1 eski 3.1 olurdu)
c1Clean session / clean start: c1 = yeni oturum, c0 = kalıcı oturumu sürdür
k60Saniye cinsinden keep-alive aralığı
u'alice'İstemcinin gönderdiği kullanıcı adı (gönderilmediyse yoktur)

Bu dört alan birçok soruyu birden yanıtlar: istemci gerçekten düşündüğünüz protokol sürümünü mü kullanıyor? Kalıcı bir oturum mu istiyor? Gerçekte hangi keep-alive değerini ayarladı?

Kopma satırları ve anlamları

Bir istemci ayrıldığında Mosquitto'nun yazdığı satır, logun tamamındaki en faydalı satırdır:

Log satırıSebepÇözüm
Client sensor-01 disconnected.İstemciden temiz bir DISCONNECTHiçbir şey — beklenen davranış
Client sensor-01 closed its connection.TCP, DISCONNECT olmadan kapandıİstemci çöktü, sonlandırıldı ya da gücü kesildi
Client sensor-01 has exceeded timeout, disconnecting.1,5 × keep-alive boyunca paket yokİstemci döngüsünü, uyku mantığını veya NAT zaman aşımını düzeltin — keep-alive zaman aşımı yazısına bakın
Client sensor-01 already connected, closing old connection.İkinci bir istemci aynı client ID'yi kullandıCihaz başına benzersiz ID — yinelenen client ID yazısına bakın
Client sensor-01 disconnected, not authorised.Yanlış kimlik bilgileri veya bağlanma izni yokKullanıcı adını, parolayı ve auth plugin'ini kontrol edin
Client sensor-01 disconnected due to protocol error.Bozuk veya beklenmeyen paketKütüphane hatası, yanlış protokol sürümü ya da WebSocket listener'ına düz MQTT
Socket error on client sensor-01, disconnecting.Bağlantı ağ seviyesinde koptuAğ kesintisi, TLS hatası veya aradaki bir cihazdan RST
Outgoing messages are being dropped for client sensor-01.İstemcinin kuyruğu doluYavaş tüketici — limitleri yükseltin ya da daha hızlı tüketin

already connected, closing old connection içeren iki satır birkaç saniyede bir sırayla görünüyorsa, iki cihaz bir client ID için çekişiyor ve döngü halinde yeniden bağlanıyordur. Client ID üreticisi ile benzersiz ID'ler üretin.

Bir oturumu debug seviyesinde izlemek

log_type debug ile Mosquitto her paketi loglar. Bir test topic'inde bir subscriber ve bir publisher kabaca şöyle görünür (Mosquitto 2.x, kısaltılmış):

Tek bir publish'in debug logu
Received SUBSCRIBE from sub-01
    testmqtt/logs/# (QoS 1)
sub-01 1 testmqtt/logs/#
Sending SUBACK to sub-01
Received PUBLISH from pub-01 (d0, q1, r0, m1, 'testmqtt/logs/a', ... (5 bytes))
Sending PUBACK to pub-01 (m1, rc0)
Sending PUBLISH to sub-01 (d0, q1, r0, m1, 'testmqtt/logs/a', ... (5 bytes))
Received PUBACK from sub-01 (Mid: 1, RC:0)

PUBLISH satırlarındaki parantez şöyle okunur: d = DUP flag'i, q = QoS, r = retain, m = message ID, ardından topic ve payload boyutu. Received PUBLISH görüyor ama hiç Sending PUBLISH görmüyorsanız broker mesajı kabul etmiş ama eşleşen bir abonelik bulamamıştır — topic filter'ı topic matcher ile kontrol edin. Denied PUBLISH satırı, bir ACL'nin mesajı engellediği anlamına gelir; bu durum sessizce reddedilen ACL yazısında ele alınıyor.

Bir durumu hızla yeniden üretmek için logu bir terminalde açık tutun ve diğerinden trafik üretin:

İki terminalle hata ayıklama
# Terminal 1 — broker tarafı
docker logs -f mosquitto 2>&1 | grep --line-buffered -E 'sub-01|pub-01'

# Terminal 2 — istemci tarafı, istemci debug çıktısıyla
mosquitto_sub -d -h localhost -i sub-01 -t 'testmqtt/logs/#' -q 1 &
mosquitto_pub -d -h localhost -i pub-01 -t 'testmqtt/logs/a' -q 1 -m 'hello'

-d, istemcilerin kendi paket loglarını (Client sub-01 sending CONNECT, received CONNACK (0)) yazdırmasını sağlar; böylece iki görünümü satır satır karşılaştırabilirsiniz.

EMQX'te tek bir istemciyi izlemek

Yoğun bir EMQX broker'ında global debug loglama çok gürültülüdür. Bunun yerine tek bir istemciyi izleyin:

EMQX: tek bir client ID'yi izleyin
emqx ctl trace start client sensor-01 /tmp/sensor-01.log
# ...istemcinin bağlanmasına, publish etmesine ve hata vermesine izin verin...
emqx ctl trace stop client sensor-01

Trace dosyası o istemcinin bağlanma, kimlik doğrulama, abone olma, publish ve kopma olaylarını içerir; broker bağlantıyı kapattığında sebebi de dahildir. Dashboard'da aynısını yapan ve sonucu indirmenizi sağlayan bir log trace sayfası bulunur. Hangi client ID'nin sorun çıkardığını bilmiyorsanız topic'e veya istemci IP'sine göre de izleme yapabilirsiniz.

Birkaç komut log aramalarının çoğunu karşılar:

Faydalı log aramaları
# Son bir saatte bir istemciyle ilgili her şey
journalctl -u mosquitto --since "1 hour ago" | grep -F 'sensor-01'

# En sık zaman aşımına uğrayan istemciler hangileri?
grep -o 'Client [^ ]* has exceeded timeout' /var/log/mosquitto/mosquitto.log | sort | uniq -c | sort -rn

# Varsayılan bir Mosquitto log satırındaki Unix zaman damgasını çevirin
date -d @1792228321        # GNU date; macOS'ta: date -r 1792228321

Broker zamanını istemcinin kendi loglarıyla ilişkilendirin. Saatler farklıysa iki tarafın da gördüğü bir olay, örneğin CONNACK üzerinden hizalayın.

Broker logu olmadığında

Broker loglarına erişiminiz yoksa aynı resmi istemci tarafından oluşturun:

  • Kütüphanenizin bildirdiği her reason code'u loglayın ve MQTT reason code'ları açıklaması yazısında ya da reason code aracında arayın.
  • Erişime açıksa broker'ın $SYS topic'lerine abone olun — bağlı istemci sayaçları ve düşürülen mesaj sayaçları çoğu zaman logla aynı eğilimi gösterir. $SYS topic'leri ile izleme yazısına bakın.
  • Sorunu aynı broker'a karşı online MQTT istemcisi ile yeniden üretin. Orada çalışıyorsa sebep broker'da değil, cihazın kodunda veya ağındadır.

Düzeltmeyi logda doğrulayın

Bir log satırı aynı zamanda kabul testinizdir. Bir değişiklikten sonra ilk senaryoyu yeniden üretin ve logu izleyin: has exceeded timeout veya already connected satırı artık görünmemeli, New client connected satırı da amaçladığınız parametreleri (protokol, clean flag'i, keep-alive) göstermelidir. Ardından debug loglamayı tekrar kapatın.

Broker tüm istemcilerin hatalarını görür ama yalnızca siz isterseniz not eder. Bağlantı mesajlarını ve okunabilir bir zaman damgasını yapılandırın, seviyeyi yalnızca inceleme sırasında yükseltin ve birkaç kopma satırını öğrenin — bunlar neredeyse birebir çözüme karşılık gelir.

Sıkça sorulan sorular

Mosquitto'da debug loglamayı nasıl açarım?

mosquitto.conf dosyasına stdout veya file gibi bir log_dest ile birlikte log_type debug (ya da log_type all) ekleyin ve broker'ı yeniden başlatın. Debug loglama broker'ın aldığı ve gönderdiği her paketi yazar; sorunu bulduğunuzda tekrar kapatın.

Mosquitto'daki 'has exceeded timeout, disconnecting' ne anlama gelir?

Broker, keep-alive aralığının 1,5 katı boyunca istemciden hiçbir şey almadığı için bağlantıyı kapattı. İstemcinin ağ döngüsü durmuş, cihaz uykuya geçmiş ya da bir NAT gateway'i bağlantıyı düşürmüştür. 'New client connected' satırındaki keep-alive değerine bakın (k60, 60 saniye demektir).

EMQX'te tek bir istemcinin loglarını nasıl görürüm?

Bir log trace kullanın: emqx ctl trace start client <clientid> <dosya> o client ID ile ilgili her şeyi bir dosyaya kaydeder; EMQX dashboard'u da log trace sayfasında aynısını sunar. İşiniz bitince emqx ctl trace stop client <clientid> ile durdurun.