From 6ddddcfe8393ef31a64cd88036e61cb335931314 Mon Sep 17 00:00:00 2001 From: Felipe Alfaro Solana Date: Thu, 24 Oct 2019 17:01:10 +0200 Subject: [PATCH] Add the `metric.IsSessionExpired` metric to the exporter. This metric reports which replicated tables have seen their Zookeeper sessions expired. This metric is labeled by database and table, plus additional labels that are added by default (e.g. ClickHouse hostname). --- pkg/apis/metrics/clickhouse_fetcher.go | 47 +++++++++++++++----------- pkg/apis/metrics/exporter.go | 2 +- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/pkg/apis/metrics/clickhouse_fetcher.go b/pkg/apis/metrics/clickhouse_fetcher.go index 16290c495..f44bfb753 100644 --- a/pkg/apis/metrics/clickhouse_fetcher.go +++ b/pkg/apis/metrics/clickhouse_fetcher.go @@ -68,7 +68,14 @@ const ( 'metric.DiskFreeBytes' AS metric, toString(filesystemFree()) AS value, 'Free disk space available at file system' AS description, - 'gauge' AS type + 'gauge' AS type + UNION ALL + SELECT + concat('metric.IsSessionExpired', '{', 'database=', database, ',table=', table, '}') AS metric, + toString(is_session_expired) AS value, + 'Whether the Zookeeper session has expired' AS description, + 'gauge' AS type + FROM system.replicas ` queryTableSizesSQL = ` @@ -85,6 +92,7 @@ const ( GROUP BY database, table` ) +// ClickHouseFetcher describes a fetcher for a particular ClickHouse host type ClickHouseFetcher struct { Hostname string Username string @@ -92,6 +100,7 @@ type ClickHouseFetcher struct { Port int } +// NewClickHouseFetcher creates a new fetcher to retrieve metrics from a particular ClickHouse host func NewClickHouseFetcher(hostname, username, password string, port int) *ClickHouseFetcher { return &ClickHouseFetcher{ Hostname: hostname, @@ -110,16 +119,16 @@ func (f *ClickHouseFetcher) newConn() *clickhouse.Conn { func (f *ClickHouseFetcher) clickHouseQueryMetrics() ([][]string, error) { data := make([][]string, 0) conn := f.newConn() - if rows, err := conn.Query(heredoc.Doc(queryMetricsSQL)); err != nil { + rows, err := conn.Query(heredoc.Doc(queryMetricsSQL)) + if err != nil { return nil, err - } else { - for rows.Next() { - var metric, value, description, _type string - if err := rows.Scan(&metric, &value, &description, &_type); err == nil { - data = append(data, []string{metric, value, description, _type}) - } else { - // Skip erroneous line - } + } + for rows.Next() { + var metric, value, description, _type string + if err := rows.Scan(&metric, &value, &description, &_type); err == nil { + data = append(data, []string{metric, value, description, _type}) + } else { + // Skip erroneous line } } return data, nil @@ -130,16 +139,16 @@ func (f *ClickHouseFetcher) clickHouseQueryMetrics() ([][]string, error) { func (f *ClickHouseFetcher) clickHouseQueryTableSizes() ([][]string, error) { data := make([][]string, 0) conn := f.newConn() - if rows, err := conn.Query(heredoc.Doc(queryTableSizesSQL)); err != nil { + rows, err := conn.Query(heredoc.Doc(queryTableSizesSQL)) + if err != nil { return nil, err - } else { - for rows.Next() { - var database, table, partitions, parts, bytes, uncompressed, _rows string - if err := rows.Scan(&database, &table, &partitions, &parts, &bytes, &uncompressed, &_rows); err == nil { - data = append(data, []string{database, table, partitions, parts, bytes, uncompressed, _rows}) - } else { - // Skip erroneous line - } + } + for rows.Next() { + var database, table, partitions, parts, bytes, uncompressed, _rows string + if err := rows.Scan(&database, &table, &partitions, &parts, &bytes, &uncompressed, &_rows); err == nil { + data = append(data, []string{database, table, partitions, parts, bytes, uncompressed, _rows}) + } else { + // Skip erroneous line } } return data, nil diff --git a/pkg/apis/metrics/exporter.go b/pkg/apis/metrics/exporter.go index b2f96fd79..1b1fc3e9d 100644 --- a/pkg/apis/metrics/exporter.go +++ b/pkg/apis/metrics/exporter.go @@ -190,7 +190,7 @@ func (e *Exporter) newFetcher(hostname string) *ClickHouseFetcher { return NewClickHouseFetcher(hostname, e.chAccessInfo.Username, e.chAccessInfo.Password, e.chAccessInfo.Port) } -// Ensure hostnames of the Pods from CHI object included into chopmetrics.Exporter state +// UpdateWatch ensures hostnames of the Pods from CHI object included into chopmetrics.Exporter state func (e *Exporter) UpdateWatch(namespace, chiName string, hostnames []string) { chi := &WatchedChi{ Namespace: namespace,