Linux log in bash

Write to custom log file from a Bash script

In Linux, I know how to write a simply message to the /var/log/messages file, in a simple shell script I created:

I want to stop throwing messages into the default /var/log/messages file, and create my own. I tried this:

#!/bin/bash logger "have more fun" > /var/log/mycustomlog 

It still logs to /var/log/messages . It did create the /var/log/mycustomlog , but it’s empty. Anyone see what I’m missing?

Redirecting standard output doesn’t work because logger doesn’t write to standard output; it writes to the file configured by syslog(3) to receive log messages.

5 Answers 5

logger logs to syslog facilities. If you want the message to go to a particular file you have to modify the syslog configuration accordingly. You could add a line like this:

and restart syslog. Then you can log like this:

logger -p local7.info "information message" logger -p local7.err "error message" 

and the messages will appear in the desired logfile with the correct log level.

Without making changes to the syslog configuration you could use logger like this:

logger -s "foo bar" >> /var/log/mycustomlog 

That would instruct logger to print the message to STDERR as well (in addition to logging it to syslog), so you could redirect STDERR to a file. However, it would be utterly pointless, because the message is already logged via syslog anyway (with the default priority user.notice ).

For anyone else who was confused at the use of the number 2 after the string in the last example, 1 redirects stdout, and 2 redirects stderr. More info available here: tldp.org/LDP/abs/html/io-redirection.html

And for anyone who doesn’t know how to edit the syslog configuration, here it is on Ubuntu: askubuntu.com/questions/42152/where-is-syslog-conf

What does the — before the file path indicate? I’ve tried googling around but can’t find anything about it. Is it required?

@chepner make a good point that logger is dedicated to logging messages.

I do need to mention that @Thomas Haratyk simply inquired why I didn’t simply use echo .

At the time, I didn’t know about echo, as I’m learning shell-scripting , but he was right.

My simple solution is now this:

#!/bin/bash echo "This logs to where I want, but using echo" > /var/log/mycustomlog 

The example above will overwrite the file after the >

So, I can append to that file with this:

#!/bin/bash echo "I will just append to my custom log file" >> /var/log/customlog 
  • on a side note, it’s simply my personal preference to keep my personal logs in /var/log/ , but I’m sure there are other good ideas out there. And since I didn’t create a daemon, /var/log/ probably isn’t the best place for my custom log file. (just saying)
Читайте также:  Create python exe in linux

I agree that this is a good approach but the log file will keep growing and there is no mechanism of archiving or deleting old logs. If you log frequently, then this can take considerable amount of storage.

There’s good amount of detail on logging for shell scripts via global varaibles of shell. We can emulate the similar kind of logging in shell script: http://www.cubicrace.com/2016/03/efficient-logging-mechnism-in-shell.html The post has details on introdducing log levels like INFO , DEBUG, ERROR. Tracing details like script entry, script exit, function entry, function exit.

If you see the man page of logger:

LOGGER(1) BSD General Commands Manual LOGGER(1)

NAME logger — a shell command interface to the syslog(3) system log module

SYNOPSIS logger [-isd] [-f file] [-p pri] [-t tag] [-u socket] [message . ]

DESCRIPTION Logger makes entries in the system log. It provides a shell command interface to the syslog(3) system log module.

It Clearly says that it will log to system log. If you want to log to file, you can use «>>» to redirect to log file.

This is an incorrect interpretation of the man page. logger uses syslog or (in the case of most Linux systems) rsyslog which can be configured to place log messages where ever you like.

I did it by using a filter. Most linux systems use rsyslog these days. The config files are located at /etc/rsyslog.conf and /etc/rsyslog.d .

Whenever I run the command logger -t SRI some message , I want «some message» to only show up in /var/log/sri.log .

To do this I added the file /etc/rsyslog.d/00-sri.conf with the following content.

# Filter all messages whose tag starts with SRI # Note that 'isequal, "SRI:"' or 'isequal "SRI"' will not work. # :syslogtag, startswith, "SRI" /var/log/sri.log # The stop command prevents this message from getting processed any further. # Thus the message will not show up in /var/log/messages. # & stop 

