MediaMTX 指标监控完全指南:启用 Prometheus 兼容的 Metrics 服务与全量指标解读
2026/9/13 18:42:38 网站建设 项目流程

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/mediamtx

MediaMTX 内置一套与 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是否启用 HTTPS
metricsServerKeyserver.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,取值为readynotReady)聚合:

  • paths:值为固定 1,用来指示该路径当前存在;
  • paths_readers:当前正在从该路径拉流的读者数量,并按readerType(如rtspSessionrtmpConn等)细分;
  • paths_inbound_bytes/paths_outbound_bytes:该路径累计接收 / 发送的字节数,是计算码率的核心数据源;
  • paths_inbound_frames_in_error:推流端送入但解析失败的帧数,可用于快速发现源端编码问题。

其中state的取值逻辑在 internal/metrics/metrics.go:路径Ready为真时为ready,否则为notReady

2. HLS:会话与 Muxer

  • hls_sessions{id,path}:每个 HLS 拉流会话计数值为 1,hls_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_bytes(RTSPS 同理,前缀为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_packetsoutbound_rtp_packets_reported_lost(对端通过 RTCP 反馈的丢失数)、outbound_rtp_packets_discarded(本地主动丢弃);
  • 出向 RTCPoutbound_rtcp_packets

这组指标对排查"画面卡顿但网络没断"之类的问题很有价值:将inbound_rtp_packets_lostoutbound_rtp_packets_reported_lost对照,就能区分丢包发生在推流链路还是拉流链路。

4. RTMP / RTMPS:连接级

RTMP 与 RTMPS 以连接为粒度输出rtmp_conns(值为 1)、rtmp_conns_inbound_bytesrtmp_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_bufpackets_send_buf/bytes_send_buf/ms_send_bufpackets_receive_buf/bytes_receive_buf/ms_receive_buf,以及 TSBPD 延迟ms_send_tsb_pd_delay/ms_receive_tsb_pd_delay
  • 其他packets_sent_ack/packets_received_nak(ACK/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_rttpackets_received_losspackets_received_belated三个指标基本就能刻画一条链路的实时健康状况。

6. WebRTC:会话级 RTP/RTCP

webrtc_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_bytesmoq_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_sentrtsp_conns_bytes_received/rtsp_conns_bytes_senthls_muxers_bytes_sent等,以及大量会话上的remoteAddr标签。新接入监控时应优先使用上面表格中列出的新指标与标签,避免未来版本移除废弃项后监控面板失效。

四、为什么没有直接的码率指标

设计上,MediaMTX不直接提供码率(bitrate)指标。原因是码率本质上是一个"随时间变化的速度",而指标端点返回的是累计字节数。任何指标分析器(例如 Grafana 搭配 Prometheus)都可以通过对累计字节做时间微分轻松得到码率:

# 某路径的出站码率(bytes per second) rate(paths_outbound_bytes{name="mypath"}[5m]) * 8

这样既避免了在服务端维护额外状态,也让消费端可以按自己的时间窗口灵活计算瞬时码率或平均码率。

五、精确筛选:用查询参数只看关心的一部分

默认情况下/metrics会返回全部指标。当服务上有大量路径和连接时,可以通过 HTTP 查询参数按类型、路径或具体对象 ID 过滤:

  • type=[TYPE]:只显示某一种类型的指标。TYPE可取pathsforward_destshls_sessionshls_muxersrtsp_connsrtsp_sessionsrtsps_connsrtsps_sessionsrtmp_connsrtmps_connssrt_connswebrtc_sessionsmoq_sessions
  • path=[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?path=camera1"

或只看 SRT 连接类型:

curl "http://localhost:9998/metrics?type=srt_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 中查询pathsrtsp_sessions_inbound_rtp_packets_lost等指标,并在 Grafana 中按标签分组绘制面板。几个常用的监控表达式:

# 实时在线路径数 count(paths{state="ready"} == 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一节,可用动作包括publishreadplaybackapimetricspprof)。默认配置下,127.0.0.1::1的本机用户拥有metrics权限,因此本机curl无需额外传凭据即可访问;跨主机访问时则需要配置相应用户或认证,请求会触发 HTTP Basic 认证(响应头为WWW-Authenticate: Basic realm="mediamtx")。

此外,服务支持 CORS 预检(OPTIONS)请求,允许通过metricsAllowOrigins配置跨域来源,方便前端工具或跨域部署的 Prometheus 直接抓取。

八、实现与测试佐证

  • 指标端点的完整实现位于 internal/metrics/metrics.go,Metrics结构体在 internal/core/core.go 中被装配,并通过SetPathManagerSetHLSServerSetRTSPServerSetSRTServerSetWebRTCServerSetMoQServer等 setter 注入各服务组件的 API 句柄(见 internal/metrics/metrics.go),指标数据全部来自这些组件实时提供的列表接口;
  • internal/metrics/metrics_test.go 中的TestMetrics使用带完整数据的桩服务对输出文本做了逐字节断言,可当作一份"指标输出规范"阅读;TestZeroMetricsFallback验证空数据时的兜底输出;TestPreflightRequest验证 CORS 预检行为;
  • 各指标对应的数据结构定义可进一步查阅 internal/defs 目录下的api_path.goapi_hls.goapi_rtsp.goapi_srt.goapi_rtmp.goapi_webrtc.goapi_moq.goapi_forward_dest.go等文件。

九、小结

MediaMTX 的 metrics 服务用一条metrics: yes配置即可开启,默认监听:9998,以标准 Prometheus 文本格式输出路径、HLS、RTSP/RTSPS、RTMP/RTMPS、SRT、WebRTC、MoQ 与转发目的地八类指标。理解这些指标的分组与标签语义,配合typepath*_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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询