Перед тим як зайти в глибоке святкування Нового Року вирішив написати два поста, один технічний, а інший про результати 2009 року. Тож щодо технічного, то одна з найважливішої функції в будь-якій системі - є її моніторинг - можливість бачити що де й як проходить, чи бувають помилки і якщо так, то де саме. Поскільки я програмую на Пітоні й Джанго, то мова буде саме про цею парочку.
Отще в Пітоні є чудернатський модуль logging, що дає можливість логувати різні за типом події. Найпростіша робота з ним це:
import logging
logging.info('info message')
logging.error('error messaqge')Найпростіший спосіб, але я його не юзаю, бо не дуже прикольно працювати зі стандартним потоком повідомлень, а краще юзати окремий, щоб чужі модуля не могли до нього нічого писати:
import logging
log = logging.getLogger('log')
log.error('error messaqge')Тепер в нас є власний потік повідомленнів, але крім того що він є, його треба й виводити кудись, зберігати, то для цього на нього навішуються різні обробники. Ось наприклад навісим, що все виводилось в консоль:
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
stream_handler = logging.StreamHandler(sys.stdout)
stream_handler.setFormatter(formatter)
stream_handler.setLevel(logging.DEBUG)
log.addHandler(stream_handler)Відмітемо, що ми встановили форматування тексту, а також уровень повідомлень розпочинаючи з яких хочемо бачити в системі.
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
stream_handler = logging.StreamHandler(sys.stdout)
stream_handler.setFormatter(formatter)
stream_handler.setLevel(logging.DEBUG)
log.addHandler(stream_handler)Крім стандартних обробників, можемо написати ще й свій, наприклад я часто добавляю запис інфи в базу, ось так я ініціалізую обробник:
db_handler = DbHandler()
db_handler.setFormatter(formatter)
db_handler.setLevel(logging.INFO)
log.addHandler(db_handler)Сам код обьекту по оброці наступний:
from logging import Handler
from dblogging.models import DbLogging
class DbHandler(Handler):
def __init__(self):
Handler.__init__(self)
def emit(self, record):
try:
msg = record.msg.split('$')
try:
c = msg[0].strip()
except:
c = ''
try:
t = msg[1].strip()
except:
t = ''
DbLogging(
level=record.levelno,
path=record.pathname,
line=record.lineno,
message_class=c,
message_text=t,
).save()dblogging - це Джанговський модуль, що складається з однієї моделі і "адмінки":
#models.py
from django.db import models
class DbLogging(models.Model):
time_add = models.DateTimeField(auto_now_add=True)
level = models.IntegerField()
path = models.CharField(max_length=200)
line = models.IntegerField()
message_class = models.CharField(max_length=200)
message_text = models.CharField(max_length=200)
def __unicode__(self):
return "%s %s %s" % (self.time_add, self.message_class, self.message_text)
#admin.py
from django.contrib import admin
from avcheck.dblogging.models import DbLogging
class DbLoggingAdmin(admin.ModelAdmin):
list_display = ('time_add', 'level', 'message_class', 'message_text', )
list_filter = ('level', 'time_add', )
admin.site.register(DbLogging, DbLoggingAdmin)Ще одну цікаву ідею можете побачити, це те що логування йде подій, що складаються з класу події і повідомлення:
logging.info("REGISTER USER$ email@email.com")Тоесть я потом могу класс события заношу в одно поле в БД, а само описание в другое. И таким образом смогу потом видеть статистику сколько человек регистрировалось за неделю. А если нужно просмотрю кто именно регистрировался. Вот такой маленький финт, который я подсмотрел в одного очень крутого программера.
Там еще декілька ньансів, але ж не буду я все детально пояснювати, нехай і вас буде якась проблемка, яку вирішите її і будете раді цій маленькій перемозі. Хоча хай пізніше, цю систему оформлю гарно і повністю викладу кудись в інтернеті.



Comments
Post new comment