From 36c234315afcb516b1821bd606343bb9a8f18e35 Mon Sep 17 00:00:00 2001 From: Thomas Roehl Date: Wed, 23 Feb 2022 13:38:59 +0100 Subject: [PATCH] Use metric configurations from Ganglia for some metrics --- sinks/gangliaSink.go | 97 ++++++++++------------------------- sinks/libgangliaSink.go | 111 ++++++++++++++-------------------------- 2 files changed, 67 insertions(+), 141 deletions(-) diff --git a/sinks/gangliaSink.go b/sinks/gangliaSink.go index ae53dd8..fc0c88f 100644 --- a/sinks/gangliaSink.go +++ b/sinks/gangliaSink.go @@ -24,6 +24,7 @@ type GangliaSinkConfig struct { AddTagsAsDesc bool `json:"add_tags_as_desc,omitempty"` ClusterName string `json:"cluster_name,omitempty"` AddTypeToName bool `json:"add_type_to_name,omitempty"` + AddUnits bool `json:"add_units,omitempty"` } type GangliaSink struct { @@ -38,6 +39,7 @@ func (s *GangliaSink) Init(config json.RawMessage) error { s.name = "GangliaSink" s.config.AddTagsAsDesc = false s.config.AddGangliaGroup = false + s.config.AddUnits = false if len(config) > 0 { err := json.Unmarshal(config, &s.config) if err != nil { @@ -70,91 +72,48 @@ func (s *GangliaSink) Init(config json.RawMessage) error { func (s *GangliaSink) Write(point lp.CCMetric) error { var err error = nil - var tagsstr []string + //var tagsstr []string var argstr []string - if s.config.AddGangliaGroup { - if point.HasTag("group") { - g, _ := point.GetTag("group") - argstr = append(argstr, fmt.Sprintf("--group=%s", g)) - } else if point.HasMeta("group") { - g, _ := point.GetMeta("group") - argstr = append(argstr, fmt.Sprintf("--group=%s", g)) - } + + // Get metric name + metricname := GangliaMetricRename(point.Name()) + + // Get metric config (type, value, ... in suitable format) + conf := GetCommonGangliaConfig(point) + if len(conf.Type) == 0 { + conf = GetGangliaConfig(point) + } + if len(conf.Type) == 0 { + return fmt.Errorf("metric %s has no 'value' field", metricname) } - for key, value := range point.Tags() { - switch key { - case "unit": - argstr = append(argstr, fmt.Sprintf("--units=%s", value)) - default: - tagsstr = append(tagsstr, fmt.Sprintf("%s=%s", key, value)) - } + if s.config.AddGangliaGroup { + argstr = append(argstr, fmt.Sprintf("--group=%s", conf.Group)) } - if s.config.MetaAsTags { - for key, value := range point.Meta() { - switch key { - case "unit": - argstr = append(argstr, fmt.Sprintf("--units=%s", value)) - default: - tagsstr = append(tagsstr, fmt.Sprintf("%s=%s", key, value)) - } - } + if s.config.AddUnits && len(conf.Unit) > 0 { + argstr = append(argstr, fmt.Sprintf("--units=%s", conf.Unit)) } + if len(s.config.ClusterName) > 0 { argstr = append(argstr, fmt.Sprintf("--cluster=%s", s.config.ClusterName)) } - if s.config.AddTagsAsDesc && len(tagsstr) > 0 { - argstr = append(argstr, fmt.Sprintf("--desc=%q", strings.Join(tagsstr, ","))) - } + // if s.config.AddTagsAsDesc && len(tagsstr) > 0 { + // argstr = append(argstr, fmt.Sprintf("--desc=%q", strings.Join(tagsstr, ","))) + // } if len(s.gmetric_config) > 0 { argstr = append(argstr, fmt.Sprintf("--conf=%s", s.gmetric_config)) } - name := GangliaMetricRename(point) if s.config.AddTypeToName { argstr = append(argstr, fmt.Sprintf("--name=%s", GangliaMetricName(point))) } else { - argstr = append(argstr, fmt.Sprintf("--name=%s", name)) + argstr = append(argstr, fmt.Sprintf("--name=%s", metricname)) } - slope := GangliaSlopeType(point) - slopeStr := "both" - if slope == 0 { - slopeStr = "zero" - } - argstr = append(argstr, fmt.Sprintf("--slope=%s", slopeStr)) + argstr = append(argstr, fmt.Sprintf("--slope=%s", conf.Slope)) + argstr = append(argstr, fmt.Sprintf("--value=%s", conf.Value)) + argstr = append(argstr, fmt.Sprintf("--type=%s", conf.Type)) + argstr = append(argstr, fmt.Sprintf("--tmax=%d", conf.Tmax)) - for k, v := range point.Fields() { - if k == "value" { - switch value := v.(type) { - case float64: - argstr = append(argstr, - fmt.Sprintf("--value=%v", value), "--type=double") - case float32: - argstr = append(argstr, - fmt.Sprintf("--value=%v", value), "--type=float") - case int: - argstr = append(argstr, - fmt.Sprintf("--value=%d", value), "--type=int32") - case int32: - argstr = append(argstr, - fmt.Sprintf("--value=%d", value), "--type=int32") - case int64: - argstr = append(argstr, - fmt.Sprintf("--value=%d", value), "--type=int32") - case uint: - argstr = append(argstr, - fmt.Sprintf("--value=%d", value), "--type=uint32") - case uint32: - argstr = append(argstr, - fmt.Sprintf("--value=%d", value), "--type=uint32") - case uint64: - argstr = append(argstr, - fmt.Sprintf("--value=%d", value), "--type=uint32") - case string: - argstr = append(argstr, - fmt.Sprintf("--value=%q", value), "--type=string") - } - } - } + cclog.ComponentDebug(s.name, s.gmetric_path, strings.Join(argstr, " ")) command := exec.Command(s.gmetric_path, argstr...) command.Wait() _, err = command.Output() diff --git a/sinks/libgangliaSink.go b/sinks/libgangliaSink.go index 7136e42..78f957d 100644 --- a/sinks/libgangliaSink.go +++ b/sinks/libgangliaSink.go @@ -82,21 +82,21 @@ const ( GMOND_CONFIG_FILE = `/etc/ganglia/gmond.conf` ) -type LibgangliaSinkSpecialMetric struct { - MetricName string `json:"metric_name,omitempty"` - NewName string `json:"new_name,omitempty"` - Slope string `json:"slope,omitempty"` -} +// type LibgangliaSinkSpecialMetric struct { +// MetricName string `json:"metric_name,omitempty"` +// NewName string `json:"new_name,omitempty"` +// Slope string `json:"slope,omitempty"` +// } type LibgangliaSinkConfig struct { defaultSinkConfig - GangliaLib string `json:"libganglia_path,omitempty"` - GmondConfig string `json:"gmond_config,omitempty"` - AddGangliaGroup bool `json:"add_ganglia_group,omitempty"` - AddTypeToName bool `json:"add_type_to_name,omitempty"` - AddUnits bool `json:"add_units,omitempty"` - ClusterName string `json:"cluster_name,omitempty"` - SpecialMetrics map[string]LibgangliaSinkSpecialMetric `json:"rename_metrics,omitempty"` // Map to rename metric name from key to value + GangliaLib string `json:"libganglia_path,omitempty"` + GmondConfig string `json:"gmond_config,omitempty"` + AddGangliaGroup bool `json:"add_ganglia_group,omitempty"` + AddTypeToName bool `json:"add_type_to_name,omitempty"` + AddUnits bool `json:"add_units,omitempty"` + ClusterName string `json:"cluster_name,omitempty"` + //SpecialMetrics map[string]LibgangliaSinkSpecialMetric `json:"rename_metrics,omitempty"` // Map to rename metric name from key to value //AddTagsAsDesc bool `json:"add_tags_as_desc,omitempty"` } @@ -184,81 +184,48 @@ func (s *LibgangliaSink) Write(point lp.CCMetric) error { } // Get metric name - metricname := GangliaMetricRename(point) - if s.config.AddTypeToName { - c_name = lookup(GangliaMetricName(point)) - } else { - c_name = lookup(metricname) - } + metricname := GangliaMetricRename(point.Name()) - // Get the value C string and lookup the type string in the cache - value, ok := point.GetField("value") - if !ok { + conf := GetCommonGangliaConfig(point) + if len(conf.Type) == 0 { + conf = GetGangliaConfig(point) + } + if len(conf.Type) == 0 { return fmt.Errorf("metric %s has no 'value' field", metricname) } - switch real := value.(type) { - case float64: - c_value = C.CString(fmt.Sprintf("%f", real)) - c_type = lookup("double") - case float32: - c_value = C.CString(fmt.Sprintf("%f", real)) - c_type = lookup("float") - case int64: - c_value = C.CString(fmt.Sprintf("%d", real)) - c_type = lookup("int32") - case int32: - c_value = C.CString(fmt.Sprintf("%d", real)) - c_type = lookup("int32") - case int: - c_value = C.CString(fmt.Sprintf("%d", real)) - c_type = lookup("int32") - case uint64: - c_value = C.CString(fmt.Sprintf("%d", real)) - c_type = lookup("uint32") - case uint32: - c_value = C.CString(fmt.Sprintf("%d", real)) - c_type = lookup("uint32") - case uint: - c_value = C.CString(fmt.Sprintf("%d", real)) - c_type = lookup("uint32") - case string: - c_value = C.CString(real) - c_type = lookup("string") - default: - return fmt.Errorf("metric %s has invalid 'value' type for %s", point.Name(), s.name) + + if s.config.AddTypeToName { + metricname = GangliaMetricName(point) } + c_value = C.CString(conf.Value) + c_type = lookup(conf.Type) + c_name = lookup(metricname) + // Add unit + unit := "" if s.config.AddUnits { - if tagunit, tagok := point.GetTag("unit"); tagok { - c_unit = lookup(tagunit) - } else if metaunit, metaok := point.GetMeta("unit"); metaok { - c_unit = lookup(metaunit) - } else { - c_unit = lookup("") - } - } else { - c_unit = lookup("") + unit = conf.Unit } + c_unit = lookup(unit) // Determine the slope of the metric. Ganglia's own collector mostly use // 'both' but the mem and swap total uses 'zero'. - slope := GangliaSlopeType(point) slope_type := C.GANGLIA_SLOPE_BOTH - switch slope { - case 0: + switch conf.Slope { + case "zero": slope_type = C.GANGLIA_SLOPE_ZERO + case "both": + slope_type = C.GANGLIA_SLOPE_BOTH } // Create a new Ganglia metric gmetric := C.Ganglia_metric_create(s.global_context) // Set name, value, type and unit in the Ganglia metric - // Since we don't have this information from the collectors, - // we assume that the metric value can go up and down (slope), - // and there is no maximum for 'dmax' and 'tmax'. - // Ganglia's collectors set 'tmax' but not 'dmax' + // The default slope_type is both directions, so up and down. Some metrics want 'zero' slope, probably constant. + // The 'tmax' value is by default 300. rval := C.int(0) - rval = C.Ganglia_metric_set(gmetric, c_name, c_value, c_type, c_unit, C.uint(slope_type), 0, 0) + rval = C.Ganglia_metric_set(gmetric, c_name, c_value, c_type, c_unit, C.uint(slope_type), C.uint(conf.Tmax), 0) switch rval { case 1: C.free(unsafe.Pointer(c_value)) @@ -268,10 +235,10 @@ func (s *LibgangliaSink) Write(point lp.CCMetric) error { return errors.New("one of your parameters has an invalid character '\"'") case 3: C.free(unsafe.Pointer(c_value)) - return fmt.Errorf("the type parameter \"%s\" is not a valid type", C.GoString(c_type)) + return fmt.Errorf("the type parameter \"%s\" is not a valid type", conf.Type) case 4: C.free(unsafe.Pointer(c_value)) - return fmt.Errorf("the value parameter \"%s\" does not represent a number", C.GoString(c_value)) + return fmt.Errorf("the value parameter \"%s\" does not represent a number", conf.Value) default: } @@ -280,8 +247,8 @@ func (s *LibgangliaSink) Write(point lp.CCMetric) error { C.Ganglia_metadata_add(gmetric, lookup("CLUSTER"), lookup(s.config.ClusterName)) } // Set the group metadata in the Ganglia metric if configured - if group, ok := point.GetMeta("group"); ok && s.config.AddGangliaGroup { - c_group := lookup(group) + if s.config.AddGangliaGroup { + c_group := lookup(conf.Group) C.Ganglia_metadata_add(gmetric, lookup("GROUP"), c_group) }