@@ -20,6 +20,7 @@ package index
2020import (
2121 "encoding/json"
2222 "fmt"
23+ "strconv"
2324
2425 "github.com/joeshaw/multierror"
2526
@@ -40,9 +41,12 @@ type Index struct {
4041 Primaries primaries `json:"primaries"`
4142 Total total `json:"total"`
4243
43- Index string `json:"index"`
44- Status string `json:"status"`
45- Shards shardStats `json:"shards"`
44+ Index string `json:"index"`
45+ Status string `json:"status"`
46+ TierPreference string `json:"tier_preference"`
47+ CreationDate int `json:"creation_date"`
48+ Version string `json:"version"`
49+ Shards shardStats `json:"shards"`
4650}
4751
4852type primaries struct {
@@ -180,11 +184,19 @@ type bulkStats struct {
180184
181185func eventsMapping (r mb.ReporterV2 , httpClient * helper.HTTP , info elasticsearch.Info , content []byte , isXpack bool ) error {
182186 clusterStateMetrics := []string {"routing_table" }
183- clusterState , err := elasticsearch .GetClusterState (httpClient , httpClient .GetURI (), clusterStateMetrics )
187+ clusterStateFilterPaths := []string {"routing_table" }
188+ clusterState , err := elasticsearch .GetClusterState (httpClient , httpClient .GetURI (), clusterStateMetrics , clusterStateFilterPaths )
184189 if err != nil {
185190 return fmt .Errorf ("failure retrieving cluster state from Elasticsearch: %w" , err )
186191 }
187192
193+ indicesSettingsPattern := "*,.*"
194+ indicesSettingsFilterPaths := []string {"*.settings.index.creation_date" , "*.settings.index.**._tier_preference" , "*.settings.index.version.created" }
195+ indicesSettings , err := elasticsearch .GetIndexSettings (httpClient , httpClient .GetURI (), indicesSettingsPattern , indicesSettingsFilterPaths )
196+ if err != nil {
197+ return fmt .Errorf ("failure retrieving index settings from Elasticsearch: %w" , err )
198+ }
199+
188200 var indicesStats stats
189201 if err := parseAPIResponse (content , & indicesStats ); err != nil {
190202 return fmt .Errorf ("failure parsing Indices Stats Elasticsearch API response: %w" , err )
@@ -204,6 +216,12 @@ func eventsMapping(r mb.ReporterV2, httpClient *helper.HTTP, info elasticsearch.
204216 continue
205217 }
206218
219+ err = addIndexSettings (& idx , indicesSettings )
220+ if err != nil {
221+ errs = append (errs , fmt .Errorf ("failure adding index settings: %w" , err ))
222+ continue
223+ }
224+
207225 event .ModuleFields .Put ("cluster.id" , info .ClusterID )
208226 event .ModuleFields .Put ("cluster.name" , info .ClusterName )
209227
@@ -271,6 +289,63 @@ func addClusterStateFields(idx *Index, clusterState mapstr.M) error {
271289 return nil
272290}
273291
292+ func addIndexSettings (idx * Index , indicesSettings mapstr.M ) error {
293+
294+ // Recover the index settings for our specific index
295+ indexSettingsValue , err := indicesSettings .GetValue (idx .Index )
296+ if err != nil {
297+ return fmt .Errorf ("failed to get index settings for index %s: %w" , idx .Index , err )
298+ }
299+
300+ indexSettings , ok := indexSettingsValue .(map [string ]interface {})
301+ if ! ok {
302+ return fmt .Errorf ("index settings is not a map for index: %s" , idx .Index )
303+ }
304+
305+ indexCreationDate , err := getIndexSettingForIndex (indexSettings , idx .Index , "index.creation_date" )
306+ if err != nil {
307+ return fmt .Errorf ("failed to get index creation date: %w" , err )
308+ }
309+
310+ idx .CreationDate , err = strconv .Atoi (indexCreationDate )
311+ if err != nil {
312+ return fmt .Errorf ("failed to convert index creation date to int: %w" , err )
313+ }
314+
315+ indexTierPreference , err := getIndexSettingForIndex (indexSettings , idx .Index , "index.routing.allocation.require._tier_preference" )
316+ if err != nil {
317+ indexTierPreference , err = getIndexSettingForIndex (indexSettings , idx .Index , "index.routing.allocation.include._tier_preference" )
318+ if err != nil {
319+ return fmt .Errorf ("failed to get index tier preference: %w" , err )
320+ }
321+ }
322+
323+ idx .TierPreference = indexTierPreference
324+
325+ indexVersion , err := getIndexSettingForIndex (indexSettings , idx .Index , "index.version.created" )
326+ if err != nil {
327+ return fmt .Errorf ("failed to get index version: %w" , err )
328+ }
329+
330+ idx .Version = indexVersion
331+
332+ return nil
333+ }
334+
335+ func getIndexSettingForIndex (indexSettings mapstr.M , index , settingKey string ) (string , error ) {
336+ fieldKey := "settings." + settingKey
337+ value , err := indexSettings .GetValue (fieldKey )
338+ if err != nil {
339+ return "" , fmt .Errorf ("'" + fieldKey + "': %w" , err )
340+ }
341+
342+ setting , ok := value .(string )
343+ if ! ok {
344+ return "" , elastic .MakeErrorForMissingField (fieldKey , elastic .Elasticsearch )
345+ }
346+ return setting , nil
347+ }
348+
274349func getClusterStateMetricForIndex (clusterState mapstr.M , index , metricKey string ) (mapstr.M , error ) {
275350 fieldKey := metricKey + ".indices." + index
276351 value , err := clusterState .GetValue (fieldKey )
@@ -308,8 +383,15 @@ func getIndexStatus(shards map[string]interface{}) (string, error) {
308383
309384 shard := mapstr .M (s )
310385
311- isPrimary := shard ["primary" ].(bool )
312- state := shard ["state" ].(string )
386+ isPrimary , ok := shard ["primary" ].(bool )
387+ if ! ok {
388+ return "" , fmt .Errorf ("%v.shards[%v].primary is not a boolean" , indexName , shardIdx )
389+ }
390+
391+ state , ok := shard ["state" ].(string )
392+ if ! ok {
393+ return "" , fmt .Errorf ("%v.shards[%v].state is not a string" , indexName , shardIdx )
394+ }
313395
314396 if isPrimary {
315397 areAllPrimariesStarted = areAllPrimariesStarted && (state == "STARTED" )
@@ -357,8 +439,15 @@ func getIndexShardStats(shards mapstr.M) (*shardStats, error) {
357439
358440 shard := mapstr .M (s )
359441
360- isPrimary := shard ["primary" ].(bool )
361- state := shard ["state" ].(string )
442+ isPrimary , ok := shard ["primary" ].(bool )
443+ if ! ok {
444+ return nil , fmt .Errorf ("%v.shards[%v].primary is not a boolean" , indexName , shardIdx )
445+ }
446+
447+ state , ok := shard ["state" ].(string )
448+ if ! ok {
449+ return nil , fmt .Errorf ("%v.shards[%v].state is not a string" , indexName , shardIdx )
450+ }
362451
363452 if isPrimary {
364453 primaries ++
0 commit comments