Skip to content

Instantly share code, notes, and snippets.

@voluntas
Last active March 26, 2020 01:23
Show Gist options
  • Save voluntas/6937403 to your computer and use it in GitHub Desktop.
Save voluntas/6937403 to your computer and use it in GitHub Desktop.
Sentry + Django コトハジメ

Sentry + Django コトハジメ

更新:2013-12-27
バージョン:1.5.1
作者:@voluntas
URL:http://voluntas.github.io/

概要

url:https://getsentry.com/welcome/

OSS で様々な言語から使えるエラートラッカー Sentry

リアルタイムエラートラッカーである Sentry は「どのようなエラー」がどう起きているのかを集計することが出来る。さらにそのエラーに対して解決チェックが可能になるため、どんなエラーが起きていたか確認しやすい。

もともと DISQUS で作られ使われていたものがオープンソースとなり、(おそらく)作者が会社を起こしてとしてサービス化までしている。

実際にサービスを運用し、開発している人からみたら必要不可欠なシステムである。

ここでは Sentry は「エラートラッカー」で Raven は 「Python で出来た Sentry 用のクライアント」を指す。

目的

  • Sentry を使ってみる
  • Raven から Sentry へエラーログを送る
  • エラーログを HTTP または Gevent+HTTP または UDP で送る
  • Redis をキャッシュとして使ってみる
  • Redis をバッファーとして使ってみる
  • Celery(Redis) をキューとして使ってみる

バージョン

Django:1.6.1
Sentry:6.4.2.1

セットアップ

$ pip install sentry

sentry の初期設定ファイルは sentry init で生成出来る

ちなみにデフォルトでは ~/.sentry/sentry.conf.py を確認しに行く

$ sentry init sentry.conf.py

sentry.conf.py 初期設定は sqlite3 になっている。試すだけならコレで問題ない。 本番では Postgres か MySQL にする必要がある。

参考までに生成された設定ファイルをそのまま乗せておく

# This file is just Python, with a touch of Django which means you
# you can inherit and tweak settings to your hearts content.
from sentry.conf.server import *

import os.path

CONF_ROOT = os.path.dirname(__file__)

DATABASES = {
    'default': {
        # You can swap out the engine for MySQL easily by changing this value
        # to ``django.db.backends.mysql`` or to PostgreSQL with
        # ``django.db.backends.postgresql_psycopg2``

        # If you change this, you'll also need to install the appropriate python
        # package: psycopg2 (Postgres) or mysql-python
        'ENGINE': 'django.db.backends.sqlite3',

        'NAME': os.path.join(CONF_ROOT, 'sentry.db'),
        'USER': 'postgres',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '',

        # If you're using Postgres, we recommend turning on autocommit
        # 'OPTIONS': {
        #     'autocommit': True,
        # }
    }
}


# If you're expecting any kind of real traffic on Sentry, we highly recommend
# configuring the CACHES and Redis settings

###########
## CACHE ##
###########

# You'll need to install the required dependencies for Memcached:
#   pip install python-memcached
#
# CACHES = {
#     'default': {
#         'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
#         'LOCATION': ['127.0.0.1:11211'],
#     }
# }

###########
## Queue ##
###########

# See http://sentry.readthedocs.org/en/latest/queue/index.html for more
# information on configuring your queue broker and workers. Sentry relies
# on a Python framework called Celery to manage queues.

# You can enable queueing of jobs by turning off the always eager setting:
# CELERY_ALWAYS_EAGER = False
# BROKER_URL = 'redis://localhost:6379'

####################
## Update Buffers ##
####################

# Buffers (combined with queueing) act as an intermediate layer between the
# database and the storage API. They will greatly improve efficiency on large
# numbers of the same events being sent to the API in a short amount of time.
# (read: if you send any kind of real data to Sentry, you should enable buffers)

# You'll need to install the required dependencies for Redis buffers:
#   pip install redis hiredis nydus
#
# SENTRY_BUFFER = 'sentry.buffer.redis.RedisBuffer'
# SENTRY_REDIS_OPTIONS = {
#     'hosts': {
#         0: {
#             'host': '127.0.0.1',
#             'port': 6379,
#         }
#     }
# }

