custom log format in bash logger - linux

I have default log format like this:
+ logger --stderr '[START]'
<13>Jun 29 13:10:02 ada: [START]
but I need something like this:
+ logger --stderr '[START]'
2018-06-29 11:11:43,524 1 INFO ada: [START]
I already consulted man logger but no illumination on how to do custom timestamps. I hope there is something like:
+ export LOGGER_FORMAT="{year}-{date}-{month} ... {level} {user}: {message}"
+ logger --stderr '[START]'
2018-06-29 11:11:43,524 1 INFO ada: [START]
Is there something like this?
journalctl already is doing it well, and it receive messages from logger command. How does that work?
journalctl
-- Logs begin at Tue 2015-02-03 21:48:52 UTC, end at Tue 2015-02-03 22:29:38 UTC. --
Feb 03 21:48:52 localhost.localdomain systemd-journal[243]: Runtime journal is u

logger generates syslog messages which have a standard format. There's a proscribed format for the timestamp in order for syslog tools to be able to parse it. It can't be and shouldn't be changed.
The systemd journal interprets the syslog messages as they're generated, parsing and storing each of the parts in its internal database in a custom format. You can do the same thing if you want to print the log messages in a different way: read up on how syslog messages are formatted, write a script or regex to pull out the component pieces, and then print them out however you like.

Related

Rsyslog send a message programmatically

