
Artem
05.07.2017
17:17:55
Может, у тебя столько данных, что тебе больше ничего не надо

Nikolay
05.07.2017
17:18:14
эластик хорош, рекомендую
для него есть aioes

b0g3r
05.07.2017
17:18:27
grep и fs - хорошо, но файл одновременно может относиться к десяти категориям, например, и файловая система это никак не отразит

Google

Artem
05.07.2017
17:18:42
ну это я говорю про фулл-текст серч

b0g3r
05.07.2017
17:19:01
понял тебя
не, хочется красивенько

Artem
05.07.2017
17:19:06
А категории можно в любой бд хранить

Python'ер
05.07.2017
17:30:52
А можно почитать где-нибудь на русском про logging? А то лень разбирать на английском, но конечно если других вариантов нет то почитаю и так.

stonepig
05.07.2017
17:31:01
конечно

Python'ер
05.07.2017
17:31:17
Где?


stonepig
05.07.2017
17:31:18
зарт где-то лекцию писал целую
щас в личку скину
не в личку,а сюда
#zart #loggging
логгинг состоит из пачки классов:
логгер Logger - источник сообщений. тот класс, у которого есть метод log, который шлёт сообщение в логгер с указанными данными и приоритетом.
у него так же есть вспомогательные методы debug/fatal/critical/info/warn/warning/error/exception, которые вызывают log с указанным уровнем.
Этот метод создает LogRecord объект, который содержит информацию о сообщении,его аргументах, отладочной инфе и экстра данных.
у логгера есть уровень (getLevel/setLevel методы), который может отфильтровать сообщения еще перед их отправкой - т.е. если у логгера например уровень ошибок, то отладочные сообщения и ворнинги будут проигнорированы сразу.
имена логгеров разделяются точками и имеют иерархию - например, отправка сообщений в myprogram.engine.mysql будет проходить по логгерам myprogram.engine.mysql, myprogram.engine, myprogram, root.
У логгера есть аттрибут propagate, по умолчанию равный True, который можно переключить в False, если нужно отключить всплытие по иерархии.
Логгеры являются синглетонами, изначально есть лишь один рутовый, с пустым '' именем. Когда программа дергает логгер через logging.getLogger, возвращается уже существующий экземпляр логгера, если есть, или создается новый (а также промежуточные выше).
Поэтому если хочется разные части программы логгировать по разному - необходимо задавать разные имена.
К каждому логгеру можно прикрепить 0 и более хендлеров. Это классы, производные от LogHandler, которые занимаются доставкой сообщений.
Тут есть и запись в файлы/потоки напрямую, или с ротацией по времени/размеру, со сжатием и без, в сеть, в сислог, в ивентлог, в базы данных, и многое другое.
Можно создавать собственные хендлеры для своих нужд.
У каждого хендлера тоже есть уровень, с помощью которого можно фильтровать сообщения по их уровню перед записью.
К хендлеру привязан форматтер - класс, который хавает логрекорд и конвертирует его в строку текста для финальной записи (стандартный форматтер еще имеет и строку форматирования времени).
В двойке форматтер умел конвертировать лишь %(name)s строки, в тройке добавили варианты с новым '{name}' форматом.
Использование:
Из обзора выше видно что всё это богатство можно поделить на две части:
для программистов (библиотек и кода вообще) - часть, занимающаяся отправкой.
для администраторов/конечных пользователей - часть, настраивающая доставку.
как применять логгинг в типичном коде - получить логгер, и отправить в него сообщение:
import logging
# использование имени модуля для логов очень популярная техника
# очень хорошо работает когда исходники выстроены в стройную иерархию
log = logging.getLogger(__name__)
def foo(x):
log.debug('отладочная инфа...', bar, baz)
...
try:
fuckup(x)
except SomeError as e:
log.exception('Shit happens') # exception вызывает log(..., exc_info=True),
# который сохраняет исключение и трейсбак в логрекорде
class Foo:
log = logging.getLogger('Foo') # иногда логгеры объявляются на уровне класса
def method(self):
self.log.warn('Deprecated method "method"')
...
class Bar:
def __init__(self):
self.log = logging.getLogger('Bar') # можно на уровне инстанса
self.log.debug('Bar.__init__(%r)', self)
def demo(self):
log = logging.getLogger('Bar') # а можно создавать по необходимости
log.critical('MAYDAY')
Настройка:
Примеры кода выше - это то, как вшить в программу генерацию логов.
Теперь встает вопрос, как настроить собсно их вывод. Из описания выше, очевидно, что самый простой способ - это задать один хендлер у рутового логгера, который будет ловить все сообщений и выводить их на экран/файл.
Именно это и делает logging.basicConfig - задает рутовому логгеру один хендлер, либо для вывода в консоль, либо в указанный файл.
Он также проверяет, было ли логгирование уже настроено, и если да, то оно не делает ничего. Поэтому вызывать basicConfig можно сколько влезет, но сработает лишь первый вызов.
Для более гибкой настройки логгинга есть модуль logging.config с пачкой методов, которые занимаются созданием хендлеров и прикручиванием их к логгерам.
Это logging.config.fileConfig, который настраивает логи через конфиг в ini-файле,
logging.config.dictConfig, настраивающий логгинг через дикт, и
logging.config.listen, который умеет открывать tcp-порт и слушать команды на реконфигурацию логов на ходу и по командам через сеть.