################
## Web Server ##
################

# You MUST configure the absolute URI root for Sentry:
SENTRY_URL_PREFIX = 'http://sentry.example.com'  # No trailing slash!

# If you're using a reverse proxy, you should enable the X-Forwarded-Proto
# header, and uncomment the following setting
# SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

SENTRY_WEB_HOST = '0.0.0.0'
SENTRY_WEB_PORT = 9000
SENTRY_WEB_OPTIONS = {
    'workers': 3,  # the number of gunicorn workers
    'secure_scheme_headers': {'X-FORWARDED-PROTO': 'https'},
}

#################
## Mail Server ##
#################

# For more information check Django's documentation:
#  https://docs.djangoproject.com/en/1.3/topics/email/?from=olddocs#e-mail-backends

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'

EMAIL_HOST = 'localhost'
EMAIL_HOST_PASSWORD = ''
EMAIL_HOST_USER = ''
EMAIL_PORT = 25
EMAIL_USE_TLS = False

# The email address to send on behalf of
SERVER_EMAIL = 'root@localhost'

###########
## etc. ##
###########

# If this file ever becomes compromised, it's important to regenerate your SECRET_KEY
# Changing this value will result in all current sessions being invalidated
SECRET_KEY = 'BlO5KHaG22LVNaPSnRIYV36TzCFXPTlo4QDveI/s+K3KkYtehVLSFw=='

# http://twitter.com/apps/new
# It's important that input a callback URL, even if its useless. We have no idea why, consult Twitter.
TWITTER_CONSUMER_KEY = ''
TWITTER_CONSUMER_SECRET = ''

# http://developers.facebook.com/setup/
FACEBOOK_APP_ID = ''
FACEBOOK_API_SECRET = ''

# http://code.google.com/apis/accounts/docs/OAuth2.html#Registering
GOOGLE_OAUTH2_CLIENT_ID = ''
GOOGLE_OAUTH2_CLIENT_SECRET = ''

# https://github.com/settings/applications/new
GITHUB_APP_ID = ''
GITHUB_API_SECRET = ''

# https://trello.com/1/appKey/generate
TRELLO_API_KEY = ''
TRELLO_API_SECRET = ''

# https://confluence.atlassian.com/display/BITBUCKET/OAuth+Consumers
BITBUCKET_CONSUMER_KEY = ''
BITBUCKET_CONSUMER_SECRET = ''

起動前に ALLOWED_HOSTS を sentry.conf.py に設定を 追加 する必要がある。 また SENTRY_URL_PREFIX を 127.0.0.1:9000 に設定を 変更 する必要がある。

ALLOWED_HOSTS = ['127.0.0.1']

SENTRY_URL_PREFIX = 'http://127.0.0.1:9000'

さらにメールサービスは今使わないのでコメントアウトして下さい。

# #################
# ## Mail Server ##
# #################

# # For more information check Django's documentation:
# #  https://docs.djangoproject.com/en/1.3/topics/email/?from=olddocs#e-mail-backends

# EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'

# EMAIL_HOST = 'localhost'
# EMAIL_HOST_PASSWORD = ''
# EMAIL_HOST_USER = ''
# EMAIL_PORT = 25
# EMAIL_USE_TLS = False

# # The email address to send on behalf of
# SERVER_EMAIL = 'root@localhost'

起動は sentry コマンドから行う

$ sentry --config=sentry.conf.py start

初回起動時はスーパーユーザの作成とモデルが生成されますが、ここでは省略してます。

スーパーユーザを作りたい場合は以下のコマンドを実行します

$ sentry --config=sentry.conf.py createsuperuser

二回目以降の表示:

Performing upgrade before service startup...
Syncing...
Creating tables ...
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)
Migrating...
Running migrations for djcelery:
- Nothing to migrate.
 - Loading initial data for djcelery.
Installed 0 object(s) from 0 fixture(s)
Running migrations for django:
- Nothing to migrate.
 - Loading initial data for django.