Then restart the rsyslogd service:

systemctl restart rsyslog.service 

Here is a shell session showing the results:

[root@rpm-server html]# logger -t SRI Hello World! [root@rpm-server html]# cat /var/log/sri.log Jun 5 10:33:01 rpm-server SRI[11785]: Hello World! [root@rpm-server html]# [root@rpm-server html]# # see that nothing shows up in /var/log/messages [root@rpm-server html]# tail -10 /var/log/messages | grep SRI [root@rpm-server html]# 

Источник

bash + logger варанты применения

Повседневные задачи администрирования Linux требуют автоматизации. Как правило, автоматизация сводится к написанию bash скриптов и их «ротации по крону», либо выполнении вручную, в зависимости от задачи. В этой заметке собраны часто встречающиеся практики логирования bash скриптов. Целевая аудитория — системные администраторы linux.

Самый простой и очевидный способ сохранить вывод скрипта это просто перенаправить его в файл.

На самом деле, нужно добавить к выводу STDERR, потому, как сообщения об ошибках пишутся именно в него:

exemple.sh > exemple.sh.log 2>&1 

Это считается нормальной практикой и обычно удовлетворяет большую часть системных администраторов. Но если серверов несколько(десятков, сотен), и логирование централизованно, удобнее использовать logger. Напомню, что logger это утилита, которая отправляет сообщения в syslog.

Читайте также:  Hp laserjet pro 404dn driver linux

Плюсы такого подхода в том, что можно перенаправлять вывод не только bash скриптов.

Минусы — невозможно отделить сообщения об ошибках от других информационных сообщений, так как в этом примере вывод слеплен в один поток и все это попадает в syslog с приоритетом user.notice(приоритет по умолчанию).

Для некоторых задач допустимо применение следующего варианта:

exemple.sh 2>&1 >/dev/null | logger -p user.error -t exemple.sh 

В этом варианте логируется только STDERR (STDOUT перенаправляется в /dev/null) с приоритетом error. Также сообщения помечаются тегом с названием скрипта. Все это может упростить поиск и устранения неисправностей в работе скриптов.

Минусом этого подхода является то, что мы теряем STDOUT. Чтобы решить эту проблему можно использовать перенаправление потоков вывода непосредственно внутри скрипта.

#!/bin/bash exec > >(logger -p local0.notice -t `basename "$0"`) exec 2> >(logger -p local0.error -t `basename "$0"`) echo "error" >&2 echo "notice" 

Этот пример иллюстрирует как можно перенаправить STDOUT и STDERR независимо друг от друга. К сожалению, этот способ порождает неожиданную проблему: сообщения из разных потоков могут попадать в syslog не в том порядке, в котором были отправлены. Такое поведение связано с тем, что потоки обрабатываются как два независимых друг от друга процесса. Не смотря на это, способ часто применяется для логирования скриптов, запускаемых cron.

Но иногда требуется запускать скрипт вручную, и в этом случае не всегда удобно следить за его работой в syslog.

#!/bin/bash # # .--------. # | STDOUT | # '--------' # ^ # | # .--------. .-----. .--------. # | STDOUT |----->| tee |---->| logger | # '--------' '-----' '--------' # exec > >(tee >(logger -p local0.notice -t `basename "$0"`)) # возможны варианты exec 2> >(tee >&2 >(logger -p local0.error -t `basename "$0"`)) #exec 2> >(logger -p local0.error -t `basename "$0"` -s) echo "error" >&2 echo "notice" 

В этом примере tee копирует «входящий» поток в logger и обратно — в STDOUT(поведение по умолчанию), а во втором случае в STDERR. Таким образом мы получаем логирование в syslog + вывод на консоль во время выполнения, что бывает полезно для скриптов, запускаемых вручную.

Логи в syslog — это просто.
Логи в syslog — это полезно, особенно если логирование централизованно. При параллельном перенаправленнии потоков вывода — следует помнить о возможном нарушении порядка следования сообщений.

