> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tell.rs/llms.txt
> Use this file to discover all available pages before exploring further.

# File Source

> Import data from files — raw lines, structured JSON, or binary re-imports.

Read events, logs, or raw lines from a file and push them into Tell's pipeline. Use this for one-time imports, replaying exported data, or ingesting log files from disk.

```toml theme={null}
[sources.file]
path = "/var/log/app.log"
mode = "lines"
```

Tell reads the file line by line, batches the content, and routes it through the pipeline like any other source.

## Read modes

The file source supports three modes, each producing different batch types:

| Mode     | Output               | Use case                                                                    |
| -------- | -------------------- | --------------------------------------------------------------------------- |
| `lines`  | Syslog batches       | Raw log files, one line per message                                         |
| `jsonl`  | Log or Event batches | Structured JSON — one JSON object per line                                  |
| `binary` | Original batches     | Re-import data previously exported by the [disk sink](/pipeline/sinks/disk) |

## Lines mode

Each line becomes a syslog message. Empty lines are skipped.

```toml theme={null}
[sources.file]
path = "/var/log/nginx/access.log"
mode = "lines"
one_shot = true
```

This reads the entire file, batches every 500 lines, and exits. Use [transforms](/pipeline/transforms/overview) downstream to parse structured fields from raw lines.

## JSONL mode

Parse each line as a JSON object and produce typed batches. Set `format` to control the schema:

### Log format

```toml theme={null}
[sources.file]
path = "logs.jsonl"
mode = "jsonl"
format = "log"
service = "api"
```

Each line is a JSON log entry:

```json theme={null}
{"level": "error", "message": "connection refused", "service": "api", "timestamp": 1718467200000}
{"level": "info", "message": "request completed", "data": {"status": 200, "duration_ms": 42}}
```

| Field        | Type    | Required | Description                                         |
| ------------ | ------- | -------- | --------------------------------------------------- |
| `message`    | string  | Yes      | Log message text.                                   |
| `level`      | string  | No       | `debug`, `info`, `warn`, `error`. Default: `info`.  |
| `timestamp`  | integer | No       | Unix milliseconds. Default: current time.           |
| `source`     | string  | No       | Source location (e.g., `app.js:42`).                |
| `service`    | string  | No       | Service name. Falls back to config `service` value. |
| `session_id` | string  | No       | Session UUID.                                       |
| `type`       | string  | No       | Log type. Default: `log`.                           |
| `data`       | object  | No       | Additional properties merged into the payload.      |

### Event format

```toml theme={null}
[sources.file]
path = "events.jsonl"
mode = "jsonl"
format = "event"
```

Each line is a JSON event:

```json theme={null}
{"type": "page_view", "device_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "properties.page": "/pricing"}
{"type": "purchase", "device_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "properties.amount": 99}
```

| Field        | Type    | Required | Description                               |
| ------------ | ------- | -------- | ----------------------------------------- |
| `type`       | string  | Yes      | Event type.                               |
| `device_id`  | string  | Yes      | Device UUID.                              |
| `event`      | string  | No       | Event name.                               |
| `session_id` | string  | No       | Session UUID.                             |
| `user_id`    | string  | No       | User identifier.                          |
| `group_id`   | string  | No       | Group identifier.                         |
| `timestamp`  | integer | No       | Unix milliseconds. Default: current time. |
| `service`    | string  | No       | Service name.                             |

Additional fields are flattened into event properties.

Parse errors in JSONL mode are logged and skipped — a malformed line won't stop the import.

## Binary mode

Re-import data previously exported by the [disk sink](/pipeline/sinks/disk). Tell reconstructs the original batches with their metadata, including source IPs.

```toml theme={null}
[sources.file]
path = "/data/tell/export/2025-06-15.bin"
mode = "binary"
```

This is useful for replaying historical data or migrating between Tell instances.

## One-shot vs continuous

By default, the file source reads the file once and exits (`one_shot = true`). Set `one_shot = false` to keep the source running after reading:

```toml theme={null}
[sources.file]
path = "test-data.jsonl"
mode = "jsonl"
format = "event"
one_shot = false
```

## Configuration reference

```toml theme={null}
[sources.file]
path = ""                # File path to read (required)
mode = "lines"           # "lines", "jsonl", or "binary"
format = "log"           # "log" or "event" (JSONL mode only)
workspace_id = "1"       # Workspace ID for routing
service = ""             # Service name for log enrichment
batch_size = 500         # Items per batch
one_shot = true          # Exit after reading the file
```

<Note>
  The file source requires the `source-file` feature flag at build time.
</Note>

## What's next

* [Routing](/pipeline/routing) — control where file data goes after ingestion
* [Transforms](/pipeline/transforms/overview) — parse and enrich raw lines before storage
* [Disk sink](/pipeline/sinks/disk) — export data that binary mode can re-import
