Sentry is an open source application exception tracking system, which is supported by Django+DRF+Celery+ celery-beat. If you are Pythoner and are familiar with these technical stack, Sentry uses Django+DRF+Celery+ celery-beat. You can read the relevant source code, and there are a lot of things to learn. It is worth mentioning that Sentry only supports Python2, not Python3, when deployed.

In this article we will deploy Sentry as Docker, which is the official recommended deployment, and write a simple Django application that uses email and spikes to notify the developer of any exceptions that occur.

The environment

I ran a cloud server on Vultr for this test, using CentOS7.

Initialization operation

Install the epel source


     
  1. $ yum install epel-release -y

Copy the code

Update the system


     
  1. $ yum update -y

Copy the code

Install some toolkits


     
  1. $ yum install python-pip vim git -y

Copy the code

You are advised to restart the system


     
  1. $ reboot

Copy the code

The basic configuration

  • memory


     
  1. $ free -h

  2.              total        used        free      shared  buff/cache   available

  3. Mem:           3.7G         95M        3.4G        8.4M        168M        3.4G

  4. Swap:            0B          0B          0B

Copy the code
  • CPU


     
  1. $ cat /proc/cpuinfo | grep processor | wc -l

  2. 2

Copy the code

The configuration is also 2H4G, if you are a server with 1G memory, it seems that IT is difficult for me to run on Tencent cloud, I feel at least 2G.

Install the Docker

The installation of CentOS series of documents on: https://docs.docker.com/install/linux/docker-ce/centos/, interested can go to reading, I’ll simplify some operations here.

  • Install some software packages


     
  1. $ yum install -y yum-utils device-mapper-persistent-data lvm2

Copy the code
  • Add the Docker’s repo source


     
  1. $ yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

Copy the code
  • Install the docker


     
  1. $ yum install docker-ce -y

Copy the code
  • Start the docker


     
  1. $ systemctl start docker

Copy the code
  • Self-start upon startup


     
  1. $ systemctl enable docker

Copy the code
  • View the Docker version


     
  1. $ docker --version

  2. Docker version 18.03.1-ce, build 9ee9f40

Copy the code
  • Run a hello-world


     
  1. $ docker run hello-world

  2. Unable to find image 'hello-world:latest' locally

  3. latest: Pulling from library/hello-world

  4. 9db2ca6ccae0: Pull complete

  5. Digest: sha256:4b8ff392a12ed9ea17784bd3c9a8b1fa3299cac44aca35a85c90c5e3c7afacdc

  6. Status: Downloaded newer image for hello-world:latest

  7. Hello from Docker!

  8. This message shows that your installation appears to be working correctly.

  9. To generate this message, Docker took the following steps:

  10. 1. The Docker client contacted the Docker daemon.

  11. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.

  12.    (amd64)

  13. 3. The Docker daemon created a new container from that image which runs the

  14.    executable that produces the output you are currently reading.

  15. 4. The Docker daemon streamed that output to the Docker client, which sent it

  16.    to your terminal.

  17. To try something more ambitious, you can run an Ubuntu container with:

  18. $ docker run -it ubuntu bash

  19. Share images, automate workflows, and more with a free Docker ID:

  20. https://hub.docker.com/

  21. For more examples and ideas, visit:

  22. https://docs.docker.com/engine/userguide/

Copy the code

If you get the same results as ME, then, OK, Docker is installed.

If you use a domestic server, it may be unusually slow in the pull image, so the official provides domestic Docker image acceleration, point me point me, after the configuration must remember to restart the Docker service, otherwise the configuration cannot be loaded, restart the command is as follows:

                                
     
  1. $ systemctl restart docker

Copy the code

Install the docker – compose


     
  1. https://github.com/docker/compose/releases/download/1.21.2/docker-compose- $curl - L ` ` uname - s - ` uname -m ` - o /usr/local/bin/docker-compose

  2. $ chmod +x /usr/local/bin/docker-compose

Copy the code