Installed 0 object(s) from 0 fixture(s)
Running migrations for sentry:
- Nothing to migrate.
 - Loading initial data for sentry.
Installed 0 object(s) from 0 fixture(s)
Running migrations for social_auth:
- Nothing to migrate.
 - Loading initial data for social_auth.
Installed 0 object(s) from 0 fixture(s)

Synced:
 > django.contrib.auth
 > django.contrib.admin
 > django.contrib.contenttypes
 > django.contrib.messages
 > django.contrib.sessions
 > django.contrib.sites
 > django.contrib.staticfiles
 > crispy_forms
 > raven.contrib.django.raven_compat
 > sentry.plugins.sentry_interface_types
 > sentry.plugins.sentry_mail
 > sentry.plugins.sentry_urls
 > sentry.plugins.sentry_useragents
 > south

Migrated:
 - djcelery
 - kombu.transport.django
 - sentry
 - social_auth
Running service: 'http'
2013-10-12 13:22:23 [53706] [INFO] Starting gunicorn 0.17.4
2013-10-12 13:22:23 [53706] [INFO] Listening at: http://0.0.0.0:9000 (53706)
2013-10-12 13:22:23 [53706] [INFO] Using worker: sync
2013-10-12 13:22:23 [53711] [INFO] Booting worker with pid: 53711
2013-10-12 13:22:23 [53712] [INFO] Booting worker with pid: 53712
2013-10-12 13:22:23 [53713] [INFO] Booting worker with pid: 53713

起動が成功したら以下にアクセスします。

http://127.0.0.1:9000/login/

ログイン画面が表示されるはずです。

https://dl.dropboxusercontent.com/u/89936/gist/sentry-django/login.png

先ほど作成したスーパーユーザでログインすると、プロジェクトが選択できます。

https://dl.dropboxusercontent.com/u/89936/gist/sentry-django/top.png

まずは Sentry の内部向けのプロジェクトを見てみましょう。 今 Sentry には何も起きてないのでイベントは登録されていません。

https://dl.dropboxusercontent.com/u/89936/gist/sentry-django/sentry_internal.png

新しくアプリを作ってテストするために新しいチームを作ってみましょう。

まずは以下の URL へ移動します

http://127.0.0.1:9000/

ここでは仮に shiguredo というプロジェクトを作ります。

https://dl.dropboxusercontent.com/u/89936/gist/sentry-django/new_team_shiguredo.png

その後チームに対して snowflake というプロジェクトを作ります。

https://dl.dropboxusercontent.com/u/89936/gist/sentry-django/new_project_snowflake.png

セッティングにとばされると思います。そこで一番したの raven test ... という行を探して下さい。 コピーします。public_key と secret_key は異なるはずです。

https://dl.dropboxusercontent.com/u/89936/gist/sentry-django/shiguredo_snowflake_settings_python.png

sdn protocol は protocol://public_key:secret_key:host/project の形式です。 今回は protocol は http で、プロジェクトが 2 です。

raven test http://7c9de9b821244afab1cc9171833a4847:de5f063137e34b558a69631f24684457@127.0.0.1:9000/2

コピーしたらまずは Stream タブへ移動します。何も出ていないはずです。

https://dl.dropboxusercontent.com/u/89936/gist/sentry-django/shiguredo_snowflake_stream.png

では、先ほどの raven コマンドをターミナルから実行します。

$ raven test http://7c9de9b821244afab1cc9171833a4847:de5f063137e34b558a69631f24684457@127.0.0.1:9000/2
Using DSN configuration:
  http://7c9de9b821244afab1cc9171833a4847:de5f063137e34b558a69631f24684457@127.0.0.1:9000/2

Client configuration:
  servers        : ['http://127.0.0.1:9000/api/2/store/']
  project        : 2
  public_key     : 7c9de9b821244afab1cc9171833a4847
  secret_key     : de5f063137e34b558a69631f24684457

Sending a test message...
success!

その後 Stream を見てみて下さい (更新は不要です)

https://dl.dropboxusercontent.com/u/89936/gist/sentry-django/shiguredo_snowflake_stream_raven_result.png

