forked from LBRYCommunity/lbry-sdk
Merge pull request #2815 from lbryio/apply_share_usage_data_live
apply share_usage_data as its set, without restarting
This commit is contained in:
commit
55f4eb80ba
5 changed files with 55 additions and 24 deletions
|
@ -256,8 +256,7 @@ def setup_logging(logger: logging.Logger, args: argparse.Namespace, conf: Config
|
|||
else:
|
||||
logger.getChild('lbry').setLevel(logging.DEBUG)
|
||||
|
||||
if conf.share_usage_data:
|
||||
loggly_handler = get_loggly_handler()
|
||||
loggly_handler = get_loggly_handler(conf)
|
||||
loggly_handler.setLevel(logging.ERROR)
|
||||
logger.getChild('lbry').addHandler(loggly_handler)
|
||||
|
||||
|
|
|
@ -110,7 +110,6 @@ class AnalyticsManager:
|
|||
self.cookies = {}
|
||||
self.url = ANALYTICS_ENDPOINT
|
||||
self._write_key = utils.deobfuscate(ANALYTICS_TOKEN)
|
||||
self._enabled = conf.share_usage_data
|
||||
self._tracked_data = collections.defaultdict(list)
|
||||
self.context = _make_context(system_info.get_platform())
|
||||
self.installation_id = installation_id
|
||||
|
@ -118,20 +117,24 @@ class AnalyticsManager:
|
|||
self.task: typing.Optional[asyncio.Task] = None
|
||||
self.external_ip: typing.Optional[str] = None
|
||||
|
||||
@property
|
||||
def enabled(self):
|
||||
return self.conf.share_usage_data
|
||||
|
||||
@property
|
||||
def is_started(self):
|
||||
return self.task is not None
|
||||
|
||||
async def start(self):
|
||||
if self._enabled and self.task is None:
|
||||
self.external_ip = await utils.get_external_ip()
|
||||
if self.task is None:
|
||||
self.task = asyncio.create_task(self.run())
|
||||
|
||||
async def run(self):
|
||||
while True:
|
||||
if self.enabled:
|
||||
self.external_ip = await utils.get_external_ip()
|
||||
await self._send_heartbeat()
|
||||
await asyncio.sleep(1800)
|
||||
self.external_ip = await utils.get_external_ip()
|
||||
|
||||
def stop(self):
|
||||
if self.task is not None and not self.task.done():
|
||||
|
@ -154,7 +157,7 @@ class AnalyticsManager:
|
|||
|
||||
async def track(self, event: typing.Dict):
|
||||
"""Send a single tracking event"""
|
||||
if self._enabled:
|
||||
if self.enabled:
|
||||
log.debug('Sending track event: %s', event)
|
||||
await self._post(event)
|
||||
|
||||
|
|
|
@ -3,10 +3,12 @@ import json
|
|||
import logging.handlers
|
||||
import traceback
|
||||
|
||||
import typing
|
||||
from aiohttp.client_exceptions import ClientError
|
||||
import aiohttp
|
||||
from lbry import utils, __version__
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from lbry.conf import Config
|
||||
|
||||
LOGGLY_TOKEN = 'BQEzZmMzLJHgAGxkBF00LGD0YGuyATVgAmqxAQEuAQZ2BQH4'
|
||||
|
||||
|
@ -36,17 +38,19 @@ class JsonFormatter(logging.Formatter):
|
|||
|
||||
|
||||
class HTTPSLogglyHandler(logging.Handler):
|
||||
def __init__(self, loggly_token: str, fqdn=False, localname=None, facility=None, cookies=None):
|
||||
def __init__(self, loggly_token: str, config: 'Config'):
|
||||
super().__init__()
|
||||
self.fqdn = fqdn
|
||||
self.localname = localname
|
||||
self.facility = facility
|
||||
self.cookies = cookies or {}
|
||||
self.cookies = {}
|
||||
self.url = "https://logs-01.loggly.com/inputs/{token}/tag/{tag}".format(
|
||||
token=utils.deobfuscate(loggly_token), tag='lbrynet-' + __version__
|
||||
)
|
||||
self._loop = asyncio.get_event_loop()
|
||||
self._session = aiohttp.ClientSession()
|
||||
self._config = config
|
||||
|
||||
@property
|
||||
def enabled(self):
|
||||
return self._config.share_usage_data
|
||||
|
||||
@staticmethod
|
||||
def get_full_message(record):
|
||||
|
@ -62,12 +66,14 @@ class HTTPSLogglyHandler(logging.Handler):
|
|||
cookies=self.cookies) as response:
|
||||
self.cookies.update(response.cookies)
|
||||
except ClientError:
|
||||
if self._loop.is_running() and retry:
|
||||
if self._loop.is_running() and retry and self.enabled:
|
||||
await self._session.close()
|
||||
self._session = aiohttp.ClientSession()
|
||||
return await self._emit(record, retry=False)
|
||||
|
||||
def emit(self, record):
|
||||
if not self.enabled:
|
||||
return
|
||||
try:
|
||||
asyncio.ensure_future(self._emit(record), loop=self._loop)
|
||||
except RuntimeError: # TODO: use a second loop
|
||||
|
@ -83,7 +89,7 @@ class HTTPSLogglyHandler(logging.Handler):
|
|||
pass
|
||||
|
||||
|
||||
def get_loggly_handler():
|
||||
handler = HTTPSLogglyHandler(LOGGLY_TOKEN)
|
||||
def get_loggly_handler(config):
|
||||
handler = HTTPSLogglyHandler(LOGGLY_TOKEN, config=config)
|
||||
handler.setFormatter(JsonFormatter())
|
||||
return handler
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from lbry.extras.daemon.loggly_handler import get_loggly_handler
|
||||
from lbry.testcase import CommandTestCase
|
||||
|
||||
|
||||
|
@ -11,6 +12,7 @@ class AddressManagement(CommandTestCase):
|
|||
self.assertItemCount(single, 1)
|
||||
self.assertEqual(single['items'][0], addresses['items'][11])
|
||||
|
||||
|
||||
class SettingsManagement(CommandTestCase):
|
||||
|
||||
async def test_settings(self):
|
||||
|
@ -23,3 +25,16 @@ class SettingsManagement(CommandTestCase):
|
|||
setting = self.daemon.jsonrpc_settings_clear('lbryum_servers')
|
||||
self.assertEqual(setting['lbryum_servers'][0], ('spv11.lbry.com', 50001))
|
||||
self.assertEqual(self.daemon.jsonrpc_settings_get()['lbryum_servers'][0], ('spv11.lbry.com', 50001))
|
||||
|
||||
# test_privacy_settings (merged for reducing test time, unmerge when its fast)
|
||||
# tests that changing share_usage_data propagates to the relevant properties
|
||||
self.assertFalse(self.daemon.jsonrpc_settings_get()['share_usage_data'])
|
||||
loggly = get_loggly_handler(self.daemon.conf)
|
||||
self.addCleanup(loggly.close)
|
||||
self.assertFalse(self.daemon.analytics_manager.enabled)
|
||||
self.assertFalse(loggly.enabled)
|
||||
self.daemon.jsonrpc_settings_set('share_usage_data', True)
|
||||
self.assertTrue(self.daemon.jsonrpc_settings_get()['share_usage_data'])
|
||||
self.assertTrue(self.daemon.analytics_manager.enabled)
|
||||
self.assertTrue(loggly.enabled)
|
||||
self.daemon.jsonrpc_settings_set('share_usage_data', False)
|
||||
|
|
|
@ -64,8 +64,9 @@ class CLILoggingTest(AsyncioTestCase):
|
|||
self.assertTrue(log.isEnabledFor(logging.INFO))
|
||||
self.assertFalse(log.isEnabledFor(logging.DEBUG))
|
||||
self.assertFalse(log.isEnabledFor(logging.DEBUG))
|
||||
self.assertEqual(len(log.handlers), 1)
|
||||
self.assertEqual(len(log.handlers), 2)
|
||||
self.assertIsInstance(log.handlers[0], logging.handlers.RotatingFileHandler)
|
||||
self.assertFalse(log.handlers[1].enabled)
|
||||
|
||||
async with get_logger(["start", "--verbose"]) as log:
|
||||
self.assertTrue(log.getChild("lbry").isEnabledFor(logging.DEBUG))
|
||||
|
@ -81,23 +82,30 @@ class CLILoggingTest(AsyncioTestCase):
|
|||
|
||||
async def test_loggly(self):
|
||||
async with get_logger(["start"]) as log: # default share_usage_data=False
|
||||
self.assertEqual(len(log.getChild("lbry").handlers), 2) # file and console
|
||||
log = log.getChild("lbry")
|
||||
self.assertIsInstance(log.handlers[0], logging.StreamHandler)
|
||||
self.assertIsInstance(log.handlers[1], logging.StreamHandler)
|
||||
self.assertIsInstance(log.handlers[2], HTTPSLogglyHandler)
|
||||
self.assertFalse(log.handlers[2].enabled)
|
||||
async with get_logger(["start"], share_usage_data=True) as log:
|
||||
log = log.getChild("lbry")
|
||||
self.assertEqual(len(log.handlers), 3)
|
||||
self.assertIsInstance(log.handlers[2], HTTPSLogglyHandler)
|
||||
self.assertTrue(log.handlers[2].enabled)
|
||||
async with get_logger(["start"], share_usage_data=False) as log: # explicit share_usage_data=False
|
||||
log = log.getChild("lbry")
|
||||
self.assertEqual(len(log.handlers), 2)
|
||||
self.assertEqual(len(log.handlers), 3)
|
||||
self.assertIsInstance(log.handlers[2], HTTPSLogglyHandler)
|
||||
self.assertFalse(log.handlers[2].enabled)
|
||||
|
||||
async def test_quiet(self):
|
||||
async with get_logger(["start"]) as log: # default is loud
|
||||
log = log.getChild("lbry")
|
||||
self.assertEqual(len(log.handlers), 2)
|
||||
self.assertEqual(len(log.handlers), 3)
|
||||
self.assertIs(type(log.handlers[1]), logging.StreamHandler)
|
||||
async with get_logger(["start", "--quiet"]) as log:
|
||||
log = log.getChild("lbry")
|
||||
self.assertEqual(len(log.handlers), 1)
|
||||
self.assertEqual(len(log.handlers), 2)
|
||||
self.assertIsNot(type(log.handlers[0]), logging.StreamHandler)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue