Skip to content

Commit

Permalink
Merge pull request #1 from voc/master
Browse files Browse the repository at this point in the history
Marge upstream
  • Loading branch information
hanatyan128 authored Jan 12, 2025
2 parents 7e937d1 + 9bc8c37 commit 98f43de
Show file tree
Hide file tree
Showing 24 changed files with 538 additions and 100 deletions.
10 changes: 10 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: 2
updates:
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "monthly"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ jobs:
build:
runs-on: "ubuntu-22.04"
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Set up Go
uses: actions/setup-go@v2
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
with:
go-version: 1.18
go-version: 1.23

- name: Install dependencies
run: ./scripts/install-dependencies.sh
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,26 @@ jobs:
runs-on: "ubuntu-latest"
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0

- name: Login to Github Packages
uses: docker/login-action@v1
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push
id: docker_build
uses: docker/build-push-action@v2
uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 # v6.10.0
with:
push: true
tags: ghcr.io/voc/srtrelay/srtrelay:latest

- name: Delete old containers
uses: actions/delete-package-versions@v4
uses: actions/delete-package-versions@e5bc658cc4c965c472efe991f8beea3981499c55 # v5.0.0
with:
package-name: 'srtrelay'
package-name: 'srtrelay/srtrelay'
package-type: 'container'
min-versions-to-keep: 10
delete-only-untagged-versions: 'true'
36 changes: 36 additions & 0 deletions .github/workflows/golangci-lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
name: golangci-lint
on:
push:
paths:
- "go.sum"
- "go.mod"
- "**.go"
- ".github/workflows/golangci-lint.yml"
- ".golangci.yml"
pull_request:

permissions: # added using https://github.com/step-security/secure-repo
contents: read

jobs:
golangci:
permissions:
contents: read # for actions/checkout to fetch code
pull-requests: read # for golangci/golangci-lint-action to fetch pull requests
name: lint
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install Go
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
with:
go-version: 1.23.x
- name: Install dependencies
run: ./scripts/install-dependencies.sh
- name: Lint
uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 # v6.1.1
with:
args: --verbose
version: v1.62.0
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
srtrelay
config.toml
/.vscode
# VSCode
/.vscode
# Jetbrains
/.idea
*.iml
11 changes: 11 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
linters:
enable:
- goimports
- misspell

issues:
exclude-rules:
- path: _test.go
linters:
- errcheck
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# syntax=docker/dockerfile:1
FROM golang:1.18-bullseye AS build
FROM golang:1.23-bookworm AS build

RUN apt-get update && \
apt-get upgrade -y && \
Expand All @@ -24,10 +24,10 @@ ARG TARGETARCH
RUN GOOS=linux GOARCH=$TARGETARCH go build -ldflags="-w -s" -v -o srtrelay .

# clean start
FROM debian:bullseye
FROM debian:bookworm
RUN apt-get update && \
apt-get upgrade -y && \
apt-get install --no-install-recommends -y libssl1.1 && \
apt-get install --no-install-recommends -y libssl3 && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
RUN useradd -l -m -r srtrelay
Expand Down
5 changes: 2 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
.PHONY: srtrelay
srtrelay:
HOME=$$(pwd) git config --global http.sslVerify false
mkdir -p $$(pwd)/gopath
HOME=$$(pwd) GOPATH=$$(pwd)/gopath go build -o srtrelay
go build -o srtrelay

install: srtrelay
mkdir -p $$(pwd)/debian/srtrelay/usr/bin
Expand Down
202 changes: 202 additions & 0 deletions api/metrics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
package api

import (
"github.com/voc/srtrelay/internal/metrics"
"github.com/voc/srtrelay/srt"

"github.com/prometheus/client_golang/prometheus"
)

const srtSubsystem = "srt"

