mirror of
https://github.com/datarhei/core.git
synced 2025-09-27 04:16:25 +08:00
Add /v3/metrics (get) endpoint to list all known metrics
This commit is contained in:
41
docs/docs.go
41
docs/docs.go
@@ -839,6 +839,30 @@ const docTemplate = `{
|
||||
}
|
||||
},
|
||||
"/api/v3/metrics": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "List all known metrics with their description and labels",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"summary": "List all known metrics with their description and labels",
|
||||
"operationId": "metrics-3-describe",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/api.MetricsDescription"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
@@ -2926,6 +2950,23 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"api.MetricsDescription": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"labels": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"api.MetricsQuery": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
@@ -831,6 +831,30 @@
|
||||
}
|
||||
},
|
||||
"/api/v3/metrics": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "List all known metrics with their description and labels",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"summary": "List all known metrics with their description and labels",
|
||||
"operationId": "metrics-3-describe",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/api.MetricsDescription"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
@@ -2918,6 +2942,23 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"api.MetricsDescription": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"labels": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"api.MetricsQuery": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
@@ -462,6 +462,17 @@ definitions:
|
||||
- password
|
||||
- username
|
||||
type: object
|
||||
api.MetricsDescription:
|
||||
properties:
|
||||
description:
|
||||
type: string
|
||||
labels:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
type: string
|
||||
type: object
|
||||
api.MetricsQuery:
|
||||
properties:
|
||||
interval_sec:
|
||||
@@ -2264,6 +2275,21 @@ paths:
|
||||
- ApiKeyAuth: []
|
||||
summary: Add JSON metadata under the given key
|
||||
/api/v3/metrics:
|
||||
get:
|
||||
description: List all known metrics with their description and labels
|
||||
operationId: metrics-3-describe
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
items:
|
||||
$ref: '#/definitions/api.MetricsDescription'
|
||||
type: array
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: List all known metrics with their description and labels
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
|
@@ -7,6 +7,12 @@ import (
|
||||
"github.com/datarhei/core/v16/monitor"
|
||||
)
|
||||
|
||||
type MetricsDescription struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Labels []string `json:"labels"`
|
||||
}
|
||||
|
||||
type MetricsQueryMetric struct {
|
||||
Name string `json:"name"`
|
||||
Labels map[string]string `json:"labels"`
|
||||
|
@@ -2,6 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/datarhei/core/v16/http/api"
|
||||
@@ -28,6 +29,34 @@ func NewMetrics(config MetricsConfig) *MetricsHandler {
|
||||
}
|
||||
}
|
||||
|
||||
// Describe the known metrics
|
||||
// @Summary List all known metrics with their description and labels
|
||||
// @Description List all known metrics with their description and labels
|
||||
// @ID metrics-3-describe
|
||||
// @Produce json
|
||||
// @Success 200 {array} api.MetricsDescription
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /api/v3/metrics [get]
|
||||
func (r *MetricsHandler) Describe(c echo.Context) error {
|
||||
response := []api.MetricsDescription{}
|
||||
|
||||
descriptors := r.metrics.Describe()
|
||||
|
||||
for _, d := range descriptors {
|
||||
response = append(response, api.MetricsDescription{
|
||||
Name: d.Name(),
|
||||
Description: d.Description(),
|
||||
Labels: d.Labels(),
|
||||
})
|
||||
}
|
||||
|
||||
sort.Slice(response, func(i, j int) bool {
|
||||
return response[i].Name < response[j].Name
|
||||
})
|
||||
|
||||
return c.JSON(http.StatusOK, response)
|
||||
}
|
||||
|
||||
// Query the collected metrics
|
||||
// @Summary Query the collected metrics
|
||||
// @Description Query the collected metrics
|
||||
|
@@ -640,6 +640,7 @@ func (s *server) setRoutesV3(v3 *echo.Group) {
|
||||
// v3 Log
|
||||
v3.GET("/log", s.v3handler.log.Log)
|
||||
|
||||
// v3 Resources
|
||||
// v3 Metrics
|
||||
v3.GET("/metrics", s.v3handler.resources.Describe)
|
||||
v3.POST("/metrics", s.v3handler.resources.Metrics)
|
||||
}
|
||||
|
@@ -20,11 +20,11 @@ func NewCPUCollector() metric.Collector {
|
||||
ncpu: 1,
|
||||
}
|
||||
|
||||
c.ncpuDescr = metric.NewDesc("cpu_ncpu", "", nil)
|
||||
c.systemDescr = metric.NewDesc("cpu_system", "", nil)
|
||||
c.userDescr = metric.NewDesc("cpu_user", "", nil)
|
||||
c.idleDescr = metric.NewDesc("cpu_idle", "", nil)
|
||||
c.otherDescr = metric.NewDesc("cpu_other", "", nil)
|
||||
c.ncpuDescr = metric.NewDesc("cpu_ncpu", "Number of logical CPUs in the system", nil)
|
||||
c.systemDescr = metric.NewDesc("cpu_system", "Percentage of CPU used for the system", nil)
|
||||
c.userDescr = metric.NewDesc("cpu_user", "Percentage of CPU used for the user", nil)
|
||||
c.idleDescr = metric.NewDesc("cpu_idle", "Percentage of idle CPU", nil)
|
||||
c.otherDescr = metric.NewDesc("cpu_other", "Percentage of CPU used for other subsystems", nil)
|
||||
|
||||
if ncpu, err := psutil.CPUCounts(true); err == nil {
|
||||
c.ncpu = ncpu
|
||||
|
@@ -17,8 +17,8 @@ func NewDiskCollector(path string) metric.Collector {
|
||||
path: path,
|
||||
}
|
||||
|
||||
c.totalDescr = metric.NewDesc("disk_total", "", []string{"path"})
|
||||
c.usageDescr = metric.NewDesc("disk_usage", "", []string{"path"})
|
||||
c.totalDescr = metric.NewDesc("disk_total", "Total size of the disk in bytes", []string{"path"})
|
||||
c.usageDescr = metric.NewDesc("disk_usage", "Number of used bytes on the disk", []string{"path"})
|
||||
|
||||
return c
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ func NewFFmpegCollector(f ffmpeg.FFmpeg) metric.Collector {
|
||||
ffmpeg: f,
|
||||
}
|
||||
|
||||
c.processDescr = metric.NewDesc("ffmpeg_process", "", []string{"state"})
|
||||
c.processDescr = metric.NewDesc("ffmpeg_process", "State of the ffmpeg process", []string{"state"})
|
||||
|
||||
return c
|
||||
}
|
||||
|
@@ -19,9 +19,9 @@ func NewFilesystemCollector(name string, fs fs.Filesystem) metric.Collector {
|
||||
name: name,
|
||||
}
|
||||
|
||||
c.limitDescr = metric.NewDesc("filesystem_limit", "", []string{"name"})
|
||||
c.usageDescr = metric.NewDesc("filesystem_usage", "", []string{"name"})
|
||||
c.filesDescr = metric.NewDesc("filesystem_files", "", []string{"name"})
|
||||
c.limitDescr = metric.NewDesc("filesystem_limit", "Total size of the filesystem in bytes, negative if unlimited", []string{"name"})
|
||||
c.usageDescr = metric.NewDesc("filesystem_usage", "Number of used bytes on the filesystem", []string{"name"})
|
||||
c.filesDescr = metric.NewDesc("filesystem_files", "Number of files on the filesystem (excluding directories)", []string{"name"})
|
||||
|
||||
return c
|
||||
}
|
||||
|
@@ -13,8 +13,8 @@ type memCollector struct {
|
||||
func NewMemCollector() metric.Collector {
|
||||
c := &memCollector{}
|
||||
|
||||
c.totalDescr = metric.NewDesc("mem_total", "", nil)
|
||||
c.freeDescr = metric.NewDesc("mem_free", "", nil)
|
||||
c.totalDescr = metric.NewDesc("mem_total", "Total available memory in bytes", nil)
|
||||
c.freeDescr = metric.NewDesc("mem_free", "Free memory in bytes", nil)
|
||||
|
||||
return c
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Pattern interface {
|
||||
@@ -304,6 +305,10 @@ func NewDesc(name, description string, labels []string) *Description {
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Description) String() string {
|
||||
return fmt.Sprintf("%s: %s (%s)", d.name, d.description, strings.Join(d.labels, ","))
|
||||
}
|
||||
|
||||
func (d *Description) Name() string {
|
||||
return d.name
|
||||
}
|
||||
@@ -312,6 +317,13 @@ func (d *Description) Description() string {
|
||||
return d.description
|
||||
}
|
||||
|
||||
func (d *Description) Labels() []string {
|
||||
labels := make([]string, len(d.labels))
|
||||
copy(labels, d.labels)
|
||||
|
||||
return labels
|
||||
}
|
||||
|
||||
type Collector interface {
|
||||
Prefix() string
|
||||
Describe() []*Description
|
||||
|
@@ -10,9 +10,26 @@ import (
|
||||
"github.com/datarhei/core/v16/monitor/metric"
|
||||
)
|
||||
|
||||
type Monitor interface {
|
||||
Register(c metric.Collector)
|
||||
type Reader interface {
|
||||
Collect(patterns []metric.Pattern) metric.Metrics
|
||||
Describe() []*metric.Description
|
||||
}
|
||||
|
||||
type Monitor interface {
|
||||
Reader
|
||||
Register(c metric.Collector)
|
||||
UnregisterAll()
|
||||
}
|
||||
|
||||
type HistoryReader interface {
|
||||
Reader
|
||||
History(timerange, interval time.Duration, patterns []metric.Pattern) []HistoryMetrics
|
||||
Resolution() (timerange, interval time.Duration)
|
||||
}
|
||||
|
||||
type HistoryMonitor interface {
|
||||
HistoryReader
|
||||
Register(c metric.Collector)
|
||||
UnregisterAll()
|
||||
}
|
||||
|
||||
@@ -75,6 +92,26 @@ func (m *monitor) Collect(patterns []metric.Pattern) metric.Metrics {
|
||||
return metrics
|
||||
}
|
||||
|
||||
func (m *monitor) Describe() []*metric.Description {
|
||||
descriptors := []*metric.Description{}
|
||||
collectors := map[metric.Collector]struct{}{}
|
||||
|
||||
m.lock.RLock()
|
||||
defer m.lock.RUnlock()
|
||||
|
||||
for _, c := range m.collectors {
|
||||
if _, ok := collectors[c]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
collectors[c] = struct{}{}
|
||||
|
||||
descriptors = append(descriptors, c.Describe()...)
|
||||
}
|
||||
|
||||
return descriptors
|
||||
}
|
||||
|
||||
func (m *monitor) UnregisterAll() {
|
||||
m.lock.Lock()
|
||||
defer m.lock.Unlock()
|
||||
@@ -86,12 +123,6 @@ func (m *monitor) UnregisterAll() {
|
||||
m.collectors = make(map[string]metric.Collector)
|
||||
}
|
||||
|
||||
type HistoryMonitor interface {
|
||||
Monitor
|
||||
History(timerange, interval time.Duration, patterns []metric.Pattern) []HistoryMetrics
|
||||
Resolution() (timerange, interval time.Duration)
|
||||
}
|
||||
|
||||
type historyMonitor struct {
|
||||
monitor Monitor
|
||||
|
||||
@@ -209,6 +240,10 @@ func (m *historyMonitor) Collect(patterns []metric.Pattern) metric.Metrics {
|
||||
return m.monitor.Collect(patterns)
|
||||
}
|
||||
|
||||
func (m *historyMonitor) Describe() []*metric.Description {
|
||||
return m.monitor.Describe()
|
||||
}
|
||||
|
||||
func (m *historyMonitor) UnregisterAll() {
|
||||
m.monitor.UnregisterAll()
|
||||
|
||||
@@ -327,13 +362,3 @@ func (m *historyMonitor) resample(values []HistoryMetrics, timerange, interval t
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
type Reader interface {
|
||||
Collect(patterns []metric.Pattern) metric.Metrics
|
||||
}
|
||||
|
||||
type HistoryReader interface {
|
||||
Reader
|
||||
History(timerange, interval time.Duration, patterns []metric.Pattern) []HistoryMetrics
|
||||
Resolution() (timerange, interval time.Duration)
|
||||
}
|
||||
|
@@ -13,8 +13,8 @@ type netCollector struct {
|
||||
func NewNetCollector() metric.Collector {
|
||||
c := &netCollector{}
|
||||
|
||||
c.rxDescr = metric.NewDesc("net_rx", "", []string{"interface"})
|
||||
c.txDescr = metric.NewDesc("net_tx", "", []string{"interface"})
|
||||
c.rxDescr = metric.NewDesc("net_rx", "Number of received bytes", []string{"interface"})
|
||||
c.txDescr = metric.NewDesc("net_tx", "Number of transmitted bytes", []string{"interface"})
|
||||
|
||||
return c
|
||||
}
|
||||
|
@@ -22,10 +22,10 @@ func NewRestreamCollector(r restream.Restreamer) metric.Collector {
|
||||
r: r,
|
||||
}
|
||||
|
||||
c.restreamProcessDescr = metric.NewDesc("restream_process", "", []string{"processid", "state", "order", "name"})
|
||||
c.restreamProcessStatesDescr = metric.NewDesc("restream_process_states", "", []string{"processid", "state"})
|
||||
c.restreamProcessIODescr = metric.NewDesc("restream_io", "", []string{"processid", "type", "id", "address", "index", "stream", "media", "name"})
|
||||
c.restreamStatesDescr = metric.NewDesc("restream_state", "", []string{"state"})
|
||||
c.restreamProcessDescr = metric.NewDesc("restream_process", "Current process values by name", []string{"processid", "state", "order", "name"})
|
||||
c.restreamProcessStatesDescr = metric.NewDesc("restream_process_states", "Current process state", []string{"processid", "state"})
|
||||
c.restreamProcessIODescr = metric.NewDesc("restream_io", "Current process IO values by name", []string{"processid", "type", "id", "address", "index", "stream", "media", "name"})
|
||||
c.restreamStatesDescr = metric.NewDesc("restream_state", "Summarized process states", []string{"state"})
|
||||
|
||||
return c
|
||||
}
|
||||
|
@@ -31,17 +31,17 @@ func NewSessionCollector(r session.RegistryReader, collectors []string) metric.C
|
||||
c.collectors = r.Collectors()
|
||||
}
|
||||
|
||||
c.totalDescr = metric.NewDesc("session_total", "", []string{"collector"})
|
||||
c.limitDescr = metric.NewDesc("session_limit", "", []string{"collector"})
|
||||
c.activeDescr = metric.NewDesc("session_active", "", []string{"collector"})
|
||||
c.rxBytesDescr = metric.NewDesc("session_rxbytes", "", []string{"collector"})
|
||||
c.txBytesDescr = metric.NewDesc("session_txbytes", "", []string{"collector"})
|
||||
c.totalDescr = metric.NewDesc("session_total", "Total sessions", []string{"collector"})
|
||||
c.limitDescr = metric.NewDesc("session_limit", "Max. number of concurrent sessions", []string{"collector"})
|
||||
c.activeDescr = metric.NewDesc("session_active", "Number of current sessions", []string{"collector"})
|
||||
c.rxBytesDescr = metric.NewDesc("session_rxbytes", "Number of received bytes", []string{"collector"})
|
||||
c.txBytesDescr = metric.NewDesc("session_txbytes", "Number of transmitted bytes", []string{"collector"})
|
||||
|
||||
c.rxBitrateDescr = metric.NewDesc("session_rxbitrate", "", []string{"collector"})
|
||||
c.txBitrateDescr = metric.NewDesc("session_txbitrate", "", []string{"collector"})
|
||||
c.rxBitrateDescr = metric.NewDesc("session_rxbitrate", "Current receiving bitrate in bit per second", []string{"collector"})
|
||||
c.txBitrateDescr = metric.NewDesc("session_txbitrate", "Current transmitting bitrate in bit per second", []string{"collector"})
|
||||
|
||||
c.maxTxBitrateDescr = metric.NewDesc("session_maxtxbitrate", "", []string{"collector"})
|
||||
c.maxRxBitrateDescr = metric.NewDesc("session_maxrxbitrate", "", []string{"collector"})
|
||||
c.maxRxBitrateDescr = metric.NewDesc("session_maxrxbitrate", "Max. allowed receiving bitrate in bit per second", []string{"collector"})
|
||||
c.maxTxBitrateDescr = metric.NewDesc("session_maxtxbitrate", "Max. allowed transmitting bitrate in bit per second", []string{"collector"})
|
||||
|
||||
return c
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@ func NewUptimeCollector() metric.Collector {
|
||||
t: time.Now(),
|
||||
}
|
||||
|
||||
c.uptimeDescr = metric.NewDesc("uptime_uptime", "", nil)
|
||||
c.uptimeDescr = metric.NewDesc("uptime_uptime", "Current uptime in seconds", nil)
|
||||
|
||||
return c
|
||||
}
|
||||
|
Reference in New Issue
Block a user