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/http" 11 "net/url" 12 "strings" 13 14 "github.com/olivere/elastic/v7/uritemplates" 15) 16 17// ClusterStatsService is documented at 18// https://www.elastic.co/guide/en/elasticsearch/reference/7.0/cluster-stats.html. 19type ClusterStatsService struct { 20 client *Client 21 22 pretty *bool // pretty format the returned JSON response 23 human *bool // return human readable values for statistics 24 errorTrace *bool // include the stack trace of returned errors 25 filterPath []string // list of filters used to reduce the response 26 headers http.Header // custom request-level HTTP headers 27 28 nodeId []string 29 flatSettings *bool 30} 31 32// NewClusterStatsService creates a new ClusterStatsService. 33func NewClusterStatsService(client *Client) *ClusterStatsService { 34 return &ClusterStatsService{ 35 client: client, 36 nodeId: make([]string, 0), 37 } 38} 39 40// Pretty tells Elasticsearch whether to return a formatted JSON response. 41func (s *ClusterStatsService) Pretty(pretty bool) *ClusterStatsService { 42 s.pretty = &pretty 43 return s 44} 45 46// Human specifies whether human readable values should be returned in 47// the JSON response, e.g. "7.5mb". 48func (s *ClusterStatsService) Human(human bool) *ClusterStatsService { 49 s.human = &human 50 return s 51} 52 53// ErrorTrace specifies whether to include the stack trace of returned errors. 54func (s *ClusterStatsService) ErrorTrace(errorTrace bool) *ClusterStatsService { 55 s.errorTrace = &errorTrace 56 return s 57} 58 59// FilterPath specifies a list of filters used to reduce the response. 60func (s *ClusterStatsService) FilterPath(filterPath ...string) *ClusterStatsService { 61 s.filterPath = filterPath 62 return s 63} 64 65// Header adds a header to the request. 66func (s *ClusterStatsService) Header(name string, value string) *ClusterStatsService { 67 if s.headers == nil { 68 s.headers = http.Header{} 69 } 70 s.headers.Add(name, value) 71 return s 72} 73 74// Headers specifies the headers of the request. 75func (s *ClusterStatsService) Headers(headers http.Header) *ClusterStatsService { 76 s.headers = headers 77 return s 78} 79 80// NodeId is documented as: A comma-separated list of node IDs or names to limit the returned information; use `_local` to return information from the node you're connecting to, leave empty to get information from all nodes. 81func (s *ClusterStatsService) NodeId(nodeId []string) *ClusterStatsService { 82 s.nodeId = nodeId 83 return s 84} 85 86// FlatSettings is documented as: Return settings in flat format (default: false). 87func (s *ClusterStatsService) FlatSettings(flatSettings bool) *ClusterStatsService { 88 s.flatSettings = &flatSettings 89 return s 90} 91 92// buildURL builds the URL for the operation. 93func (s *ClusterStatsService) buildURL() (string, url.Values, error) { 94 // Build URL 95 var err error 96 var path string 97 98 if len(s.nodeId) > 0 { 99 path, err = uritemplates.Expand("/_cluster/stats/nodes/{node_id}", map[string]string{ 100 "node_id": strings.Join(s.nodeId, ","), 101 }) 102 if err != nil { 103 return "", url.Values{}, err 104 } 105 } else { 106 path, err = uritemplates.Expand("/_cluster/stats", map[string]string{}) 107 if err != nil { 108 return "", url.Values{}, err 109 } 110 } 111 112 // Add query string parameters 113 params := url.Values{} 114 if v := s.pretty; v != nil { 115 params.Set("pretty", fmt.Sprint(*v)) 116 } 117 if v := s.human; v != nil { 118 params.Set("human", fmt.Sprint(*v)) 119 } 120 if v := s.errorTrace; v != nil { 121 params.Set("error_trace", fmt.Sprint(*v)) 122 } 123 if len(s.filterPath) > 0 { 124 params.Set("filter_path", strings.Join(s.filterPath, ",")) 125 } 126 if s.flatSettings != nil { 127 params.Set("flat_settings", fmt.Sprintf("%v", *s.flatSettings)) 128 } 129 return path, params, nil 130} 131 132// Validate checks if the operation is valid. 133func (s *ClusterStatsService) Validate() error { 134 return nil 135} 136 137// Do executes the operation. 138func (s *ClusterStatsService) Do(ctx context.Context) (*ClusterStatsResponse, error) { 139 // Check pre-conditions 140 if err := s.Validate(); err != nil { 141 return nil, err 142 } 143 144 // Get URL for request 145 path, params, err := s.buildURL() 146 if err != nil { 147 return nil, err 148 } 149 150 // Get HTTP response 151 res, err := s.client.PerformRequest(ctx, PerformRequestOptions{ 152 Method: "GET", 153 Path: path, 154 Params: params, 155 Headers: s.headers, 156 }) 157 if err != nil { 158 return nil, err 159 } 160 161 // Return operation response 162 ret := new(ClusterStatsResponse) 163 if err := s.client.decoder.Decode(res.Body, ret); err != nil { 164 return nil, err 165 } 166 return ret, nil 167} 168 169// ClusterStatsResponse is the response of ClusterStatsService.Do. 170type ClusterStatsResponse struct { 171 NodesStats *ClusterStatsNodesResponse `json:"_nodes,omitempty"` 172 Timestamp int64 `json:"timestamp"` 173 ClusterName string `json:"cluster_name"` 174 ClusterUUID string `json:"cluster_uuid"` 175 Status string `json:"status,omitempty"` // e.g. green 176 Indices *ClusterStatsIndices `json:"indices"` 177 Nodes *ClusterStatsNodes `json:"nodes"` 178} 179 180type ClusterStatsNodesResponse struct { 181 Total int `json:"total"` 182 Successful int `json:"successful"` 183 Failed int `json:"failed"` 184 Failures []*FailedNodeException `json:"failures,omitempty"` 185} 186 187type ClusterStatsIndices struct { 188 Count int `json:"count"` // number of indices 189 Shards *ClusterStatsIndicesShards `json:"shards"` 190 Docs *ClusterStatsIndicesDocs `json:"docs"` 191 Store *ClusterStatsIndicesStore `json:"store"` 192 FieldData *ClusterStatsIndicesFieldData `json:"fielddata"` 193 QueryCache *ClusterStatsIndicesQueryCache `json:"query_cache"` 194 Completion *ClusterStatsIndicesCompletion `json:"completion"` 195 Segments *IndexStatsSegments `json:"segments"` 196} 197 198type ClusterStatsIndicesShards struct { 199 Total int `json:"total"` 200 Primaries int `json:"primaries"` 201 Replication float64 `json:"replication"` 202 Index *ClusterStatsIndicesShardsIndex `json:"index"` 203} 204 205type ClusterStatsIndicesShardsIndex struct { 206 Shards *ClusterStatsIndicesShardsIndexIntMinMax `json:"shards"` 207 Primaries *ClusterStatsIndicesShardsIndexIntMinMax `json:"primaries"` 208 Replication *ClusterStatsIndicesShardsIndexFloat64MinMax `json:"replication"` 209} 210 211type ClusterStatsIndicesShardsIndexIntMinMax struct { 212 Min int `json:"min"` 213 Max int `json:"max"` 214 Avg float64 `json:"avg"` 215} 216 217type ClusterStatsIndicesShardsIndexFloat64MinMax struct { 218 Min float64 `json:"min"` 219 Max float64 `json:"max"` 220 Avg float64 `json:"avg"` 221} 222 223type ClusterStatsIndicesDocs struct { 224 Count int `json:"count"` 225 Deleted int `json:"deleted"` 226} 227 228type ClusterStatsIndicesStore struct { 229 Size string `json:"size"` // e.g. "5.3gb" 230 SizeInBytes int64 `json:"size_in_bytes"` 231} 232 233type ClusterStatsIndicesFieldData struct { 234 MemorySize string `json:"memory_size"` // e.g. "61.3kb" 235 MemorySizeInBytes int64 `json:"memory_size_in_bytes"` 236 Evictions int64 `json:"evictions"` 237 Fields map[string]struct { 238 MemorySize string `json:"memory_size"` // e.g. "61.3kb" 239 MemorySizeInBytes int64 `json:"memory_size_in_bytes"` 240 } `json:"fields,omitempty"` 241} 242 243type ClusterStatsIndicesQueryCache struct { 244 MemorySize string `json:"memory_size"` // e.g. "61.3kb" 245 MemorySizeInBytes int64 `json:"memory_size_in_bytes"` 246 TotalCount int64 `json:"total_count"` 247 HitCount int64 `json:"hit_count"` 248 MissCount int64 `json:"miss_count"` 249 CacheSize int64 `json:"cache_size"` 250 CacheCount int64 `json:"cache_count"` 251 Evictions int64 `json:"evictions"` 252} 253 254type ClusterStatsIndicesCompletion struct { 255 Size string `json:"size"` // e.g. "61.3kb" 256 SizeInBytes int64 `json:"size_in_bytes"` 257 Fields map[string]struct { 258 Size string `json:"size"` // e.g. "61.3kb" 259 SizeInBytes int64 `json:"size_in_bytes"` 260 } `json:"fields,omitempty"` 261} 262 263type ClusterStatsIndicesSegmentsFile struct { 264 Size string `json:"size"` // e.g. "61.3kb" 265 SizeInBytes int64 `json:"size_in_bytes"` 266 Description string `json:"description,omitempty"` 267} 268 269// --- 270 271type ClusterStatsNodes struct { 272 Count *ClusterStatsNodesCount `json:"count"` 273 Versions []string `json:"versions"` 274 OS *ClusterStatsNodesOsStats `json:"os"` 275 Process *ClusterStatsNodesProcessStats `json:"process"` 276 JVM *ClusterStatsNodesJvmStats `json:"jvm"` 277 FS *ClusterStatsNodesFsStats `json:"fs"` 278 Plugins []*ClusterStatsNodesPlugin `json:"plugins"` 279 280 NetworkTypes *ClusterStatsNodesNetworkTypes `json:"network_types"` 281 DiscoveryTypes *ClusterStatsNodesDiscoveryTypes `json:"discovery_types"` 282 PackagingTypes *ClusterStatsNodesPackagingTypes `json:"packaging_types"` 283} 284 285type ClusterStatsNodesCount struct { 286 Total int `json:"total"` 287 Data int `json:"data"` 288 CoordinatingOnly int `json:"coordinating_only"` 289 Master int `json:"master"` 290 Ingest int `json:"ingest"` 291} 292 293type ClusterStatsNodesOsStats struct { 294 AvailableProcessors int `json:"available_processors"` 295 AllocatedProcessors int `json:"allocated_processors"` 296 Names []struct { 297 Name string `json:"name"` 298 Value int `json:"count"` 299 } `json:"names"` 300 PrettyNames []struct { 301 PrettyName string `json:"pretty_name"` 302 Value int `json:"count"` 303 } `json:"pretty_names"` 304 Mem *ClusterStatsNodesOsStatsMem `json:"mem"` 305 // CPU []*ClusterStatsNodesOsStatsCPU `json:"cpu"` 306} 307 308type ClusterStatsNodesOsStatsMem struct { 309 Total string `json:"total"` // e.g. "16gb" 310 TotalInBytes int64 `json:"total_in_bytes"` 311 Free string `json:"free"` // e.g. "12gb" 312 FreeInBytes int64 `json:"free_in_bytes"` 313 Used string `json:"used"` // e.g. "4gb" 314 UsedInBytes int64 `json:"used_in_bytes"` 315 FreePercent int `json:"free_percent"` 316 UsedPercent int `json:"used_percent"` 317} 318 319type ClusterStatsNodesOsStatsCPU struct { 320 Vendor string `json:"vendor"` 321 Model string `json:"model"` 322 MHz int `json:"mhz"` 323 TotalCores int `json:"total_cores"` 324 TotalSockets int `json:"total_sockets"` 325 CoresPerSocket int `json:"cores_per_socket"` 326 CacheSize string `json:"cache_size"` // e.g. "256b" 327 CacheSizeInBytes int64 `json:"cache_size_in_bytes"` 328 Count int `json:"count"` 329} 330 331type ClusterStatsNodesProcessStats struct { 332 CPU *ClusterStatsNodesProcessStatsCPU `json:"cpu"` 333 OpenFileDescriptors *ClusterStatsNodesProcessStatsOpenFileDescriptors `json:"open_file_descriptors"` 334} 335 336type ClusterStatsNodesProcessStatsCPU struct { 337 Percent float64 `json:"percent"` 338} 339 340type ClusterStatsNodesProcessStatsOpenFileDescriptors struct { 341 Min int64 `json:"min"` 342 Max int64 `json:"max"` 343 Avg int64 `json:"avg"` 344} 345 346type ClusterStatsNodesJvmStats struct { 347 MaxUptime string `json:"max_uptime"` // e.g. "5h" 348 MaxUptimeInMillis int64 `json:"max_uptime_in_millis"` 349 Versions []*ClusterStatsNodesJvmStatsVersion `json:"versions"` 350 Mem *ClusterStatsNodesJvmStatsMem `json:"mem"` 351 Threads int64 `json:"threads"` 352} 353 354type ClusterStatsNodesJvmStatsVersion struct { 355 Version string `json:"version"` // e.g. "1.8.0_45" 356 VMName string `json:"vm_name"` // e.g. "Java HotSpot(TM) 64-Bit Server VM" 357 VMVersion string `json:"vm_version"` // e.g. "25.45-b02" 358 VMVendor string `json:"vm_vendor"` // e.g. "Oracle Corporation" 359 BundledJDK bool `json:"bundled_jdk"` 360 UsingBundledJDK bool `json:"using_bundled_jdk"` 361 Count int `json:"count"` 362} 363 364type ClusterStatsNodesJvmStatsMem struct { 365 HeapUsed string `json:"heap_used"` 366 HeapUsedInBytes int64 `json:"heap_used_in_bytes"` 367 HeapMax string `json:"heap_max"` 368 HeapMaxInBytes int64 `json:"heap_max_in_bytes"` 369} 370 371type ClusterStatsNodesFsStats struct { 372 Path string `json:"path"` 373 Mount string `json:"mount"` 374 Dev string `json:"dev"` 375 Total string `json:"total"` // e.g. "930.7gb"` 376 TotalInBytes int64 `json:"total_in_bytes"` 377 Free string `json:"free"` // e.g. "930.7gb"` 378 FreeInBytes int64 `json:"free_in_bytes"` 379 Available string `json:"available"` // e.g. "930.7gb"` 380 AvailableInBytes int64 `json:"available_in_bytes"` 381 DiskReads int64 `json:"disk_reads"` 382 DiskWrites int64 `json:"disk_writes"` 383 DiskIOOp int64 `json:"disk_io_op"` 384 DiskReadSize string `json:"disk_read_size"` // e.g. "0b"` 385 DiskReadSizeInBytes int64 `json:"disk_read_size_in_bytes"` 386 DiskWriteSize string `json:"disk_write_size"` // e.g. "0b"` 387 DiskWriteSizeInBytes int64 `json:"disk_write_size_in_bytes"` 388 DiskIOSize string `json:"disk_io_size"` // e.g. "0b"` 389 DiskIOSizeInBytes int64 `json:"disk_io_size_in_bytes"` 390 DiskQueue string `json:"disk_queue"` 391 DiskServiceTime string `json:"disk_service_time"` 392} 393 394type ClusterStatsNodesPlugin struct { 395 Name string `json:"name"` 396 Version string `json:"version"` 397 Description string `json:"description"` 398 URL string `json:"url"` 399 JVM bool `json:"jvm"` 400 Site bool `json:"site"` 401} 402 403type ClusterStatsNodesNetworkTypes struct { 404 TransportTypes map[string]interface{} `json:"transport_types"` // e.g. "netty4": 1 405 HTTPTypes map[string]interface{} `json:"http_types"` // e.g. "netty4": 1 406} 407 408type ClusterStatsNodesDiscoveryTypes interface{} 409 410type ClusterStatsNodesPackagingTypes []*ClusterStatsNodesPackagingType 411 412type ClusterStatsNodesPackagingType struct { 413 Flavor string `json:"flavor"` // e.g. "oss" 414 Type string `json:"type"` // e.g. "docker" 415 Count int `json:"count"` // e.g. 1 416} 417