Skip to main content
Glama
metrics_utils.go4.19 kB
package metrics import ( "bytes" "errors" "fmt" "lunar/engine/utils/environment" "lunar/toolkit-core/configuration" "strings" "github.com/rs/zerolog/log" "go.opentelemetry.io/otel/metric" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/common/expfmt" ) // EqualSystemMetrics compares only the SystemMetrics slice in Config. func (c Config) EqualSystemMetrics(other Config) bool { if len(c.SystemMetrics) != len(other.SystemMetrics) { return false } for i := range c.SystemMetrics { if !c.SystemMetrics[i].Equal(other.SystemMetrics[i]) { return false } } return true } // Equal compares two GeneralMetrics structs. func (g GeneralMetrics) Equal(other GeneralMetrics) bool { if len(g.LabelValue) != len(other.LabelValue) { return false } if len(g.MetricValue) != len(other.MetricValue) { return false } for i := range g.LabelValue { if g.LabelValue[i] != other.LabelValue[i] { return false } } for i := range g.MetricValue { if !g.MetricValue[i].Equal(other.MetricValue[i]) { return false } } return true } // Equal compares two MetricValue structs. func (m MetricValue) Equal(other MetricValue) bool { if m.Name != other.Name || m.Description != other.Description || m.JSONPath != other.JSONPath { return false } if len(m.Buckets) != len(other.Buckets) { return false } for i := range m.Buckets { if m.Buckets[i] != other.Buckets[i] { return false } } return true } func (c Config) EqualLabeledEndpoints(other *Config) bool { if len(c.LabeledEndpoints) != len(other.LabeledEndpoints) { return false } for i := range c.LabeledEndpoints { if c.LabeledEndpoints[i] != other.LabeledEndpoints[i] { return false } } return true } // registerObservableMetric registers an observable metric with the given meter func registerObservableMetric( meter metric.Meter, metricVal MetricValue, ) (meterObj metric.Observable, err error) { metricType, found := metricsObservableRegistry[metricVal.Name] if !found { return nil, fmt.Errorf("type unknown for metric: %s", metricVal.Name) } metricName := string(metricVal.Name) description := metric.WithDescription(metricVal.Description) switch metricType { //nolint:exhaustive case Int64ObservableCounter: meterObj, err = meter.Int64ObservableCounter(metricName, description) case Float64ObservableCounter: meterObj, err = meter.Float64ObservableCounter(metricName, description) case Int64ObservableUpDownCounter: meterObj, err = meter.Int64ObservableUpDownCounter(metricName, description) case Float64ObservableUpDownCounter: meterObj, err = meter.Float64ObservableUpDownCounter(metricName, description) case Int64ObservableGauge: meterObj, err = meter.Int64ObservableGauge(metricName, description) case Float64ObservableGauge: meterObj, err = meter.Float64ObservableGauge(metricName, description) default: return nil, fmt.Errorf("unknown metric type: %v", metricType) } return meterObj, err } // loadMetricsConfig loads and returns the metrics config func loadMetricsConfig() (*Config, error) { log.Info().Msg("Loading metrics config") configFilePath := environment.GetMetricsConfigFilePathOrDefault() log.Info().Msgf("Metrics config file path: %s", configFilePath) result, err := configuration.DecodeYAML[Config](configFilePath) if err != nil { return nil, err } if len(result.Content) == 0 { return nil, errors.New("metrics config file is empty") } return result.UnmarshaledData, nil } func GatherLunarMetrics() (string, error) { mfs, err := prometheus.DefaultGatherer.Gather() if err != nil { return "", fmt.Errorf("error gathering metrics: %w", err) } var buf bytes.Buffer enc := expfmt.NewEncoder(&buf, expfmt.FmtText) for _, mf := range mfs { if isMetricLunarRelated(mf.GetName()) { if err := enc.Encode(mf); err != nil { return "", fmt.Errorf("error encoding metrics: %w", err) } } } return buf.String(), nil } func isMetricLunarRelated(metricName string) bool { if strings.HasPrefix(metricName, MetricPrefix) { return true } for _, label := range labelsToInclude { if strings.Contains(metricName, label) { return true } } return false }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/TheLunarCompany/lunar'

If you have feedback or need assistance with the MCP directory API, please join our Discord server