Очередной скучный доклад про логгирование

1,045 views
884 views

Published on

Стас Рудаков, компания СООО "Гейм Стрим"/Wargaming.net

Значение логов очень часто недооценивается, а зря. Доклад с оживленным диспутом со всеми участниками митапа, чтобы разобраться: как, куда и зачем писать логи. Помимо этого затронут вопрос, как из логов выжать больше информации.

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,045
On SlideShare
0
From Embeds
0
Number of Embeds
32
Actions
Shares
0
Downloads
18
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Очередной скучный доклад про логгирование

  1. 1. ОЧЕРЕДНОЙ СКУЧНЫЙ ДОКЛАД ПРО ЛОГГИРОВАНИЕ Стас Рудаков
  2. 2. Эпиграф Невозможно объять необъятное. Козьма Прутков Про логгирование, Стас Рудаков
  3. 3. Про что будем говорить? Про логгирование, Стас Рудаков
  4. 4. Про что будем говорить? Про логгирование, там же было написано :) Про логгирование, Стас Рудаков
  5. 5. Про что будем говорить? Про логгирование, там же было написано :) А именно: зачем; как; проблемы; очевидные пути решения; неочевидные пути решения; open source инструменты. Про логгирование, Стас Рудаков
  6. 6. Что вообще значит “записать в лог”? Про логгирование, Стас Рудаков
  7. 7. Что вообще значит “записать в лог”? сформировать сообщение Про логгирование, Стас Рудаков
  8. 8. Что вообще значит “записать в лог”? сформировать сообщение по некому событию Про логгирование, Стас Рудаков
  9. 9. Что вообще значит “записать в лог”? сформировать сообщение по некому событию и, если это сообщение нас вообще интересует, Про логгирование, Стас Рудаков
  10. 10. Что вообще значит “записать в лог”? сформировать сообщение по некому событию и, если это сообщение нас вообще интересует, записать или отправить его куда-то, Про логгирование, Стас Рудаков
  11. 11. Что вообще значит “записать в лог”? сформировать сообщение по некому событию и, если это сообщение нас вообще интересует, записать или отправить его куда-то, куда имеют доступ заинтересованные лица. Про логгирование, Стас Рудаков
  12. 12. Зачем Debug Разбор инцидентов Про логгирование, Стас Рудаков
  13. 13. Зачем Debug Разбор инцидентов Сбор статистики Средне- и долгосрочный мониторинг Инструмент для службы поддержки пользователей Аналитика Про логгирование, Стас Рудаков
  14. 14. import logging Про логгирование, Стас Рудаков
  15. 15. Писать логи очень просто 1 import logging 2 3 4 5 6 7 logging . basicConfig ( format = ’ [%( asctime ) s ][%( levelname ) s ][%( name ) s ] %( message ) s ’ , stream = sys . stdout , level = logging . INFO ) 8 9 10 logger = logging . getLogger ( " meetup . python . minsk " ) logger . info ( " Stas has just started the talk on logging " ) Про логгирование, Стас Рудаков
  16. 16. Писать логи очень просто 1 import logging 2 3 4 5 6 7 logging . basicConfig ( format = ’ [%( asctime ) s ][%( levelname ) s ][%( name ) s ] %( message ) s ’ , stream = sys . stdout , level = logging . INFO ) 8 9 10 1 logger = logging . getLogger ( " meetup . python . minsk " ) logger . info ( " Stas has just started the talk on logging " ) [2014 -01 -31 06:23:27 ,904][ INFO ][ meetup . python . minsk ] Stas has just started the talk on logging Про логгирование, Стас Рудаков
  17. 17. logging: архитектура на пальцах сформировать сообщение по некому событию и, если это сообщение нас вообще интересует, записать или отправить его куда-то, куда имеют доступ заинтересованные лица. Про логгирование, Стас Рудаков
  18. 18. Про логгирование, Стас Рудаков
  19. 19. Про логгирование, Стас Рудаков
  20. 20. Про логгирование, Стас Рудаков
  21. 21. Про логгирование, Стас Рудаков
  22. 22. Про логгирование, Стас Рудаков
  23. 23. Конфигурация 1 2 3 4 5 6 7 8 9 10 11 12 13 CFG = { ’ formatters ’: { ’ simple ’: { ’ format ’: ’ %( asctime ) s %( message ) s ’} ,} , ’ filters ’: { ’ pwd ’: { ’ () ’: ’ proj . PwdFilter ’ , ’ foo ’: ’ bar ’ ,} ,} , ’ handlers ’: { ’ console ’ :{ ’ level ’: ’ DEBUG ’ , ’ class ’: ’ logging . ’ ’ StreamHandler ’ , ’ formatter ’: ’ simple ’} , Про логгирование, Стас Рудаков 14 15 16 17 18 19 20 21 22 23 24 25 26 27 ’ mail_adm ’: { ’ level ’: ’ ERROR ’ , ’ class ’: ’ proj . ’ ’ Admi nEmailHa ndler ’ , ’ filters ’: [ ’ pwd ’ ]} ,} , ’ loggers ’: { ’ ’: { ’ handlers ’: [ ’ console ’] , ’ level ’: ’ INFO ’ , ’ filters ’: [ ’ pwd ’]} , ’ django . request ’: { ’ handlers ’: [ ’ mail_adm ’] , ’ level ’: ’ ERROR ’ , ’ propagate ’: False ,} ,} ,} logging . config . dictConfig ( CFG )
  24. 24. tips n tricks: уровни логгирования Про логгирование, Стас Рудаков
  25. 25. tips n tricks: уровни логгирования CRITICAL = 50 logger.critical(u’проблема, после которой приложение не может восстановиться без постороннего вмешательства’) Про логгирование, Стас Рудаков
  26. 26. tips n tricks: уровни логгирования CRITICAL = 50 logger.critical(u’проблема, после которой приложение не может восстановиться без постороннего вмешательства’) ERROR = 40 logger.error(u’проблема, из-за которой приложение работает не в штатном режиме’) Про логгирование, Стас Рудаков
  27. 27. tips n tricks: уровни логгирования CRITICAL = 50 logger.critical(u’проблема, после которой приложение не может восстановиться без постороннего вмешательства’) ERROR = 40 logger.error(u’проблема, из-за которой приложение работает не в штатном режиме’) WARNING = 30 # уровень по умолчанию logger.warning(u’проблема, которая не мешает работе приложения, но на которую стоит обратить внимание’) Про логгирование, Стас Рудаков
  28. 28. tips n tricks: уровни логгирования CRITICAL = 50 logger.critical(u’проблема, после которой приложение не может восстановиться без постороннего вмешательства’) ERROR = 40 logger.error(u’проблема, из-за которой приложение работает не в штатном режиме’) WARNING = 30 # уровень по умолчанию logger.warning(u’проблема, которая не мешает работе приложения, но на которую стоит обратить внимание’) INFO = 20 logger.info(u’обычная запись в лог’) Про логгирование, Стас Рудаков
  29. 29. tips n tricks: уровни логгирования CRITICAL = 50 logger.critical(u’проблема, после которой приложение не может восстановиться без постороннего вмешательства’) ERROR = 40 logger.error(u’проблема, из-за которой приложение работает не в штатном режиме’) WARNING = 30 # уровень по умолчанию logger.warning(u’проблема, которая не мешает работе приложения, но на которую стоит обратить внимание’) INFO = 20 logger.info(u’обычная запись в лог’) DEBUG = 10 logger.debug(u’логи, которые помогли нам при отладке приложения и которые вряд ли пригодятся в будущем’) Про логгирование, Стас Рудаков
  30. 30. tips n tricks: traceback 1 try : 2 do_ s o me t hi n g_ u n sa f e () except Exception as e : logger . exception ( ’ Unexpected exception ’) raise 3 4 5 Про логгирование, Стас Рудаков
  31. 31. tips n tricks: traceback 1 try : 2 do_ s o me t hi n g_ u n sa f e () except Exception as e : logger . exception ( ’ Unexpected exception ’) raise 3 4 5 В лог отправится: 1 2 3 4 5 6 7 8 9 [2014 -01 -29 23:35:04 ,393][ examples ][ ERROR ] Unexpected exception Traceback ( most recent call last ) : File " stacktrace1 . py " , line 22 , in < module > d o_ s o me t hi n g_ u n sa f e () File " stacktrace1 . py " , line 18 , in do _ so m e th i ng _ u ns a fe down_rabbit_hole () File " stacktrace1 . py " , line 17 , in down_rabbit_hole sender = message . sender AttributeError : ’ NoneType ’ object has no attribute ’ sender ’ Про логгирование, Стас Рудаков
  32. 32. tips n tricks: traceback 1 try : 2 validate_data ( data ) except ValidationError as e : logger . exception ( ’ Validation failed ’) 3 4 А в лог запишется 1 2 3 4 5 6 7 8 9 [2014 -01 -29 08:33:53 ,439][ examples ][ ERROR ] Validation failed Traceback ( most recent call last ) : File " stacktrace2 . py " , line 27 , in < module > validate_data ( data ) File " stacktrace2 . py " , line 22 , in validate_data check_values ( data ) File " stacktrace2 . py " , line 21 , in check_values raise ValidationError ( ’ security key is missing ’) ValidationError : security key is missing Про логгирование, Стас Рудаков
  33. 33. tips n tricks: traceback 1 try : 2 validate_data ( data ) except ValidationError as e : logger . exception ( ’ Validation failed ’) 3 4 А в лог запишется 1 2 3 4 5 6 7 8 9 [2014 -01 -29 08:33:53 ,439][ examples ][ ERROR ] Validation failed Traceback ( most recent call last ) : File " stacktrace2 . py " , line 27 , in < module > validate_data ( data ) File " stacktrace2 . py " , line 22 , in validate_data check_values ( data ) File " stacktrace2 . py " , line 21 , in check_values raise ValidationError ( ’ security key is missing ’) ValidationError : security key is missing Но разве уровень ERROR нам подходит? Про логгирование, Стас Рудаков
  34. 34. tips n tricks: traceback 1 try : 2 validate_data ( data ) except ValidationError as e : logger . warning ( ’ Validation failed ’ , exc_info = True ) 3 4 Получаем 1 2 3 4 5 6 7 8 9 [2014 -01 -29 08:33:53 ,439][ examples ][ WARNING ] Validation failed Traceback ( most recent call last ) : File " stacktrace2 . py " , line 27 , in < module > validate_data ( data ) File " stacktrace2 . py " , line 22 , in validate_data check_values ( data ) File " stacktrace2 . py " , line 21 , in check_values raise ValidationError ( ’ security key is missing ’) ValidationError : security key is missing Про логгирование, Стас Рудаков
  35. 35. tips n tricks: “ленивое” форматирование 1 2 3 logger . info ( ’ Request id =% s message =% r ’ % (100500 , { ’ event ’: ’ meetup ’ }) ) Про логгирование, Стас Рудаков
  36. 36. tips n tricks: “ленивое” форматирование 1 2 3 logger . info ( ’ Request id =% s message =% r ’ % (100500 , { ’ event ’: ’ meetup ’ }) ) Зачем форматировать строку, если мы не знаем, попадет ли она в лог? Про логгирование, Стас Рудаков
  37. 37. tips n tricks: “ленивое” форматирование 1 2 3 logger . info ( ’ Request id =% s message =% r ’ % (100500 , { ’ event ’: ’ meetup ’ }) ) Зачем форматировать строку, если мы не знаем, попадет ли она в лог? 1 2 3 logger . info ( ’ Request id =% s message =% r ’ , 100500 , { ’ event ’: ’ meetup ’} ) Про логгирование, Стас Рудаков
  38. 38. tips n tricks: “ленивое” форматирование 1 2 3 logger . info ( ’ Request id =% s message =% r ’ % (100500 , { ’ event ’: ’ meetup ’ }) ) Зачем форматировать строку, если мы не знаем, попадет ли она в лог? 1 2 3 logger . info ( ’ Request id =% s message =% r ’ , 100500 , { ’ event ’: ’ meetup ’} ) *args работают, **kwargs не работают Про логгирование, Стас Рудаков
  39. 39. tips n tricks: ротация в один прекрасный день. . . Про логгирование, Стас Рудаков
  40. 40. tips n tricks: ротация в один прекрасный день. . . no space left on device Про логгирование, Стас Рудаков
  41. 41. tips n tricks: ротация в один прекрасный день. . . no space left on device from logging.handlers import * 1 2 3 4 5 1 2 3 4 5 Rotating Fi l eH a n dl e r ( filename , mode = ’a ’ , maxBytes =0 , backupCount =0 , encoding = None , delay = False ) $ ls logs meetup . log meetup . log .1 meetup . log .2 meetup . log .3 Про логгирование, Стас Рудаков
  42. 42. tips n tricks: ротация в один прекрасный день. . . no space left on device from logging.handlers import * 1 2 3 4 5 1 2 3 4 5 Rotating Fi l eH a n dl e r ( filename , mode = ’a ’ , maxBytes =0 , backupCount =0 , encoding = None , delay = False ) 1 $ ls logs meetup . log meetup . log .1 meetup . log .2 meetup . log .3 1 Про логгирование, Стас Рудаков 2 3 4 5 2 3 4 5 T i m e d Ro t a t i n g F i l e H a n d l e r ( filename , when = ’h ’ , interval =1 , backupCount =0 , encoding = None , delay = False , utc = False ) $ ls logs meetup . log meetup . log .2014 -01 -31 _17 meetup . log .2014 -01 -31 _18 meetup . log .2014 -01 -31 _19
  43. 43. tips n tricks: ротация в один прекрасный день. . . no space left on device from logging.handlers import * 1 2 3 4 5 1 2 3 4 5 Rotating Fi l eH a n dl e r ( filename , mode = ’a ’ , maxBytes =0 , backupCount =0 , encoding = None , delay = False ) 1 $ ls logs meetup . log meetup . log .1 meetup . log .2 meetup . log .3 1 2 3 4 5 2 3 4 5 T i m e d Ro t a t i n g F i l e H a n d l e r ( filename , when = ’h ’ , interval =1 , backupCount =0 , encoding = None , delay = False , utc = False ) $ ls logs meetup . log meetup . log .2014 -01 -31 _17 meetup . log .2014 -01 -31 _18 meetup . log .2014 -01 -31 _19 Если варианты выше не подходят, можно использовать утилиту logrotate и 1 Wa tc he dFi le Ha ndl er ( fname , mode = ’a ’ , encoding = None , delay = False ) Про логгирование, Стас Рудаков
  44. 44. Sentry getsentry.com Про логгирование, Стас Рудаков
  45. 45. Sentry - это. . . open source аггрегатор сообщений об ошибках, написанный на Python + Django + Celery, с клиентами для многих языков и платформ. Про логгирование, Стас Рудаков
  46. 46. Про логгирование, Стас Рудаков
  47. 47. Sentry: как подключить 1 2 3 from raven . handlers . logging import SentryHandler handler = SentryHandler ( ’ http :// public : secret@example . com /1 ’ , level = logging . WARNING ) Про логгирование, Стас Рудаков
  48. 48. Sentry: как подключить 1 2 3 4 5 from raven . handlers . logging import SentryHandler handler = SentryHandler ( ’ http :// public : secret@example . com /1 ’ , level = logging . WARNING ) logger = logging . getLogger ( ’ coffeemaker ’) logger . addHandler ( handler ) Про логгирование, Стас Рудаков
  49. 49. Sentry: как подключить 1 2 3 4 5 6 7 from raven . handlers . logging import SentryHandler handler = SentryHandler ( ’ http :// public : secret@example . com /1 ’ , level = logging . WARNING ) logger = logging . getLogger ( ’ coffeemaker ’) logger . addHandler ( handler ) logger . warning ( ’ We are running out of milk ’) logger . error ( ’ Not enough milk for a cappuccino ’) Про логгирование, Стас Рудаков
  50. 50. Sentry: как подключить 1 2 3 4 5 6 7 from raven . handlers . logging import SentryHandler handler = SentryHandler ( ’ http :// public : secret@example . com /1 ’ , level = logging . WARNING ) logger = logging . getLogger ( ’ coffeemaker ’) logger . addHandler ( handler ) logger . warning ( ’ We are running out of milk ’) logger . error ( ’ Not enough milk for a cappuccino ’) HTTP? Cерьезно? Про логгирование, Стас Рудаков
  51. 51. А теперь давайте вспомним, что мы с этими логами собирались делать Debug Разбор инцидентов Про логгирование, Стас Рудаков
  52. 52. А теперь давайте вспомним, что мы с этими логами собирались делать Debug Разбор инцидентов Сбор статистики Средне- и долгосрочный мониторинг Инструмент для службы поддержки пользователей Аналитика Про логгирование, Стас Рудаков
  53. 53. Назад в будущее Современные вызовы: хотим убедиться, что логи не были модифицированы злоумышленником после взлома; переходим от программ к сложным распределенным системам — хочется иметь логгирование уровня всей системы, а не отдельных приложений; быстрый поиск; метрики. Про логгирование, Стас Рудаков
  54. 54. elasticsearch elasticsearch.org Про логгирование, Стас Рудаков
  55. 55. elasticsearch - это. . . распределенный полнотекстовый поисковый движок Про логгирование, Стас Рудаков
  56. 56. elasticsearch - это. . . распределенный полнотекстовый поисковый движок c RESTful web-интерфейсом, с документами без схемы и возможностями аггрегации документов. Про логгирование, Стас Рудаков
  57. 57. elasticsearch - это. . . распределенный полнотекстовый поисковый движок c RESTful web-интерфейсом, с документами без схемы и возможностями аггрегации документов. Написан на Java с использованием библиотеки Apache Lucene. Используется в Mozilla, GitHub и многих других компаниях (если вам нужно убедить своего менеджера). Про логгирование, Стас Рудаков
  58. 58. elasticsearch - это. . . распределенный полнотекстовый поисковый движок c RESTful web-интерфейсом, с документами без схемы и возможностями аггрегации документов. Написан на Java с использованием библиотеки Apache Lucene. Используется в Mozilla, GitHub и многих других компаниях (если вам нужно убедить своего менеджера). Но как связать логгирование и elasticsearch? Про логгирование, Стас Рудаков
  59. 59. logstash logstash.net Про логгирование, Стас Рудаков
  60. 60. Про логгирование, Стас Рудаков
  61. 61. logstash + elasticsearch + kibana = nice web UI Про логгирование, Стас Рудаков
  62. 62. structlog — последний ингридиент 1 2 3 4 5 6 >>> from structlog import get_logger >>> log = get_logger () >>> log = log . bind ( user = ’ anonymous ’ , some_key =23) >>> log = log . bind ( user = ’ hynek ’ , another_key =42) >>> log . info ( ’ user . logged_in ’ , happy = True ) some_key =23 user = ’ hynek ’ another_key =42 happy = True event = ’ user . logged_in ’ http://www.structlog.org/ Про логгирование, Стас Рудаков
  63. 63. Что мы не объяли? Syslog Protocol Логи в реляционной базе данных journald logplex, fluentd Агенты для сбора логов Что, собственно, писать в логи. Про логгирование, Стас Рудаков
  64. 64. Выводы Батарейка logging вполне подходит для 95% случаев1 . 1 По статистике, не стоит доверять 75% статистики Про логгирование, Стас Рудаков
  65. 65. Выводы Батарейка logging вполне подходит для 95% случаев1 . Архитектуры систем логгирования похожи как на микро, так и на макро уровне. 1 По статистике, не стоит доверять 75% статистики Про логгирование, Стас Рудаков
  66. 66. Выводы Батарейка logging вполне подходит для 95% случаев1 . Архитектуры систем логгирования похожи как на микро, так и на макро уровне. Open source инструменты помогают выжать из логов очень много полезных свойств. 1 По статистике, не стоит доверять 75% статистики Про логгирование, Стас Рудаков
  67. 67. Выводы Батарейка logging вполне подходит для 95% случаев1 . Архитектуры систем логгирования похожи как на микро, так и на макро уровне. Open source инструменты помогают выжать из логов очень много полезных свойств. Я вас всех порядочно утомил. 1 По статистике, не стоит доверять 75% статистики Про логгирование, Стас Рудаков
  68. 68. СПАСИБО ЗА ВНИМАНИЕ. ВОПРОСЫ? Стас Рудаков mailto:stas@garage22.net https://raw.github.com/nott/talks/logging.pdf http://docs.python.org/3/library/logging.html http://www.structlog.org/ https://www.getsentry.com/ http://logstash.net/

×