Skip to content

Commit

Permalink
Fix elasticsearch v8 cluster_settings unmarshal error
Browse files Browse the repository at this point in the history
Closes prometheus-community#840

Signed-off-by: takahisa <[email protected]>
  • Loading branch information
takahisa committed Jul 29, 2024
1 parent d13c555 commit e3d4fbf
Show file tree
Hide file tree
Showing 6 changed files with 1,750 additions and 52 deletions.
58 changes: 6 additions & 52 deletions collector/cluster_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,49 +103,6 @@ var clusterSettingsDesc = map[string]*prometheus.Desc{
),
}

// clusterSettingsResponse is a representation of a Elasticsearch Cluster Settings
type clusterSettingsResponse struct {
Defaults clusterSettingsSection `json:"defaults"`
Persistent clusterSettingsSection `json:"persistent"`
Transient clusterSettingsSection `json:"transient"`
}

// clusterSettingsSection is a representation of a Elasticsearch Cluster Settings
type clusterSettingsSection struct {
Cluster clusterSettingsCluster `json:"cluster"`
}

// clusterSettingsCluster is a representation of a Elasticsearch clusterSettingsCluster Settings
type clusterSettingsCluster struct {
Routing clusterSettingsRouting `json:"routing"`
// This can be either a JSON object (which does not contain the value we are interested in) or a string
MaxShardsPerNode interface{} `json:"max_shards_per_node"`
}

// clusterSettingsRouting is a representation of a Elasticsearch Cluster shard routing configuration
type clusterSettingsRouting struct {
Allocation clusterSettingsAllocation `json:"allocation"`
}

// clusterSettingsAllocation is a representation of a Elasticsearch Cluster shard routing allocation settings
type clusterSettingsAllocation struct {
Enabled string `json:"enable"`
Disk clusterSettingsDisk `json:"disk"`
}

// clusterSettingsDisk is a representation of a Elasticsearch Cluster shard routing disk allocation settings
type clusterSettingsDisk struct {
ThresholdEnabled string `json:"threshold_enabled"`
Watermark clusterSettingsWatermark `json:"watermark"`
}

// clusterSettingsWatermark is representation of Elasticsearch Cluster shard routing disk allocation watermark settings
type clusterSettingsWatermark struct {
FloodStage string `json:"flood_stage"`
High string `json:"high"`
Low string `json:"low"`
}