How to send a message to rsyslog deamon programmatically (from a custom program)?
In the syslog there are openlog...syslog...closelog functions available. But how can i do it in case of rsyslog?
rsyslog is a central log program.
You could cat /etc/rsyslog.conf to watch how your rsyslog is configured.
Default configuration use imuxsock and imjournal.
imuxsock module actually listen like /dev/log or /run/systemd/journal/syslog. This means you could use syslog(3) man 3 syslog or cmd logger 123 to write log into /var/log/messages.
imjournal means rsyslog read log from systemd-journald(/var/log/journal/$(uuid)/*.journal. You could use sd-journal(3) api or journal cmd like echo 123 | systemd-cat to write to journal, and then rsyslog read log from it. you can see journal with journalctl -e to see the newest journal.

See user id in linux journalctl

I use journalctl -f to see the logs written by the processes, but it does not print the user who initiated the process writing to syslog.
Is there any option we can provide to journalctl in order to print the user id?
Thanks.
If you run journalctl -o verbose you will see the complete log record for each entry, which will look something like:
Fri 2019-08-02 20:02:11.307673 EDT [s=e328b42f9ccd4ef28cc946dba525b34c;i=12377a1;b=299ec3a7a9e545f3ab77225c045aee0c;m=7a7d1960ef;t=58f2b2fc43900;x=ceff52112a8146ae]
_TRANSPORT=journal
_UID=1000
_GID=1000
_CAP_EFFECTIVE=0
_AUDIT_LOGINUID=1000
_SYSTEMD_OWNER_UID=1000
_SYSTEMD_SLICE=user-1000.slice
_SYSTEMD_USER_SLICE=-.slice
_BOOT_ID=299ec3a7a9e545f3ab77225c045aee0c
_MACHINE_ID=39332780e5924d6ba0bdf775223941f6
_HOSTNAME=madhatter
PRIORITY=6
SYSLOG_FACILITY=3
CODE_FILE=../src/core/job.c
CODE_LINE=594
CODE_FUNC=job_log_begin_status_message
SYSLOG_IDENTIFIER=systemd
MESSAGE=Starting GNOME Terminal Server...
JOB_ID=1446
JOB_TYPE=start
USER_UNIT=gnome-terminal-server.service
USER_INVOCATION_ID=188bcf32f532490c8ce5ec486895f9d0
MESSAGE_ID=7d4958e842da4a758f6c1cdc7b36dcc5
_PID=3329
_COMM=systemd
_EXE=/usr/lib/systemd/systemd
_CMDLINE=/usr/lib/systemd/systemd --user
_AUDIT_SESSION=3
_SYSTEMD_CGROUP=/user.slice/user-1000.slice/user#1000.service/init.scope
_SYSTEMD_UNIT=user#1000.service
_SYSTEMD_USER_UNIT=init.scope
_SYSTEMD_INVOCATION_ID=5537b4a00b5946ce9f3b2b664c3d10e8
_SOURCE_REALTIME_TIMESTAMP=1564790531307673
Take a look at man journalctl for more information. E.g., there is a -o json if you want to programtically process log lines in some fashion.

Linux: journalctl

I would like to view only log messages created within a specified time range (08:00 - 11:00) for ALL days.
If I use:
journalctl --since 08:00 --until 11:00
It displays logs from current day only.
Any ideas?
First of all - where is your journalctl log file? Default journalctl collect logs since the launch of the system.
By default, the log file is in /var/log/journal. If this dir isn't exist set Storage=persistent in /etc/systemd/journald.conf and run systemctl restart systemd-journald.
And when journalctl saves all messages/events on all the days or when the system collects logs from a few days of the save settings day You can draw some interesting informations from journalctl in this way:
# Define year
year="2016"
# Defines the month in which you want to search
months=(08 09 10)
for i in "${months[#]}" ; do
# To set a range of days: 14 - 20
for j in `seq 14 20` ; do
journalctl --since "${year}-${i}-${j} 08:00:00" --until "${year}-${i}-${j} 11:00:00" >> /tmp/journal.${year}-${i}-${j}.log
done
done
If you want to check days from 1 to 9 will probably need to add a mechanism for adding 0 (01, 02, 03, ..., 09).
This is an example so you have to adjust it to your needs.

Changing date format in syslog

Is there anyway we can change the date format in a particular log file being logged to by syslog? I don't want to change the way all logs are being logged, but just by log file.
EDIT: I'm using syslogd (in FreeBSD)
This is how my file looks like now:
Dec 5 07:52:10 Log data 1
Dec 5 07:52:10 Log data 2
Dec 5 07:52:10 Log data 3
This is how I want it to look like:
20131205 07:52:10 Log data 1
20131205 07:52:10 Log data 2
20131205 07:52:10 Log data 3
My syslog.conf looks like this, where /var/log/my_log.log is my logfile:
+#
*.notice;local0.none;local1.none;local2.none;authpriv.none;kern.debug;mail.crit;news.err /var/log/messages
security.* /var/log/security
auth.info;authpriv.info /var/log/auth.log
mail.info /var/log/maillog
ftp.info /var/log/xferlog
cron.* /var/log/cron
*.=debug /var/log/debug.log
console.info /var/log/console.log
local1.info /var/log/my_log.log
Even if you found a different solution, I give an answer for others.
Edit your syslog configuration file (On Debian for example: /etc/syslog-ng/syslog-ng.conf).
Then declare a new template like this :
template template_date_format {
template("${YEAR}-${MONTH}-${DAY} ${HOUR}:${MIN}:${SEC} ${HOST} ${MSGHDR}${MSG}\n");
template_escape(no);
};
This is an example but you can use different macros according to syslog documentation linked in user9645's answer.
After that, find in this configuration file, all the files you want to change the output format and apply this template to them.
For example, I want to change /var/log/auth.log output format, then I change :
destination d_auth { file("/var/log/auth.log"); };
to :
destination d_auth { file("/var/log/auth.log" template(template_date_format)); };
Then restart syslog (service syslog-ng restart) and try a login to see the changes in your auth.log.
There are always a new options for the date problem, adding just a couple of lines.
My solution comes adding a file to /etc/rsyslog.d/, for example myrsyslog.conf, then add the format of your choice, mine is:
$template myformat,"%TIMESTAMP:1:10:date-rfc3339% %TIMESTAMP:19:12:date-rfc3339% %syslogtag%%msg%\n"
$ActionFileDefaultTemplate myformat
this will apply the new format to your logs making it easy to parse.
before
Sep 3 12:52:37 whs dhcpcd[477]: wlan0: expired address ...
Sep 3 12:52:37 whs dhcpcd[477]: wlan0: part of Router Advertisement expired
Sep 3 12:52:37 whs dhcpcd[477]: wlan0: deleting route to ...
after
2020-09-03 13:00:49 systemd[1]: rsyslog.service: Succeeded.
2020-09-03 13:00:49 systemd[1]: Stopped System Logging Service.
2020-09-03 13:00:49 systemd[1]: Starting System Logging Service...
I had the same issue using FreeBSD 9.2 and Zabbix system monitor GUI which cannot handle things like 'Jan' or 'Feb' in the date stamp (!) on the system log messages.
What I did was install the sysutils/syslog-ng port, and use the convert-syslogconf.awk script to migrate my /etc/syslog.conf to /usr/local/etc/syslog-ng.conf (which thankfully seemed to work well with even a fairly complex config) and added this custom formatting template to all the file() destinations:
template t_msgfmt {
template("${ISODATE} ${HOST} ${FACILITY} ${LEVEL} ${MSGHDR}${MSG}\n");
template_escape(no);
};
You can find (lots) more formatting info in the syslog-ng manual section 11.1. It is working good for me (so far) hope it helps you!
I ended up using an awk script to run through the log file and replace the date field
awk '{getDate="date -j -f \"%b %d %H:%M:%S\" \""$1" "$2" "$3"\" \"+%Y%m%d %H:%M:%S\""
while ( ( getDate | getline date ) > 0 ) { }
close(getDate);
print date,$2,$3,$4,$5}' Temp1 > Temp2
Many years later rsyslog has replaced syslogd and this has gotten super easy:
#
# Use traditional timestamp format.
# To enable high precision timestamps, comment out the following line.
#
#$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
Comment out that one line and done.

Adding year in the syslog message (linux)

I need to log the year in the log message generated by syslog daemon. In particular in the /var/log/secure file. Is it possible?
Here an example of normal syslog message:
Feb 16 04:06:58 HOST sshd[28573]: Accepted password for USER from SOURCE port 7269 ssh2
And I need something similar to:
Feb 16 2011 04:06:58 HOST sshd[28573]: Accepted password for USER from SOURCE port 7269 ssh2
Thanks in advance.
If you use rsyslog, it is easy. Refer to following:
Modify /etc/rsyslog.conf to following:
...
authpriv.* /var/log/secure;RSYSLOG_FileFormat
...
And then asking rsyslog daemon to reload configuration:
$ kill -HUP <pid of rsyslog daemon>
More reference :
http://www.rsyslog.com/doc/rsyslog_recording_pri.html
http://www.rsyslog.com/doc/rsyslog_conf_modules.html/rsyslog_conf_templates.html
syslog-ng has the ts_format() option to specify the default timestamp format for files. it is set to iso format by default, which includes the year.
you can also configure file formats using the template() option.
If your syslog respects RFC 3164 (The BSD Syslog Protocol), then you cannot configure it to record the year. Unless you have a modern syslog daemon that follows RFC 5424 (rsyslog or syslog-ng) you cannot do that.
If you can't alter the syslog on the system itself, maybe you could setup syslog to send it to a remote system with a better syslog daemon?

Resources