counterspell

package module
v0.1.4 Latest Latest
Warning

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

Go to latest
Published: Oct 9, 2025 License: Apache-2.0 Imports: 14 Imported by: 0

README

Counterspell

A lightweight, embedded observability tool for Go applications that provides OpenTelemetry tracing and logging capabilities with a local SQLite database backend and REST API for data querying.

⚠️ This project is a work in progress and is not yet ready for production use. ⚠️

What it is

  • Fast and easy to get started, no added extra cost
  • Gives you observability UI for your LLM calls with the greatest of ease
  • Prompt evals
  • Prompt optimizer
  • Embedded observability with otel, zerolog (uses sqlite), throwaway sqlite db
  • Means no external dependencies, no xtra docker containers
  • Writes logs on a separate goroutine, so your app is not affected

Getting Started

Prerequisites
  • Docker and Docker Compose
  • Go (1.25 or later)
  • Node.js (20.x or later)
Running with Docker Compose

The easiest way to get Counterspell up and running is with Docker Compose.

docker-compose up

This will start the backend server on port 8080 and the frontend UI on port 5173.

  • Backend API: http://localhost:8080
  • Frontend UI: http://localhost:5173
Development Environment

For development, you can use the provided dev.sh script, which uses kitty to create a split-pane terminal for the backend and frontend.

./dev.sh

Counterspell

Installation

go get github.com/revrost/counterspell

Todo

  • Protobuf schemas
  • Agent configuration/blueprint framework
  • Openrouter integration
  • Lightweight execution runtime utilize goroutine (cadence/go-workflow)
  • Create agent, run agent, watch UI
  • Orchestrator-Executor MVP via ui
  • Otel integration
  • Openapi streaming spec
  • Move sqlite to postgres (later)

Quick Start

The simplest way to add Counterspell to your application:

func main() {
	// Example 1: Using Echo router
	err := counterspell.AddToEcho(e,
		counterspell.WithAuthToken("secret"),
	)
	if err != nil {
		slog.Error("Error adding counterspell middleware", "err", err)
	}
}

Go to your app endpoint e.g localhost:8080/counterspell

API Endpoints

All API endpoints require authentication via the Authorization: Bearer <token> header or auth query parameter.

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. Submit a pull request

License

This project is licensed under the Apache-2.0 License.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type APIHandler added in v0.1.4

type APIHandler struct {
	// contains filtered or unexported fields
}

APIHandler handles HTTP requests for the counterspell API

func NewAPIHandler added in v0.1.4

func NewAPIHandler(database *sql.DB) *APIHandler

NewAPIHandler creates a new API handler

func (*APIHandler) GetTraceDetails added in v0.1.4

func (h *APIHandler) GetTraceDetails(c echo.Context) error

GetTraceDetails handles GET /counterspell/api/traces/:trace_id

func (*APIHandler) QueryLogs added in v0.1.4

func (h *APIHandler) QueryLogs(c echo.Context) error

QueryLogs handles GET /counterspell/api/logs

func (*APIHandler) QueryTraces added in v0.1.4

func (h *APIHandler) QueryTraces(c echo.Context) error

QueryTraces handles GET /counterspell/api/traces

type APIResponse added in v0.1.4

type APIResponse struct {
	Metadata map[string]any `json:"metadata"`
	Data     any            `json:"data"`
}

APIResponse represents the standard API response format

type LogData added in v0.1.4

type LogData struct {
	Timestamp  string
	Level      string
	Message    string
	TraceID    sql.NullString
	SpanID     sql.NullString
	Attributes string
}

LogData represents a log entry for database insertion

type LogItem added in v0.1.4

type LogItem struct {
	ID         int64          `json:"id"`
	Timestamp  string         `json:"timestamp"`
	Level      string         `json:"level"`
	Message    string         `json:"message"`
	TraceID    *string        `json:"trace_id"`
	SpanID     *string        `json:"span_id"`
	Attributes map[string]any `json:"attributes"`
}

LogItem represents a log entry

type SQLiteLogWriter added in v0.1.4

