
MediaMTX 指標監控完全指南啟用 Prometheus 兼容的 Metrics 服務與全量指標解讀【免費下載鏈接】mediamtxReady-to-use Media-over-QUIC / SRT / WebRTC / RTSP / RTMP / LL-HLS / MPEG-TS / RTP live media server and media proxy that allows to read, publish, proxy, record and playback real-time video and audio streams.項目地址: https://gitcode.com/GitHub_Trending/me/mediamtxMediaMTX 內置一套與 Prometheus 兼容的指標metrics服務通過獨立 HTTP 端口對外提供 Path、HLS、RTSP/RTSPS、RTMP/RTMPS、SRT、WebRTC、MoQ 會話以及轉發目的地的實時運行數據。本文以官方文檔 docs/2-features/22-metrics.md 為主體結合 內部實現源碼 與 默認配置 逐步講清如何開啟該服務、如何用 curl 或 Prometheus 抓取指標、每一組指標的含義以及如何用查詢參數精確篩選出關心的那一小部分數據最終支撐 Grafana 等分析器完成碼率、丟包、延遲等可視化監控。一、開啟 Metrics 服務一條配置項即可上線MediaMTX 的指標服務默認關閉只需在配置文件中設置metrics: yes或true即可啟用# Enable the metrics server, which allows to extract Prometheus-compatible metrics. metrics: false啟用后服務會在獨立端口監聽默認地址為:9998。完整相關的配置項位于 mediamtx.yml 的Global settings - Metrics server一節說明如下配置項默認值說明metricsfalse是否啟用指標服務器metricsAddress:9998TCP/HTTP 監聽地址metricsEncryptionfalse是否啟用 HTTPSmetricsServerKeyserver.keyHTTPS 所需的服務器私鑰僅在啟用加密時需要metricsServerCertserver.crtHTTPS 所需的服務器證書僅在啟用加密時需要metricsAllowOrigins[]允許的 CORS 來源支持通配符如[http://*.example.com]metricsTrustedProxies[]位于 HTTP 服務器前面的代理 IP/CIDR這些代理可通過X-Forwarded-For設置客戶端真實 IP、通過X-Forwarded-Proto設置原始協議如果啟用 HTTPS可參照配置注釋中的方式生成自簽名證書openssl genrsa -out server.key 2048 openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650從源碼層面看核心裝配發生在 internal/core/core.go當currentConf.Metrics為真且實例尚未創建時程序會構造metrics.Metrics把地址、加密、證書、CORS 來源、可信代理、讀寫超時以及認證管理器逐一注入后調用Initialize()啟動監聽。隨后日志會輸出started with listener on address (TCP/HTTP)或(TCP/HTTPS)見 internal/metrics/metrics.go。二、抓取指標一條 curl 命令即可驗證啟用服務后即可通過 Prometheus 或直接發送 HTTP 請求抓取指標curl http://localhost:9998/metrics返回體是標準的 Prometheus 文本格式形如# Paths paths{name[path_name],state[state]} 1 paths_readers{name[path_name],state[state],readerType[readerType]} 5 paths_inbound_bytes{name[path_name],state[state]} 1234 paths_outbound_bytes{name[path_name],state[state]} 1234 paths_inbound_frames_in_error{name[path_name],state[state]} 1234 # HLS sessions hls_sessions{id[id],path[path]} 1 hls_sessions_outbound_bytes{id[id],path[path]} 187 # HLS muxers hls_muxers{name[name]} 1 hls_muxers_outbound_bytes{name[name]} 187 hls_muxers_outbound_frames_discarded{name[name]} 12 # RTSP connections rtsp_conns{id[id]} 1 rtsp_conns_inbound_bytes{id[id]} 1234 rtsp_conns_outbound_bytes{id[id]} 187 # RTSP sessions rtsp_sessions{id[id],path[path],state[state]} 1 rtsp_sessions_inbound_bytes{id[id],path[path],state[state]} 1234 rtsp_sessions_inbound_rtp_packets{id[id],path[path],state[state]} 123 rtsp_sessions_inbound_rtp_packets_lost{id[id],path[path],state[state]} 123 rtsp_sessions_inbound_rtp_packets_in_error{id[id],path[path],state[state]} 123 rtsp_sessions_inbound_rtp_packets_jitter{id[id],path[path],state[state]} 123 rtsp_sessions_inbound_rtcp_packets{id[id],path[path],state[state]} 123 rtsp_sessions_inbound_rtcp_packets_in_error{id[id],path[path],state[state]} 123 rtsp_sessions_outbound_bytes{id[id],path[path],state[state]} 187 rtsp_sessions_outbound_rtp_packets{id[id],path[path],state[state]} 123 rtsp_sessions_outbound_rtp_packets_reported_lost{id[id],path[path],state[state]} 123 rtsp_sessions_outbound_rtp_packets_discarded{id[id],path[path],state[state]} 123 rtsp_sessions_outbound_rtcp_packets{id[id],path[path],state[state]} 123 # RTSPS connections rtsps_conns{id[id]} 1 rtsps_conns_inbound_bytes{id[id]} 1234 rtsps_conns_outbound_bytes{id[id]} 187 # RTSPS sessions rtsps_sessions{id[id],path[path],state[state]} 1 rtsps_sessions_inbound_bytes{id[id],path[path],state[state]} 1234 rtsps_sessions_inbound_rtp_packets{id[id],path[path],state[state]} 123 rtsps_sessions_inbound_rtp_packets_lost{id[id],path[path],state[state]} 123 rtsps_sessions_inbound_rtp_packets_in_error{id[id],path[path],state[state]} 123 rtsps_sessions_inbound_rtp_packets_jitter{id[id],path[path],state[state]} 123 rtsps_sessions_inbound_rtcp_packets{id[id],path[path],state[state]} 123 rtsps_sessions_inbound_rtcp_packets_in_error{id[id],path[path],state[state]} 123 rtsps_sessions_outbound_bytes{id[id],path[path],state[state]} 187 rtsps_sessions_outbound_rtp_packets{id[id],path[path],state[state]} 123 rtsps_sessions_outbound_rtp_packets_reported_lost{id[id],path[path],state[state]} 123 rtsps_sessions_outbound_rtp_packets_discarded{id[id],path[path],state[state]} 123 rtsps_sessions_outbound_rtcp_packets{id[id],path[path],state[state]} 123 # RTMP connections rtmp_conns{id[id],path[path],state[state]} 1 rtmp_conns_inbound_bytes{id[id],path[path],state[state]} 1234 rtmp_conns_outbound_bytes{id[id],path[path],state[state]} 187 rtmp_conns_outbound_frames_discarded{id[id],path[path],state[state]} 12 # RTMPS connections rtmps_conns{id[id],path[path],state[state]} 1 rtmps_conns_inbound_bytes{id[id],path[path],state[state]} 1234 rtmps_conns_outbound_bytes{id[id],path[path],state[state]} 187 rtmps_conns_outbound_frames_discarded{id[id],path[path],state[state]} 12 # SRT connections srt_conns{id[id],path[path],state[state]} 1 srt_conns_packets_sent{id[id],path[path],state[state]} 123 srt_conns_packets_received{id[id],path[path],state[state]} 123 srt_conns_packets_sent_unique{id[id],path[path],state[state]} 123 srt_conns_packets_received_unique{id[id],path[path],state[state]} 123 srt_conns_packets_send_loss{id[id],path[path],state[state]} 123 srt_conns_packets_received_loss{id[id],path[path],state[state]} 123 srt_conns_packets_retrans{id[id],path[path],state[state]} 123 srt_conns_packets_received_retrans{id[id],path[path],state[state]} 123 srt_conns_packets_sent_ack{id[id],path[path],state[state]} 123 srt_conns_packets_received_ack{id[id],path[path],state[state]} 123 srt_conns_packets_sent_nak{id[id],path[path],state[state]} 123 srt_conns_packets_received_nak{id[id],path[path],state[state]} 123 srt_conns_packets_sent_km{id[id],path[path],state[state]} 123 srt_conns_packets_received_km{id[id],path[path],state[state]} 123 srt_conns_us_snd_duration{id[id],path[path],state[state]} 123 srt_conns_packets_received_belated{id[id],path[path],state[state]} 123 srt_conns_packets_send_drop{id[id],path[path],state[state]} 123 srt_conns_packets_received_drop{id[id],path[path],state[state]} 123 srt_conns_packets_received_undecrypt{id[id],path[path],state[state]} 123 srt_conns_bytes_sent{id[id],path[path],state[state]} 187 srt_conns_bytes_received{id[id],path[path],state[state]} 1234 srt_conns_bytes_sent_unique{id[id],path[path],state[state]} 123 srt_conns_bytes_received_unique{id[id],path[path],state[state]} 123 srt_conns_bytes_received_loss{id[id],path[path],state[state]} 123 srt_conns_bytes_retrans{id[id],path[path],state[state]} 123 srt_conns_bytes_received_retrans{id[id],path[path],state[state]} 123 srt_conns_bytes_received_belated{id[id],path[path],state[state]} 123 srt_conns_bytes_send_drop{id[id],path[path],state[state]} 123 srt_conns_bytes_received_drop{id[id],path[path],state[state]} 123 srt_conns_bytes_received_undecrypt{id[id],path[path],state[state]} 123 srt_conns_us_packets_send_period{id[id],path[path],state[state]} 123.123 srt_conns_packets_flow_window{id[id],path[path],state[state]} 123 srt_conns_packets_flight_size{id[id],path[path],state[state]} 123 srt_conns_ms_rtt{id[id],path[path],state[state]} 123.123 srt_conns_mbps_send_rate{id[id],path[path],state[state]} 123.123 srt_conns_mbps_receive_rate{id[id],path[path],state[state]} 123.123 srt_conns_mbps_link_capacity{id[id],path[path],state[state]} 123.123 srt_conns_bytes_avail_send_buf{id[id],path[path],state[state]} 123 srt_conns_bytes_avail_receive_buf{id[id],path[path],state[state]} 123 srt_conns_mbps_max_bw{id[id],path[path],state[state]} -123 srt_conns_bytes_mss{id[id],path[path],state[state]} 123 srt_conns_packets_send_buf{id[id],path[path],state[state]} 123 srt_conns_bytes_send_buf{id[id],path[path],state[state]} 123 srt_conns_ms_send_buf{id[id],path[path],state[state]} 123 srt_conns_ms_send_tsb_pd_delay{id[id],path[path],state[state]} 123 srt_conns_packets_receive_buf{id[id],path[path],state[state]} 123 srt_conns_bytes_receive_buf{id[id],path[path],state[state]} 123 srt_conns_ms_receive_buf{id[id],path[path],state[state]} 123 srt_conns_ms_receive_tsb_pd_delay{id[id],path[path],state[state]} 123 srt_conns_packets_reorder_tolerance{id[id],path[path],state[state]} 123 srt_conns_packets_received_avg_belated_time{id[id],path[path],state[state]} 123 srt_conns_packets_send_loss_rate{id[id],path[path],state[state]} 123.123 srt_conns_packets_received_loss_rate{id[id],path[path],state[state]} 123.123 srt_conns_outbound_frames_discarded{id[id],path[path],state[state]} 12 # WebRTC sessions webrtc_sessions{id[id],path[path],state[state]} 1 webrtc_sessions_inbound_bytes{id[id],path[path],state[state]} 1234 webrtc_sessions_inbound_rtp_packets{id[id],path[path],state[state]} 123 webrtc_sessions_inbound_rtp_packets_lost{id[id],path[path],state[state]} 123 webrtc_sessions_inbound_rtp_packets_jitter{id[id],path[path],state[state]} 123 webrtc_sessions_inbound_rtcp_packets{id[id],path[path],state[state]} 123 webrtc_sessions_outbound_bytes{id[id],path[path],state[state]} 187 webrtc_sessions_outbound_rtp_packets{id[id],path[path],state[state]} 123 webrtc_sessions_outbound_rtcp_packets{id[id],path[path],state[state]} 123 webrtc_sessions_outbound_frames_discarded{id[id],path[path],state[state]} 12 # MoQ sessions moq_sessions{id[id],path[path],state[state]} 1 moq_sessions_inbound_bytes{id[id],path[path],state[state]} 1234 moq_sessions_outbound_bytes{id[id],path[path],state[state]} 187 # Forward destinations forward_dests{pos[pos],id[id],path[path],type[type],state[state]} 1 forward_dests_outbound_bytes{pos[pos],id[id],path[path],type[type],state[state]} 1234指標序列化的實現細節上述輸出并非預先寫死的模板而是每次請求時由 internal/metrics/metrics.go 中的onMetrics處理器動態收集各服務組件的數據后逐行拼裝而成指標名與標簽統一通過metric()/metricFloat()兩個輔助函數輸出前者輸出 64 位整數后者輸出浮點數見 internal/metrics/metrics.go標簽label會被按鍵名排序后輸出tags()內部使用sortedKeys因此同一指標的標簽順序是穩定、確定的便于程序解析每個指標分組之間以# 分組名注釋行分隔Prometheus 抓取器會忽略這些注釋當對應組件沒有數據時服務仍會輸出鍵名為 0 的兜底指標見測試TestZeroMetricsFallback保證監控面板上不存在指標消失導致的空洞。三、各組指標逐個拆解它們度量了什么1. Paths路徑級匯總paths組是整個服務的總覽視圖按路徑名name與狀態state取值為ready或notReady聚合paths值為固定 1用來指示該路徑當前存在paths_readers當前正在從該路徑拉流的讀者數量并按readerType如rtspSession、rtmpConn等細分paths_inbound_bytes/paths_outbound_bytes該路徑累計接收 / 發送的字節數是計算碼率的核心數據源paths_inbound_frames_in_error推流端送入但解析失敗的幀數可用于快速發現源端編碼問題。其中state的取值邏輯在 internal/metrics/metrics.go路徑Ready為真時為ready否則為notReady。2. HLS會話與 Muxerhls_sessions{id,path}每個 HLS 拉流會話計數值為 1hls_sessions_outbound_bytes為該會話累計下發的字節數hls_muxers{name}每個 HLS muxer按路徑名標識計數值為 1配合hls_muxers_outbound_bytes下發字節與hls_muxers_outbound_frames_discarded被丟棄的幀數觀察 HLS 轉封裝環節的健康度。幀被丟棄通常意味著 HLS 分段窗口過短或客戶端消費不及時。3. RTSP / RTSPS連接與會話連接connection層按id記錄控制連接的累計收發字節rtsp_conns_inbound_bytes/rtsp_conns_outbound_bytesRTSPS 同理前綴為rtsps_。會話session層按{id, path, state}三標簽細分字段最為豐富幾乎覆蓋 RTP/RTCP 的全部關鍵計數字節*_sessions_inbound_bytes/*_sessions_outbound_bytes入向 RTPinbound_rtp_packets總包數、inbound_rtp_packets_lost丟失、inbound_rtp_packets_in_error出錯、inbound_rtp_packets_jitter抖動入向 RTCPinbound_rtcp_packets/inbound_rtcp_packets_in_error出向 RTPoutbound_rtp_packets、outbound_rtp_packets_reported_lost對端通過 RTCP 反饋的丟失數、outbound_rtp_packets_discarded本地主動丟棄出向 RTCPoutbound_rtcp_packets。這組指標對排查畫面卡頓但網絡沒斷之類的問題很有價值將inbound_rtp_packets_lost與outbound_rtp_packets_reported_lost對照就能區分丟包發生在推流鏈路還是拉流鏈路。4. RTMP / RTMPS連接級RTMP 與 RTMPS 以連接為粒度輸出rtmp_conns值為 1、rtmp_conns_inbound_bytes、rtmp_conns_outbound_bytes以及rtmp_conns_outbound_frames_discarded出向被丟棄的幀數標簽為{id, path, state}。幀被丟棄往往與 RTMP 播放器帶寬不足或流中關鍵幀間隔有關。5. SRT最豐富的鏈路質量指標體系SRT 連接srt_conns{id,path,state}暴露了一整套源自 SRT 協議棧自身的統計量是判斷公網鏈路質量的關鍵丟包與重傳packets_send_loss/packets_received_loss丟包數、packets_retrans/packets_received_retrans重傳數、packets_send_loss_rate/packets_received_loss_rate丟包率浮點延遲與擁塞ms_rtt往返時延、us_packets_send_period發包間隔、packets_flow_window流控窗口、packets_flight_size在途包數帶寬mbps_send_rate/mbps_receive_rate收發速率、mbps_link_capacity鏈路容量、mbps_max_bw最大帶寬無限制時為負值緩沖bytes_avail_send_buf/bytes_avail_receive_buf、packets_send_buf/bytes_send_buf/ms_send_buf、packets_receive_buf/bytes_receive_buf/ms_receive_buf以及 TSBPD 延遲ms_send_tsb_pd_delay/ms_receive_tsb_pd_delay其他packets_sent_ack/packets_received_nakACK/NAK 計數、packets_sent_km密鑰消息、packets_received_belated遲到包、packets_send_drop/packets_received_drop丟棄、packets_received_undecrypt無法解密、bytes_mss最大分段大小、packets_reorder_tolerance亂序容限與outbound_frames_discarded。對使用 SRT 做公網遠距離傳輸例如從野外攝像機回傳的場景ms_rtt、packets_received_loss與packets_received_belated三個指標基本就能刻畫一條鏈路的實時健康狀況。6. WebRTC會話級 RTP/RTCPwebrtc_sessions{id,path,state}覆蓋入向/出向字節、RTP 包數、丟包、抖動inbound_rtp_packets_jitter與 RTCP 包數另有webrtc_sessions_outbound_frames_discarded反映因擁塞或播放端處理不及時而丟棄的幀數。7. MoQ會話級收發字節moq_sessions{id,path,state}僅暴露moq_sessions_inbound_bytes與moq_sessions_outbound_bytes兩個字節計數用于觀察基于 Media-over-QUIC 的會話流量。8. Forward destinations轉發目的地forward_dests{pos,id,path,type,state}按轉發目的地維度輸出forward_dests_outbound_bytes統計轉發出去的字節數。type標簽用于標識轉發協議類型RTSP、RTMP、SRT、WebRTC、MoQ 等。需要留意的是源碼注釋明確說明該指標的protocol標簽已廢棄由type取代見 internal/metrics/metrics.go。關于廢棄指標為保持向下兼容輸出中還存在一批以(deprecated)注釋標出的舊指標例如paths_bytes_received/paths_bytes_sent、rtsp_conns_bytes_received/rtsp_conns_bytes_sent、hls_muxers_bytes_sent等以及大量會話上的remoteAddr標簽。新接入監控時應優先使用上面表格中列出的新指標與標簽避免未來版本移除廢棄項后監控面板失效。四、為什么沒有直接的碼率指標設計上MediaMTX不直接提供碼率bitrate指標。原因是碼率本質上是一個隨時間變化的速度而指標端點返回的是累計字節數。任何指標分析器例如 Grafana 搭配 Prometheus都可以通過對累計字節做時間微分輕松得到碼率# 某路徑的出站碼率bytes per second rate(paths_outbound_bytes{namemypath}[5m]) * 8這樣既避免了在服務端維護額外狀態也讓消費端可以按自己的時間窗口靈活計算瞬時碼率或平均碼率。五、精確篩選用查詢參數只看關心的一部分默認情況下/metrics會返回全部指標。當服務上有大量路徑和連接時可以通過 HTTP 查詢參數按類型、路徑或具體對象 ID 過濾type[TYPE]只顯示某一種類型的指標。TYPE可取paths、forward_dests、hls_sessions、hls_muxers、rtsp_conns、rtsp_sessions、rtsps_conns、rtsps_sessions、rtmp_conns、rtmps_conns、srt_conns、webrtc_sessions、moq_sessionspath[PATH]只顯示屬于某個具體路徑的指標hls_muxer[PATH]只顯示某個具體 HLS muxer 的指標hls_session[ID]只顯示某個具體 HLS 會話的指標rtsp_conn[ID]只顯示某個具體 RTSP 連接的指標rtsp_session[SESSION]只顯示某個具體 RTSP 會話的指標rtsps_conn[ID]只顯示某個具體 RTSPS 連接的指標rtsps_session[SESSION]只顯示某個具體 RTSPS 會話的指標rtmp_conn[ID]只顯示某個具體 RTMP 連接的指標rtmps_conn[ID]只顯示某個具體 RTMPS 連接的指標srt_conn[ID]只顯示某個具體 SRT 連接的指標webrtc_session[ID]只顯示某個具體 WebRTC 會話的指標forward_dest[ID]只顯示某個具體轉發目的地的指標moq_session[ID]只顯示某個具體 MoQ 會話的指標。查詢參數既支持單獨使用也支持組合。例如只查看路徑camera1的匯總與轉發指標curl http://localhost:9998/metrics?pathcamera1或只看 SRT 連接類型curl http://localhost:9998/metrics?typesrt_conns這些過濾條件在 internal/metrics/metrics.go 中被逐個解析為過濾器變量并作為各組指標是否輸出的判定條件type的取值集合與 13 種指標類型常量一一對應見 internal/metrics/metrics.go。六、與 Prometheus Grafana 集成MediaMTX 的指標端點不需要任何專屬 exporter直接把它聲明為一個 Prometheus 抓取目標即可。假設 MediaMTX 與 Prometheus 同機部署scrape_configs: - job_name: mediamtx metrics_path: /metrics static_configs: - targets: [localhost:9998]隨后即可在 Prometheus 中查詢paths、rtsp_sessions_inbound_rtp_packets_lost等指標并在 Grafana 中按標簽分組繪制面板。幾個常用的監控表達式# 實時在線路徑數 count(paths{stateready} 1) # 各路徑出站碼率 sum by (name) (rate(paths_outbound_bytes[5m]) * 8) # RTSP 會話入向 RTP 丟包率 sum by (path) (increase(rtsp_sessions_inbound_rtp_packets_lost[5m])) / sum by (path) (increase(rtsp_sessions_inbound_rtp_packets[5m])) # SRT 連接往返時延 srt_conns_ms_rtt七、訪問控制與 CORS指標端點并非完全公開。服務在啟動時會掛載認證中間件見 internal/metrics/metrics.go每個請求都會以metrics動作走統一認證流程支持內部用戶、HTTP 外部認證、JWT 等多種認證方式相關配置見 mediamtx.yml 的Internal authentication一節可用動作包括publish、read、playback、api、metrics、pprof。默認配置下127.0.0.1與::1的本機用戶擁有metrics權限因此本機curl無需額外傳憑據即可訪問跨主機訪問時則需要配置相應用戶或認證請求會觸發 HTTP Basic 認證響應頭為WWW-Authenticate: Basic realmmediamtx。此外服務支持 CORS 預檢OPTIONS請求允許通過metricsAllowOrigins配置跨域來源方便前端工具或跨域部署的 Prometheus 直接抓取。八、實現與測試佐證指標端點的完整實現位于 internal/metrics/metrics.goMetrics結構體在 internal/core/core.go 中被裝配并通過SetPathManager、SetHLSServer、SetRTSPServer、SetSRTServer、SetWebRTCServer、SetMoQServer等 setter 注入各服務組件的 API 句柄見 internal/metrics/metrics.go指標數據全部來自這些組件實時提供的列表接口internal/metrics/metrics_test.go 中的TestMetrics使用帶完整數據的樁服務對輸出文本做了逐字節斷言可當作一份指標輸出規范閱讀TestZeroMetricsFallback驗證空數據時的兜底輸出TestPreflightRequest驗證 CORS 預檢行為各指標對應的數據結構定義可進一步查閱 internal/defs 目錄下的api_path.go、api_hls.go、api_rtsp.go、api_srt.go、api_rtmp.go、api_webrtc.go、api_moq.go、api_forward_dest.go等文件。九、小結MediaMTX 的 metrics 服務用一條metrics: yes配置即可開啟默認監聽:9998以標準 Prometheus 文本格式輸出路徑、HLS、RTSP/RTSPS、RTMP/RTMPS、SRT、WebRTC、MoQ 與轉發目的地八類指標。理解這些指標的分組與標簽語義配合type、path、*_conn、*_session等查詢參數按需過濾再交給 Prometheus 與 Grafana 完成碼率、丟包率、時延等衍生計算就可以構建出一套從源端推流質量到各協議分發鏈路全覆蓋的實時媒體監控體系。【免費下載鏈接】mediamtxReady-to-use Media-over-QUIC / SRT / WebRTC / RTSP / RTMP / LL-HLS / MPEG-TS / RTP live media server and media proxy that allows to read, publish, proxy, record and playback real-time video and audio streams.項目地址: https://gitcode.com/GitHub_Trending/me/mediamtx創作聲明:本文部分內容由AI輔助生成(AIGC),僅供參考