shield360

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 22, 2026 License: Apache-2.0 Imports: 21 Imported by: 0

README

Shield360 Go SDK

OpenTelemetry-native observability SDK for LLM applications in Go. Monitor your AI applications with automatic instrumentation for popular LLM providers.

Go Reference Go Report Card

Features

  • 🚀 One-line initialization - Get started with minimal code
  • 📊 OpenTelemetry-native - Built on OpenTelemetry standards
  • 💰 Cost tracking - Automatic cost calculation for LLM requests
  • 📈 Metrics collection - Token usage, latency, and performance metrics
  • 🔄 Streaming support - Full support for streaming responses
  • 🔌 Flexible integration - Works with multiple Go client libraries

Supported Integrations

  • ✅ OpenAI - Chat completions, embeddings, images, audio
  • ✅ Anthropic - Messages API with tool calling support
  • ✅ vLLM - OpenAI-compatible chat completions (local / self-hosted)

Installation

go get github.com/ThinkfleetAI/shield360-go

Quick Start

1. Initialize Shield360
package main

import (
    "context"
    "log"
    
    "github.com/ThinkfleetAI/shield360-go"
)

func main() {
    // Initialize Shield360
    err := shield360.Init(shield360.Config{
        OtlpEndpoint:    "http://127.0.0.1:4318",
        Environment:     "production",
        ApplicationName: "my-go-app",
    })
    if err != nil {
        log.Fatalf("Failed to initialize Shield360: %v", err)
    }
    defer shield360.Shutdown(context.Background())
    
    // Your application code here
}
2. Instrument OpenAI
import (
    "github.com/ThinkfleetAI/shield360-go/instrumentation/openai"
    openai_sdk "github.com/sashabaranov/go-openai"
)

// Create and instrument OpenAI client
client := openai_sdk.NewClient("your-api-key")
instrumentedClient := openai.Instrument(client)

// Use as normal - automatically traced!
resp, err := instrumentedClient.CreateChatCompletion(ctx, openai_sdk.ChatCompletionRequest{
    Model: openai_sdk.GPT4,
    Messages: []openai_sdk.ChatCompletionMessage{
        {
            Role:    openai_sdk.ChatMessageRoleUser,
            Content: "Hello!",
        },
    },
})
3. Instrument Anthropic
import (
    "github.com/ThinkfleetAI/shield360-go/instrumentation/anthropic"
)

// Create and instrument Anthropic client
client := anthropic.NewClient("your-api-key")
instrumentedClient := anthropic.Instrument(client)

// Use as normal - automatically traced!
resp, err := instrumentedClient.CreateMessage(ctx, anthropic.MessageRequest{
    Model: "claude-3-5-sonnet-20241022",
    Messages: []anthropic.Message{
        {
            Role:    "user",
            Content: "Hello!",
        },
    },
    MaxTokens: 1024,
})
4. Instrument vLLM

