At some point in a Linux admins career they need to add timestamps to output. Whether it's logging for shell script or a simple command (like ping, traceroute, etc...) timestamps can come in handy. There are many ways to accomplish this, but none are as easy as the ts
command. In this Linux quick tip we will show you how to easily add timestamps to any output using the ts command.
To use the ts command you must install the moreutils package.
Table of Contents
Using the ts Command to Add Timestamps to Output
The basic function of the ts command is to add timestamps to the beginning of each line of input. The use of the word input is initially confusing, but it will become more clear as we go through examples.
If you call ts alone it will wait for input from the keyboard. Once it receives a line of input it will add a timestamp to the beginning of that line and print it to stdout (standard output). Here we are feeding input to ts on stdin (standard input).
[savona@putor ~]$ ts
This is a line of input from stdin
Feb 15 13:49:03 This is a line of input from stdin
NOTE: To learn more about standard streams (stdin/stdout/stderr), pipes, and redirection read "Linux Fundamentals - I/O, Standard Streams, and Redirection".
This becomes a lot more useful when you feed input from a pipe. In this example we will use the ts command to print timestamps on our ping output.
[savona@putor ~]$ ping 10.0.0.1 | ts
Feb 15 14:13:01 PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
Feb 15 14:13:01 64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.393 ms
Feb 15 14:13:02 64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.380 ms
Feb 15 14:13:03 64 bytes from 10.0.0.1: icmp_seq=3 ttl=64 time=0.507 ms
Feb 15 14:13:04 64 bytes from 10.0.0.1: icmp_seq=4 ttl=64 time=0.381 ms
As you can see, ts added a timestamp to every line of input. You might ask, isn't that output? Yes, in the end it is output from the ts command. However, the pipe is taking the output from the ping command and sending it to ts as input.
The ts Command Options
There are only a few options for the ts command. Here we will outline some of these options and give examples.
Incremental Timestamps for Linux Output
Using the -s
or -i
options will give you incremental timestamps instead of absolute. However, they differ by the start of the incrementation.
The -s
option will show incremental timestamps from the start of the program or action. In other words it will show the time since you started the program. Here you can see the ping example again, this time with incrementing timestamps.
[savona@putor ~]$ ping 10.0.0.1 | ts -s
00:00:00 PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
00:00:00 64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.359 ms
00:00:01 64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.395 ms
00:00:02 64 bytes from 10.0.0.1: icmp_seq=3 ttl=64 time=0.412 ms
00:00:03 64 bytes from 10.0.0.1: icmp_seq=4 ttl=64 time=0.469 ms
00:00:04 64 bytes from 10.0.0.1: icmp_seq=5 ttl=64 time=0.460 ms
The -i
options works a little differently. It shows the time since the last timestamp. In the past I have seen some shell scripts use this in very creative ways. Here is the ping example again, this time with incrementing timestamps showing the time since the last timestamp.
[savona@putor ~]$ ping -i 3 10.0.0.1 | ts -i
00:00:00 PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
00:00:00 64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.377 m
00:00:03 64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.418 ms
00:00:03 64 bytes from 10.0.0.1: icmp_seq=3 ttl=64 time=3.46 ms
Above I configured ping to send a packet every 3 seconds. This caused the timestamp to be 3 on each output after the first since each timestamp was 3 seconds apart. Remember, the -i
option shows the time since the last timestamp.
Relative Timestamps for Linux Output
The -r
option converts existing timestamps into relative times like "26m32s ago". Again, I have a coworker who had a few clever uses for this in his shell scripts (Maybe he will share?). To demonstrate this I will use the journalctl command to display system logs. We will then pipe it to the ts command to convert them to relative timestamps.
NOTE: Both "Time::Duration" and "Date::Parse" perl modules need to be installed for this option to work. You can read "Installing Perl Modules with cpan" if you need help.
Here we print the last 4 lines of our system log with journalctl.
[root@putor log]# journalctl -f -n 4
-- Logs begin at Wed 2020-04-01 13:23:42 EDT. --
Feb 15 14:48:05 putor sudo[132384]: pam_unix(sudo:session): session closed for user root
Feb 15 14:49:14 putor savona[132410]: test
Feb 15 14:49:30 putor savona[132422]: This is a log entry
Feb 15 14:50:48 putor savona[132444]: I will add one more for good measure
Here we print the same 4 lines, this time piping it to ts -r
to convert the timestamps to relative times.
[root@putor log]# journalctl -f -n 4 | ts -r
-- Logs begin at Wed 2020-04-01 13:23:42 EDT. --
9m4s ago putor sudo[132384]: pam_unix(sudo:session): session closed for user root
7m55s ago putor savona[132410]: test
7m39s ago putor savona[132422]: This is a log entry
6m21s ago putor savona[132444]: I will add one more for good measure
NOTE: You can also covert timestamps into any format you desire, continue reading for instructions.
Formatting Timestamps with the ts Command
With the ts command, formatting timestamps is very similar to the formatting used in the date command. Let's take a look at some examples.
[savona@putor ~]$ echo " - %B Shows me just the month by name" | ts %B
February - %B Shows me just the month by name
[savona@putor ~]$ echo " - %s Shows me the UNIX epoch" | ts %s
1613420169 - %s Shows me the UNIX epoch
Of course you can combine these formatting strings to make any format you desire. Here are some more complex examples.
[savona@putor ~]$ echo " - %l\":\"%M%p Shows me 12 hour clock" | ts %l":"%M%p
3:23PM - %l":"%M%p Shows me the normal 12 hour time
[savona@putor ~]$ echo " - %%m-%d-%Y Shows me the month-day-year" | ts %m-%d-%Y
02-15-2021 - %%m-%d-%Y Shows me the month-day-year
[savona@putor ~]$ echo " - %B\" \"%d,%y Shows me the month day, year as usually written in English" | ts %B" "%d,%Y
February 15,2021 - %B" "%d,%y Shows me the month day, year as usually written in English
You can also format existing timestamps by combining the -r
option with any formatting parameters. Let's look at an example.
Here is a normal system log entry, take note of the timestamp.
Feb 15 15:32:26 putor sudo[134299]: pam_unix(sudo:session): session opened for user root(uid=0) by (uid=1000)
The journalctl timestamps are already pretty friendly. However, we can change them to whatever we desire. In this example we convert them to something very natural to Americans using %B" "%d,%Y-%l":"%M%p
.
[savona@putor ~]$ sudo journalctl -f | ts -r %B" "%d,%Y-%l":"%M%p
February 15,2021- 3:32PM putor sudo[134277]: pam_unix(sudo:session): session opened for user root(uid=0) by (uid=1000)
For all formatting parameters see strftime.
Resources and Related Articles
Leave a Reply Cancel reply
This site uses Akismet to reduce spam. Learn how your comment data is processed.
2 Comments
Join Our Newsletter
Categories
- Bash Scripting (17)
- Basic Commands (50)
- Featured (7)
- Just for Fun (5)
- Linux Quick Tips (98)
- Linux Tutorials (65)
- Miscellaneous (15)
- Network Tools (6)
- Reviews (2)
- Security (32)
As far as I know, perl or awk is installed on most linux systems.
If it is, then you could do it without installing other package.
For example:
ping google.com | awk '{ print strftime(),$0 }'
I love it, thanks for sharing!