mirror of
https://github.com/langhuihui/monibuca.git
synced 2025-09-26 23:05:55 +08:00
feat: add promethus
This commit is contained in:
29
README.md
29
README.md
@@ -21,22 +21,27 @@ func main() {
|
||||
|
||||
```
|
||||
|
||||
## with sqlite
|
||||
|
||||
```shell
|
||||
go build -tags sqlite -o monibuca_sqlite
|
||||
./monibuca_sqlite -c config.yaml
|
||||
```
|
||||
|
||||
## More Example
|
||||
|
||||
see example directory
|
||||
|
||||
# Prometheus
|
||||
|
||||
```yaml
|
||||
scrape_configs:
|
||||
- job_name: "monibuca"
|
||||
metrics_path: "/api/metrics"
|
||||
static_configs:
|
||||
- targets: ["localhost:8080"]
|
||||
```
|
||||
|
||||
# Create Plugin
|
||||
|
||||
```go
|
||||
|
||||
import (
|
||||
"m7s.live/m7s/v5"
|
||||
)
|
||||
|
||||
type MyPlugin struct {
|
||||
m7s.Plugin
|
||||
}
|
||||
|
||||
var _ = m7s.InstallPlugin[MyPlugin]()
|
||||
```
|
||||
see [plugin](./plugin/README.md)
|
6
go.mod
6
go.mod
@@ -42,6 +42,7 @@ require (
|
||||
github.com/VictoriaMetrics/fastcache v1.12.2 // indirect
|
||||
github.com/VictoriaMetrics/metrics v1.35.1 // indirect
|
||||
github.com/VictoriaMetrics/metricsql v0.76.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/c0deltin/duckdb-driver v0.1.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/chromedp/cdproto v0.0.0-20240202021202-6d0b6a386732 // indirect
|
||||
@@ -66,6 +67,7 @@ require (
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/ncruces/go-strftime v0.1.9 // indirect
|
||||
github.com/ncruces/julianday v1.0.0 // indirect
|
||||
github.com/pion/datachannel v1.5.6 // indirect
|
||||
@@ -80,6 +82,9 @@ require (
|
||||
github.com/pion/turn/v2 v2.1.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.55.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/rogpeppe/go-internal v1.12.0 // indirect
|
||||
github.com/samber/lo v1.44.0 // indirect
|
||||
@@ -119,6 +124,7 @@ require (
|
||||
github.com/gorilla/websocket v1.5.1
|
||||
github.com/onsi/ginkgo/v2 v2.9.5 // indirect
|
||||
github.com/phsym/console-slog v0.3.1
|
||||
github.com/prometheus/client_golang v1.20.4
|
||||
github.com/shirou/gopsutil/v3 v3.24.3
|
||||
go.uber.org/mock v0.4.0 // indirect
|
||||
golang.org/x/crypto v0.26.0 // indirect
|
||||
|
12
go.sum
12
go.sum
@@ -17,6 +17,8 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah
|
||||
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||
github.com/asavie/xdp v0.3.3 h1:b5Aa3EkMJYBeUO5TxPTIAa4wyUqYcsQr2s8f6YLJXhE=
|
||||
github.com/asavie/xdp v0.3.3/go.mod h1:Vv5p+3mZiDh7ImdSvdon3E78wXyre7df5V58ATdIYAY=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bluenviron/mediacommon v1.9.2 h1:EHcvoC5YMXRcFE010bTNf07ZiSlB/e/AdZyG7GsEYN0=
|
||||
github.com/bluenviron/mediacommon v1.9.2/go.mod h1:lt8V+wMyPw8C69HAqDWV5tsAwzN9u2Z+ca8B6C//+n0=
|
||||
github.com/c0deltin/duckdb-driver v0.1.0 h1:g/RAwwNDFd2HmrnqF0oPE0aY7W6F6uFJbf1+zs285eM=
|
||||
@@ -152,6 +154,8 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/ncruces/go-sqlite3 v0.18.1 h1:iN8IMZV5EMxpH88NUac9vId23eTKNFUhP7jgY0EBbNc=
|
||||
github.com/ncruces/go-sqlite3 v0.18.1/go.mod h1:eEOyZnW1dGTJ+zDpMuzfYamEUBtdFz5zeYhqLBtHxvM=
|
||||
github.com/ncruces/go-sqlite3/gormlite v0.18.0 h1:KqP9a9wlX/Ba+yG+aeVX4pnNBNdaSO6xHdNDWzPxPnk=
|
||||
@@ -237,6 +241,14 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI=
|
||||
github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
|
||||
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
|
||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||
github.com/quic-go/quic-go v0.43.1 h1:fLiMNfQVe9q2JvSsiXo4fXOEguXHGGl9+6gLp4RPeZQ=
|
||||
github.com/quic-go/quic-go v0.43.1/go.mod h1:132kz4kL3F9vxhW3CtQJLDVwcFe5wdWeJXXijhsO57M=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
|
@@ -3,11 +3,12 @@ package pkg
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"m7s.live/m7s/v5/pkg/codec"
|
||||
"m7s.live/m7s/v5/pkg/config"
|
||||
"m7s.live/m7s/v5/pkg/task"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"m7s.live/m7s/v5/pkg/util"
|
||||
)
|
||||
|
88
server.go
88
server.go
@@ -21,6 +21,8 @@ import (
|
||||
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||
myip "github.com/husanpao/ip"
|
||||
"github.com/phsym/console-slog"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"gopkg.in/yaml.v3"
|
||||
@@ -80,6 +82,22 @@ type (
|
||||
lastSummaryTime time.Time
|
||||
lastSummary *pb.SummaryResponse
|
||||
conf any
|
||||
prometheusDesc prometheusDesc
|
||||
}
|
||||
prometheusDesc struct {
|
||||
CPU struct {
|
||||
UserTime, Usage, SystemTime, IdleTime *prometheus.Desc
|
||||
}
|
||||
Memory struct {
|
||||
Total, Used, UsedPercent, Free *prometheus.Desc
|
||||
}
|
||||
Disk struct {
|
||||
Total, Used, UsedPercent, Free *prometheus.Desc
|
||||
}
|
||||
Net struct {
|
||||
BytesSent, BytesRecv, PacketsSent, PacketsRecv, ErrsSent, ErrsRecv, DroppedSent, DroppedRecv *prometheus.Desc
|
||||
}
|
||||
BPS, FPS *prometheus.Desc
|
||||
}
|
||||
CheckSubWaitTimeout struct {
|
||||
task.TickTask
|
||||
@@ -93,6 +111,31 @@ type (
|
||||
RawConfig = map[string]map[string]any
|
||||
)
|
||||
|
||||
func (d *prometheusDesc) init() {
|
||||
d.CPU.UserTime = prometheus.NewDesc("cpu_user_time", "CPU user time", nil, nil)
|
||||
d.CPU.Usage = prometheus.NewDesc("cpu_usage", "CPU usage", nil, nil)
|
||||
d.CPU.SystemTime = prometheus.NewDesc("cpu_system_time", "CPU system time", nil, nil)
|
||||
d.CPU.IdleTime = prometheus.NewDesc("cpu_idle_time", "CPU idle time", nil, nil)
|
||||
d.Memory.Total = prometheus.NewDesc("memory_total", "Memory total", nil, nil)
|
||||
d.Memory.Used = prometheus.NewDesc("memory_used", "Memory used", nil, nil)
|
||||
d.Memory.UsedPercent = prometheus.NewDesc("memory_used_percent", "Memory used percent", nil, nil)
|
||||
d.Memory.Free = prometheus.NewDesc("memory_free", "Memory free", nil, nil)
|
||||
d.Disk.Total = prometheus.NewDesc("disk_total", "Disk total", nil, nil)
|
||||
d.Disk.Used = prometheus.NewDesc("disk_used", "Disk used", nil, nil)
|
||||
d.Disk.UsedPercent = prometheus.NewDesc("disk_used_percent", "Disk used percent", nil, nil)
|
||||
d.Disk.Free = prometheus.NewDesc("disk_free", "Disk free", nil, nil)
|
||||
d.Net.BytesSent = prometheus.NewDesc("net_bytes_sent", "Network bytes sent", nil, nil)
|
||||
d.Net.BytesRecv = prometheus.NewDesc("net_bytes_recv", "Network bytes received", nil, nil)
|
||||
d.Net.PacketsSent = prometheus.NewDesc("net_packets_sent", "Network packets sent", nil, nil)
|
||||
d.Net.PacketsRecv = prometheus.NewDesc("net_packets_recv", "Network packets received", nil, nil)
|
||||
d.Net.ErrsSent = prometheus.NewDesc("net_errs_sent", "Network errors sent", nil, nil)
|
||||
d.Net.ErrsRecv = prometheus.NewDesc("net_errs_recv", "Network errors received", nil, nil)
|
||||
d.Net.DroppedSent = prometheus.NewDesc("net_dropped_sent", "Network dropped sent", nil, nil)
|
||||
d.Net.DroppedRecv = prometheus.NewDesc("net_dropped_recv", "Network dropped received", nil, nil)
|
||||
d.BPS = prometheus.NewDesc("bps", "Bytes Per Second", []string{"streamPath", "pluginName", "trackType"}, nil)
|
||||
d.FPS = prometheus.NewDesc("fps", "Frames Per Second", []string{"streamPath", "pluginName", "trackType"}, nil)
|
||||
}
|
||||
|
||||
func (w *WaitStream) GetKey() string {
|
||||
return w.StreamPath
|
||||
}
|
||||
@@ -110,6 +153,7 @@ func NewServer(conf any) (s *Server) {
|
||||
"arch": sysruntime.GOARCH,
|
||||
"cpus": int32(sysruntime.NumCPU()),
|
||||
}
|
||||
s.prometheusDesc.init()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -147,10 +191,16 @@ func (s *Server) GetKey() uint32 {
|
||||
return s.ID
|
||||
}
|
||||
|
||||
type errLogger struct {
|
||||
}
|
||||
|
||||
func (l errLogger) Println(v ...interface{}) {
|
||||
slog.Error("Exporter promhttp err: ", v...)
|
||||
}
|
||||
|
||||
func (s *Server) Start() (err error) {
|
||||
s.Server = s
|
||||
s.handler = s
|
||||
//s.config.HTTP.ListenAddrTLS = ":8443"
|
||||
httpConf, tcpConf := &s.config.HTTP, &s.config.TCP
|
||||
httpConf.ListenAddr = ":8080"
|
||||
tcpConf.ListenAddr = ":50051"
|
||||
@@ -192,6 +242,7 @@ func (s *Server) Start() (err error) {
|
||||
s.Error("SetCrashOutput", "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
s.registerHandler(map[string]http.HandlerFunc{
|
||||
"/api/config/json/{name}": s.api_Config_JSON_,
|
||||
"/api/stream/annexb/{streamPath...}": s.api_Stream_AnnexB_,
|
||||
@@ -239,9 +290,25 @@ func (s *Server) Start() (err error) {
|
||||
s.AddTaskLazy(&s.Pushs)
|
||||
s.AddTaskLazy(&s.Transforms)
|
||||
s.AddTaskLazy(&s.Devices)
|
||||
promReg := prometheus.NewPedanticRegistry()
|
||||
promReg.MustRegister(s)
|
||||
for _, plugin := range plugins {
|
||||
plugin.Init(s, cg[strings.ToLower(plugin.Name)])
|
||||
p := plugin.Init(s, cg[strings.ToLower(plugin.Name)])
|
||||
if !p.Disabled {
|
||||
if collector, ok := p.handler.(prometheus.Collector); ok {
|
||||
promReg.MustRegister(collector)
|
||||
}
|
||||
}
|
||||
}
|
||||
promhttpHandler := promhttp.HandlerFor(prometheus.Gatherers{
|
||||
prometheus.DefaultGatherer,
|
||||
promReg,
|
||||
},
|
||||
promhttp.HandlerOpts{
|
||||
ErrorLog: errLogger{},
|
||||
ErrorHandling: promhttp.ContinueOnError,
|
||||
})
|
||||
s.handle("/api/metrics", promhttpHandler)
|
||||
if grpcServer != nil {
|
||||
s.AddTask(grpcServer, s.Logger)
|
||||
}
|
||||
@@ -332,3 +399,20 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
_, _ = fmt.Fprintf(w, "%s\n", api)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) Describe(ch chan<- *prometheus.Desc) {
|
||||
ch <- s.prometheusDesc.BPS
|
||||
ch <- s.prometheusDesc.FPS
|
||||
}
|
||||
|
||||
func (s *Server) Collect(ch chan<- prometheus.Metric) {
|
||||
s.Call(func() error {
|
||||
for stream := range s.Streams.Range {
|
||||
ch <- prometheus.MustNewConstMetric(s.prometheusDesc.BPS, prometheus.GaugeValue, float64(stream.VideoTrack.AVTrack.BPS), stream.StreamPath, stream.Plugin.Meta.Name, "video")
|
||||
ch <- prometheus.MustNewConstMetric(s.prometheusDesc.FPS, prometheus.GaugeValue, float64(stream.VideoTrack.AVTrack.FPS), stream.StreamPath, stream.Plugin.Meta.Name, "video")
|
||||
ch <- prometheus.MustNewConstMetric(s.prometheusDesc.BPS, prometheus.GaugeValue, float64(stream.AudioTrack.AVTrack.BPS), stream.StreamPath, stream.Plugin.Meta.Name, "audio")
|
||||
ch <- prometheus.MustNewConstMetric(s.prometheusDesc.FPS, prometheus.GaugeValue, float64(stream.AudioTrack.AVTrack.FPS), stream.StreamPath, stream.Plugin.Meta.Name, "audio")
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user