How to add a timestamp in log files on launchd?

In launchd, you can change the path of the log files using StandardOutPath and StandardErrorPath in .plist file, but when I used it to output a log returned by the process, the resultant log files didn't add a timestamp and hence I cannot tell when each line is written nor when the process is run to begin with.

So is it feasible to add the timestamp information to the log files? The minimum requirement is month, day, hour, minute, and second.


The keys you mention don't redirect log files, they redirect the standard output/error streams. It is the responsibility of the program writing to those streams to add timestamp information.


You could use the ts command from moreutils which is available from homebrew or MacPorts. One reason to do this is if you dont want to encapsulate everything in a script and still want to use StandardErrorPath and StandardOutPath:

<key>ProgramArguments</key>
<array>
  <string>/bin/zsh</string>
  <string>-c</string>
  <string>/usr/local/opt/yabai/bin/yabai -V 2&gt; &gt;(/usr/local/opt/moreutils/bin/ts -m '[%Y-%m-%d %H:%M:%S] -' 1&gt;&amp;2) 1&gt; &gt;(/usr/local/opt/moreutits -m '[%Y-%m-%d %H:%M:%S] -')</string>
</array>

that third <string> is an xml-escaped representation of the below command:

/usr/local/opt/yabai/bin/yabai -V \
  2> >(/usr/local/opt/moreutils/bin/ts -m '[%Y-%m-%d %H:%M:%S] -' 1>&2) \
  1> >(/usr/local/opt/moreutils/bin/ts -m '[%Y-%m-%d %H:%M:%S] -')

What the above command does is 3-fold:

  • First, it runs the yabai command with verbose output enabled: /usr/local/opt/yabai/bin/yabai -V
  • Second, it redirects stderr (fd 2) into the stdin of the ts program which has formatting specified: 2> >(ts -m '[%Y-%m-%d %H:%M:%S] -' 1>&2) Since ts is going to output to stdout we need to make sure that we redirect that process's stdout to stderr, which is done by 1>&2.
  • Finally, we send stdout to another instance of ts which outputs to stdout: 1> >(/usr/local/opt/moreutils/bin/ts -m '[%Y-%m-%d %H:%M:%S] -')

By doing it this way you can preserve launchd's StandardErrorPath and StandardOutputPath output functionality. There's also the zpty module of zsh if you want to install less stuff on your machine.