Источник

Запуск Bash в деталях

Если вы нашли эту страницу в поиске, то наверняка пытаетесь решить какую-то проблему с запуском bash.

Возможно, в вашем окружении bash не устанавливается переменная среды и вы не понимаете, почему. Возможно, вы засунули что-то в различные загрузочные файлы bash или в профили, или во все файлы наугад, пока это не сработало.

В любом случае, смысл этой заметки — как можно проще изложить процедуру запуска bash, чтобы вы могли справиться с проблемами.

Диаграмма

Эта блок-схема обобщает все процессы при запуске bash.

Читайте также:  Очистить линукс одной командой

Теперь подробнее рассмотрим каждую часть.

Login Shell?

Сперва нужно выбрать, находитесь вы в командной оболочке входа (login shell) или нет.

Оболочка входа — это первая оболочка, в которую вы попадаете при входе в систему для интерактивного сеанса. Оболочка входа не требует ввода имени пользователя и пароля. Вы можете форсировать запуск оболочки входа, добавив флаг —login при вызове bash , например:

Оболочка входа настраивает базовую среду при первом запуске оболочки bash.

Интерактивный?

Затем вы определяете, является оболочка интерактивной или нет.

Это можно проверить по наличию переменной PS1 (она устанавливает функцию ввода команд):

if [ "$" ]; then echo interactive else echo non-interactive fi

Или посмотреть, установлен ли параметр -i , с помощью специальной переменной дефиса — в bash, например:

Если в выдаче есть символ i , то оболочка является интерактивной.

В оболочке входа?

Если вы находитесь в оболочке входа, то bash ищет файл /etc/profile и запускает, если он существует.

Затем ищет любой из этих трёх файлов в следующем порядке:

~/.bash_profile ~/.bash_login ~/.profile

Когда находит один, то запускает его и пропускает другие.

В интерактивной оболочке?

Если вы находитесь в интерактивной оболочке без входа в систему (non-login shell), предполагается, что вы уже побывали в оболочке входа, окружение настроено и будет унаследовано.

В этом случае выполняются по порядку следующие два файла, если они существуют:

Ни один вариант?

Если вы не находитесь ни в оболочке входа, ни в интерактивной оболочке, то ваше окружение действительно будет пустым. Это вызывает большую путаницу (см. ниже о заданиях cron).

В этом случае bash смотрит на переменную BASH_ENV вашей среды и выполняет соответствующий файл, который там указан.

Типичные трудности и эмпирические правила

Задания cron

У меня в 95% случаев отладка запуска bash связана с тем, что задание cron работает не так, как ожидалось.

Эта проклятая задача работает нормально, когда я запускаю её в командной строке, но фейлится при запуске в crontab.

  • Задания cron не являются интерактивными.
  • В отличие от скриптов в командной строке, задания cron не наследуют среду оболочки.

Вот почему зачастую приходится установить конкретный PATH для задачи cron, как здесь:

* * * * * PATH=$:/path/to/my/program/folder myprogram

Скрипты, вызывающие друг друга

Ещё одна распространенная проблема, когда скрипты по ошибке настроены на вызов друг друга. Например, /etc/profile обращается к ~/.bashrc .

Обычно так происходит, когда кто-то пытался исправить какую-то ошибку и вроде бы всё заработало. К сожалению, когда нужно разделить эти разные типы сессий, то возникают новые проблемы.

Образ Docker в песочнице

Чтобы поэкспериментировать с запуском оболочки, я создал образ Docker, который можно использовать для отладки запуска оболочки в безопасной среде.

$ docker run -n bs -d imiell/bash_startup $ docker exec -ti bs bash

Для принудительного логина и имитации оболочки входа:

Для проверки набора переменных BASH_ENV :

Для отладки crontab каждую минуту выполнятся простой скрипт (в /root/ascript ):

$ crontab -l $ cat /var/log/script.log

Источник

Оцените статью
Adblock
detector