var (
activeSocketsDesc = prometheus.NewDesc(
prometheus.BuildFQName(metrics.Namespace, srtSubsystem, "active_sockets"),
"The number of active SRT sockets",
nil, nil,
)

// Metrics from: https://pkg.go.dev/github.com/haivision/srtgo#SrtStats
pktSentTotalDesc = prometheus.NewDesc(
prometheus.BuildFQName(metrics.Namespace, srtSubsystem, "sent_packets_total"),
"total number of sent data packets, including retransmissions",
[]string{"address", "stream_id"}, nil,
)

pktRecvTotalDesc = prometheus.NewDesc(
prometheus.BuildFQName(metrics.Namespace, srtSubsystem, "receive_packets_total"),
"total number of received packets",
[]string{"address", "stream_id"}, nil,
)

pktSndLossTotalDesc = prometheus.NewDesc(
prometheus.BuildFQName(metrics.Namespace, srtSubsystem, "sent_lost_packets_total"),
"total number of lost packets (sender side)",
[]string{"address", "stream_id"}, nil,
)

pktRcvLossTotalDesc = prometheus.NewDesc(
prometheus.BuildFQName(metrics.Namespace, srtSubsystem, "receive_lost_packets_total"),
"total number of lost packets (receive_side)",
[]string{"address", "stream_id"}, nil,
)

pktRetransTotalDesc = prometheus.NewDesc(
prometheus.BuildFQName(metrics.Namespace, srtSubsystem, "retransmitted_packets_total"),
"total number of retransmitted packets",
[]string{"address", "stream_id"}, nil,
)

pktSentACKTotalDesc = prometheus.NewDesc(
prometheus.BuildFQName(metrics.Namespace, srtSubsystem, "sent_ack_packets_total"),
"total number of sent ACK packets",
[]string{"address", "stream_id"}, nil,
)

pktRecvACKTotalDesc = prometheus.NewDesc(
prometheus.BuildFQName(metrics.Namespace, srtSubsystem, "receive_ack_packets_total"),
"total number of received ACK packets",
[]string{"address", "stream_id"}, nil,
)

pktSentNAKTotalDesc = prometheus.NewDesc(
prometheus.BuildFQName(metrics.Namespace, srtSubsystem, "sent_nak_packets_total"),
"total number of received NAK packets",
[]string{"address", "stream_id"}, nil,
)

pktRecvNAKTotalDesc = prometheus.NewDesc(
prometheus.BuildFQName(metrics.Namespace, srtSubsystem, "receive_nak_packets_total"),
"total number of received NAK packets",
[]string{"address", "stream_id"}, nil,
)

sndDurationTotalDesc = prometheus.NewDesc(
prometheus.BuildFQName(metrics.Namespace, srtSubsystem, "udt_sent_duration_seconds_total"),
"total time duration when UDT is sending data (idle time exclusive)",
[]string{"address", "stream_id"}, nil,
)

pktSndDropTotalDesc = prometheus.NewDesc(
prometheus.BuildFQName(metrics.Namespace, srtSubsystem, "sent_dropped_packets_total"),
"number of too-late-to-send dropped packets",
[]string{"address", "stream_id"}, nil,
)

pktRcvDropTotalDesc = prometheus.NewDesc(
prometheus.BuildFQName(metrics.Namespace, srtSubsystem, "receive_dropped_packets_total"),
"number of too-late-to play missing packets",
[]string{"address", "stream_id"}, nil,
)

pktRcvUndecryptTotalDesc = prometheus.NewDesc(
prometheus.BuildFQName(metrics.Namespace, srtSubsystem, "receive_undecrypted_packets_total"),
"number of undecrypted packets",
[]string{"address", "stream_id"}, nil,
)

byteSentTotalDesc = prometheus.NewDesc(
prometheus.BuildFQName(metrics.Namespace, srtSubsystem, "sent_bytes_total"),
"total number of sent data bytes, including retransmissions",
[]string{"address", "stream_id"}, nil,
)

byteRecvTotalDesc = prometheus.NewDesc(
prometheus.BuildFQName(metrics.Namespace, srtSubsystem, "receive_bytes_total"),
"total number of received bytes",
[]string{"address", "stream_id"}, nil,
)

byteRcvLossTotalDesc = prometheus.NewDesc(
prometheus.BuildFQName(metrics.Namespace, srtSubsystem, "receive_lost_bytes_total"),
"total number of lost bytes",
[]string{"address", "stream_id"}, nil,
)

byteRetransTotalDesc = prometheus.NewDesc(
prometheus.BuildFQName(metrics.Namespace, srtSubsystem, "retransmitted_bytes_total"),
"total number of retransmitted bytes",
[]string{"address", "stream_id"}, nil,
)

byteSndDropTotalDesc = prometheus.NewDesc(
prometheus.BuildFQName(metrics.Namespace, srtSubsystem, "sent_dropped_bytes_total"),
"number of too-late-to-send dropped bytes",
[]string{"address", "stream_id"}, nil,
)

byteRcvDropTotalDesc = prometheus.NewDesc(
prometheus.BuildFQName(metrics.Namespace, srtSubsystem, "receive_dropped_bytes_total"),
"number of too-late-to play missing bytes (estimate based on average packet size)",
[]string{"address", "stream_id"}, nil,
)

byteRcvUndecryptTotalDesc = prometheus.NewDesc(
prometheus.BuildFQName(metrics.Namespace, srtSubsystem, "receive_undecrypted_bytes_total"),
"number of undecrypted bytes",
[]string{"address", "stream_id"}, nil,
)
)

