Notes on Working with the Sentry Source Code
Sentry basics
Steps to self-host Sentry
Sentry is a server-side logging platform. The basic setup flow (Python environment; see the official docs for Docker) is:
- Install Redis and PostgreSQL locally.
- Initialize and start both databases.
- Create a Python virtualenv (everything in this post happens inside one).
pip install sentry
- Initialize config:
sentry init /etc/sentry
(choose any path; Sentry defaults to~/.sentry
). - Update the config files, especially database settings.
- Run the database migrations.
- Start the
web
,worker
, andcron
services with thesentry
CLI.
Once the instance is up, open the web UI, create a project, and follow the instructions to send events—typically via the Raven SDK for Python.
Architecture
Sentry consists of:
- Server-side services:
web
: Django + uWSGI handling HTTP trafficworker
: Celery workers for asynchronous tasks (database I/O, etc.)cron
: scheduled jobs
- SDKs: language-specific clients (Raven for Python, etc.).
- APIs: REST endpoints for reading and writing events.
Development environment
These notes assume CentOS 7.
Runtime dependencies
Clone the source:
git clone https://github.com/getsentry/sentry
Install dependencies much like the self-host flow, plus the development requirements:
pip install -r requirements-base.txt
Entry point
setup.py
defines the console script:
1 | entry_points={ |
main
lives in sentry/runner/__init__.py
:
1 | def main(): |
The CLI itself uses click
:
1 |
|
Each subcommand eventually calls into specific handlers. For example, sentry run web
maps to sentry.runner.commands.run:web
:
1 |
|
…and so on.
Working with API endpoints
Take group_details.py
as an example: when deleting an issue it does the following (simplified):
- Validate access and locate the group.
- Mark the group’s status as pending deletion.
- Capture the previous status in an audit entry.
- Queue the actual deletion via
delete_group.apply_async
with a one-hour countdown. - Log the deletion.
- Return HTTP 202.
Actual deletion happens in Celery workers, not in the request thread.
Adding a new endpoint
Suppose we want to delete a single Event
. Two complications:
- The
Event
model (sentry_message
) has nostatus
column. - There is no ready-made
delete_event
helper.
To keep changes minimal we can ship a synchronous delete:
1 | # sentry.api.endpoints.project_event_details.ProjectEventDetailsEndpoint |
See https://github.com/chroming/sentry for a complete example.
Running the source
If you invoke sentry
from the shell it uses the installed package, not your checkout. Installing from source is one option, but during development it is helpful to run directly.
Create a helper script:
1 | # run_server.py |
This still uses uWSGI, so breakpoints do not work. For debugging APIs, run a simple WSGI server instead:
1 | # run_simple_server.py |
Static assets won’t load, but you can debug API requests comfortably.
Installing back into the environment
Once the changes are ready, install them.
Prerequisites:
sudo yum install gcc zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel tk-devel libffi-devel python-devel gcc-c++
sudo yum install npm
If you are modifying a 9.0.x branch, adjust requirements-base.txt
:
Change redis-py-cluster>=1.3.4,<1.4.0
to redis-py-cluster==1.3.4
to avoid a version conflict with the redis
package (Sentry pins redis<=1.3.5
, while newer redis-py-cluster
requires redis>=2.10.6
).
Install in editable mode:
pip install --editable .
You can now use the sentry
command as usual.