Self-hosted service
jertel/elastalert2 avatar
jertel/elastalert2

ElastAlert 2 turns Elasticsearch and OpenSearch patterns into alerts

ElastAlert 2 is a continuation of the original yelp/elastalert project. Pull requests are appreciated!

1,136 stars339 forksPythonApache-2.0

At a glance

What is it?
ElastAlert 2 is a standalone Python service that runs YAML rules on a schedule and dispatches alerts when data in Elasticsearch or OpenSearch spikes. It is a working continuation of the original Yelp project, packaged for containers and Kubernetes, but it polls rather than streams and it pins an old Elasticsearch client.
Who is it for?
Adopt ElastAlert 2 when you already run Elasticsearch or OpenSearch and need scheduled anomaly rules written in YAML, with alerts pushed to several targets. Skip it if detection must happen in the ingest path, if your data lives outside a cluster, or if you have no appetite for a rule engine you have to operate.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

ElastAlert 2 exists for the 2am question, not the dashboard question

ElastAlert 2 does one job: finding interesting shapes inside data already stored in Elasticsearch or OpenSearch and telling someone about it. The README describes it as a standalone software tool for alerting on anomalies, spikes, or other patterns of interest, and it is a continuation of the original yelp/elastalert project. The audience is operations and security teams who already operate a cluster, who want detection written as configuration rather than as a query someone remembers to run, and who need the outcome to land in a place a human will actually see. The design decision this forces is where detection lives. If the real question is which chart to look at, a dashboard already answers it and ElastAlert 2 is dead weight. If the question is who gets paged when an error rate moves past a threshold at 3am, a scheduled rule engine is the right shape of software, and the rest of the project follows from that choice: it polls, it evaluates, it dispatches. Nothing in the repository suggests it ingests data or watches a live stream.

Rules in YAML, evaluated on a schedule by APScheduler

The mechanics are visible in the package metadata. setup.py declares the distribution name elastalert2, version 2.31.0, and a description of automated rule-based alerting for Elasticsearch. It ships a schema file and a set of Elasticsearch mappings alongside the code, and the data directory includes an example configuration at examples/config.yaml.example plus a directory of example rules under examples/rules/. Scheduling is handled by apscheduler, pinned in the range 3.11.2 up to 4.0, with croniter available for cron style expressions, and the environment parsing library envparse is present for configuration. A schema file next to the code means rules are validated rather than merely parsed, and the elastalert-test-rule console script exists as a separate entry point, which tells you rule checking is a distinct operation from running the daemon. The elasticsearch client is a hard pin at 7.10.1 in both setup.py and requirements.txt, which tells you the wire protocol assumption baked into the code, and we will come back to what that means for OpenSearch clusters.

A first run through the container image, and where the rules actually live

The README does not give a pip install walkthrough, so the shortest documented path is the container route. Images are published on Docker Hub and on GitHub Container Registry, and a Helm chart is included in the repository under chart/elastalert2 for Kubernetes deployments. The Dockerfile builds a wheel on python:3.14.5-slim and generates a small run script at image build time. These are the exact lines it writes, and they show the order of operations: create the index first, then start the daemon with the same config file.

bash
    echo "elastalert-create-index --config /opt/elastalert/config.yaml" \
        >> /opt/elastalert/run.sh && \
    echo "elastalert --config /opt/elastalert/config.yaml \"\$@\"" \
        >> /opt/elastalert/run.sh && \

The image also drops privileges, running as an unprivileged user with WORKDIR /opt/elastalert and a fixed UTC timezone, so mounted config files and mounted alert logs both need to be writable by that account. For a first real use, prepare your rule file locally, mount it at /opt/elastalert/config.yaml, and start the container. On a bare Python install instead of the image, the entry points tell you what is available.

python
    entry_points={
        'console_scripts': ['elastalert-create-index=elastalert.create_index:main',
                            'elastalert-test-rule=elastalert.test_rule:main',
                            'elastalert=elastalert.elastalert:main']},

Three commands, and the middle one is the one worth running early: check a rule before the scheduler starts firing from it.

The pinned client is the sharpest edge in the dependency list

The dependency list is long and opinionated, roughly thirty packages covering schedulers, cloud SDKs and notification clients, but one line deserves a second look: elasticsearch==7.10.1. It appears identically in setup.py and in requirements.txt, with no upper range, so upgrading the client is not a matter of resolving a version constraint. That matters because the same project advertises OpenSearch as a supported backend alongside Elasticsearch. The README makes the claim, and the documentation site carries a FAQ entry about Elasticsearch 8 support, so the project clearly deals with version skew. What the metadata does not show is how a cluster speaking a newer protocol is reached through a client from the 7.x line, whether through a compatibility shim or through a proxy. If your cluster is a recent major version, this is the first thing to check, and it is checkable in the project documentation rather than by trial and error. The same caution applies to the pinned apscheduler and the other exact pins such as exotel and statsd-tags, which signal a maintainer who fixes versions deliberately.

