Added metrics for Prometheus.

This commit is contained in:
Сергей Петров 2025-03-31 11:03:17 +05:00
parent 84a29b5842
commit f0113fc53b
6 changed files with 169 additions and 176 deletions

View File

@ -2,6 +2,12 @@ package main
import ( import (
"fmt" "fmt"
"git.insit.tech/psa/rtsp_reader-writer/writer/internal/metrics"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/collectors"
"github.com/prometheus/client_golang/prometheus/promhttp"
"log"
"net/http"
"time" "time"
"git.insit.tech/psa/rtsp_reader-writer/writer/internal/config" "git.insit.tech/psa/rtsp_reader-writer/writer/internal/config"
@ -11,10 +17,25 @@ import (
) )
func main() { func main() {
// Регистрируем стандартные метрики
appRegistry := prometheus.NewRegistry()
appRegistry.MustRegister(collectors.NewGoCollector())
appRegistry.MustRegister(collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}))
appRegistry.MustRegister(metrics.ActiveCameras)
//// Эндпоинт для метрик
http.Handle("/metrics", promhttp.HandlerFor(appRegistry, promhttp.HandlerOpts{}))
config.LogsDirectory = log2.DirCreator(config.Local, "logs") config.LogsDirectory = log2.DirCreator(config.Local, "logs")
logger.Log = log2.MainLogging( logger.Log = log2.MainLogging(
fmt.Sprintf("%s/writer-main_%s.log", config.LogsDirectory, time.Now().Format("15-04-05_02-01-2006"))) fmt.Sprintf("%s/writer-main_%s.log", config.LogsDirectory, time.Now().Format("15-04-05_02-01-2006")))
rtsp.StartWriter() rtsp.StartWriter()
// Запуск сервера на порту 9110
err := http.ListenAndServe(":9110", nil)
if err != nil {
log.Println(err)
}
select {} select {}
} }

View File

