Skip to main content
Glama

MCPJungle mcp gateway

by mcpjungle
Mozilla Public License 2.0
638
  • Apple
otel_metrics.go•2.95 kB
package telemetry import ( "context" "fmt" "time" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" ) const ( labelMCPServerName = "mcp_server_name" labelToolName = "tool_name" labelToolCallOutcome = "outcome" ) const ( // attrValueMaxLen is the maximum length for string attribute values. attrValueMaxLen = 64 attrValueUnknown = "unknown" ) // OtelCustomMetrics bundles all the OpenTelemetry metric instruments used for MCPJungle. // It implements the CustomMetrics interface. type OtelCustomMetrics struct { toolCalls metric.Int64Counter toolCallLatency metric.Float64Histogram } // NewOtelCustomMetrics initializes all metric instruments required by MCPJungle. // Returns an CustomMetrics instance ready for use, or an error if any instrument // could not be created. func NewOtelCustomMetrics(meter metric.Meter) (CustomMetrics, error) { if meter == nil { return nil, fmt.Errorf("meter cannot be nil") } toolInv, err := meter.Int64Counter( "mcpjungle_tool_calls_total", metric.WithDescription("Total number of tool calls"), metric.WithUnit("1"), ) if err != nil { return nil, fmt.Errorf("failed to create tool calls counter: %w", err) } toolLat, err := meter.Float64Histogram( "mcpjungle_tool_call_latency_seconds", metric.WithDescription("Latency of tool calls in seconds"), metric.WithUnit("s"), metric.WithExplicitBucketBoundaries(0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2, 5, 10, 20, 30), ) if err != nil { return nil, fmt.Errorf("failed to create tool latency histogram: %w", err) } return &OtelCustomMetrics{ toolCalls: toolInv, toolCallLatency: toolLat, }, nil } func (m *OtelCustomMetrics) RecordToolCall( ctx context.Context, mcpServerName, toolName string, outcome ToolCallOutcome, elapsedTime time.Duration, ) { attrs := []attribute.KeyValue{ attribute.String(labelMCPServerName, boundString(mcpServerName)), attribute.String(labelToolName, boundString(toolName)), attribute.String(labelToolCallOutcome, string(outcome)), } m.toolCalls.Add(ctx, 1, metric.WithAttributes(attrs...)) m.toolCallLatency.Record(ctx, elapsedTime.Seconds(), metric.WithAttributes(attrs...)) } func (m *OtelCustomMetrics) RecordPromptCall( ctx context.Context, mcpServerName, promptName string, outcome PromptCallOutcome, elapsedTime time.Duration, ) { attrs := []attribute.KeyValue{ attribute.String(labelMCPServerName, boundString(mcpServerName)), attribute.String(labelToolName, boundString(promptName)), attribute.String(labelToolCallOutcome, string(outcome)), } m.toolCalls.Add(ctx, 1, metric.WithAttributes(attrs...)) m.toolCallLatency.Record(ctx, elapsedTime.Seconds(), metric.WithAttributes(attrs...)) } // boundString ensures strings are capped at maxLen and not empty. func boundString(s string) string { if s == "" { return attrValueUnknown } if len(s) > attrValueMaxLen { return s[:attrValueMaxLen] } return s }

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/mcpjungle/MCPJungle'

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