feat: complete agent monitoring - hook, UI, and backend filter
- Add event_type and framework filters to events query endpoint - Add /agents SPA route to web-ui server - Add Agents nav link and route in frontend - Add agents page CSS (timeline, VM pills, stats panel) - Build VM status strip, activity timeline, and real-time stats - Add agentmon hook for OpenClaw (HOOK.md + handler.ts) - Add docker-compose, Dockerfile, and supporting infra files Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
// Package main demonstrates usage of the agentmon SDK.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"agentmon/internal/sdk"
|
||||
)
|
||||
|
||||
func main() {
|
||||
emitter, err := sdk.NewEmitter(sdk.Config{
|
||||
ServerURL: "http://localhost:8080",
|
||||
Framework: "example-agent",
|
||||
ClientID: "example-client-001",
|
||||
Host: "localhost",
|
||||
BufferSize: 50,
|
||||
EnableLogging: true,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create emitter: %v", err)
|
||||
}
|
||||
defer emitter.Close(context.Background())
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
sessionID := generateSessionID()
|
||||
log.Printf("Starting session: %s", sessionID)
|
||||
|
||||
sessionStart := sdk.NewSessionStart(sessionID, sdk.WithSource(emitter))
|
||||
if err := emitter.Emit(ctx, sessionStart); err != nil {
|
||||
log.Printf("Failed to emit session.start: %v", err)
|
||||
}
|
||||
|
||||
runID := generateRunID()
|
||||
log.Printf("Starting run: %s", runID)
|
||||
|
||||
runStart := sdk.NewRunStart(sessionID, runID,
|
||||
sdk.WithSource(emitter),
|
||||
sdk.WithAttributes(map[string]any{
|
||||
"command": "example-command",
|
||||
"cwd": "/home/user/project",
|
||||
}),
|
||||
)
|
||||
if err := emitter.Emit(ctx, runStart); err != nil {
|
||||
log.Printf("Failed to emit run.start: %v", err)
|
||||
}
|
||||
|
||||
traceID := generateTraceID()
|
||||
|
||||
span1ID := generateSpanID()
|
||||
span1Start := sdk.NewSpanStart(sessionID, runID, traceID, span1ID,
|
||||
sdk.WithSource(emitter),
|
||||
sdk.WithSpanKind("tool"),
|
||||
sdk.WithName("ExampleTool"),
|
||||
sdk.WithAttributes(map[string]any{
|
||||
"tool": "example-tool",
|
||||
}),
|
||||
)
|
||||
if err := emitter.Emit(ctx, span1Start); err != nil {
|
||||
log.Printf("Failed to emit span.start: %v", err)
|
||||
}
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
span1End := sdk.NewSpanEnd(sessionID, runID, traceID, span1ID, "success", 100,
|
||||
sdk.WithSource(emitter),
|
||||
sdk.WithSpanKind("tool"),
|
||||
sdk.WithName("ExampleTool"),
|
||||
)
|
||||
if err := emitter.Emit(ctx, span1End); err != nil {
|
||||
log.Printf("Failed to emit span.end: %v", err)
|
||||
}
|
||||
|
||||
span2ID := generateSpanID()
|
||||
span2Start := sdk.NewSpanStart(sessionID, runID, traceID, span2ID,
|
||||
sdk.WithSource(emitter),
|
||||
sdk.WithSpanKind("llm"),
|
||||
sdk.WithName("ClaudeRequest"),
|
||||
sdk.WithAttributes(map[string]any{
|
||||
"model": "claude-3-opus",
|
||||
}),
|
||||
)
|
||||
if err := emitter.Emit(ctx, span2Start); err != nil {
|
||||
log.Printf("Failed to emit span.start: %v", err)
|
||||
}
|
||||
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
|
||||
span2End := sdk.NewSpanEnd(sessionID, runID, traceID, span2ID, "success", 200,
|
||||
sdk.WithSource(emitter),
|
||||
sdk.WithSpanKind("llm"),
|
||||
sdk.WithName("ClaudeRequest"),
|
||||
sdk.WithLLMUsage("claude-3-opus", 1000, 500, 0.015),
|
||||
)
|
||||
if err := emitter.Emit(ctx, span2End); err != nil {
|
||||
log.Printf("Failed to emit span.end: %v", err)
|
||||
}
|
||||
|
||||
metrics := sdk.NewMetricSnapshot(sessionID, runID, map[string]any{
|
||||
"tokens_in": 1000.0,
|
||||
"tokens_out": 500.0,
|
||||
"cost_usd": 0.015,
|
||||
"latency_ms": 300.0,
|
||||
"error_count": 0,
|
||||
})
|
||||
if err := emitter.Emit(ctx, metrics); err != nil {
|
||||
log.Printf("Failed to emit metric.snapshot: %v", err)
|
||||
}
|
||||
|
||||
runEnd := sdk.NewRunEnd(sessionID, runID, "success", 300,
|
||||
sdk.WithSource(emitter),
|
||||
sdk.WithLLMUsage("claude-3-opus", 1000, 500, 0.015),
|
||||
)
|
||||
if err := emitter.Emit(ctx, runEnd); err != nil {
|
||||
log.Printf("Failed to emit run.end: %v", err)
|
||||
}
|
||||
|
||||
sessionEnd := sdk.NewSessionEnd(sessionID, sdk.WithSource(emitter))
|
||||
if err := emitter.Emit(ctx, sessionEnd); err != nil {
|
||||
log.Printf("Failed to emit session.end: %v", err)
|
||||
}
|
||||
|
||||
if err := emitter.Flush(ctx); err != nil {
|
||||
log.Printf("Failed to flush events: %v", err)
|
||||
}
|
||||
|
||||
log.Println("Example completed successfully!")
|
||||
}
|
||||
|
||||
func generateSessionID() string {
|
||||
return fmt.Sprintf("sess-%d", time.Now().UnixNano())
|
||||
}
|
||||
|
||||
func generateRunID() string {
|
||||
return fmt.Sprintf("run-%d", time.Now().UnixNano())
|
||||
}
|
||||
|
||||
func generateTraceID() string {
|
||||
return fmt.Sprintf("trace-%d", time.Now().UnixNano())
|
||||
}
|
||||
|
||||
func generateSpanID() string {
|
||||
return fmt.Sprintf("span-%d", time.Now().UnixNano())
|
||||
}
|
||||
Reference in New Issue
Block a user