Логування в Python

24 Грудня 2009

Перед тим як зайти в глибоке святкування Нового Року вирішив написати два поста, один технічний, а інший про результати 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")

Тоесть я потом могу класс события заношу в одно поле в БД, а само описание в другое. И таким образом смогу потом видеть статистику сколько человек регистрировалось за неделю. А если нужно просмотрю кто именно регистрировался. Вот такой маленький финт, который я подсмотрел в одного очень крутого программера.

Там еще декілька ньансів, але ж не буду я все детально пояснювати, нехай і вас буде якась проблемка, яку вирішите її і будете раді цій маленькій перемозі. Хоча хай пізніше, цю систему оформлю гарно і повністю викладу кудись в інтернеті.

 
 
 
Роман Хоменко aka PresidentUA
mail/jabber: spirt40@gmail.com