// Exporter collects metrics. It implements prometheus.Collector.
type Exporter struct {
server srt.Server
}

func NewExporter(s srt.Server) *Exporter {
e := Exporter{server: s}
return &e
}

// Describe implements prometheus.Collector.
func (e *Exporter) Describe(ch chan<- *prometheus.Desc) {
ch <- activeSocketsDesc
ch <- pktSentTotalDesc
ch <- pktRecvTotalDesc
ch <- pktSndLossTotalDesc
ch <- pktRcvLossTotalDesc
ch <- pktRetransTotalDesc
ch <- pktSentACKTotalDesc
ch <- pktRecvACKTotalDesc
ch <- pktSentNAKTotalDesc
ch <- pktRecvNAKTotalDesc
ch <- sndDurationTotalDesc
ch <- pktSndDropTotalDesc
ch <- pktRcvDropTotalDesc
ch <- pktRcvUndecryptTotalDesc
ch <- byteSentTotalDesc
ch <- byteRecvTotalDesc
ch <- byteRcvLossTotalDesc
ch <- byteRetransTotalDesc
ch <- byteSndDropTotalDesc
ch <- byteRcvDropTotalDesc
ch <- byteRcvUndecryptTotalDesc
}

// Collect implements prometheus.Collector.
func (e *Exporter) Collect(ch chan<- prometheus.Metric) {
stats := e.server.GetSocketStatistics()
ch <- prometheus.MustNewConstMetric(activeSocketsDesc, prometheus.GaugeValue, float64(len(stats)))
for _, stat := range stats {
ch <- prometheus.MustNewConstMetric(pktSentTotalDesc, prometheus.CounterValue, float64(stat.Stats.PktSentTotal), stat.Address, stat.StreamID)
ch <- prometheus.MustNewConstMetric(pktRecvTotalDesc, prometheus.CounterValue, float64(stat.Stats.PktRecvTotal), stat.Address, stat.StreamID)
ch <- prometheus.MustNewConstMetric(pktSndLossTotalDesc, prometheus.CounterValue, float64(stat.Stats.PktSndLossTotal), stat.Address, stat.StreamID)
ch <- prometheus.MustNewConstMetric(pktRcvLossTotalDesc, prometheus.CounterValue, float64(stat.Stats.PktRcvLossTotal), stat.Address, stat.StreamID)
ch <- prometheus.MustNewConstMetric(pktRetransTotalDesc, prometheus.CounterValue, float64(stat.Stats.PktRetransTotal), stat.Address, stat.StreamID)
ch <- prometheus.MustNewConstMetric(pktSentACKTotalDesc, prometheus.CounterValue, float64(stat.Stats.PktSentACKTotal), stat.Address, stat.StreamID)
ch <- prometheus.MustNewConstMetric(pktRecvACKTotalDesc, prometheus.CounterValue, float64(stat.Stats.PktRecvACKTotal), stat.Address, stat.StreamID)
ch <- prometheus.MustNewConstMetric(pktSentNAKTotalDesc, prometheus.CounterValue, float64(stat.Stats.PktSentNAKTotal), stat.Address, stat.StreamID)
ch <- prometheus.MustNewConstMetric(pktRecvNAKTotalDesc, prometheus.CounterValue, float64(stat.Stats.PktRecvNAKTotal), stat.Address, stat.StreamID)
ch <- prometheus.MustNewConstMetric(sndDurationTotalDesc, prometheus.CounterValue, float64(stat.Stats.UsSndDurationTotal)/1_000_000.0, stat.Address, stat.StreamID)
ch <- prometheus.MustNewConstMetric(pktSndDropTotalDesc, prometheus.CounterValue, float64(stat.Stats.PktSndDropTotal), stat.Address, stat.StreamID)
ch <- prometheus.MustNewConstMetric(pktRcvDropTotalDesc, prometheus.CounterValue, float64(stat.Stats.PktRcvDropTotal), stat.Address, stat.StreamID)
ch <- prometheus.MustNewConstMetric(pktRcvUndecryptTotalDesc, prometheus.CounterValue, float64(stat.Stats.PktRcvUndecryptTotal), stat.Address, stat.StreamID)
ch <- prometheus.MustNewConstMetric(byteSentTotalDesc, prometheus.CounterValue, float64(stat.Stats.ByteSentTotal), stat.Address, stat.StreamID)
ch <- prometheus.MustNewConstMetric(byteRecvTotalDesc, prometheus.CounterValue, float64(stat.Stats.ByteRecvTotal), stat.Address, stat.StreamID)
ch <- prometheus.MustNewConstMetric(byteRcvLossTotalDesc, prometheus.CounterValue, float64(stat.Stats.ByteRcvLossTotal), stat.Address, stat.StreamID)
ch <- prometheus.MustNewConstMetric(byteRetransTotalDesc, prometheus.CounterValue, float64(stat.Stats.ByteRetransTotal), stat.Address, stat.StreamID)
ch <- prometheus.MustNewConstMetric(byteSndDropTotalDesc, prometheus.CounterValue, float64(stat.Stats.ByteSndDropTotal), stat.Address, stat.StreamID)
ch <- prometheus.MustNewConstMetric(byteRcvDropTotalDesc, prometheus.CounterValue, float64(stat.Stats.ByteRcvDropTotal), stat.Address, stat.StreamID)
ch <- prometheus.MustNewConstMetric(byteRcvUndecryptTotalDesc, prometheus.CounterValue, float64(stat.Stats.ByteRcvUndecryptTotal), stat.Address, stat.StreamID)
}
}
9 changes: 8 additions & 1 deletion api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@ package api
import (
"context"
"encoding/json"
"errors"
"log"
"net/http"
"sync"
"time"

"github.com/voc/srtrelay/config"
"github.com/voc/srtrelay/srt"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)

// Server serves HTTP API requests
Expand All @@ -20,6 +24,8 @@ type Server struct {
}

func NewServer(conf config.APIConfig, srtServer srt.Server) *Server {
prometheus.MustRegister(NewExporter(srtServer))
log.Println("Registered server metrics")
return &Server{
conf: conf,
srtServer: srtServer,
Expand All @@ -30,6 +36,7 @@ func (s *Server) Listen(ctx context.Context) error {
mux := http.NewServeMux()
mux.HandleFunc("/streams", s.HandleStreams)
mux.HandleFunc("/sockets", s.HandleSockets)
mux.Handle("/metrics", promhttp.Handler())
serv := &http.Server{
Addr: s.conf.Address,
Handler: mux,
Expand All @@ -43,7 +50,7 @@ func (s *Server) Listen(ctx context.Context) error {
go func() {
defer s.done.Done()
err := serv.ListenAndServe()
if err != nil && err != http.ErrServerClosed {
if err != nil && !errors.Is(err, http.ErrServerClosed) {
log.Println(err)
}
}()
Expand Down
Loading

0 comments on commit 98f43de

Please sign in to comment.