Documentation
¶
Overview ¶
Package recording owns session-recording capture and storage.
Index ¶
- Constants
- Variables
- func ContentType(format plugin.RecordingFormat) string
- func ExpiryFor(start time.Time, connectionDays, defaultDays int) *time.Time
- func StorageKey(connectionID, recordingID string, format plugin.RecordingFormat) string
- func StreamKey(userID, connectionID, routeID string, params map[string]string) string
- type BlobStore
- type Engine
- func (e *Engine) AbortChunked(ctx context.Context, recordingID, userID string) error
- func (e *Engine) AppendChunk(ctx context.Context, recordingID, userID string, index int, data []byte) error
- func (e *Engine) BeginChunked(ctx context.Context, info StreamInfo, format plugin.RecordingFormat) (models.Recording, error)
- func (e *Engine) FinalizeChunked(ctx context.Context, recordingID, userID string) (models.Recording, error)
- func (e *Engine) Prepare(ctx context.Context, info StreamInfo) (*Pending, error)
- func (e *Engine) ReapStaleChunked(ctx context.Context, maxAge time.Duration)
- func (e *Engine) Register(format plugin.RecordingFormat, f RecorderFactory)
- func (e *Engine) Resize(key string, cols, rows int)
- func (e *Engine) Start(ctx context.Context, key string) (models.Recording, error)
- func (e *Engine) Stop(_ context.Context, key string) error
- func (e *Engine) Wrap(ctx context.Context, client plugin.ClientStream, info StreamInfo) (plugin.ClientStream, func(), error)
- type LocalBlobStore
- func (s *LocalBlobStore) Append(_ context.Context, key string, data []byte) error
- func (s *LocalBlobStore) Create(_ context.Context, key string) (io.WriteCloser, error)
- func (s *LocalBlobStore) Delete(_ context.Context, key string) error
- func (s *LocalBlobStore) Open(_ context.Context, key string) (io.ReadCloser, error)
- func (s *LocalBlobStore) Size(_ context.Context, key string) (int64, error)
- type Metrics
- type Options
- type Pending
- type Recorder
- type RecorderFactory
- type StartInfo
- type StreamInfo
Constants ¶
const ( EventStart = "recording.start" EventFinalize = "recording.finalize" EventFailed = "recording.failed" EventRead = "recording.read" EventDelete = "recording.delete" )
Audit event names for recording lifecycle, kept separate from the route audit.
Variables ¶
var ErrInvalidKey = errors.New("recording: invalid storage key")
ErrInvalidKey is returned when a storage key would escape the blob root.
Functions ¶
func ContentType ¶
func ContentType(format plugin.RecordingFormat) string
ContentType is the HTTP content type a recording's bytes are served with.
func ExpiryFor ¶
ExpiryFor computes a recording's expiry from per-connection and default retention. Per-connection wins; nil means keep indefinitely (retention off).
func StorageKey ¶
func StorageKey(connectionID, recordingID string, format plugin.RecordingFormat) string
StorageKey builds the blob key for a recording, namespaced by connection.
Types ¶
type BlobStore ¶
type BlobStore interface {
// Create opens key for writing, truncating any existing object.
Create(ctx context.Context, key string) (io.WriteCloser, error)
// Append adds data to key, creating it if absent (chunked desktop uploads).
Append(ctx context.Context, key string, data []byte) error
// Open opens key for reading.
Open(ctx context.Context, key string) (io.ReadCloser, error)
// Size returns the byte length of key.
Size(ctx context.Context, key string) (int64, error)
// Delete removes key; absence is not an error.
Delete(ctx context.Context, key string) error
}
BlobStore stores recording bytes under server-generated keys.
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine decides whether a stream is recorded and owns recording lifecycle.
func (*Engine) AbortChunked ¶
AbortChunked discards an in-progress chunked recording and its bytes.
func (*Engine) AppendChunk ¶
func (e *Engine) AppendChunk(ctx context.Context, recordingID, userID string, index int, data []byte) error
AppendChunk appends one ordered chunk to a chunked recording.
func (*Engine) BeginChunked ¶
func (e *Engine) BeginChunked(ctx context.Context, info StreamInfo, format plugin.RecordingFormat) (models.Recording, error)
BeginChunked creates a desktop recording fed by client chunk uploads. The caller (HTTP handler) has already authorized the user for the connection.
func (*Engine) FinalizeChunked ¶
func (e *Engine) FinalizeChunked(ctx context.Context, recordingID, userID string) (models.Recording, error)
FinalizeChunked marks a chunked recording complete.
func (*Engine) ReapStaleChunked ¶
ReapStaleChunked aborts chunked recordings older than maxAge, freeing partial blobs left by abandoned browser captures.
func (*Engine) Register ¶
func (e *Engine) Register(format plugin.RecordingFormat, f RecorderFactory)
Register associates a recorder factory with a format.
func (*Engine) Resize ¶
Resize records a terminal resize for the live recording identified by key (the terminal resize control channel calls this). No-op when not recording.
func (*Engine) Start ¶
Start activates recording for a manual (idle) stream identified by key. It is a no-op if the stream is already recording.
func (*Engine) Stop ¶
Stop finalizes a manual recording identified by key. Forced recordings cannot be stopped while their stream is live.
func (*Engine) Wrap ¶
func (e *Engine) Wrap(ctx context.Context, client plugin.ClientStream, info StreamInfo) (plugin.ClientStream, func(), error)
Wrap is a convenience that prepares, attaches, and returns a finalize func.
type LocalBlobStore ¶
type LocalBlobStore struct {
// contains filtered or unexported fields
}
LocalBlobStore stores blobs as files under a root directory.
func NewLocalBlobStore ¶
func NewLocalBlobStore(root string) (*LocalBlobStore, error)
NewLocalBlobStore creates the root directory and returns a filesystem store.
func (*LocalBlobStore) Create ¶
func (s *LocalBlobStore) Create(_ context.Context, key string) (io.WriteCloser, error)
func (*LocalBlobStore) Delete ¶
func (s *LocalBlobStore) Delete(_ context.Context, key string) error
func (*LocalBlobStore) Open ¶
func (s *LocalBlobStore) Open(_ context.Context, key string) (io.ReadCloser, error)
type Metrics ¶
type Metrics interface {
RecordingStarted()
RecordingFinished()
AddRecordingBytes(n int)
RecordingFailed()
}
Metrics is the subset of telemetry the recording engine reports. It is satisfied by *telemetry.Metrics; a nil engine metrics falls back to noopMetrics.
type Options ¶
type Options struct {
Store store.RecordingStore
Blobs BlobStore
Audit audit.Sink
Metrics Metrics
DefaultRetentionDays int
BufferEvents int
Now func() time.Time
}
Options configures an Engine.
type Pending ¶
type Pending struct {
// contains filtered or unexported fields
}
Pending is the recording decision for a stream.
func (*Pending) Attach ¶
func (p *Pending) Attach(client plugin.ClientStream) plugin.ClientStream
Attach wraps the live client stream with the recording tap.
type Recorder ¶
type Recorder interface {
WriteOutput(ts time.Duration, p []byte) error
WriteInput(ts time.Duration, p []byte) error
Resize(ts time.Duration, cols, rows int) error
Close() error
}
Recorder encodes timestamped stream events into its backing writer. Timestamps are relative to the recording start (monotonic, non-decreasing). A Recorder is driven by a single goroutine (the tap drain loop), so it need not be reentrant.
type RecorderFactory ¶
RecorderFactory builds a Recorder for one recording, writing to w.