mirror of
https://github.com/aykhans/sarin.git
synced 2026-08-28 02:54:32 +00:00
docs: document logging and progress config, drop quiet
This commit is contained in:
+58
-37
@@ -26,7 +26,9 @@ Use `-s` or `--show-config` to see the final merged configuration before sending
|
|||||||
| [Concurrency](#concurrency) | `concurrency`<br>(number) | `-concurrency` / `-c`<br>(number) | `SARIN_CONCURRENCY`<br>(number) | `1` | Number of concurrent workers |
|
| [Concurrency](#concurrency) | `concurrency`<br>(number) | `-concurrency` / `-c`<br>(number) | `SARIN_CONCURRENCY`<br>(number) | `1` | Number of concurrent workers |
|
||||||
| [Requests](#requests) | `requests`<br>(number) | `-requests` / `-r`<br>(number) | `SARIN_REQUESTS`<br>(number) | - | Total requests to send |
|
| [Requests](#requests) | `requests`<br>(number) | `-requests` / `-r`<br>(number) | `SARIN_REQUESTS`<br>(number) | - | Total requests to send |
|
||||||
| [Duration](#duration) | `duration`<br>(duration) | `-duration` / `-d`<br>(duration) | `SARIN_DURATION`<br>(duration) | - | Test duration |
|
| [Duration](#duration) | `duration`<br>(duration) | `-duration` / `-d`<br>(duration) | `SARIN_DURATION`<br>(duration) | - | Test duration |
|
||||||
| [Quiet](#quiet) | `quiet`<br>(boolean) | `-quiet` / `-q`<br>(boolean) | `SARIN_QUIET`<br>(boolean) | `false` | Hide progress bar and logs |
|
| [Log Level](#log-level) | `logLevel`<br>(string) | `-log-level` / `-l`<br>(string) | `SARIN_LOG_LEVEL`<br>(string) | `error` | Runtime log levels to emit |
|
||||||
|
| [Log File](#log-file) | `logFile`<br>(string) | `-log-file` / `-w`<br>(string) | `SARIN_LOG_FILE`<br>(string) | - | Write runtime logs to a file |
|
||||||
|
| [Progress](#progress) | `progress`<br>(string) | `-progress` / `-p`<br>(string) | `SARIN_PROGRESS`<br>(string) | `bar` | Progress display (bar/none) |
|
||||||
| [Output](#output) | `output`<br>(string) | `-output` / `-o`<br>(string) | `SARIN_OUTPUT`<br>(string) | `table` | Output format for stats |
|
| [Output](#output) | `output`<br>(string) | `-output` / `-o`<br>(string) | `SARIN_OUTPUT`<br>(string) | `table` | Output format for stats |
|
||||||
| [Dry Run](#dry-run) | `dryRun`<br>(boolean) | `-dry-run` / `-z`<br>(boolean) | `SARIN_DRY_RUN`<br>(boolean) | `false` | Generate without sending |
|
| [Dry Run](#dry-run) | `dryRun`<br>(boolean) | `-dry-run` / `-z`<br>(boolean) | `SARIN_DRY_RUN`<br>(boolean) | `false` | Generate without sending |
|
||||||
| [Insecure](#insecure) | `insecure`<br>(boolean) | `-insecure` / `-I`<br>(boolean) | `SARIN_INSECURE`<br>(boolean) | `false` | Skip TLS verification |
|
| [Insecure](#insecure) | `insecure`<br>(boolean) | `-insecure` / `-I`<br>(boolean) | `SARIN_INSECURE`<br>(boolean) | `false` | Skip TLS verification |
|
||||||
@@ -131,7 +133,7 @@ sarin -U "http://example.com/users/{{ fakeit_UUID }}" -r 1000 -c 10
|
|||||||
|
|
||||||
## Method
|
## Method
|
||||||
|
|
||||||
HTTP method(s). If multiple values are provided, Sarin starts at a random index and cycles through them in order. Once the cycle completes, it picks a new random starting point. Supports [templating](templating.md).
|
HTTP method(s). Defaults to `GET`. If multiple values are provided, Sarin starts at a random index and cycles through them in order. Once the cycle completes, it picks a new random starting point. Supports [templating](templating.md).
|
||||||
|
|
||||||
**YAML example:**
|
**YAML example:**
|
||||||
|
|
||||||
@@ -141,9 +143,9 @@ method: GET
|
|||||||
# OR
|
# OR
|
||||||
|
|
||||||
method:
|
method:
|
||||||
- GET
|
- GET
|
||||||
- POST
|
- POST
|
||||||
- PUT
|
- PUT
|
||||||
```
|
```
|
||||||
|
|
||||||
**CLI example:**
|
**CLI example:**
|
||||||
@@ -160,7 +162,7 @@ SARIN_METHOD=GET
|
|||||||
|
|
||||||
## Timeout
|
## Timeout
|
||||||
|
|
||||||
Request timeout. Must be greater than 0.
|
Request timeout. Must be greater than 0. Defaults to `10s`.
|
||||||
|
|
||||||
Valid time units: `ns`, `us` (or `µs`), `ms`, `s`, `m`, `h`
|
Valid time units: `ns`, `us` (or `µs`), `ms`, `s`, `m`, `h`
|
||||||
|
|
||||||
@@ -168,7 +170,7 @@ Valid time units: `ns`, `us` (or `µs`), `ms`, `s`, `m`, `h`
|
|||||||
|
|
||||||
## Concurrency
|
## Concurrency
|
||||||
|
|
||||||
Number of concurrent workers. Must be between 1 and 100,000,000.
|
Number of concurrent workers. Must be between 1 and 100,000,000. Defaults to `1`.
|
||||||
|
|
||||||
## Requests
|
## Requests
|
||||||
|
|
||||||
@@ -182,15 +184,34 @@ Valid time units: `ns`, `us` (or `µs`), `ms`, `s`, `m`, `h`
|
|||||||
|
|
||||||
**Examples:** `1m30s`, `25s`, `1h`
|
**Examples:** `1m30s`, `25s`, `1h`
|
||||||
|
|
||||||
## Quiet
|
## Log Level
|
||||||
|
|
||||||
Hide the progress bar and runtime logs.
|
Runtime log levels to emit, comma-separated. Valid levels: `info`, `error`. Defaults to `error`.
|
||||||
|
|
||||||
|
- `error`: errors that occur while generating or sending a request
|
||||||
|
- `info`: every completed response
|
||||||
|
|
||||||
|
Leave empty to disable logging entirely.
|
||||||
|
|
||||||
|
**Examples:** `error` (only errors), `info` (only responses), `info,error` (both)
|
||||||
|
|
||||||
|
## Log File
|
||||||
|
|
||||||
|
Write runtime logs to this file instead of the terminal or stderr. The parent directory must exist.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sarin -U http://example.com -r 1000 --log-file ./run.log
|
||||||
|
```
|
||||||
|
|
||||||
|
## Progress
|
||||||
|
|
||||||
|
Progress display. Valid values: `bar` (default), `none`. Use `none` to hide the progress bar.
|
||||||
|
|
||||||
## Output
|
## Output
|
||||||
|
|
||||||
Output format for response statistics.
|
Output format for response statistics.
|
||||||
|
|
||||||
Valid formats: `table`, `json`, `yaml`, `none`
|
Valid formats: `table` (default), `json`, `yaml`, `none`
|
||||||
|
|
||||||
Using `none` disables output and reduces memory usage since response statistics are not stored.
|
Using `none` disables output and reduces memory usage since response statistics are not stored.
|
||||||
|
|
||||||
@@ -214,9 +235,9 @@ body: '{"product": "car"}'
|
|||||||
# OR
|
# OR
|
||||||
|
|
||||||
body:
|
body:
|
||||||
- '{"product": "car"}'
|
- '{"product": "car"}'
|
||||||
- '{"product": "phone"}'
|
- '{"product": "phone"}'
|
||||||
- '{"product": "watch"}'
|
- '{"product": "watch"}'
|
||||||
```
|
```
|
||||||
|
|
||||||
**CLI example:**
|
**CLI example:**
|
||||||
@@ -241,19 +262,19 @@ When the same key appears as **separate entries** (in CLI or config file), all v
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
params:
|
params:
|
||||||
key1: value1
|
key1: value1
|
||||||
key2: [value2, value3] # cycles between value2 and value3
|
key2: [value2, value3] # cycles between value2 and value3
|
||||||
|
|
||||||
# OR
|
# OR
|
||||||
|
|
||||||
params:
|
params:
|
||||||
- key1: value1
|
- key1: value1
|
||||||
- key2: [value2, value3] # cycles between value2 and value3
|
- key2: [value2, value3] # cycles between value2 and value3
|
||||||
|
|
||||||
# To send both values in every request, use separate entries:
|
# To send both values in every request, use separate entries:
|
||||||
params:
|
params:
|
||||||
- key2: value2
|
- key2: value2
|
||||||
- key2: value3 # both sent in every request
|
- key2: value3 # both sent in every request
|
||||||
```
|
```
|
||||||
|
|
||||||
**CLI example:**
|
**CLI example:**
|
||||||
@@ -278,19 +299,19 @@ When the same key appears as **separate entries** (in CLI or config file), all v
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
headers:
|
headers:
|
||||||
key1: value1
|
key1: value1
|
||||||
key2: [value2, value3] # cycles between value2 and value3
|
key2: [value2, value3] # cycles between value2 and value3
|
||||||
|
|
||||||
# OR
|
# OR
|
||||||
|
|
||||||
headers:
|
headers:
|
||||||
- key1: value1
|
- key1: value1
|
||||||
- key2: [value2, value3] # cycles between value2 and value3
|
- key2: [value2, value3] # cycles between value2 and value3
|
||||||
|
|
||||||
# To send both values in every request, use separate entries:
|
# To send both values in every request, use separate entries:
|
||||||
headers:
|
headers:
|
||||||
- key2: value2
|
- key2: value2
|
||||||
- key2: value3 # both sent in every request
|
- key2: value3 # both sent in every request
|
||||||
```
|
```
|
||||||
|
|
||||||
**CLI example:**
|
**CLI example:**
|
||||||
@@ -315,19 +336,19 @@ When the same key appears as **separate entries** (in CLI or config file), all v
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
cookies:
|
cookies:
|
||||||
key1: value1
|
key1: value1
|
||||||
key2: [value2, value3] # cycles between value2 and value3
|
key2: [value2, value3] # cycles between value2 and value3
|
||||||
|
|
||||||
# OR
|
# OR
|
||||||
|
|
||||||
cookies:
|
cookies:
|
||||||
- key1: value1
|
- key1: value1
|
||||||
- key2: [value2, value3] # cycles between value2 and value3
|
- key2: [value2, value3] # cycles between value2 and value3
|
||||||
|
|
||||||
# To send both values in every request, use separate entries:
|
# To send both values in every request, use separate entries:
|
||||||
cookies:
|
cookies:
|
||||||
- key2: value2
|
- key2: value2
|
||||||
- key2: value3 # both sent in every request
|
- key2: value3 # both sent in every request
|
||||||
```
|
```
|
||||||
|
|
||||||
**CLI example:**
|
**CLI example:**
|
||||||
@@ -356,9 +377,9 @@ proxy: http://proxy1.com
|
|||||||
# OR
|
# OR
|
||||||
|
|
||||||
proxy:
|
proxy:
|
||||||
- http://proxy1.com
|
- http://proxy1.com
|
||||||
- socks5://proxy2.com
|
- socks5://proxy2.com
|
||||||
- socks5h://proxy3.com
|
- socks5h://proxy3.com
|
||||||
```
|
```
|
||||||
|
|
||||||
**CLI example:**
|
**CLI example:**
|
||||||
@@ -387,9 +408,9 @@ values: "key=value"
|
|||||||
# OR
|
# OR
|
||||||
|
|
||||||
values: |
|
values: |
|
||||||
key1=value1
|
key1=value1
|
||||||
key2=value2
|
key2=value2
|
||||||
key3=value3
|
key3=value3
|
||||||
```
|
```
|
||||||
|
|
||||||
**CLI example:**
|
**CLI example:**
|
||||||
|
|||||||
+39
-3
@@ -13,6 +13,7 @@ This guide provides practical examples for common Sarin use cases.
|
|||||||
- [File Uploads](#file-uploads)
|
- [File Uploads](#file-uploads)
|
||||||
- [Using Proxies](#using-proxies)
|
- [Using Proxies](#using-proxies)
|
||||||
- [Output Formats](#output-formats)
|
- [Output Formats](#output-formats)
|
||||||
|
- [Runtime Logging](#runtime-logging)
|
||||||
- [Docker Usage](#docker-usage)
|
- [Docker Usage](#docker-usage)
|
||||||
- [Dry Run Mode](#dry-run-mode)
|
- [Dry Run Mode](#dry-run-mode)
|
||||||
- [Show Configuration](#show-configuration)
|
- [Show Configuration](#show-configuration)
|
||||||
@@ -836,10 +837,10 @@ output: none
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
**Quiet mode (hide progress bar):**
|
**Hide the progress bar:**
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sarin -U http://example.com -r 1000 -c 10 -q
|
sarin -U http://example.com -r 1000 -c 10 -p none
|
||||||
```
|
```
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
@@ -849,7 +850,42 @@ sarin -U http://example.com -r 1000 -c 10 -q
|
|||||||
url: http://example.com
|
url: http://example.com
|
||||||
requests: 1000
|
requests: 1000
|
||||||
concurrency: 10
|
concurrency: 10
|
||||||
quiet: true
|
progress: none
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
## Runtime Logging
|
||||||
|
|
||||||
|
`--log-level` selects which runtime logs Sarin emits (comma-separated `info` and `error`, default `error`). `error` covers request and generation errors, `info` covers every completed response (status, duration, headers, body). Logs appear in the progress log box on an interactive terminal, go to stderr when piped, or go to a file with `--log-file`.
|
||||||
|
|
||||||
|
**Log responses and errors:**
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sarin -U http://example.com -r 1000 -c 10 -l info,error
|
||||||
|
```
|
||||||
|
|
||||||
|
**Write logs to a file (the progress bar stays on screen):**
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sarin -U http://example.com -r 1000 -c 10 -l info --log-file ./run.log
|
||||||
|
```
|
||||||
|
|
||||||
|
**Capture logs while keeping results on stdout:**
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sarin -U http://example.com -r 1000 -l info -o json > stats.json 2> run.log
|
||||||
|
```
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>YAML equivalent</summary>
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
url: http://example.com
|
||||||
|
requests: 1000
|
||||||
|
concurrency: 10
|
||||||
|
logLevel: info,error
|
||||||
|
logFile: ./run.log
|
||||||
```
|
```
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|||||||
+12
-12
@@ -183,19 +183,19 @@ body: '{{ body_FormData "image" "@https://example.com/photo.jpg" }}'
|
|||||||
|
|
||||||
# Mixed text fields and files
|
# Mixed text fields and files
|
||||||
body: |
|
body: |
|
||||||
{{ body_FormData
|
{{ body_FormData
|
||||||
"title" "My Report"
|
"title" "My Report"
|
||||||
"author" "John Doe"
|
"author" "John Doe"
|
||||||
"cover" "@/path/to/cover.jpg"
|
"cover" "@/path/to/cover.jpg"
|
||||||
"document" "@/path/to/report.pdf"
|
"document" "@/path/to/report.pdf"
|
||||||
}}
|
}}
|
||||||
|
|
||||||
# Multiple files with same field name
|
# Multiple files with same field name
|
||||||
body: |
|
body: |
|
||||||
{{ body_FormData
|
{{ body_FormData
|
||||||
"files" "@/path/to/file1.pdf"
|
"files" "@/path/to/file1.pdf"
|
||||||
"files" "@/path/to/file2.pdf"
|
"files" "@/path/to/file2.pdf"
|
||||||
}}
|
}}
|
||||||
|
|
||||||
# Escape @ for literal value (sends "@username")
|
# Escape @ for literal value (sends "@username")
|
||||||
body: '{{ body_FormData "twitter" "@@username" }}'
|
body: '{{ body_FormData "twitter" "@@username" }}'
|
||||||
@@ -226,7 +226,7 @@ body: '{"file": "{{ file_Base64 "/path/to/document.pdf" }}", "filename": "docume
|
|||||||
body: '{"image": "{{ file_Base64 "https://example.com/photo.jpg" }}"}'
|
body: '{"image": "{{ file_Base64 "https://example.com/photo.jpg" }}"}'
|
||||||
|
|
||||||
# Combined with values for reuse
|
# Combined with values for reuse
|
||||||
values: "FILE_DATA={{ file_Base64 \"/path/to/file.bin\" }}"
|
values: 'FILE_DATA={{ file_Base64 "/path/to/file.bin" }}'
|
||||||
body: '{"data": "{{ .Values.FILE_DATA }}"}'
|
body: '{"data": "{{ .Values.FILE_DATA }}"}'
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -234,7 +234,7 @@ body: '{"data": "{{ .Values.FILE_DATA }}"}'
|
|||||||
|
|
||||||
Captcha functions solve a captcha challenge through a third-party solving service and return the resulting token, which can then be embedded directly into a request. They are intended for load testing endpoints protected by reCAPTCHA, hCaptcha, or Cloudflare Turnstile.
|
Captcha functions solve a captcha challenge through a third-party solving service and return the resulting token, which can then be embedded directly into a request. They are intended for load testing endpoints protected by reCAPTCHA, hCaptcha, or Cloudflare Turnstile.
|
||||||
|
|
||||||
The functions are organized by service: `twocaptcha_*`, `anticaptcha_*`, and `capsolver_*`. Each accepts the API key as the first argument so no global configuration is required — bring your own key and use any of the supported services per template.
|
The functions are organized by service: `twocaptcha_*`, `anticaptcha_*`, and `capsolver_*`. Each accepts the API key as the first argument so no global configuration is required. Bring your own key and use any of the supported services per template.
|
||||||
|
|
||||||
> **Important: performance and cost:**
|
> **Important: performance and cost:**
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user