通知が届いているはずなのでその通知の詳細を見てみましょう。色々情報が取られていることがわかります。

https://dl.dropboxusercontent.com/u/89936/gist/sentry-django/shiguredo_snowflake_stream_raven_result_detail.png

さて、一端一覧に戻ります。今回の通知はテストのため特に問題はありません。そこで問題ないということで「チェック」を入れてみましょう。

https://dl.dropboxusercontent.com/u/89936/gist/sentry-django/shiguredo_snowflake_stream_resolved_result.png

通知が解決されました。ここで 再度 raven test で送ってみましょう。

$ raven test http://7c9de9b821244afab1cc9171833a4847:de5f063137e34b558a69631f24684457@127.0.0.1:9000/2
Using DSN configuration:
  http://7c9de9b821244afab1cc9171833a4847:de5f063137e34b558a69631f24684457@127.0.0.1:9000/2

Client configuration:
  servers        : ['http://127.0.0.1:9000/api/2/store/']
  project        : 2
  public_key     : 7c9de9b821244afab1cc9171833a4847
  secret_key     : de5f063137e34b558a69631f24684457

Sending a test message...
success!
Event ID was 'd4d87970da6e46629b9f20adabf5006a'

https://dl.dropboxusercontent.com/u/89936/gist/sentry-django/shiguredo_snowflake_stream_raven_result_2nd.png

エラーが復活してきました。回数が 2 になっています。ひとまず解決にしておきましょう。

ここまで Sentry のセットアップから確認までをざっと見てきました。

Sentry というシステムに対して何となくイメージつかめたでしょうか。

Django + Raven

Django に Raven を使ってエラートラッカーへのログの転送を追加する。

まずは、 snowflake という django プロジェクトを作るところから

$ django-admin.py startproject snowflake

アプリケーションを作るのがめんどくさいので snowflake 直下に views.py を突っ込む準備

snowflake/urls.py に snowflake.views.home を追加します。

from django.conf.urls import patterns, include, url

urlpatterns = patterns('',
    url(r'^$', 'snowflake.views.home', name='home'),
)

snowflake/views.py を用意して home をとりあえず実装します。

from django.http import HttpResponse

def home(request):
    return HttpResponse('Hello, world!')

その後 snowflake/settings.py に Raven 用の設定を追加しましょう。

RAVEN_CONFIG に設定する dsn は Sentry の Settings タブの API Keys で確認出来ます。

https://dl.dropboxusercontent.com/u/89936/gist/sentry-django/shiguredo_snowflake_settings_api_keys.png

INSTALLED_APPS += (
    'raven.contrib.django.raven_compat',
)

RAVEN_CONFIG = {
    'dsn': 'http://7c9de9b821244afab1cc9171833a4847:de5f063137e34b558a69631f24684457@127.0.0.1:9000/2',
}

LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'root': {
        'level': 'WARNING',
        'handlers': ['sentry'],
    },
    'formatters': {
        'verbose': {
            'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
        },
    },
    'handlers': {
        'sentry': {
            'level': 'ERROR',
            'class': 'raven.contrib.django.raven_compat.handlers.SentryHandler',
        },
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'verbose'
        }
    },
    'loggers': {
        'django.db.backends': {
            'level': 'ERROR',
            'handlers': ['console'],
            'propagate': False,
        },
        'raven': {
            'level': 'DEBUG',
            'handlers': ['console'],
            'propagate': False,
        },
        'sentry.errors': {
            'level': 'DEBUG',
            'handlers': ['console'],
            'propagate': False,
        },
    },
}

設定後、開発サーバを起動します。

$ python manage.py runserver
Validating models...

0 errors found
October 12, 2013 - 10:04:22
Django version 1.5.4, using settings 'snowflake.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
[12/Oct/2013 10:04:28] "GET / HTTP/1.1" 200 12

以下にアクセスして Hello, world! が表示されていることを確認します

http://127.0.0.1:8000/

https://dl.dropboxusercontent.com/u/89936/gist/sentry-django/snowflake_hello_world.png

