mirror of https://github.com/nicolargo/glances.git
Merge branch 'develop' into issue1985
This commit is contained in:
commit
9f6295a632
17
.flake8
17
.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
|
||||
|
|
|
|||
|
|
@ -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: .
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 }}
|
||||
|
||||
|
|
|
|||
21
Makefile
21
Makefile
|
|
@ -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
|
||||
# ===================================================================
|
||||
|
|
|
|||
26
NEWS.rst
26
NEWS.rst
|
|
@ -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
|
||||
===============
|
||||
|
|
|
|||
42
README.rst
42
README.rst
|
|
@ -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
|
||||
|
|
@ -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.
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
sphinx
|
||||
sphinx_rtd_theme
|
||||
reuse
|
||||
reuse
|
||||
setuptools>=65.5.1 # not directly required, pinned by Snyk to avoid a vulnerability
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 |
1192
docs/api.rst
1192
docs/api.rst
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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 = {}
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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'];
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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."""
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 '_'
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": [
|
||||
"config:base"
|
||||
]
|
||||
}
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
6
setup.py
6
setup.py
|
|
@ -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'
|
||||
]
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue