electrum-personal-server

Maximally lightweight electrum server for a single user
git clone https://git.parazyd.org/electrum-personal-server
Log | Files | Refs | README

commit 8a3000b22333463b49582c92b62e056378c4ce9b
parent 9f795b998d245eac8e94b0c567ba2b8938acec40
Author: chris-belcher <chris-belcher@users.noreply.github.com>
Date:   Thu, 18 Apr 2019 16:49:40 +0100

Move command line logging options to config file

Closing issue #100

Diffstat:
Mconfig.cfg_sample | 52++++++++++++++++++++++++++++++++++++++--------------
Melectrumpersonalserver/server/common.py | 68++++++++++++++++++++++++++++----------------------------------------
2 files changed, 66 insertions(+), 54 deletions(-)

diff --git a/config.cfg_sample b/config.cfg_sample @@ -2,11 +2,13 @@ # Electrum Personal Server configuration file # Comments start with # +# The most important options are towards the top of the file + [master-public-keys] # Add electrum wallet master public keys to this section # In electrum then go Wallet -> Information to get the mpk -# any_name_works = xpub661MyMwAqRbcFseXCwRdRVkhVuzEiskg4QUp5XpUdNf2uGXvQmnD4zcofZ1MN6Fo8PjqQ5cemJQ39f7RTwDVVputHMFjPUn8VRp2pJQMgEF +#any_name_works = xpub661MyMwAqRbcFseXCwRdRVkhVuzEiskg4QUp5XpUdNf2uGXvQmnD4zcofZ1MN6Fo8PjqQ5cemJQ39f7RTwDVVputHMFjPUn8VRp2pJQMgEF # Multiple master public keys maybe added by simply adding another line #my_second_wallet = xpubanotherkey @@ -15,23 +17,12 @@ # this example is a 2-of-3 multisig wallet #multisig_wallet = 2 xpub661MyMwAqRbcFseXCwRdRVkhVuzEiskg4QUp5XpUdNf2uGXvQmnD4zcofZ1MN6Fo8PjqQ5cemJQ39f7RTwDVVputHMFjPUn8VRp2pJQMgEF xpub661MyMwAqRbcFseXCwRdRVkhVuzEiskg4QUp5XpUdNf2uGXvQmnD4zcofZ1MN6Fo8PjqQ5cemJQ39f7RTwDVVputHMFjPUn8VRp2pJQMgEF xpub661MyMwAqRbcFseXCwRdRVkhVuzEiskg4QUp5XpUdNf2uGXvQmnD4zcofZ1MN6Fo8PjqQ5cemJQ39f7RTwDVVputHMFjPUn8VRp2pJQMgEF -[watch-only-addresses] -#Add individual addresses to this section, for example paper wallets - -#addr = 1DuqpoeTB9zLvVCXQG53VbMxvMkijk494n - -# A space separated list is also accepted -#my_test_addresses = 3Hh7QujVLqz11tiQsnUE5CSL16WEHBmiyR 1PXRLo1FQoZyF1Jhnz4qbG5x8Bo3pFpybz bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq - -# multiple addresses may also be added in separate lines (like master public keys above) -#addr2 = 3anotheraddress - [bitcoin-rpc] host = 127.0.0.1 port = 8332 #add the bitcoin datadir to search for the .cookie file created by the -# node, which avoids the need to configure rpc_user/pass, leave empty to -# have it look in the default location +# node, which avoids the need to configure rpc_user/pass +#leave this option empty to have it look in the default location datadir = #if you dont want to use the .cookie method with datadir, uncomment to config u/p here #rpc_user = @@ -76,3 +67,36 @@ keyfile = certs/cert.key # It improves server responsiveness but stops mempool-based Electrum features # This is useful on low powered devices at times when the node mempool is large disable_mempool_fee_histogram = false + +[watch-only-addresses] +#Add individual addresses to this section, for example paper wallets +#Dont use this section for adding entire wallets, instead use the +# above section `master-public-keys` + +#addr = 1DuqpoeTB9zLvVCXQG53VbMxvMkijk494n + +# A space separated list is also accepted +#my_test_addresses = 3Hh7QujVLqz11tiQsnUE5CSL16WEHBmiyR 1PXRLo1FQoZyF1Jhnz4qbG5x8Bo3pFpybz bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq + +# multiple addresses may also be added in separate lines (like master public keys above) +#addr2 = 3anotheraddress + + +[logging] +# Section for configuring the logging output + +# The log level. Logging messages less severe than this will not be displayed +#options are 'DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL' +#Information printed to the log file is always at level DEBUG +log_level_stdout = INFO + +# Location of log file, leave empty to use the default location in temp dir +log_file_location = + +# Whether to append to log file or delete and overwrite on startup +append_log = false + +# Format to use for logging messages +#see docs https://docs.python.org/3/library/logging.html#logging.Formatter +log_format = %(levelname)s:%(asctime)s: %(message)s + diff --git a/electrumpersonalserver/server/common.py b/electrumpersonalserver/server/common.py @@ -1,9 +1,10 @@ import socket, time, json, datetime, struct, binascii, ssl, os, os.path -from configparser import ConfigParser, NoSectionError, NoOptionError +from configparser import RawConfigParser, NoSectionError, NoOptionError from collections import defaultdict import traceback, sys, platform from ipaddress import ip_network, ip_address import logging +from tempfile import gettempdir from electrumpersonalserver.server.jsonrpc import JsonRpc, JsonRpcError import electrumpersonalserver.server.hashes as hashes @@ -606,57 +607,47 @@ def obtain_rpc_username_password(datadir): def parse_args(): from argparse import ArgumentParser - from tempfile import gettempdir parser = ArgumentParser(description='Electrum Personal Server daemon') parser.add_argument('config_file', help='configuration file (mandatory)') - parser.add_argument('-l', '--log', help='log file', - default='{}/electrumpersonalserver.log'.format( - gettempdir())) - parser.add_argument('-a', '--appendlog', action='store_true', - help='append to log file') - logfmt = '%(levelname)s:%(asctime)s: %(message)s' - parser.add_argument('-f', '--logfmt', default=logfmt, - help='log format') - loglvls = [l for l in ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL')] - parser.add_argument('--loglevel', default='INFO', choices=loglvls, - help='Log level when echoing to terminal. Log file ' - + 'is always at DEBUG level') return parser.parse_args() #log for checking up/seeing your wallet, debug for when something has gone wrong -def logger_config(logger, fmt, filename, logfilemode, stdout_loglevel): - formatter = logging.Formatter(fmt) +def logger_config(logger, config): + formatter = logging.Formatter(config.get("logging", "log_format", + fallback="%(levelname)s:%(asctime)s: %(message)s")) logstream = logging.StreamHandler() logstream.setFormatter(formatter) - logstream.setLevel(stdout_loglevel) + logstream.setLevel(config.get("logging", "log_level_stdout", fallback= + "INFO")) logger.addHandler(logstream) - if filename: - logfile = logging.FileHandler(filename, mode=logfilemode) - logfile.setFormatter(formatter) - logfile.setLevel(logging.DEBUG) - logger.addHandler(logfile) + filename = config.get("logging", "log_file_location", fallback="") + if len(filename.strip()) == 0: + filename= gettempdir() + "/electrumpersonalserver.log" + logfile = logging.FileHandler(filename, mode=('a' if + config.get("logging", "append_log", fallback="false") else 'w')) + logfile.setFormatter(formatter) + logfile.setLevel(logging.DEBUG) + logger.addHandler(logfile) logger.setLevel(logging.DEBUG) - return logger + return logger, filename def main(): opts = parse_args() - logger = logging.getLogger('ELECTRUMPERSONALSERVER') - logger = logger_config(logger, fmt=opts.logfmt, filename=opts.log, - logfilemode='a' if opts.appendlog else 'w', - stdout_loglevel=opts.loglevel) - logger.info('Starting Electrum Personal Server') - logger.info('Logging to ' + opts.log) try: - config = ConfigParser() + config = RawConfigParser() config.read(opts.config_file) config.options("master-public-keys") except NoSectionError: - logger.error("Non-existant configuration file {}".format( + print("ERROR: Non-existant configuration file {}".format( opts.config_file)) return + logger = logging.getLogger('ELECTRUMPERSONALSERVER') + logger, logfilename = logger_config(logger, config) + logger.info('Starting Electrum Personal Server') + logger.info('Logging to ' + logfilename) try: rpc_u = config.get("bitcoin-rpc", "rpc_user") rpc_p = config.get("bitcoin-rpc", "rpc_password") @@ -760,21 +751,18 @@ def search_for_block_height_of_date(datestr, rpc): def rescan(): opts = parse_args() - logger = logging.getLogger('ELECTRUMPERSONALSERVER') - logger = logger_config(logger, fmt=opts.logfmt, filename=opts.log, - logfilemode='a' if opts.appendlog else 'w', - stdout_loglevel=opts.loglevel) - logger.setLevel(opts.loglevel) - logger.info('Starting the Electrum Personal Server rescan script') - logger.info('Logging to ' + opts.log) try: - config = ConfigParser() + config = RawConfigParser() config.read(opts.config_file) config.options("master-public-keys") except NoSectionError: - logger.error("Non-existant configuration file {}".format( + print("ERROR: Non-existant configuration file {}".format( opts.config_file)) return + logger = logging.getLogger('ELECTRUMPERSONALSERVER') + logger, logfilename = logger_config(logger, config) + logger.info('Starting Electrum Personal Server rescan script') + logger.info('Logging to ' + logfilename) try: rpc_u = config.get("bitcoin-rpc", "rpc_user") rpc_p = config.get("bitcoin-rpc", "rpc_password")