もちろん Sentry 側にも何も起きていません。コレでは面白くないのでわざと例外を起こしてみましょう。 とりあえず実装してないし!って例外を上げてみることにします。

from django.http import HttpResponse

def home(request):
    raise NotImplementedError
    return HttpResponse('Hello, world!')

再度アクセスしてみます。

http://127.0.0.1:8000/

もちろんエラーです。

https://dl.dropboxusercontent.com/u/89936/gist/sentry-django/snowflake_not_implemented_error.png

さて Sentry をみるとなにやら通知されています。

https://dl.dropboxusercontent.com/u/89936/gist/sentry-django/shiguredo_snowflake_stream_django_not_implemented_error.png

詳細を見てみましょう。DEBUG=True にしている時と同じ情報が表示されます、まぁエラーログなので当たり前ですね。

https://dl.dropboxusercontent.com/u/89936/gist/sentry-django/shiguredo_snowflake_stream_django_not_implemented_error_detail.png

基本的な動作はこれでおしまいです。後は本番サーバからガンガンメッセージを送りつけるだけですね。

ただ、負荷などが色々心配になると思いますので、次からはそれについて書いていきます。

実際 Sentry にもチューニング話がドキュメントに書いてあります。

HTTP ではなく UDP を使う

url:http://sentry.readthedocs.org/en/latest/config/index.html#udp-server

raven から sentry への通信は通常 HTTP ですが、ここを UDP にすることが可能になります。

UDP を使うためには eventlet が必須です。

$ pip install eventlet

また sentry.conf.py へ UDP のホストとポートの設定が必要です。

SENTRY_UDP_HOST = '0.0.0.0'
SENTRY_UDP_PORT = 9001

UDP を使う場合は通常とは別に起動する必要があります。 start の後ろに udp を指定するだけで udp が起動します。

$ sentry --config=sentry.conf.py start udp
Performing upgrade before service startup...
Syncing...
Creating tables ...
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)
Migrating...
Running migrations for djcelery:
- Nothing to migrate.
 - Loading initial data for djcelery.
Installed 0 object(s) from 0 fixture(s)
Running migrations for django:
- Nothing to migrate.
 - Loading initial data for django.
Installed 0 object(s) from 0 fixture(s)
Running migrations for sentry:
- Nothing to migrate.
 - Loading initial data for sentry.
Installed 0 object(s) from 0 fixture(s)
Running migrations for social_auth:
- Nothing to migrate.
 - Loading initial data for social_auth.
Installed 0 object(s) from 0 fixture(s)

Synced:
 > django.contrib.auth
 > django.contrib.admin
 > django.contrib.contenttypes
 > django.contrib.messages
 > django.contrib.sessions
 > django.contrib.sites
 > django.contrib.staticfiles
 > crispy_forms
 > raven.contrib.django.raven_compat
 > sentry.plugins.sentry_interface_types
 > sentry.plugins.sentry_mail
 > sentry.plugins.sentry_urls
 > sentry.plugins.sentry_useragents
 > south

Migrated:
 - djcelery
 - kombu.transport.django
 - sentry
 - social_auth
Running service: 'udp'

dsn は 以下のようになります。UDP 待ち受けポート番号を 9000 から 9001 にしているので注意して下さい。

udp://7c9de9b821244afab1cc9171833a4847:de5f063137e34b558a69631f24684457@127.0.0.1:9001/2

Django 側も、RAVEN_CONFIG の dsn を udp に変更します。

RAVEN_CONFIG = {
    'dsn': 'udp://7c9de9b821244afab1cc9171833a4847:de5f063137e34b558a69631f24684457@127.0.0.1:9001/2',
}

これで準備万端です。先ほどの snowflake を使ってエラーが問題なく通知されているか確認しましょう。

とりあえず Wireshark でのキャプチャ画像を張って UDP の使い方は終わりにします。

https://dl.dropboxusercontent.com/u/89936/gist/sentry-django/sentry_udp_wireshark.png

gevent+http を使う

動作未確認