Why this is the wrong tool for a live pipeline or for data outside a cluster

Two boundaries are clear. First, ElastAlert 2 is a poller. It schedules a query against a cluster and evaluates results, so the shortest reaction time you can hope for is bounded by your rule interval plus query time, and a rule that scans a wide time range over a large index will simply be slow. If a defect must be caught in the request path, or if a burst must be caught within seconds, a rule engine that queries after the fact is the wrong architecture, and the README says nothing about streaming ingestion, webhook pushes, or continuous queries. Second, it needs a searchable store to query. A team whose interesting data sits in a relational database, a message queue, or plain object storage cannot use it without first copying everything into Elasticsearch or OpenSearch, which is a separate project with its own cost. A third, quieter limitation: the README does not document backfilling historical data through an existing rule, so catching an anomaly that already happened may need a one-off query rather than the rule engine.

Choosing between ElastAlert 2 and the original ElastAlert, or writing your own checks

The obvious alternative is the original ElastAlert, and the difference is smaller than the naming suggests. The README states that ElastAlert 2 is backwards compatible with the original rules, and the repository description calls it a continuation rather than a fork with new syntax. So for a team that already runs ElastAlert, moving to ElastAlert 2 is mostly a packaging decision rather than a rewrite: the same rule files, but with a maintained image, a Helm chart, and a Python requirement of 3.12 or newer. The other alternative is writing checks yourself: a scheduled script that queries the cluster, compares a number to a threshold, and calls a webhook. The difference in approach is that ElastAlert 2 gives you a validated rule format, index bootstrapping through elastalert-create-index, per-rule scheduling, and notification targets already wired into the dependency list, including twilio, jira, zabbix-utils, exotel and stomp.py. The cost of that convenience is the same thing in reverse: you adopt its config model, its client pin, and its operational footprint.

A young project moving fast, under Apache 2.0 terms

The release history is short and recent. Version 2.30.0 shipped on 2026-05-27 and 2.31.0 on 2026-07-22, and the last push to the repository was on 2026-10-09, so the project is being worked on right now. The version in setup.py matches the 2.31.0 release, and the classifiers list Python 3.12, 3.13 and 3.14, with python_requires set at 3.12 or newer, which means the supported interpreter range is a moving target as new Python versions land. The top level of the repository shows a conventional Python layout with setup.py, setup.cfg, a Makefile, a tests directory, and a docs directory, and the Makefile exposes tox targets for tests, documentation and a Docker based test path. Licence wise the project is Apache 2.0, which permits commercial use and modification under its notice and patent conditions, and the repository carries a SECURITY.md for reporting urgent vulnerabilities. Upgrading is therefore a version bump in your deployment, but the pinned client and the moving Python floor mean a bump is not always free.

Editorial conclusion

Adopt ElastAlert 2 when you already run Elasticsearch or OpenSearch and need scheduled anomaly rules written in YAML, with alerts pushed to several targets. Skip it if detection must happen in the ingest path, if your data lives outside a cluster, or if you have no appetite for a rule engine you have to operate. Before installing, check the pinned client in setup.py against the version your cluster speaks, and decide whether the container image tag you pull matches the release you tested.

Frequently asked questions

What does it take to install and run ElastAlert 2?

The package requires Python 3.12 or newer and installs three console scripts: elastalert, elastalert-test-rule and elastalert-create-index. A container image is published on Docker Hub and on GitHub Container Registry, and a Helm chart is included for Kubernetes deployments.

Does ElastAlert 2 work with OpenSearch as well as Elasticsearch?

The README describes ElastAlert 2 as alerting on data in both Elasticsearch and OpenSearch, and the documentation site includes a FAQ entry about Elasticsearch 8 support. The dependency list still pins the Python client at elasticsearch==7.10.1, so check compatibility with your cluster version before you rely on it.

How can I check a rule before the scheduler starts firing from it?

setup.py registers elastalert-test-rule as a console script separate from elastalert and elastalert-create-index, so rule checking is a distinct step from running the daemon. The repository also ships examples/config.yaml.example and a directory of example rules under examples/rules/ to start from.

Official sources

  1. jertel/elastalert2 on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/jertel-elastalert2.svg)](https://hysenlabs.com/projects/jertel-elastalert2)

Was this useful?