diff --git a/.flake8 b/.flake8 index b4a2600a..d66d7164 100644 --- a/.flake8 +++ b/.flake8 @@ -1,20 +1,7 @@ [flake8] - +exclude = .git,__pycache__,docs/,build,dist ignore = - W504 # line break after binary operator - - # --- flake8-bugbear plugin - B007 # Loop control variable 'keyword' not used within the loop body. If this is intended, start the name with an underscore. - B014 # Redundant exception types in `except (IOError, OSError) as err:`. Write `except OSError as err:`, which catches exactly the same exceptions. - B008 # Do not perform function calls in argument defaults. - - # --- flake8-blind-except plugin - B902 # blind except Exception: statement - - # --- flake8-quotes plugin - Q000 # Double quotes found but single quotes preferred - - # --- flake8-quotes naming; disable all except N804 and N805 + W504, B007, B014, B008, B902, Q000, N801, N802, N803, N806, N807, N811, N812, N813, N814, N815, N816, N817, N818 # lines should not exceed 120 characters diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2d9d1376..cbe49e79 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -96,7 +96,7 @@ jobs: strategy: fail-fast: false matrix: - os: ['alpine'] + os: ['alpine', 'ubuntu'] tag: ${{ fromJson(needs.create_Docker_builds.outputs.tags) }} steps: - name: Checkout @@ -104,7 +104,7 @@ jobs: - name: Retrieve Repository Docker metadata id: docker_meta - uses: crazy-max/ghaction-docker-meta@v4.1.1 + uses: crazy-max/ghaction-docker-meta@v4.3.0 with: images: ${{ env.DEFAULT_DOCKER_IMAGE }} labels: | @@ -136,7 +136,7 @@ jobs: password: ${{ secrets.DOCKER_TOKEN }} - name: Build and push image - uses: docker/build-push-action@v3 + uses: docker/build-push-action@v4 with: push: ${{ env.PUSH_BRANCH == 'true' }} tags: "${{ env.DEFAULT_DOCKER_IMAGE }}:${{ matrix.os != 'alpine' && format('{0}-', matrix.os) || '' }}${{ matrix.tag.tag }}" diff --git a/Makefile b/Makefile index 23c358bd..6953d09d 100644 --- a/Makefile +++ b/Makefile @@ -64,6 +64,9 @@ flake8: venv-dev-upgrade ## Run flake8 linter. codespell: venv-dev-upgrade ## Run codespell to fix common misspellings in text files ./venv/bin/codespell -S .git,./docs/_build,./Glances.egg-info,./venv,./glances/outputs,*.svg -L hart,bu,te,statics +semgrep: venv-dev-upgrade ## Run semgrep to find bugs and enforce code standards + ./venv/bin/semgrep --config=auto --lang python --use-git-ignore ./glances + profiling: ## How to start the profiling of the Glances software @echo "Please complete and run: sudo ./venv/bin/py-spy record -o ./docs/_static/glances-flame.svg -d 60 -s --pid " @@ -137,6 +140,11 @@ docker-alpine: ## Generate local docker images (Alpine) docker build --target minimal -f ./docker-files/alpine.Dockerfile -t glances:local-alpine-minimal . docker build --target dev -f ./docker-files/alpine.Dockerfile -t glances:local-alpine-dev . +docker-ubuntu: ## Generate local docker images (Ubuntu) + docker build --target full -f ./docker-files/ubuntu.Dockerfile -t glances:local-ubuntu-full . + docker build --target minimal -f ./docker-files/ubuntu.Dockerfile -t glances:local-ubuntu-minimal . + docker build --target dev -f ./docker-files/ubuntu.Dockerfile -t glances:local-ubuntu-dev . + # =================================================================== # Run # =================================================================== @@ -151,13 +159,22 @@ run-local-conf: ## Start Glances in console mode with the system conf file ./venv/bin/python -m glances run-docker-alpine-minimal: ## Start Glances Alpine Docker minimal in console mode - docker run --rm -v /var/run/docker.sock:/var/run/docker.sock:ro --pid host --network host -it glances:local-alpine-minimal + docker run --rm -e TZ="${TZ}" -v /var/run/docker.sock:/var/run/docker.sock:ro --pid host --network host -it glances:local-alpine-minimal run-docker-alpine-full: ## Start Glances Alpine Docker full in console mode - docker run --rm -v /var/run/docker.sock:/var/run/docker.sock:ro --pid host --network host -it glances:local-alpine-full + docker run --rm -e TZ="${TZ}" -v /var/run/docker.sock:/var/run/docker.sock:ro --pid host --network host -it glances:local-alpine-full run-docker-alpine-dev: ## Start Glances Alpine Docker dev in console mode - docker run --rm -v /var/run/docker.sock:/var/run/docker.sock:ro --pid host --network host -it glances:local-alpine-dev + docker run --rm -e TZ="${TZ}" -v /var/run/docker.sock:/var/run/docker.sock:ro --pid host --network host -it glances:local-alpine-dev + +run-docker-ubuntu-minimal: ## Start Glances Ubuntu Docker minimal in console mode + docker run --rm -e TZ="${TZ}" -v /var/run/docker.sock:/var/run/docker.sock:ro --pid host --network host -it glances:local-ubuntu-minimal + +run-docker-ubuntu-full: ## Start Glances Ubuntu Docker full in console mode + docker run --rm -e TZ="${TZ}" -v /var/run/docker.sock:/var/run/docker.sock:ro --pid host --network host -it glances:local-ubuntu-full + +run-docker-ubuntu-dev: ## Start Glances Ubuntu Docker dev in console mode + docker run --rm -e TZ="${TZ}" -v /var/run/docker.sock:/var/run/docker.sock:ro --pid host --network host -it glances:local-ubuntu-dev run-webserver: ## Start Glances in Web server mode ./venv/bin/python -m glances -C ./conf/glances.conf -w diff --git a/NEWS.rst b/NEWS.rst index d876a860..a3ca28f4 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -2,11 +2,82 @@ Glances changelog ============================================================================== +=============== +Version 3.4.0 +=============== + + See roadmap here: https://github.com/nicolargo/glances/issues?q=is%3Aopen+is%3Aissue+milestone%3A%22Glances+3.4.0%22 + +=============== +Version 3.3.1.1 +=============== + +Hard patch on the master branch. + +Bug corrected: + + * "ModuleNotFoundError: No module named 'ujson'" #2246 + * Remove surrounding quotes for quoted command arguments #2247 (related to #2239) + =============== Version 3.3.1 =============== - Under development, see milestone https://github.com/nicolargo/glances/milestone/61 +Enhancements: + + * Minor change on the help screen + * Refactor some loop in the processes function + * Replace json by ujson #2201 + +Bug corrected: + + * Unable to see docker related information #2180 + * CSV export dependent on sort order for docker container cpu #2156 + * Error when process list is displayed in Programs mode #2209 + * Console formatting permanently messed up when other text printed #2211 + * API GET uptime returns formatted string, not seconds as the doc says #2158 + * Glances UI is breaking for multiline commands #2189 + +Documentation and CI: + + * Add unitary test for memory profiling + * Update memory profile chart + * Add run-docker-ubuntu-* in Makefile + * The open-web-browser option was missing dashes #2219 + * Correct regexp in glances.conf file example + * What is CW from network #2222 (related to discussion #2221) + * Change Glances repology URL + * Add example for the date format + * Correct Flake8 configuration file + * Drop UT for Python 3.5 and 3.6 (no more available in Ubuntu 22.04) + * Correct unitary test with Python 3.5 + * Update Makefile with comments + * Update Python minimal requirement for py3nvlm + * Update security policy (user can open private issue directly in Github) + * Add a simple run script. Entry point for IDE debuger + +Cyber security update: + + * Security alert on ujson < 5.4 + * Merge pull request #2243 from nicolargo/renovate/nvidia-cuda-12.x + * Merge pull request #2244 from nicolargo/renovate/crazy-max-ghaction-docker-meta-4.x + * Merge pull request #2228 from nicolargo/renovate/zeroconf-0.x + * Merge pull request #2242 from nicolargo/renovate/crazy-max-ghaction-docker-meta-4.x + * Merge pull request #2239 from mfridge/action-command-split + * Merge pull request #2165 from nicolargo/renovate/zeroconf-0.x + * Merge pull request #2199 from nicolargo/renovate/alpine-3.x + * Merge pull request #2202 from chncaption/oscs_fix_cdr0ts8au51t49so8c6g + * Bump loader-utils from 2.0.0 to 2.0.3 in /glances/outputs/static #2187 - Update Web lib + +Contributors for this version: + + * Nicolargo + * renovate[bot] + * chncaption + * fkwong + * *mfridge + +And also a big thanks to @RazCrimson (https://github.com/RazCrimson) for the support to the Glances community ! =============== Version 3.3.0.4 diff --git a/README.rst b/README.rst index 419b3570..db8d2631 100644 --- a/README.rst +++ b/README.rst @@ -40,16 +40,22 @@ Glances - An eye on your system Summary ======= -**Glances** is a cross-platform monitoring tool which aims to present a -large amount of monitoring information through a curses or Web -based interface. The information dynamically adapts depending on the -size of the user interface. +**Glances** is an open-source system cross-platform monitoring tool. +It allows real-time monitoring of various aspects of your system such as +CPU, memory, disk, network usage etc. It also allows monitoring of running processes, +logged in users, temperatures, voltages, fan speeds etc. +It also supports container monitoring, it supports different container management +systems such as Docker, LXC. The information is presented in an easy to read dashboard +and can also be used for remote monitoring of systems via a web interface or command +line interface. It is easy to install and use and can be customized to show only +the information that you are interested in. .. image:: https://raw.githubusercontent.com/nicolargo/glances/develop/docs/_static/glances-summary.png -It can also work in client/server mode. Remote monitoring could be done -via terminal, Web interface or API (XML-RPC and RESTful). Stats can also -be exported to files or external time/value databases. +In client/server mode, remote monitoring could be done via terminal, +Web interface or API (XML-RPC and RESTful). +Stats can also be exported to files or external time/value databases, CSV or direct +output to STDOUT. .. image:: https://raw.githubusercontent.com/nicolargo/glances/develop/docs/_static/glances-responsive-webdesign.png @@ -105,6 +111,7 @@ Optional dependencies: - ``py-cpuinfo`` (for the Quicklook CPU info module) - ``pygal`` (for the graph export module) - ``pymdstat`` (for RAID support) [Linux-only] +- ``pymongo`` (for the MongoDB export module) [Only for Python >= 3.7] - ``pysnmp`` (for SNMP support) - ``pySMART.smartx`` (for HDD Smart support) [Linux-only] - ``pyzmq`` (for the ZeroMQ export module) @@ -207,7 +214,7 @@ Run last version of Glances container in *console mode*: .. code-block:: console - docker run --rm -v /var/run/docker.sock:/var/run/docker.sock:ro --pid host --network host -it nicolargo/glances:latest-full + docker run --rm -e TZ="${TZ}" -v /var/run/docker.sock:/var/run/docker.sock:ro --pid host --network host -it nicolargo/glances:latest-full Additionally, if you want to use your own glances.conf file, you can create your own Dockerfile: @@ -224,7 +231,7 @@ variable setting parameters for the glances startup command): .. code-block:: console - docker run -v `pwd`/glances.conf:/etc/glances.conf -v /var/run/docker.sock:/var/run/docker.sock:ro --pid host -e GLANCES_OPT="-C /etc/glances.conf" -it nicolargo/glances:latest-full + docker run -e TZ="${TZ}" -v `pwd`/glances.conf:/etc/glances.conf -v /var/run/docker.sock:/var/run/docker.sock:ro --pid host -e GLANCES_OPT="-C /etc/glances.conf" -it nicolargo/glances:latest-full Where \`pwd\`/glances.conf is a local directory containing your glances.conf file. @@ -232,7 +239,7 @@ Run the container in *Web server mode*: .. code-block:: console - docker run -d --restart="always" -p 61208-61209:61208-61209 -e GLANCES_OPT="-w" -v /var/run/docker.sock:/var/run/docker.sock:ro --pid host nicolargo/glances:latest-full + docker run -d --restart="always" -p 61208-61209:61208-61209 -e TZ="${TZ}" -e GLANCES_OPT="-w" -v /var/run/docker.sock:/var/run/docker.sock:ro --pid host nicolargo/glances:latest-full GNU/Linux --------- @@ -464,7 +471,7 @@ Glances is distributed under the LGPL version 3 license. See ``COPYING`` for mor .. _readthedocs: https://glances.readthedocs.io/ .. _forum: https://groups.google.com/forum/?hl=en#!forum/glances-users .. _wiki: https://github.com/nicolargo/glances/wiki/How-to-contribute-to-Glances-%3F -.. _package: https://repology.org/metapackage/glances/packages +.. _package: https://repology.org/project/glances/versions .. _sponsors: https://github.com/sponsors/nicolargo .. _wishlist: https://www.amazon.fr/hz/wishlist/ls/BWAAQKWFR3FI?ref_=wl_share .. _issue2021: https://github.com/nicolargo/glances/issues/2021#issuecomment-1197831157 diff --git a/conf/glances.conf b/conf/glances.conf index d40a9715..b273e5ea 100644 --- a/conf/glances.conf +++ b/conf/glances.conf @@ -12,6 +12,8 @@ check_update=true # History size (maximum number of values) # Default is 1200 values (~1h with the default refresh rate) history_size=1200 +# Set the way Glances should display the date (default is %Y-%m-%d %H:%M:%S %Z) +#strftime_format="%Y-%m-%d %H:%M:%S %Z" ############################################################################## # User interface @@ -212,7 +214,7 @@ critical=-85 disable=False # Define the list of hidden disks (comma-separated regexp) #hide=sda2,sda5,loop.* -hide=loop.*,/dev/loop* +hide=loop.*,/dev/loop.* # Define the list of disks to be show (comma-separated) #show=sda.* # Alias for sda1 @@ -235,12 +237,12 @@ critical=90 #allow=shm [irq] -# Documentation: https://glances.readthedocs.io/en/stable/aoa/irq.html +# Documentation: https://glances.readthedocs.io/en/latest/aoa/irq.html # This plugin is disabled by default disable=True [folders] -# Documentation: https://glances.readthedocs.io/en/stable/aoa/folders.html +# Documentation: https://glances.readthedocs.io/en/latest/aoa/folders.html disable=False # Define a folder list to monitor # The list is composed of items (list_#nb <= 10) @@ -261,13 +263,18 @@ disable=False #folder_3_path=/nonexisting #folder_4_path=/root +[cloud] +# Documentation: https://glances.readthedocs.io/en/latest/aoa/cloud.html +# This plugin is disabled by default +disable=True + [raid] -# Documentation: https://glances.readthedocs.io/en/stable/aoa/raid.html +# Documentation: https://glances.readthedocs.io/en/latest/aoa/raid.html # This plugin is disabled by default disable=True [smart] -# Documentation: https://glances.readthedocs.io/en/stable/aoa/smart.html +# Documentation: https://glances.readthedocs.io/en/latest/aoa/smart.html # This plugin is disabled by default disable=True @@ -305,6 +312,7 @@ battery_critical=95 #core 0_fans_speed_alias=CPU Core 0 fan #or #core 0_alias=CPU Core 0 +#core 1_alias=CPU Core 1 [processcount] disable=False @@ -581,6 +589,15 @@ db=glances #user=root #password=root +[mongodb] +# Configuration for the --export mongodb option +# https://www.mongodb.com +host=localhost +port=27017 +db=glances +user=root +password=example + [kafka] # Configuration for the --export kafka option # http://kafka.apache.org/ diff --git a/dev-requirements.txt b/dev-requirements.txt index b78acaa3..f548a0eb 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -8,4 +8,6 @@ autoflake codespell memory-profiler matplotlib -setuptools>=65.5.1 # not directly required, pinned by Snyk to avoid a vulnerability \ No newline at end of file +semgrep +setuptools>=65.5.1 # not directly required, pinned by Snyk to avoid a vulnerability +numpy>=1.22.2 # not directly required, pinned by Snyk to avoid a vulnerability \ No newline at end of file diff --git a/docker-compose/docker-compose-with-traefik.yml b/docker-compose/docker-compose-with-traefik.yml index db29890f..786aa905 100644 --- a/docker-compose/docker-compose-with-traefik.yml +++ b/docker-compose/docker-compose-with-traefik.yml @@ -21,9 +21,11 @@ services: privileged: true network_mode: "host" volumes: - - /var/run/docker.sock:/var/run/docker.sock + - "/var/run/docker.sock:/var/run/docker.sock:ro" + - "./glances.conf:/glances/conf/glances.conf" environment: - - "GLANCES_OPT=-w" + - GLANCES_OPT: "-C /glances/conf/glances.conf -w" + - TZ: "${TZ}" labels: - "traefik.port=61208" - "traefik.frontend.rule=Host:glances.docker.localhost" diff --git a/docker-compose/docker-compose.yml b/docker-compose/docker-compose.yml index ee50dc4b..703d8775 100644 --- a/docker-compose/docker-compose.yml +++ b/docker-compose/docker-compose.yml @@ -5,13 +5,12 @@ services: context: ./ dockerfile: Dockerfile restart: always - ports: - - "61208:61208" - environment: - GLANCES_OPT: "-C /glances/conf/glances.conf -w" - volumes: - - "/var/run/docker.sock:/var/run/docker.sock:ro" - - "./glances.conf:/glances/conf/glances.conf" pid: "host" privileged: true network_mode: "host" + volumes: + - "/var/run/docker.sock:/var/run/docker.sock:ro" + - "./glances.conf:/glances/conf/glances.conf" + environment: + - GLANCES_OPT: "-C /glances/conf/glances.conf -w" + - TZ: "${TZ}" diff --git a/docker-compose/glances.conf b/docker-compose/glances.conf index 6f6e4180..d666b01a 100644 --- a/docker-compose/glances.conf +++ b/docker-compose/glances.conf @@ -10,8 +10,10 @@ refresh=2 # Does Glances should check if a newer version is available on PyPI ? check_update=false # History size (maximum number of values) -# Default is 3600 seconds (1 hour) -history_size=3600 +# Default is 1200 values (~1h with the default refresh rate) +history_size=1200 +# Set the way Glances should display the date (default is %Y-%m-%d %H:%M:%S %Z) +#strftime_format="%Y-%m-%d %H:%M:%S %Z" ############################################################################## # User interface @@ -212,7 +214,7 @@ critical=-85 disable=False # Define the list of hidden disks (comma-separated regexp) #hide=sda2,sda5,loop.* -hide=loop.*,/dev/loop* +hide=loop.*,/dev/loop.* # Define the list of disks to be show (comma-separated) #show=sda.* # Alias for sda1 @@ -235,12 +237,12 @@ critical=90 #allow=shm [irq] -# Documentation: https://glances.readthedocs.io/en/stable/aoa/irq.html +# Documentation: https://glances.readthedocs.io/en/latest/aoa/irq.html # This plugin is disabled by default disable=True [folders] -# Documentation: https://glances.readthedocs.io/en/stable/aoa/folders.html +# Documentation: https://glances.readthedocs.io/en/latest/aoa/folders.html disable=False # Define a folder list to monitor # The list is composed of items (list_#nb <= 10) @@ -261,13 +263,18 @@ disable=False #folder_3_path=/nonexisting #folder_4_path=/root +[cloud] +# Documentation: https://glances.readthedocs.io/en/latest/aoa/cloud.html +# This plugin is disabled by default +disable=True + [raid] -# Documentation: https://glances.readthedocs.io/en/stable/aoa/raid.html +# Documentation: https://glances.readthedocs.io/en/latest/aoa/raid.html # This plugin is disabled by default disable=True [smart] -# Documentation: https://glances.readthedocs.io/en/stable/aoa/smart.html +# Documentation: https://glances.readthedocs.io/en/latest/aoa/smart.html # This plugin is disabled by default disable=True @@ -582,6 +589,15 @@ db=glances #user=root #password=root +[mongodb] +# Configuration for the --export mongodb option +# https://www.mongodb.com +host=localhost +port=27017 +db=glances +user=root +password=example + [kafka] # Configuration for the --export kafka option # http://kafka.apache.org/ diff --git a/docker-files/alpine.Dockerfile b/docker-files/alpine.Dockerfile index 23d301e8..53e78f47 100644 --- a/docker-files/alpine.Dockerfile +++ b/docker-files/alpine.Dockerfile @@ -26,7 +26,9 @@ RUN apk add --no-cache \ curl \ lm-sensors \ wireless-tools \ - iputils + smartmontools \ + iputils \ + tzdata ############################################################################## # Install the dependencies beforehand to make them cacheable @@ -89,10 +91,13 @@ RUN apk add --no-cache \ python3 \ py3-packaging \ py3-dateutil \ + py3-requests \ curl \ lm-sensors \ wireless-tools \ - iputils + smartmontools \ + iputils \ + tzdata COPY --from=buildRequirements /root/.local/bin /usr/local/bin/ COPY --from=buildRequirements /root/.local/lib/python${PYTHON_VERSION}/site-packages /usr/lib/python${PYTHON_VERSION}/site-packages/ diff --git a/docker-files/ubuntu.Dockerfile b/docker-files/ubuntu.Dockerfile new file mode 100644 index 00000000..4f0383f3 --- /dev/null +++ b/docker-files/ubuntu.Dockerfile @@ -0,0 +1,148 @@ +# +# Glances Dockerfile (based on Ubuntu) +# +# https://github.com/nicolargo/glances +# + +# WARNING: the versions should be set. +# Ex: Python 3.10 for Ubuntu 22.04 +# Note: ENV is for future running containers. ARG for building your Docker image. + +ARG IMAGE_VERSION=12.1.0-base-ubuntu22.04 +ARG PYTHON_VERSION=3.10 +ARG PIP_MIRROR=https://mirrors.aliyun.com/pypi/simple/ +FROM nvidia/cuda:${IMAGE_VERSION} as build + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + python3 \ + python3-dev \ + python3-pip \ + python3-wheel \ + musl-dev \ + build-essential \ + libzmq5 \ + curl \ + lm-sensors \ + wireless-tools \ + smartmontools \ + net-tools \ + tzdata \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +############################################################################## +# Install the dependencies beforehand to make them cacheable + +FROM build as buildRequirements +ARG PYTHON_VERSION +ARG PIP_MIRROR + +ARG PIP_MIRROR=https://mirrors.aliyun.com/pypi/simple/ + +COPY requirements.txt . +RUN python${PYTHON_VERSION} -m pip install --no-cache-dir --user -r requirements.txt -i ${PIP_MIRROR} + +# Minimal means no webui, but it break what is done previously (see #2155) +# So install the webui requirements... +COPY webui-requirements.txt . +RUN python${PYTHON_VERSION} -m pip install --no-cache-dir --user -r webui-requirements.txt -i ${PIP_MIRROR} + +# As minimal image we want to monitor others docker containers +RUN python${PYTHON_VERSION} -m pip install --no-cache-dir --user docker -i ${PIP_MIRROR} + +# Force install otherwise it could be cached without rerun +ARG CHANGING_ARG +RUN python${PYTHON_VERSION} -m pip install --no-cache-dir --user glances -i ${PIP_MIRROR} + +############################################################################## + +FROM build as buildOptionalRequirements +ARG PYTHON_VERSION +ARG PIP_MIRROR + +COPY requirements.txt . +COPY optional-requirements.txt . +RUN CASS_DRIVER_NO_CYTHON=1 pip3 install --no-cache-dir --user -r optional-requirements.txt -i ${PIP_MIRROR} + +############################################################################## +# full image +############################################################################## + +FROM build as full +ARG PYTHON_VERSION + +COPY --from=buildRequirements /root/.local/bin /root/.local/bin/ +COPY --from=buildRequirements /root/.local/lib/python${PYTHON_VERSION}/site-packages /root/.local/lib/python${PYTHON_VERSION}/site-packages/ +COPY --from=buildOptionalRequirements /root/.local/lib/python${PYTHON_VERSION}/site-packages /root/.local/lib/python${PYTHON_VERSION}/site-packages/ +COPY ./docker-compose/glances.conf /etc/glances.conf + +# EXPOSE PORT (XMLRPC / WebUI) +EXPOSE 61209 61208 + +# Define default command. +WORKDIR /glances +CMD python3 -m glances -C /etc/glances.conf $GLANCES_OPT + +############################################################################## +# minimal image +############################################################################## + +# Create running images without any building dependency +FROM nvidia/cuda:${IMAGE_VERSION} as minimal +ARG PYTHON_VERSION + +ARG DEBIAN_FRONTEND=noninteractive +ENV TZ=Asia/Shanghai + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + python3 \ + python3-packaging \ + python3-dateutil \ + python3-requests \ + curl \ + lm-sensors \ + wireless-tools \ + smartmontools \ + net-tools \ + tzdata \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=buildRequirements /root/.local/bin /root/.local/bin/ +COPY --from=buildRequirements /root/.local/lib/python${PYTHON_VERSION}/site-packages /root/.local/lib/python${PYTHON_VERSION}/site-packages/ +COPY ./docker-compose/glances.conf /etc/glances.conf + +# EXPOSE PORT (XMLRPC / WebUI) +EXPOSE 61209 61208 + +# Define default command. +WORKDIR /glances +CMD python3 -m glances -C /etc/glances.conf $GLANCES_OPT + +############################################################################## +# dev image +############################################################################## + +FROM full as dev +ARG PYTHON_VERSION + +COPY --from=buildRequirements /root/.local/bin /root/.local/bin/ +COPY --from=buildRequirements /root/.local/lib/python${PYTHON_VERSION}/site-packages /root/.local/lib/python${PYTHON_VERSION}/site-packages/ +COPY --from=buildOptionalRequirements /root/.local/lib/python${PYTHON_VERSION}/site-packages /root/.local/lib/python${PYTHON_VERSION}/site-packages/ +COPY ./docker-compose/glances.conf /etc/glances.conf + +# Copy the current Glances source code +COPY . /glances + +# EXPOSE PORT (XMLRPC / WebUI) +EXPOSE 61209 61208 + +# Forward access and error logs to Docker's log collector +RUN ln -sf /dev/stdout /tmp/glances-root.log \ + && ln -sf /dev/stderr /var/log/error.log + +# Define default command. +WORKDIR /glances +CMD python3 -m glances -C /etc/glances.conf $GLANCES_OPT diff --git a/docs/_static/cloud.png b/docs/_static/cloud.png new file mode 100644 index 00000000..ac20d590 Binary files /dev/null and b/docs/_static/cloud.png differ diff --git a/docs/_static/glances-architexture.excalidraw b/docs/_static/glances-architexture.excalidraw new file mode 100644 index 00000000..1a413be3 --- /dev/null +++ b/docs/_static/glances-architexture.excalidraw @@ -0,0 +1,2424 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "type": "rectangle", + "version": 252, + "versionNonce": 1518270375, + "isDeleted": false, + "id": "z3aBIxHcDX9glf-RUyasf", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 421, + "y": 161, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 181, + "height": 121, + "seed": 79658283, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "du6r0JkGG0RB4vV62RPED" + }, + { + "id": "rukQ6f7gbwCK6dMF4PqSY", + "type": "arrow" + } + ], + "updated": 1675588528733, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 190, + "versionNonce": 1462725319, + "isDeleted": false, + "id": "du6r0JkGG0RB4vV62RPED", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 445.5, + "y": 208.5, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 132, + "height": 24, + "seed": 257619179, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1675588528733, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "__main__.py", + "baseline": 17, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "z3aBIxHcDX9glf-RUyasf", + "originalText": "__main__.py" + }, + { + "type": "rectangle", + "version": 298, + "versionNonce": 99010857, + "isDeleted": false, + "id": "dIN0jifjByOhE61mIip2q", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 641.5, + "y": 163.5, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 181, + "height": 121, + "seed": 271966315, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "X93uxb5Vg-Lx2teoRVW5N" + }, + { + "id": "I97BFsH6FvYyq9_UjRwU6", + "type": "arrow" + }, + { + "id": "rukQ6f7gbwCK6dMF4PqSY", + "type": "arrow" + } + ], + "updated": 1675588528733, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 237, + "versionNonce": 15377671, + "isDeleted": false, + "id": "X93uxb5Vg-Lx2teoRVW5N", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 671.5, + "y": 211, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 121, + "height": 24, + "seed": 518451141, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1675588528734, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "__init__.py", + "baseline": 17, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "dIN0jifjByOhE61mIip2q", + "originalText": "__init__.py" + }, + { + "type": "diamond", + "version": 609, + "versionNonce": 1413698281, + "isDeleted": false, + "id": "VbHVhy7vaW6prJo4QFEX5", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 639, + "y": 371, + "strokeColor": "#0b7285", + "backgroundColor": "transparent", + "width": 189, + "height": 179, + "seed": 957302987, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "TVdYovxpvasH4tY7IEceE" + }, + { + "id": "I97BFsH6FvYyq9_UjRwU6", + "type": "arrow" + }, + { + "id": "ZCD_-KAOjwV2nBx0hUglp", + "type": "arrow" + } + ], + "updated": 1675588528734, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 549, + "versionNonce": 1007357385, + "isDeleted": false, + "id": "TVdYovxpvasH4tY7IEceE", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 712.5, + "y": 454.25, + "strokeColor": "#0b7285", + "backgroundColor": "transparent", + "width": 42, + "height": 24, + "seed": 377713765, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1675588528734, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "core", + "baseline": 17, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "VbHVhy7vaW6prJo4QFEX5", + "originalText": "core" + }, + { + "id": "I97BFsH6FvYyq9_UjRwU6", + "type": "arrow", + "x": 732, + "y": 286, + "width": 0, + "height": 86, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": { + "type": 2 + }, + "seed": 1744777639, + "version": 407, + "versionNonce": 1524707975, + "isDeleted": false, + "boundElements": null, + "updated": 1675588528805, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 86 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "dIN0jifjByOhE61mIip2q", + "focus": 0, + "gap": 1.5 + }, + "endBinding": { + "elementId": "VbHVhy7vaW6prJo4QFEX5", + "focus": -0.015873015873015872, + "gap": 1 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "rEhm0ZMsmg2lbgHYNuUTa", + "type": "text", + "x": 742.5, + "y": 307, + "width": 41, + "height": 26, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": null, + "seed": 2115715529, + "version": 149, + "versionNonce": 215510185, + "isDeleted": false, + "boundElements": null, + "updated": 1675588528734, + "link": null, + "locked": false, + "text": "main", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "baseline": 18, + "containerId": null, + "originalText": "main" + }, + { + "id": "rukQ6f7gbwCK6dMF4PqSY", + "type": "arrow", + "x": 602, + "y": 221, + "width": 37, + "height": 0, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": { + "type": 2 + }, + "seed": 669272615, + "version": 400, + "versionNonce": 1229408679, + "isDeleted": false, + "boundElements": null, + "updated": 1675588528805, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 37, + 0 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "z3aBIxHcDX9glf-RUyasf", + "focus": -0.008264462809917356, + "gap": 1 + }, + "endBinding": { + "elementId": "dIN0jifjByOhE61mIip2q", + "focus": 0.04958677685950414, + "gap": 2.5 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "type": "rectangle", + "version": 396, + "versionNonce": 1582755721, + "isDeleted": false, + "id": "T-vzSegxNCFDy63YeUtoQ", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 884.5, + "y": 160.5, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 181, + "height": 121, + "seed": 1133526185, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "oD5JS6GZ5RLxtniTQ2qPO" + } + ], + "updated": 1675588528734, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 341, + "versionNonce": 175663495, + "isDeleted": false, + "id": "oD5JS6GZ5RLxtniTQ2qPO", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 942.5, + "y": 208.75, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 65, + "height": 24, + "seed": 706608743, + "groupIds": [], + "roundness": null, + "boundElements": null, + "updated": 1675588528734, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "main.py", + "baseline": 17, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "T-vzSegxNCFDy63YeUtoQ", + "originalText": "main.py" + }, + { + "type": "diamond", + "version": 683, + "versionNonce": 1187124841, + "isDeleted": false, + "id": "TPoX-fVCSz4gF9Bb7oJD4", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 880.5, + "y": 370.5, + "strokeColor": "#0b7285", + "backgroundColor": "transparent", + "width": 189, + "height": 179, + "seed": 451990279, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "hdUnLjhzTcHH_2Xr-4f4v" + } + ], + "updated": 1675588528734, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 641, + "versionNonce": 249536679, + "isDeleted": false, + "id": "hdUnLjhzTcHH_2Xr-4f4v", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 908, + "y": 447.75, + "strokeColor": "#0b7285", + "backgroundColor": "transparent", + "width": 134, + "height": 24, + "seed": 1736377577, + "groupIds": [], + "roundness": null, + "boundElements": null, + "updated": 1675588528734, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "GlancesMain()", + "baseline": 17, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "TPoX-fVCSz4gF9Bb7oJD4", + "originalText": "GlancesMain()" + }, + { + "id": "qmRB-3Yh035xXWyGPzRAh", + "type": "line", + "x": 975, + "y": 374, + "width": 0, + "height": 93, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": { + "type": 2 + }, + "seed": 1174340489, + "version": 150, + "versionNonce": 149250377, + "isDeleted": false, + "boundElements": null, + "updated": 1675588528734, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + -93 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null + }, + { + "id": "yjKLIF0byoBCFlu3snqvC", + "type": "line", + "x": 820, + "y": 458, + "width": 65, + "height": 1, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": { + "type": 2 + }, + "seed": 117968553, + "version": 148, + "versionNonce": 1804792775, + "isDeleted": false, + "boundElements": null, + "updated": 1675588528734, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 65, + -1 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null + }, + { + "id": "iPpO1aE_0LRKjBVQ0N19d", + "type": "text", + "x": 847.5, + "y": 427, + "width": 13, + "height": 26, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": null, + "seed": 1595409129, + "version": 142, + "versionNonce": 35409961, + "isDeleted": false, + "boundElements": null, + "updated": 1675588528734, + "link": null, + "locked": false, + "text": "=", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "baseline": 18, + "containerId": null, + "originalText": "=" + }, + { + "type": "diamond", + "version": 881, + "versionNonce": 524454599, + "isDeleted": false, + "id": "V_Q9JjPuvqh6fBfAh7P3g", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 637.5, + "y": 692.5, + "strokeColor": "#0b7285", + "backgroundColor": "transparent", + "width": 189, + "height": 179, + "seed": 2061438665, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "SA83r_0ZTZaJPzSOsa6ai" + }, + { + "id": "nJ0-zL6oGLjw0f7sLt3t1", + "type": "arrow" + } + ], + "updated": 1675590397112, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 823, + "versionNonce": 1616091623, + "isDeleted": false, + "id": "SA83r_0ZTZaJPzSOsa6ai", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 708.5, + "y": 769.75, + "strokeColor": "#0b7285", + "backgroundColor": "transparent", + "width": 47, + "height": 24, + "seed": 1903484487, + "groupIds": [], + "roundness": null, + "boundElements": null, + "updated": 1675590397121, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "mode", + "baseline": 17, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "V_Q9JjPuvqh6fBfAh7P3g", + "originalText": "mode" + }, + { + "id": "nJ0-zL6oGLjw0f7sLt3t1", + "type": "arrow", + "x": 731, + "y": 543, + "width": 2.1231441617119344, + "height": 148.32611751283002, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": { + "type": 2 + }, + "seed": 923576615, + "version": 504, + "versionNonce": 1410705705, + "isDeleted": false, + "boundElements": null, + "updated": 1675590397121, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 2.1231441617119344, + 148.32611751283002 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": { + "elementId": "V_Q9JjPuvqh6fBfAh7P3g", + "focus": 0.02561960456697391, + "gap": 1.6246183338150217 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "type": "text", + "version": 198, + "versionNonce": 1623364903, + "isDeleted": false, + "id": "ri2fonVaxx3URCz9V1PjJ", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 747, + "y": 553, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 56, + "height": 26, + "seed": 1733680745, + "groupIds": [], + "roundness": null, + "boundElements": null, + "updated": 1675588528734, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "start", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "start" + }, + { + "type": "rectangle", + "version": 719, + "versionNonce": 867736585, + "isDeleted": false, + "id": "So2q8hpc6F5KvtPQFTop8", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 234.5, + "y": 683.5, + "strokeColor": "#c92a2a", + "backgroundColor": "transparent", + "width": 251, + "height": 34, + "seed": 1945517991, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "sGrQmvRDJHuYF_9i6rXob" + } + ], + "updated": 1675590397121, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 675, + "versionNonce": 1991623943, + "isDeleted": false, + "id": "sGrQmvRDJHuYF_9i6rXob", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 294, + "y": 688.5, + "strokeColor": "#c92a2a", + "backgroundColor": "transparent", + "width": 132, + "height": 24, + "seed": 491532873, + "groupIds": [], + "roundness": null, + "boundElements": null, + "updated": 1675590397121, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "standalone.py", + "baseline": 17, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "So2q8hpc6F5KvtPQFTop8", + "originalText": "standalone.py" + }, + { + "type": "rectangle", + "version": 753, + "versionNonce": 1278882537, + "isDeleted": false, + "id": "1wtZQP7JhcQ4lwrIYtmqt", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 234.5, + "y": 722, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 251, + "height": 34.5, + "seed": 120949223, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "AZjkn1SJRrYlmgfL9zSOs" + } + ], + "updated": 1675590397122, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 714, + "versionNonce": 1373998119, + "isDeleted": false, + "id": "AZjkn1SJRrYlmgfL9zSOs", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 300.5, + "y": 727, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 119, + "height": 24, + "seed": 1479388169, + "groupIds": [], + "roundness": null, + "boundElements": null, + "updated": 1675590397122, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "webserver.py", + "baseline": 17, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "1wtZQP7JhcQ4lwrIYtmqt", + "originalText": "webserver.py" + }, + { + "type": "rectangle", + "version": 797, + "versionNonce": 1378217417, + "isDeleted": false, + "id": "48sa_pFKMBlEU75p47EfA", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 234.5, + "y": 763, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 251, + "height": 34, + "seed": 1398331655, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "0Z2AD5xnd4bUAS3ryDS-y" + } + ], + "updated": 1675590397122, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 759, + "versionNonce": 1037004615, + "isDeleted": false, + "id": "0Z2AD5xnd4bUAS3ryDS-y", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 317, + "y": 768, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 86, + "height": 24, + "seed": 1308778217, + "groupIds": [], + "roundness": null, + "boundElements": null, + "updated": 1675590397122, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "server.py", + "baseline": 17, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "48sa_pFKMBlEU75p47EfA", + "originalText": "server.py" + }, + { + "type": "rectangle", + "version": 836, + "versionNonce": 1553419433, + "isDeleted": false, + "id": "JwMl3Y2Txi0Xx4W1iwNcq", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 236.5, + "y": 804, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 251, + "height": 34.5, + "seed": 1769513959, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "5waxi9faL1bP3hACWhylM" + } + ], + "updated": 1675590397122, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 794, + "versionNonce": 1422913127, + "isDeleted": false, + "id": "5waxi9faL1bP3hACWhylM", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 323.5, + "y": 809, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 77, + "height": 24, + "seed": 46215689, + "groupIds": [], + "roundness": null, + "boundElements": null, + "updated": 1675590397123, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "client.py", + "baseline": 17, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "JwMl3Y2Txi0Xx4W1iwNcq", + "originalText": "client.py" + }, + { + "type": "rectangle", + "version": 890, + "versionNonce": 322555785, + "isDeleted": false, + "id": "P1bp9Rfq5SwS130g34yi7", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 235.5, + "y": 844, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 251, + "height": 34.5, + "seed": 485157865, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "cYs-xqat3zotKrKiW0d8F" + } + ], + "updated": 1675590397123, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 855, + "versionNonce": 833849735, + "isDeleted": false, + "id": "cYs-xqat3zotKrKiW0d8F", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 278, + "y": 849, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 166, + "height": 24, + "seed": 746119975, + "groupIds": [], + "roundness": null, + "boundElements": null, + "updated": 1675590397123, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "client_browser.py", + "baseline": 17, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "P1bp9Rfq5SwS130g34yi7", + "originalText": "client_browser.py" + }, + { + "id": "rQhOqJTXTXy1a48aIPtoK", + "type": "line", + "x": 504, + "y": 682, + "width": 1, + "height": 197, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": { + "type": 2 + }, + "seed": 1950842537, + "version": 308, + "versionNonce": 474543721, + "isDeleted": false, + "boundElements": null, + "updated": 1675590397123, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -1, + 197 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null + }, + { + "id": "sYMUNY_UMw9YOE9QnlXCK", + "type": "line", + "x": 643, + "y": 783, + "width": 137, + "height": 0, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": { + "type": 2 + }, + "seed": 1527629801, + "version": 371, + "versionNonce": 1639366823, + "isDeleted": false, + "boundElements": null, + "updated": 1675590397124, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -137, + 0 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null + }, + { + "type": "text", + "version": 290, + "versionNonce": 1250967881, + "isDeleted": false, + "id": "hxakD1P7MVGXZlrSZ4IDZ", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 574.5, + "y": 756, + "strokeColor": "#c92a2a", + "backgroundColor": "transparent", + "width": 13, + "height": 26, + "seed": 987379943, + "groupIds": [], + "roundness": null, + "boundElements": null, + "updated": 1675590397124, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "=", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "=" + }, + { + "type": "text", + "version": 309, + "versionNonce": 377885639, + "isDeleted": false, + "id": "eYH-l8FqVPjaI-zP9pfMb", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 548, + "y": 791, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 80, + "height": 26, + "seed": 1676833191, + "groupIds": [], + "roundness": null, + "boundElements": null, + "updated": 1675590397124, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "one of...", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "one of..." + }, + { + "type": "text", + "version": 335, + "versionNonce": 191574057, + "isDeleted": false, + "id": "mDcIG5yl_8fiGlk6dlATR", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 914, + "y": 740, + "strokeColor": "#c92a2a", + "backgroundColor": "transparent", + "width": 140, + "height": 26, + "seed": 933322633, + "groupIds": [], + "roundness": null, + "boundElements": null, + "updated": 1675590397124, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "serve_forever", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "serve_forever" + }, + { + "type": "line", + "version": 703, + "versionNonce": 1359234343, + "isDeleted": false, + "id": "Ubb64XWlshf6YUbdArM9v", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1600.5, + "y": 785, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 778, + "height": 3, + "seed": 1141088295, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": null, + "updated": 1675590439635, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + -778, + -3 + ] + ] + }, + { + "type": "rectangle", + "version": 693, + "versionNonce": 1729329735, + "isDeleted": false, + "id": "E0Uoo4aOU-71gi3MKCZ2Y", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1176.5, + "y": 160.5, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 181, + "height": 121, + "seed": 713789705, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "ui39Vh4hwmgLPRZz4n_UZ" + } + ], + "updated": 1675589927345, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 644, + "versionNonce": 1638756777, + "isDeleted": false, + "id": "ui39Vh4hwmgLPRZz4n_UZ", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1225.5, + "y": 208.75, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 83, + "height": 24, + "seed": 1115201543, + "groupIds": [], + "roundness": null, + "boundElements": null, + "updated": 1675589927345, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "stats.py", + "baseline": 17, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "E0Uoo4aOU-71gi3MKCZ2Y", + "originalText": "stats.py" + }, + { + "type": "diamond", + "version": 1049, + "versionNonce": 1678958759, + "isDeleted": false, + "id": "-Pstud5nkYt1YM31u2x_X", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1172.5, + "y": 301.5, + "strokeColor": "#0b7285", + "backgroundColor": "transparent", + "width": 189, + "height": 179, + "seed": 921077737, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "_Sg0_xkkkxDFDg2nCEEbZ" + } + ], + "updated": 1675590333864, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1013, + "versionNonce": 1132863817, + "isDeleted": false, + "id": "_Sg0_xkkkxDFDg2nCEEbZ", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1191.5, + "y": 378.75, + "strokeColor": "#0b7285", + "backgroundColor": "transparent", + "width": 151, + "height": 24, + "seed": 1989478183, + "groupIds": [], + "roundness": null, + "boundElements": null, + "updated": 1675590333864, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "GlancesStats()", + "baseline": 17, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "-Pstud5nkYt1YM31u2x_X", + "originalText": "GlancesStats()" + }, + { + "type": "line", + "version": 468, + "versionNonce": 965934473, + "isDeleted": false, + "id": "NqgLCJSHOwjxpOyVPlWws", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1268, + "y": 307, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 0, + "height": 26, + "seed": 780116681, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": null, + "updated": 1675590338064, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 0, + -26 + ] + ] + }, + { + "type": "diamond", + "version": 859, + "versionNonce": 716072489, + "isDeleted": false, + "id": "cDntBigSar4I0WkyhIBAZ", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1172.5, + "y": 502.5, + "strokeColor": "#c92a2a", + "backgroundColor": "transparent", + "width": 189, + "height": 179, + "seed": 13687943, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "AEXGY1IDMBeCvoLaKio__" + }, + { + "id": "NpkkDItD4vnSSVIkyLR5R", + "type": "arrow" + }, + { + "id": "Lm88UtXv6wAHHUhkhFctw", + "type": "arrow" + } + ], + "updated": 1675590352966, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 807, + "versionNonce": 766048263, + "isDeleted": false, + "id": "AEXGY1IDMBeCvoLaKio__", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1216.5, + "y": 579.75, + "strokeColor": "#c92a2a", + "backgroundColor": "transparent", + "width": 101, + "height": 24, + "seed": 1453216617, + "groupIds": [], + "roundness": null, + "boundElements": null, + "updated": 1675590352966, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "self.stats", + "baseline": 17, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "cDntBigSar4I0WkyhIBAZ", + "originalText": "self.stats" + }, + { + "id": "futrrb24VLy0LwGgivfSn", + "type": "line", + "x": 1269, + "y": 475, + "width": 1, + "height": 31, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": { + "type": 2 + }, + "seed": 1916753063, + "version": 191, + "versionNonce": 1514098121, + "isDeleted": false, + "boundElements": null, + "updated": 1675590368062, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -1, + 31 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null + }, + { + "type": "text", + "version": 299, + "versionNonce": 113418695, + "isDeleted": false, + "id": "7_yYXmz-cljpM3XmXnwFz", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1276.5, + "y": 475, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 13, + "height": 26, + "seed": 171440295, + "groupIds": [], + "roundness": null, + "boundElements": null, + "updated": 1675590363270, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "=", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "=" + }, + { + "type": "rectangle", + "version": 854, + "versionNonce": 1282611241, + "isDeleted": false, + "id": "zxj5BuGRA6gmOMpuytKOs", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1376, + "y": 159.5, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 208, + "height": 121, + "seed": 176909769, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "9o5H_Z0ZXJgjf4VhEnGzw" + } + ], + "updated": 1675590082537, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 823, + "versionNonce": 973642471, + "isDeleted": false, + "id": "9o5H_Z0ZXJgjf4VhEnGzw", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1392.5, + "y": 208, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 175, + "height": 24, + "seed": 1216474951, + "groupIds": [], + "roundness": null, + "boundElements": null, + "updated": 1675590082538, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "glances_curses.py", + "baseline": 17, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "zxj5BuGRA6gmOMpuytKOs", + "originalText": "glances_curses.py" + }, + { + "type": "diamond", + "version": 1194, + "versionNonce": 945697735, + "isDeleted": false, + "id": "_VvreiuDNX6NcogCsHFMV", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1387, + "y": 300.5, + "strokeColor": "#0b7285", + "backgroundColor": "transparent", + "width": 189, + "height": 179, + "seed": 1816972457, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "RQnWQ-OtQLeiQKaWp6Fgp" + } + ], + "updated": 1675590333865, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1163, + "versionNonce": 715460649, + "isDeleted": false, + "id": "RQnWQ-OtQLeiQKaWp6Fgp", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1410.5, + "y": 365.5, + "strokeColor": "#0b7285", + "backgroundColor": "transparent", + "width": 142, + "height": 48, + "seed": 1697803879, + "groupIds": [], + "roundness": null, + "boundElements": null, + "updated": 1675590333865, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "GlancesCurses\nStandalone()", + "baseline": 41, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "_VvreiuDNX6NcogCsHFMV", + "originalText": "GlancesCurses\nStandalone()" + }, + { + "type": "line", + "version": 625, + "versionNonce": 1091550985, + "isDeleted": false, + "id": "fBPzn8itK0-ofbaaQP3QN", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1481.5, + "y": 309, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 0, + "height": 29, + "seed": 272584585, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": null, + "updated": 1675590342444, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 0, + -29 + ] + ] + }, + { + "type": "diamond", + "version": 1000, + "versionNonce": 817613513, + "isDeleted": false, + "id": "nHjJ_PGbRP1C54xcsONnl", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1388, + "y": 500.5, + "strokeColor": "#c92a2a", + "backgroundColor": "transparent", + "width": 189, + "height": 179, + "seed": 298191239, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "4q18wE4O-McviQYBPBssm" + } + ], + "updated": 1675590352966, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 958, + "versionNonce": 567403079, + "isDeleted": false, + "id": "4q18wE4O-McviQYBPBssm", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1430.5, + "y": 577.75, + "strokeColor": "#c92a2a", + "backgroundColor": "transparent", + "width": 104, + "height": 24, + "seed": 1553888873, + "groupIds": [], + "roundness": null, + "boundElements": null, + "updated": 1675590352966, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "self.screen", + "baseline": 17, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "nHjJ_PGbRP1C54xcsONnl", + "originalText": "self.screen" + }, + { + "type": "line", + "version": 341, + "versionNonce": 396097287, + "isDeleted": false, + "id": "K2am61VoMQBdemjmaY1_X", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1482.5, + "y": 475, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 0, + "height": 30, + "seed": 460931239, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": null, + "updated": 1675590372353, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 30 + ] + ] + }, + { + "type": "text", + "version": 442, + "versionNonce": 898007593, + "isDeleted": false, + "id": "o-2dvVa3qGN-ZtEGLbbxq", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1491, + "y": 474, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 13, + "height": 26, + "seed": 1681244489, + "groupIds": [], + "roundness": null, + "boundElements": null, + "updated": 1675590363270, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "=", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "=" + }, + { + "type": "arrow", + "version": 771, + "versionNonce": 1605823785, + "isDeleted": false, + "id": "NpkkDItD4vnSSVIkyLR5R", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1227.536826021261, + "y": 647.4036780704577, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 2.2278702768758194, + "height": 132.47821261660965, + "seed": 2085136617, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": null, + "updated": 1675590352992, + "link": null, + "locked": false, + "startBinding": { + "elementId": "cDntBigSar4I0WkyhIBAZ", + "focus": 0.4274591641778541, + "gap": 2.3806234060035365 + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 2.2278702768758194, + 132.47821261660965 + ] + ] + }, + { + "type": "arrow", + "version": 818, + "versionNonce": 1297651175, + "isDeleted": false, + "id": "Lm88UtXv6wAHHUhkhFctw", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1310.527371847451, + "y": 646.8414945083808, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 2.2373244506859464, + "height": 133.04039617868648, + "seed": 987698825, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": null, + "updated": 1675590352992, + "link": null, + "locked": false, + "startBinding": { + "elementId": "cDntBigSar4I0WkyhIBAZ", + "focus": -0.45084771412902047, + "gap": 4.767145239963185 + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 2.2373244506859464, + 133.04039617868648 + ] + ] + }, + { + "type": "text", + "version": 361, + "versionNonce": 1517286249, + "isDeleted": false, + "id": "3d-5XlfL-DXIG63Prnbrl", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1145.5, + "y": 696, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 69, + "height": 26, + "seed": 1263546985, + "groupIds": [], + "roundness": null, + "boundElements": null, + "updated": 1675590352966, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "update", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "update" + }, + { + "type": "text", + "version": 398, + "versionNonce": 994710439, + "isDeleted": false, + "id": "uNMRAmQ5fFPZz6Cn-WskG", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1325, + "y": 696, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 64, + "height": 26, + "seed": 208532489, + "groupIds": [], + "roundness": null, + "boundElements": null, + "updated": 1675590352966, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "export", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "export" + }, + { + "type": "arrow", + "version": 800, + "versionNonce": 80715337, + "isDeleted": false, + "id": "GgJ0Au16dwqt1oMD4qRft", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1484.235303701863, + "y": 674.1181093129326, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 0.47060740372603505, + "height": 110.76378137413474, + "seed": 2080294919, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": null, + "updated": 1675590352966, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -0.47060740372603505, + 110.76378137413474 + ] + ] + }, + { + "type": "text", + "version": 416, + "versionNonce": 674694855, + "isDeleted": false, + "id": "Rd0PFLBfIckxgEJHI0gYv", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1491.5, + "y": 700, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 69, + "height": 26, + "seed": 1013327143, + "groupIds": [], + "roundness": null, + "boundElements": null, + "updated": 1675590352966, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "update", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "update" + }, + { + "id": "AJrOfZ3BWcGWx-phOFTM8", + "type": "ellipse", + "x": 1573, + "y": 769, + "width": 29, + "height": 29, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "roundness": { + "type": 2 + }, + "seed": 1997338857, + "version": 65, + "versionNonce": 1498437481, + "isDeleted": false, + "boundElements": [], + "updated": 1675590469409, + "link": null, + "locked": false + }, + { + "type": "ellipse", + "version": 108, + "versionNonce": 1598836359, + "isDeleted": false, + "id": "7MgSBEIoPRZ3PGYWt6ttF", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1113.5, + "y": 767.5, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 29, + "height": 29, + "seed": 1598347879, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "id": "JoP4A7A2IwEAe9b7xarHX", + "type": "arrow" + } + ], + "updated": 1675590494704, + "link": null, + "locked": false + }, + { + "id": "iVLKUce4Dj1p19ez2Kmis", + "type": "line", + "x": 1587, + "y": 797, + "width": 1, + "height": 41, + "angle": 0, + "strokeColor": "#495057", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 2, + "opacity": 100, + "groupIds": [], + "roundness": { + "type": 2 + }, + "seed": 1678897063, + "version": 23, + "versionNonce": 625487017, + "isDeleted": false, + "boundElements": null, + "updated": 1675590505143, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -1, + 41 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null + }, + { + "id": "jR1l0tisTaLalG3_hgJdD", + "type": "line", + "x": 1586, + "y": 837, + "width": 462, + "height": 0, + "angle": 0, + "strokeColor": "#495057", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 2, + "opacity": 100, + "groupIds": [], + "roundness": { + "type": 2 + }, + "seed": 1897784839, + "version": 54, + "versionNonce": 1411190375, + "isDeleted": false, + "boundElements": null, + "updated": 1675590505143, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -462, + 0 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null + }, + { + "id": "JoP4A7A2IwEAe9b7xarHX", + "type": "arrow", + "x": 1125, + "y": 838, + "width": 1, + "height": 37, + "angle": 0, + "strokeColor": "#495057", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 2, + "opacity": 100, + "groupIds": [], + "roundness": { + "type": 2 + }, + "seed": 1949962409, + "version": 20, + "versionNonce": 1389277065, + "isDeleted": false, + "boundElements": null, + "updated": 1675590505144, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 1, + -37 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": { + "elementId": "7MgSBEIoPRZ3PGYWt6ttF", + "focus": 0.10247888787140157, + "gap": 4.6049731745427955 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + } + ], + "appState": { + "gridSize": null, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/docs/_static/glances-flame.svg b/docs/_static/glances-flame.svg index 72744ff4..c450cb3b 100644 --- a/docs/_static/glances-flame.svg +++ b/docs/_static/glances-flame.svg @@ -1,4 +1,4 @@ - \ No newline at end of file diff --git a/docs/_static/glances-memory-profiling-with-history.png b/docs/_static/glances-memory-profiling-with-history.png index 8d9c8d7b..698b939c 100644 Binary files a/docs/_static/glances-memory-profiling-with-history.png and b/docs/_static/glances-memory-profiling-with-history.png differ diff --git a/docs/_static/glances-memory-profiling-without-history.png b/docs/_static/glances-memory-profiling-without-history.png index 795b7820..a2751e96 100644 Binary files a/docs/_static/glances-memory-profiling-without-history.png and b/docs/_static/glances-memory-profiling-without-history.png differ diff --git a/docs/_static/processlist-extended.png b/docs/_static/processlist-extended.png new file mode 100644 index 00000000..a45f7c0a Binary files /dev/null and b/docs/_static/processlist-extended.png differ diff --git a/docs/aoa/cloud.rst b/docs/aoa/cloud.rst new file mode 100644 index 00000000..d6214925 --- /dev/null +++ b/docs/aoa/cloud.rst @@ -0,0 +1,15 @@ +.. _cloud: + +CLOUD +===== + +This plugin diplays information about the cloud provider if your host is running on OpenStack. + +The plugin use the standard OpenStack `metadata`_ service to retrieve the information. + +This plugin is disable by default, please use the --enable-plugin cloud option +to enable it. + +.. image:: ../_static/cloud.png + +.. _metadata: https://docs.openstack.org/nova/latest/user/metadata.html \ No newline at end of file diff --git a/docs/aoa/diskio.rst b/docs/aoa/diskio.rst index 9a1e87d7..85125481 100644 --- a/docs/aoa/diskio.rst +++ b/docs/aoa/diskio.rst @@ -37,3 +37,9 @@ or another example: [diskio] show=sda.* + +Filtering is based on regular expression. Please be sure that your regular +expression works as expected. You can use an online tool like `regex101`_ in +order to test your regular expression. + +.. _regex101: https://regex101.com/ \ No newline at end of file diff --git a/docs/aoa/docker.rst b/docs/aoa/docker.rst index cc8c485b..568978d1 100644 --- a/docs/aoa/docker.rst +++ b/docs/aoa/docker.rst @@ -47,4 +47,9 @@ under the ``[docker]`` section: You can use all the variables ({{foo}}) available in the Docker plugin. +Filtering (for hide or show) is based on regular expression. Please be sure that your regular +expression works as expected. You can use an online tool like `regex101`_ in +order to test your regular expression. + +.. _regex101: https://regex101.com/ .. _docker-py: https://github.com/docker/docker-py diff --git a/docs/aoa/fs.rst b/docs/aoa/fs.rst index 8123bf1d..4d5dc100 100644 --- a/docs/aoa/fs.rst +++ b/docs/aoa/fs.rst @@ -53,3 +53,9 @@ Example to only show /dev/sdb mount points: [fs] show=/dev/sdb.* + +Filtering is based on regular expression. Please be sure that your regular +expression works as expected. You can use an online tool like `regex101`_ in +order to test your regular expression. + +.. _regex101: https://regex101.com/ \ No newline at end of file diff --git a/docs/aoa/header.rst b/docs/aoa/header.rst index 162c2598..c38a8884 100644 --- a/docs/aoa/header.rst +++ b/docs/aoa/header.rst @@ -22,7 +22,9 @@ file under the ``[ip]`` section: **NOTE:** Setting low values for `public_refresh_interval` will result in frequent -HTTP requests to the IP detection servers. Recommended range: 120-600 seconds +HTTP requests to the IP detection servers. Recommended range: 120-600 seconds. +Glances uses online services in order to get the IP addresses. Your IP address could be +blocked if too many requests are done. If the Censys options are configured, the public IP address is also analysed (with the same interval) and additional information is displayed. diff --git a/docs/aoa/index.rst b/docs/aoa/index.rst index a573581b..edc41e36 100644 --- a/docs/aoa/index.rst +++ b/docs/aoa/index.rst @@ -34,6 +34,7 @@ Legend: fs irq folders + cloud raid smart sensors diff --git a/docs/aoa/network.rst b/docs/aoa/network.rst index 27ad1581..a1f116ac 100644 --- a/docs/aoa/network.rst +++ b/docs/aoa/network.rst @@ -53,3 +53,9 @@ virtual docker interface (docker0, docker1, ...): wlan0_tx_warning=900000 wlan0_tx_critical=1000000 wlan0_tx_log=True + +Filtering is based on regular expression. Please be sure that your regular +expression works as expected. You can use an online tool like `regex101`_ in +order to test your regular expression. + +.. _regex101: https://regex101.com/ \ No newline at end of file diff --git a/docs/aoa/ps.rst b/docs/aoa/ps.rst index ba4ee4c2..ec4c4f95 100644 --- a/docs/aoa/ps.rst +++ b/docs/aoa/ps.rst @@ -15,10 +15,15 @@ Filtered view: .. image:: ../_static/processlist-filter.png +Extended view: + +.. image:: ../_static/processlist-extended.png + The process view consists of 3 parts: - Processes summary -- Monitored processes list (optional) +- Monitored processes list (optional, only in standalone mode) +- Extended stats for the selected process (optional) - Processes list The processes summary line displays: @@ -56,12 +61,15 @@ You can also set the sort key in the UI: * - c - --sort-processes cpu_percent - Sort by CPU + * - e + - N/A + - Pin the process and display extended stats * - i - --sort-processes io_counters - Sort by DISK I/O * - j - --programs - - Accumulate processes by program + - Accumulate processes by program (extended stats disable in this mode) * - m - --sort-processes memory_percent - Sort by MEM diff --git a/docs/aoa/sensors.rst b/docs/aoa/sensors.rst index e637af61..87d64933 100644 --- a/docs/aoa/sensors.rst +++ b/docs/aoa/sensors.rst @@ -31,6 +31,12 @@ There is no alert on this information. unitname_fan_speed_alias=Alias for fan speed .. note 4:: + If a sensors has multiple identical features names (see #2280), then + Glances will add a suffix to the feature name. + For example, if you have one sensor with two Composite features, the + second one will be named Composite_1. + +.. note 5:: The plugin could crash on some operating system (FreeBSD) with the TCP or UDP blackhole option > 0 (see issue #2106). In this case, you should disable the sensors (--disable-plugin sensors or from the diff --git a/docs/api.rst b/docs/api.rst index 1d844ca3..832a5781 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -60,25 +60,6 @@ Get the plugins list:: "uptime", "wifi"] -GET alert ---------- - -Get plugin stats:: - - # curl http://localhost:61208/api/3/alert - [[1667486328.0, - -1, - "WARNING", - "MEM", - 70.7784407976031, - 70.7784407976031, - 70.7784407976031, - 70.7784407976031, - 1, - [], - "", - "memory_percent"]] - GET amps -------- @@ -93,7 +74,7 @@ Get plugin stats:: "refresh": 3.0, "regex": True, "result": None, - "timer": 0.8428387641906738}, + "timer": 0.8183016777038574}, {"count": 0, "countmax": 20.0, "countmin": None, @@ -102,7 +83,7 @@ Get plugin stats:: "refresh": 3.0, "regex": True, "result": None, - "timer": 0.8426706790924072}] + "timer": 0.8182027339935303}] Get a specific field:: @@ -120,7 +101,7 @@ Get a specific item when field matchs the given value:: "refresh": 3.0, "regex": True, "result": None, - "timer": 0.8428387641906738}]} + "timer": 0.8183016777038574}]} GET core -------- @@ -150,19 +131,19 @@ Get plugin stats:: "ctx_switches": 0, "guest": 0.0, "guest_nice": 0.0, - "idle": 47.3, + "idle": 70.9, "interrupts": 0, "iowait": 0.0, "irq": 0.0, "nice": 0.0, "soft_interrupts": 0, - "softirq": 0.3, + "softirq": 0.0, "steal": 0.0, "syscalls": 0, - "system": 9.2, + "system": 4.0, "time_since_update": 1, - "total": 40.1, - "user": 43.2} + "total": 29.8, + "user": 25.2} Fields descriptions: @@ -185,7 +166,7 @@ Fields descriptions: Get a specific field:: # curl http://localhost:61208/api/3/cpu/total - {"total": 40.1} + {"total": 29.8} GET diskio ---------- @@ -230,19 +211,98 @@ GET docker Get plugin stats:: # curl http://localhost:61208/api/3/docker - [{"Command": ["/portainer"], - "Id": "3abd51c615968482d9ccff5afc629f267f6dda113ed68b75b432615fae3b49fb", - "Image": ["portainer/portainer-ce:2.9.3"], - "Status": "running", - "Uptime": "4 days", - "cpu_percent": 0.0, - "io_r": None, - "io_w": None, - "key": "name", - "memory_usage": 15155200, - "name": "portainer", - "network_rx": None, - "network_tx": None}] + {"containers": [{"Command": ["docker-entrypoint.sh", "mongod"], + "Id": "c3a1bb27858df965e1c524c6ef33c0fd26d765cae5bcd90fbe9e662b703a52aa", + "Image": ["mongo:latest"], + "Status": "running", + "Uptime": "1 months", + "cpu": {"total": 0.0}, + "cpu_percent": 0.0, + "io": {"cumulative_ior": 847872, + "cumulative_iow": 53813248, + "time_since_update": 1}, + "io_r": None, + "io_w": None, + "key": "name", + "memory": {"cache": None, + "limit": 7836196864, + "max_usage": None, + "rss": None, + "usage": 23642112}, + "memory_usage": 23642112, + "name": "docker-mongo_mongo_1", + "network": {"cumulative_rx": 37744307, + "cumulative_tx": 28244833, + "time_since_update": 1}, + "network_rx": None, + "network_tx": None}, + {"Command": ["tini", + "--", + "/docker-entrypoint.sh", + "mongo-express"], + "Id": "5aa8f03d6027d00244cf5ce5f4ffe616fd8a31e95ff7091ca02b8d99c00b276c", + "Image": ["mongo-express:latest"], + "Status": "running", + "Uptime": "1 months", + "cpu": {"total": 0.0}, + "cpu_percent": 0.0, + "io": {}, + "io_r": None, + "io_w": None, + "key": "name", + "memory": {}, + "memory_usage": None, + "name": "docker-mongo_mongo-express_1", + "network": {}, + "network_rx": None, + "network_tx": None}, + {"Command": ["/portainer"], + "Id": "3abd51c615968482d9ccff5afc629f267f6dda113ed68b75b432615fae3b49fb", + "Image": ["portainer/portainer-ce:2.9.3"], + "Status": "running", + "Uptime": "1 months", + "cpu": {"total": 0.0}, + "cpu_percent": 0.0, + "io": {}, + "io_r": None, + "io_w": None, + "key": "name", + "memory": {}, + "memory_usage": None, + "name": "portainer", + "network": {}, + "network_rx": None, + "network_tx": None}], + "version": {"ApiVersion": "1.42", + "Arch": "amd64", + "BuildTime": "2023-02-01T17:49:08.000000000+00:00", + "Components": [{"Details": {"ApiVersion": "1.42", + "Arch": "amd64", + "BuildTime": "2023-02-01T17:49:08.000000000+00:00", + "Experimental": "false", + "GitCommit": "d7573ab", + "GoVersion": "go1.19.5", + "KernelVersion": "5.15.0-58-generic", + "MinAPIVersion": "1.12", + "Os": "linux"}, + "Name": "Engine", + "Version": "23.0.0"}, + {"Details": {"GitCommit": "31aa4358a36870b21a992d3ad2bef29e1d693bec"}, + "Name": "containerd", + "Version": "1.6.16"}, + {"Details": {"GitCommit": "v1.1.4-0-g5fd4c4d"}, + "Name": "runc", + "Version": "1.1.4"}, + {"Details": {"GitCommit": "de40ad0"}, + "Name": "docker-init", + "Version": "0.19.0"}], + "GitCommit": "d7573ab", + "GoVersion": "go1.19.5", + "KernelVersion": "5.15.0-58-generic", + "MinAPIVersion": "1.12", + "Os": "linux", + "Platform": {"Name": "Docker Engine - Community"}, + "Version": "23.0.0"}} GET fs ------ @@ -251,13 +311,13 @@ Get plugin stats:: # curl http://localhost:61208/api/3/fs [{"device_name": "/dev/mapper/ubuntu--gnome--vg-root", - "free": 64626642944, + "free": 53470863360, "fs_type": "ext4", "key": "mnt_point", "mnt_point": "/", - "percent": 72.0, + "percent": 76.8, "size": 243334156288, - "used": 166320058368}, + "used": 177475837952}, {"device_name": "zsfpool", "free": 41811968, "fs_type": "zfs", @@ -276,13 +336,13 @@ Get a specific item when field matchs the given value:: # curl http://localhost:61208/api/3/fs/mnt_point// {"/": [{"device_name": "/dev/mapper/ubuntu--gnome--vg-root", - "free": 64626642944, + "free": 53470863360, "fs_type": "ext4", "key": "mnt_point", "mnt_point": "/", - "percent": 72.0, + "percent": 76.8, "size": 243334156288, - "used": 166320058368}]} + "used": 177475837952}]} GET ip ------ @@ -290,11 +350,11 @@ GET ip Get plugin stats:: # curl http://localhost:61208/api/3/ip - {"address": "192.168.0.48", + {"address": "192.168.0.32", "gateway": "192.168.0.254", "mask": "255.255.255.0", "mask_cidr": 24, - "public_address": "82.66.169.82", + "public_address": "91.166.228.228", "public_info_human": ""} Get a specific field:: @@ -309,9 +369,9 @@ Get plugin stats:: # curl http://localhost:61208/api/3/load {"cpucore": 4, - "min1": 2.57275390625, - "min15": 1.9169921875, - "min5": 2.05908203125} + "min1": 0.79833984375, + "min15": 0.7431640625, + "min5": 0.8056640625} Fields descriptions: @@ -323,7 +383,7 @@ Fields descriptions: Get a specific field:: # curl http://localhost:61208/api/3/load/min1 - {"min1": 2.57275390625} + {"min1": 0.79833984375} GET mem ------- @@ -331,16 +391,16 @@ GET mem Get plugin stats:: # curl http://localhost:61208/api/3/mem - {"active": 2859896832, - "available": 2289856512, - "buffers": 244420608, - "cached": 2865504256, - "free": 2289856512, - "inactive": 3594788864, - "percent": 70.8, - "shared": 670150656, - "total": 7836188672, - "used": 5546332160} + {"active": 2350882816, + "available": 2422988800, + "buffers": 131072000, + "cached": 2795134976, + "free": 2422988800, + "inactive": 3522777088, + "percent": 69.1, + "shared": 685944832, + "total": 7836196864, + "used": 5413208064} Fields descriptions: @@ -359,7 +419,7 @@ Fields descriptions: Get a specific field:: # curl http://localhost:61208/api/3/mem/total - {"total": 7836188672} + {"total": 7836196864} GET memswap ----------- @@ -367,13 +427,13 @@ GET memswap Get plugin stats:: # curl http://localhost:61208/api/3/memswap - {"free": 4244574208, - "percent": 47.5, - "sin": 2742693888, - "sout": 8789086208, + {"free": 5875109888, + "percent": 27.3, + "sin": 8760786944, + "sout": 14506393600, "time_since_update": 1, "total": 8082419712, - "used": 3837845504} + "used": 2207309824} Fields descriptions: @@ -397,29 +457,29 @@ Get plugin stats:: # curl http://localhost:61208/api/3/network [{"alias": None, - "cumulative_cx": 450898582, - "cumulative_rx": 225449291, - "cumulative_tx": 225449291, - "cx": 7262, + "cumulative_cx": 1140515614, + "cumulative_rx": 570257807, + "cumulative_tx": 570257807, + "cx": 5342, "interface_name": "lo", "is_up": True, "key": "interface_name", - "rx": 3631, + "rx": 2671, "speed": 0, "time_since_update": 1, - "tx": 3631}, + "tx": 2671}, {"alias": None, - "cumulative_cx": 10030241644, - "cumulative_rx": 9391810395, - "cumulative_tx": 638431249, - "cx": 29813, + "cumulative_cx": 36011739106, + "cumulative_rx": 34790353651, + "cumulative_tx": 1221385455, + "cx": 24457, "interface_name": "wlp2s0", "is_up": True, "key": "interface_name", - "rx": 22832, + "rx": 18960, "speed": 0, "time_since_update": 1, - "tx": 6981}] + "tx": 5497}] Fields descriptions: @@ -427,8 +487,10 @@ Fields descriptions: * **alias**: Interface alias name (optional) (unit is *string*) * **rx**: The received/input rate (in bit per second) (unit is *bps*) * **tx**: The sent/output rate (in bit per second) (unit is *bps*) +* **cx**: The cumulative received+sent rate (in bit per second) (unit is *bps*) * **cumulative_rx**: The number of bytes received through the interface (cumulative) (unit is *bytes*) * **cumulative_tx**: The number of bytes sent through the interface (cumulative) (unit is *bytes*) +* **cumulative_cx**: The cumulative number of bytes reveived and sent through the interface (cumulative) (unit is *bytes*) * **speed**: Maximum interface speed (in bit per second). Can return 0 on some operating-system (unit is *bps*) * **is_up**: Is the interface up ? (unit is *bool*) * **time_since_update**: Number of seconds since last update (unit is *seconds*) @@ -438,28 +500,32 @@ Get a specific field:: # curl http://localhost:61208/api/3/network/interface_name {"interface_name": ["lo", "wlp2s0", - "br-87386b77b676", "br_grafana", "br-119e6ee04e05", "docker0", - "vethfb650c2", - "mpqemubr0"]} + "br-87386b77b676", + "mpqemubr0", + "tap-1e376645a40", + "br-ef0a06c4e10f", + "veth9910148", + "veth5e7315e", + "veth24ae93e"]} Get a specific item when field matchs the given value:: # curl http://localhost:61208/api/3/network/interface_name/lo {"lo": [{"alias": None, - "cumulative_cx": 450898582, - "cumulative_rx": 225449291, - "cumulative_tx": 225449291, - "cx": 7262, + "cumulative_cx": 1140515614, + "cumulative_rx": 570257807, + "cumulative_tx": 570257807, + "cx": 5342, "interface_name": "lo", "is_up": True, "key": "interface_name", - "rx": 3631, + "rx": 2671, "speed": 0, "time_since_update": 1, - "tx": 3631}]} + "tx": 2671}]} GET now ------- @@ -467,7 +533,7 @@ GET now Get plugin stats:: # curl http://localhost:61208/api/3/now - "2022-11-03 15:38:47 CET" + "2023-03-11 17:30:43 CET" GET percpu ---------- @@ -478,29 +544,29 @@ Get plugin stats:: [{"cpu_number": 0, "guest": 0.0, "guest_nice": 0.0, - "idle": 63.8, + "idle": 22.0, "iowait": 0.0, "irq": 0.0, "key": "cpu_number", "nice": 0.0, "softirq": 0.0, "steal": 0.0, - "system": 4.8, - "total": 36.2, - "user": 31.4}, + "system": 1.0, + "total": 78.0, + "user": 67.0}, {"cpu_number": 1, "guest": 0.0, "guest_nice": 0.0, - "idle": 75.0, + "idle": 81.0, "iowait": 0.0, "irq": 0.0, "key": "cpu_number", "nice": 0.0, "softirq": 0.0, "steal": 0.0, - "system": 5.0, - "total": 25.0, - "user": 16.0}] + "system": 2.0, + "total": 19.0, + "user": 7.0}] Get a specific field:: @@ -519,7 +585,7 @@ Get plugin stats:: "port": 0, "refresh": 30, "rtt_warning": None, - "status": 0.027686, + "status": 0.003449, "timeout": 3}] Get a specific field:: @@ -536,7 +602,7 @@ Get a specific item when field matchs the given value:: "port": 0, "refresh": 30, "rtt_warning": None, - "status": 0.027686, + "status": 0.003449, "timeout": 3}]} GET processcount @@ -545,12 +611,12 @@ GET processcount Get plugin stats:: # curl http://localhost:61208/api/3/processcount - {"pid_max": 0, "running": 3, "sleeping": 324, "thread": 1659, "total": 393} + {"pid_max": 0, "running": 1, "sleeping": 319, "thread": 1542, "total": 387} Get a specific field:: # curl http://localhost:61208/api/3/processcount/total - {"total": 393} + {"total": 387} GET processlist --------------- @@ -558,51 +624,51 @@ GET processlist Get plugin stats:: # curl http://localhost:61208/api/3/processlist - [{"cmdline": ["/snap/firefox/1943/usr/lib/firefox/firefox"], + [{"cmdline": ["/snap/firefox/2391/usr/lib/firefox/firefox"], "cpu_percent": 0.0, - "cpu_times": pcputimes(user=8365.21, system=2822.21, children_user=7790.52, children_system=1387.48, iowait=0.0), - "gids": pgids(real=1000, effective=1000, saved=1000), - "io_counters": [4765441024, 9684750336, 0, 0, 0], + "cpu_times": [1287.11, 419.09, 1097.08, 148.64, 0.0], + "gids": [1000, 1000, 1000], + "io_counters": [502609920, 1333940224, 0, 0, 0], "key": "pid", - "memory_info": pmem(rss=556318720, vms=13286076416, shared=121720832, text=634880, lib=0, data=1310076928, dirty=0), - "memory_percent": 7.099353311742211, + "memory_info": [509206528, 21605502976, 176431104, 626688, 0, 833679360, 0], + "memory_percent": 6.498133429231825, "name": "firefox", "nice": 0, - "num_threads": 151, - "pid": 252940, + "num_threads": 117, + "pid": 846720, "status": "S", "time_since_update": 1, "username": "nicolargo"}, - {"cmdline": ["/snap/firefox/1943/usr/lib/firefox/firefox", + {"cmdline": ["/snap/firefox/2391/usr/lib/firefox/firefox", "-contentproc", "-childID", "1", "-isForBrowser", "-prefsLen", - "30965", + "31514", "-prefMapSize", - "235589", + "238439", "-jsInitLen", - "246848", + "246560", "-parentBuildID", - "20221007191409", + "20230228074855", "-appDir", - "/snap/firefox/1943/usr/lib/firefox/browser", - "{9845d5f8-7cf9-4af9-9d46-4d914b28196f}", - "252940", + "/snap/firefox/2391/usr/lib/firefox/browser", + "{0f8147f2-5422-4d6d-9491-68894fb5c106}", + "846720", "true", "tab"], "cpu_percent": 0.0, - "cpu_times": pcputimes(user=1498.65, system=289.34, children_user=0.0, children_system=0.0, iowait=0.0), - "gids": pgids(real=1000, effective=1000, saved=1000), - "io_counters": [204542976, 0, 0, 0, 0], + "cpu_times": [185.15, 34.08, 0.0, 0.0, 0.0], + "gids": [1000, 1000, 1000], + "io_counters": [9207808, 0, 0, 0, 0], "key": "pid", - "memory_info": pmem(rss=445616128, vms=3534884864, shared=79106048, text=634880, lib=0, data=932179968, dirty=0), - "memory_percent": 5.686643681669639, + "memory_info": [435576832, 3219697664, 100659200, 626688, 0, 613511168, 0], + "memory_percent": 5.558523344418112, "name": "WebExtensions", "nice": 0, - "num_threads": 21, - "pid": 253132, + "num_threads": 20, + "pid": 846991, "status": "S", "time_since_update": 1, "username": "nicolargo"}] @@ -610,234 +676,223 @@ Get plugin stats:: Get a specific field:: # curl http://localhost:61208/api/3/processlist/pid - {"pid": [252940, - 253132, - 3549, - 590528, - 253182, - 590488, - 607540, - 479037, - 479255, - 604831, - 253186, - 479104, - 17347, - 549166, - 253147, - 51440, - 478972, - 479089, - 601048, - 608133, - 608049, - 608003, - 480067, - 602074, - 450641, - 479007, - 597870, - 482393, - 590512, - 603305, - 608247, - 546430, - 4055, - 602075, - 495478, - 3958, - 3499, - 546431, - 2245, - 521697, - 479112, - 521756, - 590492, - 253071, - 253654, - 521757, - 450239, - 16698, - 479015, - 521726, - 255947, - 557500, - 479296, - 2917, - 449090, - 3651, - 2429, - 3844, - 3364, - 521696, - 4977, - 3744, - 450957, - 1369, - 3743, - 17373, - 17566, - 4062, - 17754, + {"pid": [846720, + 846991, + 847043, + 4150, + 847035, + 255919, + 255685, + 847039, + 859882, + 836010, + 255737, + 847051, + 4473, + 847007, + 285410, + 422, + 875536, + 255627, + 258480, + 6074, + 255751, + 876641, + 876390, + 847507, + 876962, + 255664, + 62850, + 877142, + 2512, + 4544, + 4035, + 846970, + 847508, + 256270, + 258481, + 255769, + 596789, + 285072, + 95798, + 2721, + 4585, + 255672, + 4413, + 789543, + 860282, + 285950, + 4248, + 789544, + 3955, + 286011, + 255906, + 255976, + 4932, + 1635, + 829380, + 829424, + 14455, 1, - 3737, - 107498, - 3627, - 3929, - 1391, - 566917, - 1415, - 478976, - 3760, - 544074, - 17501, - 3618, - 19717, - 3742, - 3345, - 1587, - 603476, - 3528, - 107499, - 4087, - 544139, - 3663, - 492260, - 1945, - 3806, - 3592, - 478977, - 17308, - 3736, - 109608, - 3353, - 1381, - 17346, - 3557, - 480091, - 17292, - 3750, - 2371, - 1416, - 1593, - 1368, - 3745, - 3637, - 1487, - 3378, - 2412, - 1352, - 17755, - 2187, - 3891, - 3739, - 3817, - 1408, - 3373, - 51420, - 15018, - 1917, - 3799, - 3616, - 14997, - 3697, - 3380, - 1615, - 17237, - 1392, - 3943, - 3599, - 3588, - 54676, - 483374, - 1375, - 3905, - 3755, - 3547, - 3633, - 1407, - 3741, - 3813, - 3604, - 3444, - 3569, - 523017, - 3583, - 3734, - 3747, - 1397, - 3753, - 3748, - 17238, - 3804, - 1365, - 3362, - 1412, - 3437, - 3729, - 3385, - 3361, - 4518, - 1360, - 568870, - 3556, - 479311, - 3517, - 54624, - 282637, - 1399, - 1743, - 1377, - 1176, - 17258, - 602118, - 1367, - 2405, - 450933, - 568871, - 1470, - 2920, + 4325, + 4331, + 4223, + 4332, + 4561, + 4214, + 3351, + 4625, + 1660, + 1681, + 219792, + 14458, + 1876, + 4327, + 3934, + 3944, + 5299, + 4182, + 4130, + 4659, + 4263, + 4445, + 286108, + 4339, + 4233, + 4137, + 2239, + 1682, + 129087, + 4352, + 129101, + 4261, + 255632, + 830552, + 823483, + 17189, + 4377, + 129097, + 3968, + 1634, + 1442, + 255633, + 1777, + 2179, + 117714, + 59511, + 4330, + 4452, + 1643, + 706956, + 17205, + 1655, + 4524, + 3700, + 706252, + 3966, + 4229, + 3971, + 1873, + 96102, + 4201, + 4192, + 1673, + 4334, + 4392, + 4155, + 4329, + 4443, + 1617, + 4328, + 1675, + 4573, + 4485, + 1661, + 4337, + 4050, + 285853, + 1631, + 4178, + 4166, + 1666, + 4348, + 4324, + 4335, + 4045, + 4347, + 285970, + 285913, + 4173, + 468, + 4212, + 3976, + 1885, + 1626, + 1676, + 4314, + 1670, + 9703, + 1646, + 4119, + 1443, + 877118, + 3952, + 129099, + 49191, + 2020, + 255649, + 1633, + 4162, + 1441, + 14505, + 49179, 3953, - 608222, - 17516, - 2406, - 181215, - 58637, - 478993, - 58407, - 54523, - 1363, - 181218, - 181225, - 1353, - 478979, - 608246, - 181228, - 2208, - 3733, - 4187, - 450920, - 3425, - 450913, - 594820, - 450892, - 450882, - 58639, - 2226, + 3701, 3354, - 567106, - 2252, - 1485, - 568756, - 568754, - 568874, - 181221, + 129100, + 1449, + 1685, + 4579, + 1450, + 2472, + 219931, + 49182, + 1618, + 843176, + 877141, + 1804, + 49194, + 1803, + 4323, + 2480, + 3707, + 4018, + 255635, + 285883, + 285777, + 285877, + 872737, + 285835, + 285843, + 285784, + 285905, + 3945, + 4820, + 285898, + 2475, + 1447, + 2503, + 2485, + 706960, + 1628, + 1695, + 49185, 2, 3, 4, 5, - 7, - 9, + 6, + 8, 10, 11, 12, @@ -879,152 +934,157 @@ Get a specific field:: 99, 100, 101, - 103, - 105, + 104, 106, - 108, + 107, + 109, 110, 112, - 114, + 117, 118, - 119, - 121, - 130, - 133, - 139, - 188, - 195, - 196, - 197, - 198, - 199, - 200, + 128, + 131, + 137, + 171, + 175, 201, - 202, - 210, - 211, - 216, + 205, 217, - 234, - 283, - 284, - 359, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 248, + 249, + 254, + 255, + 312, + 361, 362, - 386, - 485, - 495, - 559, - 560, - 561, - 562, - 778, - 779, - 780, - 781, - 788, - 789, - 790, - 791, - 792, - 793, - 794, - 795, - 848, - 849, - 850, - 851, - 852, - 853, - 854, - 855, - 856, - 857, - 858, - 859, - 860, - 861, - 862, - 863, - 864, - 865, - 866, - 890, - 891, - 898, - 899, - 915, - 916, - 917, - 918, - 919, - 920, - 921, - 1891, - 1897, - 2256, - 2266, - 3584, - 17240, - 17274, - 58642, - 58643, - 58644, - 58645, - 58646, - 58647, - 58648, - 58649, - 58650, - 543848, - 543849, - 543851, - 557402, - 557403, - 557405, - 557406, - 557407, - 557455, - 599474, - 600991, - 600996, - 601072, - 602168, - 604267, - 604944, - 605094, - 605573, - 606456, - 606737, - 606840, - 606857, - 606952, - 607316, - 607432, - 607520, - 607844, - 608070]} + 442, + 447, + 577, + 601, + 676, + 677, + 678, + 693, + 963, + 964, + 965, + 966, + 967, + 968, + 969, + 970, + 971, + 972, + 973, + 974, + 1026, + 1027, + 1028, + 1029, + 1030, + 1031, + 1032, + 1033, + 1034, + 1035, + 1036, + 1037, + 1038, + 1039, + 1040, + 1041, + 1042, + 1043, + 1044, + 1071, + 1072, + 1080, + 1081, + 1105, + 1106, + 1107, + 1108, + 1109, + 1110, + 1111, + 2504, + 2521, + 2531, + 2597, + 2598, + 2599, + 2600, + 2602, + 2604, + 2609, + 2610, + 4034, + 18603, + 220739, + 220749, + 220750, + 220751, + 220752, + 220756, + 285941, + 829051, + 829052, + 829054, + 859825, + 860163, + 860164, + 860166, + 860167, + 860169, + 860220, + 868345, + 871910, + 872852, + 873104, + 873258, + 873643, + 874420, + 874573, + 874834, + 874866, + 875114, + 875396, + 875564, + 876077, + 876089, + 876121, + 876528, + 876924, + 877134]} Get a specific item when field matchs the given value:: - # curl http://localhost:61208/api/3/processlist/pid/252940 - {"252940": [{"cmdline": ["/snap/firefox/1943/usr/lib/firefox/firefox"], + # curl http://localhost:61208/api/3/processlist/pid/846720 + {"846720": [{"cmdline": ["/snap/firefox/2391/usr/lib/firefox/firefox"], "cpu_percent": 0.0, - "cpu_times": [8365.21, 2822.21, 7790.52, 1387.48, 0.0], + "cpu_times": [1287.11, 419.09, 1097.08, 148.64, 0.0], "gids": [1000, 1000, 1000], - "io_counters": [4765441024, 9684750336, 0, 0, 0], + "io_counters": [502609920, 1333940224, 0, 0, 0], "key": "pid", - "memory_info": [556318720, - 13286076416, - 121720832, - 634880, + "memory_info": [509206528, + 21605502976, + 176431104, + 626688, 0, - 1310076928, + 833679360, 0], - "memory_percent": 7.099353311742211, + "memory_percent": 6.498133429231825, "name": "firefox", "nice": 0, - "num_threads": 151, - "pid": 252940, + "num_threads": 117, + "pid": 846720, "status": "S", "time_since_update": 1, "username": "nicolargo"}]} @@ -1035,7 +1095,7 @@ GET psutilversion Get plugin stats:: # curl http://localhost:61208/api/3/psutilversion - (5, 9, 2) + [5, 9, 4] GET quicklook ------------- @@ -1043,28 +1103,54 @@ GET quicklook Get plugin stats:: # curl http://localhost:61208/api/3/quicklook - {"cpu": 40.1, - "cpu_hz": 1700000000.0, - "cpu_hz_current": 1697255250.0, + {"cpu": 29.8, + "cpu_hz": 3000000000.0, + "cpu_hz_current": 1604295750.0, "cpu_name": "Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz", - "mem": 70.8, + "mem": 69.1, "percpu": [{"cpu_number": 0, "guest": 0.0, "guest_nice": 0.0, - "idle": 63.8, + "idle": 22.0, "iowait": 0.0, "irq": 0.0, "key": "cpu_number", "nice": 0.0, "softirq": 0.0, "steal": 0.0, - "system": 4.8, - "total": 36.2, - "user": 31.4}, + "system": 1.0, + "total": 78.0, + "user": 67.0}, {"cpu_number": 1, "guest": 0.0, "guest_nice": 0.0, - "idle": 75.0, + "idle": 81.0, + "iowait": 0.0, + "irq": 0.0, + "key": "cpu_number", + "nice": 0.0, + "softirq": 0.0, + "steal": 0.0, + "system": 2.0, + "total": 19.0, + "user": 7.0}, + {"cpu_number": 2, + "guest": 0.0, + "guest_nice": 0.0, + "idle": 70.0, + "iowait": 0.0, + "irq": 0.0, + "key": "cpu_number", + "nice": 0.0, + "softirq": 0.0, + "steal": 0.0, + "system": 2.0, + "total": 30.0, + "user": 20.0}, + {"cpu_number": 3, + "guest": 0.0, + "guest_nice": 0.0, + "idle": 83.0, "iowait": 0.0, "irq": 0.0, "key": "cpu_number", @@ -1072,40 +1158,14 @@ Get plugin stats:: "softirq": 0.0, "steal": 0.0, "system": 5.0, - "total": 25.0, - "user": 16.0}, - {"cpu_number": 2, - "guest": 0.0, - "guest_nice": 0.0, - "idle": 59.0, - "iowait": 0.0, - "irq": 0.0, - "key": "cpu_number", - "nice": 0.0, - "softirq": 0.0, - "steal": 0.0, - "system": 4.0, - "total": 41.0, - "user": 37.0}, - {"cpu_number": 3, - "guest": 0.0, - "guest_nice": 0.0, - "idle": 37.0, - "iowait": 0.0, - "irq": 0.0, - "key": "cpu_number", - "nice": 0.0, - "softirq": 1.0, - "steal": 0.0, - "system": 9.0, - "total": 63.0, - "user": 52.0}], - "swap": 47.5} + "total": 17.0, + "user": 6.0}], + "swap": 27.3} Get a specific field:: # curl http://localhost:61208/api/3/quicklook/cpu - {"cpu": 40.1} + {"cpu": 29.8} GET sensors ----------- @@ -1115,14 +1175,14 @@ Get plugin stats:: # curl http://localhost:61208/api/3/sensors [{"critical": 105, "key": "label", - "label": "acpitz 1", + "label": "acpitz 0", "type": "temperature_core", "unit": "C", "value": 27, "warning": 105}, {"critical": 105, "key": "label", - "label": "acpitz 2", + "label": "acpitz 1", "type": "temperature_core", "unit": "C", "value": 29, @@ -1131,8 +1191,8 @@ Get plugin stats:: Get a specific field:: # curl http://localhost:61208/api/3/sensors/label - {"label": ["acpitz 1", - "acpitz 2", + {"label": ["acpitz 0", + "acpitz 1", "Package id 0", "Core 0", "Core 1", @@ -1143,10 +1203,10 @@ Get a specific field:: Get a specific item when field matchs the given value:: - # curl http://localhost:61208/api/3/sensors/label/acpitz 1 - {"acpitz 1": [{"critical": 105, + # curl http://localhost:61208/api/3/sensors/label/acpitz 0 + {"acpitz 0": [{"critical": 105, "key": "label", - "label": "acpitz 1", + "label": "acpitz 0", "type": "temperature_core", "unit": "C", "value": 27, @@ -1162,7 +1222,7 @@ Get plugin stats:: "hr_name": "Ubuntu 22.04 64bit", "linux_distro": "Ubuntu 22.04", "os_name": "Linux", - "os_version": "5.15.0-48-generic", + "os_version": "5.15.0-58-generic", "platform": "64bit"} Get a specific field:: @@ -1176,7 +1236,7 @@ GET uptime Get plugin stats:: # curl http://localhost:61208/api/3/uptime - {"seconds": 1663028} + "56 days, 0:19:45" GET all stats ------------- @@ -1192,33 +1252,33 @@ GET stats history History of a plugin:: # curl http://localhost:61208/api/3/cpu/history - {"system": [["2022-11-03T15:38:48.622076", 9.2], - ["2022-11-03T15:38:49.730978", 9.2], - ["2022-11-03T15:38:51.050563", 10.3]], - "user": [["2022-11-03T15:38:48.622053", 43.2], - ["2022-11-03T15:38:49.730971", 43.2], - ["2022-11-03T15:38:51.050548", 39.8]]} + {"system": [["2023-03-11T17:30:44.653473", 4.0], + ["2023-03-11T17:30:45.724303", 4.0], + ["2023-03-11T17:30:46.822979", 0.9]], + "user": [["2023-03-11T17:30:44.653466", 25.2], + ["2023-03-11T17:30:45.724298", 25.2], + ["2023-03-11T17:30:46.822974", 5.1]]} Limit history to last 2 values:: # curl http://localhost:61208/api/3/cpu/history/2 - {"system": [["2022-11-03T15:38:49.730978", 9.2], - ["2022-11-03T15:38:51.050563", 10.3]], - "user": [["2022-11-03T15:38:49.730971", 43.2], - ["2022-11-03T15:38:51.050548", 39.8]]} + {"system": [["2023-03-11T17:30:45.724303", 4.0], + ["2023-03-11T17:30:46.822979", 0.9]], + "user": [["2023-03-11T17:30:45.724298", 25.2], + ["2023-03-11T17:30:46.822974", 5.1]]} History for a specific field:: # curl http://localhost:61208/api/3/cpu/system/history - {"system": [["2022-11-03T15:38:48.622076", 9.2], - ["2022-11-03T15:38:49.730978", 9.2], - ["2022-11-03T15:38:51.050563", 10.3]]} + {"system": [["2023-03-11T17:30:44.653473", 4.0], + ["2023-03-11T17:30:45.724303", 4.0], + ["2023-03-11T17:30:46.822979", 0.9]]} Limit history for a specific field to last 2 values:: # curl http://localhost:61208/api/3/cpu/system/history - {"system": [["2022-11-03T15:38:49.730978", 9.2], - ["2022-11-03T15:38:51.050563", 10.3]]} + {"system": [["2023-03-11T17:30:45.724303", 4.0], + ["2023-03-11T17:30:46.822979", 0.9]]} GET limits (used for thresholds) -------------------------------- @@ -1226,10 +1286,9 @@ GET limits (used for thresholds) All limits/thresholds:: # curl http://localhost:61208/api/3/all/limits - {"alert": {"history_size": 3600.0}, - "amps": {"amps_disable": ["False"], "history_size": 3600.0}, - "cloud": {"history_size": 3600.0}, - "core": {"history_size": 3600.0}, + {"alert": {"history_size": 1200.0}, + "amps": {"amps_disable": ["False"], "history_size": 1200.0}, + "core": {"history_size": 1200.0}, "cpu": {"cpu_ctx_switches_careful": 160000.0, "cpu_ctx_switches_critical": 200000.0, "cpu_ctx_switches_warning": 180000.0, @@ -1252,21 +1311,21 @@ All limits/thresholds:: "cpu_user_critical": 90.0, "cpu_user_log": ["False"], "cpu_user_warning": 70.0, - "history_size": 3600.0}, + "history_size": 1200.0}, "diskio": {"diskio_disable": ["False"], - "diskio_hide": ["loop.*", "/dev/loop*"], - "history_size": 3600.0}, + "diskio_hide": ["loop.*", "/dev/loop.*"], + "history_size": 1200.0}, "docker": {"docker_all": ["False"], "docker_disable": ["False"], "docker_max_name_size": 20.0, - "history_size": 3600.0}, - "folders": {"folders_disable": ["False"], "history_size": 3600.0}, + "history_size": 1200.0}, + "folders": {"folders_disable": ["False"], "history_size": 1200.0}, "fs": {"fs_careful": 50.0, "fs_critical": 90.0, "fs_disable": ["False"], "fs_hide": ["/boot.*", "/snap.*"], "fs_warning": 70.0, - "history_size": 3600.0}, + "history_size": 1200.0}, "gpu": {"gpu_disable": ["False"], "gpu_mem_careful": 50.0, "gpu_mem_critical": 90.0, @@ -1274,9 +1333,9 @@ All limits/thresholds:: "gpu_proc_careful": 50.0, "gpu_proc_critical": 90.0, "gpu_proc_warning": 70.0, - "history_size": 3600.0}, - "help": {"history_size": 3600.0}, - "ip": {"history_size": 3600.0, + "history_size": 1200.0}, + "help": {"history_size": 1200.0}, + "ip": {"history_size": 1200.0, "ip_censys_fields": ["location:continent", "location:country", "autonomous_system:name"], @@ -1284,22 +1343,22 @@ All limits/thresholds:: "ip_disable": ["False"], "ip_public_ip_disabled": ["False"], "ip_public_refresh_interval": 300.0}, - "load": {"history_size": 3600.0, + "load": {"history_size": 1200.0, "load_careful": 0.7, "load_critical": 5.0, "load_disable": ["False"], "load_warning": 1.0}, - "mem": {"history_size": 3600.0, + "mem": {"history_size": 1200.0, "mem_careful": 50.0, "mem_critical": 90.0, "mem_disable": ["False"], "mem_warning": 70.0}, - "memswap": {"history_size": 3600.0, + "memswap": {"history_size": 1200.0, "memswap_careful": 50.0, "memswap_critical": 90.0, "memswap_disable": ["False"], "memswap_warning": 70.0}, - "network": {"history_size": 3600.0, + "network": {"history_size": 1200.0, "network_disable": ["False"], "network_rx_careful": 70.0, "network_rx_critical": 90.0, @@ -1307,8 +1366,8 @@ All limits/thresholds:: "network_tx_careful": 70.0, "network_tx_critical": 90.0, "network_tx_warning": 80.0}, - "now": {"history_size": 3600.0}, - "percpu": {"history_size": 3600.0, + "now": {"history_size": 1200.0}, + "percpu": {"history_size": 1200.0, "percpu_disable": ["False"], "percpu_iowait_careful": 50.0, "percpu_iowait_critical": 90.0, @@ -1319,13 +1378,13 @@ All limits/thresholds:: "percpu_user_careful": 50.0, "percpu_user_critical": 90.0, "percpu_user_warning": 70.0}, - "ports": {"history_size": 3600.0, + "ports": {"history_size": 1200.0, "ports_disable": ["False"], "ports_port_default_gateway": ["True"], "ports_refresh": 30.0, "ports_timeout": 3.0}, - "processcount": {"history_size": 3600.0, "processcount_disable": ["False"]}, - "processlist": {"history_size": 3600.0, + "processcount": {"history_size": 1200.0, "processcount_disable": ["False"]}, + "processlist": {"history_size": 1200.0, "processlist_cpu_careful": 50.0, "processlist_cpu_critical": 90.0, "processlist_cpu_warning": 70.0, @@ -1372,8 +1431,8 @@ All limits/thresholds:: "17", "18", "19"]}, - "psutilversion": {"history_size": 3600.0}, - "quicklook": {"history_size": 3600.0, + "psutilversion": {"history_size": 1200.0}, + "quicklook": {"history_size": 1200.0, "quicklook_cpu_careful": 50.0, "quicklook_cpu_critical": 90.0, "quicklook_cpu_warning": 70.0, @@ -1385,7 +1444,7 @@ All limits/thresholds:: "quicklook_swap_careful": 50.0, "quicklook_swap_critical": 90.0, "quicklook_swap_warning": 70.0}, - "sensors": {"history_size": 3600.0, + "sensors": {"history_size": 1200.0, "sensors_battery_careful": 80.0, "sensors_battery_critical": 95.0, "sensors_battery_warning": 90.0, @@ -1397,10 +1456,10 @@ All limits/thresholds:: "sensors_temperature_hdd_careful": 45.0, "sensors_temperature_hdd_critical": 60.0, "sensors_temperature_hdd_warning": 52.0}, - "system": {"history_size": 3600.0, + "system": {"history_size": 1200.0, "system_disable": ["False"], "system_refresh": 60}, - "uptime": {"history_size": 3600.0}} + "uptime": {"history_size": 1200.0}} Limits/thresholds for the cpu plugin:: @@ -1427,5 +1486,5 @@ Limits/thresholds for the cpu plugin:: "cpu_user_critical": 90.0, "cpu_user_log": ["False"], "cpu_user_warning": 70.0, - "history_size": 3600.0} + "history_size": 1200.0} diff --git a/docs/cmds.rst b/docs/cmds.rst index 055664ff..7a2fb069 100644 --- a/docs/cmds.rst +++ b/docs/cmds.rst @@ -174,7 +174,7 @@ Command-Line Options set the server cache time [default: 1 sec] -.. option:: open-web-browser +.. option:: --open-web-browser try to open the Web UI in the default Web browser diff --git a/docs/gw/couchdb.rst b/docs/gw/couchdb.rst index 66c547ba..3e4d92bd 100644 --- a/docs/gw/couchdb.rst +++ b/docs/gw/couchdb.rst @@ -9,42 +9,35 @@ following: .. code-block:: ini - [couchdb] + [mongodb] host=localhost - port=5984 - user=root - password=root + port=27017 db=glances + user=root + password=example and run Glances with: .. code-block:: console - $ glances --export couchdb + $ glances --export mongodb -Documents are stored in native ``JSON`` format. Glances adds ``"type"`` -and ``"time"`` entries: +Documents are stored in native the configured database (glances by default) +with one collection per plugin. -- ``type``: plugin name -- ``time``: timestamp (format: "2016-09-24T16:39:08.524828Z") - -Example of Couch Document for the load stats: +Example of MongoDB Document for the load stats: .. code-block:: json { - "_id": "36cbbad81453c53ef08804cb2612d5b6", - "_rev": "1-382400899bec5615cabb99aa34df49fb", - "min15": 0.33, - "time": "2016-09-24T16:39:08.524828Z", - "min5": 0.4, - "cpucore": 4, - "load_warning": 1, - "min1": 0.5, - "history_size": 28800, - "load_critical": 5, - "type": "load", - "load_careful": 0.7 + _id: ObjectId('63d78ffee5528e543ce5af3a'), + min1: 1.46337890625, + min5: 1.09619140625, + min15: 1.07275390625, + cpucore: 4, + history_size: 1200, + load_disable: 'False', + load_careful: 0.7, + load_warning: 1, + load_critical: 5 } - -You can view the result using the CouchDB utils URL: http://127.0.0.1:5984/_utils/database.html?glances. diff --git a/docs/gw/index.rst b/docs/gw/index.rst index 8052e744..e0b635f2 100644 --- a/docs/gw/index.rst +++ b/docs/gw/index.rst @@ -18,6 +18,7 @@ to providing stats to multiple services (see list below). json kafka mqtt + mongodb opentsdb prometheus rabbitmq diff --git a/docs/gw/mongodb.rst b/docs/gw/mongodb.rst new file mode 100644 index 00000000..4ef71692 --- /dev/null +++ b/docs/gw/mongodb.rst @@ -0,0 +1,50 @@ +.. _couchdb: + +MongoDB +======= + +You can export statistics to a ``MongoDB`` server. +The connection should be defined in the Glances configuration file as +following: + +.. code-block:: ini + + [couchdb] + host=localhost + port= + user=root + password=example + db=glances + +and run Glances with: + +.. code-block:: console + + $ glances --export couchdb + +Documents are stored in native ``JSON`` format. Glances adds ``"type"`` +and ``"time"`` entries: + +- ``type``: plugin name +- ``time``: timestamp (format: "2016-09-24T16:39:08.524828Z") + +Example of Couch Document for the load stats: + +.. code-block:: json + + { + "_id": "36cbbad81453c53ef08804cb2612d5b6", + "_rev": "1-382400899bec5615cabb99aa34df49fb", + "min15": 0.33, + "time": "2016-09-24T16:39:08.524828Z", + "min5": 0.4, + "cpucore": 4, + "load_warning": 1, + "min1": 0.5, + "history_size": 28800, + "load_critical": 5, + "type": "load", + "load_careful": 0.7 + } + +You can view the result using the CouchDB utils URL: http://127.0.0.1:5984/_utils/database.html?glances. diff --git a/docs/man/glances.1 b/docs/man/glances.1 index d3bf7346..fcfc5f2b 100644 --- a/docs/man/glances.1 +++ b/docs/man/glances.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "GLANCES" "1" "Nov 03, 2022" "3.3.1_beta1" "Glances" +.TH "GLANCES" "1" "Mar 11, 2023" "3.4.0_beta1" "Glances" .SH NAME glances \- An eye on your system .SH SYNOPSIS @@ -258,7 +258,7 @@ set the server cache time [default: 1 sec] .UNINDENT .INDENT 0.0 .TP -.B open\-web\-browser +.B \-\-open\-web\-browser try to open the Web UI in the default Web browser .UNINDENT .INDENT 0.0 @@ -732,60 +732,60 @@ format): .nf .ft C { - "version": 1, - "disable_existing_loggers": "False", - "root": { - "level": "INFO", - "handlers": ["file", "console"] + \(dqversion\(dq: 1, + \(dqdisable_existing_loggers\(dq: \(dqFalse\(dq, + \(dqroot\(dq: { + \(dqlevel\(dq: \(dqINFO\(dq, + \(dqhandlers\(dq: [\(dqfile\(dq, \(dqconsole\(dq] }, - "formatters": { - "standard": { - "format": "%(asctime)s \-\- %(levelname)s \-\- %(message)s" + \(dqformatters\(dq: { + \(dqstandard\(dq: { + \(dqformat\(dq: \(dq%(asctime)s \-\- %(levelname)s \-\- %(message)s\(dq }, - "short": { - "format": "%(levelname)s: %(message)s" + \(dqshort\(dq: { + \(dqformat\(dq: \(dq%(levelname)s: %(message)s\(dq }, - "free": { - "format": "%(message)s" + \(dqfree\(dq: { + \(dqformat\(dq: \(dq%(message)s\(dq } }, - "handlers": { - "file": { - "level": "DEBUG", - "class": "logging.handlers.RotatingFileHandler", - "formatter": "standard", - "filename": "/var/tmp/glances.log" + \(dqhandlers\(dq: { + \(dqfile\(dq: { + \(dqlevel\(dq: \(dqDEBUG\(dq, + \(dqclass\(dq: \(dqlogging.handlers.RotatingFileHandler\(dq, + \(dqformatter\(dq: \(dqstandard\(dq, + \(dqfilename\(dq: \(dq/var/tmp/glances.log\(dq }, - "console": { - "level": "CRITICAL", - "class": "logging.StreamHandler", - "formatter": "free" + \(dqconsole\(dq: { + \(dqlevel\(dq: \(dqCRITICAL\(dq, + \(dqclass\(dq: \(dqlogging.StreamHandler\(dq, + \(dqformatter\(dq: \(dqfree\(dq } }, - "loggers": { - "debug": { - "handlers": ["file", "console"], - "level": "DEBUG" + \(dqloggers\(dq: { + \(dqdebug\(dq: { + \(dqhandlers\(dq: [\(dqfile\(dq, \(dqconsole\(dq], + \(dqlevel\(dq: \(dqDEBUG\(dq }, - "verbose": { - "handlers": ["file", "console"], - "level": "INFO" + \(dqverbose\(dq: { + \(dqhandlers\(dq: [\(dqfile\(dq, \(dqconsole\(dq], + \(dqlevel\(dq: \(dqINFO\(dq }, - "standard": { - "handlers": ["file"], - "level": "INFO" + \(dqstandard\(dq: { + \(dqhandlers\(dq: [\(dqfile\(dq], + \(dqlevel\(dq: \(dqINFO\(dq }, - "requests": { - "handlers": ["file", "console"], - "level": "ERROR" + \(dqrequests\(dq: { + \(dqhandlers\(dq: [\(dqfile\(dq, \(dqconsole\(dq], + \(dqlevel\(dq: \(dqERROR\(dq }, - "elasticsearch": { - "handlers": ["file", "console"], - "level": "ERROR" + \(dqelasticsearch\(dq: { + \(dqhandlers\(dq: [\(dqfile\(dq, \(dqconsole\(dq], + \(dqlevel\(dq: \(dqERROR\(dq }, - "elasticsearch.trace": { - "handlers": ["file", "console"], - "level": "ERROR" + \(dqelasticsearch.trace\(dq: { + \(dqhandlers\(dq: [\(dqfile\(dq, \(dqconsole\(dq], + \(dqlevel\(dq: \(dqERROR\(dq } } } @@ -885,6 +885,6 @@ $ glances –browser .sp Nicolas Hennion aka Nicolargo <\fI\%contact@nicolargo.com\fP> .SH COPYRIGHT -2022, Nicolas Hennion +2023, Nicolas Hennion .\" Generated by docutils manpage writer. . diff --git a/glances/__main__.py b/glances/__main__.py index 06d73c72..0da0b639 100644 --- a/glances/__main__.py +++ b/glances/__main__.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # -*- coding: utf-8 -*- # # Glances - An eye on your system diff --git a/glances/config.py b/glances/config.py index bbb77317..7138e48c 100644 --- a/glances/config.py +++ b/glances/config.py @@ -172,11 +172,7 @@ class Config(object): if not self.parser.has_section('global'): self.parser.add_section('global') self.set_default('global', 'strftime_format', '') - - # check_update - if not self.parser.has_section('global'): - self.parser.add_section('global') - self.set_default('global', 'check_update', 'false') + self.set_default('global', 'check_update', 'true') # Quicklook if not self.parser.has_section('quicklook'): diff --git a/glances/exports/cassandra/__init__.py b/glances/exports/cassandra/__init__.py index 195bb4b2..49a8c936 100644 --- a/glances/exports/cassandra/__init__.py +++ b/glances/exports/cassandra/__init__.py @@ -112,7 +112,6 @@ class Export(GlancesExport): # Write input to the Cassandra table try: - stmt = "INSERT INTO {} (plugin, time, stat) VALUES (?, ?, ?)".format(self.table) query = self.session.prepare(stmt) self.session.execute(query, (name, uuid_from_time(datetime.now()), data)) diff --git a/glances/exports/csv/__init__.py b/glances/exports/csv/__init__.py index e0f108c1..88e0615a 100644 --- a/glances/exports/csv/__init__.py +++ b/glances/exports/csv/__init__.py @@ -81,10 +81,10 @@ class Export(GlancesExport): # Loop over plugins to export for plugin in self.plugins_to_export(stats): if isinstance(all_stats[plugin], list): - for stat in all_stats[plugin]: + for stat in sorted(all_stats[plugin], key=lambda x: x['key']): # First line: header if self.first_line: - csv_header += ('{}_{}_{}'.format(plugin, self.get_item_key(stat), item) for item in stat) + csv_header += ['{}_{}_{}'.format(plugin, self.get_item_key(stat), item) for item in stat] # Others lines: stats csv_data += itervalues(stat) elif isinstance(all_stats[plugin], dict): diff --git a/glances/exports/glances_mongodb.py b/glances/exports/glances_mongodb.py new file mode 100644 index 00000000..556f6d60 --- /dev/null +++ b/glances/exports/glances_mongodb.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +# +# This file is part of Glances. +# +# SPDX-FileCopyrightText: 2023 Nicolas Hennion +# +# SPDX-License-Identifier: LGPL-3.0-only +# + +"""MongoDB interface class.""" + +import sys +from datetime import datetime + +from glances.logger import logger +from glances.exports.glances_export import GlancesExport + +import pymongo +from urllib.parse import quote_plus + + +class Export(GlancesExport): + + """This class manages the MongoDB export module.""" + + def __init__(self, config=None, args=None): + """Init the MongoDB export IF.""" + super(Export, self).__init__(config=config, args=args) + + # Mandatory configuration keys (additional to host and port) + self.db = None + + # Optional configuration keys + self.user = None + self.password = None + + # Load the Cassandra configuration file section + self.export_enable = self.load_conf('mongodb', mandatories=['host', 'port', 'db'], options=['user', 'password']) + if not self.export_enable: + sys.exit(2) + + # Init the CouchDB client + self.client = self.init() + + def init(self): + """Init the connection to the CouchDB server.""" + if not self.export_enable: + return None + + server_uri = 'mongodb://%s:%s@%s:%s' % (quote_plus(self.user), quote_plus(self.password), self.host, self.port) + + try: + client = pymongo.MongoClient(server_uri) + client.admin.command('ping') + except Exception as e: + logger.critical("Cannot connect to MongoDB server %s:%s (%s)" % (self.host, self.port, e)) + sys.exit(2) + else: + logger.info("Connected to the MongoDB server") + + return client + + def database(self): + """Return the CouchDB database object""" + return self.client[self.db] + + def export(self, name, columns, points): + """Write the points to the MongoDB server.""" + logger.debug("Export {} stats to MongoDB".format(name)) + + # Create DB input + data = dict(zip(columns, points)) + + # Write data to the MongoDB database + try: + self.database()[name].insert_one(data) + except Exception as e: + logger.error("Cannot export {} stats to MongoDB ({})".format(name, e)) diff --git a/glances/main.py b/glances/main.py index 9704fbc5..53a43a1a 100644 --- a/glances/main.py +++ b/glances/main.py @@ -235,6 +235,13 @@ Examples of use: dest='enable_separator', help='enable separator in the UI', ), + parser.add_argument( + '--disable-cursor', + action='store_true', + default=False, + dest='disable_cursor', + help='disable cursor (process selection) in the UI', + ), # Sort processes list parser.add_argument( '--sort-processes', @@ -699,6 +706,11 @@ Examples of use: logger.critical("Process filter is only available in standalone mode") sys.exit(2) + # Cursor option is only available in standalone mode + if not args.disable_cursor and not self.is_standalone(): + logger.critical("Cursor is only available in standalone mode") + sys.exit(2) + # Disable HDDTemp if sensors are disabled if getattr(self.args, 'disable_sensors', False): disable(self.args, 'hddtemp') diff --git a/glances/outdated.py b/glances/outdated.py index 2602bda0..9936d0b5 100644 --- a/glances/outdated.py +++ b/glances/outdated.py @@ -48,10 +48,15 @@ class Outdated(object): # Set default value... self.data = {u'installed_version': __version__, u'latest_version': '0.0', u'refresh_date': datetime.now()} - # Read the configuration file - self.load_config(config) + + # Disable update check if `packaging` is not installed if not PACKAGING_IMPORT: self.args.disable_check_update = True + + # Read the configuration file only if update check is not explicitly disabled + if not self.args.disable_check_update: + self.load_config(config) + logger.debug("Check Glances version up-to-date: {}".format(not self.args.disable_check_update)) # And update ! diff --git a/glances/outputs/glances_bottle.py b/glances/outputs/glances_bottle.py index 6e7a702a..741841ee 100644 --- a/glances/outputs/glances_bottle.py +++ b/glances/outputs/glances_bottle.py @@ -126,10 +126,8 @@ class GlancesBottle(object): if username == self.args.username: from glances.password import GlancesPassword - pwd = GlancesPassword(username=username, - config=self.config) - return pwd.check_password(self.args.password, - pwd.sha256_hash(password)) + pwd = GlancesPassword(username=username, config=self.config) + return pwd.check_password(self.args.password, pwd.get_hash(password)) else: return False @@ -161,6 +159,9 @@ class GlancesBottle(object): '/api/%s///history/' % self.API_VERSION, method="GET", callback=self._api_item_history ) self._app.route('/api/%s///' % self.API_VERSION, method="GET", callback=self._api_value) + self._app.route( + '/api/%s///' % self.API_VERSION, method="GET", callback=self._api_value + ) bindmsg = 'Glances RESTful API Server started on {}api/{}/'.format(self.bind_url, self.API_VERSION) logger.info(bindmsg) @@ -228,7 +229,7 @@ class GlancesBottle(object): """ response.status = 200 - return None + return "Active" @compress def _api_help(self): diff --git a/glances/outputs/glances_curses.py b/glances/outputs/glances_curses.py index 6c2601cd..6b2501da 100644 --- a/glances/outputs/glances_curses.py +++ b/glances/outputs/glances_curses.py @@ -267,6 +267,7 @@ class _GlancesCurses(object): self.ifCAREFUL_color2 = curses.color_pair(8) | A_BOLD self.ifWARNING_color2 = curses.color_pair(5) | A_BOLD self.ifCRITICAL_color2 = curses.color_pair(6) | A_BOLD + self.ifINFO_color = curses.color_pair(8) self.filter_color = A_BOLD self.selected_color = A_BOLD @@ -300,6 +301,7 @@ class _GlancesCurses(object): self.ifCAREFUL_color2 = curses.A_UNDERLINE self.ifWARNING_color2 = A_BOLD self.ifCRITICAL_color2 = curses.A_REVERSE + self.ifINFO_color = A_BOLD self.filter_color = A_BOLD self.selected_color = A_BOLD @@ -327,6 +329,7 @@ class _GlancesCurses(object): 'CRITICAL_LOG': self.ifCRITICAL_color, 'PASSWORD': curses.A_PROTECT, 'SELECTED': self.selected_color, + 'INFO': self.ifINFO_color } def set_cursor(self, value): @@ -406,13 +409,15 @@ class _GlancesCurses(object): elif self.pressedkey == ord('9'): # '9' > Theme from black to white and reverse self._init_colors() - elif self.pressedkey == ord('e'): + elif self.pressedkey == ord('e') and not self.args.programs: # 'e' > Enable/Disable process extended self.args.enable_process_extended = not self.args.enable_process_extended if not self.args.enable_process_extended: glances_processes.disable_extended() else: glances_processes.enable_extended() + # When a process is selected (and only in standalone mode), disable the cursor + self.args.disable_cursor = self.args.enable_process_extended and self.args.is_standalone elif self.pressedkey == ord('E'): # 'E' > Erase the process filter glances_processes.process_filter = None @@ -426,7 +431,7 @@ class _GlancesCurses(object): elif self.pressedkey == ord('-'): # '+' > Decrease process nice level self.decrease_nice_process = not self.decrease_nice_process - elif self.pressedkey == ord('k'): + elif self.pressedkey == ord('k') and not self.args.disable_cursor: # 'k' > Kill selected process (after confirmation) self.kill_process = not self.kill_process elif self.pressedkey == ord('w'): @@ -450,11 +455,11 @@ class _GlancesCurses(object): # ">" (right arrow) navigation through process sort next_sort = (self.loop_position() + 1) % len(self._sort_loop) glances_processes.set_sort_key(self._sort_loop[next_sort], False) - elif self.pressedkey == curses.KEY_UP or self.pressedkey == 65: + elif self.pressedkey == curses.KEY_UP or self.pressedkey == 65 and not self.args.disable_cursor: # 'UP' > Up in the server list if self.args.cursor_position > 0: self.args.cursor_position -= 1 - elif self.pressedkey == curses.KEY_DOWN or self.pressedkey == 66: + elif self.pressedkey == curses.KEY_DOWN or self.pressedkey == 66 and not self.args.disable_cursor: # 'DOWN' > Down in the server list # if self.args.cursor_position < glances_processes.max_processes - 2: if self.args.cursor_position < glances_processes.processes_count: @@ -679,7 +684,6 @@ class _GlancesCurses(object): new_filter = self.display_popup( 'Process filter pattern: \n\n' + 'Examples:\n' - + '- python\n' + '- .*python.*\n' + '- /usr/lib.*\n' + '- name:.*nautilus.*\n' @@ -1109,7 +1113,7 @@ class _GlancesCurses(object): def erase(self): """Erase the content of the screen.""" - self.term_window.erase() + self.term_window.clear() def flush(self, stats, cs_status=None): """Clear and update the screen. diff --git a/glances/outputs/glances_sparklines.py b/glances/outputs/glances_sparklines.py index 1a8c1f03..6d6d2b86 100644 --- a/glances/outputs/glances_sparklines.py +++ b/glances/outputs/glances_sparklines.py @@ -77,7 +77,7 @@ class Sparkline(object): def get(self): """Return the sparkline.""" - ret = sparklines(self.percents)[0] + ret = sparklines(self.percents, minimum=0, maximum=100)[0] if self.__with_text: percents_without_none = [x for x in self.percents if x is not None] if len(percents_without_none) > 0: diff --git a/glances/outputs/glances_stdout_apidoc.py b/glances/outputs/glances_stdout_apidoc.py index 34802872..4c75d069 100644 --- a/glances/outputs/glances_stdout_apidoc.py +++ b/glances/outputs/glances_stdout_apidoc.py @@ -70,7 +70,7 @@ def print_plugins_list(stat): print('') -def print_plugin_export(plugin, stat_export): +def print_plugin_stats(plugin, stat): sub_title = 'GET {}'.format(plugin) print(sub_title) print('-' * len(sub_title)) @@ -79,7 +79,7 @@ def print_plugin_export(plugin, stat_export): print('Get plugin stats::') print('') print(' # curl {}/{}'.format(API_URL, plugin)) - print(indent_stat(stat_export)) + print(indent_stat(json.loads(stat.get_stats()))) print('') @@ -223,7 +223,7 @@ class GlancesStdoutApiDoc(object): stat_export = stat.get_export() if stat_export is None or stat_export == [] or stat_export == {}: continue - print_plugin_export(plugin, stat_export) + print_plugin_stats(plugin, stat) print_plugin_description(plugin, stat) print_plugin_item_value(plugin, stat, stat_export) diff --git a/glances/outputs/static/js/App.vue b/glances/outputs/static/js/App.vue index cd6dcf84..576d3813 100644 --- a/glances/outputs/static/js/App.vue +++ b/glances/outputs/static/js/App.vue @@ -123,6 +123,7 @@ v-if="!args.disable_sensors" :data="data" > +
@@ -138,13 +139,6 @@
-
-
-
- -
-
-
diff --git a/glances/outputs/static/js/components/plugin-cloud.vue b/glances/outputs/static/js/components/plugin-cloud.vue index 1cebc903..022de7e4 100644 --- a/glances/outputs/static/js/components/plugin-cloud.vue +++ b/glances/outputs/static/js/components/plugin-cloud.vue @@ -16,12 +16,12 @@ export default { return this.data.stats['cloud']; }, provider() { - return this.stats['ami-id'] !== undefined ? 'AWS EC2' : null; + return this.stats['id'] !== undefined ? `${stats['platform']}` : null; }, instance() { const { stats } = this; - return this.stats['ami-id'] !== undefined - ? `${stats['instance-type']} instance ${stats['instance-id']} (${stats['reggion']})` + return this.stats['id'] !== undefined + ? `${stats['type']} instance ${stats['name']} (${stats['region']})` : null; } } diff --git a/glances/outputs/static/package-lock.json b/glances/outputs/static/package-lock.json index 060bb12e..981429ad 100644 --- a/glances/outputs/static/package-lock.json +++ b/glances/outputs/static/package-lock.json @@ -4,31 +4,30 @@ "requires": true, "packages": { "": { - "name": "static", "dependencies": { "bootstrap": "^3.4.1", "favico.js": "^0.3.10", - "hotkeys-js": "^3.10.0", + "hotkeys-js": "^3.10.1", "lodash": "^4.17.21", - "sanitize-html": "^2.7.2", - "vue": "^3.2.41" + "sanitize-html": "^2.8.1", + "vue": "^3.2.45" }, "devDependencies": { "copy-webpack-plugin": "^11.0.0", - "css-loader": "^6.7.1", + "css-loader": "^6.7.3", "del": "^7.0.0", - "eslint": "^8.25.0", - "eslint-plugin-vue": "^9.6.0", + "eslint": "^8.32.0", + "eslint-plugin-vue": "^9.9.0", "html-webpack-plugin": "^5.5.0", "less": "^4.1.3", "less-loader": "^11.1.0", - "sass": "^1.55.0", - "sass-loader": "^13.1.0", + "sass": "^1.57.1", + "sass-loader": "^13.2.0", "style-loader": "^3.3.1", "url-loader": "^4.1.1", - "vue-loader": "^17.0.0", - "webpack": "^5.74.0", - "webpack-cli": "^4.10.0", + "vue-loader": "^17.0.1", + "webpack": "^5.75.0", + "webpack-cli": "^5.0.1", "webpack-dev-server": "^4.11.1" } }, @@ -148,9 +147,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.4.tgz", - "integrity": "sha512-qpVT7gtuOLjWeDTKLkJ6sryqLliBaFpAtGeqw5cs5giLldvh+Ch0plqnUMKoVAUS6ZEueQQiZV+p5pxtPitEsA==", + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.13.tgz", + "integrity": "sha512-gFDLKMfpiXCsjt4za2JA9oTMn70CeseCehb11kRZgvd7+F67Hih3OHOK24cRrWECJ/ljfPGac6ygXAs/C8kIvw==", "bin": { "parser": "bin/babel-parser.js" }, @@ -168,15 +167,15 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", + "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.4.0", - "globals": "^13.15.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -234,14 +233,14 @@ "peer": true }, "node_modules/@humanwhocodes/config-array": { - "version": "0.10.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz", - "integrity": "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==", + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", - "minimatch": "^3.0.4" + "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" @@ -618,36 +617,36 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.41.tgz", - "integrity": "sha512-oA4mH6SA78DT+96/nsi4p9DX97PHcNROxs51lYk7gb9Z4BPKQ3Mh+BLn6CQZBw857Iuhu28BfMSRHAlPvD4vlw==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.45.tgz", + "integrity": "sha512-rcMj7H+PYe5wBV3iYeUgbCglC+pbpN8hBLTJvRiK2eKQiWqu+fG9F+8sW99JdL4LQi7Re178UOxn09puSXvn4A==", "dependencies": { "@babel/parser": "^7.16.4", - "@vue/shared": "3.2.41", + "@vue/shared": "3.2.45", "estree-walker": "^2.0.2", "source-map": "^0.6.1" } }, "node_modules/@vue/compiler-dom": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.41.tgz", - "integrity": "sha512-xe5TbbIsonjENxJsYRbDJvthzqxLNk+tb3d/c47zgREDa/PCp6/Y4gC/skM4H6PIuX5DAxm7fFJdbjjUH2QTMw==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.45.tgz", + "integrity": "sha512-tyYeUEuKqqZO137WrZkpwfPCdiiIeXYCcJ8L4gWz9vqaxzIQRccTSwSWZ/Axx5YR2z+LvpUbmPNXxuBU45lyRw==", "dependencies": { - "@vue/compiler-core": "3.2.41", - "@vue/shared": "3.2.41" + "@vue/compiler-core": "3.2.45", + "@vue/shared": "3.2.45" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.41.tgz", - "integrity": "sha512-+1P2m5kxOeaxVmJNXnBskAn3BenbTmbxBxWOtBq3mQTCokIreuMULFantBUclP0+KnzNCMOvcnKinqQZmiOF8w==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.45.tgz", + "integrity": "sha512-1jXDuWah1ggsnSAOGsec8cFjT/K6TMZ0sPL3o3d84Ft2AYZi2jWJgRMjw4iaK0rBfA89L5gw427H4n1RZQBu6Q==", "dependencies": { "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.41", - "@vue/compiler-dom": "3.2.41", - "@vue/compiler-ssr": "3.2.41", - "@vue/reactivity-transform": "3.2.41", - "@vue/shared": "3.2.41", + "@vue/compiler-core": "3.2.45", + "@vue/compiler-dom": "3.2.45", + "@vue/compiler-ssr": "3.2.45", + "@vue/reactivity-transform": "3.2.45", + "@vue/shared": "3.2.45", "estree-walker": "^2.0.2", "magic-string": "^0.25.7", "postcss": "^8.1.10", @@ -655,69 +654,69 @@ } }, "node_modules/@vue/compiler-ssr": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.41.tgz", - "integrity": "sha512-Y5wPiNIiaMz/sps8+DmhaKfDm1xgj6GrH99z4gq2LQenfVQcYXmHIOBcs5qPwl7jaW3SUQWjkAPKMfQemEQZwQ==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.45.tgz", + "integrity": "sha512-6BRaggEGqhWht3lt24CrIbQSRD5O07MTmd+LjAn5fJj568+R9eUD2F7wMQJjX859seSlrYog7sUtrZSd7feqrQ==", "dependencies": { - "@vue/compiler-dom": "3.2.41", - "@vue/shared": "3.2.41" + "@vue/compiler-dom": "3.2.45", + "@vue/shared": "3.2.45" } }, "node_modules/@vue/reactivity": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.41.tgz", - "integrity": "sha512-9JvCnlj8uc5xRiQGZ28MKGjuCoPhhTwcoAdv3o31+cfGgonwdPNuvqAXLhlzu4zwqavFEG5tvaoINQEfxz+l6g==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.45.tgz", + "integrity": "sha512-PRvhCcQcyEVohW0P8iQ7HDcIOXRjZfAsOds3N99X/Dzewy8TVhTCT4uXpAHfoKjVTJRA0O0K+6QNkDIZAxNi3A==", "dependencies": { - "@vue/shared": "3.2.41" + "@vue/shared": "3.2.45" } }, "node_modules/@vue/reactivity-transform": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.41.tgz", - "integrity": "sha512-mK5+BNMsL4hHi+IR3Ft/ho6Za+L3FA5j8WvreJ7XzHrqkPq8jtF/SMo7tuc9gHjLDwKZX1nP1JQOKo9IEAn54A==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.45.tgz", + "integrity": "sha512-BHVmzYAvM7vcU5WmuYqXpwaBHjsS8T63jlKGWVtHxAHIoMIlmaMyurUSEs1Zcg46M4AYT5MtB1U274/2aNzjJQ==", "dependencies": { "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.41", - "@vue/shared": "3.2.41", + "@vue/compiler-core": "3.2.45", + "@vue/shared": "3.2.45", "estree-walker": "^2.0.2", "magic-string": "^0.25.7" } }, "node_modules/@vue/runtime-core": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.41.tgz", - "integrity": "sha512-0LBBRwqnI0p4FgIkO9q2aJBBTKDSjzhnxrxHYengkAF6dMOjeAIZFDADAlcf2h3GDALWnblbeprYYpItiulSVQ==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.45.tgz", + "integrity": "sha512-gzJiTA3f74cgARptqzYswmoQx0fIA+gGYBfokYVhF8YSXjWTUA2SngRzZRku2HbGbjzB6LBYSbKGIaK8IW+s0A==", "dependencies": { - "@vue/reactivity": "3.2.41", - "@vue/shared": "3.2.41" + "@vue/reactivity": "3.2.45", + "@vue/shared": "3.2.45" } }, "node_modules/@vue/runtime-dom": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.41.tgz", - "integrity": "sha512-U7zYuR1NVIP8BL6jmOqmapRAHovEFp7CSw4pR2FacqewXNGqZaRfHoNLQsqQvVQ8yuZNZtxSZy0FFyC70YXPpA==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.45.tgz", + "integrity": "sha512-cy88YpfP5Ue2bDBbj75Cb4bIEZUMM/mAkDMfqDTpUYVgTf/kuQ2VQ8LebuZ8k6EudgH8pYhsGWHlY0lcxlvTwA==", "dependencies": { - "@vue/runtime-core": "3.2.41", - "@vue/shared": "3.2.41", + "@vue/runtime-core": "3.2.45", + "@vue/shared": "3.2.45", "csstype": "^2.6.8" } }, "node_modules/@vue/server-renderer": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.41.tgz", - "integrity": "sha512-7YHLkfJdTlsZTV0ae5sPwl9Gn/EGr2hrlbcS/8naXm2CDpnKUwC68i1wGlrYAfIgYWL7vUZwk2GkYLQH5CvFig==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.45.tgz", + "integrity": "sha512-ebiMq7q24WBU1D6uhPK//2OTR1iRIyxjF5iVq/1a5I1SDMDyDu4Ts6fJaMnjrvD3MqnaiFkKQj+LKAgz5WIK3g==", "dependencies": { - "@vue/compiler-ssr": "3.2.41", - "@vue/shared": "3.2.41" + "@vue/compiler-ssr": "3.2.45", + "@vue/shared": "3.2.45" }, "peerDependencies": { - "vue": "3.2.41" + "vue": "3.2.45" } }, "node_modules/@vue/shared": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.41.tgz", - "integrity": "sha512-W9mfWLHmJhkfAmV+7gDjcHeAWALQtgGT3JErxULl0oz6R6+3ug91I7IErs93eCFhPCZPHBs4QJS7YWEV7A3sxw==" + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.45.tgz", + "integrity": "sha512-Ewzq5Yhimg7pSztDV+RH1UDKBzmtqieXQlpTVm2AwraoRL/Rks96mvd8Vgi7Lj+h+TH8dv7mXD3FRZR3TUvbSg==" }, "node_modules/@webassemblyjs/ast": { "version": "1.11.1", @@ -866,34 +865,42 @@ } }, "node_modules/@webpack-cli/configtest": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz", - "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.0.1.tgz", + "integrity": "sha512-njsdJXJSiS2iNbQVS0eT8A/KPnmyH4pv1APj2K0d1wrZcBLw+yppxOy4CGqa0OxDJkzfL/XELDhD8rocnIwB5A==", "dev": true, + "engines": { + "node": ">=14.15.0" + }, "peerDependencies": { - "webpack": "4.x.x || 5.x.x", - "webpack-cli": "4.x.x" + "webpack": "5.x.x", + "webpack-cli": "5.x.x" } }, "node_modules/@webpack-cli/info": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz", - "integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.1.tgz", + "integrity": "sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA==", "dev": true, - "dependencies": { - "envinfo": "^7.7.3" + "engines": { + "node": ">=14.15.0" }, "peerDependencies": { - "webpack-cli": "4.x.x" + "webpack": "5.x.x", + "webpack-cli": "5.x.x" } }, "node_modules/@webpack-cli/serve": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz", - "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.1.tgz", + "integrity": "sha512-0G7tNyS+yW8TdgHwZKlDWYXFA6OJQnoLCQvYKkQP0Q2X205PSQ6RNUj0M+1OB/9gRQaUZ/ccYfaxd0nhaWKfjw==", "dev": true, + "engines": { + "node": ">=14.15.0" + }, "peerDependencies": { - "webpack-cli": "4.x.x" + "webpack": "5.x.x", + "webpack-cli": "5.x.x" }, "peerDependenciesMeta": { "webpack-dev-server": { @@ -2047,19 +2054,19 @@ } }, "node_modules/css-loader": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.1.tgz", - "integrity": "sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.3.tgz", + "integrity": "sha512-qhOH1KlBMnZP8FzRO6YCH9UHXQhVMcEGLyNdb7Hv2cpcmJbW0YrddO+tG1ab5nT41KpHIYGsbeHqxB9xPu1pKQ==", "dev": true, "dependencies": { "icss-utils": "^5.1.0", - "postcss": "^8.4.7", + "postcss": "^8.4.19", "postcss-modules-extract-imports": "^3.0.0", "postcss-modules-local-by-default": "^4.0.0", "postcss-modules-scope": "^3.0.0", "postcss-modules-values": "^4.0.0", "postcss-value-parser": "^4.2.0", - "semver": "^7.3.5" + "semver": "^7.3.8" }, "engines": { "node": ">= 12.13.0" @@ -2434,6 +2441,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", @@ -2458,6 +2466,7 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, "dependencies": { "domelementtype": "^2.2.0" }, @@ -2472,6 +2481,7 @@ "version": "2.8.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, "dependencies": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", @@ -2583,6 +2593,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } @@ -2675,14 +2686,15 @@ } }, "node_modules/eslint": { - "version": "8.25.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.25.0.tgz", - "integrity": "sha512-DVlJOZ4Pn50zcKW5bYH7GQK/9MsoQG2d5eDH0ebEkE8PbgzTTmtt/VTH9GGJ4BfeZCpBLqFfvsjX35UacUL83A==", + "version": "8.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.32.0.tgz", + "integrity": "sha512-nETVXpnthqKPFyuY2FNjz/bEd6nbosRgKbkgS/y1C7LJop96gYHWpiguLecMHQ2XCPxn77DS0P+68WzG6vkZSQ==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.3.3", - "@humanwhocodes/config-array": "^0.10.5", + "@eslint/eslintrc": "^1.4.1", + "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -2698,14 +2710,14 @@ "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", - "globby": "^11.1.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", @@ -2730,9 +2742,9 @@ } }, "node_modules/eslint-plugin-vue": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.6.0.tgz", - "integrity": "sha512-zzySkJgVbFCylnG2+9MDF7N+2Rjze2y0bF8GyUNpFOnT8mCMfqqtLDJkHBuYu9N/psW1A6DVbQhPkP92E+qakA==", + "version": "9.9.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.9.0.tgz", + "integrity": "sha512-YbubS7eK0J7DCf0U2LxvVP7LMfs6rC6UltihIgval3azO3gyDwEGVgsCMe1TmDiEkl6GdMKfRpaME6QxIYtzDQ==", "dev": true, "dependencies": { "eslint-utils": "^3.0.0", @@ -2878,6 +2890,15 @@ "node": ">=10.13.0" } }, + "node_modules/eslint/node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/eslint/node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -3558,9 +3579,9 @@ "dev": true }, "node_modules/globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -3584,35 +3605,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby/node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/globule": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.4.tgz", @@ -3756,9 +3748,9 @@ } }, "node_modules/hotkeys-js": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/hotkeys-js/-/hotkeys-js-3.10.0.tgz", - "integrity": "sha512-20xeVdOqcgTkMox0+BqFwADZP7+5dy/9CFPpAinSMh2d0s3b0Hs2V2D+lMh4Hphkf7VE9pwnOl58eP1te+REcg==" + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/hotkeys-js/-/hotkeys-js-3.10.1.tgz", + "integrity": "sha512-mshqjgTqx8ee0qryHvRgZaZDxTwxam/2yTQmQlqAWS3+twnq1jsY9Yng9zB7lWq6WRrjTbTOc7knNwccXQiAjQ==" }, "node_modules/hpack.js": { "version": "2.1.6", @@ -3826,6 +3818,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "dev": true, "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", { @@ -3841,9 +3834,9 @@ } }, "node_modules/http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", "dev": true, "optional": true, "peer": true @@ -4186,12 +4179,12 @@ "dev": true }, "node_modules/interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", "dev": true, "engines": { - "node": ">= 0.10" + "node": ">=10.13.0" } }, "node_modules/ip": { @@ -4527,9 +4520,9 @@ "peer": true }, "node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, "bin": { "json5": "lib/cli.js" @@ -5815,9 +5808,9 @@ } }, "node_modules/postcss": { - "version": "8.4.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", - "integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==", + "version": "8.4.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", + "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", "funding": [ { "type": "opencollective", @@ -6223,15 +6216,15 @@ } }, "node_modules/rechoir": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", - "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", "dev": true, "dependencies": { - "resolve": "^1.9.0" + "resolve": "^1.20.0" }, "engines": { - "node": ">= 0.10" + "node": ">= 10.13.0" } }, "node_modules/redent": { @@ -6479,18 +6472,69 @@ "dev": true }, "node_modules/sanitize-html": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.7.2.tgz", - "integrity": "sha512-DggSTe7MviO+K4YTCwprG6W1vsG+IIX67yp/QY55yQqKCJYSWzCA1rZbaXzkjoKeL9+jqwm56wD6srYLtUNivg==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.8.1.tgz", + "integrity": "sha512-qK5neD0SaMxGwVv5txOYv05huC3o6ZAA4h5+7nJJgWMNFUNRjcjLO6FpwAtKzfKCZ0jrG6xTk6eVFskbvOGblg==", "dependencies": { "deepmerge": "^4.2.2", "escape-string-regexp": "^4.0.0", - "htmlparser2": "^6.0.0", + "htmlparser2": "^8.0.0", "is-plain-object": "^5.0.0", "parse-srcset": "^1.0.2", "postcss": "^8.3.11" } }, + "node_modules/sanitize-html/node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/sanitize-html/node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/sanitize-html/node_modules/domutils": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", + "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.1" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/sanitize-html/node_modules/entities": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", + "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/sanitize-html/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -6502,6 +6546,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/sanitize-html/node_modules/htmlparser2": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", + "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "entities": "^4.3.0" + } + }, "node_modules/sanitize-html/node_modules/is-plain-object": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", @@ -6511,9 +6573,9 @@ } }, "node_modules/sass": { - "version": "1.55.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.55.0.tgz", - "integrity": "sha512-Pk+PMy7OGLs9WaxZGJMn7S96dvlyVBwwtToX895WmCpAOr5YiJYEUJfiJidMuKb613z2xNWcXCHEuOvjZbqC6A==", + "version": "1.57.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.57.1.tgz", + "integrity": "sha512-O2+LwLS79op7GI0xZ8fqzF7X2m/m8WFfI02dHOdsK5R2ECeS5F62zrwg/relM1rjSLy7Vd/DiMNIvPrQGsA0jw==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", @@ -6548,9 +6610,9 @@ } }, "node_modules/sass-loader": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.1.0.tgz", - "integrity": "sha512-tZS1RJQ2n2+QNyf3CCAo1H562WjL/5AM6Gi8YcPVVoNxQX8d19mx8E+8fRrMWsyc93ZL6Q8vZDSM0FHVTJaVnQ==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.2.0.tgz", + "integrity": "sha512-JWEp48djQA4nbZxmgC02/Wh0eroSUutulROUusYJO9P9zltRbNN80JCBHqRGzjd4cmZCa/r88xgfkjGD0TXsHg==", "dev": true, "dependencies": { "klona": "^2.0.4", @@ -6565,7 +6627,7 @@ }, "peerDependencies": { "fibers": ">= 3.1.0", - "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0", "sass": "^1.3.0", "sass-embedded": "*", "webpack": "^5.0.0" @@ -6652,9 +6714,9 @@ } }, "node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -6838,15 +6900,6 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", @@ -6967,7 +7020,8 @@ "node_modules/sourcemap-codec": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead" }, "node_modules/spdx-correct": { "version": "3.1.1", @@ -7647,15 +7701,15 @@ "peer": true }, "node_modules/vue": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.41.tgz", - "integrity": "sha512-uuuvnrDXEeZ9VUPljgHkqB5IaVO8SxhPpqF2eWOukVrBnRBx2THPSGQBnVRt0GrIG1gvCmFXMGbd7FqcT1ixNQ==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.45.tgz", + "integrity": "sha512-9Nx/Mg2b2xWlXykmCwiTUCWHbWIj53bnkizBxKai1g61f2Xit700A1ljowpTIM11e3uipOeiPcSqnmBg6gyiaA==", "dependencies": { - "@vue/compiler-dom": "3.2.41", - "@vue/compiler-sfc": "3.2.41", - "@vue/runtime-dom": "3.2.41", - "@vue/server-renderer": "3.2.41", - "@vue/shared": "3.2.41" + "@vue/compiler-dom": "3.2.45", + "@vue/compiler-sfc": "3.2.45", + "@vue/runtime-dom": "3.2.45", + "@vue/server-renderer": "3.2.45", + "@vue/shared": "3.2.45" } }, "node_modules/vue-eslint-parser": { @@ -7728,9 +7782,9 @@ "dev": true }, "node_modules/vue-loader": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-17.0.0.tgz", - "integrity": "sha512-OWSXjrzIvbF2LtOUmxT3HYgwwubbfFelN8PAP9R9dwpIkj48TVioHhWWSx7W7fk+iF5cgg3CBJRxwTdtLU4Ecg==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-17.0.1.tgz", + "integrity": "sha512-/OOyugJnImKCkAKrAvdsWMuwoCqGxWT5USLsjohzWbMgOwpA5wQmzQiLMzZd7DjhIfunzAGIApTOgIylz/kwcg==", "dev": true, "dependencies": { "chalk": "^4.1.0", @@ -7739,6 +7793,14 @@ }, "peerDependencies": { "webpack": "^4.1.0 || ^5.0.0-0" + }, + "peerDependenciesMeta": { + "@vue/compiler-sfc": { + "optional": true + }, + "vue": { + "optional": true + } } }, "node_modules/watchpack": { @@ -7764,9 +7826,9 @@ } }, "node_modules/webpack": { - "version": "5.74.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz", - "integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==", + "version": "5.75.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz", + "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.3", @@ -7811,44 +7873,42 @@ } }, "node_modules/webpack-cli": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz", - "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.0.1.tgz", + "integrity": "sha512-S3KVAyfwUqr0Mo/ur3NzIp6jnerNpo7GUO6so51mxLi1spqsA17YcMXy0WOIJtBSnj748lthxC6XLbNKh/ZC+A==", "dev": true, "dependencies": { "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.2.0", - "@webpack-cli/info": "^1.5.0", - "@webpack-cli/serve": "^1.7.0", + "@webpack-cli/configtest": "^2.0.1", + "@webpack-cli/info": "^2.0.1", + "@webpack-cli/serve": "^2.0.1", "colorette": "^2.0.14", - "commander": "^7.0.0", + "commander": "^9.4.1", "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", "fastest-levenshtein": "^1.0.12", "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", "webpack-merge": "^5.7.3" }, "bin": { "webpack-cli": "bin/cli.js" }, "engines": { - "node": ">=10.13.0" + "node": ">=14.15.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "4.x.x || 5.x.x" + "webpack": "5.x.x" }, "peerDependenciesMeta": { "@webpack-cli/generators": { "optional": true }, - "@webpack-cli/migrate": { - "optional": true - }, "webpack-bundle-analyzer": { "optional": true }, @@ -7858,12 +7918,12 @@ } }, "node_modules/webpack-cli/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", "dev": true, "engines": { - "node": ">= 10" + "node": "^12.20.0 || >=14" } }, "node_modules/webpack-dev-middleware": { @@ -8387,9 +8447,9 @@ } }, "@babel/parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.4.tgz", - "integrity": "sha512-qpVT7gtuOLjWeDTKLkJ6sryqLliBaFpAtGeqw5cs5giLldvh+Ch0plqnUMKoVAUS6ZEueQQiZV+p5pxtPitEsA==" + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.13.tgz", + "integrity": "sha512-gFDLKMfpiXCsjt4za2JA9oTMn70CeseCehb11kRZgvd7+F67Hih3OHOK24cRrWECJ/ljfPGac6ygXAs/C8kIvw==" }, "@discoveryjs/json-ext": { "version": "0.5.5", @@ -8398,15 +8458,15 @@ "dev": true }, "@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", + "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.4.0", - "globals": "^13.15.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -8449,14 +8509,14 @@ "peer": true }, "@humanwhocodes/config-array": { - "version": "0.10.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz", - "integrity": "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==", + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", - "minimatch": "^3.0.4" + "minimatch": "^3.0.5" }, "dependencies": { "debug": { @@ -8793,36 +8853,36 @@ } }, "@vue/compiler-core": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.41.tgz", - "integrity": "sha512-oA4mH6SA78DT+96/nsi4p9DX97PHcNROxs51lYk7gb9Z4BPKQ3Mh+BLn6CQZBw857Iuhu28BfMSRHAlPvD4vlw==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.45.tgz", + "integrity": "sha512-rcMj7H+PYe5wBV3iYeUgbCglC+pbpN8hBLTJvRiK2eKQiWqu+fG9F+8sW99JdL4LQi7Re178UOxn09puSXvn4A==", "requires": { "@babel/parser": "^7.16.4", - "@vue/shared": "3.2.41", + "@vue/shared": "3.2.45", "estree-walker": "^2.0.2", "source-map": "^0.6.1" } }, "@vue/compiler-dom": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.41.tgz", - "integrity": "sha512-xe5TbbIsonjENxJsYRbDJvthzqxLNk+tb3d/c47zgREDa/PCp6/Y4gC/skM4H6PIuX5DAxm7fFJdbjjUH2QTMw==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.45.tgz", + "integrity": "sha512-tyYeUEuKqqZO137WrZkpwfPCdiiIeXYCcJ8L4gWz9vqaxzIQRccTSwSWZ/Axx5YR2z+LvpUbmPNXxuBU45lyRw==", "requires": { - "@vue/compiler-core": "3.2.41", - "@vue/shared": "3.2.41" + "@vue/compiler-core": "3.2.45", + "@vue/shared": "3.2.45" } }, "@vue/compiler-sfc": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.41.tgz", - "integrity": "sha512-+1P2m5kxOeaxVmJNXnBskAn3BenbTmbxBxWOtBq3mQTCokIreuMULFantBUclP0+KnzNCMOvcnKinqQZmiOF8w==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.45.tgz", + "integrity": "sha512-1jXDuWah1ggsnSAOGsec8cFjT/K6TMZ0sPL3o3d84Ft2AYZi2jWJgRMjw4iaK0rBfA89L5gw427H4n1RZQBu6Q==", "requires": { "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.41", - "@vue/compiler-dom": "3.2.41", - "@vue/compiler-ssr": "3.2.41", - "@vue/reactivity-transform": "3.2.41", - "@vue/shared": "3.2.41", + "@vue/compiler-core": "3.2.45", + "@vue/compiler-dom": "3.2.45", + "@vue/compiler-ssr": "3.2.45", + "@vue/reactivity-transform": "3.2.45", + "@vue/shared": "3.2.45", "estree-walker": "^2.0.2", "magic-string": "^0.25.7", "postcss": "^8.1.10", @@ -8830,66 +8890,66 @@ } }, "@vue/compiler-ssr": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.41.tgz", - "integrity": "sha512-Y5wPiNIiaMz/sps8+DmhaKfDm1xgj6GrH99z4gq2LQenfVQcYXmHIOBcs5qPwl7jaW3SUQWjkAPKMfQemEQZwQ==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.45.tgz", + "integrity": "sha512-6BRaggEGqhWht3lt24CrIbQSRD5O07MTmd+LjAn5fJj568+R9eUD2F7wMQJjX859seSlrYog7sUtrZSd7feqrQ==", "requires": { - "@vue/compiler-dom": "3.2.41", - "@vue/shared": "3.2.41" + "@vue/compiler-dom": "3.2.45", + "@vue/shared": "3.2.45" } }, "@vue/reactivity": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.41.tgz", - "integrity": "sha512-9JvCnlj8uc5xRiQGZ28MKGjuCoPhhTwcoAdv3o31+cfGgonwdPNuvqAXLhlzu4zwqavFEG5tvaoINQEfxz+l6g==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.45.tgz", + "integrity": "sha512-PRvhCcQcyEVohW0P8iQ7HDcIOXRjZfAsOds3N99X/Dzewy8TVhTCT4uXpAHfoKjVTJRA0O0K+6QNkDIZAxNi3A==", "requires": { - "@vue/shared": "3.2.41" + "@vue/shared": "3.2.45" } }, "@vue/reactivity-transform": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.41.tgz", - "integrity": "sha512-mK5+BNMsL4hHi+IR3Ft/ho6Za+L3FA5j8WvreJ7XzHrqkPq8jtF/SMo7tuc9gHjLDwKZX1nP1JQOKo9IEAn54A==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.45.tgz", + "integrity": "sha512-BHVmzYAvM7vcU5WmuYqXpwaBHjsS8T63jlKGWVtHxAHIoMIlmaMyurUSEs1Zcg46M4AYT5MtB1U274/2aNzjJQ==", "requires": { "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.41", - "@vue/shared": "3.2.41", + "@vue/compiler-core": "3.2.45", + "@vue/shared": "3.2.45", "estree-walker": "^2.0.2", "magic-string": "^0.25.7" } }, "@vue/runtime-core": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.41.tgz", - "integrity": "sha512-0LBBRwqnI0p4FgIkO9q2aJBBTKDSjzhnxrxHYengkAF6dMOjeAIZFDADAlcf2h3GDALWnblbeprYYpItiulSVQ==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.45.tgz", + "integrity": "sha512-gzJiTA3f74cgARptqzYswmoQx0fIA+gGYBfokYVhF8YSXjWTUA2SngRzZRku2HbGbjzB6LBYSbKGIaK8IW+s0A==", "requires": { - "@vue/reactivity": "3.2.41", - "@vue/shared": "3.2.41" + "@vue/reactivity": "3.2.45", + "@vue/shared": "3.2.45" } }, "@vue/runtime-dom": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.41.tgz", - "integrity": "sha512-U7zYuR1NVIP8BL6jmOqmapRAHovEFp7CSw4pR2FacqewXNGqZaRfHoNLQsqQvVQ8yuZNZtxSZy0FFyC70YXPpA==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.45.tgz", + "integrity": "sha512-cy88YpfP5Ue2bDBbj75Cb4bIEZUMM/mAkDMfqDTpUYVgTf/kuQ2VQ8LebuZ8k6EudgH8pYhsGWHlY0lcxlvTwA==", "requires": { - "@vue/runtime-core": "3.2.41", - "@vue/shared": "3.2.41", + "@vue/runtime-core": "3.2.45", + "@vue/shared": "3.2.45", "csstype": "^2.6.8" } }, "@vue/server-renderer": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.41.tgz", - "integrity": "sha512-7YHLkfJdTlsZTV0ae5sPwl9Gn/EGr2hrlbcS/8naXm2CDpnKUwC68i1wGlrYAfIgYWL7vUZwk2GkYLQH5CvFig==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.45.tgz", + "integrity": "sha512-ebiMq7q24WBU1D6uhPK//2OTR1iRIyxjF5iVq/1a5I1SDMDyDu4Ts6fJaMnjrvD3MqnaiFkKQj+LKAgz5WIK3g==", "requires": { - "@vue/compiler-ssr": "3.2.41", - "@vue/shared": "3.2.41" + "@vue/compiler-ssr": "3.2.45", + "@vue/shared": "3.2.45" } }, "@vue/shared": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.41.tgz", - "integrity": "sha512-W9mfWLHmJhkfAmV+7gDjcHeAWALQtgGT3JErxULl0oz6R6+3ug91I7IErs93eCFhPCZPHBs4QJS7YWEV7A3sxw==" + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.45.tgz", + "integrity": "sha512-Ewzq5Yhimg7pSztDV+RH1UDKBzmtqieXQlpTVm2AwraoRL/Rks96mvd8Vgi7Lj+h+TH8dv7mXD3FRZR3TUvbSg==" }, "@webassemblyjs/ast": { "version": "1.11.1", @@ -9038,25 +9098,23 @@ } }, "@webpack-cli/configtest": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz", - "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.0.1.tgz", + "integrity": "sha512-njsdJXJSiS2iNbQVS0eT8A/KPnmyH4pv1APj2K0d1wrZcBLw+yppxOy4CGqa0OxDJkzfL/XELDhD8rocnIwB5A==", "dev": true, "requires": {} }, "@webpack-cli/info": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz", - "integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.1.tgz", + "integrity": "sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA==", "dev": true, - "requires": { - "envinfo": "^7.7.3" - } + "requires": {} }, "@webpack-cli/serve": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz", - "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.1.tgz", + "integrity": "sha512-0G7tNyS+yW8TdgHwZKlDWYXFA6OJQnoLCQvYKkQP0Q2X205PSQ6RNUj0M+1OB/9gRQaUZ/ccYfaxd0nhaWKfjw==", "dev": true, "requires": {} }, @@ -9943,19 +10001,19 @@ } }, "css-loader": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.1.tgz", - "integrity": "sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.3.tgz", + "integrity": "sha512-qhOH1KlBMnZP8FzRO6YCH9UHXQhVMcEGLyNdb7Hv2cpcmJbW0YrddO+tG1ab5nT41KpHIYGsbeHqxB9xPu1pKQ==", "dev": true, "requires": { "icss-utils": "^5.1.0", - "postcss": "^8.4.7", + "postcss": "^8.4.19", "postcss-modules-extract-imports": "^3.0.0", "postcss-modules-local-by-default": "^4.0.0", "postcss-modules-scope": "^3.0.0", "postcss-modules-values": "^4.0.0", "postcss-value-parser": "^4.2.0", - "semver": "^7.3.5" + "semver": "^7.3.8" } }, "css-select": { @@ -10221,6 +10279,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, "requires": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", @@ -10236,6 +10295,7 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, "requires": { "domelementtype": "^2.2.0" } @@ -10244,6 +10304,7 @@ "version": "2.8.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, "requires": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", @@ -10341,7 +10402,8 @@ "entities": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true }, "env-paths": { "version": "2.2.1", @@ -10413,14 +10475,15 @@ "peer": true }, "eslint": { - "version": "8.25.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.25.0.tgz", - "integrity": "sha512-DVlJOZ4Pn50zcKW5bYH7GQK/9MsoQG2d5eDH0ebEkE8PbgzTTmtt/VTH9GGJ4BfeZCpBLqFfvsjX35UacUL83A==", + "version": "8.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.32.0.tgz", + "integrity": "sha512-nETVXpnthqKPFyuY2FNjz/bEd6nbosRgKbkgS/y1C7LJop96gYHWpiguLecMHQ2XCPxn77DS0P+68WzG6vkZSQ==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.3.3", - "@humanwhocodes/config-array": "^0.10.5", + "@eslint/eslintrc": "^1.4.1", + "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -10436,14 +10499,14 @@ "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", - "globby": "^11.1.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", @@ -10508,6 +10571,12 @@ "is-glob": "^4.0.3" } }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, "locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -10550,9 +10619,9 @@ } }, "eslint-plugin-vue": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.6.0.tgz", - "integrity": "sha512-zzySkJgVbFCylnG2+9MDF7N+2Rjze2y0bF8GyUNpFOnT8mCMfqqtLDJkHBuYu9N/psW1A6DVbQhPkP92E+qakA==", + "version": "9.9.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.9.0.tgz", + "integrity": "sha512-YbubS7eK0J7DCf0U2LxvVP7LMfs6rC6UltihIgval3azO3gyDwEGVgsCMe1TmDiEkl6GdMKfRpaME6QxIYtzDQ==", "dev": true, "requires": { "eslint-utils": "^3.0.0", @@ -11079,9 +11148,9 @@ "dev": true }, "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -11095,28 +11164,6 @@ } } }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "dependencies": { - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - } - } - }, "globule": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.4.tgz", @@ -11229,9 +11276,9 @@ } }, "hotkeys-js": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/hotkeys-js/-/hotkeys-js-3.10.0.tgz", - "integrity": "sha512-20xeVdOqcgTkMox0+BqFwADZP7+5dy/9CFPpAinSMh2d0s3b0Hs2V2D+lMh4Hphkf7VE9pwnOl58eP1te+REcg==" + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/hotkeys-js/-/hotkeys-js-3.10.1.tgz", + "integrity": "sha512-mshqjgTqx8ee0qryHvRgZaZDxTwxam/2yTQmQlqAWS3+twnq1jsY9Yng9zB7lWq6WRrjTbTOc7knNwccXQiAjQ==" }, "hpack.js": { "version": "2.1.6", @@ -11283,6 +11330,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "dev": true, "requires": { "domelementtype": "^2.0.1", "domhandler": "^4.0.0", @@ -11291,9 +11339,9 @@ } }, "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", "dev": true, "optional": true, "peer": true @@ -11554,9 +11602,9 @@ "dev": true }, "interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", "dev": true }, "ip": { @@ -11822,9 +11870,9 @@ "peer": true }, "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true }, "jsprim": { @@ -12813,9 +12861,9 @@ } }, "postcss": { - "version": "8.4.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", - "integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==", + "version": "8.4.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", + "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", "requires": { "nanoid": "^3.3.4", "picocolors": "^1.0.0", @@ -13124,12 +13172,12 @@ } }, "rechoir": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", - "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", "dev": true, "requires": { - "resolve": "^1.9.0" + "resolve": "^1.20.0" } }, "redent": { @@ -13312,23 +13360,67 @@ "dev": true }, "sanitize-html": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.7.2.tgz", - "integrity": "sha512-DggSTe7MviO+K4YTCwprG6W1vsG+IIX67yp/QY55yQqKCJYSWzCA1rZbaXzkjoKeL9+jqwm56wD6srYLtUNivg==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.8.1.tgz", + "integrity": "sha512-qK5neD0SaMxGwVv5txOYv05huC3o6ZAA4h5+7nJJgWMNFUNRjcjLO6FpwAtKzfKCZ0jrG6xTk6eVFskbvOGblg==", "requires": { "deepmerge": "^4.2.2", "escape-string-regexp": "^4.0.0", - "htmlparser2": "^6.0.0", + "htmlparser2": "^8.0.0", "is-plain-object": "^5.0.0", "parse-srcset": "^1.0.2", "postcss": "^8.3.11" }, "dependencies": { + "dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "requires": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + } + }, + "domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "requires": { + "domelementtype": "^2.3.0" + } + }, + "domutils": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", + "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", + "requires": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.1" + } + }, + "entities": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", + "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==" + }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" }, + "htmlparser2": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", + "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", + "requires": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "entities": "^4.3.0" + } + }, "is-plain-object": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", @@ -13337,9 +13429,9 @@ } }, "sass": { - "version": "1.55.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.55.0.tgz", - "integrity": "sha512-Pk+PMy7OGLs9WaxZGJMn7S96dvlyVBwwtToX895WmCpAOr5YiJYEUJfiJidMuKb613z2xNWcXCHEuOvjZbqC6A==", + "version": "1.57.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.57.1.tgz", + "integrity": "sha512-O2+LwLS79op7GI0xZ8fqzF7X2m/m8WFfI02dHOdsK5R2ECeS5F62zrwg/relM1rjSLy7Vd/DiMNIvPrQGsA0jw==", "dev": true, "requires": { "chokidar": ">=3.0.0 <4.0.0", @@ -13362,9 +13454,9 @@ } }, "sass-loader": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.1.0.tgz", - "integrity": "sha512-tZS1RJQ2n2+QNyf3CCAo1H562WjL/5AM6Gi8YcPVVoNxQX8d19mx8E+8fRrMWsyc93ZL6Q8vZDSM0FHVTJaVnQ==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.2.0.tgz", + "integrity": "sha512-JWEp48djQA4nbZxmgC02/Wh0eroSUutulROUusYJO9P9zltRbNN80JCBHqRGzjd4cmZCa/r88xgfkjGD0TXsHg==", "dev": true, "requires": { "klona": "^2.0.4", @@ -13427,9 +13519,9 @@ } }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -13584,12 +13676,6 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, "smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", @@ -14211,15 +14297,15 @@ } }, "vue": { - "version": "3.2.41", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.41.tgz", - "integrity": "sha512-uuuvnrDXEeZ9VUPljgHkqB5IaVO8SxhPpqF2eWOukVrBnRBx2THPSGQBnVRt0GrIG1gvCmFXMGbd7FqcT1ixNQ==", + "version": "3.2.45", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.45.tgz", + "integrity": "sha512-9Nx/Mg2b2xWlXykmCwiTUCWHbWIj53bnkizBxKai1g61f2Xit700A1ljowpTIM11e3uipOeiPcSqnmBg6gyiaA==", "requires": { - "@vue/compiler-dom": "3.2.41", - "@vue/compiler-sfc": "3.2.41", - "@vue/runtime-dom": "3.2.41", - "@vue/server-renderer": "3.2.41", - "@vue/shared": "3.2.41" + "@vue/compiler-dom": "3.2.45", + "@vue/compiler-sfc": "3.2.45", + "@vue/runtime-dom": "3.2.45", + "@vue/server-renderer": "3.2.45", + "@vue/shared": "3.2.45" } }, "vue-eslint-parser": { @@ -14271,9 +14357,9 @@ } }, "vue-loader": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-17.0.0.tgz", - "integrity": "sha512-OWSXjrzIvbF2LtOUmxT3HYgwwubbfFelN8PAP9R9dwpIkj48TVioHhWWSx7W7fk+iF5cgg3CBJRxwTdtLU4Ecg==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-17.0.1.tgz", + "integrity": "sha512-/OOyugJnImKCkAKrAvdsWMuwoCqGxWT5USLsjohzWbMgOwpA5wQmzQiLMzZd7DjhIfunzAGIApTOgIylz/kwcg==", "dev": true, "requires": { "chalk": "^4.1.0", @@ -14301,9 +14387,9 @@ } }, "webpack": { - "version": "5.74.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz", - "integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==", + "version": "5.75.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz", + "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==", "dev": true, "requires": { "@types/eslint-scope": "^3.7.3", @@ -14333,29 +14419,30 @@ } }, "webpack-cli": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz", - "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.0.1.tgz", + "integrity": "sha512-S3KVAyfwUqr0Mo/ur3NzIp6jnerNpo7GUO6so51mxLi1spqsA17YcMXy0WOIJtBSnj748lthxC6XLbNKh/ZC+A==", "dev": true, "requires": { "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.2.0", - "@webpack-cli/info": "^1.5.0", - "@webpack-cli/serve": "^1.7.0", + "@webpack-cli/configtest": "^2.0.1", + "@webpack-cli/info": "^2.0.1", + "@webpack-cli/serve": "^2.0.1", "colorette": "^2.0.14", - "commander": "^7.0.0", + "commander": "^9.4.1", "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", "fastest-levenshtein": "^1.0.12", "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", "webpack-merge": "^5.7.3" }, "dependencies": { "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", "dev": true } } diff --git a/glances/outputs/static/package.json b/glances/outputs/static/package.json index 9273bd6d..2643075d 100644 --- a/glances/outputs/static/package.json +++ b/glances/outputs/static/package.json @@ -3,27 +3,27 @@ "dependencies": { "bootstrap": "^3.4.1", "favico.js": "^0.3.10", - "hotkeys-js": "^3.10.0", + "hotkeys-js": "^3.10.1", "lodash": "^4.17.21", - "sanitize-html": "^2.7.2", - "vue": "^3.2.41" + "sanitize-html": "^2.8.1", + "vue": "^3.2.45" }, "devDependencies": { "copy-webpack-plugin": "^11.0.0", - "css-loader": "^6.7.1", + "css-loader": "^6.7.3", "del": "^7.0.0", - "eslint": "^8.25.0", - "eslint-plugin-vue": "^9.6.0", + "eslint": "^8.32.0", + "eslint-plugin-vue": "^9.9.0", "html-webpack-plugin": "^5.5.0", "less": "^4.1.3", "less-loader": "^11.1.0", - "sass": "^1.55.0", - "sass-loader": "^13.1.0", + "sass": "^1.57.1", + "sass-loader": "^13.2.0", "style-loader": "^3.3.1", "url-loader": "^4.1.1", - "vue-loader": "^17.0.0", - "webpack": "^5.74.0", - "webpack-cli": "^4.10.0", + "vue-loader": "^17.0.1", + "webpack": "^5.75.0", + "webpack-cli": "^5.0.1", "webpack-dev-server": "^4.11.1" }, "scripts": { diff --git a/glances/outputs/static/public/glances.js b/glances/outputs/static/public/glances.js index 0572dbdc..765c9104 100644 Binary files a/glances/outputs/static/public/glances.js and b/glances/outputs/static/public/glances.js differ diff --git a/glances/password.py b/glances/password.py index d05934b4..181cfb4d 100644 --- a/glances/password.py +++ b/glances/password.py @@ -44,17 +44,12 @@ class GlancesPassword(object): def get_hash(self, plain_password, salt=''): """Return the hashed password, salt + pbkdf2_hmac.""" - return hashlib.pbkdf2_hmac('sha256', - plain_password.encode(), - salt.encode(), - 100000, - dklen=128).hex() + return to_hex(hashlib.pbkdf2_hmac('sha256', plain_password.encode(), salt.encode(), 100000, dklen=128)) def hash_password(self, plain_password): """Hash password with a salt based on UUID (universally unique identifier).""" salt = uuid.uuid4().hex - encrypted_password = self.get_hash(plain_password, - salt=salt) + encrypted_password = self.get_hash(plain_password, salt=salt) return salt + '$' + encrypted_password def check_password(self, hashed_password, plain_password): @@ -63,8 +58,7 @@ class GlancesPassword(object): Return the comparison with the encrypted_password. """ salt, encrypted_password = hashed_password.split('$') - re_encrypted_password = self.get_hash(plain_password, - salt = salt) + re_encrypted_password = self.get_hash(plain_password, salt=salt) return encrypted_password == re_encrypted_password def get_password(self, description='', confirm=False, clear=False): diff --git a/glances/plugins/cloud/model.py b/glances/plugins/cloud/model.py index e34960cd..86756249 100644 --- a/glances/plugins/cloud/model.py +++ b/glances/plugins/cloud/model.py @@ -10,7 +10,8 @@ """Cloud plugin. Supported Cloud API: -- OpenStack meta data (class ThreadOpenStack, see below): AWS, OVH... +- OpenStack meta data (class ThreadOpenStack) - Vanilla OpenStack +- OpenStackEC2 meta data (class ThreadOpenStackEC2) - Amazon EC2 compatible """ import threading @@ -53,13 +54,16 @@ class PluginModel(GlancesPluginModel): # Init thread to grab OpenStack stats asynchronously self.OPENSTACK = ThreadOpenStack() + self.OPENSTACKEC2 = ThreadOpenStackEC2() # Run the thread self.OPENSTACK.start() + self.OPENSTACKEC2.start() def exit(self): """Overwrite the exit method to close threads.""" self.OPENSTACK.stop() + self.OPENSTACKEC2.stop() # Call the father class super(PluginModel, self).exit() @@ -80,12 +84,15 @@ class PluginModel(GlancesPluginModel): # Update the stats if self.input_method == 'local': stats = self.OPENSTACK.stats + if not stats: + stats = self.OPENSTACKEC2.stats # Example: - # Uncomment to test on physical computer - # stats = {'ami-id': 'ami-id', - # 'instance-id': 'instance-id', - # 'instance-type': 'instance-type', - # 'region': 'placement/availability-zone'} + # Uncomment to test on physical computer (only for test purpose) + # stats = {'id': 'ami-id', + # 'name': 'My VM', + # 'type': 'Gold', + # 'region': 'France', + # 'platform': 'OpenStack'} # Update the stats self.stats = stats @@ -101,13 +108,14 @@ class PluginModel(GlancesPluginModel): return ret # Generate the output - if 'instance-type' in self.stats and 'instance-id' in self.stats and 'region' in self.stats: - msg = 'Cloud ' - ret.append(self.curse_add_line(msg, "TITLE")) - msg = '{} instance {} ({})'.format( - self.stats['instance-type'], self.stats['instance-id'], self.stats['region'] - ) - ret.append(self.curse_add_line(msg)) + msg = self.stats.get('platform', 'Unknown') + ret.append(self.curse_add_line(msg, "TITLE")) + msg = ' {} instance {} ({})'.format( + self.stats.get('type', 'Unknown'), + self.stats.get('name', 'Unknown'), + self.stats.get('region', 'Unknown') + ) + ret.append(self.curse_add_line(msg)) # Return the message with decoration # logger.info(ret) @@ -121,13 +129,19 @@ class ThreadOpenStack(threading.Thread): stats is a dict """ + # The metadata service provides a way for instances to retrieve + # instance-specific data via a REST API. Instances access this + # service at 169.254.169.254 or at fe80::a9fe:a9fe. + # All types of metadata, be it user-, nova- or vendor-provided, + # can be accessed via this service. # https://docs.openstack.org/nova/latest/user/metadata-service.html - OPENSTACK_API_URL = 'http://169.254.169.254/latest/meta-data' + OPENSTACK_PLATFORM = "OpenStack" + OPENSTACK_API_URL = 'http://169.254.169.254/openstack/latest/meta-data' OPENSTACK_API_METADATA = { - 'ami-id': 'ami-id', - 'instance-id': 'instance-id', - 'instance-type': 'instance-type', - 'region': 'placement/availability-zone', + 'id': 'project_id', + 'name': 'name', + 'type': 'meta/role', + 'region': 'availability_zone', } def __init__(self): @@ -159,6 +173,9 @@ class ThreadOpenStack(threading.Thread): else: if r.ok: self._stats[k] = to_ascii(r.content) + else: + # No break during the loop, so we can set the platform + self._stats['platform'] = self.OPENSTACK_PLATFORM return True @@ -180,3 +197,26 @@ class ThreadOpenStack(threading.Thread): def stopped(self): """Return True is the thread is stopped.""" return self._stopper.is_set() + + +class ThreadOpenStackEC2(ThreadOpenStack): + """ + Specific thread to grab OpenStack EC2 (Amazon cloud) stats. + + stats is a dict + """ + + # The metadata service provides a way for instances to retrieve + # instance-specific data via a REST API. Instances access this + # service at 169.254.169.254 or at fe80::a9fe:a9fe. + # All types of metadata, be it user-, nova- or vendor-provided, + # can be accessed via this service. + # https://docs.openstack.org/nova/latest/user/metadata-service.html + OPENSTACK_PLATFORM = "Amazon EC2" + OPENSTACK_API_URL = 'http://169.254.169.254/latest/meta-data' + OPENSTACK_API_METADATA = { + 'id': 'ami-id', + 'name': 'instance-id', + 'type': 'instance-type', + 'region': 'placement/availability-zone', + } diff --git a/glances/plugins/help/model.py b/glances/plugins/help/model.py index 35801d1c..88691874 100644 --- a/glances/plugins/help/model.py +++ b/glances/plugins/help/model.py @@ -110,7 +110,7 @@ class PluginModel(GlancesPluginModel): ('misc_erase_process_filter', msg_col.format('E', 'Erase process filter')), ('misc_generate_history_graphs', msg_col.format('g', 'Generate history graphs')), ('misc_help', msg_col.format('h', 'HELP')), - ('misc_accumulate_processes_by_program', msg_col.format('j', 'Accumulate processes by program')), + ('misc_accumulate_processes_by_program', msg_col.format('j', 'Display threads or programs')), ('misc_increase_nice_process', msg_col.format('+', 'Increase nice process')), ('misc_decrease_nice_process', msg_col.format('-', 'Decrease nice process (need admin rights)')), ('misc_kill_process', msg_col.format('k', 'Kill process')), diff --git a/glances/plugins/network/model.py b/glances/plugins/network/model.py index c732f735..334a4d23 100644 --- a/glances/plugins/network/model.py +++ b/glances/plugins/network/model.py @@ -32,11 +32,16 @@ fields_description = { 'alias': {'description': 'Interface alias name (optional).', 'unit': 'string'}, 'rx': {'description': 'The received/input rate (in bit per second).', 'unit': 'bps'}, 'tx': {'description': 'The sent/output rate (in bit per second).', 'unit': 'bps'}, + 'cx': {'description': 'The cumulative received+sent rate (in bit per second).', 'unit': 'bps'}, 'cumulative_rx': { 'description': 'The number of bytes received through the interface (cumulative).', 'unit': 'bytes', }, 'cumulative_tx': {'description': 'The number of bytes sent through the interface (cumulative).', 'unit': 'bytes'}, + 'cumulative_cx': { + 'description': 'The cumulative number of bytes reveived and sent through the interface (cumulative).', + 'unit': 'bytes', + }, 'speed': { 'description': 'Maximum interface speed (in bit per second). Can return 0 on some operating-system.', 'unit': 'bps', diff --git a/glances/plugins/processlist/model.py b/glances/plugins/processlist/model.py index 55a943ab..f1170f38 100644 --- a/glances/plugins/processlist/model.py +++ b/glances/plugins/processlist/model.py @@ -145,9 +145,10 @@ class PluginModel(GlancesPluginModel): # Update stats using the standard system lib # Note: Update is done in the processcount plugin # Just return the processes list - stats = glances_processes.getlist() if self.args.programs: - stats = processes_to_programs(stats) + stats = glances_processes.getlist(as_programs=True) + else: + stats = glances_processes.getlist() elif self.input_method == 'snmp': # No SNMP grab for processes @@ -349,14 +350,14 @@ class PluginModel(GlancesPluginModel): """Get curses data to display for a process. - p is the process to display - - selected is a tag=True if the selected process + - selected is a tag=True if p is the selected process """ ret = [self.curse_new_line()] + # When a process is selected: # * display a special character at the beginning of the line # * underline the command name - if args.is_standalone: - ret.append(self.curse_add_line(unicode_message('PROCESS_SELECTOR') if selected else ' ', 'SELECTED')) + ret.append(self.curse_add_line(unicode_message('PROCESS_SELECTOR') if (selected and not args.disable_cursor) else ' ', 'SELECTED')) # CPU ret.append(self._get_process_curses_cpu(p, selected, args)) @@ -403,7 +404,7 @@ class PluginModel(GlancesPluginModel): cmdline = p.get('cmdline', '?') try: - process_decoration = 'PROCESS_SELECTED' if (selected and args.is_standalone) else 'PROCESS' + process_decoration = 'PROCESS_SELECTED' if (selected and not args.disable_cursor) else 'PROCESS' if cmdline: path, cmd, arguments = split_cmdline(bare_process_name, cmdline) # Manage end of line in arguments (see #1692) @@ -427,74 +428,14 @@ class PluginModel(GlancesPluginModel): logger.debug("Can not decode command line '{}' ({})".format(cmdline, e)) ret.append(self.curse_add_line('', splittable=True)) - # Add extended stats but only for the top processes - if args.cursor_position == 0 and 'extended_stats' in p and args.enable_process_extended: - # Left padding - xpad = ' ' * 13 - # First line is CPU affinity - if 'cpu_affinity' in p and p['cpu_affinity'] is not None: - ret.append(self.curse_new_line()) - msg = xpad + 'CPU affinity: ' + str(len(p['cpu_affinity'])) + ' cores' - ret.append(self.curse_add_line(msg, splittable=True)) - # Second line is memory info - if 'memory_info' in p and p['memory_info'] is not None: - ret.append(self.curse_new_line()) - msg = '{}Memory info: {}'.format(xpad, p['memory_info']) - if 'memory_swap' in p and p['memory_swap'] is not None: - msg += ' swap ' + self.auto_unit(p['memory_swap'], low_precision=False) - ret.append(self.curse_add_line(msg, splittable=True)) - # Third line is for open files/network sessions - msg = '' - if 'num_threads' in p and p['num_threads'] is not None: - msg += str(p['num_threads']) + ' threads ' - if 'num_fds' in p and p['num_fds'] is not None: - msg += str(p['num_fds']) + ' files ' - if 'num_handles' in p and p['num_handles'] is not None: - msg += str(p['num_handles']) + ' handles ' - if 'tcp' in p and p['tcp'] is not None: - msg += str(p['tcp']) + ' TCP ' - if 'udp' in p and p['udp'] is not None: - msg += str(p['udp']) + ' UDP' - if msg != '': - ret.append(self.curse_new_line()) - msg = xpad + 'Open: ' + msg - ret.append(self.curse_add_line(msg, splittable=True)) - # Fourth line is IO nice level (only Linux and Windows OS) - if 'ionice' in p and p['ionice'] is not None and hasattr(p['ionice'], 'ioclass'): - ret.append(self.curse_new_line()) - msg = xpad + 'IO nice: ' - k = 'Class is ' - v = p['ionice'].ioclass - # Linux: The scheduling class. 0 for none, 1 for real time, 2 for best-effort, 3 for idle. - # Windows: On Windows only ioclass is used and it can be set to 2 (normal), 1 (low) or 0 (very low). - if WINDOWS: - if v == 0: - msg += k + 'Very Low' - elif v == 1: - msg += k + 'Low' - elif v == 2: - msg += 'No specific I/O priority' - else: - msg += k + str(v) - else: - if v == 0: - msg += 'No specific I/O priority' - elif v == 1: - msg += k + 'Real Time' - elif v == 2: - msg += k + 'Best Effort' - elif v == 3: - msg += k + 'IDLE' - else: - msg += k + str(v) - # value is a number which goes from 0 to 7. - # The higher the value, the lower the I/O priority of the process. - if hasattr(p['ionice'], 'value') and p['ionice'].value != 0: - msg += ' (value %s/7)' % str(p['ionice'].value) - ret.append(self.curse_add_line(msg, splittable=True)) - return ret + def is_selected_process(self, args): + return args.is_standalone and \ + self.args.enable_process_extended and \ + args.cursor_position is not None and \ + glances_processes.extended_process is not None + def msg_curse(self, args=None, max_width=None): """Return the dict to display in the curse interface.""" # Init the return message @@ -506,6 +447,16 @@ class PluginModel(GlancesPluginModel): # Compute the sort key process_sort_key = glances_processes.sort_key + processes_list_sorted = self.__sort_stats(process_sort_key) + + # Display extended stats for selected process + ############################################# + + if self.is_selected_process(args): + self.__msg_curse_extended_process(ret, glances_processes.extended_process) + + # Display others processes list + ############################### # Header self.__msg_curse_header(ret, process_sort_key, args) @@ -514,10 +465,10 @@ class PluginModel(GlancesPluginModel): # Loop over processes (sorted by the sort key previously compute) # This is a Glances bottleneck (see flame graph), # get_process_curses_data should be optimzed - i = 0 - for p in self.__sort_stats(process_sort_key): - ret.extend(self.get_process_curses_data(p, i == args.cursor_position, args)) - i += 1 + for position, process in enumerate(processes_list_sorted): + ret.extend(self.get_process_curses_data(process, + position == args.cursor_position, + args)) # A filter is set Display the stats summaries if glances_processes.process_filter is not None: @@ -531,6 +482,116 @@ class PluginModel(GlancesPluginModel): # Return the message with decoration return ret + def __msg_curse_extended_process(self, ret, p): + """Get extended curses data for the selected process (see issue #2225) + + The result depends of the process type (process or thread). + + Input p is a dict with the following keys: + {'status': 'S', + 'memory_info': pmem(rss=466890752, vms=3365347328, shared=68153344, text=659456, lib=0, data=774647808, dirty=0), + 'pid': 4980, + 'io_counters': [165385216, 0, 165385216, 0, 1], + 'num_threads': 20, + 'nice': 0, + 'memory_percent': 5.958135664449709, + 'cpu_percent': 0.0, + 'gids': pgids(real=1000, effective=1000, saved=1000), + 'cpu_times': pcputimes(user=696.38, system=119.98, children_user=0.0, children_system=0.0, iowait=0.0), + 'name': 'WebExtensions', + 'key': 'pid', + 'time_since_update': 2.1997854709625244, + 'cmdline': ['/snap/firefox/2154/usr/lib/firefox/firefox', '-contentproc', '-childID', '...'], + 'username': 'nicolargo', + 'cpu_min': 0.0, + 'cpu_max': 7.0, + 'cpu_mean': 3.2} + """ + if self.args.programs: + self.__msg_curse_extended_process_program(ret, p) + else: + self.__msg_curse_extended_process_thread(ret, p) + + def __msg_curse_extended_process_program(self, ret, p): + # Title + msg = "Pinned program {} ('e' to unpin)".format(p['name']) + ret.append(self.curse_add_line(msg, "TITLE")) + + ret.append(self.curse_new_line()) + ret.append(self.curse_new_line()) + + def __msg_curse_extended_process_thread(self, ret, p): + # Title + ret.append(self.curse_add_line("Pinned thread ", "TITLE")) + ret.append(self.curse_add_line(p['name'], "UNDERLINE")) + ret.append(self.curse_add_line(" ('e' to unpin)")) + + # First line is CPU affinity + ret.append(self.curse_new_line()) + ret.append(self.curse_add_line(' CPU Min/Max/Mean: ')) + msg = '{: >7.1f}{: >7.1f}{: >7.1f}%'.format(p['cpu_min'], p['cpu_max'], p['cpu_mean']) + ret.append(self.curse_add_line(msg, decoration='INFO')) + if 'cpu_affinity' in p and p['cpu_affinity'] is not None: + ret.append(self.curse_add_line(' Affinity: ')) + ret.append(self.curse_add_line(str(len(p['cpu_affinity'])), decoration='INFO')) + ret.append(self.curse_add_line(' cores', decoration='INFO')) + if 'ionice' in p and p['ionice'] is not None and hasattr(p['ionice'], 'ioclass'): + msg = ' IO nice: ' + k = 'Class is ' + v = p['ionice'].ioclass + # Linux: The scheduling class. 0 for none, 1 for real time, 2 for best-effort, 3 for idle. + # Windows: On Windows only ioclass is used and it can be set to 2 (normal), 1 (low) or 0 (very low). + if WINDOWS: + if v == 0: + msg += k + 'Very Low' + elif v == 1: + msg += k + 'Low' + elif v == 2: + msg += 'No specific I/O priority' + else: + msg += k + str(v) + else: + if v == 0: + msg += 'No specific I/O priority' + elif v == 1: + msg += k + 'Real Time' + elif v == 2: + msg += k + 'Best Effort' + elif v == 3: + msg += k + 'IDLE' + else: + msg += k + str(v) + # value is a number which goes from 0 to 7. + # The higher the value, the lower the I/O priority of the process. + if hasattr(p['ionice'], 'value') and p['ionice'].value != 0: + msg += ' (value %s/7)' % str(p['ionice'].value) + ret.append(self.curse_add_line(msg, splittable=True)) + + # Second line is memory info + ret.append(self.curse_new_line()) + ret.append(self.curse_add_line(' MEM Min/Max/Mean: ')) + msg = '{: >7.1f}{: >7.1f}{: >7.1f}%'.format(p['memory_min'], p['memory_max'], p['memory_mean']) + ret.append(self.curse_add_line(msg, decoration='INFO')) + if 'memory_info' in p and p['memory_info'] is not None: + ret.append(self.curse_add_line(' Memory info: ')) + for k in p['memory_info']._asdict(): + ret.append(self.curse_add_line(self.auto_unit(p['memory_info']._asdict()[k], low_precision=False), decoration='INFO', splittable=True)) + ret.append(self.curse_add_line(' ' + k + ' ', splittable=True)) + if 'memory_swap' in p and p['memory_swap'] is not None: + ret.append(self.curse_add_line(self.auto_unit(p['memory_swap'], low_precision=False), decoration='INFO', splittable=True)) + ret.append(self.curse_add_line(' swap ', splittable=True)) + + # Third line is for open files/network sessions + ret.append(self.curse_new_line()) + ret.append(self.curse_add_line(' Open: ')) + for stat_prefix in ['num_threads', 'num_fds', 'num_handles', 'tcp', 'udp']: + if stat_prefix in p and p[stat_prefix] is not None: + ret.append(self.curse_add_line(str(p[stat_prefix]), decoration='INFO')) + ret.append(self.curse_add_line(' {} '.format(stat_prefix.replace('num_', '')))) + + ret.append(self.curse_new_line()) + ret.append(self.curse_new_line()) + def __msg_curse_header(self, ret, process_sort_key, args=None): """Build the header and add it to the ret dict.""" sort_style = 'SORT' @@ -577,10 +638,15 @@ class PluginModel(GlancesPluginModel): msg, sort_style if process_sort_key == 'io_counters' else 'DEFAULT', optional=True, additional=True ) ) - if not self.args.programs: - msg = self.layout_header['command'].format('Command', "('k' to kill)" if args.is_standalone else "") + if args.is_standalone and not args.disable_cursor: + if self.args.programs: + shortkey = "('k' to kill)" + else: + shortkey = "('e' to pin | 'k' to kill)" else: - msg = self.layout_header['command'].format('Programs', "('k' to kill)" if args.is_standalone else "") + shortkey = "" + msg = self.layout_header['command'].format("Programs" if self.args.programs else "Command", + shortkey) ret.append(self.curse_add_line(msg, sort_style if process_sort_key == 'name' else 'DEFAULT')) def __msg_curse_sum(self, ret, sep_char='_', mmm=None, args=None): diff --git a/glances/plugins/sensors/model.py b/glances/plugins/sensors/model.py index 38c6cbdb..6a9f5cba 100644 --- a/glances/plugins/sensors/model.py +++ b/glances/plugins/sensors/model.py @@ -175,7 +175,7 @@ class PluginModel(GlancesPluginModel): # Alert processing if i['type'] == SENSOR_TEMP_TYPE: if self.is_limit('critical', stat_name='sensors_temperature_' + i['label']): - # By default use the thresholds confiured in the glances.conf file (see #2058) + # By default use the thresholds configured in the glances.conf file (see #2058) alert = self.get_alert(current=i['value'], header='temperature_' + i['label']) else: # Else use the system thresholds @@ -197,7 +197,7 @@ class PluginModel(GlancesPluginModel): self.views[i[self.get_key()]]['value']['decoration'] = alert def battery_trend(self, stats): - """Return the trend characterr for the battery""" + """Return the trend character for the battery""" if 'status' not in stats: return '' if stats['status'].startswith('Charg'): @@ -331,12 +331,15 @@ class GlancesGrabSensors(object): else: return ret for chip_name, chip in iteritems(input_list): - i = 1 - for feature in chip: + label_index = 1 + for chip_name_index, feature in enumerate(chip): sensors_current = {} # Sensor name if feature.label == '': - sensors_current['label'] = chip_name + ' ' + str(i) + sensors_current['label'] = chip_name + ' ' + str(chip_name_index) + elif feature.label in [i['label'] for i in ret]: + sensors_current['label'] = feature.label + ' ' + str(label_index) + label_index += 1 else: sensors_current['label'] = feature.label # Sensors value, limit and unit @@ -348,7 +351,6 @@ class GlancesGrabSensors(object): sensors_current['critical'] = int(system_critical) if system_critical is not None else None # Add sensor to the list ret.append(sensors_current) - i += 1 return ret def get(self, sensor_type=SENSOR_TEMP_TYPE): diff --git a/glances/processes.py b/glances/processes.py index 4c3b1355..ddf54b88 100644 --- a/glances/processes.py +++ b/glances/processes.py @@ -12,6 +12,7 @@ import os from glances.globals import BSD, LINUX, MACOS, WINDOWS, iterkeys from glances.timer import Timer, getTimeSinceLastUpdate from glances.filter import GlancesFilter +from glances.programs import processes_to_programs from glances.logger import logger import psutil @@ -36,6 +37,10 @@ class GlancesProcesses(object): def __init__(self, cache_timeout=60): """Init the class to collect stats about processes.""" + # Init the args, coming from the GlancesStandalone class + # Should be set by the set_args method + self.args = None + # Add internals caches because psutil do not cache all the stats # See: https://github.com/giampaolo/psutil/issues/462 self.username_cache = {} @@ -69,6 +74,7 @@ class GlancesProcesses(object): # Extended stats for top process is enable by default self.disable_extended_tag = False + self.extended_process = None # Test if the system can grab io_counters try: @@ -108,6 +114,10 @@ class GlancesProcesses(object): self._max_values = {} self.reset_max_values() + def set_args(self, args): + """Set args.""" + self.args = args + def reset_processcount(self): """Reset the global process count""" self.processcount = {'total': 0, 'running': 0, 'sleeping': 0, 'thread': 0, 'pid_max': None} @@ -246,6 +256,91 @@ class GlancesProcesses(object): for k in self._max_values_list: self._max_values[k] = 0.0 + def get_extended_stats(self, proc): + """Get the extended stats for the given PID.""" + # - cpu_affinity (Linux, Windows, FreeBSD) + # - ionice (Linux and Windows > Vista) + # - num_ctx_switches (not available on Illumos/Solaris) + # - num_fds (Unix-like) + # - num_handles (Windows) + # - memory_maps (only swap, Linux) + # https://www.cyberciti.biz/faq/linux-which-process-is-using-swap/ + # - connections (TCP and UDP) + # - CPU min/max/mean + + # Set the extended stats list (OS dependant) + extended_stats = ['cpu_affinity', 'ionice', 'num_ctx_switches'] + if LINUX: + # num_fds only available on Unix system (see issue #1351) + extended_stats += ['num_fds'] + if WINDOWS: + extended_stats += ['num_handles'] + + ret = {} + try: + # Get the extended stats + selected_process = psutil.Process(proc['pid']) + ret = selected_process.as_dict(attrs=extended_stats, ad_value=None) + + if LINUX: + try: + ret['memory_swap'] = sum([v.swap for v in selected_process.memory_maps()]) + except (psutil.NoSuchProcess, KeyError): + # (KeyError catch for issue #1551) + pass + except (psutil.AccessDenied, NotImplementedError): + # NotImplementedError: /proc/${PID}/smaps file doesn't exist + # on kernel < 2.6.14 or CONFIG_MMU kernel configuration option + # is not enabled (see psutil #533/glances #413). + ret['memory_swap'] = None + try: + ret['tcp'] = len(selected_process.connections(kind="tcp")) + ret['udp'] = len(selected_process.connections(kind="udp")) + except (psutil.AccessDenied, psutil.NoSuchProcess): + # Manage issue1283 (psutil.AccessDenied) + ret['tcp'] = None + ret['udp'] = None + except (psutil.NoSuchProcess, ValueError, AttributeError) as e: + logger.error('Can not grab extended stats ({})'.format(e)) + self.extended_process = None + ret['extended_stats'] = False + else: + logger.debug('Grab extended stats for process {}'.format(proc['pid'])) + + # Compute CPU and MEM min/max/mean + for stat_prefix in ['cpu', 'memory']: + if stat_prefix + '_min' not in self.extended_process: + ret[stat_prefix + '_min'] = proc[stat_prefix + '_percent'] + else: + ret[stat_prefix + '_min'] = proc[stat_prefix + '_percent'] if proc[stat_prefix + '_min'] > proc[stat_prefix + '_percent'] else proc[stat_prefix + '_min'] + if stat_prefix + '_max' not in self.extended_process: + ret[stat_prefix + '_max'] = proc[stat_prefix + '_percent'] + else: + ret[stat_prefix + '_max'] = proc[stat_prefix + '_percent'] if proc[stat_prefix + '_max'] < proc[stat_prefix + '_percent'] else proc[stat_prefix + '_max'] + if stat_prefix + '_mean_sum' not in self.extended_process: + ret[stat_prefix + '_mean_sum'] = proc[stat_prefix + '_percent'] + else: + ret[stat_prefix + '_mean_sum'] = proc[stat_prefix + '_mean_sum'] + proc[stat_prefix + '_percent'] + if stat_prefix + '_mean_counter' not in self.extended_process: + ret[stat_prefix + '_mean_counter'] = 1 + else: + ret[stat_prefix + '_mean_counter'] = proc[stat_prefix + '_mean_counter'] + 1 + ret[stat_prefix + '_mean'] = ret[stat_prefix + '_mean_sum'] / ret[stat_prefix + '_mean_counter'] + + ret['extended_stats'] = True + return ret + + def is_selected_extended_process(self, position): + """Return True if the process is the selected one for extended stats.""" + return hasattr(self.args, 'programs') and \ + not self.args.programs and \ + hasattr(self.args, 'enable_process_extended') and \ + self.args.enable_process_extended and \ + not self.disable_extended_tag and \ + hasattr(self.args, 'cursor_position') and \ + position == self.args.cursor_position and \ + not self.args.disable_cursor + def update(self): """Update the processes stats.""" # Reset the stats @@ -285,78 +380,44 @@ class GlancesProcesses(object): is_cached = True # Build the processes stats list (it is why we need psutil>=5.3.0) - # This is on of the main bottleneck of Glances (see flame graph) - self.processlist = [ - p.info - for p in psutil.process_iter(attrs=sorted_attrs, ad_value=None) - # OS-related processes filter - if not (BSD and p.info['name'] == 'idle') - and not (WINDOWS and p.info['name'] == 'System Idle Process') - and not (MACOS and p.info['name'] == 'kernel_task') - and - # Kernel threads filter - not (self.no_kernel_threads and LINUX and p.info['gids'].real == 0) - ] - + # This is one of the main bottleneck of Glances (see flame graph) + # Filter processes + self.processlist = list( + filter( + lambda p: not (BSD and p.info['name'] == 'idle') + and not (WINDOWS and p.info['name'] == 'System Idle Process') + and not (MACOS and p.info['name'] == 'kernel_task') + and not (self.no_kernel_threads and LINUX and p.info['gids'].real == 0), + psutil.process_iter(attrs=sorted_attrs, ad_value=None), + ) + ) + # Only get the info key + self.processlist = [p.info for p in self.processlist] # Sort the processes list by the current sort_key self.processlist = sort_stats(self.processlist, sorted_by=self.sort_key, reverse=True) # Update the processcount self.update_processcount(self.processlist) - # Loop over processes and add metadata - first = True - for proc in self.processlist: - # Get extended stats, only for top processes (see issue #403). - if first and not self.disable_extended_tag: - # - cpu_affinity (Linux, Windows, FreeBSD) - # - ionice (Linux and Windows > Vista) - # - num_ctx_switches (not available on Illumos/Solaris) - # - num_fds (Unix-like) - # - num_handles (Windows) - # - memory_maps (only swap, Linux) - # https://www.cyberciti.biz/faq/linux-which-process-is-using-swap/ - # - connections (TCP and UDP) - extended = {} - try: - top_process = psutil.Process(proc['pid']) - extended_stats = ['cpu_affinity', 'ionice', 'num_ctx_switches'] - if LINUX: - # num_fds only available on Unix system (see issue #1351) - extended_stats += ['num_fds'] - if WINDOWS: - extended_stats += ['num_handles'] + # Loop over processes and : + # - add extended stats for selected process + # - add metadata + for position, proc in enumerate(self.processlist): + # Extended stats + ################ - # Get the extended stats - extended = top_process.as_dict(attrs=extended_stats, ad_value=None) + # Get the selected process when the 'e' key is pressed + if self.is_selected_extended_process(position): + self.extended_process = proc - if LINUX: - try: - extended['memory_swap'] = sum([v.swap for v in top_process.memory_maps()]) - except (psutil.NoSuchProcess, KeyError): - # (KeyError catch for issue #1551) - pass - except (psutil.AccessDenied, NotImplementedError): - # NotImplementedError: /proc/${PID}/smaps file doesn't exist - # on kernel < 2.6.14 or CONFIG_MMU kernel configuration option - # is not enabled (see psutil #533/glances #413). - extended['memory_swap'] = None - try: - extended['tcp'] = len(top_process.connections(kind="tcp")) - extended['udp'] = len(top_process.connections(kind="udp")) - except (psutil.AccessDenied, psutil.NoSuchProcess): - # Manage issue1283 (psutil.AccessDenied) - extended['tcp'] = None - extended['udp'] = None - except (psutil.NoSuchProcess, ValueError, AttributeError) as e: - logger.error('Can not grab extended stats ({})'.format(e)) - extended['extended_stats'] = False - else: - logger.debug('Grab extended stats for process {}'.format(proc['pid'])) - extended['extended_stats'] = True - proc.update(extended) - first = False - # /End of extended stats + # Grab extended stats only for the selected process (see issue #2225) + if self.extended_process is not None and \ + proc['pid'] == self.extended_process['pid']: + proc.update(self.get_extended_stats(self.extended_process)) + self.extended_process = proc + + # Meta data + ########### # PID is the key proc['key'] = 'pid' @@ -409,8 +470,8 @@ class GlancesProcesses(object): # Save values to cache self.processlist_cache[proc['pid']] = {cached: proc[cached] for cached in cached_attrs} - # Apply filter - self.processlist = [p for p in self.processlist if not (self._filter.is_filtered(p))] + # Apply user filter + self.processlist = list(filter(lambda p: not self._filter.is_filtered(p), self.processlist)) # Compute the maximum value for keys in self._max_values_list: CPU, MEM # Useful to highlight the processes with maximum values @@ -423,9 +484,14 @@ class GlancesProcesses(object): """Get the number of processes.""" return self.processcount - def getlist(self, sorted_by=None): - """Get the processlist.""" - return self.processlist + def getlist(self, sorted_by=None, as_programs=False): + """Get the processlist. + By default, return the list of threads. + If as_programs is True, return the list of programs.""" + if as_programs: + return processes_to_programs(self.processlist) + else: + return self.processlist @property def sort_key(self): diff --git a/glances/programs.py b/glances/programs.py index 95837d74..35442aa8 100644 --- a/glances/programs.py +++ b/glances/programs.py @@ -36,7 +36,7 @@ def processes_to_programs(processes): 'name': p['name'], 'cmdline': [p['name']], 'pid': '_', - 'username': p['username'], + 'username': p['username'] if 'username' in p else '_', 'nice': p['nice'], 'status': p['status'], } diff --git a/glances/secure.py b/glances/secure.py index 60328508..6a97037f 100644 --- a/glances/secure.py +++ b/glances/secure.py @@ -11,6 +11,7 @@ from glances.globals import nativestr from subprocess import Popen, PIPE +import re def secure_popen(cmd): @@ -48,8 +49,9 @@ def __secure_popen(cmd): p_last = None # Split by pipe '|' for sub_cmd in cmd.split('|'): - # Split by space ' ' - sub_cmd_split = [i for i in sub_cmd.split(' ') if i] + # Split by space character, but do no split spaces within quotes (remove surrounding quotes, though) + tmp_split = [_ for _ in list(filter(None, re.split(r'(\s+)|(".*?"+?)|(\'.*?\'+?)', sub_cmd))) if _ != ' '] + sub_cmd_split = [_[1:-1] if (_[0] == _[-1] == '"') or (_[0] == _[-1] == '\'') else _ for _ in tmp_split] p = Popen(sub_cmd_split, shell=False, stdin=sub_cmd_stdin, stdout=PIPE, stderr=PIPE) if p_last is not None: # Allow p_last to receive a SIGPIPE if p exits. diff --git a/glances/server.py b/glances/server.py index 051c7973..44e8b1ea 100644 --- a/glances/server.py +++ b/glances/server.py @@ -94,7 +94,6 @@ class GlancesXMLRPCServer(SimpleXMLRPCServer, object): finished = False def __init__(self, bind_address, bind_port=61209, requestHandler=GlancesXMLRPCHandler, config=None): - self.bind_address = bind_address self.bind_port = bind_port self.config = config diff --git a/glances/snmp.py b/glances/snmp.py index af717411..368efd19 100644 --- a/glances/snmp.py +++ b/glances/snmp.py @@ -24,7 +24,6 @@ class GlancesSNMPClient(object): """SNMP client class (based on pysnmp library).""" def __init__(self, host='localhost', port=161, version='2c', community='public', user='private', auth=''): - super(GlancesSNMPClient, self).__init__() self.cmdGen = cmdgen.CommandGenerator() diff --git a/glances/standalone.py b/glances/standalone.py index c1268580..8ab60e8c 100644 --- a/glances/standalone.py +++ b/glances/standalone.py @@ -14,7 +14,6 @@ import time from glances.globals import WINDOWS from glances.logger import logger -from glances.outputs.glances_stdout_json import GlancesStdoutJson from glances.processes import glances_processes from glances.stats import GlancesStats from glances.outputs.glances_curses import GlancesCursesStandalone @@ -51,6 +50,9 @@ class GlancesStandalone(object): self.display_modules_list() sys.exit(0) + # The args is needed to get the selected process in the process list (Curses mode) + glances_processes.set_args(args) + # If process extended stats is disabled by user if not args.enable_process_extended: logger.debug("Extended stats for top process are disabled") @@ -193,3 +195,8 @@ class GlancesStandalone(object): ) ) print("You should consider upgrading using: pip install --upgrade glances") + print("Disable this warning temporarily using: glances --disable-check-update") + print( + "To disable it permanently, refer config reference at " + "https://glances.readthedocs.io/en/latest/config.html#syntax" + ) diff --git a/glances/stats.py b/glances/stats.py index 6939cdb9..6b67974a 100644 --- a/glances/stats.py +++ b/glances/stats.py @@ -123,7 +123,7 @@ class GlancesStats(object): if args is not None: # If the all key is set in the disable_plugin option then look in the enable_plugin option if getattr(args, 'disable_all', False): - logger.info('%s => %s', name, getattr(args, 'enable_' + name, False)) + logger.debug('%s => %s', name, getattr(args, 'enable_' + name, False)) setattr(args, 'disable_' + name, not getattr(args, 'enable_' + name, False)) else: setattr(args, 'disable_' + name, getattr(args, 'disable_' + name, False)) diff --git a/optional-requirements.txt b/optional-requirements.txt index 78c51eda..ac233bff 100644 --- a/optional-requirements.txt +++ b/optional-requirements.txt @@ -22,6 +22,7 @@ potsdb prometheus_client pygal pymdstat +pymongo; python_version >= "3.7" pysnmp pySMART.smartx python-dateutil @@ -32,5 +33,5 @@ six sparklines statsd wifi -zeroconf==0.19.1; python_version < "3.7" +zeroconf==0.47.3; python_version < "3.7" zeroconf; python_version >= "3.7" diff --git a/requirements.txt b/requirements.txt index 89d1e3df..889ff764 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,4 @@ defusedxml packaging ujson<4; python_version >= "3.5" and python_version < "3.6" ujson<5; python_version >= "3.6" and python_version < "3.7" -ujson; python_version >= "3.7" +ujson>=5.4.0; python_version >= "3.7" diff --git a/setup.py b/setup.py index fec0ccd7..a8191091 100755 --- a/setup.py +++ b/setup.py @@ -37,7 +37,16 @@ def get_data_files(): def get_install_requires(): - requires = ['psutil>=5.3.0', 'defusedxml', 'future', 'packaging'] + requires = [ + 'psutil>=5.6.7', + 'defusedxml', + 'packaging', + 'future; python_version < "3.0"', + 'ujson<3; python_version < "3.0"', + 'ujson<4; python_version >= "3.5" and python_version < "3.6"', + 'ujson<5; python_version >= "3.6" and python_version < "3.7"', + 'ujson>=5.4.0; python_version >= "3.7"', + ] if sys.platform.startswith('win'): requires.append('bottle') requires.append('requests') @@ -127,13 +136,11 @@ setup( 'License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)', 'Operating System :: OS Independent', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', 'Topic :: System :: Monitoring' ] ) diff --git a/unitest-restful.py b/unitest-restful.py index ea8da34a..f9455385 100755 --- a/unitest-restful.py +++ b/unitest-restful.py @@ -222,6 +222,16 @@ class TestGlances(unittest.TestCase): self.assertIsInstance(req.json(), dict) self.assertIsInstance(req.json()['interface_name'], list) + def test_012_status(self): + """Check status endpoint.""" + method = "status" + print('INFO: [TEST_012] Status') + print("HTTP RESTful request: %s/%s" % (URL, method)) + req = self.http_get("%s/%s" % (URL, method)) + + self.assertTrue(req.ok) + self.assertEqual(req.text, "Active") + def test_999_stop_server(self): """Stop the Glances Web Server.""" print('INFO: [TEST_999] Stop the Glances Web Server')