output

package
v0.4.7 Latest Latest
Warning

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

Go to latest
Published: Nov 9, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package output provides JSONL output for crawl results.

Output is structured as typed record envelopes containing objects, errors, and progress updates. Each line is a self-contained JSON object that can be parsed independently.

Index

Constants

View Source
const (
	// TypeObject identifies object listing records.
	TypeObject = "gonimbus.object.v1"

	// TypeError identifies error records.
	TypeError = "gonimbus.error.v1"

	// TypeProgress identifies progress update records.
	TypeProgress = "gonimbus.progress.v1"

	// TypeSummary identifies final summary records.
	TypeSummary = "gonimbus.summary.v1"

	// TypePreflight identifies preflight capability check records.
	TypePreflight = "gonimbus.preflight.v1"

	// TypeTransfer identifies per-object transfer results.
	TypeTransfer = "gonimbus.transfer.v1"

	// TypeSkip identifies per-object skips (dedup/on_exists).
	TypeSkip = "gonimbus.skip.v1"

	// TypePrefix identifies prefix summary records.
	TypePrefix = "gonimbus.prefix.v1"
)

Record type constants define the envelope types for JSONL output. These follow the pattern: gonimbus.<type>.v<version>

View Source
const (
	// ErrCodeAccessDenied indicates permission failure.
	ErrCodeAccessDenied = "ACCESS_DENIED"

	// ErrCodeNotFound indicates the object or bucket was not found.
	ErrCodeNotFound = "NOT_FOUND"

	// ErrCodeTimeout indicates an operation timed out.
	ErrCodeTimeout = "TIMEOUT"

	// ErrCodeThrottled indicates rate limiting.
	ErrCodeThrottled = "THROTTLED"

	// ErrCodeInternal indicates an unexpected internal error.
	ErrCodeInternal = "INTERNAL"

	// ErrCodeProviderUnavailable indicates provider or network availability issues.
	ErrCodeProviderUnavailable = "PROVIDER_UNAVAILABLE"

	// ErrCodeTransient indicates a temporary network or transport failure.
	ErrCodeTransient = "TRANSIENT"

	// ErrCodeAlreadyExists indicates a write was refused because the target exists.
	ErrCodeAlreadyExists = "ALREADY_EXISTS"

	// ErrCodeInvalidInput indicates malformed or unsupported input data.
	ErrCodeInvalidInput = "INVALID_INPUT"
)

Error codes for ErrorRecord.

View Source
const (
	// PhaseStarting indicates the crawl is initializing.
	PhaseStarting = "starting"

	// PhaseListing indicates objects are being listed.
	PhaseListing = "listing"

	// PhaseEnriching indicates metadata enrichment is in progress.
	PhaseEnriching = "enriching"

	// PhaseComplete indicates the crawl has finished.
	PhaseComplete = "complete"
)

Progress phase constants.

Variables

View Source
var (
	// ErrWriterClosed is returned when writing to a closed writer.
	ErrWriterClosed = errors.New("writer is closed")
)

Writer errors.

Functions

func IsAdvisoryProducerRecordType

func IsAdvisoryProducerRecordType(recordType string) bool

IsAdvisoryProducerRecordType reports whether a producer is permitted to mark envelopes of recordType with Advisory=true.

Only non-authoritative control/summary records that carry neither work items, admission/completeness gates, nor upstream error signals may be marked advisory. Work records (gonimbus.reflow.input.*, gonimbus.index.object.*), admission/integrity records (gonimbus.crawl.selection_summary.*, gonimbus.index.query_receipt.*), per-object probe records (gonimbus.content.probe.v1), and error records (gonimbus.error.*) must never be marked advisory.

Types

type ErrorRecord

type ErrorRecord struct {
	// Code is a machine-readable error code.
	Code string `json:"code"`

	// Message is a human-readable error description.
	Message string `json:"message"`

	// Key is the object key related to this error, if applicable.
	Key string `json:"key,omitempty"`

	// Prefix is the prefix being listed when the error occurred.
	Prefix string `json:"prefix,omitempty"`

	// Details contains additional error context.
	Details any `json:"details,omitempty"`

	// Collision contains reflow collision context when an error is caused by a
	// destination collision.
	Collision any `json:"collision,omitempty"`
}

ErrorRecord is the data payload for errors.

Errors are emitted as records rather than failing the entire crawl, allowing partial results when some operations fail.

type JSONLWriter

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

JSONLWriter writes records as newline-delimited JSON to an io.Writer.

JSONLWriter is safe for concurrent use. Writes are serialized using a mutex to ensure atomic line writes (no interleaved output).

func NewJSONLWriter

func NewJSONLWriter(w io.Writer, jobID, provider string) *JSONLWriter

NewJSONLWriter creates a new JSONL writer.

