Skip to content

Commit

Permalink
ex-185 (jebene) added log_file flag to allow Bridget to specify the log
Browse files Browse the repository at this point in the history
file destination
  • Loading branch information
jebene committed Mar 30, 2015
1 parent ef43c7c commit 8024143
Show file tree
Hide file tree
Showing 11 changed files with 95 additions and 17 deletions.
1 change: 0 additions & 1 deletion jacquard/command_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
"""
from __future__ import absolute_import

from collections import defaultdict
import errno
import glob
import os
Expand Down
1 change: 1 addition & 0 deletions jacquard/expand.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ def add_subparser(subparser):
parser.add_argument("-v", "--verbose", action='store_true')
parser.add_argument("-c", "--column_specification", help="Path to text file containing column regular expressions to be included in output file")
parser.add_argument("--force", action='store_true', help="Overwrite contents of output directory")
parser.add_argument("--log_file", help="Log file destination")

def _predict_output(args):
return set([os.path.basename(args.output)])
Expand Down
1 change: 1 addition & 0 deletions jacquard/filter_hc_somatic.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ def add_subparser(subparser):
parser.add_argument("output", help="Path to output directory. Will create if doesn't exist and will overwrite files in output directory as necessary")
parser.add_argument("-v", "--verbose", action='store_true')
parser.add_argument("--force", action='store_true', help="Overwrite contents of output directory")
parser.add_argument("--log_file", help="Log file destination")

def _validate_arguments(args):
input_dir = os.path.abspath(args.input)
Expand Down
2 changes: 1 addition & 1 deletion jacquard/jacquard.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ def _dispatch(modules, arguments):
command, args = _parse_command_line_args(modules, arguments)
execution_context = _get_execution_context(command)

logger.initialize_logger(args.subparser_name)
logger.initialize_logger(args)
logger.debug("Jacquard run begins")
logger.debug("cwd|{}", os.getcwd())
logger.debug("command|{}", " ".join(arguments))
Expand Down
35 changes: 33 additions & 2 deletions jacquard/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,18 @@
"""
#pylint: disable=invalid-name, global-statement
from __future__ import print_function, absolute_import

from datetime import datetime
import errno
import getpass
import logging
import os
import socket
import sys

import jacquard.utils as utils


WARNING_OCCURRED = False
"""Used to vary the Done message to emphasize upstream log warnings"""
log_filename = None
Expand All @@ -25,11 +30,37 @@
_logging_dict = {}
_verbose = False

def _makepath(path):
try:
os.makedirs(path)
except OSError as exc:
if exc.errno == errno.EEXIST and os.path.isdir(path):
pass
else: raise

def _validate_log_file(log_file):
try:
_makepath(os.path.dirname(log_file))
except OSError:
raise utils.UsageError(("Jacquard cannot create specified log file "
"[{}]. Review inputs and try again."), log_file)

try:
log = open(log_file, "w")
log.close()
except IOError:
raise utils.UsageError(("Jacquard cannot create specified log file "
"[{}]. Review inputs and try again."), log_file)

def initialize_logger(command, verbose=False):
def initialize_logger(args, verbose=False):
"""Sets command name and formatting for subsequent calls to logger"""

global log_filename
log_filename = os.path.join(os.getcwd(), "jacquard.log")
if args.log_file:
_validate_log_file(args.log_file)
log_filename = args.log_file

logging.basicConfig(format=_FILE_LOG_FORMAT,
level="DEBUG",
datefmt=_DATE_FORMAT,
Expand All @@ -43,7 +74,7 @@ def initialize_logger(command, verbose=False):
_logging_dict = {'user': getpass.getuser(),
'host': socket.gethostname(),
'start_time': start_time,
'tool': command}
'tool': args.subparser_name}

def error(message, *args):
_print("ERROR", message, args)
Expand Down
2 changes: 1 addition & 1 deletion jacquard/merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
import jacquard.utils as utils
from jacquard.vcf import FileWriter
import jacquard.vcf as vcf
import jacquard.variant_callers.variant_caller_factory as variant_caller_factory


_DEFAULT_INCLUDED_FORMAT_TAGS = ["JQ_.*"]
Expand Down Expand Up @@ -411,6 +410,7 @@ def add_subparser(subparser):
parser.add_argument("-v", "--verbose", action='store_true')
parser.add_argument("--force", action='store_true', help="Overwrite contents of output directory")
parser.add_argument("--include_format_tags", dest='tags', help="Comma-separated list of regexs for format tags to include in output. Defaults to all JQ tags.")
parser.add_argument("--log_file", help="Log file destination")

def _predict_output(args):
desired_output_files = set([os.path.basename(args.output)])
Expand Down
1 change: 1 addition & 0 deletions jacquard/summarize.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ def add_subparser(subparser):
parser.add_argument("output", help="Path to output VCf")
parser.add_argument("-v", "--verbose", action='store_true')
parser.add_argument("--force", action='store_true', help="Overwrite contents of output directory")
parser.add_argument("--log_file", help="Log file destination")

def report_prediction(args):
return set([os.path.basename(args.output)])
Expand Down
1 change: 1 addition & 0 deletions jacquard/translate.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ def add_subparser(subparser):
parser.add_argument("--force", action='store_true', help="Overwrite contents of output directory")
parser.add_argument("--varscan_hc_filter_filename", help="Regex pattern that identifies optional VarScan high-confidence filter files. The VCF, high-confidence file pairs should share the same prefix. For example, given patientA.snp.vcf, patientA.indel.vcf, patientA.snp.fpfilter.pass, patientA.indel.fpfilter.pass, you could enable this option as varscan_hc_filter_filename='.fpfilter.pass$'")
parser.add_argument("--allow_inconsistent_sample_sets", help="Allow inconsistent sample sets to be used")
parser.add_argument("--log_file", help="Path to log file destination. Defaults to current working directory if not specified.")

