Search code examples
pythonloggingcronraspbianraspberry-pi3

Python os.path.join() not joining properly when using cron job


I have a python script at /home/pi/update_rrd_data.py that's supposed to store logs in the folder /home/pi/logs_rrd.

This is how I've implemented it:

current_folder = os.path.dirname(os.path.abspath(inspect.stack()[0][1]))
log_folder = os.path.join(current_folder, 'logs_rrd')
if not os.path.exists(log_folder): os.makedirs(log_folder)

file_name = __file__[:-3]  + '_' + datetime.strftime(datetime.now(), '%Y%m%d%H%M') + '.log'
log_file = os.path.join(log_folder, file_name)

logging.basicConfig(filename=log_file, level=logging.DEBUG, format='%(asctime)s:%(levelname)s:%(filename)s->%(funcName)s:%(message)s', datefmt='%m/%d/%Y_%I:%M:%S_%p')
logging.info('\nCurrent Folder: {}\nLog Folder: {}\nLog File: {}'.format(current_folder, log_folder, log_file))

When I run the script manually, it works fine and this is what I get in the log file at /home/pi/logs_rrd/update_rrd_data_201709271426.log:
Current Folder: /home/pi
Log Folder: /home/pi/logs_rrd
Log File: /home/pi/logs_rrd/update_rrd_data_201709271426.log

However, when I run it as a cron job, the log files are created in the same folder as the script instead of the logs_rrd folder. This is what I get in the log file at /home/pi/update_rrd_data_201709271445.log:
Current Folder: /home/pi
Log Folder: /home/pi/logs_rrd
Log File: /home/pi/update_rrd_data_201709271445.log

I can't figure out why the log folder value is ok but then the log file removes the logs_rrd part of log folder.

This is how I run the cron:

*/5 * * * * /usr/bin/python /home/pi/update_rrd_data.py

All the folders and files are owned by root so there shouldn't be any write permission issues.


Solution

  • in the case where it doesn't work, __file__ is probably an absolute path, so

    log_file = os.path.join(log_folder, file_name)
    

    has no effect, (it retuns file_name) and the original script directory is kept.

    Instead of __file__[:-3], just do:

    os.path.basename(os.path.splitext(__file__)[0])
    

    to get rid of the extension (which may not be .py in some cases BTW) and of the script file path in all cases, so the next os.path.join command works properly.

    Alternate solution using pathlib and a Path object (requires Python 3):

    pathlib.Path(__file__).with_suffix('').name
    

    that removes the directory & the file extension amounting to the same result.