Parameters:

  • w: The underlying writer (stdout, file, etc.)
  • jobID: Correlation ID for this crawl job
  • provider: Storage provider identifier (e.g., "s3")

func (*JSONLWriter) Close

func (jw *JSONLWriter) Close() error

Close marks the writer as closed.

If the underlying writer implements io.Closer, it is NOT closed. The caller is responsible for closing the underlying writer.

func (*JSONLWriter) WriteAdvisoryAny

func (jw *JSONLWriter) WriteAdvisoryAny(ctx context.Context, recordType string, data any) error

WriteAdvisoryAny emits a JSONL record with top-level advisory=true for record types classified as advisory producer records by IsAdvisoryProducerRecordType. Attempting to mark a non-advisory record type returns a WriteError and writes nothing.

func (*JSONLWriter) WriteAny

func (jw *JSONLWriter) WriteAny(ctx context.Context, recordType string, data any) error

WriteAny emits a JSONL record with a custom type.

This is intended for CLI commands that emit typed records not covered by the Writer interface (e.g. probing/inspection records).

func (*JSONLWriter) WriteError

func (jw *JSONLWriter) WriteError(ctx context.Context, err *ErrorRecord) error

WriteError emits an error record.

func (*JSONLWriter) WriteObject

func (jw *JSONLWriter) WriteObject(ctx context.Context, obj *ObjectRecord) error

WriteObject emits an object record.

func (*JSONLWriter) WritePrefix

func (jw *JSONLWriter) WritePrefix(ctx context.Context, prefix *PrefixRecord) error

func (*JSONLWriter) WritePreflight

func (jw *JSONLWriter) WritePreflight(ctx context.Context, preflight *PreflightRecord) error

WritePreflight emits a preflight record.

func (*JSONLWriter) WriteProgress

func (jw *JSONLWriter) WriteProgress(ctx context.Context, prog *ProgressRecord) error

WriteProgress emits a progress record.

func (*JSONLWriter) WriteSkip

func (jw *JSONLWriter) WriteSkip(ctx context.Context, skip *SkipRecord) error

func (*JSONLWriter) WriteSummary

func (jw *JSONLWriter) WriteSummary(ctx context.Context, sum *SummaryRecord) error

WriteSummary emits a summary record.

func (*JSONLWriter) WriteTransfer

func (jw *JSONLWriter) WriteTransfer(ctx context.Context, transfer *TransferRecord) error

type ObjectRecord

type ObjectRecord struct {
	// Key is the full object key (path) in the bucket.
	Key string `json:"key"`

	// Size is the object size in bytes.
	Size int64 `json:"size"`

	// ETag is the entity tag, typically an MD5 hash of the object.
	ETag string `json:"etag"`

	// LastModified is when the object was last modified.
	LastModified time.Time `json:"last_modified"`

	// StorageClass is the provider-native storage class when supplied.
	StorageClass string `json:"storage_class,omitempty"`

	// ContentType is the MIME type of the object.
	// Only populated if metadata enrichment is enabled.
	ContentType string `json:"content_type,omitempty"`

	// Metadata contains user-defined metadata key-value pairs.
	// Only populated if metadata enrichment is enabled.
	Metadata map[string]string `json:"metadata,omitempty"`
}

ObjectRecord is the data payload for object listings.

This contains the metadata for a single object that matched the crawl patterns.

type PrefixRecord

type PrefixRecord struct {
	Prefix    string `json:"prefix"`
	Delimiter string `json:"delimiter"`

	// Depth indicates the traversal depth of this prefix relative to the root.
	// Wave 1 emits a single record at depth=0.
	Depth int `json:"depth,omitempty"`

	ObjectsDirect  int64 `json:"objects_direct"`
	BytesDirect    int64 `json:"bytes_direct"`
	CommonPrefixes int64 `json:"common_prefixes"`
	Pages          int64 `json:"pages"`
	Truncated      bool  `json:"truncated"`

	TruncatedReason string `json:"truncated_reason,omitempty"`
}

PrefixRecord is the data payload for prefix summaries.

Prefix records are emitted by directory-like commands (tree/du). The fields are intended to be stable across providers.

type PreflightCheckResult

type PreflightCheckResult struct {
	Capability string `json:"capability"`
	Allowed    bool   `json:"allowed"`
	Method     string `json:"method,omitempty"`
	ErrorCode  string `json:"error_code,omitempty"`
	Detail     string `json:"detail,omitempty"`
}

PreflightCheckResult is a single capability check result.

type PreflightRecord

type PreflightRecord struct {
	Mode          string                 `json:"mode"`
	ProbeStrategy string                 `json:"probe_strategy,omitempty"`
	ProbePrefix   string                 `json:"probe_prefix,omitempty"`
	Results       []PreflightCheckResult `json:"results"`
}