func (c *ClusterSettingsCollector) Update(ctx context.Context, ch chan<- prometheus.Metric) error {
u := c.u.ResolveReference(&url.URL{Path: "_cluster/settings"})
q := u.Query()
Expand Down Expand Up @@ -185,15 +142,12 @@ func (c *ClusterSettingsCollector) Update(ctx context.Context, ch chan<- prometh
}

// Max shards per node
if maxShardsPerNodeString, ok := merged.Cluster.MaxShardsPerNode.(string); ok {
maxShardsPerNode, err := strconv.ParseInt(maxShardsPerNodeString, 10, 64)
if err == nil {
ch <- prometheus.MustNewConstMetric(
clusterSettingsDesc["maxShardsPerNode"],
prometheus.GaugeValue,
float64(maxShardsPerNode),
)
}
if maxShardsPerNode, err := strconv.ParseInt(merged.Cluster.MaxShardsPerNode, 10, 64); err == nil {
ch <- prometheus.MustNewConstMetric(
clusterSettingsDesc["maxShardsPerNode"],
prometheus.GaugeValue,
float64(maxShardsPerNode),
)
}

// Shard allocation enabled
Expand Down
87 changes: 87 additions & 0 deletions collector/cluster_settings_response.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright 2021 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package collector

import (
"encoding/json"
"github.com/mitchellh/mapstructure"
)

// clusterSettingsResponse is a representation of a Elasticsearch Cluster Settings
type clusterSettingsResponse struct {
Defaults clusterSettingsSection `json:"defaults"`
Persistent clusterSettingsSection `json:"persistent"`
Transient clusterSettingsSection `json:"transient"`
}

// clusterSettingsSection is a representation of a Elasticsearch Cluster Settings
type clusterSettingsSection struct {
Cluster clusterSettingsCluster `json:"cluster" mapstructure:",squash"`
}

// clusterSettingsCluster is a representation of a Elasticsearch clusterSettingsCluster Settings
type clusterSettingsCluster struct {
Routing clusterSettingsRouting `json:"routing" mapstructure:",squash"`

MaxShardsPerNode string `json:"max_shards_per_node" mapstructure:"cluster.max_shards_per_node"`
}

// clusterSettingsRouting is a representation of a Elasticsearch Cluster shard routing configuration
type clusterSettingsRouting struct {
Allocation clusterSettingsAllocation `json:"allocation" mapstructure:",squash"`
}

// clusterSettingsAllocation is a representation of a Elasticsearch Cluster shard routing allocation settings
type clusterSettingsAllocation struct {
Enabled string `json:"enable" mapstructure:"cluster.routing.allocation.enable"`
Disk clusterSettingsDisk `json:"disk" mapstructure:",squash"`
}

// clusterSettingsDisk is a representation of a Elasticsearch Cluster shard routing disk allocation settings
type clusterSettingsDisk struct {
ThresholdEnabled string `json:"threshold_enabled" mapstructure:"cluster.routing.allocation.disk.threshold_enabled"`
Watermark clusterSettingsWatermark `json:"watermark" mapstructure:",squash"`
}

// clusterSettingsWatermark is representation of Elasticsearch Cluster shard routing disk allocation watermark settings
type clusterSettingsWatermark struct {
FloodStage string `json:"flood_stage" mapstructure:"cluster.routing.allocation.disk.watermark.flood_stage"`
High string `json:"high" mapstructure:"cluster.routing.allocation.disk.watermark.high"`
Low string `json:"low" mapstructure:"cluster.routing.allocation.disk.watermark.low"`
}

func (c *clusterSettingsSection) UnmarshalJSON(data []byte) error {
var settings map[string]interface{}

if err := json.Unmarshal(data, &settings); err != nil {
return err
}

settings = flatten(settings)
return mapstructure.Decode(settings, c)
}

func flatten(m map[string]interface{}) map[string]interface{} {
result := make(map[string]interface{})
for k1, v1 := range m {
if n, ok := v1.(map[string]interface{}); ok {
for k2, v2 := range flatten(n) {
result[k1+"."+k2] = v2
}
} else {
result[k1] = v1
}
}
return result
}
24 changes: 24 additions & 0 deletions collector/cluster_settings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,30 @@ elasticsearch_clustersettings_allocation_watermark_high_bytes 2.147483648e+11
# HELP elasticsearch_clustersettings_allocation_watermark_low_bytes Low watermark for disk usage in bytes.
# TYPE elasticsearch_clustersettings_allocation_watermark_low_bytes gauge
elasticsearch_clustersettings_allocation_watermark_low_bytes 5.24288e+07
`,
},
{
name: "8.10.4",
file: "../fixtures/settings-8.10.4.json",
want: `
# HELP elasticsearch_clustersettings_stats_max_shards_per_node Current maximum number of shards per node setting.
# TYPE elasticsearch_clustersettings_stats_max_shards_per_node gauge
elasticsearch_clustersettings_stats_max_shards_per_node 1000
# HELP elasticsearch_clustersettings_stats_shard_allocation_enabled Current mode of cluster wide shard routing allocation settings.
# TYPE elasticsearch_clustersettings_stats_shard_allocation_enabled gauge
elasticsearch_clustersettings_stats_shard_allocation_enabled 0
# HELP elasticsearch_clustersettings_allocation_threshold_enabled Is disk allocation decider enabled.
# TYPE elasticsearch_clustersettings_allocation_threshold_enabled gauge
elasticsearch_clustersettings_allocation_threshold_enabled 1
# HELP elasticsearch_clustersettings_allocation_watermark_flood_stage_ratio Flood stage watermark as a ratio.
# TYPE elasticsearch_clustersettings_allocation_watermark_flood_stage_ratio gauge
elasticsearch_clustersettings_allocation_watermark_flood_stage_ratio 0.95
# HELP elasticsearch_clustersettings_allocation_watermark_high_ratio High watermark for disk usage as a ratio.
# TYPE elasticsearch_clustersettings_allocation_watermark_high_ratio gauge
elasticsearch_clustersettings_allocation_watermark_high_ratio 0.9
# HELP elasticsearch_clustersettings_allocation_watermark_low_ratio Low watermark for disk usage as a ratio.
# TYPE elasticsearch_clustersettings_allocation_watermark_low_ratio gauge
elasticsearch_clustersettings_allocation_watermark_low_ratio 0.85
`,
},
}
Expand Down
Loading

0 comments on commit e3d4fbf

Please sign in to comment.