@ -3,7 +3,7 @@ module git.insit.tech/psa/rtsp_reader-writer/writer
go 1.24.1 go 1.24.1
require ( require (
git.insit.tech/sas/rtsp_proxy v0.0.0-20250327104342-ec8a9640a1f9 git.insit.tech/sas/rtsp_proxy v0.0.0-20250328095933-2642c2a10d0c
github.com/Eyevinn/mp4ff v0.47.0 github.com/Eyevinn/mp4ff v0.47.0
github.com/bluenviron/gortsplib/v4 v4.12.3 github.com/bluenviron/gortsplib/v4 v4.12.3
github.com/bluenviron/mediacommon v1.14.0 github.com/bluenviron/mediacommon v1.14.0

View File

@ -1,7 +1,5 @@
git.insit.tech/sas/rtsp_proxy v0.0.0-20250326040356-446f7f0578d9 h1:8aOLn23rkkXR/mpkOtbaNrCWsiBs0Pl+/ds3CzUuHZo= git.insit.tech/sas/rtsp_proxy v0.0.0-20250328095933-2642c2a10d0c h1:eABK52LAFilOYqVViB7XRA+maacYIGe14NzKdWW+HV0=
git.insit.tech/sas/rtsp_proxy v0.0.0-20250326040356-446f7f0578d9/go.mod h1:/AHWd1Otr+ikOLWzpXtoozzifEx9ZKou+R6DgwaEzr0= git.insit.tech/sas/rtsp_proxy v0.0.0-20250328095933-2642c2a10d0c/go.mod h1:/AHWd1Otr+ikOLWzpXtoozzifEx9ZKou+R6DgwaEzr0=
git.insit.tech/sas/rtsp_proxy v0.0.0-20250327104342-ec8a9640a1f9 h1:VX17M9CHqtPbPrvR/24WlyxDyohy/AVsOxzFS6K5B7s=
git.insit.tech/sas/rtsp_proxy v0.0.0-20250327104342-ec8a9640a1f9/go.mod h1:/AHWd1Otr+ikOLWzpXtoozzifEx9ZKou+R6DgwaEzr0=
github.com/Eyevinn/mp4ff v0.47.0 h1:XSSHYt5+I0fyOnHWoNwM72DtivlmHFR0V9azgIi+ZVU= github.com/Eyevinn/mp4ff v0.47.0 h1:XSSHYt5+I0fyOnHWoNwM72DtivlmHFR0V9azgIi+ZVU=
github.com/Eyevinn/mp4ff v0.47.0/go.mod h1:hJNUUqOBryLAzUW9wpCJyw2HaI+TCd2rUPhafoS5lgg= github.com/Eyevinn/mp4ff v0.47.0/go.mod h1:hJNUUqOBryLAzUW9wpCJyw2HaI+TCd2rUPhafoS5lgg=
github.com/asticode/go-astikit v0.30.0/go.mod h1:h4ly7idim1tNhaVkdVBeXQZEE3L0xblP7fCWbgwipF0= github.com/asticode/go-astikit v0.30.0/go.mod h1:h4ly7idim1tNhaVkdVBeXQZEE3L0xblP7fCWbgwipF0=
@ -28,13 +26,10 @@ github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg=
github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
@ -61,12 +56,8 @@ github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGC
github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg= github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= 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/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k= github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k=
github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18= github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18=
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/prometheus/procfs v0.16.0 h1:xh6oHhKwnOJKMYiYBDWmkHqQPyiY40sny36Cmx2bbsM= github.com/prometheus/procfs v0.16.0 h1:xh6oHhKwnOJKMYiYBDWmkHqQPyiY40sny36Cmx2bbsM=
github.com/prometheus/procfs v0.16.0/go.mod h1:8veyXUu3nGP7oaCxhX6yeaM5u4stL2FeMXnCqhDthZg= github.com/prometheus/procfs v0.16.0/go.mod h1:8veyXUu3nGP7oaCxhX6yeaM5u4stL2FeMXnCqhDthZg=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
@ -87,14 +78,10 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=
google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@ -1,36 +1,36 @@
#camera_1: rtsp://intercom-video-1.insit.ru/camera01-centr-pl_slavy camera_1: rtsp://intercom-video-1.insit.ru/camera01-centr-pl_slavy
#camera_2: rtsp://intercom-video-1.insit.ru/camera03-centr-administraciya camera_2: rtsp://intercom-video-1.insit.ru/camera03-centr-administraciya
#camera_3: rtsp://intercom-video-1.insit.ru/camera08-centr-skver_kalinina camera_3: rtsp://intercom-video-1.insit.ru/camera08-centr-skver_kalinina
#camera_4: rtsp://intercom-video-1.insit.ru/camera04-centr-pobedy camera_4: rtsp://intercom-video-1.insit.ru/camera04-centr-pobedy
#camera_5: rtsp://intercom-video-1.insit.ru/camera11-centr-dk_kirova camera_5: rtsp://intercom-video-1.insit.ru/camera11-centr-dk_kirova
#camera_6: rtsp://intercom-video-1.insit.ru/camera13-centr-pobedy_sutyagina camera_6: rtsp://intercom-video-1.insit.ru/camera13-centr-pobedy_sutyagina
#camera_7: rtsp://intercom-video-1.insit.ru/camera09-centr-nalogovaya camera_7: rtsp://intercom-video-1.insit.ru/camera09-centr-nalogovaya
#camera_8: rtsp://intercom-video-1.insit.ru/camera59-centr-prktslavy camera_8: rtsp://intercom-video-1.insit.ru/camera59-centr-prktslavy
#camera_9: rtsp://intercom-video-1.insit.ru/camera10-centr-kommunisticheskiy_ilycha camera_9: rtsp://intercom-video-1.insit.ru/camera10-centr-kommunisticheskiy_ilycha
#camera_10: rtsp://intercom-video-1.insit.ru/camera16-centr-sportschool2 camera_10: rtsp://intercom-video-1.insit.ru/camera16-centr-sportschool2
#camera_11: rtsp://intercom-video-1.insit.ru/camera40-center-kommunisticheskiy camera_11: rtsp://intercom-video-1.insit.ru/camera40-center-kommunisticheskiy
#camera_12: rtsp://intercom-video-1.insit.ru/camera12-centr-skver_pavshih_geroev camera_12: rtsp://intercom-video-1.insit.ru/camera12-centr-skver_pavshih_geroev
#camera_13: rtsp://intercom-video-1.insit.ru/camera39-center-kommunisticheskiy camera_13: rtsp://intercom-video-1.insit.ru/camera39-center-kommunisticheskiy
#camera_14: rtsp://intercom-video-1.insit.ru/camera14-centr-stadion_himik camera_14: rtsp://intercom-video-1.insit.ru/camera14-centr-stadion_himik
#camera_15: rtsp://intercom-video-1.insit.ru/camera41-center-kuznecova_borby camera_15: rtsp://intercom-video-1.insit.ru/camera41-center-kuznecova_borby
#camera_16: rtsp://intercom-video-1.insit.ru/camera83-gorod-Kommunistichesky camera_16: rtsp://intercom-video-1.insit.ru/camera83-gorod-Kommunistichesky
camera_17: rtsp://intercom-video-1.insit.ru/camera54-centr-kirova-kalinina camera_17: rtsp://intercom-video-1.insit.ru/camera54-centr-kirova-kalinina
#camera_18: rtsp://intercom-video-1.insit.ru/camera53-centr-pobedy_slavy camera_18: rtsp://intercom-video-1.insit.ru/camera53-centr-pobedy_slavy
#camera_19: rtsp://intercom-video-1.insit.ru/camera44-center-skver_temnika camera_19: rtsp://intercom-video-1.insit.ru/camera44-center-skver_temnika
#camera_20: rtsp://intercom-video-1.insit.ru/camera28-oktyabrskiy-severnaya23a camera_20: rtsp://intercom-video-1.insit.ru/camera28-oktyabrskiy-severnaya23a
#camera_21: rtsp://intercom-video-1.insit.ru/dp-qamumnrlkizuypnetljzzkjqamdoti camera_21: rtsp://intercom-video-1.insit.ru/dp-qamumnrlkizuypnetljzzkjqamdoti
#camera_22: rtsp://intercom-video-1.insit.ru/dp-ohusuxzcvzsnpzzvkpyhddnwxuyeyc camera_22: rtsp://intercom-video-1.insit.ru/dp-ohusuxzcvzsnpzzvkpyhddnwxuyeyc
#camera_23: rtsp://intercom-video-1.insit.ru/dp-bflbwjulvgfzurmcpejklrfvqairns camera_23: rtsp://intercom-video-1.insit.ru/dp-bflbwjulvgfzurmcpejklrfvqairns
#camera_24: rtsp://intercom-video-1.insit.ru/dp-ajiymmjyytokybrpganfcxlfyjcdbgezphn camera_24: rtsp://intercom-video-1.insit.ru/dp-ajiymmjyytokybrpganfcxlfyjcdbgezphn
#camera_25: rtsp://intercom-video-2.insit.ru/dp-pobedi6a-ii-2125126423 camera_25: rtsp://intercom-video-2.insit.ru/dp-pobedi6a-ii-2125126423
#camera_26: rtsp://intercom-video-1.insit.ru/dp-pobedi11-ii-2108117729 camera_26: rtsp://intercom-video-1.insit.ru/dp-pobedi11-ii-2108117729
#camera_27: rtsp://intercom-video-2.insit.ru/dp-pobedi11-i-2108117197 camera_27: rtsp://intercom-video-2.insit.ru/dp-pobedi11-i-2108117197
#camera_28: rtsp://intercom-video-2.insit.ru/dp-nfhapwbfjpqkmaymfeipraxtzcpedk camera_28: rtsp://intercom-video-2.insit.ru/dp-nfhapwbfjpqkmaymfeipraxtzcpedk
#camera_29: rtsp://intercom-video-1.insit.ru/dp-swcixufwlheiwwrcvsrbkmhqzqvbxz camera_29: rtsp://intercom-video-1.insit.ru/dp-swcixufwlheiwwrcvsrbkmhqzqvbxz
#camera_30: rtsp://intercom-video-1.insit.ru/dp-nerrjszqrbhjvqmfxskunejafdiihj camera_30: rtsp://intercom-video-1.insit.ru/dp-nerrjszqrbhjvqmfxskunejafdiihj
#camera_31: rtsp://intercom-video-1.insit.ru/dp-aiwukyujwonohpjyzeniispqqullyr camera_31: rtsp://intercom-video-1.insit.ru/dp-aiwukyujwonohpjyzeniispqqullyr
#camera_32: rtsp://intercom-video-1.insit.ru/dp-woxvkbynctgfbuztsalttgburbpvjf camera_32: rtsp://intercom-video-1.insit.ru/dp-woxvkbynctgfbuztsalttgburbpvjf
#camera_33: rtsp://intercom-video-1.insit.ru/dp-fdzbasqehtptsuhxnjeqqnlrixfahcgvlcr camera_33: rtsp://intercom-video-1.insit.ru/dp-fdzbasqehtptsuhxnjeqqnlrixfahcgvlcr
#camera_34: rtsp://intercom-video-1.insit.ru/dp-exyeqscyamrbkwkjifagouyprtsdoe camera_34: rtsp://intercom-video-1.insit.ru/dp-exyeqscyamrbkwkjifagouyprtsdoe
#camera_35: rtsp://intercom-video-2.insit.ru/dp-sutyagina3a-iv-uujtwbsjekv camera_35: rtsp://intercom-video-2.insit.ru/dp-sutyagina3a-iv-uujtwbsjekv
#camera_36: rtsp://intercom-video-1.insit.ru/dp-wyshispseamhqmnhkqwkbarshnrvni camera_36: rtsp://intercom-video-1.insit.ru/dp-wyshispseamhqmnhkqwkbarshnrvni

View File

@ -13,6 +13,7 @@ import (
"git.insit.tech/psa/rtsp_reader-writer/writer/internal/config" "git.insit.tech/psa/rtsp_reader-writer/writer/internal/config"
"git.insit.tech/psa/rtsp_reader-writer/writer/internal/ingest/formats" "git.insit.tech/psa/rtsp_reader-writer/writer/internal/ingest/formats"
logger "git.insit.tech/psa/rtsp_reader-writer/writer/internal/log" logger "git.insit.tech/psa/rtsp_reader-writer/writer/internal/log"
"git.insit.tech/psa/rtsp_reader-writer/writer/internal/metrics"
"git.insit.tech/psa/rtsp_reader-writer/writer/pkg/storage" "git.insit.tech/psa/rtsp_reader-writer/writer/pkg/storage"
log2 "git.insit.tech/sas/rtsp_proxy/core/log" log2 "git.insit.tech/sas/rtsp_proxy/core/log"
"github.com/bluenviron/gortsplib/v4" "github.com/bluenviron/gortsplib/v4"
@ -48,6 +49,10 @@ func StartWriter() {
// rtsp processes RTSP protocol. // rtsp processes RTSP protocol.
func rtsp(dir string, period int, link string, number int) error { func rtsp(dir string, period int, link string, number int) error {
// Увеличиваем счетчик при старте обработки камеры
metrics.ActiveCameras.Inc()
defer metrics.ActiveCameras.Dec()
// Create data folder in the directory. // Create data folder in the directory.
dirData := log2.DirCreator(dir, "data") dirData := log2.DirCreator(dir, "data")
@ -278,8 +283,13 @@ func rtsp(dir string, period int, link string, number int) error {
}() }()
if err = c.Wait(); err != nil { if err = c.Wait(); err != nil {
rtsp(dir, period, link, fn.Number+1)
cam.Error("c.Wait() error:", zap.Error(c.Wait())) cam.Error("c.Wait() error:", zap.Error(c.Wait()))
logger.Log.Error("c.Wait() error for camera:", zap.String("camera:", link), zap.Error(c.Wait()))
go func() {
time.Sleep(40 * time.Second)
rtsp(dir, period, link, fn.Number+1)
}()
time.Sleep(1 * time.Second)
} }
case videoFormat == "" && audioFormat == "G711": case videoFormat == "" && audioFormat == "G711":
@ -366,9 +376,15 @@ func rtsp(dir string, period int, link string, number int) error {
*/ */
} }
}() }()
if err = c.Wait(); err != nil { if err = c.Wait(); err != nil {
rtsp(dir, period, link, fn.Number+1)
cam.Error("c.Wait() error:", zap.Error(c.Wait())) cam.Error("c.Wait() error:", zap.Error(c.Wait()))
logger.Log.Error("c.Wait() error for camera:", zap.String("camera:", link), zap.Error(c.Wait()))
go func() {
time.Sleep(40 * time.Second)
rtsp(dir, period, link, fn.Number+1)
}()
time.Sleep(1 * time.Second)
} }
case videoFormat == "H264" && audioFormat == "AAC": case videoFormat == "H264" && audioFormat == "AAC":
@ -486,8 +502,13 @@ func rtsp(dir string, period int, link string, number int) error {
}() }()
if err = c.Wait(); err != nil { if err = c.Wait(); err != nil {
rtsp(dir, period, link, fn.Number+1)
cam.Error("c.Wait() error:", zap.Error(c.Wait())) cam.Error("c.Wait() error:", zap.Error(c.Wait()))
logger.Log.Error("c.Wait() error for camera:", zap.String("camera:", link), zap.Error(c.Wait()))
go func() {
time.Sleep(40 * time.Second)
rtsp(dir, period, link, fn.Number+1)
}()
time.Sleep(1 * time.Second)
} }
case videoFormat == "H264" && audioFormat == "G711" || videoFormat == "H264" && audioFormat == "": case videoFormat == "H264" && audioFormat == "G711" || videoFormat == "H264" && audioFormat == "":
@ -502,11 +523,11 @@ func rtsp(dir string, period int, link string, number int) error {
return err return err
} }
g711RTPDec, err := g711Format.CreateDecoder() //g711RTPDec, err := g711Format.CreateDecoder()
if err != nil { //if err != nil {
cam.Error("create decoder error:", zap.Error(err)) // cam.Error("create decoder error:", zap.Error(err))
return err // return err
} //}
//// Setup MPEG-TS muxer. //// Setup MPEG-TS muxer.
//var aacFormat *format.MPEG4Audio //var aacFormat *format.MPEG4Audio
@ -561,7 +582,7 @@ func rtsp(dir string, period int, link string, number int) error {
// Process input rtp packets. // Process input rtp packets.
c.OnPacketRTPAny(func(medi *description.Media, forma format.Format, pkt *rtp.Packet) { c.OnPacketRTPAny(func(medi *description.Media, forma format.Format, pkt *rtp.Packet) {
switch f := forma.(type) { switch forma.(type) {
case *format.H264: case *format.H264:
// Process H264 flow and return PTS and AU. // Process H264 flow and return PTS and AU.
pts, au, err := formats.ProcessH264(&c, h264Media, h264RTPDec, pkt) pts, au, err := formats.ProcessH264(&c, h264Media, h264RTPDec, pkt)
@ -590,26 +611,26 @@ func rtsp(dir string, period int, link string, number int) error {
case *format.G711: case *format.G711:
// Process G711 flow and returns PTS and AU. // Process G711 flow and returns PTS and AU.
pts, au, err := formats.ProcessG711(&c, g711Media, g711RTPDec, pkt) //pts, au, err := formats.ProcessG711(&c, g711Media, g711RTPDec, pkt)
if err != nil { //if err != nil {
cam.Warn("process packet error:", zap.Error(err)) // cam.Warn("process packet error:", zap.Error(err))
} //}
//
if au != nil { //if au != nil {
// Convert G711 to LPCM. // // Convert G711 to LPCM.
lpcmSamples := formats.ConvertG711ToLPCM(au, f.MULaw) // lpcmSamples := formats.ConvertG711ToLPCM(au, f.MULaw)
//
// Add appropriate lines to the interleaved packet. // // Add appropriate lines to the interleaved packet.
seg.Packet.Type = storage.PacketTypeLPCM // seg.Packet.Type = storage.PacketTypeLPCM
seg.Packet.Pts = pts // seg.Packet.Pts = pts
seg.Packet.LPCMSamples = lpcmSamples // seg.Packet.LPCMSamples = lpcmSamples
//
// Write segment with interleaved packets. // // Write segment with interleaved packets.
if err := storage.WriteInterleavedPacket(file, seg); err != nil { // if err := storage.WriteInterleavedPacket(file, seg); err != nil {
cam.Error("write segment error:", zap.Error(err)) // cam.Error("write segment error:", zap.Error(err))
return // return
} // }
} //}
//// Convert G711 to AAC. //// Convert G711 to AAC.
//au, err = formats.ConvertLPCMToAAC(lpcmSamples) //au, err = formats.ConvertLPCMToAAC(lpcmSamples)
@ -710,8 +731,13 @@ func rtsp(dir string, period int, link string, number int) error {
}() }()
if err = c.Wait(); err != nil { if err = c.Wait(); err != nil {
rtsp(dir, period, link, fn.Number+1)
cam.Error("c.Wait() error:", zap.Error(c.Wait())) cam.Error("c.Wait() error:", zap.Error(c.Wait()))
logger.Log.Error("c.Wait() error for camera:", zap.String("camera:", link), zap.Error(c.Wait()))
go func() {
time.Sleep(40 * time.Second)
rtsp(dir, period, link, fn.Number+1)
}()
time.Sleep(1 * time.Second)
} }
case videoFormat == "H264-" && audioFormat == "": case videoFormat == "H264-" && audioFormat == "":
@ -813,8 +839,13 @@ func rtsp(dir string, period int, link string, number int) error {
}() }()
if err = c.Wait(); err != nil { if err = c.Wait(); err != nil {
rtsp(dir, period, link, fn.Number+1)
cam.Error("c.Wait() error:", zap.Error(c.Wait())) cam.Error("c.Wait() error:", zap.Error(c.Wait()))
logger.Log.Error("c.Wait() error for camera:", zap.String("camera:", link), zap.Error(c.Wait()))
go func() {
time.Sleep(40 * time.Second)
rtsp(dir, period, link, fn.Number+1)
}()
time.Sleep(1 * time.Second)
} }
case videoFormat == "H265" && audioFormat == "": case videoFormat == "H265" && audioFormat == "":
@ -918,8 +949,13 @@ func rtsp(dir string, period int, link string, number int) error {
}() }()
if err = c.Wait(); err != nil { if err = c.Wait(); err != nil {
rtsp(dir, period, link, fn.Number+1)
cam.Error("c.Wait() error:", zap.Error(c.Wait())) cam.Error("c.Wait() error:", zap.Error(c.Wait()))
logger.Log.Error("c.Wait() error for camera:", zap.String("camera:", link), zap.Error(c.Wait()))
go func() {
time.Sleep(40 * time.Second)
rtsp(dir, period, link, fn.Number+1)
}()
time.Sleep(1 * time.Second)
} }
case videoFormat == "" && audioFormat == "LPCM": case videoFormat == "" && audioFormat == "LPCM":
@ -1001,8 +1037,13 @@ func rtsp(dir string, period int, link string, number int) error {
}() }()
if err = c.Wait(); err != nil { if err = c.Wait(); err != nil {
rtsp(dir, period, link, fn.Number+1)
cam.Error("c.Wait() error:", zap.Error(c.Wait())) cam.Error("c.Wait() error:", zap.Error(c.Wait()))
logger.Log.Error("c.Wait() error for camera:", zap.String("camera:", link), zap.Error(c.Wait()))
go func() {
time.Sleep(40 * time.Second)
rtsp(dir, period, link, fn.Number+1)
}()
time.Sleep(1 * time.Second)
} }
case videoFormat == "MJPEG" && audioFormat == "": case videoFormat == "MJPEG" && audioFormat == "":
@ -1084,8 +1125,13 @@ func rtsp(dir string, period int, link string, number int) error {
}() }()
if err = c.Wait(); err != nil { if err = c.Wait(); err != nil {
rtsp(dir, period, link, fn.Number+1)
cam.Error("c.Wait() error:", zap.Error(c.Wait())) cam.Error("c.Wait() error:", zap.Error(c.Wait()))
logger.Log.Error("c.Wait() error for camera:", zap.String("camera:", link), zap.Error(c.Wait()))
go func() {
time.Sleep(40 * time.Second)
rtsp(dir, period, link, fn.Number+1)
}()
time.Sleep(1 * time.Second)
} }
case videoFormat == "" && audioFormat == "AAC": case videoFormat == "" && audioFormat == "AAC":
@ -1169,8 +1215,13 @@ func rtsp(dir string, period int, link string, number int) error {
}() }()
if err = c.Wait(); err != nil { if err = c.Wait(); err != nil {
rtsp(dir, period, link, fn.Number+1)
cam.Error("c.Wait() error:", zap.Error(c.Wait())) cam.Error("c.Wait() error:", zap.Error(c.Wait()))
logger.Log.Error("c.Wait() error for camera:", zap.String("camera:", link), zap.Error(c.Wait()))
go func() {
time.Sleep(40 * time.Second)
rtsp(dir, period, link, fn.Number+1)
}()
time.Sleep(1 * time.Second)
} }
case videoFormat == "" && audioFormat == "OPUS": case videoFormat == "" && audioFormat == "OPUS":
@ -1252,8 +1303,13 @@ func rtsp(dir string, period int, link string, number int) error {
}() }()
if err = c.Wait(); err != nil { if err = c.Wait(); err != nil {
rtsp(dir, period, link, fn.Number+1)
cam.Error("c.Wait() error:", zap.Error(c.Wait())) cam.Error("c.Wait() error:", zap.Error(c.Wait()))
logger.Log.Error("c.Wait() error for camera:", zap.String("camera:", link), zap.Error(c.Wait()))
go func() {
time.Sleep(40 * time.Second)
rtsp(dir, period, link, fn.Number+1)
}()
time.Sleep(1 * time.Second)
} }
case videoFormat == "VP8" && audioFormat == "": case videoFormat == "VP8" && audioFormat == "":
@ -1344,8 +1400,13 @@ func rtsp(dir string, period int, link string, number int) error {
}() }()
if err = c.Wait(); err != nil { if err = c.Wait(); err != nil {
rtsp(dir, period, link, fn.Number+1)
cam.Error("c.Wait() error:", zap.Error(c.Wait())) cam.Error("c.Wait() error:", zap.Error(c.Wait()))
logger.Log.Error("c.Wait() error for camera:", zap.String("camera:", link), zap.Error(c.Wait()))
go func() {
time.Sleep(40 * time.Second)
rtsp(dir, period, link, fn.Number+1)
}()
time.Sleep(1 * time.Second)
} }
case videoFormat == "VP9" && audioFormat == "": case videoFormat == "VP9" && audioFormat == "":
@ -1436,8 +1497,13 @@ func rtsp(dir string, period int, link string, number int) error {
}() }()
if err = c.Wait(); err != nil { if err = c.Wait(); err != nil {
rtsp(dir, period, link, fn.Number+1)
cam.Error("c.Wait() error:", zap.Error(c.Wait())) cam.Error("c.Wait() error:", zap.Error(c.Wait()))
logger.Log.Error("c.Wait() error for camera:", zap.String("camera:", link), zap.Error(c.Wait()))
go func() {
time.Sleep(40 * time.Second)
rtsp(dir, period, link, fn.Number+1)
}()
time.Sleep(1 * time.Second)
} }
} }