PreflightRecord is the data payload for preflight capability checks.

Preflight records are emitted early, before long-running operations. They provide an explicit contract for what was checked and whether the principal appears to have the required permissions.

type ProgressRecord

type ProgressRecord struct {
	// Phase indicates the current crawl phase.
	Phase string `json:"phase"`

	// ObjectsFound is the total number of objects seen so far.
	ObjectsFound int64 `json:"objects_found"`

	// ObjectsMatched is the number of objects matching patterns.
	ObjectsMatched int64 `json:"objects_matched"`

	// BytesTotal is the cumulative size of matched objects in bytes.
	BytesTotal int64 `json:"bytes_total"`

	// Prefix is the current prefix being listed, if applicable.
	Prefix string `json:"prefix,omitempty"`
}

ProgressRecord is the data payload for progress updates.

Progress records are emitted periodically during crawls to provide visibility into long-running operations.

type Record

type Record struct {
	// Type identifies the record type (e.g., "gonimbus.object.v1").
	Type string `json:"type"`

	// TS is the timestamp when the record was created (RFC3339Nano).
	TS time.Time `json:"ts"`

	// JobID is the correlation ID for this crawl job.
	JobID string `json:"job_id"`

	// Provider identifies the storage provider (e.g., "s3", "gcs").
	Provider string `json:"provider"`

	// Advisory marks a non-work, non-integrity control/summary envelope that
	// a consumer without a registered handler for Type may skip with a bounded
	// warning. Known record types and recognized work/integrity/error families
	// are always validated or refused regardless of this marker.
	Advisory bool `json:"advisory,omitempty"`

	// Data contains the type-specific payload as raw JSON.
	Data json.RawMessage `json:"data"`
}

Record is the envelope for all JSONL output.

Each line of JSONL output contains a Record with a type-specific payload in the Data field. The type field determines how to interpret the Data payload.

type SkipRecord

type SkipRecord struct {
	SourceKey string `json:"source_key"`
	TargetKey string `json:"target_key"`
	Reason    string `json:"reason"`
}

SkipRecord is the data payload for skipped objects.

type SummaryRecord

type SummaryRecord struct {
	// ObjectsFound is the total number of objects seen.
	ObjectsFound int64 `json:"objects_found"`

	// ObjectsMatched is the number of objects matching patterns.
	ObjectsMatched int64 `json:"objects_matched"`

	// BytesTotal is the cumulative size of matched objects in bytes.
	BytesTotal int64 `json:"bytes_total"`

	// Duration is the total crawl duration.
	Duration time.Duration `json:"duration_ns"`

	// DurationHuman is a human-readable duration string.
	DurationHuman string `json:"duration"`

	// Errors is the count of errors encountered.
	Errors int64 `json:"errors"`

	// Prefixes lists the prefixes that were crawled.
	Prefixes []string `json:"prefixes,omitempty"`
}

SummaryRecord is the data payload for final summaries.

A summary record is emitted at the end of a crawl with aggregate statistics.

type TransferRecord

type TransferRecord struct {
	SourceKey string `json:"source_key"`
	TargetKey string `json:"target_key"`
	Bytes     int64  `json:"bytes"`
}

TransferRecord is the data payload for a successful transfer.

type WriteError

type WriteError struct {
	Op  string // Operation that failed (e.g., "marshal_data", "write")
	Err error  // Underlying error
}

WriteError wraps errors that occur during write operations.

func (*WriteError) Error

func (e *WriteError) Error() string

func (*WriteError) Unwrap

func (e *WriteError) Unwrap() error

type Writer

type Writer interface {
	// WriteObject emits an object record.
	WriteObject(ctx context.Context, obj *ObjectRecord) error

	// WriteError emits an error record.
	WriteError(ctx context.Context, err *ErrorRecord) error

	// WriteProgress emits a progress record.
	WriteProgress(ctx context.Context, prog *ProgressRecord) error

	// WriteSummary emits a summary record.
	WriteSummary(ctx context.Context, sum *SummaryRecord) error

	// WritePrefix emits a prefix summary record.
	WritePrefix(ctx context.Context, prefix *PrefixRecord) error

	// WritePreflight emits a preflight record.
	WritePreflight(ctx context.Context, preflight *PreflightRecord) error

	// WriteTransfer emits a transfer record.
	WriteTransfer(ctx context.Context, transfer *TransferRecord) error

	// WriteSkip emits a skip record.
	WriteSkip(ctx context.Context, skip *SkipRecord) error

	// Close flushes any buffered output and releases resources.
	Close() error
}

Writer outputs JSONL records for crawl results.

Implementations must be safe for concurrent use from multiple goroutines. Each Write* method emits a complete record as a single line of JSON followed by a newline.

Jump to

Keyboard shortcuts

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