Merge branch 'develop' into issue1985

This commit is contained in:
nicolargo 2023-01-13 15:45:40 +01:00
commit 9f6295a632
58 changed files with 1098 additions and 941 deletions

17
.flake8
View File

@ -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

View File

@ -25,7 +25,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install pip install build tools
run: >-
@ -96,35 +96,35 @@ jobs:
strategy:
fail-fast: false
matrix:
os: ['debian', 'alpine']
os: ['alpine']
tag: ${{ fromJson(needs.create_Docker_builds.outputs.tags) }}
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Retrieve Repository Docker metadata
id: docker_meta
uses: crazy-max/ghaction-docker-meta@v2.5.0
uses: crazy-max/ghaction-docker-meta@v4.2.0
with:
images: ${{ env.DEFAULT_DOCKER_IMAGE }}
labels: |
org.opencontainers.image.url=https://nicolargo.github.io/glances/
- name: Cache Docker layers
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ env.NODE_ENV }}-${{ matrix.os }}-${{ matrix.tag.tag }}
restore-keys: ${{ runner.os }}-buildx-${{ env.NODE_ENV }}-${{ matrix.os }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
uses: docker/setup-qemu-action@v2
with:
platforms: all
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v2
with:
version: latest
@ -136,10 +136,10 @@ jobs:
password: ${{ secrets.DOCKER_TOKEN }}
- name: Build and push image
uses: docker/build-push-action@v2
uses: docker/build-push-action@v3
with:
push: ${{ env.PUSH_BRANCH == 'true' }}
tags: "${{ env.DEFAULT_DOCKER_IMAGE }}:${{ matrix.os != 'debian' && format('{0}-', matrix.os) || '' }}${{ matrix.tag.tag }}"
tags: "${{ env.DEFAULT_DOCKER_IMAGE }}:${{ matrix.os != 'alpine' && format('{0}-', matrix.os) || '' }}${{ matrix.tag.tag }}"
build-args: |
CHANGING_ARG=${{ github.sha }}
context: .

View File

@ -39,7 +39,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL

View File

@ -10,14 +10,14 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["2.7", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10"]
python-version: ["2.7", "3.7", "3.8", "3.9", "3.10", "3.11"]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

View File

@ -74,6 +74,18 @@ trace-malloc: ## Trace the malloc() calls
memory-leak: ## Profile memory leaks
./venv/bin/python -m glances -C ./conf/glances.conf --memory-leak
memory-profiling: ## Profile memory usage
@echo "It's a very long test (~4 hours)..."
rm -f mprofile_*.dat
@echo "1/2 - Start memory profiling with the history option enable"
./venv/bin/mprof run -T 1 -C run.py -C ./conf/glances.conf --stop-after 2400 --quiet
./venv/bin/mprof plot --output ./docs/_static/glances-memory-profiling-with-history.png
rm -f mprofile_*.dat
@echo "2/2 - Start memory profiling with the history option disable"
./venv/bin/mprof run -T 1 -C run.py -C ./conf/glances.conf --disable-history --stop-after 2400 --quiet
./venv/bin/mprof plot --output ./docs/_static/glances-memory-profiling-without-history.png
rm -f mprofile_*.dat
# ===================================================================
# Docs
# ===================================================================
@ -118,11 +130,18 @@ flatpak: venv-dev-upgrade ## Generate FlatPack JSON file
# Docker
# ===================================================================
docker:
docker: docker-alpine ## Generate local docker images
docker-alpine: ## Generate local docker images (Alpine)
docker build --target full -f ./docker-files/alpine.Dockerfile -t glances:local-alpine-full .
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
# ===================================================================

View File

@ -8,6 +8,32 @@ Version 3.3.1
Under development, see milestone https://github.com/nicolargo/glances/milestone/61
===============
Version 3.3.0.4
===============
Refactor the Docker images factory, from now, only Alpine image wll be provided.
The following Docker images (nicolargo/glances) are availables:
- *latest-full* for a full Alpine Glances image (latest release) with all dependencies
- *latest* for a basic Alpine Glances (latest release) version with minimal dependencies (Bottle and Docker)
- *dev* for a basic Alpine Glances image (based on development branch) with all dependencies (Warning: may be instable)
===============
Version 3.3.0.2
===============
Bug corrected:
* Password files in same configuration dir in effect #2143
* Fail to load config file on Python 3.10 #2176
===============
Version 3.3.0.1
===============
Just a version to rebuild the Docker images.
===============
Version 3.3.0
===============

View File

@ -57,12 +57,25 @@ Glances is written in Python and uses libraries to grab information from
your system. It is based on an open architecture where developers can
add new plugins or exports modules.
Project sponsorship
===================
You can help me to achieve my goals of improving this open-source project
or just say "thank you" by:
- sponsor me using one-time or monthly tier Github sponsors_ page
- send me some pieces of bitcoin: 185KN9FCix3svJYp7JQM7hRMfSKyeaJR4X
- buy me a gift on my wishlist_ page
Any and all contributions are greatly appreciated.
Requirements
============
- ``python>=2.7`` or ``python>=3.4``
- ``psutil>=5.3.0`` (better with latest version)
- ``defusedxml`` (in order to monkey patch xmlrpc)
- ``ujson`` (an optimized alternative to the standard json module)
- ``future`` (for Python 2 support)
*Note for Python 2.6 users*
@ -181,25 +194,20 @@ If you want to support other distributions, please contribute to `glancesautoins
Docker: the fun way
-------------------
Glances containers are availables. You can use it to monitor your
server and all your other containers!
Glances Docker images are availables. You can use it to monitor your
server and all your containers !
Get the Glances container:
.. code-block:: console
docker pull nicolargo/glances:alpine-latest-full
docker pull nicolargo/glances:latest-full
The following tags are availables:
- *alpine-latest-full* for a full Alpine Glances image (latest release) with all dependencies
- *latest-full* for a full Debian Glances image (latest release) with all dependencies
- *alpine-latest* for a basic Alpine Glances (latest release) version with minimal dependencies
- *latest* for a basic Debian Glances image (latest release) with minimal dependencies
- *alpine-dev* for a basic Alpine Glances image (development branch) with all dependencies
- *dev* for a basic Debian Glances image (development branch) with all dependencies
You can also specify a version (example: *alpine-3.2.7-full*).
- *latest-full* for a full Alpine Glances image (latest release) with all dependencies
- *latest* for a basic Alpine Glances (latest release) version with minimal dependencies (Bottle and Docker)
- *dev* for a basic Alpine Glances image (based on development branch) with all dependencies (Warning: may be instable)
Run last version of Glances container in *console mode*:
@ -442,15 +450,6 @@ There is also a chat dedicated to the Glances developers:
.. image:: https://badges.gitter.im/Join%20Chat.svg
:target: https://gitter.im/nicolargo/glances?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
Donation
========
If you like this open-source project, you can become a sponsor.
See the Github sponsors_ page (one-time or monthly tier available).
Or send me some bitcoins: 185KN9FCix3svJYp7JQM7hRMfSKyeaJR4X
Author
======
@ -471,7 +470,8 @@ 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
.. _issue2021comment: https://github.com/nicolargo/glances/issues/2021#issuecomment-1197831157

34
SECURITY.md Normal file
View File

@ -0,0 +1,34 @@
# Security Policy
## Supported Versions
Use this section to tell people about which versions of your project are
currently being supported with security updates.
| Version | Support security updates |
| ------- | ------------------------ |
| 3.x | :white_check_mark: |
| < 3.0 | :x: |
## Reporting a Vulnerability
If there are any vulnerabilities in {{cookiecutter.project_name}}, don't hesitate to report them.
1. Describe the vulnerability.
* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
* Full paths of source file(s) related to the manifestation of the issue
* The location of the affected source code (tag/branch/commit or direct URL)
* Any special configuration required to reproduce the issue
* Step-by-step instructions to reproduce the issue
* Proof-of-concept or exploit code (if possible)
* Impact of the issue, including how an attacker might exploit the issue
2. If you have a fix, that is most welcome -- please attach or summarize it in your message!
3. We will evaluate the vulnerability and, if necessary, release a fix or mitigating steps to address it. We will contact you to let you know the outcome, and will credit you in the report.
4. Please do not disclose the vulnerability publicly until a fix is released!
Once we have either a) published a fix, or b) declined to address the vulnerability for whatever reason, you are free to publicly disclose it.

View File

@ -10,8 +10,10 @@ refresh=2
# Does Glances should check if a newer version is available on PyPI ?
check_update=true
# 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

View File

@ -6,3 +6,6 @@ flake8
autopep8
autoflake
codespell
memory-profiler
matplotlib
setuptools>=65.5.1 # not directly required, pinned by Snyk to avoid a vulnerability

View File

@ -1,3 +1,4 @@
sphinx
sphinx_rtd_theme
reuse
reuse
setuptools>=65.5.1 # not directly required, pinned by Snyk to avoid a vulnerability

View File

@ -1,3 +1,3 @@
FROM nicolargo/glances:alpine-dev
FROM nicolargo/glances:latest as glancesminimal
COPY glances.conf /glances/conf/glances.conf
CMD python -m glances -C /glances/conf/glances.conf $GLANCES_OPT

View File

@ -15,7 +15,7 @@ services:
- "traefik.frontend.rule=Host:whoami.docker.localhost"
monitoring:
image: nicolargo/glances:alpine-dev
image: nicolargo/glances:dev
restart: unless-stopped
pid: host
privileged: true

View File

@ -8,7 +8,7 @@
# Ex: Python 3.10 for Alpine 3.16
# Note: ENV is for future running containers. ARG for building your Docker image.
ARG IMAGE_VERSION=3.16
ARG IMAGE_VERSION=3.17
ARG PYTHON_VERSION=3.10
FROM alpine:${IMAGE_VERSION} as build
ARG PYTHON_VERSION
@ -33,12 +33,15 @@ RUN apk add --no-cache \
FROM build as buildRequirements
ARG PYTHON_VERSION
COPY requirements.txt .
COPY webui-requirements.txt .
RUN pip3 install --no-cache-dir --user -r requirements.txt
# Minimal means no webui, but it break what is done previously (see #2155)
# So install the webui requirements...
COPY webui-requirements.txt .
RUN pip3 install --no-cache-dir --user -r webui-requirements.txt
# As minimal image we want to monitor others docker containers
RUN pip3 install --no-cache-dir --user docker
@ -70,9 +73,8 @@ COPY ./docker-compose/glances.conf /etc/glances.conf
# EXPOSE PORT (XMLRPC / WebUI)
EXPOSE 61209 61208
WORKDIR /glances
# Define default command.
WORKDIR /glances
CMD python3 -m glances -C /etc/glances.conf $GLANCES_OPT
##############################################################################
@ -85,6 +87,8 @@ ARG PYTHON_VERSION
RUN apk add --no-cache \
python3 \
py3-packaging \
py3-dateutil \
curl \
lm-sensors \
wireless-tools \
@ -94,10 +98,11 @@ 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/
COPY ./docker-compose/glances.conf /etc/glances.conf
# EXPOSE PORT (XMLRPC only because WebUI is not available)
EXPOSE 61209
# EXPOSE PORT (XMLRPC / WebUI)
EXPOSE 61209 61208
# Define default command.
WORKDIR /glances
CMD python3 -m glances -C /etc/glances.conf $GLANCES_OPT
##############################################################################
@ -122,7 +127,6 @@ EXPOSE 61209 61208
RUN ln -sf /dev/stdout /tmp/glances-root.log \
&& ln -sf /dev/stderr /var/log/error.log
WORKDIR /glances
# Define default command.
WORKDIR /glances
CMD python3 -m glances -C /etc/glances.conf $GLANCES_OPT

View File

@ -1,56 +1,67 @@
#
# Glances Dockerfile (based on Debian)
# Glances Dockerfile (based on Ubuntu)
#
# https://github.com/nicolargo/glances
#
# WARNING: the version should be set.
# Ex: Python 3.10 for 3.10-slim-buster
# 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=3.10-slim-buster
ARG IMAGE_VERSION=11.8.0-base-ubuntu22.04
ARG PYTHON_VERSION=3.10
FROM python:${IMAGE_VERSION} as build
ARG PYTHON_VERSION
ARG PIP_MIRROR=https://mirrors.aliyun.com/pypi/simple/
FROM nvidia/cuda:${IMAGE_VERSION} as build
# Install package
RUN apt-get update && \
apt-get install -y --no-install-recommends \
python3-dev \
curl \
build-essential \
lm-sensors \
wireless-tools \
smartmontools \
iputils-ping && \
apt-get clean && rm -rf /var/lib/apt/lists/*
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 \
net-tools \
&& 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 .
COPY webui-requirements.txt .
RUN pip3 install --no-cache-dir --user -r 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...
RUN pip3 install --no-cache-dir --user -r webui-requirements.txt
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 pip3 install --no-cache-dir --user docker
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 pip3 install --no-cache-dir --user glances
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
RUN CASS_DRIVER_NO_CYTHON=1 pip3 install --no-cache-dir --user -r optional-requirements.txt -i ${PIP_MIRROR}
##############################################################################
# full image
@ -59,17 +70,16 @@ RUN CASS_DRIVER_NO_CYTHON=1 pip3 install --no-cache-dir --user -r optional-requi
FROM build as full
ARG PYTHON_VERSION
COPY --from=buildRequirements /root/.local/bin /usr/local/bin/
COPY --from=buildRequirements /root/.local/lib/python${PYTHON_VERSION}/site-packages /usr/local/lib/python${PYTHON_VERSION}/site-packages/
COPY --from=buildOptionalRequirements /root/.local/lib/python${PYTHON_VERSION}/site-packages /usr/local/lib/python${PYTHON_VERSION}/site-packages/
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
WORKDIR /glances
# Define default command.
WORKDIR /glances
CMD python3 -m glances -C /etc/glances.conf $GLANCES_OPT
##############################################################################
@ -77,26 +87,33 @@ CMD python3 -m glances -C /etc/glances.conf $GLANCES_OPT
##############################################################################
# Create running images without any building dependency
FROM python:${IMAGE_VERSION} as minimal
FROM nvidia/cuda:${IMAGE_VERSION} as minimal
ARG PYTHON_VERSION
RUN apt-get update && \
apt-get install -y --no-install-recommends \
curl \
lm-sensors \
wireless-tools \
smartmontools \
iputils-ping && \
apt-get clean && rm -rf /var/lib/apt/lists/*
ARG DEBIAN_FRONTEND=noninteractive
ENV TZ=Asia/Shanghai
COPY --from=buildRequirements /root/.local/bin /usr/local/bin/
COPY --from=buildRequirements /root/.local/lib/python${PYTHON_VERSION}/site-packages /usr/local/lib/python${PYTHON_VERSION}/site-packages/
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
python3 \
python3-packaging \
python3-dateutil \
curl \
lm-sensors \
wireless-tools \
net-tools \
&& 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)
EXPOSE 61209
# EXPOSE PORT (XMLRPC / WebUI)
EXPOSE 61209 61208
# Define default command.
WORKDIR /glances
CMD python3 -m glances -C /etc/glances.conf $GLANCES_OPT
##############################################################################
@ -106,9 +123,9 @@ CMD python3 -m glances -C /etc/glances.conf $GLANCES_OPT
FROM full as dev
ARG PYTHON_VERSION
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/
COPY --from=buildOptionalRequirements /root/.local/lib/python${PYTHON_VERSION}/site-packages /usr/lib/python${PYTHON_VERSION}/site-packages/
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
@ -121,7 +138,6 @@ EXPOSE 61209 61208
RUN ln -sf /dev/stdout /tmp/glances-root.log \
&& ln -sf /dev/stderr /var/log/error.log
WORKDIR /glances
# Define default command.
WORKDIR /glances
CMD python3 -m glances -C /etc/glances.conf $GLANCES_OPT

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 139 KiB

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -24,8 +24,10 @@ from datetime import datetime
# Insert Glances' path into the system.
sys.path.insert(0, os.path.abspath('..'))
# WARNING: Do not move this import before the sys.path.insert() call.
from glances import __version__
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.

View File

@ -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" "Oct 17, 2022" "3.3.0.1" "Glances"
.TH "GLANCES" "1" "Dec 21, 2022" "3.3.1_beta1" "Glances"
.SH NAME
glances \- An eye on your system
.SH SYNOPSIS

View File

@ -186,6 +186,9 @@ class GlancesAutoDiscoverClient(object):
# Issue #528 (no network interface available)
pass
# Ensure zeroconf_bind_address is an IP address not an host
zeroconf_bind_address = socket.gethostbyname(zeroconf_bind_address)
# Check IP v4/v6
address_family = socket.getaddrinfo(zeroconf_bind_address, args.port)[0][0]

View File

@ -9,7 +9,7 @@
"""Manage the Glances client."""
import json
import ujson
import socket
import sys
import time
@ -119,7 +119,7 @@ class GlancesClient(object):
if __version__.split('.')[0] == client_version.split('.')[0]:
# Init stats
self.stats = GlancesStatsClient(config=self.config, args=self.args)
self.stats.set_plugins(json.loads(self.client.getAllPlugins()))
self.stats.set_plugins(ujson.loads(self.client.getAllPlugins()))
logger.debug("Client version: {} / Server version: {}".format(__version__, client_version))
else:
self.log_and_exit(
@ -198,7 +198,7 @@ class GlancesClient(object):
"""
# Update the stats
try:
server_stats = json.loads(self.client.getAll())
server_stats = ujson.loads(self.client.getAll())
except socket.error:
# Client cannot get server stats
return "Disconnected"

View File

@ -9,7 +9,7 @@
"""Manage the Glances client browser (list of Glances server)."""
import json
import ujson
import socket
import threading
@ -98,12 +98,12 @@ class GlancesClientBrowser(object):
# Mandatory stats
try:
# CPU%
cpu_percent = 100 - json.loads(s.getCpu())['idle']
cpu_percent = 100 - ujson.loads(s.getCpu())['idle']
server['cpu_percent'] = '{:.1f}'.format(cpu_percent)
# MEM%
server['mem_percent'] = json.loads(s.getMem())['percent']
server['mem_percent'] = ujson.loads(s.getMem())['percent']
# OS (Human Readable name)
server['hr_name'] = json.loads(s.getSystem())['hr_name']
server['hr_name'] = ujson.loads(s.getSystem())['hr_name']
except (socket.error, Fault, KeyError) as e:
logger.debug("Error while grabbing stats form {}: {}".format(uri, e))
server['status'] = 'OFFLINE'
@ -123,7 +123,7 @@ class GlancesClientBrowser(object):
# Optional stats (load is not available on Windows OS)
try:
# LOAD
load_min5 = json.loads(s.getLoad())['min5']
load_min5 = ujson.loads(s.getLoad())['min5']
server['load_min5'] = '{:.2f}'.format(load_min5)
except Exception as e:
logger.warning("Error while grabbing stats form {}: {}".format(uri, e))

View File

@ -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):

View File

@ -13,7 +13,7 @@ I am your father...
...for all Glances exports IF.
"""
import json
from glances.globals import json_dumps
from glances.compat import NoOptionError, NoSectionError, iteritems, iterkeys
from glances.logger import logger
@ -185,7 +185,7 @@ class GlancesExport(object):
# Walk through the dict
for key, value in iteritems(stats):
if isinstance(value, bool):
value = json.dumps(value)
value = json_dumps(value)
if isinstance(value, list):
try:
value = value[0]

View File

@ -1,8 +1,8 @@
"""JSON interface class."""
import sys
import json
from glances.globals import json_dumps
from glances.compat import PY3, listkeys
from glances.logger import logger
from glances.exports.glances_export import GlancesExport
@ -55,10 +55,10 @@ class Export(GlancesExport):
# Export stats to JSON file
if PY3:
with open(self.json_filename, "w") as self.json_file:
self.json_file.write("{}\n".format(json.dumps(self.buffer)))
self.json_file.write("{}\n".format(json_dumps(self.buffer)))
else:
with open(self.json_filename, "wb") as self.json_file:
self.json_file.write("{}\n".format(json.dumps(self.buffer)))
self.json_file.write("{}\n".format(json_dumps(self.buffer)))
# Reset buffer
self.buffer = {}

View File

@ -13,9 +13,9 @@ import sys
from glances.logger import logger
from glances.exports.glances_export import GlancesExport
from glances.globals import json_dumps
from kafka import KafkaProducer
import json
class Export(GlancesExport):
@ -54,7 +54,7 @@ class Export(GlancesExport):
try:
s = KafkaProducer(
bootstrap_servers=server_uri,
value_serializer=lambda v: json.dumps(v).encode('utf-8'),
value_serializer=lambda v: json_dumps(v).encode('utf-8'),
compression_type=self.compression,
)
except Exception as e:

View File

@ -11,11 +11,11 @@
import socket
import string
import json
import sys
from glances.logger import logger
from glances.exports.glances_export import GlancesExport
from glances.globals import json_dumps
# Import paho for MQTT
from requests import certs
@ -116,7 +116,7 @@ class Export(GlancesExport):
# Add the value
current_level[split_key[len(split_key) - 1]] = sensor_values[key]
json_value = json.dumps(output_value)
json_value = json_dumps(output_value)
self.client.publish(topic, json_value)
except Exception as e:
logger.error("Can not export stats to MQTT server (%s)" % e)

View File

@ -10,11 +10,11 @@
"""ZeroMQ interface class."""
import sys
import json
from glances.compat import b
from glances.logger import logger
from glances.exports.glances_export import GlancesExport
from glances.globals import json_dumps
import zmq
from zmq.utils.strtypes import asbytes
@ -84,7 +84,7 @@ class Export(GlancesExport):
# - First frame containing the following prefix (STRING)
# - Second frame with the Glances plugin name (STRING)
# - Third frame with the Glances plugin stats (JSON)
message = [b(self.prefix), b(name), asbytes(json.dumps(data))]
message = [b(self.prefix), b(name), asbytes(json_dumps(data))]
# Write data to the ZeroMQ bus
# Result can be view: tcp://host:port

View File

@ -13,7 +13,7 @@ import errno
import os
import sys
import platform
import json
import ujson
from operator import itemgetter
# OS constants (some libraries/features are OS-dependent)
@ -53,9 +53,9 @@ def json_dumps(data):
Manage the issue #815 for Windows OS with UnicodeDecodeError catching.
"""
try:
return json.dumps(data)
return ujson.dumps(data)
except UnicodeDecodeError:
return json.dumps(data, ensure_ascii=False)
return ujson.dumps(data, ensure_ascii=False)
def json_dumps_dictlist(data, item):

View File

@ -773,5 +773,5 @@ Examples of use:
"""
from glances.password import GlancesPassword
password = GlancesPassword(username=username)
password = GlancesPassword(username=username, config=self.get_config())
return password.get_password(description, confirm, clear)

View File

@ -9,7 +9,6 @@
"""Web interface class."""
import json
import os
import sys
import tempfile
@ -18,6 +17,7 @@ import webbrowser
import zlib
import socket
from glances.globals import json_dumps
from glances.compat import b
from glances.timer import Timer
from glances.logger import logger
@ -127,7 +127,7 @@ class GlancesBottle(object):
if username == self.args.username:
from glances.password import GlancesPassword
pwd = GlancesPassword()
pwd = GlancesPassword(username=username, config=self.config)
return pwd.check_password(self.args.password, pwd.sha256_hash(password))
else:
return False
@ -240,7 +240,7 @@ class GlancesBottle(object):
# Update the stat
view_data = self.stats.get_plugin("help").get_view_data()
try:
plist = json.dumps(view_data, sort_keys=True)
plist = json_dumps(view_data)
except Exception as e:
abort(404, "Cannot get help view data (%s)" % str(e))
return plist
@ -278,7 +278,7 @@ class GlancesBottle(object):
self.__update__()
try:
plist = json.dumps(self.plugins_list)
plist = json_dumps(self.plugins_list)
except Exception as e:
abort(404, "Cannot get plugin list (%s)" % str(e))
return plist
@ -307,7 +307,7 @@ class GlancesBottle(object):
try:
# Get the JSON value of the stat ID
statval = json.dumps(self.stats.getAllAsDict())
statval = json_dumps(self.stats.getAllAsDict())
except Exception as e:
abort(404, "Cannot get stats (%s)" % str(e))
@ -326,7 +326,7 @@ class GlancesBottle(object):
try:
# Get the JSON value of the stat limits
limits = json.dumps(self.stats.getAllLimitsAsDict())
limits = json_dumps(self.stats.getAllLimitsAsDict())
except Exception as e:
abort(404, "Cannot get limits (%s)" % (str(e)))
return limits
@ -344,7 +344,7 @@ class GlancesBottle(object):
try:
# Get the JSON value of the stat view
limits = json.dumps(self.stats.getAllViewsAsDict())
limits = json_dumps(self.stats.getAllViewsAsDict())
except Exception as e:
abort(404, "Cannot get views (%s)" % (str(e)))
return limits
@ -528,7 +528,7 @@ class GlancesBottle(object):
try:
# Get the JSON value of the config' dict
args_json = json.dumps(self.config.as_dict())
args_json = json_dumps(self.config.as_dict())
except Exception as e:
abort(404, "Cannot get config (%s)" % str(e))
return args_json
@ -550,7 +550,7 @@ class GlancesBottle(object):
try:
# Get the JSON value of the config' dict
args_json = json.dumps(config_dict[item])
args_json = json_dumps(config_dict[item])
except Exception as e:
abort(404, "Cannot get config item (%s)" % str(e))
return args_json
@ -569,7 +569,7 @@ class GlancesBottle(object):
# Get the JSON value of the args' dict
# Use vars to convert namespace to dict
# Source: https://docs.python.org/%s/library/functions.html#vars
args_json = json.dumps(vars(self.args))
args_json = json_dumps(vars(self.args))
except Exception as e:
abort(404, "Cannot get args (%s)" % str(e))
return args_json
@ -592,7 +592,7 @@ class GlancesBottle(object):
# Get the JSON value of the args' dict
# Use vars to convert namespace to dict
# Source: https://docs.python.org/%s/library/functions.html#vars
args_json = json.dumps(vars(self.args)[item])
args_json = json_dumps(vars(self.args)[item])
except Exception as e:
abort(404, "Cannot get args item (%s)" % str(e))
return args_json

View File

@ -680,7 +680,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'
@ -1110,7 +1109,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.

View File

@ -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)

View File

@ -5,12 +5,15 @@
<span>{{ running }} run,</span>
<span>{{ sleeping }} slp,</span>
<span>{{ stopped }} oth</span>
<span>{{ args.programs ? 'Programs' : 'Threads' }}</span>
<span class="title">{{ sorter.auto ? 'sorted automatically' : 'sorted' }}</span>
<span>by {{ sorter.getColumnLabel(sorter.column) }}</span>
</section>
</template>
<script>
import { store } from '../store.js';
export default {
props: {
data: {
@ -20,7 +23,15 @@ export default {
type: Object
}
},
data() {
return {
store
};
},
computed: {
args() {
return this.store.args || {};
},
stats() {
return this.data.stats['processcount'];
},

View File

@ -199,7 +199,7 @@ export default {
((isWindows && process.nice != 32) || (!isWindows && process.nice != 0));
if (Array.isArray(process.cmdline)) {
process.cmdline = process.cmdline.join(' ');
process.cmdline = process.cmdline.join(' ').replace(/\n/g, ' ');
}
if (process.cmdline === null) {

View File

@ -1332,6 +1332,15 @@
"tweetnacl": "^0.14.3"
}
},
"node_modules/big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
"dev": true,
"engines": {
"node": "*"
}
},
"node_modules/binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
@ -2514,6 +2523,15 @@
"optional": true,
"peer": true
},
"node_modules/emojis-list": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
"dev": true,
"engines": {
"node": ">= 4"
}
},
"node_modules/encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
@ -4508,6 +4526,18 @@
"optional": true,
"peer": true
},
"node_modules/json5": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
"dev": true,
"bin": {
"json5": "lib/cli.js"
},
"engines": {
"node": ">=6"
}
},
"node_modules/jsprim": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
@ -4653,6 +4683,20 @@
"node": ">=6.11.5"
}
},
"node_modules/loader-utils": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
"dev": true,
"dependencies": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
},
"engines": {
"node": ">=8.9.0"
}
},
"node_modules/locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
@ -4911,12 +4955,6 @@
"node": "*"
}
},
"node_modules/minimist": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
"dev": true
},
"node_modules/minimist-options": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz",
@ -7530,53 +7568,6 @@
}
}
},
"node_modules/url-loader/node_modules/big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
"dev": true,
"engines": {
"node": "*"
}
},
"node_modules/url-loader/node_modules/emojis-list": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
"dev": true,
"engines": {
"node": ">= 4"
}
},
"node_modules/url-loader/node_modules/json5": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
"integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
"dev": true,
"dependencies": {
"minimist": "^1.2.5"
},
"bin": {
"json5": "lib/cli.js"
},
"engines": {
"node": ">=6"
}
},
"node_modules/url-loader/node_modules/loader-utils": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
"dev": true,
"dependencies": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
},
"engines": {
"node": ">=8.9.0"
}
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@ -7750,50 +7741,6 @@
"webpack": "^4.1.0 || ^5.0.0-0"
}
},
"node_modules/vue-loader/node_modules/big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
"dev": true,
"engines": {
"node": "*"
}
},
"node_modules/vue-loader/node_modules/emojis-list": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
"dev": true,
"engines": {
"node": ">= 4"
}
},
"node_modules/vue-loader/node_modules/json5": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
"dev": true,
"bin": {
"json5": "lib/cli.js"
},
"engines": {
"node": ">=6"
}
},
"node_modules/vue-loader/node_modules/loader-utils": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz",
"integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==",
"dev": true,
"dependencies": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
},
"engines": {
"node": ">=8.9.0"
}
},
"node_modules/watchpack": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
@ -9457,6 +9404,12 @@
"tweetnacl": "^0.14.3"
}
},
"big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
"dev": true
},
"binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
@ -10339,6 +10292,12 @@
"optional": true,
"peer": true
},
"emojis-list": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
"dev": true
},
"encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
@ -11862,6 +11821,12 @@
"optional": true,
"peer": true
},
"json5": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
"dev": true
},
"jsprim": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
@ -11966,6 +11931,17 @@
"integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==",
"dev": true
},
"loader-utils": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
"dev": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
},
"locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
@ -12167,12 +12143,6 @@
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
"dev": true
},
"minimist-options": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz",
@ -14171,40 +14141,6 @@
"loader-utils": "^2.0.0",
"mime-types": "^2.1.27",
"schema-utils": "^3.0.0"
},
"dependencies": {
"big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
"dev": true
},
"emojis-list": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
"dev": true
},
"json5": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
"integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
"dev": true,
"requires": {
"minimist": "^1.2.5"
}
},
"loader-utils": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
"dev": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
}
}
},
"util-deprecate": {
@ -14343,37 +14279,6 @@
"chalk": "^4.1.0",
"hash-sum": "^2.0.0",
"loader-utils": "^2.0.0"
},
"dependencies": {
"big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
"dev": true
},
"emojis-list": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
"dev": true
},
"json5": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
"dev": true
},
"loader-utils": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz",
"integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==",
"dev": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
}
}
},
"watchpack": {

File diff suppressed because one or more lines are too long

View File

@ -38,9 +38,10 @@ class GlancesPassword(object):
"""Return the local password path.
Related toissue: Password files in same configuration dir in effect #2143
"""
return self.config.get_value('passwords',
'local_password_path',
default=user_config_dir())
if self.config is None:
return user_config_dir()
else:
return self.config.get_value('passwords', 'local_password_path', default=user_config_dir())
def sha256_hash(self, plain_password):
"""Return the SHA-256 of the given password."""

View File

@ -14,7 +14,6 @@ Just a stupid plugin to display the help screen.
"""
import sys
from glances.compat import iteritems
from collections import OrderedDict
from glances import __version__, psutil_version
from glances.plugins.glances_plugin import GlancesPlugin
from itertools import chain
@ -63,7 +62,7 @@ class Plugin(GlancesPlugin):
self.view_data.update(
[
## First column
# First column
#
('header_sort', msg_header.format('SORT PROCESSES:')),
('sort_auto', msg_col.format('a', 'Automatically')),
@ -91,7 +90,7 @@ class Plugin(GlancesPlugin):
('show_hide_wifi_module', msg_col.format('W', 'Wifi')),
('show_hide_processes', msg_col.format('z', 'Processes')),
('show_hide_left_sidebar', msg_col.format('2', 'Left sidebar')),
## Second column
# Second column
#
('show_hide_quick_look', msg_col.format('3', 'Quick Look')),
('show_hide_cpu_mem_swap', msg_col.format('4', 'CPU, MEM, and SWAP')),
@ -111,7 +110,7 @@ class Plugin(GlancesPlugin):
('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')),
@ -146,7 +145,7 @@ class Plugin(GlancesPlugin):
ret.append(self.curse_new_line())
## key-shortcuts
# key-shortcuts
#
# Collect all values after the 1st key-msg
# in a list of curse-lines.

View File

@ -10,7 +10,7 @@
"""IP plugin."""
import threading
from json import loads
from ujson import loads
from glances.compat import queue, urlopen, urlopen_auth
from glances.logger import logger

View File

@ -29,21 +29,50 @@ import psutil
# 'key': 'interface_name'}
# Fields description
fields_description = {
'interface_name': {'description': 'Interface name.', 'unit': 'string'},
'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'},
'interface_name': {
'description': 'Interface name.',
'unit': 'string'
},
'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_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',
},
'is_up': {'description': 'Is the interface up ?', 'unit': 'bool'},
'time_since_update': {'description': 'Number of seconds since last update.', 'unit': 'seconds'},
'is_up': {
'description': 'Is the interface up ?',
'unit': 'bool'
},
'time_since_update': {
'description': 'Number of seconds since last update.',
'unit': 'seconds'
},
}
# SNMP OID

View File

@ -178,13 +178,13 @@ class GlancesPlugin(object):
def update_stats_history(self):
"""Update stats history."""
# If the plugin data is a dict, the dict's key should be used
if self.get_key() is None:
item_name = ''
else:
item_name = self.get_key()
# Build the history
if self.get_export() and self.history_enable():
# If the plugin data is a dict, the dict's key should be used
if self.get_key() is None:
item_name = ''
else:
item_name = self.get_key()
for i in self.get_items_history_list():
if isinstance(self.get_export(), list):
# Stats is a list of data

View File

@ -48,7 +48,7 @@ def split_cmdline(bare_process_name, cmdline):
path, cmd = "", cmdline[0]
else:
path, cmd = os.path.split(cmdline[0])
arguments = ' '.join(cmdline[1:])
arguments = ' '.join(cmdline[1:]).replace('\n', ' ')
return path, cmd, arguments
@ -350,7 +350,7 @@ class Plugin(GlancesPlugin):
"""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:

View File

@ -286,21 +286,19 @@ 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)
self.processlist = sort_stats(self.processlist,
sorted_by=self.sort_key,
reverse=True)
# Update the processcount
self.update_processcount(self.processlist)
@ -410,8 +408,9 @@ 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

View File

@ -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'],
}
@ -53,7 +53,7 @@ def processes_to_programs(processes):
programs_dict[p[key]]['childrens'].append(p['pid'])
# If all the subprocess has the same value, display it
programs_dict[p[key]]['username'] = (
p['username'] if p['username'] == programs_dict[p[key]]['username'] else '_'
p['username'] if ('username' in p) and (p['username'] == programs_dict[p[key]]['username']) else '_'
)
programs_dict[p[key]]['nice'] = p['nice'] if p['nice'] == programs_dict[p[key]]['nice'] else '_'
programs_dict[p[key]]['status'] = p['status'] if p['status'] == programs_dict[p[key]]['status'] else '_'

View File

@ -11,6 +11,7 @@
from glances.compat import nativestr
from subprocess import Popen, PIPE
import re
def secure_popen(cmd):
@ -48,8 +49,8 @@ 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
sub_cmd_split = [_ for _ in list(filter(None, re.split(r'(\s+)|(".*?"+?)|(\'.*?\'+?)', sub_cmd))) if _ != ' ']
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.

View File

@ -9,7 +9,7 @@
"""Manage the Glances server."""
import json
from glances.globals import json_dumps
import socket
import sys
from base64 import b64decode
@ -67,7 +67,7 @@ class GlancesXMLRPCHandler(SimpleXMLRPCRequestHandler, object):
if username in self.server.user_dict:
from glances.password import GlancesPassword
pwd = GlancesPassword()
pwd = GlancesPassword(username=username, config=self.config)
return pwd.check_password(self.server.user_dict[username], password)
else:
return False
@ -93,10 +93,11 @@ class GlancesXMLRPCServer(SimpleXMLRPCServer, object):
finished = False
def __init__(self, bind_address, bind_port=61209, requestHandler=GlancesXMLRPCHandler):
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
try:
self.address_family = socket.getaddrinfo(bind_address, bind_port)[0][0]
except socket.error as e:
@ -146,19 +147,19 @@ class GlancesInstance(object):
def getAll(self):
# Update and return all the stats
self.__update__()
return json.dumps(self.stats.getAll())
return json_dumps(self.stats.getAll())
def getAllPlugins(self):
# Return the plugins list
return json.dumps(self.stats.getPluginsList())
return json_dumps(self.stats.getPluginsList())
def getAllLimits(self):
# Return all the plugins limits
return json.dumps(self.stats.getAllLimitsAsDict())
return json_dumps(self.stats.getAllLimitsAsDict())
def getAllViews(self):
# Return all the plugins views
return json.dumps(self.stats.getAllViewsAsDict())
return json_dumps(self.stats.getAllViewsAsDict())
def __getattr__(self, item):
"""Overwrite the getattr method in case of attribute is not found.
@ -191,7 +192,7 @@ class GlancesServer(object):
# Init the XML RPC server
try:
self.server = GlancesXMLRPCServer(args.bind_address, args.port, requestHandler)
self.server = GlancesXMLRPCServer(args.bind_address, args.port, requestHandler, config=config)
except Exception as e:
logger.critical("Cannot start Glances server: {}".format(e))
sys.exit(2)
@ -211,6 +212,7 @@ class GlancesServer(object):
if not self.args.disable_autodiscover:
# Note: The Zeroconf service name will be based on the hostname
# Correct issue: Zeroconf problem with zeroconf service name #889
logger.info('Autodiscover is enabled with service name {}'.format(socket.gethostname().split('.', 1)[0]))
self.autodiscover_client = GlancesAutoDiscoverClient(socket.gethostname().split('.', 1)[0], args)
else:
logger.info("Glances autodiscover announce is disabled")

View File

@ -118,7 +118,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))

View File

@ -11,11 +11,11 @@ docker>=2.0.0
elasticsearch
graphitesender
hddtemp
influxdb>=1.0.0
influxdb-client; python_version >= "3.6"
influxdb>=1.0.0 # For InfluxDB < 1.8
influxdb-client; python_version >= "3.7" # For InfluxDB >= 1.8
kafka-python
netifaces
py3nvml; python_version >= "3.0"
py3nvml; python_version >= "3.5"
paho-mqtt
pika
podman; python_version >= "3.6"
@ -33,5 +33,5 @@ six
sparklines
statsd
wifi
zeroconf==0.19.1; python_version < "3.0"
zeroconf; python_version >= "3.0"
zeroconf==0.47.1; python_version < "3.7"
zeroconf; python_version >= "3.7"

6
renovate.json Normal file
View File

@ -0,0 +1,6 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base"
]
}

View File

@ -1,4 +1,8 @@
psutil>=5.3.0
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"

8
run.py Executable file
View File

@ -0,0 +1,8 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import re
import sys
from glances import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(main())

View File

@ -52,7 +52,7 @@ def get_install_requires():
def get_install_extras_require():
extras_require = {
'action': ['chevron'],
'browser': ['zeroconf==0.19.1' if PY2 else 'zeroconf>=0.19.1'],
'browser': ['zeroconf==0.47.1' if PY2 else 'zeroconf>=0.19.1'],
'cloud': ['requests'],
'docker': ['docker>=2.0.0', 'python-dateutil', 'six'],
'export': ['bernhard', 'cassandra-driver', 'couchdb', 'elasticsearch',
@ -135,13 +135,11 @@ setup(
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'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'
]
)

View File

@ -15,6 +15,7 @@ import subprocess
import time
import numbers
import unittest
import os
from glances import __version__
from glances.compat import text_type
@ -54,7 +55,11 @@ class TestGlances(unittest.TestCase):
global pid
print('INFO: [TEST_000] Start the Glances Web Server')
cmdline = "python -m glances -B localhost -w -p %s" % SERVER_PORT
if os.path.isfile("./venv/bin/python"):
cmdline = "./venv/bin/python"
else:
cmdline = "python"
cmdline += " -m glances -B localhost -w -p %s" % SERVER_PORT
print("Run the Glances Web Server on port %s" % SERVER_PORT)
args = shlex.split(cmdline)
pid = subprocess.Popen(args)

View File

@ -15,6 +15,7 @@ import shlex
import subprocess
import time
import unittest
import os
from glances import __version__
from glances.compat import ServerProxy
@ -43,7 +44,11 @@ class TestGlances(unittest.TestCase):
global pid
print('INFO: [TEST_000] Start the Glances Web Server')
cmdline = "python -m glances -B localhost -s -p %s" % SERVER_PORT
if os.path.isfile("./venv/bin/python"):
cmdline = "./venv/bin/python"
else:
cmdline = "python"
cmdline += " -m glances -B localhost -s -p %s" % SERVER_PORT
print("Run the Glances Server on port %s" % SERVER_PORT)
args = shlex.split(cmdline)
pid = subprocess.Popen(args)