type SQLiteLogWriter struct {
	// contains filtered or unexported fields
}

SQLiteLogWriter writes logs to SQLite asynchronously

func NewSQLiteLogWriter added in v0.1.4

func NewSQLiteLogWriter(database *sql.DB) *SQLiteLogWriter

NewSQLiteLogWriter creates a new log writer

func (*SQLiteLogWriter) Close added in v0.1.4

func (w *SQLiteLogWriter) Close() error

Close shuts down the writer

func (*SQLiteLogWriter) Write added in v0.1.4

func (w *SQLiteLogWriter) Write(p []byte) (n int, err error)

Write implements io.Writer

type SQLiteSpanExporter added in v0.1.4

type SQLiteSpanExporter struct {
	// contains filtered or unexported fields
}

SQLiteSpanExporter implements the OpenTelemetry SpanExporter interface and writes spans to SQLite database asynchronously

func NewSQLiteSpanExporter added in v0.1.4

func NewSQLiteSpanExporter(database *sql.DB) *SQLiteSpanExporter

NewSQLiteSpanExporter creates a new SQLite span exporter

func (*SQLiteSpanExporter) ExportSpans added in v0.1.4

func (e *SQLiteSpanExporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan) error

ExportSpans exports spans to the SQLite database This method is called by the OpenTelemetry SDK

func (*SQLiteSpanExporter) ForceFlush added in v0.1.4

func (e *SQLiteSpanExporter) ForceFlush(ctx context.Context) error

ForceFlush forces the exporter to flush any buffered spans

func (*SQLiteSpanExporter) Shutdown added in v0.1.4

func (e *SQLiteSpanExporter) Shutdown(ctx context.Context) error

Shutdown gracefully shuts down the exporter

type Service added in v0.1.4

type Service struct {
	// contains filtered or unexported fields
}

ServiceHandler handles HTTP requests for the counterspell API

func NewService added in v0.1.4

func NewService(database *sql.DB) *Service

NewServiceHandler creates a new ServiceHandler

func (*Service) CreateBlueprint added in v0.1.4

func (*Service) GetBlueprint added in v0.1.4

GetBlueprint

func (*Service) GetTrace added in v0.1.4

func (*Service) ListBlueprints added in v0.1.4

GetBlueprints

func (*Service) ListLogs added in v0.1.4

func (*Service) ListTraces added in v0.1.4

type SpanData added in v0.1.4

type SpanData struct {
	SpanID       string
	TraceID      string
	ParentSpanID sql.NullString
	Name         string
	StartTime    string
	EndTime      string
	DurationNs   int64
	Attributes   string
	ServiceName  string
	HasError     bool
}

SpanData represents a span ready to be inserted into the database

type SpanItem added in v0.1.4

type SpanItem struct {
	SpanID       string         `json:"span_id"`
	TraceID      string         `json:"trace_id"`
	ParentSpanID *string        `json:"parent_span_id"`
	Name         string         `json:"name"`
	StartTime    string         `json:"start_time"`
	EndTime      string         `json:"end_time"`
	DurationNs   int64          `json:"duration_ns"`
	Attributes   map[string]any `json:"attributes"`
	ServiceName  string         `json:"service_name"`
	HasError     bool           `json:"has_error"`
}

SpanItem represents a span in the trace detail view

type TraceDetail added in v0.1.4

type TraceDetail struct {
	TraceID string     `json:"trace_id"`
	Spans   []SpanItem `json:"spans"`
}

TraceDetail represents detailed trace information

type TraceListItem added in v0.1.4

type TraceListItem struct {
	TraceID        string  `json:"trace_id"`
	RootSpanName   string  `json:"root_span_name"`
	TraceStartTime string  `json:"trace_start_time"`
	DurationMs     float64 `json:"duration_ms"`
	SpanCount      int64   `json:"span_count"`
	ErrorCount     int64   `json:"error_count"`
	HasError       bool    `json:"has_error"`
}

TraceListItem represents a trace in the list view

Directories

Path Synopsis
cmd
cs command
server command
pkg
db

Jump to

Keyboard shortcuts

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