Documentation
¶
Overview ¶
Package capture stores bounded, best-effort diagnostics for requests under declared webhook prefixes and serves guarded viewer routes. Prefixes and full-body mode are Go declarations (application.Builder.CaptureWebhooks); deployment settings can only reduce capture, never extend it.
Index ¶
- Constants
- func CaptureBodyOmissionCodec() codec.Codec[CaptureBodyOmission]
- func CaptureBodyStateCodec() codec.Codec[CaptureBodyState]
- func CaptureModeCodec() codec.Codec[CaptureMode]
- func CaptureOmissionCodec() codec.Codec[CaptureOmission]
- func CaptureResponseStateCodec() codec.Codec[CaptureResponseState]
- func CapturedFieldJSON() foundrycontract.JSON[CapturedField]
- func CapturedRequestDetailJSON() foundrycontract.JSON[CapturedRequestDetail]
- func CapturedRequestFiltersDescriptor() foundryhttp.Query[CapturedRequestFilters]
- func CapturedRequestJSON() foundrycontract.JSON[CapturedRequest]
- func CapturedRequestPathDescriptor() foundryhttp.Path[CapturedRequestPath]
- func Command(construct func(foundation.Resolver) (*Store, error)) (cli.Declaration, error)
- func Migrations() []migrate.Definition
- func Module(name foundation.ProviderID, key foundation.Key[*Store], ...) foundation.Module
- func NewRecorder(config Config) (*httpcapture.Recorder, error)
- func Routes[M any](group http.Scope, captures *Store, guard http.GuardBinding[M], ...) ([]http.RouteRegistration, error)
- type CaptureBodyOmission
- func (CaptureBodyOmission) EnumDescriptor() enum.Descriptor[CaptureBodyOmission]
- func (v CaptureBodyOmission) IsValid() bool
- func (v CaptureBodyOmission) MarshalJSON() ([]byte, error)
- func (v CaptureBodyOmission) MarshalText() ([]byte, error)
- func (v *CaptureBodyOmission) Scan(source any) error
- func (v *CaptureBodyOmission) UnmarshalJSON(data []byte) error
- func (v *CaptureBodyOmission) UnmarshalText(data []byte) error
- func (v CaptureBodyOmission) Validate() error
- func (v CaptureBodyOmission) Value() (driver.Value, error)
- type CaptureBodyState
- func (CaptureBodyState) EnumDescriptor() enum.Descriptor[CaptureBodyState]
- func (v CaptureBodyState) IsValid() bool
- func (v CaptureBodyState) MarshalJSON() ([]byte, error)
- func (v CaptureBodyState) MarshalText() ([]byte, error)
- func (v *CaptureBodyState) Scan(source any) error
- func (v *CaptureBodyState) UnmarshalJSON(data []byte) error
- func (v *CaptureBodyState) UnmarshalText(data []byte) error
- func (v CaptureBodyState) Validate() error
- func (v CaptureBodyState) Value() (driver.Value, error)
- type CaptureMode
- func (CaptureMode) EnumDescriptor() enum.Descriptor[CaptureMode]
- func (v CaptureMode) IsValid() bool
- func (v CaptureMode) MarshalJSON() ([]byte, error)
- func (v CaptureMode) MarshalText() ([]byte, error)
- func (v *CaptureMode) Scan(source any) error
- func (v *CaptureMode) UnmarshalJSON(data []byte) error
- func (v *CaptureMode) UnmarshalText(data []byte) error
- func (v CaptureMode) Validate() error
- func (v CaptureMode) Value() (driver.Value, error)
- type CaptureOmission
- func (CaptureOmission) EnumDescriptor() enum.Descriptor[CaptureOmission]
- func (v CaptureOmission) IsValid() bool
- func (v CaptureOmission) MarshalJSON() ([]byte, error)
- func (v CaptureOmission) MarshalText() ([]byte, error)
- func (v *CaptureOmission) Scan(source any) error
- func (v *CaptureOmission) UnmarshalJSON(data []byte) error
- func (v *CaptureOmission) UnmarshalText(data []byte) error
- func (v CaptureOmission) Validate() error
- func (v CaptureOmission) Value() (driver.Value, error)
- type CaptureResponseState
- func (CaptureResponseState) EnumDescriptor() enum.Descriptor[CaptureResponseState]
- func (v CaptureResponseState) IsValid() bool
- func (v CaptureResponseState) MarshalJSON() ([]byte, error)
- func (v CaptureResponseState) MarshalText() ([]byte, error)
- func (v *CaptureResponseState) Scan(source any) error
- func (v *CaptureResponseState) UnmarshalJSON(data []byte) error
- func (v *CaptureResponseState) UnmarshalText(data []byte) error
- func (v CaptureResponseState) Validate() error
- func (v CaptureResponseState) Value() (driver.Value, error)
- type CapturedField
- type CapturedFieldValidationFieldSet
- type CapturedRequest
- type CapturedRequestDetail
- type CapturedRequestDetailValidationFieldSet
- type CapturedRequestFilters
- type CapturedRequestPath
- type CapturedRequestValidationFieldSet
- type Config
- type Dependencies
- type PruneCommand
- type Store
Constants ¶
Variables ¶
This section is empty.
Functions ¶
func CaptureBodyOmissionCodec ¶
func CaptureBodyOmissionCodec() codec.Codec[CaptureBodyOmission]
CaptureBodyOmissionCodec applies the generated membership rule at both SQL boundaries. Example: CaptureBodyOmissionCodec()
func CaptureBodyStateCodec ¶
func CaptureBodyStateCodec() codec.Codec[CaptureBodyState]
CaptureBodyStateCodec applies the generated membership rule at both SQL boundaries. Example: CaptureBodyStateCodec()
func CaptureModeCodec ¶
func CaptureModeCodec() codec.Codec[CaptureMode]
CaptureModeCodec applies the generated membership rule at both SQL boundaries. Example: CaptureModeCodec()
func CaptureOmissionCodec ¶
func CaptureOmissionCodec() codec.Codec[CaptureOmission]
CaptureOmissionCodec applies the generated membership rule at both SQL boundaries. Example: CaptureOmissionCodec()
func CaptureResponseStateCodec ¶
func CaptureResponseStateCodec() codec.Codec[CaptureResponseState]
CaptureResponseStateCodec applies the generated membership rule at both SQL boundaries. Example: CaptureResponseStateCodec()
func CapturedFieldJSON ¶
func CapturedFieldJSON() foundrycontract.JSON[CapturedField]
CapturedFieldJSON describes the concrete CapturedField JSON boundary. Reuse this immutable descriptor for decoding and client contract export. Fields are discovered from Go declarations; persistence models are not response DTOs. Example: CapturedFieldJSON()
func CapturedRequestDetailJSON ¶
func CapturedRequestDetailJSON() foundrycontract.JSON[CapturedRequestDetail]
CapturedRequestDetailJSON describes the concrete CapturedRequestDetail JSON boundary. Reuse this immutable descriptor for decoding and client contract export. Fields are discovered from Go declarations; persistence models are not response DTOs. Example: CapturedRequestDetailJSON()
func CapturedRequestFiltersDescriptor ¶
func CapturedRequestFiltersDescriptor() foundryhttp.Query[CapturedRequestFilters]
CapturedRequestFiltersDescriptor binds query parameters to concrete CapturedRequestFilters fields. Reuse this descriptor for request decoding and query URL encoding. Optional fields preserve omission; repeated fields retain slice order.
Example: CapturedRequestFiltersDescriptor()
func CapturedRequestJSON ¶
func CapturedRequestJSON() foundrycontract.JSON[CapturedRequest]
CapturedRequestJSON describes the concrete CapturedRequest JSON boundary. Reuse this immutable descriptor for decoding and client contract export. Fields are discovered from Go declarations; persistence models are not response DTOs. Example: CapturedRequestJSON()
func CapturedRequestPathDescriptor ¶
func CapturedRequestPathDescriptor() foundryhttp.Path[CapturedRequestPath]
CapturedRequestPathDescriptor binds the declared pattern to concrete CapturedRequestPath fields. Reuse this descriptor for route registration and named URL generation.
func Command ¶
func Command(construct func(foundation.Resolver) (*Store, error)) (cli.Declaration, error)
Command declares `webhook-captures prune` for the ordinary CLI registry. construct resolves a store after boot; it works after capture is disabled or removed, as long as the table's database and schema are configured.
Example: capture.Command(func(r foundation.Resolver) (*capture.Store, error) { return foundation.Resolve(r, key) })
func Migrations ¶
func Migrations() []migrate.Definition
Migrations returns the framework-owned capture table. Application assembly registers it for the configured database and schema; apply it with the ordinary migration command before capture can store rows. Rolling back the framework keeps the table.
func Module ¶
func Module(name foundation.ProviderID, key foundation.Key[*Store], requires []foundation.ProviderID, construct func(foundation.Resolver) (*Store, error)) foundation.Module
Module registers the store factory and, at boot, its cleanup before any work starts. The writer and retention loop run beside the HTTP kernel, where captures originate, or after Start without a selected kernel; CLI and worker processes resolve the store for reads and the prune command. Cleanup runs after the HTTP kernel has drained and waits for Close to finish. Requires must name every borrowed resource owner.
Example: capture.Module("app.webhook-captures", key, requires, construct)
func NewRecorder ¶
func NewRecorder(config Config) (*httpcapture.Recorder, error)
NewRecorder validates config and builds the static in-memory handoff that the HTTP kernel fills and the Store drains. It performs no I/O and starts no goroutine. Application assembly passes it to http.WithWebhookCapture and New.
func Routes ¶
func Routes[M any](group http.Scope, captures *Store, guard http.GuardBinding[M], access ...http.GuardOption[M]) ([]http.RouteRegistration, error)
Routes declares the read-only viewer within group under /webhook-captures:
GET "" ID <group>.webhook-captures.list newest-first cursor page of CapturedRequest
GET "/{request}" ID <group>.webhook-captures.show CapturedRequestDetail, 404 when unknown or expired
Both routes authenticate through guard, require every access option before decoding the query or path, and send Cache-Control: no-store. access must not be empty: mounting the viewer always states who may read captured payloads. List requires a from time and a window of at most 30 days; pages hold 30 items by default and at most 100. Declarations are validated before return.
Example: capture.Routes(group, captures, admins, http.Scopes(developerRead), http.Permissions(developerPermission))
Types ¶
type CaptureBodyOmission ¶
type CaptureBodyOmission string
CaptureBodyOmission explains why a body was not stored. Completeness comes only from an observed end of stream, never from a successful parse.
const ( // OmittedUnread: the request finished before capture read its body, as // with maintenance, capacity or declared-length rejections. OmittedUnread CaptureBodyOmission = "unread" // OmittedOverCaptureLimit: the body exceeded the configured capture limit. OmittedOverCaptureLimit CaptureBodyOmission = "over_capture_limit" // OmittedBodyLimit: the server body limit stopped reading. OmittedBodyLimit CaptureBodyOmission = "body_limit" // OmittedClientDisconnect: the client closed the stream early. OmittedClientDisconnect CaptureBodyOmission = "client_disconnect" // OmittedReadTimeout: the read deadline expired. OmittedReadTimeout CaptureBodyOmission = "read_timeout" // OmittedReadFailed: another transport read failure. OmittedReadFailed CaptureBodyOmission = "read_failed" // OmittedContentEncoded: redacted mode cannot inspect compressed bodies. OmittedContentEncoded CaptureBodyOmission = "content_encoded" // OmittedUnsupportedMediaType: redacted mode stores only JSON, URL-encoded // and multipart form bodies. OmittedUnsupportedMediaType CaptureBodyOmission = "unsupported_media_type" // OmittedMalformed: the body did not parse as its declared media type and // is never stored raw. OmittedMalformed CaptureBodyOmission = "malformed" // OmittedRedactionLimit: nesting, token, part or output bounds were exceeded. OmittedRedactionLimit CaptureBodyOmission = "redaction_limit" )
func CaptureBodyOmissionValues ¶
func CaptureBodyOmissionValues() []CaptureBodyOmission
CaptureBodyOmissionValues returns declared values in source order, with independent slice ownership. Example: CaptureBodyOmissionValues()
func ParseCaptureBodyOmission ¶
func ParseCaptureBodyOmission(text string) (CaptureBodyOmission, error)
ParseCaptureBodyOmission decodes and validates an enum's text representation. Example: ParseCaptureBodyOmission(text)
func (CaptureBodyOmission) EnumDescriptor ¶
func (CaptureBodyOmission) EnumDescriptor() enum.Descriptor[CaptureBodyOmission]
EnumDescriptor describes this enum type independently of the receiver's value.
func (CaptureBodyOmission) IsValid ¶
func (v CaptureBodyOmission) IsValid() bool
IsValid checks membership; a Go cast alone does not validate external values.
func (CaptureBodyOmission) MarshalJSON ¶
func (v CaptureBodyOmission) MarshalJSON() ([]byte, error)
MarshalJSON encodes a validated enum as JSON.
func (CaptureBodyOmission) MarshalText ¶
func (v CaptureBodyOmission) MarshalText() ([]byte, error)
MarshalText encodes a validated enum as text.
func (*CaptureBodyOmission) Scan ¶
func (v *CaptureBodyOmission) Scan(source any) error
Scan changes the receiver only after successful decoding. SQL NULL is rejected.
func (*CaptureBodyOmission) UnmarshalJSON ¶
func (v *CaptureBodyOmission) UnmarshalJSON(data []byte) error
UnmarshalJSON decodes validated JSON and rejects null.
func (*CaptureBodyOmission) UnmarshalText ¶
func (v *CaptureBodyOmission) UnmarshalText(data []byte) error
UnmarshalText decodes validated enum text and changes the receiver only on success.
func (CaptureBodyOmission) Validate ¶
func (v CaptureBodyOmission) Validate() error
Validate reports invalid values without formatting the input.
type CaptureBodyState ¶
type CaptureBodyState string
CaptureBodyState says what a capture's stored body holds.
const ( // BodyEmpty is a complete request without body bytes. BodyEmpty CaptureBodyState = "empty" // BodyExact holds the complete body bytes exactly as received (full mode). BodyExact CaptureBodyState = "exact" // BodyJSON holds the redacted JSON document. BodyJSON CaptureBodyState = "json" // BodyForm holds redacted URL-encoded fields as a JSON array of // {"name","values"} objects. BodyForm CaptureBodyState = "form" // BodyMultipart holds a JSON array describing each part; file contents // are never stored. BodyMultipart CaptureBodyState = "multipart" // BodyOmitted stores nothing; CaptureBodyOmission says why. BodyOmitted CaptureBodyState = "omitted" )
func CaptureBodyStateValues ¶
func CaptureBodyStateValues() []CaptureBodyState
CaptureBodyStateValues returns declared values in source order, with independent slice ownership. Example: CaptureBodyStateValues()
func ParseCaptureBodyState ¶
func ParseCaptureBodyState(text string) (CaptureBodyState, error)
ParseCaptureBodyState decodes and validates an enum's text representation. Example: ParseCaptureBodyState(text)
func (CaptureBodyState) EnumDescriptor ¶
func (CaptureBodyState) EnumDescriptor() enum.Descriptor[CaptureBodyState]
EnumDescriptor describes this enum type independently of the receiver's value.
func (CaptureBodyState) IsValid ¶
func (v CaptureBodyState) IsValid() bool
IsValid checks membership; a Go cast alone does not validate external values.
func (CaptureBodyState) MarshalJSON ¶
func (v CaptureBodyState) MarshalJSON() ([]byte, error)
MarshalJSON encodes a validated enum as JSON.
func (CaptureBodyState) MarshalText ¶
func (v CaptureBodyState) MarshalText() ([]byte, error)
MarshalText encodes a validated enum as text.
func (*CaptureBodyState) Scan ¶
func (v *CaptureBodyState) Scan(source any) error
Scan changes the receiver only after successful decoding. SQL NULL is rejected.
func (*CaptureBodyState) UnmarshalJSON ¶
func (v *CaptureBodyState) UnmarshalJSON(data []byte) error
UnmarshalJSON decodes validated JSON and rejects null.
func (*CaptureBodyState) UnmarshalText ¶
func (v *CaptureBodyState) UnmarshalText(data []byte) error
UnmarshalText decodes validated enum text and changes the receiver only on success.
func (CaptureBodyState) Validate ¶
func (v CaptureBodyState) Validate() error
Validate reports invalid values without formatting the input.
type CaptureMode ¶
type CaptureMode string
CaptureMode is the body disclosure policy a capture was stored under.
const ( // Redacted masks credential-named fields, shortens long values and // summarizes multipart files. It is the default for every prefix. Redacted CaptureMode = "redacted" // Full stores complete bodies within the capture limit exactly as received. // Only a Go declaration with http.FullCaptureBody selects it. Full CaptureMode = "full" )
func CaptureModeValues ¶
func CaptureModeValues() []CaptureMode
CaptureModeValues returns declared values in source order, with independent slice ownership. Example: CaptureModeValues()
func ParseCaptureMode ¶
func ParseCaptureMode(text string) (CaptureMode, error)
ParseCaptureMode decodes and validates an enum's text representation. Example: ParseCaptureMode(text)
func (CaptureMode) EnumDescriptor ¶
func (CaptureMode) EnumDescriptor() enum.Descriptor[CaptureMode]
EnumDescriptor describes this enum type independently of the receiver's value.
func (CaptureMode) IsValid ¶
func (v CaptureMode) IsValid() bool
IsValid checks membership; a Go cast alone does not validate external values.
func (CaptureMode) MarshalJSON ¶
func (v CaptureMode) MarshalJSON() ([]byte, error)
MarshalJSON encodes a validated enum as JSON.
func (CaptureMode) MarshalText ¶
func (v CaptureMode) MarshalText() ([]byte, error)
MarshalText encodes a validated enum as text.
func (*CaptureMode) Scan ¶
func (v *CaptureMode) Scan(source any) error
Scan changes the receiver only after successful decoding. SQL NULL is rejected.
func (*CaptureMode) UnmarshalJSON ¶
func (v *CaptureMode) UnmarshalJSON(data []byte) error
UnmarshalJSON decodes validated JSON and rejects null.
func (*CaptureMode) UnmarshalText ¶
func (v *CaptureMode) UnmarshalText(data []byte) error
UnmarshalText decodes validated enum text and changes the receiver only on success.
func (CaptureMode) Validate ¶
func (v CaptureMode) Validate() error
Validate reports invalid values without formatting the input.
type CaptureOmission ¶
type CaptureOmission string
CaptureOmission marks request or response metadata that was cut to its bound or left out.
const ( MethodTruncated CaptureOmission = "method_truncated" PathTruncated CaptureOmission = "path_truncated" QueryTruncated CaptureOmission = "query_truncated" QueryMalformed CaptureOmission = "query_malformed" HeadersTruncated CaptureOmission = "headers_truncated" ContentTypeTruncated CaptureOmission = "content_type_truncated" ContentEncodingTruncated CaptureOmission = "content_encoding_truncated" ResponseTruncated CaptureOmission = "response_truncated" ResponseMetadataTruncated CaptureOmission = "response_metadata_truncated" )
func CaptureOmissionValues ¶
func CaptureOmissionValues() []CaptureOmission
CaptureOmissionValues returns declared values in source order, with independent slice ownership. Example: CaptureOmissionValues()
func ParseCaptureOmission ¶
func ParseCaptureOmission(text string) (CaptureOmission, error)
ParseCaptureOmission decodes and validates an enum's text representation. Example: ParseCaptureOmission(text)
func (CaptureOmission) EnumDescriptor ¶
func (CaptureOmission) EnumDescriptor() enum.Descriptor[CaptureOmission]
EnumDescriptor describes this enum type independently of the receiver's value.
func (CaptureOmission) IsValid ¶
func (v CaptureOmission) IsValid() bool
IsValid checks membership; a Go cast alone does not validate external values.
func (CaptureOmission) MarshalJSON ¶
func (v CaptureOmission) MarshalJSON() ([]byte, error)
MarshalJSON encodes a validated enum as JSON.
func (CaptureOmission) MarshalText ¶
func (v CaptureOmission) MarshalText() ([]byte, error)
MarshalText encodes a validated enum as text.
func (*CaptureOmission) Scan ¶
func (v *CaptureOmission) Scan(source any) error
Scan changes the receiver only after successful decoding. SQL NULL is rejected.
func (*CaptureOmission) UnmarshalJSON ¶
func (v *CaptureOmission) UnmarshalJSON(data []byte) error
UnmarshalJSON decodes validated JSON and rejects null.
func (*CaptureOmission) UnmarshalText ¶
func (v *CaptureOmission) UnmarshalText(data []byte) error
UnmarshalText decodes validated enum text and changes the receiver only on success.
func (CaptureOmission) Validate ¶
func (v CaptureOmission) Validate() error
Validate reports invalid values without formatting the input.
type CaptureResponseState ¶
type CaptureResponseState string
CaptureResponseState records how the handler's response ended. It describes writes the server accepted, not delivery to the caller.
const ( // ResponseComplete: the handler returned and every write was accepted. ResponseComplete CaptureResponseState = "complete" // ResponseWriteFailed: a response write failed. ResponseWriteFailed CaptureResponseState = "write_failed" // ResponseAborted: a raw panic aborted the connection. ResponseAborted CaptureResponseState = "aborted" // ResponseHijacked: the handler took over the connection. ResponseHijacked CaptureResponseState = "hijacked" )
func CaptureResponseStateValues ¶
func CaptureResponseStateValues() []CaptureResponseState
CaptureResponseStateValues returns declared values in source order, with independent slice ownership. Example: CaptureResponseStateValues()
func ParseCaptureResponseState ¶
func ParseCaptureResponseState(text string) (CaptureResponseState, error)
ParseCaptureResponseState decodes and validates an enum's text representation. Example: ParseCaptureResponseState(text)
func (CaptureResponseState) EnumDescriptor ¶
func (CaptureResponseState) EnumDescriptor() enum.Descriptor[CaptureResponseState]
EnumDescriptor describes this enum type independently of the receiver's value.
func (CaptureResponseState) IsValid ¶
func (v CaptureResponseState) IsValid() bool
IsValid checks membership; a Go cast alone does not validate external values.
func (CaptureResponseState) MarshalJSON ¶
func (v CaptureResponseState) MarshalJSON() ([]byte, error)
MarshalJSON encodes a validated enum as JSON.
func (CaptureResponseState) MarshalText ¶
func (v CaptureResponseState) MarshalText() ([]byte, error)
MarshalText encodes a validated enum as text.
func (*CaptureResponseState) Scan ¶
func (v *CaptureResponseState) Scan(source any) error
Scan changes the receiver only after successful decoding. SQL NULL is rejected.
func (*CaptureResponseState) UnmarshalJSON ¶
func (v *CaptureResponseState) UnmarshalJSON(data []byte) error
UnmarshalJSON decodes validated JSON and rejects null.
func (*CaptureResponseState) UnmarshalText ¶
func (v *CaptureResponseState) UnmarshalText(data []byte) error
UnmarshalText decodes validated enum text and changes the receiver only on success.
func (CaptureResponseState) Validate ¶
func (v CaptureResponseState) Validate() error
Validate reports invalid values without formatting the input.
type CapturedField ¶
CapturedField is one header, query or form name with its values. Masked credential values read "[masked]".
type CapturedFieldValidationFieldSet ¶
type CapturedFieldValidationFieldSet struct {
// Name validates the declared JSON property "name".
Name foundryvalidation.Field[CapturedField, string]
// Values validates the declared JSON property "values".
Values foundryvalidation.Field[CapturedField, []string]
}
CapturedFieldValidationFieldSet retains concrete DTO and value types for validation. Example: CapturedFieldValidationFields()
func CapturedFieldValidationFields ¶
func CapturedFieldValidationFields() CapturedFieldValidationFieldSet
CapturedFieldValidationFields returns typed field descriptors. Example: CapturedFieldValidationFields() Compose rules with these fields; JSON names and selectors are generated.
type CapturedRequest ¶
type CapturedRequest struct {
RequestID attribution.RequestID `json:"request_id"`
ReceivedAt temporal.DateTime `json:"received_at"`
Method string `json:"method"`
// Path is the escaped request path as sent, at most 4 KiB.
Path string `json:"path"`
// Route is the matched route ID; null when no route matched.
Route value.Nullable[string] `json:"route"`
ClientIP value.Nullable[string] `json:"client_ip"`
// Status is the committed response status; null when none was sent.
Status value.Nullable[int32] `json:"status"`
Outcome observability.Outcome `json:"outcome"`
ResponseState CaptureResponseState `json:"response_state"`
DurationMS int64 `json:"duration_ms"`
Mode CaptureMode `json:"mode"`
BodyState CaptureBodyState `json:"body_state"`
// BodyOmission is set exactly when BodyState is omitted.
BodyOmission value.Nullable[CaptureBodyOmission] `json:"body_omission"`
// DeclaredBytes is the request Content-Length; null when absent.
DeclaredBytes value.Nullable[int64] `json:"declared_bytes"`
// MeasuredBytes is the body size, known only after the end of the stream.
MeasuredBytes value.Nullable[int64] `json:"measured_bytes"`
// ObservedBytes counts body bytes read from the client.
ObservedBytes int64 `json:"observed_bytes"`
// DroppedBefore counts captures the writing process lost after its
// previous stored capture and before this one.
DroppedBefore int64 `json:"dropped_before"`
}
CapturedRequest is one list item and the head of a detail. It never carries headers, query values or bodies.
type CapturedRequestDetail ¶
type CapturedRequestDetail struct {
Request CapturedRequest `json:"request"`
Headers []CapturedField `json:"headers"`
Query []CapturedField `json:"query"`
ContentType string `json:"content_type"`
ContentEncoding string `json:"content_encoding"`
Body []byte `json:"body"`
ResponseContentType string `json:"response_content_type"`
ResponseEncoding string `json:"response_encoding"`
ResponseBytes int64 `json:"response_bytes"`
ResponseHead []byte `json:"response_head"`
Omissions []CaptureOmission `json:"omissions"`
}
CapturedRequestDetail is one capture with its stored metadata and bodies. Body and ResponseHead are base64 in JSON. The response head is the first 4 KiB the server accepted for writing; it is not redacted.
type CapturedRequestDetailValidationFieldSet ¶
type CapturedRequestDetailValidationFieldSet struct {
// Body validates the declared JSON property "body".
Body foundryvalidation.Field[CapturedRequestDetail, []byte]
// ContentEncoding validates the declared JSON property "content_encoding".
ContentEncoding foundryvalidation.Field[CapturedRequestDetail, string]
// ContentType validates the declared JSON property "content_type".
ContentType foundryvalidation.Field[CapturedRequestDetail, string]
// Headers validates the declared JSON property "headers".
Headers foundryvalidation.Field[CapturedRequestDetail, []CapturedField]
// Omissions validates the declared JSON property "omissions".
Omissions foundryvalidation.Field[CapturedRequestDetail, []CaptureOmission]
// Query validates the declared JSON property "query".
Query foundryvalidation.Field[CapturedRequestDetail, []CapturedField]
// Request validates the declared JSON property "request".
Request foundryvalidation.Field[CapturedRequestDetail, CapturedRequest]
// ResponseBytes validates the declared JSON property "response_bytes".
ResponseBytes foundryvalidation.Field[CapturedRequestDetail, int64]
// ResponseContentType validates the declared JSON property "response_content_type".
ResponseContentType foundryvalidation.Field[CapturedRequestDetail, string]
// ResponseEncoding validates the declared JSON property "response_encoding".
ResponseEncoding foundryvalidation.Field[CapturedRequestDetail, string]
// ResponseHead validates the declared JSON property "response_head".
ResponseHead foundryvalidation.Field[CapturedRequestDetail, []byte]
}
CapturedRequestDetailValidationFieldSet retains concrete DTO and value types for validation. Example: CapturedRequestDetailValidationFields()
func CapturedRequestDetailValidationFields ¶
func CapturedRequestDetailValidationFields() CapturedRequestDetailValidationFieldSet
CapturedRequestDetailValidationFields returns typed field descriptors. Example: CapturedRequestDetailValidationFields() Compose rules with these fields; JSON names and selectors are generated.
type CapturedRequestFilters ¶
type CapturedRequestFilters struct {
From temporal.DateTime `query:"from"`
Until value.Optional[temporal.DateTime] `query:"until"`
// Method matches the request method exactly.
Method value.Optional[string] `query:"method"`
// PathPrefix matches captures whose escaped path starts with this text.
PathPrefix value.Optional[string] `query:"path_prefix"`
Status value.Optional[int32] `query:"status"`
Mode value.Optional[CaptureMode] `query:"mode"`
}
CapturedRequestFilters narrows the list. From is required and the window spans at most 30 days; Until defaults to no upper bound.
Example: capture.CapturedRequestFilters{From: since, Method: value.Set("POST")}
type CapturedRequestPath ¶
type CapturedRequestPath struct {
Request attribution.RequestID `path:"request"`
}
CapturedRequestPath binds the show route's request ID.
type CapturedRequestValidationFieldSet ¶
type CapturedRequestValidationFieldSet struct {
// BodyOmission validates the declared JSON property "body_omission".
//
// BodyOmission is set exactly when BodyState is omitted.
//
BodyOmission foundryvalidation.Field[CapturedRequest, foundryvalue.Nullable[CaptureBodyOmission]]
// BodyState validates the declared JSON property "body_state".
BodyState foundryvalidation.Field[CapturedRequest, CaptureBodyState]
// ClientIP validates the declared JSON property "client_ip".
ClientIP foundryvalidation.Field[CapturedRequest, foundryvalue.Nullable[string]]
// DeclaredBytes validates the declared JSON property "declared_bytes".
//
// DeclaredBytes is the request Content-Length; null when absent.
//
DeclaredBytes foundryvalidation.Field[CapturedRequest, foundryvalue.Nullable[int64]]
// DroppedBefore validates the declared JSON property "dropped_before".
//
// DroppedBefore counts captures the writing process lost after its
// previous stored capture and before this one.
//
DroppedBefore foundryvalidation.Field[CapturedRequest, int64]
// DurationMS validates the declared JSON property "duration_ms".
DurationMS foundryvalidation.Field[CapturedRequest, int64]
// MeasuredBytes validates the declared JSON property "measured_bytes".
//
// MeasuredBytes is the body size, known only after the end of the stream.
//
MeasuredBytes foundryvalidation.Field[CapturedRequest, foundryvalue.Nullable[int64]]
// Method validates the declared JSON property "method".
Method foundryvalidation.Field[CapturedRequest, string]
// Mode validates the declared JSON property "mode".
Mode foundryvalidation.Field[CapturedRequest, CaptureMode]
// ObservedBytes validates the declared JSON property "observed_bytes".
//
// ObservedBytes counts body bytes read from the client.
//
ObservedBytes foundryvalidation.Field[CapturedRequest, int64]
// Outcome validates the declared JSON property "outcome".
Outcome foundryvalidation.Field[CapturedRequest, observability.Outcome]
// Path validates the declared JSON property "path".
//
// Path is the escaped request path as sent, at most 4 KiB.
//
Path foundryvalidation.Field[CapturedRequest, string]
// ReceivedAt validates the declared JSON property "received_at".
ReceivedAt foundryvalidation.Field[CapturedRequest, temporal.DateTime]
// RequestID validates the declared JSON property "request_id".
RequestID foundryvalidation.Field[CapturedRequest, attribution.RequestID]
// ResponseState validates the declared JSON property "response_state".
ResponseState foundryvalidation.Field[CapturedRequest, CaptureResponseState]
// Route validates the declared JSON property "route".
//
// Route is the matched route ID; null when no route matched.
//
Route foundryvalidation.Field[CapturedRequest, foundryvalue.Nullable[string]]
// Status validates the declared JSON property "status".
//
// Status is the committed response status; null when none was sent.
//
Status foundryvalidation.Field[CapturedRequest, foundryvalue.Nullable[int32]]
}
CapturedRequestValidationFieldSet retains concrete DTO and value types for validation. Example: CapturedRequestValidationFields()
func CapturedRequestValidationFields ¶
func CapturedRequestValidationFields() CapturedRequestValidationFieldSet
CapturedRequestValidationFields returns typed field descriptors. Example: CapturedRequestValidationFields() Compose rules with these fields; JSON names and selectors are generated.
type Config ¶
type Config struct {
// BodyBytes bounds the request body read before the handler (1 KiB to
// 8 MiB). A larger body is omitted; the handler still receives every byte.
BodyBytes int
// ValueBytes bounds a redacted JSON string or form, query or multipart
// field value (64 bytes to 1 MiB); longer values read "[omitted N bytes]".
ValueBytes int
// ForceRedacted stores every prefix redacted, including prefixes declared
// with http.FullCaptureBody.
ForceRedacted bool
// Rate admits at most this many captures per second per process (1 to
// 10,000). Refused requests are served normally and counted as lost.
Rate int
// Burst is the admission burst (1 to 10,000).
Burst int
// QueueRows bounds captures being read, queued or written (1 to 256).
QueueRows int
// RetainedBytes bounds memory held by those captures (enough for one
// capture, up to 1 GiB).
RetainedBytes int64
// Retention deletes captures older than this (1 hour to 365 days).
Retention time.Duration
// MaxRows keeps about this many newest captures in the table (1,000 to
// 10,000,000). Pruning catches up every minute while over the cap.
MaxRows int
}
Config holds deployment limits for one capture store. Settings load it as features.webhook_capture.config.
Example: config := capture.DefaultConfig(); config.Retention = 7 * 24 * time.Hour
func DefaultConfig ¶
func DefaultConfig() Config
DefaultConfig returns a 2 MiB body limit, 4 KiB values, 50 captures per second with a burst of 50, 256 queued captures within 64 MiB, 30-day retention and 100,000 rows.
type Dependencies ¶
type Dependencies struct {
DB *database.DB
// Schema holds foundry_webhook_captures; it must be a valid identifier.
Schema string
// Clock supplies retention cutoffs. Receive times come from the kernel.
Clock clock.Clock
Logger *slog.Logger
}
Dependencies are borrowed; the Store never closes them.
type PruneCommand ¶
type PruneCommand struct {
// contains filtered or unexported fields
}
PruneCommand is a validated prune operation. Without --before it applies the configured retention and row cap; with it, only the explicit cutoff, which must not be later than now. Without --apply it only counts.
func ParsePrune ¶
func ParsePrune(args []string, help io.Writer) (PruneCommand, error)
ParsePrune parses prune arguments without database I/O. It writes help on request and then returns flag.ErrHelp.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store owns the capture table: the single writer that drains the recorder, retention, and the bounded reads behind Routes. Applications hold it to mount Routes; Module drives its lifecycle. Construct it with New.
func New ¶
func New(recorder *httpcapture.Recorder, deps Dependencies, config Config) (*Store, error)
New validates its inputs without I/O. A nil recorder gives a store that reads and prunes but never writes, as when capture is disabled at runtime.
Example: capture.New(recorder, capture.Dependencies{DB: db, Schema: "public", Clock: clock.System{}, Logger: logger}, capture.DefaultConfig())
func (*Store) Close ¶
Close stops admission, writes what remains within a short drain budget and counts the rest as lost. It runs after the HTTP kernel has drained.
Source Files
¶
- capture_body_omission_foundry.gen.go
- capture_body_state_foundry.gen.go
- capture_mode_foundry.gen.go
- capture_omission_foundry.gen.go
- capture_response_state_foundry.gen.go
- captured_field_foundry.gen.go
- captured_request_detail_foundry.gen.go
- captured_request_filters_foundry.gen.go
- captured_request_foundry.gen.go
- captured_request_path_foundry.gen.go
- command.go
- config.go
- migrations.go
- module.go
- read.go
- redact.go
- retention.go
- routes.go
- store.go
- types.go