Skip to content

Commit

Permalink
Merge pull request #38 from shiguredo/feature/add-license-expired-at-…
Browse files Browse the repository at this point in the history
…metrics

ライセンス期限に関連するメトリクスの追加
  • Loading branch information
tnamao authored Feb 8, 2024
2 parents 78c3f2a + 53c3e08 commit cc72f77
Show file tree
Hide file tree
Showing 11 changed files with 115 additions and 11 deletions.
11 changes: 11 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# CHANGES

## develop

- [ADD] `sora_license_expired_at_timestamp_seconds` メトリクスを追加する
- Sora のライセンス期限を epoch 秒に変換したものを返す
- 仮にライセンスの期限が 2024 年 1 月の場合は、`2024-01-31T23:59:59Z` の epoch 秒になる
- @tnamao
- [ADD] `sora_time_seconds` メトリクスを追加する
- これは `Node exporter``node_time_seconds` と同じもので、exporter が起動しているサーバーのシステム時間を epoch 秒で返す
- `sora_license_expired_at_timestamp_seconds` と組み合わせてライセンスの期限を監視することを想定している
- @tnamao

## 2024.1.0

- [FIX] Sora 2023.2.0 で `ListClusterNodes` API の `include_all_known_nodes` のデフォルト値が変更で panic が起こす問題に対応する
Expand Down
28 changes: 26 additions & 2 deletions collector/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,27 @@ import (
"github.com/prometheus/client_golang/prometheus"
)

var (
// for testing
freezedTimeSeconds = float64(time.Date(2024, 1, 7, 17, 41, 31, 312389, time.UTC).UnixNano()) / 1e9
)

