mirror of
https://github.com/certbot/certbot.git
synced 2026-01-21 19:01:07 +03:00
CLI debug log file
This commit is contained in:
@@ -3,8 +3,10 @@
|
||||
import argparse
|
||||
import atexit
|
||||
import logging
|
||||
import logging.handlers
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
import configargparse
|
||||
import zope.component
|
||||
@@ -70,9 +72,6 @@ More detailed help:
|
||||
|
||||
|
||||
def _account_init(args, config):
|
||||
le_util.make_or_verify_dir(
|
||||
config.config_dir, constants.CONFIG_DIRS_MODE, os.geteuid())
|
||||
|
||||
# Prepare for init of Client
|
||||
if args.email is None:
|
||||
return client.determine_account(config)
|
||||
@@ -559,6 +558,8 @@ def _paths_parser(helpful):
|
||||
help=config_help("config_dir"))
|
||||
add("paths", "--work-dir", default=flag_default("work_dir"),
|
||||
help=config_help("work_dir"))
|
||||
add("paths", "--logs-dir", default=flag_default("logs_dir"),
|
||||
help="Path to a directory where logs are stored.")
|
||||
add("paths", "--backup-dir", default=flag_default("backup_dir"),
|
||||
help=config_help("backup_dir"))
|
||||
add("paths", "--key-dir", default=flag_default("key_dir"),
|
||||
@@ -575,14 +576,39 @@ def _paths_parser(helpful):
|
||||
|
||||
def _setup_logging(args):
|
||||
level = -args.verbose_count * 10
|
||||
logging.getLogger().setLevel(level)
|
||||
fmt = "%(asctime)s:%(levelname)s:%(name)s:%(message)s"
|
||||
if args.text_mode:
|
||||
handler = logging.StreamHandler()
|
||||
handler.setFormatter(logging.Formatter(fmt))
|
||||
else:
|
||||
handler = log.DialogHandler()
|
||||
handler.setFormatter(logging.Formatter(logging.BASIC_FORMAT))
|
||||
logging.getLogger().addHandler(handler)
|
||||
# dialog box is small, display as less as possible
|
||||
handler.setFormatter(logging.Formatter("%(message)s"))
|
||||
handler.setLevel(level)
|
||||
|
||||
# TODO: use fileConfig?
|
||||
|
||||
# unconditionally log to file for debugging purposes
|
||||
# TODO: change before release?
|
||||
log_file_name = os.path.join(args.logs_dir, 'letsencrypt.log')
|
||||
file_handler = logging.handlers.RotatingFileHandler(
|
||||
log_file_name, maxBytes=2**20, backupCount=10)
|
||||
# rotate on each invocation, rollover only possible when maxBytes
|
||||
# is nonzero and backupCount is nonzero, so we set maxBytes as big
|
||||
# as possible not to overrun in single CLI invocation (1MB).
|
||||
file_handler.doRollover() # TODO: creates empty letsencrypt.log.1 file
|
||||
file_handler.setLevel(logging.DEBUG)
|
||||
file_handler_formatter = logging.Formatter(fmt=fmt)
|
||||
file_handler_formatter.converter = time.gmtime # don't use localtime
|
||||
file_handler.setFormatter(file_handler_formatter)
|
||||
|
||||
root_logger = logging.getLogger()
|
||||
root_logger.setLevel(logging.DEBUG) # send all records to handlers
|
||||
root_logger.addHandler(handler)
|
||||
root_logger.addHandler(file_handler)
|
||||
|
||||
logging.debug("Root logging level set at %d", level)
|
||||
logging.info("Saving debug log to %s", log_file_name)
|
||||
|
||||
|
||||
def main(cli_args=sys.argv[1:]):
|
||||
@@ -599,6 +625,13 @@ def main(cli_args=sys.argv[1:]):
|
||||
displayer = display_util.NcursesDisplay()
|
||||
zope.component.provideUtility(displayer)
|
||||
|
||||
for directory in config.config_dir, config.work_dir:
|
||||
le_util.make_or_verify_dir(
|
||||
directory, constants.CONFIG_DIRS_MODE, os.geteuid())
|
||||
# TODO: logs might contain sensitive data such as contents of the
|
||||
# private key! #525
|
||||
le_util.make_or_verify_dir(args.logs_dir, 0o700, os.geteuid())
|
||||
|
||||
_setup_logging(args)
|
||||
# do not log `args`, as it contains sensitive data (e.g. revoke --key)!
|
||||
logging.debug("Arguments: %r", cli_args)
|
||||
|
||||
@@ -15,6 +15,7 @@ CLI_DEFAULTS = dict(
|
||||
rollback_checkpoints=0,
|
||||
config_dir="/etc/letsencrypt",
|
||||
work_dir="/var/lib/letsencrypt",
|
||||
logs_dir="/var/log/letsencrypt",
|
||||
no_verify_ssl=False,
|
||||
dvsni_port=challenges.DVSNI.PORT,
|
||||
cert_path="./cert.pem",
|
||||
|
||||
@@ -106,6 +106,9 @@ def _paths_parser(parser):
|
||||
help=cli.config_help("config_dir"))
|
||||
add("--work-dir", default=cli.flag_default("work_dir"),
|
||||
help=cli.config_help("work_dir"))
|
||||
add("--logs-dir", default=cli.flag_default("logs_dir"),
|
||||
help="Path to a directory where logs are stored.")
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
"""Tests for letsencrypt.cli."""
|
||||
import itertools
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import mock
|
||||
@@ -8,10 +11,19 @@ import mock
|
||||
class CLITest(unittest.TestCase):
|
||||
"""Tests for different commands."""
|
||||
|
||||
@classmethod
|
||||
def _call(cls, args):
|
||||
def setUp(self):
|
||||
self.tmp_dir = tempfile.mkdtemp()
|
||||
self.config_dir = os.path.join(self.tmp_dir, 'config')
|
||||
self.work_dir = os.path.join(self.tmp_dir, 'work')
|
||||
self.logs_dir = os.path.join(self.tmp_dir, 'logs')
|
||||
|
||||
def tearDown(self):
|
||||
shutil.rmtree(self.tmp_dir)
|
||||
|
||||
def _call(self, args):
|
||||
from letsencrypt import cli
|
||||
args = ['--text'] + args
|
||||
args = ['--text', '--config-dir', self.config_dir,
|
||||
'--work-dir', self.work_dir, '--logs-dir', self.logs_dir] + args
|
||||
with mock.patch('letsencrypt.cli.sys.stdout') as stdout:
|
||||
with mock.patch('letsencrypt.cli.sys.stderr') as stderr:
|
||||
with mock.patch('letsencrypt.cli.client') as client:
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
root="$(mktemp -d)"
|
||||
echo "\nRoot integration tests directory: $root"
|
||||
store_flags="--config-dir $root/conf --work-dir $root/work"
|
||||
store_flags="$store_flags --logs-dir $root/logs"
|
||||
|
||||
common() {
|
||||
# first three flags required, rest is handy defaults
|
||||
|
||||
Reference in New Issue
Block a user