Raven 側を修正すれば終わりだと思ったので settings.py の RAVEN_CONFIG の dsn のプロトコルを gevent+http にすればいいかと思ったのですが、どうもうまく動いていないようです。

RAVEN_CONFIG = {
    'dsn': 'gevent+http://7c9de9b821244afab1cc9171833a4847:de5f063137e34b558a69631f24684457@127.0.0.1:9000/2',
}

今のところ UDP で問題ないと考えているので、がんばって追う気にもなれず ... 。

どなたか何をすればいいか知っていたら教えて下さい。

Redis をバッファに使う

Sentry と Raven の通信は udp を使っています

バッファは一時的に大量の似たようなリクエストが来た時、データベースの負荷を押さえられます。 まぁ簡単に言えば Redis が一端そのリクエストを受けてくれます。

$ pip install redis hiredis nydus
SENTRY_BUFFER = 'sentry.buffer.redis.RedisBuffer'
SENTRY_REDIS_OPTIONS = {
    'hosts': {
        0: {
            'host': '127.0.0.1',
            'port': 6379,
        }
    }
}

上記の設定を有効にして、エラーを通知してみて、redis の中身を表示させてみました。

redis 127.0.0.1:6379> KEYS *
 1) "sentry.grouptag:lock:1b55bf853089a8f7e4df3f47c28054a2"
 2) "sentry.searchtoken:lock:4a664601aa4381b0e24292904b30c70f"
 3) "sentry.searchtoken:b710b7473e317310210aec964a9f6206:times_seen"
 4) "sentry.tagvalue:lock:625c4c0554854d542326b3f250c94425"
 5) "sentry.groupcountbyminute:lock:8b8557142a27c2a3ca7ca5371eac5e2b"
 6) "sentry.tagvalue:lock:8dd5228dc062b643aa10310cd9fad08a"
 7) "sentry.searchtoken:lock:30e11d925f6ed60a3353a37e4934e52e"
 8) "sentry.searchtoken:lock:0c2085f6e9c4867439c54252f6236eb6"
 9) "sentry.tagvalue:3d057cd3ad10e288a9819ab9259a8191:times_seen"
