// internal/client/client.go
package client
import (
"context"
"fmt"
"log"
"net/http"
"os"
"time"
v1 "github.com/chussenot/datadog-mcp/internal/api/v1"
)
// DataDogClient wraps the generated client with additional functionality
type DataDogClient struct {
Client *v1.ClientWithResponses
Site string
}
// NewDataDogClient creates a new DataDog client with authentication
func NewDataDogClient(apiKey, site string) (*DataDogClient, error) {
log.Printf("🔧 Creating DataDog client for site: %s", site)
log.Printf("🔧 API Key length: %d characters", len(apiKey))
log.Printf("🔧 API Key prefix: %s...", apiKey[:min(8, len(apiKey))])
// Create HTTP client with timeout
httpClient := &http.Client{
Timeout: 30 * time.Second,
}
// Create request editor to add API key authentication
editor := v1.WithRequestEditorFn(func(ctx context.Context, req *http.Request) error {
log.Printf("🌐 Making request to: %s %s", req.Method, req.URL.String())
req.Header.Set("DD-API-KEY", apiKey)
log.Printf("🔑 Added DD-API-KEY header: %s...", apiKey[:min(8, len(apiKey))])
// Also try adding application key if available
if appKey := os.Getenv("DATADOG_APP_KEY"); appKey != "" {
req.Header.Set("DD-APPLICATION-KEY", appKey)
log.Printf("🔑 Added DD-APPLICATION-KEY header: %s...", appKey[:min(8, len(appKey))])
} else {
log.Printf("⚠️ No DATADOG_APP_KEY found, using API key only")
}
return nil
})
// Create client with base URL and authentication
baseURL := fmt.Sprintf("https://api.%s", site)
log.Printf("🌐 DataDog API Base URL: %s", baseURL)
client, err := v1.NewClientWithResponses(baseURL, v1.WithHTTPClient(httpClient), editor)
if err != nil {
log.Printf("❌ Failed to create DataDog client: %v", err)
return nil, fmt.Errorf("failed to create DataDog client: %w", err)
}
log.Printf("✅ DataDog client created successfully")
return &DataDogClient{
Client: client,
Site: site,
}, nil
}
// Helper function for min
func min(a, b int) int {
if a < b {
return a
}
return b
}