View File

@ -1,89 +1,8 @@
package metrics package metrics
import ( import "github.com/prometheus/client_golang/prometheus"
"net/http"
"runtime"
"github.com/prometheus/client_golang/prometheus" var ActiveCameras = prometheus.NewGauge(prometheus.GaugeOpts{
"github.com/prometheus/client_golang/prometheus/collectors" Name: "active_rtsp_cameras_total",
"github.com/prometheus/client_golang/prometheus/promhttp" Help: "Количество активных rtsp потоков (работающих горутин) для камер.",
) })
//// Пользовательские метрики
//var (
// rtspConnectSuccess = prometheus.NewCounter(prometheus.CounterOpts{
// Name: "rtsp_connect_success_total",
// Help: "Количество успешных подключений к RTSP источнику.",
// })
// rtspConnectErrors = prometheus.NewCounter(prometheus.CounterOpts{
// Name: "rtsp_connect_errors_total",
// Help: "Количество ошибок подключения к RTSP источнику.",
// })
// rtspBytesRead = prometheus.NewCounter(prometheus.CounterOpts{
// Name: "rtsp_bytes_read_total",
// Help: "Общее количество байт, прочитанных из RTSP-потоков.",
// })
// funcDuration = prometheus.NewHistogramVec(prometheus.HistogramOpts{
// Name: "function_execution_seconds",
// Help: "Время выполнения функций приложения.",
// Buckets: prometheus.DefBuckets,
// }, []string{"function"})
//)
func init() {
// Регистрируем стандартные метрики Go
prometheus.MustRegister(collectors.NewGoCollector())
prometheus.MustRegister(collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}))
//// Регистрируем пользовательские метрики
//prometheus.MustRegister(rtspConnectSuccess)
//prometheus.MustRegister(rtspConnectErrors)
//prometheus.MustRegister(rtspBytesRead)
//prometheus.MustRegister(funcDuration)
}
//func processStream() {
// timer := prometheus.NewTimer(funcDuration.WithLabelValues("processStream"))
// defer timer.ObserveDuration()
//
// // Пример: имитация подключения к RTSP
// if err := connectToRTSP(); err != nil {
// rtspConnectErrors.Inc()
// return
// }
// rtspConnectSuccess.Inc()
//
// // Пример: чтение данных
// n := readRTSPData()
// rtspBytesRead.Add(float64(n))
//}
//func connectToRTSP() error {
// // Логика подключения (пример)
// return nil // или вернуть ошибку
//}
//func readRTSPData() int {
// // Логика чтения данных (пример)
// // Для демонстрации можно вернуть случайное значение
// return 1024
//}
func metricsHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
// Дополнительно можно вывести информацию о количестве горутин
w.Write([]byte("Goroutines: "))
w.Write([]byte(string(runtime.NumGoroutine())))
}
func Metrics() {
// Эндпоинт для метрик Prometheus
http.Handle("/metrics", promhttp.Handler())
// Остальные эндпоинты вашего приложения
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
//processStream()
w.Write([]byte("Processing stream..."))
})
http.ListenAndServe(":9100", nil)
}