1

I am writing a python script to take dump backup of Mongo. I want my output to be redirect to a text file that can be used for further reference.

I have tried sys.stdout but it is only printing the output of print command

sys.stdout



!/usr/bin/python3
import os
import time
import datetime
import sys
import subprocess
import glob


'''
    mongo backup by python

'''


BKP_DIR = "/apps/mongobackup/mongo_backup"
BLD = "/apps/mongobackup/logs"



# configs:


host = "NA" # if host is your local machine leave it NA
db_name = sys.argv[1]
port = sys.argv[2] # if mongo is on default port (37017) leave in NA

now = datetime.datetime.now()
new_today_date = now.strftime("%m%d%Y_%H%M%S")
outputs_dir = os.path.join(BKP_DIR, db_name, new_today_date)
output_log=os.path.join(BLD,"output.log")
try:
    # Create target Directory
    os.mkdir(outputs_dir)
    print("Directory " , outputs_dir ,  " Created ")
except FileExistsError:
    print("Directory " , outputs_dir ,  " already exists")
username = "dba" # if there is no username set, leave it in NA
password = "dba" # if there is no password set, leave it in NA

def render_output_locations():
  return outputs_dir + time.strftime("%m%d%Y_%H%M%S")

orig_stdout = sys.stdout
f = open('out.txt', 'w')
sys.stdout = f
def run_backup():
  command = "mongodump"
  if host != 'NA':
    command += " --host " + host
  if port != 'NA':
    command += " --port " + port
  if username != 'NA':
    command += " --username " + username
  if password != 'NA':
    command += " --password " + password
  if db_name != 'NA':
      command += " -d local --authenticationDatabase admin"

  command += " --out " + outputs_dir
  os.system(command)


print("mongo backup progress started")


run_backup()

sys.stdout = orig_stdout
f.close()

Output :-

$a>cat out.txt

mongo backup progress started

Desired Output:-

$>cat out.txt

mongo backup progress started

 2019-08-20T03:33:03.132-0400    writing local.oplog.rs to    
    2019-08-20T03:33:03.132-0400    writing local.startup_log to    
    2019-08-20T03:33:03.132-0400    writing local.replset.minvalid to    
    2019-08-20T03:33:03.132-0400    writing local.replset.election to    
    2019-08-20T03:33:03.184-0400    done dumping local.startup_log (1 document)    
    2019-08-20T03:33:03.184-0400    writing local.replset.oplogTruncateAfterPoint to    
    2019-08-20T03:33:03.184-0400    done dumping local.replset.election (1 document)    
    2019-08-20T03:33:03.208-0400    done dumping local.replset.minvalid (1 document)    
    2019-08-20T03:33:03.209-0400    done dumping local.replset.oplogTruncateAfterPoint (1 document)    
    2019-08-20T03:33:05.833-0400    local.oplog.rs  1881559    
    2019-08-20T03:33:06.509-0400    local.oplog.rs  2389014
    2019-08-20T03:33:06.509-0400    done dumping local.oplog.rs (2389014 documents)
Guy Zarzar
  • 43
  • 1
  • 3
Abhinav
  • 314
  • 2
  • 12
  • Try also redirect `sys.stderr` to your `f` handler. – pawelbylina Aug 20 '19 at 07:52
  • i have tried sys.stderr it is creating empty file – Abhinav Aug 20 '19 at 07:54
  • Don't `>cat out.txt`, you need to redirect your output to the file, not to the `cat`! Just do `./your_script.py >out.txt` – h4z3 Aug 20 '19 at 07:54
  • hi @ h4z3 i want to create log inside the python script not the os level redirecting – Abhinav Aug 20 '19 at 07:55
  • @Abhinav: ok, I see now. You are using `os.system` to run mongo which is creating new process that's why your output redirection will not work. You should use `subprocess` like here: https://stackoverflow.com/questions/1996518/retrieving-the-output-of-subprocess-call/21000308 – pawelbylina Aug 20 '19 at 07:58
  • @pako can you explain me how do i use subprocess in my above script "from subprocess import STDOUT" – Abhinav Aug 20 '19 at 08:10
  • @Abhinav: see my answer below. Did it help? – pawelbylina Aug 20 '19 at 09:05

1 Answers1

0

Use subprocess.call instead of os.system:

from subprocess import call

output = open('output.txt', 'w')
call(command, stdout=output, stderr=output, shell=True)
pawelbylina
  • 1,387
  • 10
  • 17