diff --git a/cmd/influxd/run/server.go b/cmd/influxd/run/server.go index 49549e569ab..8d4af811e2e 100644 --- a/cmd/influxd/run/server.go +++ b/cmd/influxd/run/server.go @@ -199,7 +199,7 @@ func NewServer(c *Config, buildInfo *BuildInfo) (*Server, error) { config: c, } - s.Monitor = monitor.New(s, c.Monitor) + s.Monitor = monitor.New(s, c.Monitor, &c.Data) s.config.registerDiagnostics(s.Monitor) if err := s.MetaClient.Open(); err != nil { diff --git a/monitor/build_info_test.go b/monitor/build_info_test.go index 851ed3b13dd..a7f7280a0ee 100644 --- a/monitor/build_info_test.go +++ b/monitor/build_info_test.go @@ -5,10 +5,11 @@ import ( "testing" "github.com/influxdata/influxdb/monitor" + "github.com/influxdata/influxdb/tsdb" ) func TestDiagnostics_BuildInfo(t *testing.T) { - s := monitor.New(nil, monitor.Config{}) + s := monitor.New(nil, monitor.Config{}, &tsdb.Config{}) s.Version = "1.2.0" s.Commit = "b7bb7e8359642b6e071735b50ae41f5eb343fd42" s.Branch = "1.2" diff --git a/monitor/go_runtime_test.go b/monitor/go_runtime_test.go index dc52b662386..ecfd715d837 100644 --- a/monitor/go_runtime_test.go +++ b/monitor/go_runtime_test.go @@ -6,10 +6,11 @@ import ( "testing" "github.com/influxdata/influxdb/monitor" + "github.com/influxdata/influxdb/tsdb" ) func TestDiagnostics_GoRuntime(t *testing.T) { - s := monitor.New(nil, monitor.Config{}) + s := monitor.New(nil, monitor.Config{}, &tsdb.Config{}) if err := s.Open(); err != nil { t.Fatalf("unexpected error: %s", err) } diff --git a/monitor/network_test.go b/monitor/network_test.go index 0615e0a11cd..29e3a1190f3 100644 --- a/monitor/network_test.go +++ b/monitor/network_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/influxdata/influxdb/monitor" + "github.com/influxdata/influxdb/tsdb" ) func TestDiagnostics_Network(t *testing.T) { @@ -14,7 +15,7 @@ func TestDiagnostics_Network(t *testing.T) { t.Fatalf("unexpected error retrieving hostname: %s", err) } - s := monitor.New(nil, monitor.Config{}) + s := monitor.New(nil, monitor.Config{}, &tsdb.Config{}) if err := s.Open(); err != nil { t.Fatalf("unexpected error: %s", err) } diff --git a/monitor/service.go b/monitor/service.go index dfa286804ad..56aa821a235 100644 --- a/monitor/service.go +++ b/monitor/service.go @@ -17,6 +17,7 @@ import ( "github.com/influxdata/influxdb/models" "github.com/influxdata/influxdb/monitor/diagnostics" "github.com/influxdata/influxdb/services/meta" + "github.com/influxdata/influxdb/tsdb" "go.uber.org/zap" ) @@ -96,6 +97,9 @@ type Monitor struct { // Writer for pushing stats back into the database. PointsWriter PointsWriter + // TSDB configuration for diagnostics + TSDBConfig *tsdb.Config + Logger *zap.Logger } @@ -105,7 +109,7 @@ type PointsWriter interface { } // New returns a new instance of the monitor system. -func New(r Reporter, c Config) *Monitor { +func New(r Reporter, c Config, tsdbConfig *tsdb.Config) *Monitor { return &Monitor{ globalTags: newTags(), diagRegistrations: make(map[string]diagnostics.Client), @@ -114,6 +118,7 @@ func New(r Reporter, c Config) *Monitor { storeDatabase: c.StoreDatabase, storeInterval: time.Duration(c.StoreInterval), storeRetentionPolicy: MonitorRetentionPolicy, + TSDBConfig: tsdbConfig, Logger: zap.NewNop(), } } @@ -145,6 +150,9 @@ func (m *Monitor) Open() error { m.RegisterDiagnosticsClient("runtime", &goRuntime{}) m.RegisterDiagnosticsClient("network", &network{}) m.RegisterDiagnosticsClient("system", &system{}) + if m.TSDBConfig != nil { + m.RegisterDiagnosticsClient("config", m.TSDBConfig) + } m.mu.Lock() m.done = make(chan struct{}) diff --git a/monitor/service_test.go b/monitor/service_test.go index 82be9e988e5..eccb2d6a28e 100644 --- a/monitor/service_test.go +++ b/monitor/service_test.go @@ -15,12 +15,13 @@ import ( "github.com/influxdata/influxdb/monitor" "github.com/influxdata/influxdb/services/meta" "github.com/influxdata/influxdb/toml" + "github.com/influxdata/influxdb/tsdb" "go.uber.org/zap" "go.uber.org/zap/zaptest/observer" ) func TestMonitor_Open(t *testing.T) { - s := monitor.New(nil, monitor.Config{}) + s := monitor.New(nil, monitor.Config{}, &tsdb.Config{}) if err := s.Open(); err != nil { t.Fatalf("unexpected open error: %s", err) } @@ -48,7 +49,7 @@ func TestMonitor_SetPointsWriter_StoreEnabled(t *testing.T) { } config := monitor.NewConfig() - s := monitor.New(nil, config) + s := monitor.New(nil, config, &tsdb.Config{}) s.MetaClient = &mc core, logs := observer.New(zap.DebugLevel) s.WithLogger(zap.New(core)) @@ -67,7 +68,7 @@ func TestMonitor_SetPointsWriter_StoreEnabled(t *testing.T) { } func TestMonitor_SetPointsWriter_StoreDisabled(t *testing.T) { - s := monitor.New(nil, monitor.Config{}) + s := monitor.New(nil, monitor.Config{}, &tsdb.Config{}) core, logs := observer.New(zap.DebugLevel) s.WithLogger(zap.New(core)) @@ -134,7 +135,7 @@ func TestMonitor_StoreStatistics(t *testing.T) { config := monitor.NewConfig() config.StoreInterval = toml.Duration(10 * time.Millisecond) - s := monitor.New(nil, config) + s := monitor.New(nil, config, &tsdb.Config{}) s.MetaClient = &mc s.PointsWriter = &pw @@ -210,7 +211,7 @@ func TestMonitor_Reporter(t *testing.T) { config := monitor.NewConfig() config.StoreInterval = toml.Duration(10 * time.Millisecond) - s := monitor.New(reporter, config) + s := monitor.New(reporter, config, &tsdb.Config{}) s.MetaClient = &mc s.PointsWriter = &pw @@ -306,7 +307,7 @@ func TestMonitor_Expvar(t *testing.T) { config := monitor.NewConfig() config.StoreInterval = toml.Duration(10 * time.Millisecond) - s := monitor.New(nil, config) + s := monitor.New(nil, config, &tsdb.Config{}) s.MetaClient = &mc s.PointsWriter = &pw @@ -400,7 +401,7 @@ func TestMonitor_QuickClose(t *testing.T) { var pw PointsWriter config := monitor.NewConfig() config.StoreInterval = toml.Duration(24 * time.Hour) - s := monitor.New(nil, config) + s := monitor.New(nil, config, &tsdb.Config{}) s.MetaClient = &mc s.PointsWriter = &pw diff --git a/monitor/system_test.go b/monitor/system_test.go index 923345b8961..c6274e9a297 100644 --- a/monitor/system_test.go +++ b/monitor/system_test.go @@ -7,10 +7,11 @@ import ( "time" "github.com/influxdata/influxdb/monitor" + "github.com/influxdata/influxdb/tsdb" ) func TestDiagnostics_System(t *testing.T) { - s := monitor.New(nil, monitor.Config{}) + s := monitor.New(nil, monitor.Config{}, &tsdb.Config{}) if err := s.Open(); err != nil { t.Fatalf("unexpected error: %s", err) } diff --git a/services/httpd/handler.go b/services/httpd/handler.go index aaba02596d3..d12e9dab857 100644 --- a/services/httpd/handler.go +++ b/services/httpd/handler.go @@ -36,6 +36,7 @@ import ( "github.com/influxdata/influxdb/services/storage" "github.com/influxdata/influxdb/storage/reads" "github.com/influxdata/influxdb/storage/reads/datatypes" + "github.com/influxdata/influxdb/toml" "github.com/influxdata/influxdb/tsdb" "github.com/influxdata/influxdb/uuid" "github.com/influxdata/influxql" @@ -2298,6 +2299,34 @@ func (h *Handler) serveExpvar(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "\"cmdline\": %s", val) } + if val := diags["config"]; val != nil { + jv, err := parseConfigDiagnostics(val) + if err != nil { + h.httpError(w, err.Error(), http.StatusInternalServerError) + return + } + + data, err := json.Marshal(jv) + if err != nil { + h.httpError(w, err.Error(), http.StatusInternalServerError) + return + } + + if !first { + _, err := fmt.Fprintln(w, ",") + if err != nil { + h.httpError(w, err.Error(), http.StatusInternalServerError) + return + } + } + first = false + _, err = fmt.Fprintf(w, "\"config\": %s", data) + if err != nil { + h.httpError(w, err.Error(), http.StatusInternalServerError) + return + } + } + // We're going to print some kind of crypto data, we just // need to find the proper source for it. { @@ -2564,6 +2593,33 @@ func parseCryptoDiagnostics(d *diagnostics.Diagnostics) (map[string]interface{}, return m, nil } +// parseConfigDiagnostics converts the config diagnostics into proper format +// for JSON marshaling, handling toml.Size and toml.Duration types properly. +func parseConfigDiagnostics(d *diagnostics.Diagnostics) (map[string]interface{}, error) { + if len(d.Rows) == 0 { + return nil, fmt.Errorf("no config diagnostic data available") + } + + m := make(map[string]interface{}) + for i, col := range d.Columns { + if i >= len(d.Rows[0]) { + continue + } + + val := d.Rows[0][i] + switch v := val.(type) { + case toml.Size: + m[col] = uint64(v) + case toml.Duration: + m[col] = time.Duration(v).String() + default: + m[col] = v + } + } + + return m, nil +} + // httpError writes an error to the client in a standard format. func (h *Handler) httpError(w http.ResponseWriter, errmsg string, code int) { if code == http.StatusUnauthorized { diff --git a/tsdb/config.go b/tsdb/config.go index 7d5e5d1d779..60d4d9071d8 100644 --- a/tsdb/config.go +++ b/tsdb/config.go @@ -286,5 +286,8 @@ func (c Config) Diagnostics() (*diagnostics.Diagnostics, error) { "max-index-log-file-size": c.MaxIndexLogFileSize, "series-id-set-cache-size": c.SeriesIDSetCacheSize, "series-file-max-concurrent-compactions": c.SeriesFileMaxConcurrentSnapshotCompactions, + "aggressive-points-per-block": c.AggressivePointsPerBlock, + "compact-throughput": c.CompactThroughput, + "compact-throughput-burst": c.CompactThroughputBurst, }), nil }