I installed is 1.21.2 version, usually you install the docker and docker – compose is the latest version will not have what problem, check the docker – compose version

                                    
     
  1. $ docker -compose -- version

  2. Docker-compose version 1.21.2, Build A133471

Copy the code

Install the Sentry

Finally, the key step, Sentry, officially provides a complete set of Docker deployment mode to run Sentry.

  • Download the project


     
  1. $ cd /opt/

  2. $ git clone https://github.com/getsentry/onpremise.git sentry

  3. $ cd sentry

Copy the code
  • Create the database and Sentry configuration directory


     
  1. $ mkdir -p data/{sentry,postgres}

Copy the code
  • Add some dependency libraries


     
  1. $ vim requirements.txt

  2. # Add plugins here

  3. Sentry-dingding ~=0.0.1 # pin notification plugin

  4. Django-smtp-ssl ~=1.0 # Supports SSL for sending emails

Copy the code
  • Build the Docker image


     
  1. $ docker-compose build

Copy the code
  • Generate the key


     
  1. $ docker-compose run --rm web config generate-secret-key

  2. .

  3. The last line will output a secret key similar to the following

  4. kbjodp(id&b0^kbnxijn11&2e6xu&vy1(oini! -zl)pl610n&v

Copy the code

Add the above key to the SENTRY_SECRET_KEY environment variable in the docker-comemage. yml file

                                            
     
  1. $ vim docker -compose. yml

  2. .

  3. SENTRY_SECRET_KEY : 'kbjodp(id&b0^kbnxijn11&2e6xu&vy1(oini! -zl)pl610n&v'

Copy the code
  • Generate database tables and create administrator users


     
  1. $ docker-compose run --rm web upgrade

  2. .

  3. Would you like to create a user account now? [Y/n]: Y # Create a user

  4. Email: [email protected] #

  5. Password: # Password

  6. Repeat for confirmation: #

  7. Should this user be a superuser? [y/N]: y # is the super administrator

Copy the code
  • Start the service


     
  1. $ docker-compose up -d

Copy the code

You can use docker-compose PS to see which containers are started

                                                
     
  1. $ docker -compose ps

  2. Name Command State Ports

  3. ------------------------------------------------------------------------------------

  4. sentry_cron_1 /entrypoint. sh run cron Up 9000 /tcp

  5. sentry_memcached_1 docker -entrypoint. sh memcached Up 11211 /tcp

  6. sentry_postgres_1 docker -entrypoint. sh postgres Up 5432 /tcp

  7. sentry_redis_1 docker -entrypoint. sh redis ... Up 6379 /tcp

  8. sentry_smtp_1 docker -entrypoint. sh tini ... Up 25 /tcp

  9. Sentry_web_1 /entrypoint. sh run Web Up 0.0.0.0 :9000 ->9000 / TCP

  10. sentry_worker_1 /entrypoint. sh run worker Up 9000 /tcp

Copy the code

The above services are described as follows:

The name of the describe
sentry_cron Scheduled task, usingcelery-beat
sentry_memcached memcached
sentry_postgres PGSQL database
sentry_redis Run celery required services
sentry_smtp email
sentry_web usedjango+drfWrite a setSentry Web interface
sentry_worker Celery worker service, used to run asynchronous tasks

When the service is started, it listens on port 9000 by default. If you want to change it, you can do so in docker-comemage.yml.

I added an A record to my domain name ansheng.me. The record value is sentry, which points to the cloud server of Sentry, so it can be accessed through sentry.ansheng. me.

Basic Sentry Settings

The browser open http://sentry.ansheng.me:9000/, enter email address and password to log in

Once logged in successfully, enter the corresponding RootURL and Admin Email, and click Continue

Clicking takes you to the main Sentry screen

Add a Python project

Click Addnew in the upper right corner and select Project

And then create the project

After the project has been created, a use screen appears

Testing Python programs

Following the above steps, let’s do it step by step. I’m operating on my server, and the Python version is as follows:


     
  1. $ python -V

  2. Python 2.7.5

Copy the code
  • Install the raven


     
  1. $ pip install raven --upgrade

Copy the code
  • Adding test code


     
  1. $ vim sentry_python_test.py

  2. from raven import Client

  3. client = Client('http://ce5502f746a4484f9b2c391a54d2d1c4:[email protected]:9000/2')

  4. try:

  5. 1/0

  6. except ZeroDivisionError:

  7.    client.captureException()

Copy the code
  • run


     
  1. $ python sentry_python_test.py

  2. Sentry is attempting to send 1 pending error messages

  3. Waiting up to 10 seconds

  4. Press Ctrl-C to quit

Copy the code

Check the abnormal

In the usage screen above, click Gotit~Takeme to theIssueStream. Enter the project’s Issue page, or error page

You can see that there is already an exception. This exception is the error that we caught when we tested. Click on the heading of ZeroDivisionError to enter the detailed page of the exception.

On the project page, you can see MESSAGE and EXCEPTION, which output the error details

Basically the steps are the same as above, the flow is similar

Add Django projects and monitor them

Follow the steps above to create the PythonSentry project and add a Django framework project named Cash and save the DSN record values

http://9ad8168873a94fb1927e14111b9bca1e:[email protected]:9000/3

Creating a Django project

Django projects I created on my computer.

  • Add a virtual environment named Cash


     
  1. $pyEnv VirtualEnv 3.6.5 cash

Copy the code
  • Switching virtual Environments


     
  1. $ pyenv activate cash

Copy the code
  • Install django


     
  1. $ pip install django

Copy the code
  • Create a project


     
  1. $ cd /tmp

  2. $ django-admin startproject cash

  3. $ cd cash

  4. $ python manage.py migrate

Copy the code
  • Start the project


     
  1. $ python manage.py runserver 0:9999

  2. Performing system checks...

  3. System check identified no issues (0 silenced).

  4. July 17, 2018 - 03:35:05

  5. Django version 2.0.7, using settings 'cash.settings'

  6. Starting development server at http://0:9999/

  7. Quit the server with CONTROL-C.

Copy the code

Port listening at 9999, you can use curl to test access

                                                                                                                                            
     
  1. $curl -i HTTP :// 127.0.1:9999

  2. HTTP / 1.1 200 OK

  3. .

Copy the code

A status of 200 indicates no problem

  • Viewing the directory Structure


     
  1. ➜  cash tree ./

  2. . /

  3. ├ ─ ─ cash

  4. │ ├ ─ ─ just set py

  5. │ ├ ─ ─ Settings. Py

  6. │ ├ ─ ─ urls. Py

  7. │ ├ ─ ─ views. Py

  8. │ └ ─ ─ wsgi. Py

  9. ├ ─ ─ the sqlite3

  10. └ ─ ─ the manage. Py

Copy the code
  • Write a simple view


     
  1. $ vim cash/views.py

  2. from django.http import HttpResponse

  3. def success(request):

  4.    return HttpResponse("OK")

  5. def error(request):

  6. 1/0

  7.    return HttpResponse("Not OK")

Copy the code
  • Add the url


     
  1. $ vim cash/urls.py

  2. from django.urls import path

  3. from . import views

  4. urlpatterns = [

  5.    path('success', views.success, name='success'),

  6.    path('error', views.error, name='error'),

  7. ]

Copy the code
  • Access to the test

Access the API that returns success


     
  1. $curl http://127.0.0.1:9999/success

  2. OK

Copy the code

Accessing an ERROR reporting API


     
  1. $curl -i http://127.0.0.1:9999/error

  2. HTTP/1.1 500 Internal Server Error

  3. .

Copy the code

An error of 500 was reported, and the log output is as follows

                                                                                                                                                
     
  1. Internal Server Error : /error

  2. Traceback ( most recent call last ):

  3. The File "/ Users/shengan /. / lib/python3.6 pyenv/versions/cash/site - packages/django/core/handlers/exception. Py", line 35, in inner

  4. response = get_response (request )

  5. The File "/ Users/shengan /. / lib/python3.6 pyenv/versions/cash/site - packages/django/core/handlers/base. Py", line 128, in _get_response

  6. response = self. process_exception_by_middleware( e, request)

  7. The File "/ Users/shengan /. / lib/python3.6 pyenv/versions/cash/site - packages/django/core/handlers/base. Py", line 126, in _get_response

  8. response = wrapped_callback (request , *callback_args , **callback_kwargs )

  9. File "/private/tmp/cash/cash/views.py", line 8 , in error

  10. 1/0

  11. ZeroDivisionError : division by zero

  12. [17/ Jul/ 2018 03:50:55] "HTTP/1.1" 500 60675

Copy the code

Integrated Sentry

  • Install the raven


     
  1. $ pip install raven --upgrade

Copy the code
  • Add raven.contrib.django.raven_compat to INSTALLED_APPS


     
  1. INSTALLED_APPS = (

  2. .

  3.    'raven.contrib.django.raven_compat',

  4. )

Copy the code
  • Add the Sentry configuration in Setting


     
  1. import os

  2. import raven

  3. RAVEN_CONFIG = {

  4. 'dsn': 'http://9ad8168873a94fb1927e14111b9bca1e:[email protected]:9000/3' # DSN enter DSN we just recorded

  5. }

Copy the code
  • After that, I’ll let’s test it out

Wrong API access


     
  1. $curl -i http://127.0.0.1:9999/error

Copy the code
  • Exception list

  • Exception details

Configuring Email Notification

I use netease email here, and the specific operations are as follows

  • Modify the config.yml file to add the Mail Server configuration


     
  1. $ vim config.yml

  2. mail.backend: 'django_smtp_ssl.SSLEmailBackend'  # Use dummy if you want to disable email entirely

  3. mail.host: 'smtp.163.com'

  4. mail.port: 465

  5. mail.username: '[email protected]'

  6. Mail. password: '14RJg5vzGFWUNKiP'

  7. mail.use-tls: false

  8. # The email address to send on behalf of

  9. mail.from: '[email protected]'

Copy the code
  • Rebuild the image


     
  1. $ docker-compose build

  2. $ docker-compose up -d

Copy the code

After the restart, the configuration of the mailbox can be found under Admin==> mail

Then click below to send a test email to [email protected], and then go to your email to see if you received the email

I can receive the test email sent successfully. Usually, I can receive the abnormal notification after the email configuration is completed.

  • Verify the user’s mailbox

Find the Settings = > Account = > Emails

Then click Resendverification and you receive a verification email

Click Confirm to Confirm email.

  • Exception notification test

And then, we’re accessing the wrong API


     
  1. $curl -i http://127.0.0.1:9999/error

  2. HTTP/1.1 500 Internal Server Error

Copy the code
  • Check your mailbox for alarm emails

Basically, you’ll get an error email similar to the one above. Somehow that avatar doesn’t show up. Anyway, if you want to see the error details, click on ViewonSentry to open the exception details.

Configure pin notification

As we all know, the timeliness of mailbox notification is too poor to be delivered without delay, so we focus on the group notification of Dingdingrobot.

  • Create a pin group to add a custom robot and obtain an access_token

I’m here for the access_token dadfa77dfc3fe3b34e91237665afbef165e745dd93ec191c48bf4843b1ad63c 4

  • configuration

Find all integrations for the Cash project

Then locate the DingDing Plugin, enable the Plugin, and click Configure Plugin to Configure the Plugin

Enter the access_token you just obtained and click Save Changes to Save your Changes

  • Test Exception Notification

Then we access the API for the following exception


     
  1. $curl -i http://127.0.0.1:9999/error

  2. HTTP/1.1 500 Internal Server Error

  3. .

Copy the code

Your stitching robot should now send the following error

Click the href above to jump to the error details page, and this article ends.