Integration Guide
Learn how to integrate Rustic Debug with your existing RusticAI applications and development workflow.
Integration Overview
Rustic Debug can be integrated in several ways:
- Standalone Mode - Run as a separate debugging service
- Embedded Mode - Integrate directly into your application
- Sidecar Pattern - Deploy alongside your services
- Development Mode - Use during local development
Standalone Integration
Basic Setup
The simplest way to integrate Rustic Debug is running it as a standalone service:
# Start Rustic Debug pointing to your Redis instance
rustic-debug start \
--redis-url redis://your-redis-host:6379 \
--guild-whitelist "your-guild-*" \
--port 3000
Docker Compose Integration
Add Rustic Debug to your existing docker-compose.yml
:
version: '3.8'
services:
# Your existing services
your-app:
image: your-app:latest
depends_on:
- redis
redis:
image: redis:7-alpine
ports:
- "6379:6379"
# Add Rustic Debug
rustic-debug:
image: rusticai/rustic-debug:latest
ports:
- "3000:3000"
environment:
- REDIS_URL=redis://redis:6379
- DEBUG_READ_ONLY=true
- DEBUG_GUILD_WHITELIST=production-*,staging-*
depends_on:
- redis
networks:
- your-network
Kubernetes Integration
Deploy Rustic Debug in your Kubernetes cluster:
apiVersion: apps/v1
kind: Deployment
metadata:
name: rustic-debug
namespace: rustic-ai
spec:
replicas: 1
selector:
matchLabels:
app: rustic-debug
template:
metadata:
labels:
app: rustic-debug
spec:
containers:
- name: rustic-debug
image: rusticai/rustic-debug:latest
ports:
- containerPort: 3000
env:
- name: REDIS_URL
valueFrom:
secretKeyRef:
name: redis-credentials
key: url
- name: DEBUG_READ_ONLY
value: "true"
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
name: rustic-debug-service
namespace: rustic-ai
spec:
selector:
app: rustic-debug
ports:
- port: 3000
targetPort: 3000
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rustic-debug-ingress
namespace: rustic-ai
spec:
rules:
- host: debug.your-domain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: rustic-debug-service
port:
number: 3000
Embedded Integration
Node.js/TypeScript Integration
Install the Rustic Debug SDK:
npm install @rustic-ai/debug-embedded
Embed in your application:
import { RusticDebugServer } from '@rustic-ai/debug-embedded';
import { createServer } from 'http';
// Your application
const app = express();
// Initialize Rustic Debug
const debugServer = new RusticDebugServer({
redis: {
url: process.env.REDIS_URL || 'redis://localhost:6379'
},
server: {
port: 3001, // Debug UI port
embedded: true
},
auth: {
enabled: true,
sharedSecret: process.env.DEBUG_SECRET
}
});
// Start debug server
await debugServer.start();
// Optional: Add middleware to your app
app.use('/debug', debugServer.getMiddleware());
// Your application routes
app.get('/health', (req, res) => {
res.json({
status: 'healthy',
debug: debugServer.getStatus()
});
});
app.listen(3000);
Python Integration
For Python RusticAI applications:
from rustic_debug import DebugServer, DebugMiddleware
from rustic_ai import Guild
import asyncio
# Initialize debug server
debug_server = DebugServer(
redis_url="redis://localhost:6379",
port=3001,
read_only=True
)
# Start debug server in background
async def start_debug():
await debug_server.start()
print(f"Debug UI available at http://localhost:3001")
# Add to your RusticAI guild
guild = Guild("my-guild")
# Add debug middleware
guild.add_middleware(DebugMiddleware(debug_server))
# Your application logic
@guild.agent("processor")
async def process_message(message):
# Debug context is automatically captured
result = await do_processing(message)
return result
# Run everything
async def main():
await asyncio.gather(
start_debug(),
guild.run()
)
if __name__ == "__main__":
asyncio.run(main())
Sidecar Pattern
Kubernetes Sidecar
Deploy Rustic Debug as a sidecar container:
apiVersion: apps/v1
kind: Deployment
metadata:
name: your-app-with-debug
spec:
template:
spec:
containers:
# Main application
- name: your-app
image: your-app:latest
ports:
- containerPort: 8080
# Rustic Debug sidecar
- name: debug-sidecar
image: rusticai/rustic-debug:latest
ports:
- containerPort: 3000
env:
- name: REDIS_URL
value: "redis://localhost:6379"
- name: DEBUG_GUILD_WHITELIST
value: "your-app-guild"
# Redis sidecar (optional)
- name: redis
image: redis:7-alpine
ports:
- containerPort: 6379
Docker Sidecar
Using Docker networks for sidecar pattern:
# Create network
docker network create rustic-network
# Run Redis
docker run -d \
--name redis \
--network rustic-network \
redis:7-alpine
# Run your application
docker run -d \
--name your-app \
--network rustic-network \
-e REDIS_URL=redis://redis:6379 \
your-app:latest
# Run Rustic Debug as sidecar
docker run -d \
--name rustic-debug \
--network rustic-network \
-p 3000:3000 \
-e REDIS_URL=redis://redis:6379 \
-e DEBUG_GUILD_WHITELIST=your-app-* \
rusticai/rustic-debug:latest
Development Integration
VS Code Integration
Add to .vscode/launch.json
:
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug with Rustic Debug",
"type": "node",
"request": "launch",
"runtimeExecutable": "npm",
"runtimeArgs": ["run", "dev:with-debug"],
"env": {
"RUSTIC_DEBUG_ENABLED": "true",
"RUSTIC_DEBUG_PORT": "3001"
},
"serverReadyAction": {
"pattern": "Debug UI available at (https?://localhost:[0-9]+)",
"uriFormat": "%s",
"action": "openExternally"
}
}
]
}
Add to package.json
:
{
"scripts": {
"dev:with-debug": "concurrently \"npm run dev\" \"rustic-debug start --dev\""
}
}
Testing Integration
Use Rustic Debug in your tests:
import { RusticDebugClient } from '@rustic-ai/debug-client';
import { describe, it, expect, beforeAll, afterAll } from 'jest';
describe('Message Processing', () => {
let debug: RusticDebugClient;
beforeAll(async () => {
debug = new RusticDebugClient({
url: 'http://localhost:3001'
});
await debug.connect();
});
afterAll(async () => {
await debug.disconnect();
});
it('should process messages without errors', async () => {
// Start monitoring
const monitor = debug.monitor({
guild: 'test-guild',
topic: 'test-topic'
});
// Run your test
await yourApp.processMessage({
topic: 'test-topic',
content: 'test message'
});
// Check results in debug
const messages = await monitor.getMessages();
expect(messages).toHaveLength(1);
expect(messages[0].status).toBe('success');
// Check for errors
const errors = await monitor.getErrors();
expect(errors).toHaveLength(0);
});
});
CI/CD Integration
GitHub Actions
.github/workflows/debug-integration.yml
:
name: Debug Integration Tests
on: [push, pull_request]
jobs:
test-with-debug:
runs-on: ubuntu-latest
services:
redis:
image: redis:7-alpine
ports:
- 6379:6379
rustic-debug:
image: rusticai/rustic-debug:latest
ports:
- 3001:3000
env:
REDIS_URL: redis://redis:6379
DEBUG_READ_ONLY: false
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm ci
- name: Run tests with debug monitoring
run: npm run test:integration
env:
REDIS_URL: redis://localhost:6379
DEBUG_URL: http://localhost:3001
- name: Export debug report
if: always()
run: |
npx @rustic-ai/debug-cli export \
--url http://localhost:3001 \
--format html \
--output debug-report.html
- name: Upload debug report
if: always()
uses: actions/upload-artifact@v3
with:
name: debug-report
path: debug-report.html
Jenkins Pipeline
pipeline {
agent any
stages {
stage('Setup') {
steps {
sh 'docker-compose up -d redis rustic-debug'
sh 'npm ci'
}
}
stage('Test with Debug') {
steps {
script {
try {
sh 'npm run test:integration'
} finally {
// Capture debug report
sh '''
npx @rustic-ai/debug-cli export \
--url http://localhost:3001 \
--format html \
--output debug-report.html
'''
archiveArtifacts artifacts: 'debug-report.html'
}
}
}
}
stage('Performance Test') {
steps {
sh '''
npx @rustic-ai/debug-cli monitor \
--url http://localhost:3001 \
--duration 5m \
--threshold-latency 100 \
--threshold-errors 1
'''
}
}
}
post {
always {
sh 'docker-compose down'
}
}
}
SDK Integration
JavaScript/TypeScript SDK
import { RusticDebugSDK } from '@rustic-ai/debug-sdk';
// Initialize SDK
const debug = new RusticDebugSDK({
apiUrl: 'http://localhost:3001',
apiKey: process.env.DEBUG_API_KEY
});
// Instrument your code
class MessageProcessor {
@debug.trace('process-message')
async processMessage(message: Message) {
// Automatically tracked
const result = await this.doProcessing(message);
return result;
}
@debug.measure('processing-time')
private async doProcessing(message: Message) {
// Performance metrics automatically collected
return await heavyComputation(message);
}
}
// Manual instrumentation
async function handleRequest(req: Request) {
const span = debug.startSpan('handle-request');
try {
// Your logic
const result = await process(req);
span.setTag('status', 'success');
return result;
} catch (error) {
span.setTag('error', true);
span.log({ event: 'error', message: error.message });
throw error;
} finally {
span.finish();
}
}
Python SDK
from rustic_debug import DebugSDK, trace, measure
# Initialize SDK
debug = DebugSDK(
api_url="http://localhost:3001",
api_key=os.environ.get("DEBUG_API_KEY")
)
class MessageProcessor:
@trace("process-message")
async def process_message(self, message):
# Automatically tracked
result = await self.do_processing(message)
return result
@measure("processing-time")
async def do_processing(self, message):
# Performance metrics collected
return await heavy_computation(message)
# Manual instrumentation
async def handle_request(request):
with debug.start_span("handle-request") as span:
try:
result = await process(request)
span.set_tag("status", "success")
return result
except Exception as e:
span.set_tag("error", True)
span.log({"event": "error", "message": str(e)})
raise
Configuration Management
Environment-Based Config
// config/debug.config.ts
export const debugConfig = {
development: {
enabled: true,
url: 'http://localhost:3001',
verbosity: 'debug',
features: {
replay: true,
export: true,
modify: true
}
},
staging: {
enabled: true,
url: 'https://debug-staging.example.com',
verbosity: 'info',
features: {
replay: false,
export: true,
modify: false
}
},
production: {
enabled: true,
url: 'https://debug.example.com',
verbosity: 'warn',
features: {
replay: false,
export: false,
modify: false
},
auth: {
required: true,
token: process.env.DEBUG_AUTH_TOKEN
}
}
};
// Use in application
const env = process.env.NODE_ENV || 'development';
const config = debugConfig[env];
if (config.enabled) {
const debug = new RusticDebugClient(config);
await debug.connect();
}
Monitoring Integration
Prometheus Metrics
# prometheus.yml
scrape_configs:
- job_name: 'rustic-debug'
static_configs:
- targets: ['localhost:3001']
metrics_path: '/metrics'
Grafana Dashboard
Import the Rustic Debug dashboard:
{
"dashboard": {
"title": "Rustic Debug Monitoring",
"panels": [
{
"title": "Message Rate",
"targets": [
{
"expr": "rate(rustic_debug_messages_total[5m])"
}
]
},
{
"title": "Error Rate",
"targets": [
{
"expr": "rate(rustic_debug_errors_total[5m])"
}
]
},
{
"title": "Latency P95",
"targets": [
{
"expr": "histogram_quantile(0.95, rustic_debug_latency_bucket)"
}
]
}
]
}
}
Security Considerations
Network Policies
# Kubernetes NetworkPolicy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: rustic-debug-network-policy
spec:
podSelector:
matchLabels:
app: rustic-debug
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
allow-debug: "true"
ports:
- protocol: TCP
port: 3000
egress:
- to:
- podSelector:
matchLabels:
app: redis
ports:
- protocol: TCP
port: 6379
Authentication Setup
// Secure integration with authentication
const debug = new RusticDebugClient({
url: 'https://debug.example.com',
auth: {
type: 'oauth2',
clientId: process.env.DEBUG_CLIENT_ID,
clientSecret: process.env.DEBUG_CLIENT_SECRET,
tokenUrl: 'https://auth.example.com/token'
},
tls: {
rejectUnauthorized: true,
ca: fs.readFileSync('/path/to/ca.pem')
}
});
Next Steps
- API Reference - Complete API documentation
- Contributing - Contribute to the project
- Architecture - System architecture