From a9ee2aa09c00b6adc396c666d6e970e2b58918e6 Mon Sep 17 00:00:00 2001 From: nicolargo Date: Sat, 19 Nov 2022 15:27:12 +0100 Subject: Replace json by ujson #2201 --- README.rst | 1 + glances/client.py | 6 +++--- glances/client_browser.py | 10 +++++----- glances/exports/glances_export.py | 4 ++-- glances/exports/glances_json.py | 6 +++--- glances/exports/glances_kafka.py | 4 ++-- glances/exports/glances_mqtt.py | 4 ++-- glances/exports/glances_zeromq.py | 4 ++-- glances/globals.py | 6 +++--- glances/outputs/glances_bottle.py | 20 ++++++++++---------- glances/plugins/glances_ip.py | 2 +- glances/server.py | 10 +++++----- requirements.txt | 3 +++ 13 files changed, 42 insertions(+), 38 deletions(-) diff --git a/README.rst b/README.rst index 2cc9f924..480a59a3 100644 --- a/README.rst +++ b/README.rst @@ -75,6 +75,7 @@ Requirements - ``python>=2.7`` or ``python>=3.4`` - ``psutil>=5.3.0`` (better with latest version) - ``defusedxml`` (in order to monkey patch xmlrpc) +- ``ujson`` (an optimized alternative to the standard json module) - ``future`` (for Python 2 support) *Note for Python 2.6 users* diff --git a/glances/client.py b/glances/client.py index 46c81db4..d87fe658 100644 --- a/glances/client.py +++ b/glances/client.py @@ -9,7 +9,7 @@ """Manage the Glances client.""" -import json +import ujson import socket import sys import time @@ -119,7 +119,7 @@ class GlancesClient(object): if __version__.split('.')[0] == client_version.split('.')[0]: # Init stats self.stats = GlancesStatsClient(config=self.config, args=self.args) - self.stats.set_plugins(json.loads(self.client.getAllPlugins())) + self.stats.set_plugins(ujson.loads(self.client.getAllPlugins())) logger.debug("Client version: {} / Server version: {}".format(__version__, client_version)) else: self.log_and_exit( @@ -198,7 +198,7 @@ class GlancesClient(object): """ # Update the stats try: - server_stats = json.loads(self.client.getAll()) + server_stats = ujson.loads(self.client.getAll()) except socket.error: # Client cannot get server stats return "Disconnected" diff --git a/glances/client_browser.py b/glances/client_browser.py index 13161e3c..522ccc98 100644 --- a/glances/client_browser.py +++ b/glances/client_browser.py @@ -9,7 +9,7 @@ """Manage the Glances client browser (list of Glances server).""" -import json +import ujson import socket import threading @@ -98,12 +98,12 @@ class GlancesClientBrowser(object): # Mandatory stats try: # CPU% - cpu_percent = 100 - json.loads(s.getCpu())['idle'] + cpu_percent = 100 - ujson.loads(s.getCpu())['idle'] server['cpu_percent'] = '{:.1f}'.format(cpu_percent) # MEM% - server['mem_percent'] = json.loads(s.getMem())['percent'] + server['mem_percent'] = ujson.loads(s.getMem())['percent'] # OS (Human Readable name) - server['hr_name'] = json.loads(s.getSystem())['hr_name'] + server['hr_name'] = ujson.loads(s.getSystem())['hr_name'] except (socket.error, Fault, KeyError) as e: logger.debug("Error while grabbing stats form {}: {}".format(uri, e)) server['status'] = 'OFFLINE' @@ -123,7 +123,7 @@ class GlancesClientBrowser(object): # Optional stats (load is not available on Windows OS) try: # LOAD - load_min5 = json.loads(s.getLoad())['min5'] + load_min5 = ujson.loads(s.getLoad())['min5'] server['load_min5'] = '{:.2f}'.format(load_min5) except Exception as e: logger.warning("Error while grabbing stats form {}: {}".format(uri, e)) diff --git a/glances/exports/glances_export.py b/glances/exports/glances_export.py index 1b650901..e8e0667f 100644 --- a/glances/exports/glances_export.py +++ b/glances/exports/glances_export.py @@ -13,7 +13,7 @@ I am your father... ...for all Glances exports IF. """ -import json +from glances.globals import json_dumps from glances.compat import NoOptionError, NoSectionError, iteritems, iterkeys from glances.logger import logger @@ -185,7 +185,7 @@ class GlancesExport(object): # Walk through the dict for key, value in iteritems(stats): if isinstance(value, bool): - value = json.dumps(value) + value = json_dumps(value) if isinstance(value, list): try: value = value[0] diff --git a/glances/exports/glances_json.py b/glances/exports/glances_json.py index 82d344c2..6a9e5fe9 100644 --- a/glances/exports/glances_json.py +++ b/glances/exports/glances_json.py @@ -1,8 +1,8 @@ """JSON interface class.""" import sys -import json +from glances.globals import json_dumps from glances.compat import PY3, listkeys from glances.logger import logger from glances.exports.glances_export import GlancesExport @@ -55,10 +55,10 @@ class Export(GlancesExport): # Export stats to JSON file if PY3: with open(self.json_filename, "w") as self.json_file: - self.json_file.write("{}\n".format(json.dumps(self.buffer))) + self.json_file.write("{}\n".format(json_dumps(self.buffer))) else: with open(self.json_filename, "wb") as self.json_file: - self.json_file.write("{}\n".format(json.dumps(self.buffer))) + self.json_file.write("{}\n".format(json_dumps(self.buffer))) # Reset buffer self.buffer = {} diff --git a/glances/exports/glances_kafka.py b/glances/exports/glances_kafka.py index 275b9595..ccb51b43 100644 --- a/glances/exports/glances_kafka.py +++ b/glances/exports/glances_kafka.py @@ -13,9 +13,9 @@ import sys from glances.logger import logger from glances.exports.glances_export import GlancesExport +from glances.globals import json_dumps from kafka import KafkaProducer -import json class Export(GlancesExport): @@ -54,7 +54,7 @@ class Export(GlancesExport): try: s = KafkaProducer( bootstrap_servers=server_uri, - value_serializer=lambda v: json.dumps(v).encode('utf-8'), + value_serializer=lambda v: json_dumps(v).encode('utf-8'), compression_type=self.compression, ) except Exception as e: diff --git a/glances/exports/glances_mqtt.py b/glances/exports/glances_mqtt.py index 0f3d3587..ea2c7941 100644 --- a/glances/exports/glances_mqtt.py +++ b/glances/exports/glances_mqtt.py @@ -11,11 +11,11 @@ import socket import string -import json import sys from glances.logger import logger from glances.exports.glances_export import GlancesExport +from glances.globals import json_dumps # Import paho for MQTT from requests import certs @@ -116,7 +116,7 @@ class Export(GlancesExport): # Add the value current_level[split_key[len(split_key) - 1]] = sensor_values[key] - json_value = json.dumps(output_value) + json_value = json_dumps(output_value) self.client.publish(topic, json_value) except Exception as e: logger.error("Can not export stats to MQTT server (%s)" % e) diff --git a/glances/exports/glances_zeromq.py b/glances/exports/glances_zeromq.py index 0f2fa310..b7f8e1c0 100644 --- a/glances/exports/glances_zeromq.py +++ b/glances/exports/glances_zeromq.py @@ -10,11 +10,11 @@ """ZeroMQ interface class.""" import sys -import json from glances.compat import b from glances.logger import logger from glances.exports.glances_export import GlancesExport +from glances.globals import json_dumps import zmq from zmq.utils.strtypes import asbytes @@ -84,7 +84,7 @@ class Export(GlancesExport): # - First frame containing the following prefix (STRING) # - Second frame with the Glances plugin name (STRING) # - Third frame with the Glances plugin stats (JSON) - message = [b(self.prefix), b(name), asbytes(json.dumps(data))] + message = [b(self.prefix), b(name), asbytes(json_dumps(data))] # Write data to the ZeroMQ bus # Result can be view: tcp://host:port diff --git a/glances/globals.py b/glances/globals.py index c7506453..10a40e0d 100644 --- a/glances/globals.py +++ b/glances/globals.py @@ -13,7 +13,7 @@ import errno import os import sys import platform -import json +import ujson from operator import itemgetter # OS constants (some libraries/features are OS-dependent) @@ -53,9 +53,9 @@ def json_dumps(data): Manage the issue #815 for Windows OS with UnicodeDecodeError catching. """ try: - return json.dumps(data) + return ujson.dumps(data) except UnicodeDecodeError: - return json.dumps(data, ensure_ascii=False) + return ujson.dumps(data, ensure_ascii=False) def json_dumps_dictlist(data, item): diff --git a/glances/outputs/glances_bottle.py b/glances/outputs/glances_bottle.py index f2e030cb..5c475a7f 100644 --- a/glances/outputs/glances_bottle.py +++ b/glances/outputs/glances_bottle.py @@ -9,7 +9,6 @@ """Web interface class.""" -import json import os import sys import tempfile @@ -18,6 +17,7 @@ import webbrowser import zlib import socket +from glances.globals import json_dumps from glances.compat import b from glances.timer import Timer from glances.logger import logger @@ -240,7 +240,7 @@ class GlancesBottle(object): # Update the stat view_data = self.stats.get_plugin("help").get_view_data() try: - plist = json.dumps(view_data, sort_keys=True) + plist = json_dumps(view_data) except Exception as e: abort(404, "Cannot get help view data (%s)" % str(e)) return plist @@ -278,7 +278,7 @@ class GlancesBottle(object): self.__update__() try: - plist = json.dumps(self.plugins_list) + plist = json_dumps(self.plugins_list) except Exception as e: abort(404, "Cannot get plugin list (%s)" % str(e)) return plist @@ -307,7 +307,7 @@ class GlancesBottle(object): try: # Get the JSON value of the stat ID - statval = json.dumps(self.stats.getAllAsDict()) + statval = json_dumps(self.stats.getAllAsDict()) except Exception as e: abort(404, "Cannot get stats (%s)" % str(e)) @@ -326,7 +326,7 @@ class GlancesBottle(object): try: # Get the JSON value of the stat limits - limits = json.dumps(self.stats.getAllLimitsAsDict()) + limits = json_dumps(self.stats.getAllLimitsAsDict()) except Exception as e: abort(404, "Cannot get limits (%s)" % (str(e))) return limits @@ -344,7 +344,7 @@ class GlancesBottle(object): try: # Get the JSON value of the stat view - limits = json.dumps(self.stats.getAllViewsAsDict()) + limits = json_dumps(self.stats.getAllViewsAsDict()) except Exception as e: abort(404, "Cannot get views (%s)" % (str(e))) return limits @@ -528,7 +528,7 @@ class GlancesBottle(object): try: # Get the JSON value of the config' dict - args_json = json.dumps(self.config.as_dict()) + args_json = json_dumps(self.config.as_dict()) except Exception as e: abort(404, "Cannot get config (%s)" % str(e)) return args_json @@ -550,7 +550,7 @@ class GlancesBottle(object): try: # Get the JSON value of the config' dict - args_json = json.dumps(config_dict[item]) + args_json = json_dumps(config_dict[item]) except Exception as e: abort(404, "Cannot get config item (%s)" % str(e)) return args_json @@ -569,7 +569,7 @@ class GlancesBottle(object): # Get the JSON value of the args' dict # Use vars to convert namespace to dict # Source: https://docs.python.org/%s/library/functions.html#vars - args_json = json.dumps(vars(self.args)) + args_json = json_dumps(vars(self.args)) except Exception as e: abort(404, "Cannot get args (%s)" % str(e)) return args_json @@ -592,7 +592,7 @@ class GlancesBottle(object): # Get the JSON value of the args' dict # Use vars to convert namespace to dict # Source: https://docs.python.org/%s/library/functions.html#vars - args_json = json.dumps(vars(self.args)[item]) + args_json = json_dumps(vars(self.args)[item]) except Exception as e: abort(404, "Cannot get args item (%s)" % str(e)) return args_json diff --git a/glances/plugins/glances_ip.py b/glances/plugins/glances_ip.py index bacbb3ce..6813d54a 100644 --- a/glances/plugins/glances_ip.py +++ b/glances/plugins/glances_ip.py @@ -10,7 +10,7 @@ """IP plugin.""" import threading -from json import loads +from ujson import loads from glances.compat import queue, urlopen, urlopen_auth from glances.logger import logger diff --git a/glances/server.py b/glances/server.py index 80bafb64..b6a3e194 100644 --- a/glances/server.py +++ b/glances/server.py @@ -9,7 +9,7 @@ """Manage the Glances server.""" -import json +from glances.globals import json_dumps import socket import sys from base64 import b64decode @@ -147,19 +147,19 @@ class GlancesInstance(object): def getAll(self): # Update and return all the stats self.__update__() - return json.dumps(self.stats.getAll()) + return json_dumps(self.stats.getAll()) def getAllPlugins(self): # Return the plugins list - return json.dumps(self.stats.getPluginsList()) + return json_dumps(self.stats.getPluginsList()) def getAllLimits(self): # Return all the plugins limits - return json.dumps(self.stats.getAllLimitsAsDict()) + return json_dumps(self.stats.getAllLimitsAsDict()) def getAllViews(self): # Return all the plugins views - return json.dumps(self.stats.getAllViewsAsDict()) + return json_dumps(self.stats.getAllViewsAsDict()) def __getattr__(self, item): """Overwrite the getattr method in case of attribute is not found. diff --git a/requirements.txt b/requirements.txt index 87c46a0a..b90ec686 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,3 +2,6 @@ psutil>=5.3.0 defusedxml packaging future; python_version < "3.0" +ujson<3; python_version < "3.0" +ujson<5; python_version >= "3.6" and python_version < "3.7" +ujson; python_version >= "3.7" -- cgit v1.2.3