Migration from Elastic
This guide helps Elastic Stack (ELK / Elastic Security) users move to CSIRT-Pro. It maps KQL and Elasticsearch concepts to their PRQL equivalents and lays out a practical migration workflow.
Concept Mapping
Most Elastic concepts map cleanly onto CSIRT-Pro. Queries move from KQL or Lucene to PRQL, and detection logic moves into Playbooks.
| Elastic Concept | CSIRT-Pro Equivalent | Notes |
|---|---|---|
| Index / Data Stream | Pipeline | Each Pipeline maps to its own log store |
| Index Pattern | Pipeline name | Queries target the pipeline name directly |
| KQL / Lucene | PRQL | Pipelined syntax, strongly typed |
| Kibana Dashboard | Dashboard | 12-column grid, PDF export, JSON import/export |
| Detection Rule | Playbook (schedule trigger) | More flexible: full Python/JS logic |
| Alert | Case (opened by Playbook/UEBA) | Threaded investigation workflow |
| Saved Search | Saved Visualization | Query and chart config are persisted |
| Index Lifecycle Policy (ILM) | Pipeline TTL | Simple day-based retention |
| Ingest Pipeline | Pipeline parse settings | Regex or JSON extraction at query time |
| Kibana Lens / Visualize | Search visualization | Multiple chart types, right-click to switch |
| Elastic Agent / Beats | API client / log shipper | Any HTTP-capable agent works |
| Spaces | Organizations | Full multi-tenant isolation |
| Cross-Cluster Search | SharedAccess | Fine-grained cross-org data sharing |
| Elastic SIEM | Built-in (Search + Cases + UEBA) | Unified in one product |
| Elastic SOAR | Playbook | Visual editor with Python/JS nodes |
KQL to PRQL Mapping
Basic Search
Multiple Conditions (AND)
OR Conditions
Wildcard / Partial Match
Numeric Range
Negation
Aggregation: Count by Field
Date Histogram
Automatic Bucketing
The CSIRT-Pro Timeline visualization applies date-histogram bucketing automatically. Select the Timeline chart type after running your query.
Operator Reference
| KQL / Elastic | PRQL Equivalent | Notes |
|---|---|---|
field: "value" |
filter field == "value" |
Exact match |
field: *pattern* |
filter field ~= "pattern" |
Regex partial match |
field >= 100 |
filter field >= 100 |
Numeric comparison |
NOT field: "value" |
filter field != "value" |
Negation |
AND |
Multiple filter lines |
Sequential filters are AND-ed |
OR |
\|\| inside a filter |
filter (a == 1 \|\| b == 2) |
_source: [fields] |
select {fields} |
Field projection |
sort: [{"@timestamp": "desc"}] |
sort {-__time} |
Descending sort |
size: N |
take N |
Limit results |
terms aggregation |
group {field} (aggregate {...}) |
Group and aggregate |
sum aggregation |
aggregate {total = sum field} |
Sum aggregation |
avg aggregation |
aggregate {avg = average field} |
Average aggregation |
min / max aggregation |
aggregate {min field} / aggregate {max field} |
Min/Max |
Ingest Pipeline Mapping
In Elastic, parsing happens at ingest time through ingest-pipeline processors. In CSIRT-Pro, you define the parse rule on the pipeline, and extraction runs at query time (schema-on-read). A Grok processor maps to a regex parse rule with the matching field names.
Elastic Ingest Pipeline (Grok Processor)
{
"processors": [
{
"grok": {
"field": "message",
"patterns": ["%{IP:src_ip} %{WORD:action} %{NUMBER:bytes}"]
}
}
]
}
CSIRT-Pro Pipeline Parse Settings
druid_parse:
druid_parse_field:
A Grok numeric field maps to a typed parse field with name(Type) (e.g. bytes(Int64)), so numeric comparison and aggregation work without conversion functions. Untyped names default to String. Typing works in both regex and JSON mode.
Converting Grok patterns
You do not have to translate Grok patterns by hand. Paste a sample log line into AI Parse Generation: it accepts Grok-style input and produces the regex and field names, which you review and apply.
Data Migration Workflow
Phase 1: Set Up Pipelines
- Map each Elasticsearch index or data stream to a CSIRT-Pro Pipeline.
- Configure parse settings to match your existing ingest-pipeline processors.
- Use AI Parse Generation to draft rules quickly from sample logs.
- Set TTL values to match your existing ILM hot/warm/delete phases.
Phase 2: Parallel Ingestion
- Configure your log shippers to send data to both Elastic and CSIRT-Pro at the same time.
- Confirm the data in the CSIRT-Pro Search screen.
- Compare record counts and field-extraction accuracy.
Phase 3: Historical Data Export
Export data from Elasticsearch and import it into CSIRT-Pro.
Using the Scroll API
# Export from Elasticsearch
curl -X POST "http://elasticsearch:9200/firewall-logs/_search?scroll=5m" \
-H "Content-Type: application/json" \
-d '{"size": 1000, "query": {"match_all": {}}}' \
> export.json
# Convert to NDJSON and import to CSIRT-Pro
curl -X POST "https://<domain>/api/v2/ingest/batch" \
-H "Content-Type: application/json" \
-H "X-API-Key: <api_key>" \
-d '{
"pipeline_id": "<pipeline_id>",
"records": [ ... ]
}'
Using Elasticdump (for large datasets)
# Export
elasticdump --input=http://elasticsearch:9200/my-index --output=data.json --type=data
# Transform and import to CSIRT-Pro
# (use a script to convert to the CSIRT-Pro batch format)
Phase 4: Migrate Dashboards and Detection Rules
- Recreate Kibana dashboards by converting KQL queries to PRQL.
- Convert Elastic Detection Rules to CSIRT-Pro Playbooks with schedule triggers and PRQL-based detection logic.
- Map Elastic alerting actions to Playbook notification nodes (Slack, email, webhook).
Phase 5: Cutover
- Redirect all log shippers to CSIRT-Pro only.
- Scale down or decommission the Elasticsearch nodes.
- Keep Elasticsearch in read-only mode until CSIRT-Pro retention covers your compliance window.
Common Questions
How does CSIRT-Pro handle schemaless data?
JSON logs are ingested without a schema definition.
When the parse rule is empty, the pipeline treats messages as JSON and extracts fields at query time, and a value that does not match its declared type becomes NULL.
Field names can carry type annotations (name(Type)) in both JSON mode and regex mode; untyped fields default to String.
For structured text logs, configure a regex parse rule per pipeline, optionally typing fields the same way.
Can I still use Sigma rules?
Yes.
CSIRT-Pro includes a Sigma rule conversion endpoint (POST /api/sigma) that translates Sigma YAML into PRQL queries.
What about ECS (Elastic Common Schema)?
CSIRT-Pro does not require a fixed schema. You can keep using ECS field names in your logs, and they are preserved as written.
How does pricing compare?
CSIRT-Pro uses predictable pricing rather than node-based or resource-based licensing. Capacity planning is straightforward, and there is no cluster sizing to tune.