Connectors / Files & object stores
Local files
sinkLocal file sink; JSONL/JSON/CSV/XML/Excel/Avro/Parquet by extension, rollover, atomic temp+rename, atomic overwrite
Install
cargo install faucet-cli --features sink-file faucet init --sink file
# Cargo.toml — use it as a library cargo add faucet-sink-file
Starter config
sink:
type: file
config:
path: "" # REQUIRED — The file to write, as a template.
# format: null # Which format a file is in: resolved from its extension (`auto`) or fixed.
# compression: null # User-facing compression config.
# if_exists: null # What happens when a file this run writes already exists (`if_exists`).
# write_mode: null # Pipeline-level write mode (`write_mode`).
# max_records_per_file: 0 # Roll to a new file after this many records.
# max_bytes_per_file: 0 # Roll to a new file once the current one reaches about this many bytes, counted on the records' JSON length before compression (on the columnar Parquet path, their in-memory Arrow size).
# create_dirs: true # Create missing parent directories (default `true`).
# batch_size: 1000 # Records per upstream page.
# csv: { ... } # CSV dialect.
# excel: { ... } # Excel worksheet selection.
# xml: { ... } # XML record framing.
# avro: { ... } # Avro read/write options.
# parquet: { ... } # Parquet write options.
# json_lines: { ... } # JSON Lines write options.
# encryption: null # Encrypt the output at rest (AES-256-GCM).
Capabilities
| Delivery | At-least-once |
|---|---|
| Write modes | append, overwrite |
| Exactly-once writes | No |
| Schema evolution | No |
| Scoped cleanup | No |
| Staged bulk load | No |
| Run rollback | No |
| Compression | Yes |
Config fields
| Field | Type | Default | Description |
|---|---|---|---|
pathrequired | string | — | The file to write, as a template. {part} is replaced by the rollover part number (00001, 00002, …); with a rollover cap and no {part}, -{part} is inserted before the extension. A path ending in / is a directory: files are named part-{part} plus the format's extension, so format must be set. ${now.*} tokens are resolved by the CLI before the sink sees the path. |
format | object | auto | File format: auto (default) resolves from the path's extension, looking through a compression suffix (.csv.gz is CSV). ORC is read-only and refused. |
compression | string | object | auto | Compression of the finished file: auto (default) resolves from the suffix (.gz, .zst). It applies to every format; Parquet, Avro and Excel already compress internally, so a codec on them compresses the file a second time and most readers then cannot open it without decompressing first. |
if_exists | object | replace | What to do with a file that already exists (default replace): replace it, append to it (JSON Lines, CSV, raw text), or fail with error. mode is accepted as another name for this field, and overwrite / error_if_exists for its values. |
write_mode | object | append | append (default) or overwrite — replace the destination's whole output set when the run succeeds. |
max_records_per_file | integer | — | Roll to a new file after this many records. max_rows_per_file is a deprecated name for it. |
max_bytes_per_file | integer | — | Roll to a new file once the current one reaches about this many bytes, counted on the records' JSON length before compression (on the columnar Parquet path, their in-memory Arrow size). A single page larger than the cap still lands in one file. |
create_dirs | boolean | true | Create missing parent directories (default true). |
batch_size | integer | 1000 | Records per upstream page. Informational: the sink writes each page it is handed. Defaults to DEFAULT_BATCH_SIZE. |
csv | object | delimiter: ","has_headers: truequote: "on_unknown_field: widen | CSV dialect, used when the format is CSV. |
excel | object | header_row: 0 | Worksheet name, used when the format is Excel. |
xml | object | record_element: recordroot_element: records | Record framing, used when the format is XML. |
avro | object | codec: null | Writer schema and block codec, used when the format is Avro. |
parquet | object | row_group_size: 1048576 | Compression (default snappy), row groups and an optional explicit schema, used when the format is Parquet. |
json_lines | object | pretty: false | Pretty-printing, used when the format is JSON Lines. |
encryption | object | — | Encrypt the output at rest (AES-256-GCM). Uncompressed JSON Lines and raw text seal each record on its own line (base64), exactly as the jsonl sink does, so the file stays appendable. Every other file — compressed JSON Lines included — is sealed whole when it is published, after any compression; appending to one decrypts it first. Appending to an existing file that is not sealed the same way is refused. The file source's encryption block reads both back. Scratch files are not encrypted while the run is in progress; those holding plaintext are readable by their owner only. |
Get started
Your first pipeline runs in five minutes.
Install the CLI, scaffold a config, and move real data — nothing external to stand up.
curl -LsSf https://github.com/faucet-hq/faucet-stream/releases/latest/download/faucet-cli-installer.sh | sh brew install faucet-hq/faucet-stream/faucet-cli