#TODO (cgates): This module is both a command and also manipulates VcfRecords
# like a caller. This is the only body of code that does both these things.
Expand Down
2 changes: 1 addition & 1 deletion test/command_validator_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ def test_create_temp_working_dir_createsIfNotExists(self):
command_validator._create_temp_working_dir(None, args)
self.assertTrue(os.path.isdir(tmp_dir))

## cgates: This test is a good idea, but doesn't work reliably on Windows 7.
##TODO: cgates: This test is a good idea, but doesn't work reliably on Windows 7.
## Can we remove it with a clean conscience? What's a better way?
def xtest_create_temp_working_dir_doesNotExistCannotCreateTmp_directoryGivenAsOutput(self):
with TempDirectory() as output_dir:
Expand Down
65 changes: 54 additions & 11 deletions test/logger_test.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#pylint: disable=line-too-long, invalid-name, too-many-public-methods
from StringIO import StringIO
from argparse import Namespace
from datetime import datetime
import os
import shutil
import sys
from StringIO import StringIO
import unittest

import jacquard.logger as logger


Expand All @@ -20,15 +23,41 @@ def tearDown(self):
except OSError:
pass

def test_initialize_logger(self):
def test_initialize_logger_defaultFilename(self):
tool = "foo"
logger.initialize_logger(tool)
args = Namespace(subparser_name=tool,
log_file=None)
logger.initialize_logger(args)
self.assertEquals(['host', 'tool', 'start_time', 'user'],
logger._logging_dict.keys())
self.assertEquals("jacquard.log", os.path.basename(logger.log_filename))

def test_initialize_logger_suppliedFilename(self):
tool = "foo"
log_filename = "tmp/log.foo"
args = Namespace(subparser_name=tool,
log_file=log_filename)
logger.initialize_logger(args)
self.assertEquals(['host', 'tool', 'start_time', 'user'],
logger._logging_dict.keys())
self.assertEquals(log_filename, logger.log_filename)

def test_initialize_logger_createsParentDirs(self):
try:
tool = "foo"
log_filename = "tmp/log.foo"
args = Namespace(subparser_name=tool,
log_file=log_filename)
logger.initialize_logger(args)
self.assertTrue(os.path.isdir(os.path.dirname(log_filename)))
finally:
shutil.rmtree(os.path.dirname(log_filename))

def test_error(self):
tool = "foo"
logger.initialize_logger(tool)
args = Namespace(subparser_name=tool,
log_file=None)
logger.initialize_logger(args)
logger.error("bar")

root_logger = logger.logging.getLogger()
Expand All @@ -43,7 +72,9 @@ def test_error(self):

def test_warning(self):
tool = "foo"
logger.initialize_logger(tool)
args = Namespace(subparser_name=tool,
log_file=None)
logger.initialize_logger(args)
self.assertFalse(logger.WARNING_OCCURRED)
logger.warning("bar")
self.assertTrue(logger.WARNING_OCCURRED)
Expand All @@ -57,7 +88,9 @@ def test_warning(self):

def test_info(self):
tool = "foo"
logger.initialize_logger(tool)
args = Namespace(subparser_name=tool,
log_file=None)
logger.initialize_logger(args)
current_time = datetime.now()

logger.info("bar")
Expand All @@ -78,7 +111,9 @@ def test_info(self):

def test_info_message_args(self):
tool = "foo"
logger.initialize_logger(tool)
args = Namespace(subparser_name=tool,
log_file=None)
logger.initialize_logger(args)
current_time = datetime.now()

logger.info("bar {}/{}", "1", "2")
Expand All @@ -99,7 +134,9 @@ def test_info_message_args(self):

def test_debug(self):
tool = "foo"
logger.initialize_logger(tool)
args = Namespace(subparser_name=tool,
log_file=None)
logger.initialize_logger(args)

logger.debug("bar")

Expand All @@ -110,7 +147,9 @@ def test_debug(self):

def test_debug_consoleWhenVerbose(self):
tool = "foo"
logger.initialize_logger(tool, True)
args = Namespace(subparser_name=tool,
log_file=None)
logger.initialize_logger(args, True)
logger.debug("bar")
root_logger = logger.logging.getLogger()

Expand All @@ -123,7 +162,9 @@ def test_debug_consoleWhenVerbose(self):

def test_debug_noConsoleWhenNotVerbose(self):
tool = "foo"
logger.initialize_logger(tool)
args = Namespace(subparser_name=tool,
log_file=None)
logger.initialize_logger(args)

logger.debug("bar")

Expand All @@ -134,7 +175,9 @@ def test_debug_noConsoleWhenNotVerbose(self):

def test_noExceptionOnMalformedMessage(self):
tool = "foo"
logger.initialize_logger(tool)
args = Namespace(subparser_name=tool,
log_file=None)
logger.initialize_logger(args)

logger.info("bar {}/{}/{}", "1", "2")

Expand Down
1 change: 1 addition & 0 deletions test/mock_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def add_subparser(subparser):
parser.add_argument("input", help="foo")
parser.add_argument("output", help="foo")
parser.add_argument("--force", action='store_true', help="foo")
parser.add_argument("--log_file", help="foo")

def execute(args, execution_context):
global execute_called
Expand Down

0 comments on commit 8024143

Please sign in to comment.