Использование служб журналирования
Службы журналирования это службы, дающие программам возможность сообщать о происходящих событиях, помечая их приоритетами важности, а также ведущие учет этих сообщений-логов. Чаще всего необходимость в логировании возникает у программ-демонов, так как обычного доступа к терминалу у них нет. Интерфейс к таким службам из CL программ тут и рассмотрим.
Ведение обычных текстовых логов в целом не представляет особой сложности - например, код в log.lisp из Hunchentoot. Однако, в случаях когда приложение работает на правах демона, традиционным считается подход использования службы журналирования. Это обеспечивает, во-первых, единообразие: директория /var/log (Linux, FreeBSD) содержит сообщения как от ядра и различных утилит, так и от различных демонов - серверов (например /var/log/nginx), почтовых программ, программ планировщиков и так далее. Во-вторых - удобный парсинг, ротирование, или вывод в реальном времени на специализированную консоль.
Всё что необходимо для доступа к системе логирования - описать три функции из стандартной библиотеки, а именно openlog, syslog и closelog. Эти функции являются частью стандарта POSIX, в то время как реализаций службы журналирования несколько - как классический syslogd, так и более современный syslog-ng.
Требования к системе
Наличие директория /var/log с содержимым не обязательно означает, что система логирования включена и настроена, необходимо убедиться в этом:
- Запустить демон соответствующей службы, например:
/etc/init.d/syslog-ng start
- Произвести соответствующие настройки, для syslog-ng - в файле /etc/syslog-ng/syslog-ng.conf. Без этих настроек служба будет работать простейшим образом, записывая все логи в файл /var/log/messages.
IOLIB
С помощью IOLIB, возможно 1), можно осуществлять логирование следующим образом:
(defpackage :my-package
(:use #:common-lisp #:iolib.os))
(in-package :my-package)
(with-log ("my-programm")
(dotimes (i 3)
(write-log "my message ~A" i)))
После чего должно появиться:
tail /var/log/messages
Jul 18 23:47:36 tux my-programm: my message 0
Jul 18 23:47:36 tux my-programm: my message 1
Jul 18 23:47:36 tux my-programm: my message 2
А если необходимо вести логи повсеместно:
(defpackage :my-package
(:use #:common-lisp #:iolib.os))
(in-package :my-package)
(open-log "my-programm-2")
(dotimes (i 3)
(write-log isys:log-info "my message ~A" i))
;; etc.
(close-log)
tail /var/log/messages
Jul 18 23:50:15 tux my-programm-2: my message 0
Jul 18 23:50:15 tux my-programm-2: my message 1
Jul 18 23:50:15 tux my-programm-2: my message 2
Но здесь возникает обычная проблема - нужно не забыть закрыть лог (относительно необходимо, конечно, - учитывая специфику выполнения CL приложений, а также то, что сейчас почти все ОС гарантируют автоматическое закрытие логов всех закрытых программ). Если же начать писать не открывая лога, то сообщения будут записаны от имени лисп-процесса:
(write-log isys:log-info "my message ~A" 'foo)
tail /var/log/messages
Jul 17 15:34:08 tux sbcl: My message: FOO
Возможно захочется ещё чтобы логи программы не мешались с другими а были доступны отдельно - тогда нужно настроить соответствующую службу журналирования (как это объясняется в многочисленных статьях).
Другие возможности логирования
- log.lisp из hunchentoot как наиболее простой вариант,
- (sb-posix:syslog priority format &rest args) для записи логов от имени SBCL.
- И другие: http://www.cliki.net/admin/search?words=logging