Skip to content

Commit 0a45b6a

Browse files
committed
Add client name to telemetry metrics.
1 parent ff55cd3 commit 0a45b6a

File tree

6 files changed

+74
-30
lines changed

6 files changed

+74
-30
lines changed

cmd/docker-mcp/internal/gateway/handlers.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ func (g *Gateway) mcpServerToolHandler(serverConfig *catalog.ServerConfig, serve
8080
attribute.String("mcp.server.name", serverConfig.Name),
8181
attribute.String("mcp.server.type", serverType),
8282
attribute.String("mcp.tool.name", req.Params.Name),
83+
attribute.String("mcp.client.name", req.Session.InitializeParams().ClientInfo.Name),
8384
),
8485
)
8586

@@ -107,6 +108,7 @@ func (g *Gateway) mcpServerToolHandler(serverConfig *catalog.ServerConfig, serve
107108
attribute.String("mcp.server.name", serverConfig.Name),
108109
attribute.String("mcp.server.type", serverType),
109110
attribute.String("mcp.tool.name", req.Params.Name),
111+
attribute.String("mcp.client.name", req.Session.InitializeParams().ClientInfo.Name),
110112
),
111113
)
112114

@@ -153,7 +155,7 @@ func (g *Gateway) mcpServerPromptHandler(serverConfig *catalog.ServerConfig, ser
153155
defer span.End()
154156

155157
// Record prompt get counter
156-
telemetry.RecordPromptGet(ctx, req.Params.Name, serverConfig.Name)
158+
telemetry.RecordPromptGet(ctx, req.Params.Name, serverConfig.Name, req.Session.InitializeParams().ClientInfo.Name)
157159

158160
client, err := g.clientPool.AcquireClient(ctx, serverConfig, getClientConfig(nil, req.Session, server))
159161
if err != nil {
@@ -168,7 +170,7 @@ func (g *Gateway) mcpServerPromptHandler(serverConfig *catalog.ServerConfig, ser
168170

169171
// Record duration
170172
duration := time.Since(startTime).Milliseconds()
171-
telemetry.RecordPromptDuration(ctx, req.Params.Name, serverConfig.Name, float64(duration))
173+
telemetry.RecordPromptDuration(ctx, req.Params.Name, serverConfig.Name, float64(duration), req.Session.InitializeParams().ClientInfo.Name)
172174

173175
if err != nil {
174176
span.RecordError(err)
@@ -214,7 +216,7 @@ func (g *Gateway) mcpServerResourceHandler(serverConfig *catalog.ServerConfig, s
214216
defer span.End()
215217

216218
// Record counter with server attribution
217-
telemetry.RecordResourceRead(ctx, req.Params.URI, serverConfig.Name)
219+
telemetry.RecordResourceRead(ctx, req.Params.URI, serverConfig.Name, req.Session.InitializeParams().ClientInfo.Name)
218220

219221
client, err := g.clientPool.AcquireClient(ctx, serverConfig, getClientConfig(nil, req.Session, server))
220222
if err != nil {
@@ -229,7 +231,7 @@ func (g *Gateway) mcpServerResourceHandler(serverConfig *catalog.ServerConfig, s
229231

230232
// Record duration regardless of error
231233
duration := time.Since(startTime).Milliseconds()
232-
telemetry.RecordResourceDuration(ctx, req.Params.URI, serverConfig.Name, float64(duration))
234+
telemetry.RecordResourceDuration(ctx, req.Params.URI, serverConfig.Name, float64(duration), req.Session.InitializeParams().ClientInfo.Name)
233235

234236
if err != nil {
235237
span.RecordError(err)

cmd/docker-mcp/internal/gateway/handlers_prompt_telemetry_test.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ func TestPromptHandlerTelemetry(t *testing.T) {
4848

4949
// Record prompt call
5050
ctx := context.Background()
51-
telemetry.RecordPromptGet(ctx, promptName, serverConfig.Name)
51+
telemetry.RecordPromptGet(ctx, promptName, serverConfig.Name, "test-client")
5252

5353
// Collect metrics
5454
var rm metricdata.ResourceMetrics
@@ -79,6 +79,8 @@ func TestPromptHandlerTelemetry(t *testing.T) {
7979
attribute.String("mcp.prompt.name", promptName))
8080
assert.Contains(t, attrs,
8181
attribute.String("mcp.server.origin", serverConfig.Name))
82+
assert.Contains(t, attrs,
83+
attribute.String("mcp.client.name", "test-client"))
8284
}
8385
}
8486
}
@@ -110,7 +112,7 @@ func TestPromptHandlerTelemetry(t *testing.T) {
110112

111113
// Record prompt duration
112114
ctx := context.Background()
113-
telemetry.RecordPromptDuration(ctx, promptName, serverConfig.Name, duration)
115+
telemetry.RecordPromptDuration(ctx, promptName, serverConfig.Name, duration, "test-client")
114116

115117
// Collect metrics
116118
var rm metricdata.ResourceMetrics
@@ -142,6 +144,8 @@ func TestPromptHandlerTelemetry(t *testing.T) {
142144
attribute.String("mcp.prompt.name", promptName))
143145
assert.Contains(t, attrs,
144146
attribute.String("mcp.server.origin", serverConfig.Name))
147+
assert.Contains(t, attrs,
148+
attribute.String("mcp.client.name", "test-client"))
145149
}
146150
}
147151
}

cmd/docker-mcp/internal/gateway/handlers_resource_telemetry_test.go

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ func TestResourceHandlerTelemetry(t *testing.T) {
5555
// Test data
5656
ctx := context.Background()
5757
resourceURI := "file:///test/resource.txt"
58+
clientName := "test-client"
5859
serverConfig := &catalog.ServerConfig{
5960
Name: "test-server",
6061
Spec: catalog.Server{
@@ -63,7 +64,7 @@ func TestResourceHandlerTelemetry(t *testing.T) {
6364
}
6465

6566
// Record resource read
66-
telemetry.RecordResourceRead(ctx, resourceURI, serverConfig.Name)
67+
telemetry.RecordResourceRead(ctx, resourceURI, serverConfig.Name, clientName)
6768

6869
// Verify metrics were collected
6970
var rm metricdata.ResourceMetrics
@@ -92,6 +93,7 @@ func TestResourceHandlerTelemetry(t *testing.T) {
9293
attrs := sum.DataPoints[0].Attributes
9394
hasURI := false
9495
hasServer := false
96+
hasClient := false
9597
for _, attr := range attrs.ToSlice() {
9698
if attr.Key == "mcp.resource.uri" {
9799
assert.Equal(t, resourceURI, attr.Value.AsString())
@@ -101,9 +103,14 @@ func TestResourceHandlerTelemetry(t *testing.T) {
101103
assert.Equal(t, serverConfig.Name, attr.Value.AsString())
102104
hasServer = true
103105
}
106+
if attr.Key == "mcp.client.name" {
107+
assert.Equal(t, clientName, attr.Value.AsString())
108+
hasClient = true
109+
}
104110
}
105111
assert.True(t, hasURI, "Should have resource URI attribute")
106112
assert.True(t, hasServer, "Should have server origin attribute")
113+
assert.True(t, hasClient, "Should have client name attribute")
107114
}
108115
}
109116
}
@@ -126,10 +133,11 @@ func TestResourceHandlerTelemetry(t *testing.T) {
126133
ctx := context.Background()
127134
resourceURI := "file:///test/resource.txt"
128135
serverName := "test-server"
136+
clientName := "test-client"
129137
duration := 42.5 // milliseconds
130138

131139
// Record duration
132-
telemetry.RecordResourceDuration(ctx, resourceURI, serverName, duration)
140+
telemetry.RecordResourceDuration(ctx, resourceURI, serverName, duration, clientName)
133141

134142
// Verify metrics
135143
var rm metricdata.ResourceMetrics
@@ -284,9 +292,10 @@ func TestResourceTemplateHandlerTelemetry(t *testing.T) {
284292
ctx := context.Background()
285293
uriTemplate := "file:///test/{id}/resource.txt"
286294
serverName := "test-server"
295+
clientName := "test-client"
287296

288297
// Record resource template read
289-
telemetry.RecordResourceTemplateRead(ctx, uriTemplate, serverName)
298+
telemetry.RecordResourceTemplateRead(ctx, uriTemplate, serverName, clientName)
290299

291300
// Verify metrics
292301
var rm metricdata.ResourceMetrics
@@ -484,6 +493,7 @@ func TestMcpServerResourceHandlerInstrumentation(t *testing.T) {
484493
Image: "test/image:latest",
485494
},
486495
}
496+
clientName := "test-client"
487497
params := &mcp.ReadResourceParams{
488498
URI: "file:///test/resource.txt",
489499
}
@@ -498,14 +508,14 @@ func TestMcpServerResourceHandlerInstrumentation(t *testing.T) {
498508
startTime := time.Now()
499509

500510
// Record counter (as handler would)
501-
telemetry.RecordResourceRead(ctx, params.URI, serverConfig.Name)
511+
telemetry.RecordResourceRead(ctx, params.URI, serverConfig.Name, clientName)
502512

503513
// Simulate some work
504514
time.Sleep(10 * time.Millisecond)
505515

506516
// Record duration (as handler would)
507517
duration := time.Since(startTime).Milliseconds()
508-
telemetry.RecordResourceDuration(ctx, params.URI, serverConfig.Name, float64(duration))
518+
telemetry.RecordResourceDuration(ctx, params.URI, serverConfig.Name, float64(duration), clientName)
509519

510520
// End span
511521
span.End()
@@ -560,6 +570,7 @@ func TestMcpServerResourceHandlerInstrumentation(t *testing.T) {
560570
Image: "test/image:latest",
561571
},
562572
}
573+
clientName := "test-client"
563574
params := &mcp.ReadResourceParams{
564575
URI: "file:///test/missing.txt",
565576
}
@@ -572,7 +583,7 @@ func TestMcpServerResourceHandlerInstrumentation(t *testing.T) {
572583
)
573584

574585
// Record counter
575-
telemetry.RecordResourceRead(ctx, params.URI, serverConfig.Name)
586+
telemetry.RecordResourceRead(ctx, params.URI, serverConfig.Name, clientName)
576587

577588
// Simulate error
578589
err := errors.New("resource not found")

cmd/docker-mcp/internal/gateway/handlers_telemetry_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,13 +170,15 @@ func TestTelemetryMetricRecording(t *testing.T) {
170170
serverName := "test-server"
171171
serverType := "docker"
172172
toolName := "test-tool"
173+
clientName := "test-client"
173174

174175
// Record metrics as the handler would
175176
telemetry.ToolCallCounter.Add(ctx, 1,
176177
metric.WithAttributes(
177178
attribute.String("mcp.server.name", serverName),
178179
attribute.String("mcp.server.type", serverType),
179180
attribute.String("mcp.tool.name", toolName),
181+
attribute.String("mcp.client.name", clientName),
180182
),
181183
)
182184

@@ -186,6 +188,7 @@ func TestTelemetryMetricRecording(t *testing.T) {
186188
attribute.String("mcp.server.name", serverName),
187189
attribute.String("mcp.server.type", serverType),
188190
attribute.String("mcp.tool.name", toolName),
191+
attribute.String("mcp.client.name", clientName),
189192
),
190193
)
191194

@@ -210,6 +213,7 @@ func TestTelemetryMetricRecording(t *testing.T) {
210213
assertMetricAttribute(t, attrs, "mcp.server.name", serverName)
211214
assertMetricAttribute(t, attrs, "mcp.server.type", serverType)
212215
assertMetricAttribute(t, attrs, "mcp.tool.name", toolName)
216+
assertMetricAttribute(t, attrs, "mcp.client.name", clientName)
213217

214218
case "mcp.tool.duration":
215219
foundHistogram = true
@@ -303,6 +307,7 @@ func TestToolCallDurationMeasurement(t *testing.T) {
303307
attribute.String("mcp.server.name", "test-server"),
304308
attribute.String("mcp.server.type", "docker"),
305309
attribute.String("mcp.tool.name", "test-tool"),
310+
attribute.String("mcp.client.name", "test-client"),
306311
),
307312
)
308313

cmd/docker-mcp/internal/interceptors/telemetry.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,24 @@ func TelemetryMiddleware() mcp.Middleware {
3232
telemetry.RecordInitialize(ctx, params)
3333
tracked = true
3434
case "tools/list":
35+
session := req.GetSession().(*mcp.ServerSession)
3536
ctx, span = telemetry.StartListSpan(ctx, "tools")
36-
telemetry.RecordListTools(ctx)
37+
telemetry.RecordListTools(ctx, session.InitializeParams().ClientInfo.Name)
3738
tracked = true
3839
case "prompts/list":
40+
session := req.GetSession().(*mcp.ServerSession)
3941
ctx, span = telemetry.StartListSpan(ctx, "prompts")
40-
telemetry.RecordListPrompts(ctx)
42+
telemetry.RecordListPrompts(ctx, session.InitializeParams().ClientInfo.Name)
4143
tracked = true
4244
case "resources/list":
45+
session := req.GetSession().(*mcp.ServerSession)
4346
ctx, span = telemetry.StartListSpan(ctx, "resources")
44-
telemetry.RecordListResources(ctx)
47+
telemetry.RecordListResources(ctx, session.InitializeParams().ClientInfo.Name)
4548
tracked = true
4649
case "resourceTemplates/list":
50+
session := req.GetSession().(*mcp.ServerSession)
4751
ctx, span = telemetry.StartListSpan(ctx, "resourceTemplates")
48-
telemetry.RecordListResourceTemplates(ctx)
52+
telemetry.RecordListResourceTemplates(ctx, session.InitializeParams().ClientInfo.Name)
4953
tracked = true
5054
}
5155

0 commit comments

Comments
 (0)