type Collector struct {
mutex sync.RWMutex
logger log.Logger
timeout time.Duration
URI string
skipSslVerify bool
freezeTimeSeconds bool
enableSoraClientMetrics bool
enableSoraConnectionErrorMetrics bool
enableErlangVMMetrics bool
EnableSoraClusterMetrics bool

soraUp *prometheus.Desc
soraVersionInfo *prometheus.Desc
soraTimeSeconds *prometheus.Desc

ConnectionMetrics
WebhookMetrics
ClientMetrics
Expand All @@ -40,6 +48,7 @@ type CollectorOptions struct {
URI string
SkipSslVerify bool
Timeout time.Duration
FreezeTimeSeconds bool
Logger log.Logger
EnableSoraClientMetrics bool
EnableSoraConnectionErrorMetrics bool
Expand All @@ -62,13 +71,19 @@ func NewCollector(options *CollectorOptions) *Collector {
skipSslVerify: options.SkipSslVerify,
logger: options.Logger,

// for testing
freezeTimeSeconds: options.FreezeTimeSeconds,

enableSoraClientMetrics: options.EnableSoraClientMetrics,
enableSoraConnectionErrorMetrics: options.EnableSoraConnectionErrorMetrics,
enableErlangVMMetrics: options.EnableErlangVMMetrics,
EnableSoraClusterMetrics: options.EnableSoraClusterMetrics,

soraUp: newDesc("up", "Whether the last scrape of metrics from Sora was able to connect to the server (1 for yes, 0 for no)."),
soraVersionInfo: newDescWithLabel("version_info", "sora version info.", []string{"version"}),
soraUp: newDesc("up", "Whether the last scrape of metrics from Sora was able to connect to the server (1 for yes, 0 for no)."),
soraVersionInfo: newDescWithLabel("version_info", "sora version info.", []string{"version"}),
// same as node expoter's node_time_seconds
soraTimeSeconds: newDesc("time_seconds", "System time in seconds since epoch."),

ConnectionMetrics: connectionMetrics,
WebhookMetrics: webhookMetrics,
ClientMetrics: clientMetrics,
Expand Down Expand Up @@ -175,6 +190,14 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) {

ch <- newGauge(c.soraUp, 1)
ch <- newGauge(c.soraVersionInfo, 1, report.SoraVersion)

if c.freezeTimeSeconds {
ch <- newGauge(c.soraTimeSeconds, freezedTimeSeconds)
} else {
nowSec := float64(time.Now().UnixNano()) / 1e9
ch <- newGauge(c.soraTimeSeconds, nowSec)
}

c.LicenseMetrics.Collect(ch, licenseInfo)
c.ConnectionMetrics.Collect(ch, report.soraConnectionReport)
c.WebhookMetrics.Collect(ch, report.soraWebhookReport)
Expand All @@ -196,6 +219,7 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) {
func (c *Collector) Describe(ch chan<- *prometheus.Desc) {
ch <- c.soraUp
ch <- c.soraVersionInfo
ch <- c.soraTimeSeconds
c.LicenseMetrics.Describe(ch)
c.ConnectionMetrics.Describe(ch)
c.WebhookMetrics.Describe(ch)
Expand Down
36 changes: 29 additions & 7 deletions collector/license.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
package collector

import "github.com/prometheus/client_golang/prometheus"
import (
"time"

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

var (
licenseMetrics = LicenseMetrics{
licenseInfo: newDescWithLabel("license_info", "sora license info.", []string{"expired_at", "product_name", "serial_code", "type"}),
licenseMaxConnections: newDesc("license_max_connections", "sora license file's max_connections."),
licenseMaxNodes: newDesc("license_max_nodes", "sora license file's max_nodes."),
licenseInfo: newDescWithLabel("license_info", "sora license info.", []string{"expired_at", "product_name", "serial_code", "type"}),
licenseMaxConnections: newDesc("license_max_connections", "sora license file's max_connections."),
licenseMaxNodes: newDesc("license_max_nodes", "sora license file's max_nodes."),
licenseExpiredAtTimestampSeconds: newDesc("license_expired_at_timestamp_seconds", "sora license file's expire seconds since epoch."),
}
)

type LicenseMetrics struct {
licenseInfo *prometheus.Desc
licenseMaxConnections *prometheus.Desc
licenseMaxNodes *prometheus.Desc
licenseInfo *prometheus.Desc
licenseMaxConnections *prometheus.Desc
licenseMaxNodes *prometheus.Desc
licenseExpiredAtTimestampSeconds *prometheus.Desc
}

func (m *LicenseMetrics) Describe(ch chan<- *prometheus.Desc) {
ch <- m.licenseInfo
ch <- m.licenseMaxConnections
ch <- m.licenseMaxNodes
ch <- m.licenseExpiredAtTimestampSeconds
}

func (m *LicenseMetrics) Collect(ch chan<- prometheus.Metric, info soraLicenseInfo) {
Expand All @@ -28,4 +35,19 @@ func (m *LicenseMetrics) Collect(ch chan<- prometheus.Metric, info soraLicenseIn
if info.MaxNodes != nil {
ch <- newGauge(m.licenseMaxNodes, float64(*info.MaxNodes))
}

expiredAtSec := expiredAtToSecondSinceEpoch(info.ExpiredAt)
ch <- newGauge(m.licenseExpiredAtTimestampSeconds, expiredAtSec)
}

func expiredAtToSecondSinceEpoch(expiredAt string) float64 {
// expiredAt: "2024-12"
expiredAtTime, err := time.Parse("2006-01", expiredAt)
if err != nil {
return 0
}

// 期限翌月の 1 日 0 時 0 分0 秒の 1 秒前
expiredTimestamp := time.Date(expiredAtTime.Year(), expiredAtTime.Month()+1, 1, 0, 0, 0, 0, time.UTC).Add(-time.Second)
return float64(expiredTimestamp.UnixNano()) / 1e9
}
7 changes: 5 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ type handler struct {
soraAPIURL string
soraSkipSslVeirfy bool
soraTimeout time.Duration
soraFreezeTimeSeconds bool
enableSoraClientMetrics bool
enableSoraConnectionErrorMetrics bool
enableErlangVMMetrics bool
Expand All @@ -94,7 +95,7 @@ type handler struct {

func newHandler(
includeExporterMetrics bool, maxRequests int, logger log.Logger,
soraAPIURL string, soraSkipSslVeirfy bool, soraTimeout time.Duration,
soraAPIURL string, soraSkipSslVeirfy bool, soraTimeout time.Duration, soraFreezeTimeSeconds bool,
enableSoraClientMetrics bool, enableSoraConnectionErrorMetrics bool, enableErlangVMMetrics bool, enableSoraClusterMetrics bool) *handler {

h := &handler{
Expand All @@ -105,6 +106,7 @@ func newHandler(
soraAPIURL: soraAPIURL,
soraSkipSslVeirfy: soraSkipSslVeirfy,
soraTimeout: soraTimeout,
soraFreezeTimeSeconds: soraFreezeTimeSeconds,
enableSoraClientMetrics: enableSoraClientMetrics,
enableSoraConnectionErrorMetrics: enableSoraConnectionErrorMetrics,
enableErlangVMMetrics: enableErlangVMMetrics,
Expand Down Expand Up @@ -132,6 +134,7 @@ func (h *handler) innerHandler() http.Handler {
URI: h.soraAPIURL,
SkipSslVerify: h.soraSkipSslVeirfy,
Timeout: h.soraTimeout,
FreezeTimeSeconds: h.soraFreezeTimeSeconds,
Logger: h.logger,
EnableSoraClientMetrics: h.enableSoraClientMetrics,
EnableSoraConnectionErrorMetrics: h.enableSoraConnectionErrorMetrics,
Expand Down Expand Up @@ -185,7 +188,7 @@ func main() {
})
soraHandler := newHandler(
!*disableExporterMetrics, *maxRequests, logger,
*soraAPIURL, *soraSkipSslVeirfy, *soraTimeout,
*soraAPIURL, *soraSkipSslVeirfy, *soraTimeout, false,
*enableSoraClientMetrics, *enableSoraConnectionErrorMetrics, *enableErlangVMMetrics, *enableSoraClusterMetrics)
http.Handle(*metricsPath, soraHandler)

Expand Down
8 changes: 8 additions & 0 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ func TestInvalidConfig(t *testing.T) {
URI: s.URL,
SkipSslVerify: true,
Timeout: timeout,
FreezeTimeSeconds: true,
Logger: log.NewNopLogger(),
EnableSoraClientMetrics: true,
EnableSoraConnectionErrorMetrics: true,
Expand All @@ -298,6 +299,7 @@ func TestMaximumMetrics(t *testing.T) {
URI: s.URL,
SkipSslVerify: true,
Timeout: timeout,
FreezeTimeSeconds: true,
Logger: log.NewNopLogger(),
EnableSoraClientMetrics: true,
EnableSoraConnectionErrorMetrics: true,
Expand All @@ -316,6 +318,7 @@ func TestSoraErlangVMEnabledMetrics(t *testing.T) {
URI: s.URL,
SkipSslVerify: true,
Timeout: timeout,
FreezeTimeSeconds: true,
Logger: log.NewNopLogger(),
EnableSoraClientMetrics: false,
EnableSoraConnectionErrorMetrics: false,
Expand All @@ -334,6 +337,7 @@ func TestSoraClientEnabledMetrics(t *testing.T) {
URI: s.URL,
SkipSslVerify: true,
Timeout: timeout,
FreezeTimeSeconds: true,
Logger: log.NewNopLogger(),
EnableSoraClientMetrics: true,
EnableSoraConnectionErrorMetrics: false,
Expand All @@ -352,6 +356,7 @@ func TestSoraConnectionErrorEnabledMetrics(t *testing.T) {
URI: s.URL,
SkipSslVerify: true,
Timeout: timeout,
FreezeTimeSeconds: true,
Logger: log.NewNopLogger(),
EnableSoraClientMetrics: false,
EnableSoraConnectionErrorMetrics: true,
Expand Down Expand Up @@ -395,6 +400,7 @@ func TestMinimumMetrics(t *testing.T) {
URI: s.URL,
SkipSslVerify: true,
Timeout: timeout,
FreezeTimeSeconds: true,
Logger: log.NewNopLogger(),
EnableSoraClientMetrics: false,
EnableSoraConnectionErrorMetrics: false,
Expand All @@ -413,6 +419,7 @@ func TestSoraClusterEnabledMetrics(t *testing.T) {
URI: s.URL,
SkipSslVerify: true,
Timeout: timeout,
FreezeTimeSeconds: true,
Logger: log.NewNopLogger(),
EnableSoraClientMetrics: false,
EnableSoraConnectionErrorMetrics: false,
Expand All @@ -432,6 +439,7 @@ func TestSoraClusterEnabledMetricsCurrentJsonData(t *testing.T) {
URI: s.URL,
SkipSslVerify: true,
Timeout: timeout,
FreezeTimeSeconds: true,
Logger: log.NewNopLogger(),
EnableSoraClientMetrics: false,
EnableSoraConnectionErrorMetrics: false,
Expand Down
6 changes: 6 additions & 0 deletions test/maximum.metrics
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ sora_erlang_vm_wall_clock_wallclock_time_since_last_call 9090
# TYPE sora_event_webhook_total counter
sora_event_webhook_total{state="failed"} 94
sora_event_webhook_total{state="successful"} 97
# HELP sora_license_expired_at_timestamp_seconds sora license file's expire seconds since epoch.
# TYPE sora_license_expired_at_timestamp_seconds gauge
sora_license_expired_at_timestamp_seconds 1.759276799e+09
# HELP sora_license_info sora license info.
# TYPE sora_license_info gauge
sora_license_info{expired_at="2025-09",product_name="Sora",serial_code="EXPORTER-SRA-E001-202509-N10-100",type="Experimental"} 1
Expand Down Expand Up @@ -174,6 +177,9 @@ sora_session_webhook_total{state="successful"} 98
# TYPE sora_successful_auth_webhook_total counter
sora_successful_auth_webhook_total{state="allowed"} 91
sora_successful_auth_webhook_total{state="denied"} 92
# HELP sora_time_seconds System time in seconds since epoch.
# TYPE sora_time_seconds gauge
sora_time_seconds 1.7046492910003123e+09
# HELP sora_turn_connections_total The total number of connections with TURN.
# TYPE sora_turn_connections_total counter
sora_turn_connections_total{proto="tcp"} 2
Expand Down
6 changes: 6 additions & 0 deletions test/minimum.metrics
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ sora_duration_seconds_total 1412
# TYPE sora_event_webhook_total counter
sora_event_webhook_total{state="failed"} 94
sora_event_webhook_total{state="successful"} 97
# HELP sora_license_expired_at_timestamp_seconds sora license file's expire seconds since epoch.
# TYPE sora_license_expired_at_timestamp_seconds gauge
sora_license_expired_at_timestamp_seconds 1.759276799e+09
# HELP sora_license_info sora license info.
# TYPE sora_license_info gauge
sora_license_info{expired_at="2025-09",product_name="Sora",serial_code="EXPORTER-SRA-E001-202509-N10-100",type="Experimental"} 1
Expand All @@ -46,6 +49,9 @@ sora_session_webhook_total{state="successful"} 98
# TYPE sora_successful_auth_webhook_total counter
sora_successful_auth_webhook_total{state="allowed"} 91
sora_successful_auth_webhook_total{state="denied"} 92
# HELP sora_time_seconds System time in seconds since epoch.
# TYPE sora_time_seconds gauge
sora_time_seconds 1.7046492910003123e+09
# HELP sora_turn_connections_total The total number of connections with TURN.
# TYPE sora_turn_connections_total counter
sora_turn_connections_total{proto="tcp"} 444
Expand Down
6 changes: 6 additions & 0 deletions test/sora_client_enabled.metrics
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ sora_duration_seconds_total 1412
# TYPE sora_event_webhook_total counter
sora_event_webhook_total{state="failed"} 94
sora_event_webhook_total{state="successful"} 97
# HELP sora_license_expired_at_timestamp_seconds sora license file's expire seconds since epoch.
# TYPE sora_license_expired_at_timestamp_seconds gauge
sora_license_expired_at_timestamp_seconds 1.759276799e+09
# HELP sora_license_info sora license info.
# TYPE sora_license_info gauge
sora_license_info{expired_at="2025-09",product_name="Sora",serial_code="EXPORTER-SRA-E001-202509-N10-100",type="Experimental"} 1
Expand Down Expand Up @@ -75,6 +78,9 @@ sora_session_webhook_total{state="successful"} 98
# TYPE sora_successful_auth_webhook_total counter
sora_successful_auth_webhook_total{state="allowed"} 91
sora_successful_auth_webhook_total{state="denied"} 92
# HELP sora_time_seconds System time in seconds since epoch.
# TYPE sora_time_seconds gauge
sora_time_seconds 1.7046492910003123e+09
# HELP sora_turn_connections_total The total number of connections with TURN.
# TYPE sora_turn_connections_total counter
sora_turn_connections_total{proto="tcp"} 2
Expand Down
6 changes: 6 additions & 0 deletions test/sora_cluster_metrics_enabled.metrics
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ sora_duration_seconds_total 1412
# TYPE sora_event_webhook_total counter
sora_event_webhook_total{state="failed"} 94
sora_event_webhook_total{state="successful"} 97
# HELP sora_license_expired_at_timestamp_seconds sora license file's expire seconds since epoch.
# TYPE sora_license_expired_at_timestamp_seconds gauge
sora_license_expired_at_timestamp_seconds 1.759276799e+09
# HELP sora_license_info sora license info.
# TYPE sora_license_info gauge
sora_license_info{expired_at="2025-09",product_name="Sora",serial_code="EXPORTER-SRA-E001-202509-N10-100",type="Experimental"} 1
Expand Down Expand Up @@ -63,6 +66,9 @@ sora_session_webhook_total{state="successful"} 98
# TYPE sora_successful_auth_webhook_total counter
sora_successful_auth_webhook_total{state="allowed"} 91
sora_successful_auth_webhook_total{state="denied"} 92
# HELP sora_time_seconds System time in seconds since epoch.
# TYPE sora_time_seconds gauge
sora_time_seconds 1.7046492910003123e+09
# HELP sora_turn_connections_total The total number of connections with TURN.
# TYPE sora_turn_connections_total counter
sora_turn_connections_total{proto="tcp"} 2
Expand Down
6 changes: 6 additions & 0 deletions test/sora_connection_error_enabled.metrics
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ sora_duration_seconds_total 1412
# TYPE sora_event_webhook_total counter
sora_event_webhook_total{state="failed"} 94
sora_event_webhook_total{state="successful"} 97
# HELP sora_license_expired_at_timestamp_seconds sora license file's expire seconds since epoch.
# TYPE sora_license_expired_at_timestamp_seconds gauge
sora_license_expired_at_timestamp_seconds 1.759276799e+09
# HELP sora_license_info sora license info.
# TYPE sora_license_info gauge
sora_license_info{expired_at="2025-09",product_name="Sora",serial_code="EXPORTER-SRA-E001-202509-N10-100",type="Experimental"} 1
Expand Down Expand Up @@ -53,6 +56,9 @@ sora_session_webhook_total{state="successful"} 98
# TYPE sora_successful_auth_webhook_total counter
sora_successful_auth_webhook_total{state="allowed"} 91
sora_successful_auth_webhook_total{state="denied"} 92
# HELP sora_time_seconds System time in seconds since epoch.
# TYPE sora_time_seconds gauge
sora_time_seconds 1.7046492910003123e+09
# HELP sora_turn_connections_total The total number of connections with TURN.
# TYPE sora_turn_connections_total counter
sora_turn_connections_total{proto="tcp"} 2
Expand Down
6 changes: 6 additions & 0 deletions test/sora_erlang_vm_enabled.metrics
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ sora_erlang_vm_wall_clock_wallclock_time_since_last_call 9090
# TYPE sora_event_webhook_total counter
sora_event_webhook_total{state="failed"} 94
sora_event_webhook_total{state="successful"} 97
# HELP sora_license_expired_at_timestamp_seconds sora license file's expire seconds since epoch.
# TYPE sora_license_expired_at_timestamp_seconds gauge
sora_license_expired_at_timestamp_seconds 1.759276799e+09
# HELP sora_license_info sora license info.
# TYPE sora_license_info gauge
sora_license_info{expired_at="2025-09",product_name="Sora",serial_code="EXPORTER-SRA-E001-202509-N10-100",type="Experimental"} 1
Expand Down Expand Up @@ -130,6 +133,9 @@ sora_session_webhook_total{state="successful"} 98
# TYPE sora_successful_auth_webhook_total counter
sora_successful_auth_webhook_total{state="allowed"} 91
sora_successful_auth_webhook_total{state="denied"} 92
# HELP sora_time_seconds System time in seconds since epoch.
# TYPE sora_time_seconds gauge
sora_time_seconds 1.7046492910003123e+09
# HELP sora_turn_connections_total The total number of connections with TURN.
# TYPE sora_turn_connections_total counter
sora_turn_connections_total{proto="tcp"} 2
Expand Down

0 comments on commit cc72f77

Please sign in to comment.