mirror of
https://github.com/netdata/netdata.git
synced 2025-04-26 13:54:48 +00:00
go.d icecast single source response (#18195)
This commit is contained in:
parent
4e2076d8b1
commit
073e2d4110
6 changed files with 116 additions and 25 deletions
src/go/plugin/go.d/modules/icecast
|
@ -11,19 +11,6 @@ import (
|
||||||
"github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/web"
|
"github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/web"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
serverStats struct {
|
|
||||||
IceStats *struct {
|
|
||||||
Source []sourceStats `json:"source"`
|
|
||||||
} `json:"icestats"`
|
|
||||||
}
|
|
||||||
sourceStats struct {
|
|
||||||
ServerName string `json:"server_name"`
|
|
||||||
StreamStart string `json:"stream_start"`
|
|
||||||
Listeners int64 `json:"listeners"`
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
urlPathServerStats = "/status-json.xsl" // https://icecast.org/docs/icecast-trunk/server_stats/
|
urlPathServerStats = "/status-json.xsl" // https://icecast.org/docs/icecast-trunk/server_stats/
|
||||||
)
|
)
|
||||||
|
|
|
@ -19,16 +19,18 @@ var (
|
||||||
dataConfigJSON, _ = os.ReadFile("testdata/config.json")
|
dataConfigJSON, _ = os.ReadFile("testdata/config.json")
|
||||||
dataConfigYAML, _ = os.ReadFile("testdata/config.yaml")
|
dataConfigYAML, _ = os.ReadFile("testdata/config.yaml")
|
||||||
|
|
||||||
dataServerStats, _ = os.ReadFile("testdata/server_stats.json")
|
dataServerStatsMultiSource, _ = os.ReadFile("testdata/stats_multi_source.json")
|
||||||
dataServerStatsNoSources, _ = os.ReadFile("testdata/server_stats_no_sources.json")
|
dataServerStatsSingleSource, _ = os.ReadFile("testdata/stats_single_source.json")
|
||||||
|
dataServerStatsNoSources, _ = os.ReadFile("testdata/stats_no_sources.json")
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_testDataIsValid(t *testing.T) {
|
func Test_testDataIsValid(t *testing.T) {
|
||||||
for name, data := range map[string][]byte{
|
for name, data := range map[string][]byte{
|
||||||
"dataConfigJSON": dataConfigJSON,
|
"dataConfigJSON": dataConfigJSON,
|
||||||
"dataConfigYAML": dataConfigYAML,
|
"dataConfigYAML": dataConfigYAML,
|
||||||
"dataServerStats": dataServerStats,
|
"dataServerStats": dataServerStatsMultiSource,
|
||||||
"dataServerStatsNoSources": dataServerStatsNoSources,
|
"dataServerStatsSingleSource": dataServerStatsSingleSource,
|
||||||
|
"dataServerStatsNoSources": dataServerStatsNoSources,
|
||||||
} {
|
} {
|
||||||
require.NotNil(t, data, name)
|
require.NotNil(t, data, name)
|
||||||
}
|
}
|
||||||
|
@ -80,9 +82,13 @@ func TestIcecast_Check(t *testing.T) {
|
||||||
wantFail bool
|
wantFail bool
|
||||||
prepare func(t *testing.T) (*Icecast, func())
|
prepare func(t *testing.T) (*Icecast, func())
|
||||||
}{
|
}{
|
||||||
"success default config": {
|
"success multiple sources": {
|
||||||
wantFail: false,
|
wantFail: false,
|
||||||
prepare: prepareCaseOk,
|
prepare: prepareCaseMultipleSources,
|
||||||
|
},
|
||||||
|
"success single source": {
|
||||||
|
wantFail: false,
|
||||||
|
prepare: prepareCaseMultipleSources,
|
||||||
},
|
},
|
||||||
"fails on no sources": {
|
"fails on no sources": {
|
||||||
wantFail: true,
|
wantFail: true,
|
||||||
|
@ -122,14 +128,21 @@ func TestIcecast_Collect(t *testing.T) {
|
||||||
wantMetrics map[string]int64
|
wantMetrics map[string]int64
|
||||||
wantCharts int
|
wantCharts int
|
||||||
}{
|
}{
|
||||||
"success default config": {
|
"success multiple sources": {
|
||||||
prepare: prepareCaseOk,
|
prepare: prepareCaseMultipleSources,
|
||||||
wantCharts: len(sourceChartsTmpl) * 2,
|
wantCharts: len(sourceChartsTmpl) * 2,
|
||||||
wantMetrics: map[string]int64{
|
wantMetrics: map[string]int64{
|
||||||
"source_abc_listeners": 1,
|
"source_abc_listeners": 1,
|
||||||
"source_efg_listeners": 10,
|
"source_efg_listeners": 10,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"success single source": {
|
||||||
|
prepare: prepareCaseSingleSource,
|
||||||
|
wantCharts: len(sourceChartsTmpl) * 1,
|
||||||
|
wantMetrics: map[string]int64{
|
||||||
|
"source_abc_listeners": 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
"fails on no sources": {
|
"fails on no sources": {
|
||||||
prepare: prepareCaseNoSources,
|
prepare: prepareCaseNoSources,
|
||||||
},
|
},
|
||||||
|
@ -160,13 +173,32 @@ func TestIcecast_Collect(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareCaseOk(t *testing.T) (*Icecast, func()) {
|
func prepareCaseMultipleSources(t *testing.T) (*Icecast, func()) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
srv := httptest.NewServer(http.HandlerFunc(
|
srv := httptest.NewServer(http.HandlerFunc(
|
||||||
func(w http.ResponseWriter, r *http.Request) {
|
func(w http.ResponseWriter, r *http.Request) {
|
||||||
switch r.URL.Path {
|
switch r.URL.Path {
|
||||||
case urlPathServerStats:
|
case urlPathServerStats:
|
||||||
_, _ = w.Write(dataServerStats)
|
_, _ = w.Write(dataServerStatsMultiSource)
|
||||||
|
default:
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
icecast := New()
|
||||||
|
icecast.URL = srv.URL
|
||||||
|
require.NoError(t, icecast.Init())
|
||||||
|
|
||||||
|
return icecast, srv.Close
|
||||||
|
}
|
||||||
|
|
||||||
|
func prepareCaseSingleSource(t *testing.T) (*Icecast, func()) {
|
||||||
|
t.Helper()
|
||||||
|
srv := httptest.NewServer(http.HandlerFunc(
|
||||||
|
func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
switch r.URL.Path {
|
||||||
|
case urlPathServerStats:
|
||||||
|
_, _ = w.Write(dataServerStatsSingleSource)
|
||||||
default:
|
default:
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
}
|
}
|
||||||
|
|
45
src/go/plugin/go.d/modules/icecast/server_stats.go
Normal file
45
src/go/plugin/go.d/modules/icecast/server_stats.go
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
package icecast
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
serverStats struct {
|
||||||
|
IceStats *struct {
|
||||||
|
Source iceSource `json:"source"`
|
||||||
|
} `json:"icestats"`
|
||||||
|
}
|
||||||
|
iceSource []sourceStats
|
||||||
|
sourceStats struct {
|
||||||
|
ServerName string `json:"server_name"`
|
||||||
|
StreamStart string `json:"stream_start"`
|
||||||
|
Listeners int64 `json:"listeners"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (i *iceSource) UnmarshalJSON(data []byte) error {
|
||||||
|
var v any
|
||||||
|
if err := json.Unmarshal(data, &v); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch v.(type) {
|
||||||
|
case []any:
|
||||||
|
type plain iceSource
|
||||||
|
return json.Unmarshal(data, (*plain)(i))
|
||||||
|
case map[string]any:
|
||||||
|
var s sourceStats
|
||||||
|
if err := json.Unmarshal(data, &s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*i = []sourceStats{s}
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("invalid source data type: expected array or object")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
27
src/go/plugin/go.d/modules/icecast/testdata/stats_single_source.json
vendored
Normal file
27
src/go/plugin/go.d/modules/icecast/testdata/stats_single_source.json
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"icestats": {
|
||||||
|
"admin": "icemaster@localhost",
|
||||||
|
"host": "localhost",
|
||||||
|
"location": "Earth",
|
||||||
|
"server_id": "Icecast 2.4.4",
|
||||||
|
"server_start": "Wed, 17 Jul 2024 11:27:40 +0300",
|
||||||
|
"server_start_iso8601": "2024-07-17T11:27:40+0300",
|
||||||
|
"source": {
|
||||||
|
"audio_info": "ice-bitrate=128;ice-channels=2;ice-samplerate=44100",
|
||||||
|
"genre": "(null)",
|
||||||
|
"ice-bitrate": 128,
|
||||||
|
"ice-channels": 2,
|
||||||
|
"ice-samplerate": 44100,
|
||||||
|
"listener_peak": 2,
|
||||||
|
"listeners": 1,
|
||||||
|
"listenurl": "http://localhost:8000/line.nsv",
|
||||||
|
"server_description": "(null)",
|
||||||
|
"server_name": "abc",
|
||||||
|
"server_type": "audio/mpeg",
|
||||||
|
"server_url": "(null)",
|
||||||
|
"stream_start": "Wed, 17 Jul 2024 12:10:20 +0300",
|
||||||
|
"stream_start_iso8601": "2024-07-17T12:10:20+0300",
|
||||||
|
"dummy": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue