package metrics import ( "fmt" "strings" "github.com/prometheus/client_golang/prometheus" "rgdd.se/silentct/internal/monitor" "rgdd.se/silentct/pkg/storage/index" ) type Metrics struct { errorCounter prometheus.Counter logIndex *prometheus.GaugeVec logSize *prometheus.GaugeVec logTimestamp *prometheus.GaugeVec needRestart prometheus.Gauge unexpectedCertificateCount *prometheus.GaugeVec } func NewMetrics(registry *prometheus.Registry) *Metrics { m := &Metrics{ errorCounter: prometheus.NewCounter( prometheus.CounterOpts{ Name: "silentct_error_counter", Help: "The number of errors propagated to the main loop.", }, ), logIndex: prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "silentct_log_index", Help: "The next log entry to be downloaded.", }, []string{"log_id"}, ), logSize: prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "silentct_log_size", Help: "The number of entries in the log.", }, []string{"log_id"}, ), logTimestamp: prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "silentct_log_timestamp", Help: "The log's UNIX timestamp in ms.", }, []string{"log_id"}, ), needRestart: prometheus.NewGauge( prometheus.GaugeOpts{ Name: "silentct_need_restart", Help: "A non-zero value if the monitor needs restarting.", }, ), unexpectedCertificateCount: prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "silentct_unexpected_certificate_count", Help: "Number of certificates without any allowlisting", }, []string{"log_id", "log_index", "crt_sans"}, ), } registry.MustRegister( m.errorCounter, m.logIndex, m.logSize, m.logTimestamp, m.needRestart, m.unexpectedCertificateCount, ) return m } func (m *Metrics) LogState(state monitor.State) { id := fmt.Sprintf("%x", state.LogID) m.logIndex.WithLabelValues(id).Set(float64(state.NextIndex)) m.logSize.WithLabelValues(id).Set(float64(state.TreeSize)) m.logTimestamp.WithLabelValues(id).Set(float64(state.Timestamp)) } func (m *Metrics) RemoveLogState(state monitor.State) { id := fmt.Sprintf("%x", state.LogID) m.logIndex.Delete(prometheus.Labels{"id": id}) m.logSize.Delete(prometheus.Labels{"id": id}) m.logTimestamp.Delete(prometheus.Labels{"id": id}) } func (m *Metrics) UnexpectedCertificateCount(alerts []index.CertificateInfo) { m.unexpectedCertificateCount.Reset() for _, alert := range alerts { labels := prometheus.Labels{ "crt_sans": strings.Join(alert.SANs, " "), "log_id": fmt.Sprintf("%x", alert.LogID), "log_index": fmt.Sprintf("%d", alert.LogIndex), } m.unexpectedCertificateCount.With(labels).Set(1) } } func (m *Metrics) CountError() { m.errorCounter.Inc() } func (m *Metrics) NeedRestart() { m.needRestart.Set(float64(1)) }