Documentation
¶
Index ¶
- Variables
- func CompareJSON(a, b []byte, ignorePaths []string) []string
- type Broadcaster
- type CapturedEntry
- type ComparisonConfig
- type ComparisonReport
- type Engine
- func (e *Engine) CancelReplay(ctx context.Context, runID string) error
- func (e *Engine) CompareRuns(ctx context.Context, runAID, runBID string) (*RunComparison, error)
- func (e *Engine) GenerateSynthetic(ctx context.Context, scenario SyntheticScenario) (*Recording, error)
- func (e *Engine) PauseReplay(ctx context.Context, runID string) error
- func (e *Engine) ResumeReplay(ctx context.Context, runID string) error
- func (e *Engine) SetBroadcaster(b Broadcaster)
- func (e *Engine) StartRecording(ctx context.Context, name string, durationSec int, filter RecordingFilter) (*Recording, error)
- func (e *Engine) StartReplay(ctx context.Context, recordingID string, speed float64) (*ReplayRun, error)
- func (e *Engine) StopRecording(ctx context.Context) (*Recording, error)
- func (e *Engine) Store() RecordingStore
- type LatencyStats
- type Mismatch
- type Recording
- type RecordingFilter
- type RecordingStatus
- type RecordingStore
- type ReplayResult
- type ReplayRun
- type ReplaySchedule
- type ReplayStatus
- type RunComparison
- type RunSummary
- type SyntheticScenario
Constants ¶
This section is empty.
Variables ¶
var ErrNotFound = errors.New("not found")
ErrNotFound is returned when a recording or run does not exist.
Functions ¶
func CompareJSON ¶
CompareJSON parses two JSON byte slices and returns a list of human-readable diff strings. Paths listed in ignorePaths are skipped.
Types ¶
type Broadcaster ¶
Broadcaster is the subset of admin.EventBroadcaster the engine needs.
type CapturedEntry ¶
type CapturedEntry struct {
ID string `json:"id"`
Timestamp time.Time `json:"timestamp"`
Service string `json:"service"`
Action string `json:"action"`
Method string `json:"method"`
Path string `json:"path"`
StatusCode int `json:"status_code"`
LatencyMs float64 `json:"latency_ms"`
RequestHeaders map[string]string `json:"request_headers,omitempty"`
RequestBody string `json:"request_body,omitempty"`
ResponseBody string `json:"response_body,omitempty"`
OffsetMs float64 `json:"offset_ms"` // milliseconds since recording start
}
CapturedEntry is a single request captured during a recording session.
type ComparisonConfig ¶
type ComparisonConfig struct {
IgnorePaths []string // JSON paths to skip (e.g., "RequestId", "ResponseMetadata")
IgnoreHeaders []string // Headers to skip during comparison
StrictMode bool // If false, only compare status codes + key fields
}
ComparisonConfig controls how two recordings are compared.
type ComparisonReport ¶
type ComparisonReport struct {
TotalRequests int `json:"total_requests"`
Matched int `json:"matched"`
Mismatched int `json:"mismatched"`
Errors int `json:"errors"`
CompatibilityPct float64 `json:"compatibility_pct"`
Mismatches []Mismatch `json:"mismatches,omitempty"`
}
ComparisonReport summarises the result of comparing two recordings.
func CompareRecordings ¶
func CompareRecordings(original, replay *Recording, cfg ComparisonConfig) *ComparisonReport
CompareRecordings compares two recordings entry-by-entry and returns a report. The original and replay recordings are matched by entry index order.
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine orchestrates traffic recording, replay, and synthetic generation.
func New ¶
func New(store RecordingStore, log *gateway.RequestLog, gwPort int) *Engine
New creates a traffic engine.
func (*Engine) CancelReplay ¶
CancelReplay cancels a running or paused replay.
func (*Engine) CompareRuns ¶
CompareRuns produces a side-by-side comparison of two replay runs.
func (*Engine) GenerateSynthetic ¶
func (e *Engine) GenerateSynthetic(ctx context.Context, scenario SyntheticScenario) (*Recording, error)
GenerateSynthetic creates a recording from a template scenario.
func (*Engine) PauseReplay ¶
PauseReplay pauses a running replay.
func (*Engine) ResumeReplay ¶
ResumeReplay resumes a paused replay.
func (*Engine) SetBroadcaster ¶
func (e *Engine) SetBroadcaster(b Broadcaster)
SetBroadcaster wires an SSE broadcaster for progress events.
func (*Engine) StartRecording ¶
func (e *Engine) StartRecording(ctx context.Context, name string, durationSec int, filter RecordingFilter) (*Recording, error)
StartRecording begins capturing live traffic from the RequestLog. It polls the log every 250ms for new entries matching the filter and automatically stops after durationSec seconds (0 = indefinite until StopRecording).
func (*Engine) StartReplay ¶
func (e *Engine) StartReplay(ctx context.Context, recordingID string, speed float64) (*ReplayRun, error)
StartReplay replays a recording against the gateway at the given speed multiplier.
func (*Engine) StopRecording ¶
StopRecording stops the currently active recording.
func (*Engine) Store ¶
func (e *Engine) Store() RecordingStore
Store returns the underlying RecordingStore.
type LatencyStats ¶
type LatencyStats struct {
MinMs float64 `json:"min_ms"`
MaxMs float64 `json:"max_ms"`
AvgMs float64 `json:"avg_ms"`
P50Ms float64 `json:"p50_ms"`
P95Ms float64 `json:"p95_ms"`
P99Ms float64 `json:"p99_ms"`
}
LatencyStats summarises latency across a replay run.
type Mismatch ¶
type Mismatch struct {
EntryID string `json:"entry_id"`
Service string `json:"service"`
Action string `json:"action"`
OriginalStatus int `json:"original_status"`
ReplayStatus int `json:"replay_status"`
Diffs []string `json:"diffs"`
Severity string `json:"severity"` // "status", "data", "schema"
}
Mismatch describes a single entry-level discrepancy between two recordings.
type Recording ¶
type Recording struct {
ID string `json:"id"`
Name string `json:"name"`
Status RecordingStatus `json:"status"`
Filter RecordingFilter `json:"filter"`
DurationSec int `json:"duration_sec"`
StartedAt time.Time `json:"started_at"`
StoppedAt *time.Time `json:"stopped_at,omitempty"`
EntryCount int `json:"entry_count"`
Entries []CapturedEntry `json:"entries,omitempty"`
}
Recording holds a named set of captured traffic.
type RecordingFilter ¶
type RecordingFilter struct {
Service string `json:"service,omitempty"`
Path string `json:"path,omitempty"`
Method string `json:"method,omitempty"`
}
RecordingFilter constrains which requests are captured.
type RecordingStatus ¶
type RecordingStatus string
RecordingStatus describes the state of a traffic recording.
const ( RecordingActive RecordingStatus = "active" RecordingCompleted RecordingStatus = "completed" RecordingStopped RecordingStatus = "stopped" )
type RecordingStore ¶
type RecordingStore interface {
SaveRecording(ctx context.Context, rec *Recording) error
GetRecording(ctx context.Context, id string) (*Recording, error)
ListRecordings(ctx context.Context) ([]Recording, error)
DeleteRecording(ctx context.Context, id string) error
SaveRun(ctx context.Context, run *ReplayRun) error
GetRun(ctx context.Context, id string) (*ReplayRun, error)
ListRuns(ctx context.Context) ([]ReplayRun, error)
UpdateRun(ctx context.Context, run *ReplayRun) error
}
RecordingStore persists traffic recordings and replay runs.
type ReplayResult ¶
type ReplayResult struct {
EntryID string `json:"entry_id"`
OriginalStatus int `json:"original_status"`
OriginalMs float64 `json:"original_latency_ms"`
ReplayStatus int `json:"replay_status"`
ReplayMs float64 `json:"replay_latency_ms"`
Match bool `json:"match"`
LatencyDelta float64 `json:"latency_delta_ms"`
Error string `json:"error,omitempty"`
}
ReplayResult captures the outcome of replaying one captured entry.
type ReplayRun ¶
type ReplayRun struct {
ID string `json:"id"`
RecordingID string `json:"recording_id"`
Status ReplayStatus `json:"status"`
Speed float64 `json:"speed"` // 1.0 = realtime, 2.0 = 2x, etc.
StartedAt time.Time `json:"started_at"`
FinishedAt *time.Time `json:"finished_at,omitempty"`
TotalCount int `json:"total_count"`
ReplayedCount int `json:"replayed_count"`
MatchCount int `json:"match_count"`
MismatchCount int `json:"mismatch_count"`
ErrorCount int `json:"error_count"`
Results []ReplayResult `json:"results,omitempty"`
Stats LatencyStats `json:"stats"`
}
ReplayRun tracks a single replay execution.
type ReplaySchedule ¶
type ReplaySchedule struct {
ID string `json:"id"`
RecordingID string `json:"recording_id"`
Speed float64 `json:"speed"`
CronExpr string `json:"cron_expr"`
Enabled bool `json:"enabled"`
}
ReplaySchedule defines a cron-like schedule for running replays automatically.
type ReplayStatus ¶
type ReplayStatus string
ReplayStatus describes the state of a replay run.
const ( ReplayPending ReplayStatus = "pending" ReplayRunning ReplayStatus = "running" ReplayPaused ReplayStatus = "paused" ReplayCompleted ReplayStatus = "completed" ReplayCancelled ReplayStatus = "cancelled" ReplayFailed ReplayStatus = "failed" )
type RunComparison ¶
type RunComparison struct {
RunA RunSummary `json:"run_a"`
RunB RunSummary `json:"run_b"`
LatencyDelta LatencyStats `json:"latency_delta"`
MatchDelta float64 `json:"match_rate_delta"` // runB match% - runA match%
}
RunComparison holds a side-by-side comparison of two replay runs.
type RunSummary ¶
type RunSummary struct {
ID string `json:"id"`
RecordingID string `json:"recording_id"`
Status ReplayStatus `json:"status"`
TotalCount int `json:"total_count"`
MatchRate float64 `json:"match_rate"`
Stats LatencyStats `json:"stats"`
}
RunSummary is a compact summary of a replay run for comparisons.
type SyntheticScenario ¶
type SyntheticScenario struct {
Name string `json:"name"`
Service string `json:"service"`
Action string `json:"action"`
Method string `json:"method"`
Path string `json:"path"`
Headers map[string]string `json:"headers,omitempty"`
Body string `json:"body,omitempty"`
Count int `json:"count"` // number of entries to generate
IntervalMs int `json:"interval_ms"` // spacing between entries
}
SyntheticScenario defines a template for generating synthetic traffic recordings.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package dynamostore implements traffic.RecordingStore backed by DynamoDB via the generic dynamostore package.
|
Package dynamostore implements traffic.RecordingStore backed by DynamoDB via the generic dynamostore package. |
|
Package filestore persists traffic recordings and replay runs as JSON files on disk.
|
Package filestore persists traffic recordings and replay runs as JSON files on disk. |