diff --git a/collector/binlog.go b/collector/binlog.go index e8703eb..f79cc90 100644 --- a/collector/binlog.go +++ b/collector/binlog.go @@ -4,6 +4,8 @@ package collector import ( "database/sql" + "strconv" + "strings" "github.com/prometheus/client_golang/prometheus" ) @@ -28,6 +30,11 @@ var ( "Number of registered binlog files.", []string{}, nil, ) + binlogFileNumberDesc = prometheus.NewDesc( + prometheus.BuildFQName(namespace, binlog, "file_number"), + "The last binlog file number.", + []string{}, nil, + ) ) // ScrapeBinlogSize colects from `SHOW BINARY LOGS`. @@ -71,6 +78,11 @@ func ScrapeBinlogSize(db *sql.DB, ch chan<- prometheus.Metric) error { ch <- prometheus.MustNewConstMetric( binlogFilesDesc, prometheus.GaugeValue, float64(count), ) + // The last row contains the last binlog file number. + value, _ := strconv.ParseFloat(strings.Split(filename, ".")[1], 64) + ch <- prometheus.MustNewConstMetric( + binlogFileNumberDesc, prometheus.GaugeValue, value, + ) return nil } diff --git a/collector/binlog_test.go b/collector/binlog_test.go new file mode 100644 index 0000000..408c552 --- /dev/null +++ b/collector/binlog_test.go @@ -0,0 +1,52 @@ +package collector + +import ( + "testing" + + "github.com/prometheus/client_golang/prometheus" + dto "github.com/prometheus/client_model/go" + "github.com/smartystreets/goconvey/convey" + "gopkg.in/DATA-DOG/go-sqlmock.v1" +) + +func TestScrapeBinlogSize(t *testing.T) { + db, mock, err := sqlmock.New() + if err != nil { + t.Fatalf("error opening a stub database connection: %s", err) + } + defer db.Close() + + mock.ExpectQuery(logbinQuery).WillReturnRows(sqlmock.NewRows([]string{""}).AddRow(1)) + + columns := []string{"Log_name", "File_size"} + rows := sqlmock.NewRows(columns). + AddRow("centos6-bin.000001", "1813"). + AddRow("centos6-bin.000002", "120"). + AddRow("centos6-bin.000444", "573009") + mock.ExpectQuery(sanitizeQuery(binlogQuery)).WillReturnRows(rows) + + ch := make(chan prometheus.Metric) + go func() { + if err = ScrapeBinlogSize(db, ch); err != nil { + t.Errorf("error calling function on test: %s", err) + } + close(ch) + }() + + counterExpected := []MetricResult{ + {labels: labelMap{}, value: 574942, metricType: dto.MetricType_GAUGE}, + {labels: labelMap{}, value: 3, metricType: dto.MetricType_GAUGE}, + {labels: labelMap{}, value: 444, metricType: dto.MetricType_GAUGE}, + } + convey.Convey("Metrics comparison", t, func() { + for _, expect := range counterExpected { + got := readMetric(<-ch) + convey.So(got, convey.ShouldResemble, expect) + } + }) + + // Ensure all SQL queries were executed + if err := mock.ExpectationsWereMet(); err != nil { + t.Errorf("there were unfulfilled expections: %s", err) + } +}