Try It Without an Account
Run a real pipeline on your own machine before you sign up for anything. Local mode runs the Expanso Edge agent standalone, without a connection to the control plane, so there is no account, bootstrap token, or Cloud setup.
The pipeline you will run filters log noise at the source. It drops routine health checks, debug chatter, and successful static-asset requests, and keeps everything else, including errors and warnings. You send it log lines over HTTP and see what survives.
What you need
expanso-edgeandexpanso-cliinstalled (Installation). Local mode needs both: the agent runs the pipeline, and the CLI submits it.curland two terminal windows.
Check both tools are on your PATH:
expanso-edge version
expanso-cli version
Step 1: Write the pipeline
Make an empty folder for this walkthrough and work inside it:
mkdir expanso-try && cd expanso-try
Create log-filter.yaml:
cat > log-filter.yaml <<'EOF'
name: log-filter
description: Keep signal, drop routine log noise at the source
type: pipeline
config:
input:
http_server:
address: 127.0.0.1:8090
path: /ingest
pipeline:
processors:
- mapping: |
let raw = content().string()
let doc = $raw.parse_json().catch(null)
let doc = if $doc.type() == "object" { $doc } else {
{"log": $raw}
}
let level = $doc.level.string().catch("").lowercase()
let path = $doc.http.path.string().catch("")
let status = $doc.http.status.number().catch(0)
let is_health = $path.re_match(
"^/(health|healthz|ready|livez|metrics)($|[/?])"
)
let is_debug = $level == "debug"
let is_static = $status > 0 && $status < 400 &&
$path.re_match("\\.(css|js|png|jpg|svg|woff2?)($|[?#])")
root = if $is_health || $is_debug || $is_static {
deleted()
} else {
$doc.merge({"kept": true})
}
output:
sync_response: {}
EOF
The file is a job: a name, a type, and the pipeline under config.
The pipeline reads each HTTP request body as one log line, decides whether to
keep it with a mapping (written in
Bloblang), and returns the result in the HTTP response
through sync_response. Lines that are
not JSON objects are kept and wrapped as {"log": ...}.
Step 2: Check it without running anything
expanso-edge validate log-filter.yaml
[OK] log-filter.yaml: valid
validate works offline and never executes the pipeline, so you can run it
after every edit. Add -o json to get each error with its path and line
number.
Step 3: Start a local agent
In your first terminal, from the expanso-try folder:
expanso-edge run --local --data-dir ./.edge
Among the startup lines (timestamps trimmed) you will see:
INF API server listening addr=127.0.0.1:9010 component=api_server
INF Expanso Edge Service started successfully component=edge_service
Leave it running. The agent now accepts jobs on localhost:9010.
--data-dir ./.edge keeps the agent's job store, execution state, and
pipeline logs in this folder. Without it, the agent uses
~/.expanso/edge (or /var/lib/expanso/edge when run as a system service).
Step 4: Deploy the pipeline
In your second terminal, from the same folder:
export EXPANSO_CLI_CONFIG_DIR="$PWD/.expanso-cli"
expanso-cli job deploy log-filter.yaml \
--endpoint http://localhost:9010
Job 'log-filter' created successfully in namespace ''
EXPANSO_CLI_CONFIG_DIR gives the CLI its own settings folder inside
expanso-try, and --endpoint names the local agent on every command, so
the CLI never uses a saved profile or an Expanso Cloud workspace you may
have set up elsewhere. Keep both on every expanso-cli command in this
walkthrough.
Step 5: Send it some logs
Create a small sample:
cat > sample.log <<'EOF'
{"level":"info","http":{"path":"/healthz","status":200}}
{"level":"error","msg":"payment failed"}
{"level":"info","http":{"path":"/orders","status":200}}
{"level":"debug","msg":"cache lookup"}
{"level":"info","http":{"path":"/assets/app.js","status":200}}
{"level":"warn","msg":"retry budget low"}
EOF
Send it one line at a time:
while IFS= read -r line; do
curl -s -d "$line" http://127.0.0.1:8090/ingest; echo
done < sample.log
{"kept":true,"level":"error","msg":"payment failed"}
{"http":{"path":"/orders","status":200},"kept":true,"level":"info"}
{"kept":true,"level":"warn","msg":"retry budget low"}
Three of the six lines come back. The blank lines are the health check, the
debug line, and the static asset: the pipeline dropped them before they
could go anywhere. The error, the warning, and the real API request
survive, each marked "kept": true.
Try a line of your own, in any format:
curl -s -d 'GET /login 401 from 10.0.0.9' \
http://127.0.0.1:8090/ingest; echo
{"kept":true,"log":"GET /login 401 from 10.0.0.9"}
Step 6: Change the rule
Edit log-filter.yaml, for example to stop dropping health checks by
removing $is_health || from the root = if line. Then check and redeploy
the same file:
expanso-edge validate log-filter.yaml
expanso-cli job deploy log-filter.yaml \
--endpoint http://localhost:9010
[OK] log-filter.yaml: valid
Job 'log-filter' updated successfully in namespace '' (version: 2)
Run the Step 5 loop again: the health check now comes back as the first line.
Clean up
Stop the agent with Ctrl+C in the first terminal. The job store and
pipeline logs are in ./.edge, so if you start the agent again with the same
--data-dir, log-filter starts again too. Delete the expanso-try folder
(including .edge and any .expanso-cli settings) to start fresh.
Troubleshooting
bind: address already in use when starting the agent means something
else already uses port 9010. Pick another port for the agent:
expanso-edge run --local --data-dir ./.edge \
--api-listen 127.0.0.1:9011
Then use --endpoint http://localhost:9011 on every expanso-cli command.
The same applies to the pipeline's own port: change 8090 in both
log-filter.yaml and the curl commands.
NO_CHANGES_DETECTED from expanso-cli job deploy means the file is
identical to the job already deployed. Edit it first, or add --force to
deploy it anyway.
Where is the pipeline's own log? In
./.edge/executions/<job-id>/logs/pipeline.log. Get the job ID with
expanso-cli job list --endpoint http://localhost:9010.
Next steps
- Examples with a "Try locally" block that runs on this same agent: data transformer, metadata enrichment, and deadband filtering.
- Local Mode: what local mode supports, its CLI commands, and troubleshooting.
- Bloblang Guide: the language behind the
mappingprocessor. - Cloud Quick Start: when you want to manage pipelines across a fleet of edge nodes from one control plane.