ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

MediaMTX 指标监控完全指南:启用 Prometheus 兼容的 Metrics 服务与全量指标解读

MediaMTX 指标监控完全指南:启用 Prometheus 兼容的 Metrics 服务与全量指标解读 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),仅供参考
返回列表