1// Copyright 2012-present Oliver Eilhard. All rights reserved. 2// Use of this source code is governed by a MIT-license. 3// See http://olivere.mit-license.org/license.txt for details. 4 5package elastic 6 7import ( 8 "context" 9 "fmt" 10 "net/url" 11 "strings" 12 13 "github.com/olivere/elastic/uritemplates" 14) 15 16// IndicesStatsService provides stats on various metrics of one or more 17// indices. See https://www.elastic.co/guide/en/elasticsearch/reference/6.7/indices-stats.html. 18type IndicesStatsService struct { 19 client *Client 20 pretty bool 21 metric []string 22 index []string 23 level string 24 types []string 25 completionFields []string 26 fielddataFields []string 27 fields []string 28 groups []string 29 human *bool 30} 31 32// NewIndicesStatsService creates a new IndicesStatsService. 33func NewIndicesStatsService(client *Client) *IndicesStatsService { 34 return &IndicesStatsService{ 35 client: client, 36 index: make([]string, 0), 37 metric: make([]string, 0), 38 completionFields: make([]string, 0), 39 fielddataFields: make([]string, 0), 40 fields: make([]string, 0), 41 groups: make([]string, 0), 42 types: make([]string, 0), 43 } 44} 45 46// Metric limits the information returned the specific metrics. Options are: 47// docs, store, indexing, get, search, completion, fielddata, flush, merge, 48// query_cache, refresh, suggest, and warmer. 49func (s *IndicesStatsService) Metric(metric ...string) *IndicesStatsService { 50 s.metric = append(s.metric, metric...) 51 return s 52} 53 54// Index is the list of index names; use `_all` or empty string to perform 55// the operation on all indices. 56func (s *IndicesStatsService) Index(indices ...string) *IndicesStatsService { 57 s.index = append(s.index, indices...) 58 return s 59} 60 61// Type is a list of document types for the `indexing` index metric. 62func (s *IndicesStatsService) Type(types ...string) *IndicesStatsService { 63 s.types = append(s.types, types...) 64 return s 65} 66 67// Level returns stats aggregated at cluster, index or shard level. 68func (s *IndicesStatsService) Level(level string) *IndicesStatsService { 69 s.level = level 70 return s 71} 72 73// CompletionFields is a list of fields for `fielddata` and `suggest` 74// index metric (supports wildcards). 75func (s *IndicesStatsService) CompletionFields(completionFields ...string) *IndicesStatsService { 76 s.completionFields = append(s.completionFields, completionFields...) 77 return s 78} 79 80// FielddataFields is a list of fields for `fielddata` index metric (supports wildcards). 81func (s *IndicesStatsService) FielddataFields(fielddataFields ...string) *IndicesStatsService { 82 s.fielddataFields = append(s.fielddataFields, fielddataFields...) 83 return s 84} 85 86// Fields is a list of fields for `fielddata` and `completion` index metric 87// (supports wildcards). 88func (s *IndicesStatsService) Fields(fields ...string) *IndicesStatsService { 89 s.fields = append(s.fields, fields...) 90 return s 91} 92 93// Groups is a list of search groups for `search` index metric. 94func (s *IndicesStatsService) Groups(groups ...string) *IndicesStatsService { 95 s.groups = append(s.groups, groups...) 96 return s 97} 98 99// Human indicates whether to return time and byte values in human-readable format.. 100func (s *IndicesStatsService) Human(human bool) *IndicesStatsService { 101 s.human = &human 102 return s 103} 104 105// Pretty indicates that the JSON response be indented and human readable. 106func (s *IndicesStatsService) Pretty(pretty bool) *IndicesStatsService { 107 s.pretty = pretty 108 return s 109} 110 111// buildURL builds the URL for the operation. 112func (s *IndicesStatsService) buildURL() (string, url.Values, error) { 113 var err error 114 var path string 115 if len(s.index) > 0 && len(s.metric) > 0 { 116 path, err = uritemplates.Expand("/{index}/_stats/{metric}", map[string]string{ 117 "index": strings.Join(s.index, ","), 118 "metric": strings.Join(s.metric, ","), 119 }) 120 } else if len(s.index) > 0 { 121 path, err = uritemplates.Expand("/{index}/_stats", map[string]string{ 122 "index": strings.Join(s.index, ","), 123 }) 124 } else if len(s.metric) > 0 { 125 path, err = uritemplates.Expand("/_stats/{metric}", map[string]string{ 126 "metric": strings.Join(s.metric, ","), 127 }) 128 } else { 129 path = "/_stats" 130 } 131 if err != nil { 132 return "", url.Values{}, err 133 } 134 135 // Add query string parameters 136 params := url.Values{} 137 if s.pretty { 138 params.Set("pretty", "true") 139 } 140 if len(s.groups) > 0 { 141 params.Set("groups", strings.Join(s.groups, ",")) 142 } 143 if s.human != nil { 144 params.Set("human", fmt.Sprintf("%v", *s.human)) 145 } 146 if s.level != "" { 147 params.Set("level", s.level) 148 } 149 if len(s.types) > 0 { 150 params.Set("types", strings.Join(s.types, ",")) 151 } 152 if len(s.completionFields) > 0 { 153 params.Set("completion_fields", strings.Join(s.completionFields, ",")) 154 } 155 if len(s.fielddataFields) > 0 { 156 params.Set("fielddata_fields", strings.Join(s.fielddataFields, ",")) 157 } 158 if len(s.fields) > 0 { 159 params.Set("fields", strings.Join(s.fields, ",")) 160 } 161 return path, params, nil 162} 163 164// Validate checks if the operation is valid. 165func (s *IndicesStatsService) Validate() error { 166 return nil 167} 168 169// Do executes the operation. 170func (s *IndicesStatsService) Do(ctx context.Context) (*IndicesStatsResponse, error) { 171 // Check pre-conditions 172 if err := s.Validate(); err != nil { 173 return nil, err 174 } 175 176 // Get URL for request 177 path, params, err := s.buildURL() 178 if err != nil { 179 return nil, err 180 } 181 182 // Get HTTP response 183 res, err := s.client.PerformRequest(ctx, PerformRequestOptions{ 184 Method: "GET", 185 Path: path, 186 Params: params, 187 }) 188 if err != nil { 189 return nil, err 190 } 191 192 // Return operation response 193 ret := new(IndicesStatsResponse) 194 if err := s.client.decoder.Decode(res.Body, ret); err != nil { 195 return nil, err 196 } 197 return ret, nil 198} 199 200// IndicesStatsResponse is the response of IndicesStatsService.Do. 201type IndicesStatsResponse struct { 202 // Shards provides information returned from shards. 203 Shards *ShardsInfo `json:"_shards"` 204 205 // All provides summary stats about all indices. 206 All *IndexStats `json:"_all,omitempty"` 207 208 // Indices provides a map into the stats of an index. The key of the 209 // map is the index name. 210 Indices map[string]*IndexStats `json:"indices,omitempty"` 211} 212 213// IndexStats is index stats for a specific index. 214type IndexStats struct { 215 Primaries *IndexStatsDetails `json:"primaries,omitempty"` 216 Total *IndexStatsDetails `json:"total,omitempty"` 217 Shards map[string][]*IndexStatsDetails `json:"shards,omitempty"` 218} 219 220type IndexStatsDetails struct { 221 Docs *IndexStatsDocs `json:"docs,omitempty"` 222 Store *IndexStatsStore `json:"store,omitempty"` 223 Indexing *IndexStatsIndexing `json:"indexing,omitempty"` 224 Get *IndexStatsGet `json:"get,omitempty"` 225 Search *IndexStatsSearch `json:"search,omitempty"` 226 Merges *IndexStatsMerges `json:"merges,omitempty"` 227 Refresh *IndexStatsRefresh `json:"refresh,omitempty"` 228 Flush *IndexStatsFlush `json:"flush,omitempty"` 229 Warmer *IndexStatsWarmer `json:"warmer,omitempty"` 230 FilterCache *IndexStatsFilterCache `json:"filter_cache,omitempty"` 231 IdCache *IndexStatsIdCache `json:"id_cache,omitempty"` 232 Fielddata *IndexStatsFielddata `json:"fielddata,omitempty"` 233 Percolate *IndexStatsPercolate `json:"percolate,omitempty"` 234 Completion *IndexStatsCompletion `json:"completion,omitempty"` 235 Segments *IndexStatsSegments `json:"segments,omitempty"` 236 Translog *IndexStatsTranslog `json:"translog,omitempty"` 237 Suggest *IndexStatsSuggest `json:"suggest,omitempty"` 238 QueryCache *IndexStatsQueryCache `json:"query_cache,omitempty"` 239} 240 241type IndexStatsDocs struct { 242 Count int64 `json:"count,omitempty"` 243 Deleted int64 `json:"deleted,omitempty"` 244} 245 246type IndexStatsStore struct { 247 Size string `json:"size,omitempty"` // human size, e.g. 119.3mb 248 SizeInBytes int64 `json:"size_in_bytes,omitempty"` 249} 250 251type IndexStatsIndexing struct { 252 IndexTotal int64 `json:"index_total,omitempty"` 253 IndexTime string `json:"index_time,omitempty"` 254 IndexTimeInMillis int64 `json:"index_time_in_millis,omitempty"` 255 IndexCurrent int64 `json:"index_current,omitempty"` 256 DeleteTotal int64 `json:"delete_total,omitempty"` 257 DeleteTime string `json:"delete_time,omitempty"` 258 DeleteTimeInMillis int64 `json:"delete_time_in_millis,omitempty"` 259 DeleteCurrent int64 `json:"delete_current,omitempty"` 260 NoopUpdateTotal int64 `json:"noop_update_total,omitempty"` 261} 262 263type IndexStatsGet struct { 264 Total int64 `json:"total,omitempty"` 265 GetTime string `json:"get_time,omitempty"` 266 TimeInMillis int64 `json:"time_in_millis,omitempty"` 267 ExistsTotal int64 `json:"exists_total,omitempty"` 268 ExistsTime string `json:"exists_time,omitempty"` 269 ExistsTimeInMillis int64 `json:"exists_time_in_millis,omitempty"` 270 MissingTotal int64 `json:"missing_total,omitempty"` 271 MissingTime string `json:"missing_time,omitempty"` 272 MissingTimeInMillis int64 `json:"missing_time_in_millis,omitempty"` 273 Current int64 `json:"current,omitempty"` 274} 275 276type IndexStatsSearch struct { 277 OpenContexts int64 `json:"open_contexts,omitempty"` 278 QueryTotal int64 `json:"query_total,omitempty"` 279 QueryTime string `json:"query_time,omitempty"` 280 QueryTimeInMillis int64 `json:"query_time_in_millis,omitempty"` 281 QueryCurrent int64 `json:"query_current,omitempty"` 282 FetchTotal int64 `json:"fetch_total,omitempty"` 283 FetchTime string `json:"fetch_time,omitempty"` 284 FetchTimeInMillis int64 `json:"fetch_time_in_millis,omitempty"` 285 FetchCurrent int64 `json:"fetch_current,omitempty"` 286 ScrollTotal int64 `json:"scroll_total,omitempty"` 287 ScrollTime string `json:"scroll_time,omitempty"` 288 ScrollTimeInMillis int64 `json:"scroll_time_in_millis,omitempty"` 289 ScrollCurrent int64 `json:"scroll_current,omitempty"` 290 SuggestTotal int64 `json:"suggest_total,omitempty"` 291 SuggestTime string `json:"suggest_time,omitempty"` 292 SuggestTimeInMillis int64 `json:"suggest_time_in_millis,omitempty"` 293 SuggestCurrent int64 `json:"suggest_current,omitempty"` 294} 295 296type IndexStatsMerges struct { 297 Current int64 `json:"current,omitempty"` 298 CurrentDocs int64 `json:"current_docs,omitempty"` 299 CurrentSize string `json:"current_size,omitempty"` 300 CurrentSizeInBytes int64 `json:"current_size_in_bytes,omitempty"` 301 Total int64 `json:"total,omitempty"` 302 TotalTime string `json:"total_time,omitempty"` 303 TotalTimeInMillis int64 `json:"total_time_in_millis,omitempty"` 304 TotalDocs int64 `json:"total_docs,omitempty"` 305 TotalSize string `json:"total_size,omitempty"` 306 TotalSizeInBytes int64 `json:"total_size_in_bytes,omitempty"` 307} 308 309type IndexStatsRefresh struct { 310 Total int64 `json:"total,omitempty"` 311 TotalTime string `json:"total_time,omitempty"` 312 TotalTimeInMillis int64 `json:"total_time_in_millis,omitempty"` 313} 314 315type IndexStatsFlush struct { 316 Total int64 `json:"total,omitempty"` 317 TotalTime string `json:"total_time,omitempty"` 318 TotalTimeInMillis int64 `json:"total_time_in_millis,omitempty"` 319} 320 321type IndexStatsWarmer struct { 322 Current int64 `json:"current,omitempty"` 323 Total int64 `json:"total,omitempty"` 324 TotalTime string `json:"total_time,omitempty"` 325 TotalTimeInMillis int64 `json:"total_time_in_millis,omitempty"` 326} 327 328type IndexStatsFilterCache struct { 329 MemorySize string `json:"memory_size,omitempty"` 330 MemorySizeInBytes int64 `json:"memory_size_in_bytes,omitempty"` 331 Evictions int64 `json:"evictions,omitempty"` 332} 333 334type IndexStatsIdCache struct { 335 MemorySize string `json:"memory_size,omitempty"` 336 MemorySizeInBytes int64 `json:"memory_size_in_bytes,omitempty"` 337} 338 339type IndexStatsFielddata struct { 340 MemorySize string `json:"memory_size,omitempty"` 341 MemorySizeInBytes int64 `json:"memory_size_in_bytes,omitempty"` 342 Evictions int64 `json:"evictions,omitempty"` 343} 344 345type IndexStatsPercolate struct { 346 Total int64 `json:"total,omitempty"` 347 GetTime string `json:"get_time,omitempty"` 348 TimeInMillis int64 `json:"time_in_millis,omitempty"` 349 Current int64 `json:"current,omitempty"` 350 MemorySize string `json:"memory_size,omitempty"` 351 MemorySizeInBytes int64 `json:"memory_size_in_bytes,omitempty"` 352 Queries int64 `json:"queries,omitempty"` 353} 354 355type IndexStatsCompletion struct { 356 Size string `json:"size,omitempty"` 357 SizeInBytes int64 `json:"size_in_bytes,omitempty"` 358} 359 360type IndexStatsSegments struct { 361 Count int64 `json:"count,omitempty"` 362 Memory string `json:"memory,omitempty"` 363 MemoryInBytes int64 `json:"memory_in_bytes,omitempty"` 364 IndexWriterMemory string `json:"index_writer_memory,omitempty"` 365 IndexWriterMemoryInBytes int64 `json:"index_writer_memory_in_bytes,omitempty"` 366 IndexWriterMaxMemory string `json:"index_writer_max_memory,omitempty"` 367 IndexWriterMaxMemoryInBytes int64 `json:"index_writer_max_memory_in_bytes,omitempty"` 368 VersionMapMemory string `json:"version_map_memory,omitempty"` 369 VersionMapMemoryInBytes int64 `json:"version_map_memory_in_bytes,omitempty"` 370 FixedBitSetMemory string `json:"fixed_bit_set,omitempty"` 371 FixedBitSetMemoryInBytes int64 `json:"fixed_bit_set_memory_in_bytes,omitempty"` 372} 373 374type IndexStatsTranslog struct { 375 Operations int64 `json:"operations,omitempty"` 376 Size string `json:"size,omitempty"` 377 SizeInBytes int64 `json:"size_in_bytes,omitempty"` 378} 379 380type IndexStatsSuggest struct { 381 Total int64 `json:"total,omitempty"` 382 Time string `json:"time,omitempty"` 383 TimeInMillis int64 `json:"time_in_millis,omitempty"` 384 Current int64 `json:"current,omitempty"` 385} 386 387type IndexStatsQueryCache struct { 388 MemorySize string `json:"memory_size,omitempty"` 389 MemorySizeInBytes int64 `json:"memory_size_in_bytes,omitempty"` 390 Evictions int64 `json:"evictions,omitempty"` 391 HitCount int64 `json:"hit_count,omitempty"` 392 MissCount int64 `json:"miss_count,omitempty"` 393} 394