From 7491000a13fcaf1c22ba34cf081416bc4833a3f1 Mon Sep 17 00:00:00 2001 From: Chuddah Date: Sun, 16 Feb 2020 22:17:05 +0000 Subject: [PATCH 1/2] Replaced debug output of json.dumps with an indirection to lazy __str__. json.dumps is a processing intensive operation. This is being called every time data is received from the server (most noticeably during library updates) for debug logging. If the user has debug logging disabled (the default option) then the user is still paying for processing which is discarded. The fix is to add a level of indirection where the dumps function is only called if a string representation of the json is requested; ie. when the debug string is evaluated. --- jellyfin_kodi/entrypoint/default.py | 4 ++-- jellyfin_kodi/entrypoint/service.py | 4 ++-- jellyfin_kodi/helper/debug.py | 15 +++++++++++++++ jellyfin_kodi/jellyfin/http.py | 5 +++-- jellyfin_kodi/monitor.py | 4 ++-- 5 files changed, 24 insertions(+), 8 deletions(-) create mode 100644 jellyfin_kodi/helper/debug.py diff --git a/jellyfin_kodi/entrypoint/default.py b/jellyfin_kodi/entrypoint/default.py index ba8a7573..97f1ac21 100644 --- a/jellyfin_kodi/entrypoint/default.py +++ b/jellyfin_kodi/entrypoint/default.py @@ -15,7 +15,7 @@ import client from database import reset, get_sync, Database, jellyfin_db, get_credentials from objects import Objects, Actions from downloader import TheVoid -from helper import translate, event, settings, window, dialog, api, JSONRPC +from helper import translate, event, settings, window, dialog, api, JSONRPC, debug ################################################################################################# @@ -45,7 +45,7 @@ class Events(object): if server == 'None': server = None - LOG.info("path: %s params: %s", path, json.dumps(params, indent=4)) + LOG.info("path: %s params: %s", path, debug.JsonDebugPrinter(params)) if '/extrafanart' in base_url: diff --git a/jellyfin_kodi/entrypoint/service.py b/jellyfin_kodi/entrypoint/service.py index b3b0ed2b..28ebc155 100644 --- a/jellyfin_kodi/entrypoint/service.py +++ b/jellyfin_kodi/entrypoint/service.py @@ -20,7 +20,7 @@ import library import setup import monitor from views import Views, verify_kodi_defaults -from helper import translate, window, settings, event, dialog +from helper import translate, window, settings, event, dialog, debug from jellyfin import Jellyfin ################################################################################################# @@ -171,7 +171,7 @@ class Service(xbmc.Monitor): data = json.loads(data) - LOG.debug("[ %s: %s ] %s", sender, method, json.dumps(data, indent=4)) + LOG.debug("[ %s: %s ] %s", sender, method, debug.JsonDebugPrinter(data)) if method == 'ServerOnline': if data.get('ServerId') is None: diff --git a/jellyfin_kodi/helper/debug.py b/jellyfin_kodi/helper/debug.py new file mode 100644 index 00000000..7dc2e4dc --- /dev/null +++ b/jellyfin_kodi/helper/debug.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- + +################################################################################################## + +import json + +################################################################################################## + +class JsonDebugPrinter(object): + + def __init__(self, json): + self.json = json + + def __str__(self): + return json.dumps(self.json, indent=4) diff --git a/jellyfin_kodi/jellyfin/http.py b/jellyfin_kodi/jellyfin/http.py index 63c58f3b..1b7921ed 100644 --- a/jellyfin_kodi/jellyfin/http.py +++ b/jellyfin_kodi/jellyfin/http.py @@ -11,6 +11,7 @@ import requests from six import string_types from .exceptions import HTTPException +from helper import debug ################################################################################################# @@ -80,7 +81,7 @@ class HTTP(object): raise AttributeError("Request cannot be empty") data = self._request(data) - LOG.debug("--->[ http ] %s", json.dumps(data, indent=4)) + LOG.debug("--->[ http ] %s", debug.JsonDebugPrinter(data)) retry = data.pop('retry', 5) while True: @@ -162,7 +163,7 @@ class HTTP(object): elapsed = int(r.elapsed.total_seconds() * 1000) response = r.json() LOG.debug("---<[ http ][%s ms]", elapsed) - LOG.debug(json.dumps(response, indent=4)) + LOG.debug(debug.JsonDebugPrinter(response)) return response except ValueError: diff --git a/jellyfin_kodi/monitor.py b/jellyfin_kodi/monitor.py index 00f88d12..804fa506 100644 --- a/jellyfin_kodi/monitor.py +++ b/jellyfin_kodi/monitor.py @@ -15,7 +15,7 @@ import downloader import player from client import get_device_id from objects import PlaylistWorker, on_play, on_update, special_listener -from helper import translate, settings, window, dialog, api, JSONRPC +from helper import translate, settings, window, dialog, api, JSONRPC, debug from jellyfin import Jellyfin from webservice import WebService @@ -96,7 +96,7 @@ class Monitor(xbmc.Monitor): data = json.loads(data) - LOG.debug("[ %s: %s ] %s", sender, method, json.dumps(data, indent=4)) + LOG.debug("[ %s: %s ] %s", sender, method, debug.JsonDebugPrinter(data)) if self.sleep: LOG.info("System.OnSleep detected, ignore monitor request.") From de493d13dde30ef3cf7d2f50dc98cfa2033f16c2 Mon Sep 17 00:00:00 2001 From: Chuddah Date: Sat, 22 Feb 2020 15:04:28 +0000 Subject: [PATCH 2/2] Moved JsonDebugPrinter to existing utils module --- jellyfin_kodi/entrypoint/default.py | 5 +++-- jellyfin_kodi/entrypoint/service.py | 5 +++-- jellyfin_kodi/helper/debug.py | 15 --------------- jellyfin_kodi/helper/utils.py | 13 +++++++++++++ jellyfin_kodi/jellyfin/http.py | 6 +++--- jellyfin_kodi/monitor.py | 5 +++-- 6 files changed, 25 insertions(+), 24 deletions(-) delete mode 100644 jellyfin_kodi/helper/debug.py diff --git a/jellyfin_kodi/entrypoint/default.py b/jellyfin_kodi/entrypoint/default.py index 97f1ac21..49a90f04 100644 --- a/jellyfin_kodi/entrypoint/default.py +++ b/jellyfin_kodi/entrypoint/default.py @@ -15,7 +15,8 @@ import client from database import reset, get_sync, Database, jellyfin_db, get_credentials from objects import Objects, Actions from downloader import TheVoid -from helper import translate, event, settings, window, dialog, api, JSONRPC, debug +from helper import translate, event, settings, window, dialog, api, JSONRPC +from helper.utils import JsonDebugPrinter ################################################################################################# @@ -45,7 +46,7 @@ class Events(object): if server == 'None': server = None - LOG.info("path: %s params: %s", path, debug.JsonDebugPrinter(params)) + LOG.info("path: %s params: %s", path, JsonDebugPrinter(params)) if '/extrafanart' in base_url: diff --git a/jellyfin_kodi/entrypoint/service.py b/jellyfin_kodi/entrypoint/service.py index 28ebc155..27ee4372 100644 --- a/jellyfin_kodi/entrypoint/service.py +++ b/jellyfin_kodi/entrypoint/service.py @@ -20,7 +20,8 @@ import library import setup import monitor from views import Views, verify_kodi_defaults -from helper import translate, window, settings, event, dialog, debug +from helper import translate, window, settings, event, dialog +from helper.utils import JsonDebugPrinter from jellyfin import Jellyfin ################################################################################################# @@ -171,7 +172,7 @@ class Service(xbmc.Monitor): data = json.loads(data) - LOG.debug("[ %s: %s ] %s", sender, method, debug.JsonDebugPrinter(data)) + LOG.debug("[ %s: %s ] %s", sender, method, JsonDebugPrinter(data)) if method == 'ServerOnline': if data.get('ServerId') is None: diff --git a/jellyfin_kodi/helper/debug.py b/jellyfin_kodi/helper/debug.py deleted file mode 100644 index 7dc2e4dc..00000000 --- a/jellyfin_kodi/helper/debug.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- - -################################################################################################## - -import json - -################################################################################################## - -class JsonDebugPrinter(object): - - def __init__(self, json): - self.json = json - - def __str__(self): - return json.dumps(self.json, indent=4) diff --git a/jellyfin_kodi/helper/utils.py b/jellyfin_kodi/helper/utils.py index ea93d27f..48c88724 100644 --- a/jellyfin_kodi/helper/utils.py +++ b/jellyfin_kodi/helper/utils.py @@ -494,3 +494,16 @@ def has_attribute(obj, name): return True except AttributeError: return False + + +class JsonDebugPrinter(object): + + ''' Helper class to defer converting data to JSON until it is needed. + See: https://github.com/jellyfin/jellyfin-kodi/pull/193 + ''' + + def __init__(self, data): + self.data = data + + def __str__(self): + return json.dumps(self.data, indent=4) diff --git a/jellyfin_kodi/jellyfin/http.py b/jellyfin_kodi/jellyfin/http.py index 1b7921ed..be022420 100644 --- a/jellyfin_kodi/jellyfin/http.py +++ b/jellyfin_kodi/jellyfin/http.py @@ -11,7 +11,7 @@ import requests from six import string_types from .exceptions import HTTPException -from helper import debug +from helper.utils import JsonDebugPrinter ################################################################################################# @@ -81,7 +81,7 @@ class HTTP(object): raise AttributeError("Request cannot be empty") data = self._request(data) - LOG.debug("--->[ http ] %s", debug.JsonDebugPrinter(data)) + LOG.debug("--->[ http ] %s", JsonDebugPrinter(data)) retry = data.pop('retry', 5) while True: @@ -163,7 +163,7 @@ class HTTP(object): elapsed = int(r.elapsed.total_seconds() * 1000) response = r.json() LOG.debug("---<[ http ][%s ms]", elapsed) - LOG.debug(debug.JsonDebugPrinter(response)) + LOG.debug(JsonDebugPrinter(response)) return response except ValueError: diff --git a/jellyfin_kodi/monitor.py b/jellyfin_kodi/monitor.py index 804fa506..4adbaef2 100644 --- a/jellyfin_kodi/monitor.py +++ b/jellyfin_kodi/monitor.py @@ -15,7 +15,8 @@ import downloader import player from client import get_device_id from objects import PlaylistWorker, on_play, on_update, special_listener -from helper import translate, settings, window, dialog, api, JSONRPC, debug +from helper import translate, settings, window, dialog, api, JSONRPC +from helper.utils import JsonDebugPrinter from jellyfin import Jellyfin from webservice import WebService @@ -96,7 +97,7 @@ class Monitor(xbmc.Monitor): data = json.loads(data) - LOG.debug("[ %s: %s ] %s", sender, method, debug.JsonDebugPrinter(data)) + LOG.debug("[ %s: %s ] %s", sender, method, JsonDebugPrinter(data)) if self.sleep: LOG.info("System.OnSleep detected, ignore monitor request.")