/* ** Copyright 2022 Dolysis Consulting Limited ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. ** ** For changes see the git log */ package pkg import ( "net/url" "strconv" "time" ipp "git.st8l.com/dolysis/go-ipp" "github.com/go-logr/logr" "github.com/prometheus/client_golang/prometheus" ) const ( namespace = "cups" ) func NewExporter(cupsUri string, log logr.Logger) (*Exporter, error) { cu, err := url.Parse(cupsUri) if err != nil { return nil, err } port, err := strconv.Atoi(cu.Port()) if err != nil { return nil, err } password, _ := cu.User.Password() client := ipp.NewCUPSClient(cu.Hostname(), port, cu.User.Username(), password, cu.Scheme == "https") return &Exporter{ log: log, client: client, lastJobId: 0, lastCompletedJobId: 0, cupsUp: prometheus.NewDesc( "cups_up", "Was the last scrape of cups successful", nil, nil, ), scrapeDurationSeconds: prometheus.NewDesc( prometheus.BuildFQName(namespace, "", "scrape_duration_seconds"), "Duration of the last scrape in seconds", nil, nil, ), jobsTotal: prometheus.NewDesc( prometheus.BuildFQName(namespace, "job", "total"), "Total number of print jobs", []string{"printer"}, nil, ), jobStateTotal: prometheus.NewDesc( prometheus.BuildFQName(namespace, "job", "state_total"), "Number of jobs per state", []string{"printer", "state"}, nil, ), printersTotal: prometheus.NewDesc( prometheus.BuildFQName(namespace, "printer", "total"), "Number of available printers", nil, nil, ), printerStateTotal: prometheus.NewDesc( prometheus.BuildFQName(namespace, "printer", "state_total"), "Number of printers per state", []string{"printer", "state"}, nil, ), }, nil } type Exporter struct { log logr.Logger client *ipp.CUPSClient lastJobId int lastCompletedJobId int cupsUp *prometheus.Desc scrapeDurationSeconds *prometheus.Desc jobsTotal *prometheus.Desc jobStateTotal *prometheus.Desc printersTotal *prometheus.Desc printerStateTotal *prometheus.Desc } func (e *Exporter) Describe(ch chan<- *prometheus.Desc) { ch <- e.cupsUp ch <- e.scrapeDurationSeconds ch <- e.jobsTotal ch <- e.jobStateTotal ch <- e.printersTotal ch <- e.printerStateTotal } func (e *Exporter) Collect(ch chan<- prometheus.Metric) { cupsUp := float64(1) scrapeStartTime := time.Now() if err := e.jobsMetrics(ch); err != nil { e.log.Error(err, "failed to get job metrics") cupsUp = 0 } if err := e.printerMetrics(ch); err != nil { e.log.Error(err, "failed to get printer metrics") cupsUp = 0 } scrapeDuration := time.Since(scrapeStartTime) ch <- prometheus.MustNewConstMetric(e.scrapeDurationSeconds, prometheus.GaugeValue, scrapeDuration.Seconds()) ch <- prometheus.MustNewConstMetric(e.cupsUp, prometheus.GaugeValue, cupsUp) }