10) "sentry.tagvalue:lock:4cbedfe394956483479cf23132ec700f"
11) "sentry.tagvalue:2ee31b364bb69967d137b6a89bef9ec0:times_seen"
12) "sentry.grouptag:9f8873e95f976ab181536d77d7da2c13:times_seen"
13) "sentry.groupcountbyminute:8b8557142a27c2a3ca7ca5371eac5e2b:times_seen"
14) "sentry.searchtoken:lock:b710b7473e317310210aec964a9f6206"
15) "sentry.projectcountbyminute:5ee7ff6b561b11f6f4b3d315995d4d2f:times_seen"
16) "sentry.group:681afe34439cf1a3939f032f7bab1dde:times_seen"
17) "sentry.grouptag:lock:b7c5ec7964859c917ba7565f6d22089b"
18) "sentry.searchdocument:681afe34439cf1a3939f032f7bab1dde:total_events"
19) "sentry.searchtoken:f19861c71197145a88cea0a143c15750:times_seen"
20) "sentry.tagvalue:lock:db837530328fca287f5c743717a22b48"
21) "sentry.searchtoken:83e66fa8b9093d42fa279a18a1ef5163:times_seen"
22) "sentry.searchtoken:lock:06889ecc89608a38f7b77d2136c7d750"
23) "sentry.grouptag:7f5cb01296b65fc654fdfd704a5f121d:times_seen"
24) "sentry.searchdocument:lock:681afe34439cf1a3939f032f7bab1dde"
25) "sentry.searchtoken:3c21428b8b20b073e48247d6119d45c6:times_seen"
26) "sentry.grouptag:lock:f05d114feb26f7fdfd001939ad06aa67"
27) "sentry.group:lock:681afe34439cf1a3939f032f7bab1dde"
28) "sentry.grouptag:ee5144235f69994b1934d01ade8c88bc:times_seen"
29) "sentry.searchtoken:30e11d925f6ed60a3353a37e4934e52e:times_seen"
30) "sentry.tagvalue:lock:dae86c8250d926f60ed825d9ca581a10"
31) "sentry.grouptag:707ee13ead4b63ee3fe63c490e772ccd:times_seen"
32) "sentry.projectcountbyminute:lock:5ee7ff6b561b11f6f4b3d315995d4d2f"
33) "sentry.tagvalue:lock:3d057cd3ad10e288a9819ab9259a8191"
34) "sentry.tagvalue:8dd5228dc062b643aa10310cd9fad08a:times_seen"
35) "sentry.searchtoken:lock:83e66fa8b9093d42fa279a18a1ef5163"
36) "sentry.tagvalue:db837530328fca287f5c743717a22b48:times_seen"
37) "sentry.searchtoken:lock:a540504942830228a5cbc89df3a3b257"
38) "sentry.searchtoken:lock:3c21428b8b20b073e48247d6119d45c6"
39) "sentry.tagvalue:dae86c8250d926f60ed825d9ca581a10:times_seen"
40) "sentry.searchtoken:78e1cc6babba33814a8370b062f53908:times_seen"
41) "sentry.searchtoken:lock:78e1cc6babba33814a8370b062f53908"
42) "sentry.searchtoken:lock:200449cb57e2d7f88abae365c8d7ff51"
43) "sentry.grouptag:lock:ee5144235f69994b1934d01ade8c88bc"
44) "sentry.grouptag:lock:7f5cb01296b65fc654fdfd704a5f121d"
45) "sentry.tagvalue:625c4c0554854d542326b3f250c94425:times_seen"
46) "sentry.searchtoken:06889ecc89608a38f7b77d2136c7d750:times_seen"
47) "sentry.searchtoken:lock:f19861c71197145a88cea0a143c15750"
48) "sentry.grouptag:b7c5ec7964859c917ba7565f6d22089b:times_seen"
49) "sentry.tagvalue:e01aa735ab111cc499724d64b615467c:times_seen"
50) "sentry.grouptag:8d44de0934d0830fe63da65930f4560b:times_seen"
51) "sentry.grouptag:lock:707ee13ead4b63ee3fe63c490e772ccd"
52) "sentry.grouptag:lock:8d44de0934d0830fe63da65930f4560b"
53) "sentry.tagvalue:lock:e01aa735ab111cc499724d64b615467c"
54) "sentry.searchtoken:0c2085f6e9c4867439c54252f6236eb6:times_seen"
55) "sentry.searchtoken:a540504942830228a5cbc89df3a3b257:times_seen"
56) "sentry.grouptag:f05d114feb26f7fdfd001939ad06aa67:times_seen"
57) "sentry.searchtoken:6b43676b1625732caccd13fb0789667c:times_seen"
58) "sentry.grouptag:lock:9f8873e95f976ab181536d77d7da2c13"
59) "sentry.searchtoken:200449cb57e2d7f88abae365c8d7ff51:times_seen"
60) "sentry.tagvalue:4cbedfe394956483479cf23132ec700f:times_seen"
61) "sentry.searchtoken:4a664601aa4381b0e24292904b30c70f:times_seen"
62) "sentry.tagvalue:lock:2ee31b364bb69967d137b6a89bef9ec0"
63) "sentry.searchtoken:lock:6b43676b1625732caccd13fb0789667c"
64) "sentry.grouptag:1b55bf853089a8f7e4df3f47c28054a2:times_seen"

バッファが有効になっていることが確認出来ました。エラーはスパイクで来ることが多そうなのでこの設定あはとても有効そうですね。

Redis をキャッシュに使う

Sentry と Raven の通信は udp を使っています

Sentry にはもともとキャッシュ機能があり、Memcached 機能があるのですが Redis で統一したいよねということで Redis を使うという例です。

デフォルトはこうなっていますが、ここを redis を使うように書き換えます。

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': ['127.0.0.1:11211'],
    }
}

redis を django の Cache として使うために django-redis-cache をインストールします。

url:https://github.com/sebleier/django-redis-cache
$ pip install django-redis-cache hiredis

ポート番号はデフォルトです。