vLLM exposes an OpenAI-compatible HTTP API. Point the instrumented client at your vLLM server (default http://127.0.0.1:8000/v1). Spans use gen_ai.system=vllm so they are distinct from OpenAI.

import (
    "github.com/ThinkfleetAI/shield360-go/instrumentation/vllm"
)

client := vllm.NewClient("http://127.0.0.1:8000/v1") // optional: vllm.WithAPIKey("...")

resp, err := client.CreateChatCompletion(ctx, vllm.ChatCompletionRequest{
    Model: "meta-llama/Llama-3-8B-Instruct",
    Messages: []vllm.ChatMessage{
        {Role: "user", Content: "Hello!"},
    },
})

Configuration Options

config := shield360.Config{
    // Required
    OtlpEndpoint:    "http://127.0.0.1:4318",  // OTLP endpoint
    
    // Optional
    Environment:     "production",              // Deployment environment
    ApplicationName: "my-go-app",              // Application name
    ServiceVersion:  "1.0.0",                  // Service version
    
    // OTLP Configuration
    OtlpHeaders:     map[string]string{},      // Custom OTLP headers
    
    // Feature Flags
    DisableTracing:  false,                    // Disable tracing
    DisableMetrics:  false,                    // Disable metrics
    DisableBatch:    false,                    // Disable batch processing
    
    // Timeouts
    TraceExporterTimeout:  10 * time.Second,   // Trace export timeout
    MetricExporterTimeout: 10 * time.Second,   // Metric export timeout
    MetricExportInterval:  30 * time.Second,   // Metric export interval
    
    // Pricing
    PricingEndpoint:    "",                    // Custom pricing endpoint
    DisablePricingFetch: false,                // Disable pricing fetch
    PricingInfo:        map[string]ModelPricing{}, // Custom pricing
}

Streaming Support

OpenAI, Anthropic, and vLLM integrations support streaming responses:

OpenAI Streaming
stream, err := instrumentedClient.CreateChatCompletionStream(ctx, request)
if err != nil {
    log.Fatal(err)
}
defer stream.Close()

for {
    response, err := stream.Recv()
    if errors.Is(err, io.EOF) {
        break
    }
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Printf(response.Choices[0].Delta.Content)
}
Anthropic Streaming
stream, err := instrumentedClient.CreateMessageStream(ctx, request)
if err != nil {
    log.Fatal(err)
}
defer stream.Close()

for {
    event, err := stream.Recv()
    if errors.Is(err, io.EOF) {
        break
    }
    if err != nil {
        log.Fatal(err)
    }
    
    // Handle event
}
vLLM Streaming
stream, err := client.CreateChatCompletionStream(ctx, vllm.ChatCompletionRequest{
    Model:    "meta-llama/Llama-3-8B-Instruct",
    Messages: []vllm.ChatMessage{{Role: "user", Content: "Hello!"}},
})
if err != nil {
    log.Fatal(err)
}
defer stream.Close()

for {
    chunk, err := stream.Recv()
    if errors.Is(err, io.EOF) {
        break
    }
    if err != nil {
        log.Fatal(err)
    }
    if len(chunk.Choices) > 0 {
        fmt.Print(chunk.Choices[0].Delta.Content)
    }
}

Collected Telemetry

Traces
  • Operation name and type (chat, embedding, etc.)
  • Request and response models
  • Input/output messages
  • Token usage (input, output, total)
  • Cost calculations
  • Response times
  • Error details
Metrics
  • gen_ai.client.token.usage - Token usage counter
  • gen_ai.client.operation.duration - Operation duration histogram
  • gen_ai.server.time_to_first_token - TTFT for streaming
  • gen_ai.server.time_per_output_token - TBT for streaming
Attributes

All traces include standard OpenTelemetry semantic conventions:

  • gen_ai.operation.name
  • gen_ai.system
  • gen_ai.request.model
  • gen_ai.response.model
  • gen_ai.usage.input_tokens
  • gen_ai.usage.output_tokens
  • server.address
  • server.port

Advanced Usage

Custom Pricing

Provide custom pricing information for models:

config := shield360.Config{
    PricingInfo: map[string]shield360.ModelPricing{
        "gpt-4-custom": {
            InputCostPerToken:  0.00003,
            OutputCostPerToken: 0.00006,
        },
    },
}
Custom Headers

Add custom headers to OTLP exports:

config := shield360.Config{
    OtlpHeaders: map[string]string{
        "Authorization": "Bearer token",
        "X-Custom-Header": "value",
    },
}

Integration with Shield360 Dashboard

The Go SDK works seamlessly with the Shield360 Dashboard:

  1. Start Shield360 stack:
docker compose up -d
  1. Configure SDK to send data:
shield360.Init(shield360.Config{
    OtlpEndpoint: "http://localhost:4318",
})
  1. View your traces at http://localhost:3000

Examples

See the examples/ directory for complete working examples:

Rule Engine - shield360.EvaluateRule()

Evaluate trace attributes against the Shield360 Rule Engine to retrieve matching rules and associated entities (contexts, prompts, evaluation configurations). This function does not require shield360.Init() — it is a standalone HTTP call.

Parameters (EvaluateRuleOptions)
Field Type Description
URL string Shield360 dashboard URL. Falls back to SHIELD360_URL env, then http://127.0.0.1:3000.
APIKey string Bearer token. Falls back to SHIELD360_API_KEY env.
EntityType RuleEntityType RuleEntityContext, RuleEntityPrompt, or RuleEntityEvaluation.
Fields map[string]interface{} Trace attributes to evaluate against rules.
IncludeEntityData bool If true, include full entity data in response.
EntityInputs map[string]interface{} Optional inputs for entity resolution (e.g. prompt variables).
Timeout time.Duration HTTP timeout. Default: 30s.
Example
result, err := shield360.EvaluateRule(ctx, shield360.EvaluateRuleOptions{
    EntityType: shield360.RuleEntityContext,
    Fields: map[string]interface{}{
        "gen_ai.system":        "openai",
        "gen_ai.request.model": "gpt-4",
        "service.name":         "my-app",
    },
    IncludeEntityData: true,
})
if err != nil {
    log.Fatal(err)
}
fmt.Println("Matching rules:", result.MatchingRuleIDs)
fmt.Println("Entities:", result.Entities)

Requirements

  • Go 1.21 or higher
  • OpenTelemetry Collector or compatible backend

Contributing

We welcome contributions! See CONTRIBUTING.md for details.

License

Apache License 2.0 - see LICENSE

Support

Documentation

Overview

Package shield360 provides OpenTelemetry-native observability for LLM applications in Go. It offers automatic instrumentation for popular LLM providers like OpenAI and Anthropic.

Index

Constants

View Source
const Version = "1.0.0"

Version is the current version of the Shield360 Go SDK.

This is the single source of truth. Releases go through the Release / Packages workflow, which tags this repository `sdk-go-<Version>`; the mirror sync then tags ThinkfleetAI/shield360-go `v<Version>`, which is the tag Go itself resolves, because a module's import path is its repository URL and this repository is private.

Variables

This section is empty.

Functions

func Init

func Init(cfg Config) error

Init initializes the Shield360 SDK with the provided configuration. This should be called once at application startup.

Example:

err := shield360.Init(shield360.Config{
    OtlpEndpoint:    "http://127.0.0.1:4318",
    Environment:     "production",
    ApplicationName: "my-go-app",
})
if err != nil {
    log.Fatalf("Failed to initialize Shield360: %v", err)
}
defer shield360.Shutdown(context.Background())

func IsInitialized

func IsInitialized() bool

IsInitialized returns whether Shield360 has been initialized.

func Shutdown

func Shutdown(ctx context.Context) error

Shutdown gracefully shuts down the Shield360 SDK. It should be called before application exit to ensure all telemetry data is flushed.

Types

type Config

type Config struct {
	// OtlpEndpoint is the OTLP endpoint for sending traces and metrics
	// Default: "http://127.0.0.1:4318"
	OtlpEndpoint string

	// OtlpHeaders are additional headers to send with OTLP requests
	OtlpHeaders map[string]string

	// Environment identifies the deployment environment
	// Default: "default"
	Environment string

	// ApplicationName is the name of your application
	// Default: "default"
	ApplicationName string

	// TracerName is the name for the tracer provider
	// Default: "shield360"
	TracerName string

	// ServiceVersion is the version of your service
	ServiceVersion string

	// DisableTracing disables trace collection
	// Default: false
	DisableTracing bool

	// DisableMetrics disables metrics collection
	// Default: false
	DisableMetrics bool

	// DisableBatch disables batch processing for exports
	// Default: false
	DisableBatch bool

	// TraceExporterTimeout is the timeout for trace exports
	// Default: 10 seconds
	TraceExporterTimeout time.Duration

	// MetricExporterTimeout is the timeout for metric exports
	// Default: 10 seconds
	MetricExporterTimeout time.Duration

	// MetricExportInterval is the interval for metric exports
	// Default: 30 seconds
	MetricExportInterval time.Duration

	// PricingInfo contains custom pricing information for models
	PricingInfo map[string]ModelPricing

	// PricingEndpoint is the endpoint to fetch pricing information
	// Default: none; pricing is not fetched unless an endpoint is set
	PricingEndpoint string

	// DisablePricingFetch disables automatic pricing information fetching
	DisablePricingFetch bool

	// DisableCaptureMessageContent prevents prompt/completion text from being
	// recorded as span attributes. Set to true for privacy-sensitive workloads.
	// Default: false (content IS captured, matching Python SDK default of capture_message_content=True)
	DisableCaptureMessageContent bool

	// DetailedTracing enables detailed component-level tracing.
	// Default: false
	DetailedTracing bool

	// IDGenerator overrides the default OTel ID generator. Use this when
	// callers need deterministic trace/span IDs (e.g. the shield360 CLI's
	// coding-agent hook deriving a stable TraceId from a session id so
	// every span emitted across separate hook invocations lands in the
	// same trace). When nil, OTel's random generator is used.
	IDGenerator sdktrace.IDGenerator

	// Sampler overrides the default head sampler. When nil, the SDK
	// uses AlwaysSample — every span emitted reaches the collector.
	// Callers wanting a head-sampling strategy (e.g. drop noisy
	// `coding_agent.tool.requested` events) can pass a
	// ParentBasedSampler or a custom span-name aware sampler here.
	// See cli/internal/otlp/sampler.go for an example.
	Sampler sdktrace.Sampler

	// ExtraResourceAttributes are merged into the OTel Resource set on
	// every span/metric this SDK emits. Callers use this to attach
	// stable identity (e.g. `gen_ai.user.name`, `host.name`) once at
	// startup rather than tagging each span individually.
	ExtraResourceAttributes map[string]string
}

Config holds the configuration for Shield360 SDK initialization

func GetConfig

func GetConfig() *Config

GetConfig returns the current global configuration. Returns nil if Shield360 is not initialized.

type EvaluateRuleOptions

type EvaluateRuleOptions struct {
	// URL is the Shield360 dashboard base URL.
	// Falls back to SHIELD360_URL env var, then http://127.0.0.1:3000.
	URL string

	// APIKey is the Bearer token for authentication.
	// Falls back to SHIELD360_API_KEY env var.
	APIKey string

	// EntityType specifies which kind of entities to match ("context", "prompt", or "evaluation").
	EntityType RuleEntityType

	// Fields are the trace attributes to evaluate against rules.
	// Example: {"gen_ai.system": "openai", "gen_ai.request.model": "gpt-4"}
	Fields map[string]interface{}

	// IncludeEntityData requests full entity data in the response when true.
	IncludeEntityData bool

	// EntityInputs provides optional inputs for entity resolution (e.g. prompt variables).
	EntityInputs map[string]interface{}

	// Timeout for the HTTP request. Defaults to 30 seconds.
	Timeout time.Duration
}

EvaluateRuleOptions holds parameters for the EvaluateRule call.

type EvaluateRuleResult

type EvaluateRuleResult struct {
	MatchingRuleIDs []string               `json:"matchingRuleIds"`
	Entities        []RuleEntity           `json:"entities"`
	EntityData      map[string]interface{} `json:"entity_data,omitempty"`
}

EvaluateRuleResult is the parsed response from the rule engine evaluate endpoint.

func EvaluateRule

func EvaluateRule(ctx context.Context, opts EvaluateRuleOptions) (*EvaluateRuleResult, error)

EvaluateRule calls the Shield360 dashboard rule-engine evaluate endpoint. It sends the provided fields against configured rules and returns matching rule IDs, associated entities, and optionally the full entity data.

This function does NOT require shield360.Init() — it is a standalone HTTP call, consistent with get_prompt/get_secrets in the Python and TypeScript SDKs.

Example:

result, err := shield360.EvaluateRule(ctx, shield360.EvaluateRuleOptions{
    EntityType: shield360.RuleEntityContext,
    Fields: map[string]interface{}{
        "gen_ai.system":        "openai",
        "gen_ai.request.model": "gpt-4",
        "service.name":         "my-app",
    },
    IncludeEntityData: true,
})

type ModelPricing

type ModelPricing struct {
	InputCostPerToken  float64
	OutputCostPerToken float64
}

ModelPricing represents pricing information for a model

type RuleEntity

type RuleEntity struct {
	RuleID     string `json:"rule_id"`
	EntityType string `json:"entity_type"`
	EntityID   string `json:"entity_id"`
}

RuleEntity represents a single matched rule-entity association.

type RuleEntityType

type RuleEntityType string

RuleEntityType constrains the entity_type values accepted by the rule engine.

const (
	// RuleEntityContext matches rules that return context entities.
	RuleEntityContext RuleEntityType = "context"
	// RuleEntityPrompt matches rules that return prompt entities.
	RuleEntityPrompt RuleEntityType = "prompt"
	// RuleEntityEvaluation matches rules that return evaluation entities.
	RuleEntityEvaluation RuleEntityType = "evaluation"
)

Directories

Path Synopsis
instrumentation
Package semconv provides semantic conventions for Gen AI observability.
Package semconv provides semantic conventions for Gen AI observability.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL