From 9bd14b283fc013790fad77693da008e9cc1ea773 Mon Sep 17 00:00:00 2001 From: Greg Date: Wed, 12 Sep 2018 02:03:59 -0600 Subject: [PATCH] Add support for couchdb 2.0+ API (#4654) --- plugins/inputs/couchdb/README.md | 196 +-------------- plugins/inputs/couchdb/couchdb.go | 291 +++++++++++++++-------- plugins/inputs/couchdb/couchdb_test.go | 9 +- plugins/inputs/couchdb/dev/telegraf.conf | 9 + 4 files changed, 207 insertions(+), 298 deletions(-) create mode 100644 plugins/inputs/couchdb/dev/telegraf.conf diff --git a/plugins/inputs/couchdb/README.md b/plugins/inputs/couchdb/README.md index 686914583..0af06cc54 100644 --- a/plugins/inputs/couchdb/README.md +++ b/plugins/inputs/couchdb/README.md @@ -62,194 +62,12 @@ httpd statistics: ### Example output: +**Post Couchdb 2.0** ``` -➜ telegraf git:(master) ✗ ./telegraf --config ./config.conf --input-filter couchdb --test -* Plugin: couchdb, - Collection 1 -> couchdb,server=http://localhost:5984/_stats couchdb_auth_cache_hits_current=0, -couchdb_auth_cache_hits_max=0, -couchdb_auth_cache_hits_mean=0, -couchdb_auth_cache_hits_min=0, -couchdb_auth_cache_hits_stddev=0, -couchdb_auth_cache_hits_sum=0, -couchdb_auth_cache_misses_current=0, -couchdb_auth_cache_misses_max=0, -couchdb_auth_cache_misses_mean=0, -couchdb_auth_cache_misses_min=0, -couchdb_auth_cache_misses_stddev=0, -couchdb_auth_cache_misses_sum=0, -couchdb_database_reads_current=0, -couchdb_database_reads_max=0, -couchdb_database_reads_mean=0, -couchdb_database_reads_min=0, -couchdb_database_reads_stddev=0, -couchdb_database_reads_sum=0, -couchdb_database_writes_current=1102, -couchdb_database_writes_max=131, -couchdb_database_writes_mean=0.116, -couchdb_database_writes_min=0, -couchdb_database_writes_stddev=3.536, -couchdb_database_writes_sum=1102, -couchdb_open_databases_current=1, -couchdb_open_databases_max=1, -couchdb_open_databases_mean=0, -couchdb_open_databases_min=0, -couchdb_open_databases_stddev=0.01, -couchdb_open_databases_sum=1, -couchdb_open_os_files_current=2, -couchdb_open_os_files_max=2, -couchdb_open_os_files_mean=0, -couchdb_open_os_files_min=0, -couchdb_open_os_files_stddev=0.02, -couchdb_open_os_files_sum=2, -couchdb_request_time_current=242.21, -couchdb_request_time_max=102, -couchdb_request_time_mean=5.767, -couchdb_request_time_min=1, -couchdb_request_time_stddev=17.369, -couchdb_request_time_sum=242.21, -httpd_bulk_requests_current=0, -httpd_bulk_requests_max=0, -httpd_bulk_requests_mean=0, -httpd_bulk_requests_min=0, -httpd_bulk_requests_stddev=0, -httpd_bulk_requests_sum=0, -httpd_clients_requesting_changes_current=0, -httpd_clients_requesting_changes_max=0, -httpd_clients_requesting_changes_mean=0, -httpd_clients_requesting_changes_min=0, -httpd_clients_requesting_changes_stddev=0, -httpd_clients_requesting_changes_sum=0, -httpd_request_methods_copy_current=0, -httpd_request_methods_copy_max=0, -httpd_request_methods_copy_mean=0, -httpd_request_methods_copy_min=0, -httpd_request_methods_copy_stddev=0, -httpd_request_methods_copy_sum=0, -httpd_request_methods_delete_current=0, -httpd_request_methods_delete_max=0, -httpd_request_methods_delete_mean=0, -httpd_request_methods_delete_min=0, -httpd_request_methods_delete_stddev=0, -httpd_request_methods_delete_sum=0, -httpd_request_methods_get_current=31, -httpd_request_methods_get_max=1, -httpd_request_methods_get_mean=0.003, -httpd_request_methods_get_min=0, -httpd_request_methods_get_stddev=0.057, -httpd_request_methods_get_sum=31, -httpd_request_methods_head_current=0, -httpd_request_methods_head_max=0, -httpd_request_methods_head_mean=0, -httpd_request_methods_head_min=0, -httpd_request_methods_head_stddev=0, -httpd_request_methods_head_sum=0, -httpd_request_methods_post_current=1102, -httpd_request_methods_post_max=131, -httpd_request_methods_post_mean=0.116, -httpd_request_methods_post_min=0, -httpd_request_methods_post_stddev=3.536, -httpd_request_methods_post_sum=1102, -httpd_request_methods_put_current=1, -httpd_request_methods_put_max=1, -httpd_request_methods_put_mean=0, -httpd_request_methods_put_min=0, -httpd_request_methods_put_stddev=0.01, -httpd_request_methods_put_sum=1, -httpd_requests_current=1133, -httpd_requests_max=130, -httpd_requests_mean=0.118, -httpd_requests_min=0, -httpd_requests_stddev=3.512, -httpd_requests_sum=1133, -httpd_status_codes_200_current=31, -httpd_status_codes_200_max=1, -httpd_status_codes_200_mean=0.003, -httpd_status_codes_200_min=0, -httpd_status_codes_200_stddev=0.057, -httpd_status_codes_200_sum=31, -httpd_status_codes_201_current=1103, -httpd_status_codes_201_max=130, -httpd_status_codes_201_mean=0.116, -httpd_status_codes_201_min=0, -httpd_status_codes_201_stddev=3.532, -httpd_status_codes_201_sum=1103, -httpd_status_codes_202_current=0, -httpd_status_codes_202_max=0, -httpd_status_codes_202_mean=0, -httpd_status_codes_202_min=0, -httpd_status_codes_202_stddev=0, -httpd_status_codes_202_sum=0, -httpd_status_codes_301_current=0, -httpd_status_codes_301_max=0, -httpd_status_codes_301_mean=0, -httpd_status_codes_301_min=0, -httpd_status_codes_301_stddev=0, -httpd_status_codes_301_sum=0, -httpd_status_codes_304_current=0, -httpd_status_codes_304_max=0, -httpd_status_codes_304_mean=0, -httpd_status_codes_304_min=0, -httpd_status_codes_304_stddev=0, -httpd_status_codes_304_sum=0, -httpd_status_codes_400_current=0, -httpd_status_codes_400_max=0, -httpd_status_codes_400_mean=0, -httpd_status_codes_400_min=0, -httpd_status_codes_400_stddev=0, -httpd_status_codes_400_sum=0, -httpd_status_codes_401_current=0, -httpd_status_codes_401_max=0, -httpd_status_codes_401_mean=0, -httpd_status_codes_401_min=0, -httpd_status_codes_401_stddev=0, -httpd_status_codes_401_sum=0, -httpd_status_codes_403_current=0, -httpd_status_codes_403_max=0, -httpd_status_codes_403_mean=0, -httpd_status_codes_403_min=0, -httpd_status_codes_403_stddev=0, -httpd_status_codes_403_sum=0, -httpd_status_codes_404_current=0, -httpd_status_codes_404_max=0, -httpd_status_codes_404_mean=0, -httpd_status_codes_404_min=0, -httpd_status_codes_404_stddev=0, -httpd_status_codes_404_sum=0, -httpd_status_codes_405_current=0, -httpd_status_codes_405_max=0, -httpd_status_codes_405_mean=0, -httpd_status_codes_405_min=0, -httpd_status_codes_405_stddev=0, -httpd_status_codes_405_sum=0, -httpd_status_codes_409_current=0, -httpd_status_codes_409_max=0, -httpd_status_codes_409_mean=0, -httpd_status_codes_409_min=0, -httpd_status_codes_409_stddev=0, -httpd_status_codes_409_sum=0, -httpd_status_codes_412_current=0, -httpd_status_codes_412_max=0, -httpd_status_codes_412_mean=0, -httpd_status_codes_412_min=0, -httpd_status_codes_412_stddev=0, -httpd_status_codes_412_sum=0, -httpd_status_codes_500_current=0, -httpd_status_codes_500_max=0, -httpd_status_codes_500_mean=0, -httpd_status_codes_500_min=0, -httpd_status_codes_500_stddev=0, -httpd_status_codes_500_sum=0, -httpd_temporary_view_reads_current=0, -httpd_temporary_view_reads_max=0, -httpd_temporary_view_reads_mean=0, -httpd_temporary_view_reads_min=0, -httpd_temporary_view_reads_stddev=0, -httpd_temporary_view_reads_sum=0, -httpd_view_reads_current=0, -httpd_view_reads_max=0, -httpd_view_reads_mean=0, -httpd_view_reads_min=0, -httpd_view_reads_stddev=0, -httpd_view_reads_sum=0 1454692257621938169 +couchdb,server=http://couchdb22:5984/_node/_local/_stats couchdb_auth_cache_hits_value=0,httpd_request_methods_delete_value=0,couchdb_auth_cache_misses_value=0,httpd_request_methods_get_value=42,httpd_status_codes_304_value=0,httpd_status_codes_400_value=0,httpd_request_methods_head_value=0,httpd_status_codes_201_value=0,couchdb_database_reads_value=0,httpd_request_methods_copy_value=0,couchdb_request_time_max=0,httpd_status_codes_200_value=42,httpd_status_codes_301_value=0,couchdb_open_os_files_value=2,httpd_request_methods_put_value=0,httpd_request_methods_post_value=0,httpd_status_codes_202_value=0,httpd_status_codes_403_value=0,httpd_status_codes_409_value=0,couchdb_database_writes_value=0,couchdb_request_time_min=0,httpd_status_codes_412_value=0,httpd_status_codes_500_value=0,httpd_status_codes_401_value=0,httpd_status_codes_404_value=0,httpd_status_codes_405_value=0,couchdb_open_databases_value=0 1536707179000000000 +``` + +**Pre Couchdb 2.0** +``` +couchdb,server=http://couchdb16:5984/_stats couchdb_request_time_sum=96,httpd_status_codes_200_sum=37,httpd_status_codes_200_min=0,httpd_requests_mean=0.005,httpd_requests_min=0,couchdb_request_time_stddev=3.833,couchdb_request_time_min=1,httpd_request_methods_get_stddev=0.073,httpd_request_methods_get_min=0,httpd_status_codes_200_mean=0.005,httpd_status_codes_200_max=1,httpd_requests_sum=37,couchdb_request_time_current=96,httpd_request_methods_get_sum=37,httpd_request_methods_get_mean=0.005,httpd_request_methods_get_max=1,httpd_status_codes_200_stddev=0.073,couchdb_request_time_mean=2.595,couchdb_request_time_max=25,httpd_request_methods_get_current=37,httpd_status_codes_200_current=37,httpd_requests_current=37,httpd_requests_stddev=0.073,httpd_requests_max=1 1536707179000000000 ``` diff --git a/plugins/inputs/couchdb/couchdb.go b/plugins/inputs/couchdb/couchdb.go index da6ba67dc..bc9f31688 100644 --- a/plugins/inputs/couchdb/couchdb.go +++ b/plugins/inputs/couchdb/couchdb.go @@ -3,44 +3,52 @@ package couchdb import ( "encoding/json" "fmt" - "github.com/influxdata/telegraf" - "github.com/influxdata/telegraf/plugins/inputs" "net/http" - "reflect" "sync" "time" + + "github.com/influxdata/telegraf" + "github.com/influxdata/telegraf/plugins/inputs" ) -// Schema: -type metaData struct { - Description string `json:"description"` - Current float64 `json:"current"` - Sum float64 `json:"sum"` - Mean float64 `json:"mean"` - Stddev float64 `json:"stddev"` - Min float64 `json:"min"` - Max float64 `json:"max"` -} +type ( + metaData struct { + Current *float64 `json:"current"` + Sum *float64 `json:"sum"` + Mean *float64 `json:"mean"` + Stddev *float64 `json:"stddev"` + Min *float64 `json:"min"` + Max *float64 `json:"max"` + Value *float64 `json:"value"` + } -type Stats struct { - Couchdb struct { - AuthCacheMisses metaData `json:"auth_cache_misses"` - DatabaseWrites metaData `json:"database_writes"` - OpenDatabases metaData `json:"open_databases"` - AuthCacheHits metaData `json:"auth_cache_hits"` - RequestTime metaData `json:"request_time"` - DatabaseReads metaData `json:"database_reads"` - OpenOsFiles metaData `json:"open_os_files"` - } `json:"couchdb"` - HttpdRequestMethods struct { + oldValue struct { + Value metaData `json:"value"` + metaData + } + + couchdb struct { + AuthCacheHits metaData `json:"auth_cache_hits"` + AuthCacheMisses metaData `json:"auth_cache_misses"` + DatabaseWrites metaData `json:"database_writes"` + DatabaseReads metaData `json:"database_reads"` + OpenDatabases metaData `json:"open_databases"` + OpenOsFiles metaData `json:"open_os_files"` + RequestTime oldValue `json:"request_time"` + HttpdRequestMethods httpdRequestMethods `json:"httpd_request_methods"` + HttpdStatusCodes httpdStatusCodes `json:"httpd_status_codes"` + } + + httpdRequestMethods struct { Put metaData `json:"PUT"` Get metaData `json:"GET"` Copy metaData `json:"COPY"` Delete metaData `json:"DELETE"` Post metaData `json:"POST"` Head metaData `json:"HEAD"` - } `json:"httpd_request_methods"` - HttpdStatusCodes struct { + } + + httpdStatusCodes struct { Status200 metaData `json:"200"` Status201 metaData `json:"201"` Status202 metaData `json:"202"` @@ -54,19 +62,29 @@ type Stats struct { Status409 metaData `json:"409"` Status412 metaData `json:"412"` Status500 metaData `json:"500"` - } `json:"httpd_status_codes"` - Httpd struct { - ClientsRequestingChanges metaData `json:"clients_requesting_changes"` - TemporaryViewReads metaData `json:"temporary_view_reads"` - Requests metaData `json:"requests"` - BulkRequests metaData `json:"bulk_requests"` - ViewReads metaData `json:"view_reads"` - } `json:"httpd"` -} + } -type CouchDB struct { - HOSTs []string `toml:"hosts"` -} + httpd struct { + BulkRequests metaData `json:"bulk_requests"` + Requests metaData `json:"requests"` + TemporaryViewReads metaData `json:"temporary_view_reads"` + ViewReads metaData `json:"view_reads"` + ClientsRequestingChanges metaData `json:"clients_requesting_changes"` + } + + Stats struct { + Couchdb couchdb `json:"couchdb"` + HttpdRequestMethods httpdRequestMethods `json:"httpd_request_methods"` + HttpdStatusCodes httpdStatusCodes `json:"httpd_status_codes"` + Httpd httpd `json:"httpd"` + } + + CouchDB struct { + Hosts []string `toml:"hosts"` + + client *http.Client + } +) func (*CouchDB) Description() string { return "Read CouchDB Stats from one or more servers" @@ -75,14 +93,14 @@ func (*CouchDB) Description() string { func (*CouchDB) SampleConfig() string { return ` ## Works with CouchDB stats endpoints out of the box - ## Multiple HOSTs from which to read CouchDB stats: + ## Multiple Hosts from which to read CouchDB stats: hosts = ["http://localhost:8086/_stats"] ` } func (c *CouchDB) Gather(accumulator telegraf.Accumulator) error { var wg sync.WaitGroup - for _, u := range c.HOSTs { + for _, u := range c.Hosts { wg.Add(1) go func(host string) { defer wg.Done() @@ -97,67 +115,125 @@ func (c *CouchDB) Gather(accumulator telegraf.Accumulator) error { return nil } -var tr = &http.Transport{ - ResponseHeaderTimeout: time.Duration(3 * time.Second), -} - -var client = &http.Client{ - Transport: tr, - Timeout: time.Duration(4 * time.Second), -} - func (c *CouchDB) fetchAndInsertData(accumulator telegraf.Accumulator, host string) error { - - response, error := client.Get(host) + if c.client == nil { + c.client = &http.Client{ + Transport: &http.Transport{ + ResponseHeaderTimeout: time.Duration(3 * time.Second), + }, + Timeout: time.Duration(4 * time.Second), + } + } + response, error := c.client.Get(host) if error != nil { return error } defer response.Body.Close() - var stats Stats + if response.StatusCode != 200 { + return fmt.Errorf("Failed to get stats from couchdb: HTTP responded %d", response.StatusCode) + } + + stats := Stats{} decoder := json.NewDecoder(response.Body) decoder.Decode(&stats) fields := map[string]interface{}{} + // for couchdb 2.0 API changes + requestTime := metaData{ + Current: stats.Couchdb.RequestTime.Current, + Sum: stats.Couchdb.RequestTime.Sum, + Mean: stats.Couchdb.RequestTime.Mean, + Stddev: stats.Couchdb.RequestTime.Stddev, + Min: stats.Couchdb.RequestTime.Min, + Max: stats.Couchdb.RequestTime.Max, + } + + httpdRequestMethodsPut := stats.HttpdRequestMethods.Put + httpdRequestMethodsGet := stats.HttpdRequestMethods.Get + httpdRequestMethodsCopy := stats.HttpdRequestMethods.Copy + httpdRequestMethodsDelete := stats.HttpdRequestMethods.Delete + httpdRequestMethodsPost := stats.HttpdRequestMethods.Post + httpdRequestMethodsHead := stats.HttpdRequestMethods.Head + + httpdStatusCodesStatus200 := stats.HttpdStatusCodes.Status200 + httpdStatusCodesStatus201 := stats.HttpdStatusCodes.Status201 + httpdStatusCodesStatus202 := stats.HttpdStatusCodes.Status202 + httpdStatusCodesStatus301 := stats.HttpdStatusCodes.Status301 + httpdStatusCodesStatus304 := stats.HttpdStatusCodes.Status304 + httpdStatusCodesStatus400 := stats.HttpdStatusCodes.Status400 + httpdStatusCodesStatus401 := stats.HttpdStatusCodes.Status401 + httpdStatusCodesStatus403 := stats.HttpdStatusCodes.Status403 + httpdStatusCodesStatus404 := stats.HttpdStatusCodes.Status404 + httpdStatusCodesStatus405 := stats.HttpdStatusCodes.Status405 + httpdStatusCodesStatus409 := stats.HttpdStatusCodes.Status409 + httpdStatusCodesStatus412 := stats.HttpdStatusCodes.Status412 + httpdStatusCodesStatus500 := stats.HttpdStatusCodes.Status500 + // check if couchdb2.0 is used + if stats.Couchdb.HttpdRequestMethods.Get.Value != nil { + requestTime = stats.Couchdb.RequestTime.Value + + httpdRequestMethodsPut = stats.Couchdb.HttpdRequestMethods.Put + httpdRequestMethodsGet = stats.Couchdb.HttpdRequestMethods.Get + httpdRequestMethodsCopy = stats.Couchdb.HttpdRequestMethods.Copy + httpdRequestMethodsDelete = stats.Couchdb.HttpdRequestMethods.Delete + httpdRequestMethodsPost = stats.Couchdb.HttpdRequestMethods.Post + httpdRequestMethodsHead = stats.Couchdb.HttpdRequestMethods.Head + + httpdStatusCodesStatus200 = stats.Couchdb.HttpdStatusCodes.Status200 + httpdStatusCodesStatus201 = stats.Couchdb.HttpdStatusCodes.Status201 + httpdStatusCodesStatus202 = stats.Couchdb.HttpdStatusCodes.Status202 + httpdStatusCodesStatus301 = stats.Couchdb.HttpdStatusCodes.Status301 + httpdStatusCodesStatus304 = stats.Couchdb.HttpdStatusCodes.Status304 + httpdStatusCodesStatus400 = stats.Couchdb.HttpdStatusCodes.Status400 + httpdStatusCodesStatus401 = stats.Couchdb.HttpdStatusCodes.Status401 + httpdStatusCodesStatus403 = stats.Couchdb.HttpdStatusCodes.Status403 + httpdStatusCodesStatus404 = stats.Couchdb.HttpdStatusCodes.Status404 + httpdStatusCodesStatus405 = stats.Couchdb.HttpdStatusCodes.Status405 + httpdStatusCodesStatus409 = stats.Couchdb.HttpdStatusCodes.Status409 + httpdStatusCodesStatus412 = stats.Couchdb.HttpdStatusCodes.Status412 + httpdStatusCodesStatus500 = stats.Couchdb.HttpdStatusCodes.Status500 + } + // CouchDB meta stats: - c.MapCopy(fields, c.generateFields("couchdb_auth_cache_misses", stats.Couchdb.AuthCacheMisses)) - c.MapCopy(fields, c.generateFields("couchdb_database_writes", stats.Couchdb.DatabaseWrites)) - c.MapCopy(fields, c.generateFields("couchdb_open_databases", stats.Couchdb.OpenDatabases)) - c.MapCopy(fields, c.generateFields("couchdb_auth_cache_hits", stats.Couchdb.AuthCacheHits)) - c.MapCopy(fields, c.generateFields("couchdb_request_time", stats.Couchdb.RequestTime)) - c.MapCopy(fields, c.generateFields("couchdb_database_reads", stats.Couchdb.DatabaseReads)) - c.MapCopy(fields, c.generateFields("couchdb_open_os_files", stats.Couchdb.OpenOsFiles)) + c.generateFields(fields, "couchdb_auth_cache_misses", stats.Couchdb.AuthCacheMisses) + c.generateFields(fields, "couchdb_database_writes", stats.Couchdb.DatabaseWrites) + c.generateFields(fields, "couchdb_open_databases", stats.Couchdb.OpenDatabases) + c.generateFields(fields, "couchdb_auth_cache_hits", stats.Couchdb.AuthCacheHits) + c.generateFields(fields, "couchdb_request_time", requestTime) + c.generateFields(fields, "couchdb_database_reads", stats.Couchdb.DatabaseReads) + c.generateFields(fields, "couchdb_open_os_files", stats.Couchdb.OpenOsFiles) // http request methods stats: - c.MapCopy(fields, c.generateFields("httpd_request_methods_put", stats.HttpdRequestMethods.Put)) - c.MapCopy(fields, c.generateFields("httpd_request_methods_get", stats.HttpdRequestMethods.Get)) - c.MapCopy(fields, c.generateFields("httpd_request_methods_copy", stats.HttpdRequestMethods.Copy)) - c.MapCopy(fields, c.generateFields("httpd_request_methods_delete", stats.HttpdRequestMethods.Delete)) - c.MapCopy(fields, c.generateFields("httpd_request_methods_post", stats.HttpdRequestMethods.Post)) - c.MapCopy(fields, c.generateFields("httpd_request_methods_head", stats.HttpdRequestMethods.Head)) + c.generateFields(fields, "httpd_request_methods_put", httpdRequestMethodsPut) + c.generateFields(fields, "httpd_request_methods_get", httpdRequestMethodsGet) + c.generateFields(fields, "httpd_request_methods_copy", httpdRequestMethodsCopy) + c.generateFields(fields, "httpd_request_methods_delete", httpdRequestMethodsDelete) + c.generateFields(fields, "httpd_request_methods_post", httpdRequestMethodsPost) + c.generateFields(fields, "httpd_request_methods_head", httpdRequestMethodsHead) // status code stats: - c.MapCopy(fields, c.generateFields("httpd_status_codes_200", stats.HttpdStatusCodes.Status200)) - c.MapCopy(fields, c.generateFields("httpd_status_codes_201", stats.HttpdStatusCodes.Status201)) - c.MapCopy(fields, c.generateFields("httpd_status_codes_202", stats.HttpdStatusCodes.Status202)) - c.MapCopy(fields, c.generateFields("httpd_status_codes_301", stats.HttpdStatusCodes.Status301)) - c.MapCopy(fields, c.generateFields("httpd_status_codes_304", stats.HttpdStatusCodes.Status304)) - c.MapCopy(fields, c.generateFields("httpd_status_codes_400", stats.HttpdStatusCodes.Status400)) - c.MapCopy(fields, c.generateFields("httpd_status_codes_401", stats.HttpdStatusCodes.Status401)) - c.MapCopy(fields, c.generateFields("httpd_status_codes_403", stats.HttpdStatusCodes.Status403)) - c.MapCopy(fields, c.generateFields("httpd_status_codes_404", stats.HttpdStatusCodes.Status404)) - c.MapCopy(fields, c.generateFields("httpd_status_codes_405", stats.HttpdStatusCodes.Status405)) - c.MapCopy(fields, c.generateFields("httpd_status_codes_409", stats.HttpdStatusCodes.Status409)) - c.MapCopy(fields, c.generateFields("httpd_status_codes_412", stats.HttpdStatusCodes.Status412)) - c.MapCopy(fields, c.generateFields("httpd_status_codes_500", stats.HttpdStatusCodes.Status500)) + c.generateFields(fields, "httpd_status_codes_200", httpdStatusCodesStatus200) + c.generateFields(fields, "httpd_status_codes_201", httpdStatusCodesStatus201) + c.generateFields(fields, "httpd_status_codes_202", httpdStatusCodesStatus202) + c.generateFields(fields, "httpd_status_codes_301", httpdStatusCodesStatus301) + c.generateFields(fields, "httpd_status_codes_304", httpdStatusCodesStatus304) + c.generateFields(fields, "httpd_status_codes_400", httpdStatusCodesStatus400) + c.generateFields(fields, "httpd_status_codes_401", httpdStatusCodesStatus401) + c.generateFields(fields, "httpd_status_codes_403", httpdStatusCodesStatus403) + c.generateFields(fields, "httpd_status_codes_404", httpdStatusCodesStatus404) + c.generateFields(fields, "httpd_status_codes_405", httpdStatusCodesStatus405) + c.generateFields(fields, "httpd_status_codes_409", httpdStatusCodesStatus409) + c.generateFields(fields, "httpd_status_codes_412", httpdStatusCodesStatus412) + c.generateFields(fields, "httpd_status_codes_500", httpdStatusCodesStatus500) // httpd stats: - c.MapCopy(fields, c.generateFields("httpd_clients_requesting_changes", stats.Httpd.ClientsRequestingChanges)) - c.MapCopy(fields, c.generateFields("httpd_temporary_view_reads", stats.Httpd.TemporaryViewReads)) - c.MapCopy(fields, c.generateFields("httpd_requests", stats.Httpd.Requests)) - c.MapCopy(fields, c.generateFields("httpd_bulk_requests", stats.Httpd.BulkRequests)) - c.MapCopy(fields, c.generateFields("httpd_view_reads", stats.Httpd.ViewReads)) + c.generateFields(fields, "httpd_clients_requesting_changes", stats.Httpd.ClientsRequestingChanges) + c.generateFields(fields, "httpd_temporary_view_reads", stats.Httpd.TemporaryViewReads) + c.generateFields(fields, "httpd_requests", stats.Httpd.Requests) + c.generateFields(fields, "httpd_bulk_requests", stats.Httpd.BulkRequests) + c.generateFields(fields, "httpd_view_reads", stats.Httpd.ViewReads) tags := map[string]string{ "server": host, @@ -166,34 +242,39 @@ func (c *CouchDB) fetchAndInsertData(accumulator telegraf.Accumulator, host stri return nil } -func (*CouchDB) MapCopy(dst, src interface{}) { - dv, sv := reflect.ValueOf(dst), reflect.ValueOf(src) - for _, k := range sv.MapKeys() { - dv.SetMapIndex(k, sv.MapIndex(k)) +func (c *CouchDB) generateFields(fields map[string]interface{}, prefix string, obj metaData) { + if obj.Value != nil { + fields[prefix+"_value"] = *obj.Value } -} - -func (*CouchDB) safeCheck(value interface{}) interface{} { - if value == nil { - return 0.0 + if obj.Current != nil { + fields[prefix+"_current"] = *obj.Current } - return value -} - -func (c *CouchDB) generateFields(prefix string, obj metaData) map[string]interface{} { - fields := map[string]interface{}{ - prefix + "_current": c.safeCheck(obj.Current), - prefix + "_sum": c.safeCheck(obj.Sum), - prefix + "_mean": c.safeCheck(obj.Mean), - prefix + "_stddev": c.safeCheck(obj.Stddev), - prefix + "_min": c.safeCheck(obj.Min), - prefix + "_max": c.safeCheck(obj.Max), + if obj.Sum != nil { + fields[prefix+"_sum"] = *obj.Sum + } + if obj.Mean != nil { + fields[prefix+"_mean"] = *obj.Mean + } + if obj.Stddev != nil { + fields[prefix+"_stddev"] = *obj.Stddev + } + if obj.Min != nil { + fields[prefix+"_min"] = *obj.Min + } + if obj.Max != nil { + fields[prefix+"_max"] = *obj.Max } - return fields } func init() { inputs.Add("couchdb", func() telegraf.Input { - return &CouchDB{} + return &CouchDB{ + client: &http.Client{ + Transport: &http.Transport{ + ResponseHeaderTimeout: time.Duration(3 * time.Second), + }, + Timeout: time.Duration(4 * time.Second), + }, + } }) } diff --git a/plugins/inputs/couchdb/couchdb_test.go b/plugins/inputs/couchdb/couchdb_test.go index 4c0370852..933d6cc8d 100644 --- a/plugins/inputs/couchdb/couchdb_test.go +++ b/plugins/inputs/couchdb/couchdb_test.go @@ -1,12 +1,13 @@ package couchdb_test import ( - "github.com/influxdata/telegraf/plugins/inputs/couchdb" - "github.com/influxdata/telegraf/testutil" - "github.com/stretchr/testify/require" "net/http" "net/http/httptest" "testing" + + "github.com/influxdata/telegraf/plugins/inputs/couchdb" + "github.com/influxdata/telegraf/testutil" + "github.com/stretchr/testify/require" ) func TestBasic(t *testing.T) { @@ -312,7 +313,7 @@ func TestBasic(t *testing.T) { defer fakeServer.Close() plugin := &couchdb.CouchDB{ - HOSTs: []string{fakeServer.URL + "/_stats"}, + Hosts: []string{fakeServer.URL + "/_stats"}, } var acc testutil.Accumulator diff --git a/plugins/inputs/couchdb/dev/telegraf.conf b/plugins/inputs/couchdb/dev/telegraf.conf new file mode 100644 index 000000000..30366e922 --- /dev/null +++ b/plugins/inputs/couchdb/dev/telegraf.conf @@ -0,0 +1,9 @@ +[agent] + interval="1s" + flush_interval="1s" + +[[inputs.couchdb]] + hosts = ["http://couchdb16:5984/_stats", "http://couchdb22:5984/_node/_local/_stats"] + +[[outputs.file]] + files = ["stdout"]