Google

stonepig
05.07.2017
17:31:55
Важные аспекты:
Логгеры - синглетоны.
Все настройки логгеров и хендлеров глобальны на уровне процесса.
Нельзя настроить разный логгинг в разных тредах.
Реконфигурация через fileConfig НЕ УДАЛЯЕТ старых хендлеров, но по дефолту их отключает.
По этой причине я б не рекомендовал заниматься реконфигурацией логгинга на ходу, по возможности.
Логгинг тредсейф, так что можно смело ебашить вызовы логгеров куда попало.
Конфигурацию логгинга должны делать ТОЛЬКО программы и делать это на запуске.
Прочий код, библиотеки и фреймворки обычно должны довольствоваться лишь логгерами.
Я не упомянул еще ряда мелочей - подробности в документации и коде.

Python'ер
05.07.2017
17:32:20
Спасибо!

Denis
05.07.2017
19:18:16
О, Игорь

ultranoise ?
05.07.2017
19:24:55
кто то трогал MasterPass?

Дмитрий
05.07.2017
19:25:15
а как правильно и модно смотреть логи? а то я через tail -f смотрю как дедушка, а хочется гуй красивый

Igor
05.07.2017
19:26:13
это если скорее все-таки логи об ошибках

Дмитрий
05.07.2017
19:26:48
хм, я туда сейчас unhandeled exceptions засылаю

Igor
05.07.2017
19:26:49
подключается с полпинка
https://docs.sentry.io/clients/python/integrations/logging/

Дмитрий
05.07.2017
19:27:45
круто! спасибо
блин, если оно так же валится в Unresolved Issues, то неудобно :/
есть такая штука, но это же страх https://pythonhosted.org/logview/

Igor
05.07.2017
19:34:52

Дмитрий
05.07.2017
19:36:14
у меня на втором монитрое лог дев сервера открыт, и если фронтенды какую-нибудь дичь засылают я иду сразу пинаю их и помогаю понять быстрее где косячат
в консоли главный минус, что неудобно грепом трейсбек вывести нормально
хотя через sed наверно можно

Igor
05.07.2017
19:38:37
> неудобно грепом трейсбек вывести нормально
а че не grep -A10 -B10 (добавить-убрать по вкусу)?

Admin
ERROR: S client not available

Google

Igor
05.07.2017
19:38:58
ну или egrep и регуляркой, наверняка есть готовые
https://stackoverflow.com/questions/17559418/how-can-i-use-awk-or-grep-to-capture-an-entire-python-traceback-in-a-log-file

Дмитрий
05.07.2017
19:40:36
Я думал grep тупой и мысли погуглить не было

Dk
05.07.2017
19:41:26
Как же man?

Igor
05.07.2017
19:41:50
да зачем тут man. они большие и оверкилл. --help хватает за глаза обычно.
а там на полторы страницы параметров. (читай: дохуя)

Дмитрий
05.07.2017
19:42:06
я ж говорю, думал греп строку вырезает и все :)

Igor
05.07.2017
19:42:18
это ты еще the-silver-searcher не видел

Дмитрий
05.07.2017
19:42:29
если б подумал что он может это уметь - нашел бы за минуту ))

Igor
05.07.2017
19:42:30
хотя он больше для поиска по исходникам

Дмитрий
05.07.2017
19:45:47
??

ultranoise ?
05.07.2017
20:21:24
еще раз спрошу
кто то трогал tap2pay, masterpass?

Pavel
05.07.2017
22:18:25
Всем привет! Есть сайт на джанге, есть посты и в них много картинок. Нужно хранить картинки в отдельном хранилище, что бы не забивать сервер и не нужно даже хранить ссылки на картинки в базе. На фронте загружается картинка, кладется в хранилище, в теле поста <img src="<линк на картинку в хранилище>", как можно это реализовать? Чем проще тем лучше.

Artur
05.07.2017
22:32:45
можно отдельный сервер поднять который по запросу будет нужную пикчу выдавать, но все равно какую-нибудь информацию хранить скорее всего придется, либо на 2ом сервере мониторить ссылку статьи и по ключам уже отдавать, но проще базу с урлами хранить

Igor
05.07.2017
22:33:23
> проще базу с урлами хранить
+1
с путями/названиями пикч