CACHES = {
    'default': {
        'BACKEND': 'redis_cache.RedisCache',
        'LOCATION': '127.0.0.1:6379',
        'OPTIONS': {
            'DB': 1,
            'PARSER_CLASS': 'redis.connection.HiredisParser'
        },
    },
}

redis を起動して cli で中身を見てみます。

$ redis-server
$ redis-cli -n 1

# 初期状態

redis 127.0.0.1:6379[1]> KEYS *
1) ":1:filterkey:all:2"
2) ":1:modelcache:Team:0b30ef0e4bad967092d5c6fac5a82d3a"
3) ":1:modelcache:Team:e2434c3e4540e3b17e55fd342499410c"

# ここで一回イベントを飛ばしている

redis 127.0.0.1:6379[1]> KEYS *
1) ":1:modelcache:Team:e2434c3e4540e3b17e55fd342499410c"
2) ":1:modelcache:Team:0b30ef0e4bad967092d5c6fac5a82d3a"
3) ":1:modelcache:ProjectKey:4720421b15c5ac28c9c5e0a4490bcf21"
4) ":1:modelcache:ProjectKey:0b30ef0e4bad967092d5c6fac5a82d3a"
5) ":1:filterkey:all:2"
6) ":1:modelcache:ProjectKey:87cf28442df0b8dee2c05c17cded614e"
7) ":1:modelcache:Project:0b30ef0e4bad967092d5c6fac5a82d3a"
8) ":1:modelcache:Project:f4529ed6f3d5507f4c14e15ebe4102d1"

正常にキャッシュされていることが確認出来ました。

Celery (Redis) を使う

Sentry と Raven の通信は udp を使っています

Sentry からデータベースに書く際に即座に書くのでは無く一端 Queue を経由して書くようにします。 コレを使う事でデータベースに一気に負荷が行かないようにします。

url:http://sentry.readthedocs.org/en/latest/queue/

celery が必要なのでその辺インストールが必要です。Queue には Redis を使用します。

$ pip install celery redis

sentry.conf.py にて以下の二行を設定します。

CELERY_ALWAYS_EAGER = False
BROKER_URL = 'redis://127.0.0.1:6379/2'

その後 sentry コマンド経由で celery を起動します。 表示される config を確認して無事動作していることを確認して下さい。

$ sentry --config=sentry.conf.py celery worker -B

 -------------- celery@example.com v3.0.23 (Chiastic Slide)
---- **** -----
--- * ***  * -- Darwin-12.5.0-x86_64-i386-64bit
-- * - **** ---
- ** ---------- [config]
- ** ---------- .> broker:      redis://127.0.0.1:6379/2
- ** ---------- .> app:         default:0x109812550 (djcelery.loaders.DjangoLoader)
- ** ---------- .> concurrency: 4 (processes)
- *** --- * --- .> events:      OFF (enable -E to monitor this worker)
-- ******* ----
--- ***** ----- [queues]
 -------------- .> alerts:      exchange:default(direct) binding:alerts
                .> celery:      exchange:default(direct) binding:celery
                .> cleanup:     exchange:default(direct) binding:cleanup
                .> counters:    exchange:default(direct) binding:counters
                .> default:     exchange:default(direct) binding:default
                .> events:      exchange:default(direct) binding:events
                .> search:      exchange:default(direct) binding:search
                .> sourcemaps:  exchange:default(direct) binding:sourcemaps
                .> triggers:    exchange:default(direct) binding:triggers
                .> update:      exchange:default(direct) binding:update

[2013-10-14 10:18:05,216: WARNING/MainProcess] celery@example.com ready.

redis が使われているかを redis-cli を使って確認します。 問題なく動作していることが確認出来ました。

$ redis-cli -n 2
redis 127.0.0.1:6379[2]> KEYS *
1) "_kombu.binding.celery.pidbox"
2) "_kombu.binding.default"
@aolmaillogin
Copy link

Very interesting blog. Alot of blogs I see these days don't really provide anything that I'm interested in, but I'm most definately interested in this one. Just thought that I would post and let you know.
list of emoticons

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment