├── .coveragerc ├── .dockerignore ├── .gitattributes ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE.md ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── build.yml │ ├── build_docker.yml │ ├── ci.yml │ ├── cyber.yml │ ├── inactive_issues.yml │ ├── needs_contributor.yml │ ├── quality.yml │ ├── test.yml │ └── webui.yml ├── .gitignore ├── .mailmap ├── .pre-commit-config.yaml ├── .readthedocs.yaml ├── .reuse └── dep5 ├── AUTHORS ├── CODE-OF-CONDUCT.md ├── CONTRIBUTING.md ├── COPYING ├── LICENSES └── LGPL-3.0-only.txt ├── MANIFEST.in ├── Makefile ├── NEWS.rst ├── README.rst ├── SECURITY.md ├── conf ├── glances-grafana-flux.json ├── glances-grafana-influxql.json └── glances.conf ├── dev-requirements.txt ├── doc-requirements.txt ├── docker-bin.sh ├── docker-compose ├── Dockerfile ├── docker-compose-with-traefik.yml ├── docker-compose.yml └── glances.conf ├── docker-files ├── README.md ├── alpine.Dockerfile ├── docker-logger.json └── ubuntu.Dockerfile ├── docker-requirements.txt ├── docs ├── Makefile ├── README.txt ├── _static │ ├── Glances Logo dark.svg │ ├── Glances Logo.svg │ ├── Glances Text Logo dark.svg │ ├── Glances Text Logo.svg │ ├── amp-dropbox.png │ ├── amp-python-warning.png │ ├── amp-python.png │ ├── amps.png │ ├── aws.png │ ├── browser.png │ ├── cloud.png │ ├── connected.png │ ├── connections.png │ ├── containers.png │ ├── cpu-wide.png │ ├── cpu.png │ ├── disconnected.png │ ├── diskio.png │ ├── events.png │ ├── folders.png │ ├── fs.png │ ├── glances-architecture.excalidraw │ ├── glances-architecture.png │ ├── glances-cgraph.svg │ ├── glances-flame.svg │ ├── glances-influxdb.png │ ├── glances-memory-profiling-with-history.png │ ├── glances-memory-profiling-without-history.png │ ├── glances-pyinstrument.html │ ├── glances-responsive-webdesign.png │ ├── glances-summary.png │ ├── gpu.png │ ├── grafana.png │ ├── graph-load.svg │ ├── hddtemp.png │ ├── header.png │ ├── ip.png │ ├── irq.png │ ├── load.png │ ├── loadpercent.png │ ├── mem-wide.png │ ├── mem.png │ ├── monitored.png │ ├── network.png │ ├── per-cpu.png │ ├── pergpu.png │ ├── ports.png │ ├── processlist-extended.png │ ├── processlist-filter.png │ ├── processlist-top.png │ ├── processlist-wide.png │ ├── processlist.png │ ├── prometheus_exporter.png │ ├── prometheus_server.png │ ├── quicklook-percpu.png │ ├── quicklook.png │ ├── raid.png │ ├── reddit.png │ ├── screencast.gif │ ├── screenshot-web.png │ ├── screenshot-web2.png │ ├── screenshot-wide.png │ ├── screenshot.png │ ├── sensors.png │ ├── smart.png │ ├── sparkline.png │ ├── trend.png │ ├── twitter-icon.png │ └── wifi.png ├── _templates │ └── links.html ├── aoa │ ├── actions.rst │ ├── amps.rst │ ├── cloud.rst │ ├── connections.rst │ ├── containers.rst │ ├── cpu.rst │ ├── diskio.rst │ ├── events.rst │ ├── folders.rst │ ├── fs.rst │ ├── gpu.rst │ ├── hddtemp.rst │ ├── header.rst │ ├── index.rst │ ├── irq.rst │ ├── load.rst │ ├── memory.rst │ ├── network.rst │ ├── ports.rst │ ├── ps.rst │ ├── quicklook.rst │ ├── raid.rst │ ├── sensors.rst │ ├── smart.rst │ ├── vms.rst │ └── wifi.rst ├── api.rst ├── build.sh ├── cmds.rst ├── conf.py ├── config.rst ├── dev │ ├── README.txt │ └── glances-cprofile.png ├── docker.rst ├── faq.rst ├── glances.rst ├── gw │ ├── cassandra.rst │ ├── couchdb.rst │ ├── csv.rst │ ├── elastic.rst │ ├── graph.rst │ ├── graphite.rst │ ├── index.rst │ ├── influxdb.rst │ ├── json.rst │ ├── kafka.rst │ ├── mongodb.rst │ ├── mqtt.rst │ ├── opentsdb.rst │ ├── prometheus.rst │ ├── rabbitmq.rst │ ├── restful.rst │ ├── riemann.rst │ ├── statsd.rst │ └── zeromq.rst ├── index.rst ├── install.rst ├── make.bat ├── man │ └── glances.1 ├── objects.inv ├── quickstart.rst └── support.rst ├── glances ├── README.txt ├── __init__.py ├── __main__.py ├── actions.py ├── amps │ ├── __init__.py │ ├── amp.py │ ├── default │ │ └── __init__.py │ ├── nginx │ │ └── __init__.py │ ├── systemd │ │ └── __init__.py │ └── systemv │ │ └── __init__.py ├── amps_list.py ├── attribute.py ├── client.py ├── client_browser.py ├── config.py ├── cpu_percent.py ├── event.py ├── events_list.py ├── exports │ ├── README.rst │ ├── __init__.py │ ├── export.py │ ├── glances_cassandra │ │ └── __init__.py │ ├── glances_couchdb │ │ └── __init__.py │ ├── glances_csv │ │ └── __init__.py │ ├── glances_elasticsearch │ │ └── __init__.py │ ├── glances_graph │ │ └── __init__.py │ ├── glances_graphite │ │ └── __init__.py │ ├── glances_influxdb │ │ └── __init__.py │ ├── glances_influxdb2 │ │ └── __init__.py │ ├── glances_influxdb3 │ │ └── __init__.py │ ├── glances_json │ │ └── __init__.py │ ├── glances_kafka │ │ └── __init__.py │ ├── glances_mongodb │ │ └── __init__.py │ ├── glances_mqtt │ │ └── __init__.py │ ├── glances_opentsdb │ │ └── __init__.py │ ├── glances_prometheus │ │ └── __init__.py │ ├── glances_rabbitmq │ │ └── __init__.py │ ├── glances_restful │ │ └── __init__.py │ ├── glances_riemann │ │ └── __init__.py │ ├── glances_statsd │ │ └── __init__.py │ └── glances_zeromq │ │ └── __init__.py ├── filter.py ├── folder_list.py ├── globals.py ├── history.py ├── logger.py ├── main.py ├── outdated.py ├── outputs │ ├── __init__.py │ ├── glances_bars.py │ ├── glances_colors.py │ ├── glances_curses.py │ ├── glances_curses_browser.py │ ├── glances_restful_api.py │ ├── glances_sparklines.py │ ├── glances_stdout.py │ ├── glances_stdout_apidoc.py │ ├── glances_stdout_csv.py │ ├── glances_stdout_issue.py │ ├── glances_stdout_json.py │ ├── glances_unicode.py │ └── static │ │ ├── .prettierrc.js │ │ ├── README.md │ │ ├── css │ │ ├── custom.scss │ │ └── style.scss │ │ ├── eslint.config.mjs │ │ ├── images │ │ ├── favicon.ico │ │ └── glances.png │ │ ├── js │ │ ├── App.vue │ │ ├── Browser.vue │ │ ├── app.js │ │ ├── browser.js │ │ ├── components │ │ │ ├── help.vue │ │ │ ├── plugin-alert.vue │ │ │ ├── plugin-amps.vue │ │ │ ├── plugin-cloud.vue │ │ │ ├── plugin-connections.vue │ │ │ ├── plugin-containers.vue │ │ │ ├── plugin-cpu.vue │ │ │ ├── plugin-diskio.vue │ │ │ ├── plugin-folders.vue │ │ │ ├── plugin-fs.vue │ │ │ ├── plugin-gpu.vue │ │ │ ├── plugin-hostname.vue │ │ │ ├── plugin-ip.vue │ │ │ ├── plugin-irq.vue │ │ │ ├── plugin-load.vue │ │ │ ├── plugin-mem.vue │ │ │ ├── plugin-memswap.vue │ │ │ ├── plugin-network.vue │ │ │ ├── plugin-now.vue │ │ │ ├── plugin-percpu.vue │ │ │ ├── plugin-ports.vue │ │ │ ├── plugin-process.vue │ │ │ ├── plugin-processcount.vue │ │ │ ├── plugin-processlist.vue │ │ │ ├── plugin-quicklook.vue │ │ │ ├── plugin-raid.vue │ │ │ ├── plugin-sensors.vue │ │ │ ├── plugin-smart.vue │ │ │ ├── plugin-system.vue │ │ │ ├── plugin-uptime.vue │ │ │ ├── plugin-vms.vue │ │ │ └── plugin-wifi.vue │ │ ├── filters.js │ │ ├── services.js │ │ ├── store.js │ │ └── uiconfig.json │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── public │ │ ├── browser.js │ │ ├── favicon.ico │ │ └── glances.js │ │ ├── templates │ │ ├── browser.html │ │ └── index.html │ │ └── webpack.config.js ├── password.py ├── password_list.py ├── plugins │ ├── README.rst │ ├── __init__.py │ ├── __pycache__ │ │ └── __init__.py │ ├── alert │ │ └── __init__.py │ ├── amps │ │ └── __init__.py │ ├── cloud │ │ └── __init__.py │ ├── connections │ │ └── __init__.py │ ├── containers │ │ ├── __init__.py │ │ └── engines │ │ │ ├── __init__.py │ │ │ ├── docker.py │ │ │ └── podman.py │ ├── core │ │ └── __init__.py │ ├── cpu │ │ └── __init__.py │ ├── diskio │ │ └── __init__.py │ ├── folders │ │ └── __init__.py │ ├── fs │ │ └── __init__.py │ ├── gpu │ │ ├── __init__.py │ │ └── cards │ │ │ ├── __init__.py │ │ │ ├── amd.py │ │ │ └── nvidia.py │ ├── help │ │ └── __init__.py │ ├── ip │ │ └── __init__.py │ ├── irq │ │ └── __init__.py │ ├── load │ │ └── __init__.py │ ├── mem │ │ └── __init__.py │ ├── memswap │ │ └── __init__.py │ ├── network │ │ └── __init__.py │ ├── now │ │ └── __init__.py │ ├── percpu │ │ └── __init__.py │ ├── plugin │ │ ├── __init__.py │ │ └── model.py │ ├── ports │ │ └── __init__.py │ ├── processcount │ │ └── __init__.py │ ├── processlist │ │ └── __init__.py │ ├── programlist │ │ └── __init__.py │ ├── psutilversion │ │ └── __init__.py │ ├── quicklook │ │ └── __init__.py │ ├── raid │ │ └── __init__.py │ ├── sensors │ │ ├── __init__.py │ │ └── sensor │ │ │ ├── __init__.py │ │ │ ├── glances_batpercent.py │ │ │ └── glances_hddtemp.py │ ├── smart │ │ └── __init__.py │ ├── system │ │ └── __init__.py │ ├── uptime │ │ └── __init__.py │ ├── version │ │ └── __init__.py │ ├── vms │ │ ├── __init__.py │ │ └── engines │ │ │ ├── __init__.py │ │ │ ├── multipass.py │ │ │ └── virsh.py │ └── wifi │ │ └── __init__.py ├── ports_list.py ├── processes.py ├── programs.py ├── secure.py ├── server.py ├── servers_list.py ├── servers_list_dynamic.py ├── servers_list_static.py ├── snmp.py ├── standalone.py ├── stats.py ├── stats_client.py ├── stats_client_snmp.py ├── stats_server.py ├── stats_streamer.py ├── thresholds.py ├── timer.py ├── web_list.py └── webserver.py ├── optional-requirements.txt ├── pyproject.toml ├── renovate.json ├── requirements.txt ├── run-venv.py ├── run.py ├── snap ├── local │ └── launchers │ │ └── glances-launch └── snapcraft.yaml ├── sonar-project.properties ├── tests-data ├── issues │ └── issue2849.py ├── plugins │ └── gpu │ │ └── amd │ │ └── sys │ │ ├── class │ │ └── drm │ │ │ └── card0 │ │ │ └── device │ │ │ ├── gpu_busy_percent │ │ │ ├── hwmon │ │ │ └── hwmon0 │ │ │ │ └── temp1_input │ │ │ ├── mem_info_vram_total │ │ │ ├── mem_info_vram_used │ │ │ ├── pp_dpm_mclk │ │ │ └── pp_dpm_sclk │ │ └── kernel │ │ └── debug │ │ └── dri │ │ └── 0 │ │ └── amdgpu_pm_info └── tools │ └── csvcheck.py ├── tests ├── conftest.py ├── test_core.py ├── test_export_csv.sh ├── test_export_influxdb_v1.sh ├── test_export_influxdb_v3.sh ├── test_export_json.sh ├── test_memoryleak.py ├── test_perf.py ├── test_restful.py ├── test_webui.py └── test_xmlrpc.py ├── tox.ini ├── uninstall.sh └── webui-requirements.txt /.coveragerc: -------------------------------------------------------------------------------- 1 | [report] 2 | 3 | include = 4 | *glances* 5 | 6 | omit = 7 | glances/outputs/* 8 | glances/exports/* 9 | glances/compat.py 10 | glances/autodiscover.py 11 | glances/client_browser.py 12 | glances/config.py 13 | glances/history.py 14 | glances/monitored_list.py 15 | glances/outdated.py 16 | glances/password*.py 17 | glances/snmp.py 18 | glances/static_list.py 19 | 20 | exclude_lines = 21 | pragma: no cover 22 | if PY3: 23 | if __name__ == .__main__.: 24 | if sys.platform.startswith 25 | except ImportError: 26 | raise NotImplementedError 27 | if WINDOWS 28 | if MACOS 29 | if BSD 30 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | # Ignore everything 2 | * 3 | 4 | # Include only code files 5 | !/glances/**/*.py 6 | 7 | # Include WebUI files (remove when webui moved to seperate package) 8 | !/glances/outputs/static 9 | 10 | # Include Requirements files 11 | !/requirements.txt 12 | !/docker-requirements.txt 13 | !/webui-requirements.txt 14 | !/optional-requirements.txt 15 | 16 | # Include Config file 17 | !/docker-compose/glances.conf 18 | !/docker-files/docker-logger.json 19 | 20 | # Include Binary file 21 | !/docker-bin.sh 22 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | glances/outputs/static/public/* -diff linguist-vendored 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: nicolargo 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Before filling this issue, please read the manual (https://glances.readthedocs.io/en/latest/) and search if the bug do not already exists in the database (https://github.com/nicolargo/glances/issues). 2 | 3 | For any questions concerning installation or use, please open a discussion (https://github.com/nicolargo/glances/discussions), not an issue. 4 | 5 | #### Description 6 | 7 | For a bug: Describe the bug and list the steps you used when the issue occurred. 8 | 9 | For an enhancement or new feature: Describe your needs. 10 | 11 | #### Versions 12 | 13 | * Glances & psutil versions: `To be completed with result of: glances -V` 14 | * Operating System: `To be completed with result of: lsb_release -a` 15 | * How do you install Glances (Pypi package, script, package manager, source): `To be completed` 16 | * Glances test (only available with Glances 3.1.7 or higher): 17 | 18 | ``` 19 | To be completed with result of: glances --issue 20 | ``` 21 | 22 | #### Configuration and log file 23 | 24 | You can also [pastebin](https://pastebin.com/): 25 | 26 | * the Glances configuration file (https://glances.readthedocs.io/en/latest/config.html#location) 27 | * the Glances log file (https://glances.readthedocs.io/en/latest/config.html#logging) 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | **Check the bug** 10 | Before filling this bug report, please search if a similar issue already exists. 11 | In this case, just add a comment on this existing issue. 12 | 13 | **Describe the bug** 14 | A clear and concise description of what the bug is. 15 | 16 | **To Reproduce** 17 | Steps to reproduce the behavior: 18 | 1. Start Glances with the following options '...' 19 | 2. Press the key '....' 20 | 3. See error 21 | 22 | **Expected behavior** 23 | A clear and concise description of what you expected to happen. 24 | 25 | **Screenshots** 26 | If applicable, add screenshots to help explain your problem. 27 | 28 | **Environement (please complete the following information)** 29 | - Operating System (lsb_release -a or OS name/version): `To be completed with result of: lsb_release -a` 30 | - Glances & psutil versions: `To be completed with result of: glances -V` 31 | - How do you install Glances (Pypi package, script, package manager, source): `To be completed` 32 | - Glances test: ` To be completed with result of: glances --issue` 33 | 34 | **Additional context** 35 | Add any other context about the problem here. 36 | 37 | You can also [pastebin](https://pastebin.com/): 38 | 39 | * the Glances configuration file (https://glances.readthedocs.io/en/latest/config.html#location) 40 | * the Glances log file (https://glances.readthedocs.io/en/latest/config.html#logging) 41 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | #### Description 2 | 3 | Please describe the goal of this pull request. 4 | 5 | For any questions concerning installation or use, please open a discussion (https://github.com/nicolargo/glances/discussions), not an issue. 6 | 7 | #### Resume 8 | 9 | * Bug fix: yes/no 10 | * New feature: yes/no 11 | * Fixed tickets: comma-separated list of tickets fixed by the PR, if any 12 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | # This pipeline aims at building Glances Pypi packages 2 | 3 | name: build 4 | 5 | on: 6 | workflow_call: 7 | 8 | jobs: 9 | 10 | build: 11 | name: Build distribution 📦 12 | if: github.event_name == 'push' 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v4 16 | - name: Set up Python 17 | uses: actions/setup-python@v5 18 | with: 19 | python-version: "3.13" 20 | - name: Install pypa/build 21 | run: >- 22 | python3 -m 23 | pip install 24 | build 25 | --user 26 | - name: Build a binary wheel and a source tarball 27 | run: python3 -m build 28 | - name: Store the distribution packages 29 | uses: actions/upload-artifact@v4 30 | with: 31 | name: python-package-distributions 32 | path: dist/ 33 | 34 | pypi: 35 | name: Publish Python 🐍 distribution 📦 to PyPI 36 | if: startsWith(github.ref, 'refs/tags') 37 | needs: 38 | - build 39 | runs-on: ubuntu-latest 40 | environment: 41 | name: pypi 42 | url: https://pypi.org/p/glances 43 | permissions: 44 | attestations: write 45 | id-token: write 46 | steps: 47 | - name: Download all the dists 48 | uses: actions/download-artifact@v4 49 | with: 50 | name: python-package-distributions 51 | path: dist/ 52 | - name: Publish distribution 📦 to PyPI 53 | uses: pypa/gh-action-pypi-publish@release/v1 54 | with: 55 | skip-existing: true 56 | attestations: false 57 | 58 | pypi_test: 59 | name: Publish Python 🐍 distribution 📦 to TestPyPI 60 | if: github.ref == 'refs/heads/develop' 61 | needs: 62 | - build 63 | runs-on: ubuntu-latest 64 | environment: 65 | name: testpypi 66 | url: https://pypi.org/p/glances 67 | permissions: 68 | attestations: write 69 | id-token: write 70 | steps: 71 | - name: Download all the dists 72 | uses: actions/download-artifact@v4 73 | with: 74 | name: python-package-distributions 75 | path: dist/ 76 | - name: Publish distribution 📦 to TestPyPI 77 | uses: pypa/gh-action-pypi-publish@release/v1 78 | with: 79 | repository-url: https://test.pypi.org/legacy/ 80 | skip-existing: true 81 | attestations: false 82 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: 4 | pull_request: 5 | branches: [ develop ] 6 | push: 7 | branches: [ master, develop ] 8 | tags: 9 | - v* 10 | 11 | jobs: 12 | quality: 13 | uses: ./.github/workflows/quality.yml 14 | test: 15 | uses: ./.github/workflows/test.yml 16 | needs: [quality] 17 | build: 18 | if: github.event_name != 'pull_request' 19 | uses: ./.github/workflows/build.yml 20 | needs: [quality, test] 21 | build_docker: 22 | if: github.event_name != 'pull_request' 23 | uses: ./.github/workflows/build_docker.yml 24 | secrets: 25 | DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} 26 | DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }} 27 | needs: [quality, test] 28 | -------------------------------------------------------------------------------- /.github/workflows/cyber.yml: -------------------------------------------------------------------------------- 1 | name: cyber 2 | 3 | on: 4 | workflow_call: 5 | 6 | jobs: 7 | trivy: 8 | name: Trivy scan 9 | 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Checkout code 14 | uses: actions/checkout@v4 15 | 16 | - name: Run Trivy vulnerability scanner in repo mode 17 | uses: aquasecurity/trivy-action@master 18 | with: 19 | scan-type: 'fs' 20 | ignore-unfixed: true 21 | format: 'sarif' 22 | output: 'trivy-results.sarif' 23 | severity: 'CRITICAL' 24 | 25 | - name: Upload Trivy scan results to GitHub Security tab 26 | uses: github/codeql-action/upload-sarif@v3 27 | with: 28 | sarif_file: 'trivy-results.sarif' 29 | -------------------------------------------------------------------------------- /.github/workflows/inactive_issues.yml: -------------------------------------------------------------------------------- 1 | name: Label inactive issues 2 | on: 3 | schedule: 4 | - cron: "30 1 * * *" 5 | 6 | jobs: 7 | close-issues: 8 | runs-on: ubuntu-latest 9 | permissions: 10 | issues: write 11 | pull-requests: write 12 | steps: 13 | - uses: actions/stale@v9 14 | with: 15 | days-before-issue-stale: 90 16 | days-before-issue-close: -1 17 | stale-issue-label: "inactive" 18 | stale-issue-message: "This issue is stale because it has been open for 3 months with no activity." 19 | close-issue-message: "This issue was closed because it has been inactive for 30 days since being marked as stale." 20 | days-before-pr-stale: -1 21 | days-before-pr-close: -1 22 | repo-token: ${{ secrets.GITHUB_TOKEN }} 23 | -------------------------------------------------------------------------------- /.github/workflows/needs_contributor.yml: -------------------------------------------------------------------------------- 1 | name: Add a message when needs contributor tag is used 2 | on: 3 | issues: 4 | types: 5 | - labeled 6 | jobs: 7 | add-comment: 8 | if: github.event.label.name == 'needs contributor' 9 | runs-on: ubuntu-latest 10 | permissions: 11 | issues: write 12 | steps: 13 | - name: Add comment 14 | run: gh issue comment "$NUMBER" --body "$BODY" 15 | env: 16 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 17 | GH_REPO: ${{ github.repository }} 18 | NUMBER: ${{ github.event.issue.number }} 19 | BODY: > 20 | This issue is available for anyone to work on. 21 | **Make sure to reference this issue in your pull request.** 22 | :sparkles: Thank you for your contribution ! :sparkles: -------------------------------------------------------------------------------- /.github/workflows/quality.yml: -------------------------------------------------------------------------------- 1 | name: quality 2 | 3 | on: 4 | workflow_call: 5 | 6 | jobs: 7 | analyze: 8 | name: Analyze 9 | runs-on: ubuntu-latest 10 | permissions: 11 | actions: read 12 | contents: read 13 | security-events: write 14 | 15 | strategy: 16 | fail-fast: false 17 | matrix: 18 | language: [ 'javascript', 'python' ] 19 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] 20 | # Learn more: 21 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed 22 | 23 | steps: 24 | - name: Checkout repository 25 | uses: actions/checkout@v4 26 | 27 | # Initializes the CodeQL tools for scanning. 28 | - name: Initialize CodeQL 29 | uses: github/codeql-action/init@v3 30 | with: 31 | languages: ${{ matrix.language }} 32 | # If you wish to specify custom queries, you can do so here or in a config file. 33 | # By default, queries listed here will override any specified in a config file. 34 | # Prefix the list here with "+" to use these queries and those in the config file. 35 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 36 | 37 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 38 | # If this step fails, then you should remove it and run the build manually (see below) 39 | - name: Autobuild 40 | uses: github/codeql-action/autobuild@v3 41 | 42 | # ℹ️ Command-line programs to run using the OS shell. 43 | # 📚 https://git.io/JvXDl 44 | 45 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 46 | # and modify them (or add more) to build your code if your project 47 | # uses a compiled language 48 | 49 | #- run: | 50 | # make bootstrap 51 | # make release 52 | 53 | - name: Perform CodeQL Analysis 54 | uses: github/codeql-action/analyze@v3 55 | -------------------------------------------------------------------------------- /.github/workflows/webui.yml: -------------------------------------------------------------------------------- 1 | name: webui 2 | 3 | on: 4 | workflow_call: 5 | 6 | jobs: 7 | build: 8 | 9 | runs-on: ubuntu-latest 10 | 11 | strategy: 12 | matrix: 13 | node-version: [20.x] 14 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ 15 | 16 | steps: 17 | - uses: actions/checkout@v4 18 | - name: Glances will be build with Node.js ${{ matrix.node-version }} 19 | uses: actions/setup-node@v4 20 | with: 21 | node-version: ${{ matrix.node-version }} 22 | cache: 'npm' 23 | cache-dependency-path: ./glances/outputs/static/package-lock.json 24 | - name: Build Glances WebUI 25 | working-directory: ./glances/outputs/static 26 | # TODO: add the following line when https://github.com/nicolargo/glances/issues/2914 will be solved 27 | # npm audit fix 28 | run: | 29 | npm ci 30 | npm run build 31 | - name: Commit and push WebUI 32 | env: 33 | CI_COMMIT_MESSAGE: Continuous Integration Build Artifacts 34 | CI_COMMIT_AUTHOR: Continuous Integration 35 | run: | 36 | git config --global user.name "${{ env.CI_COMMIT_AUTHOR }}" 37 | git config --global user.email "username@users.noreply.github.com" 38 | git add glances/outputs/static 39 | /bin/bash -c "git commit -m '${{ env.CI_COMMIT_MESSAGE }}' || true" 40 | git push 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.py[co] 3 | 4 | # Packages 5 | *.egg 6 | *.egg-info 7 | dist 8 | build 9 | 10 | # Eclipse and other IDE 11 | .idea 12 | *.pydevproject 13 | .project 14 | .metadata 15 | bin/** 16 | tmp/** 17 | tmp/**/* 18 | *.tmp 19 | *.bak 20 | *.swp 21 | *~.nib 22 | local.properties 23 | .classpath 24 | .settings/ 25 | .loadpath 26 | 27 | # External tool builders 28 | .externalToolBuilders/ 29 | *yarn.lock 30 | 31 | # Locally stored "Eclipse launch configurations" 32 | *.launch 33 | 34 | # CDT-specific 35 | .cproject 36 | 37 | # PDT-specific 38 | .buildpath 39 | 40 | # ctags 41 | .tags* 42 | 43 | # Sphinx 44 | _build 45 | 46 | # Tox 47 | .tox/ 48 | 49 | # web ui 50 | node_modules/ 51 | bower_components/ 52 | 53 | # visual stdio code 54 | .vscode/ 55 | 56 | # Snap packaging specific 57 | /snap/.snapcraft/ 58 | /parts/ 59 | /stage/ 60 | /prime/ 61 | 62 | /*.snap 63 | /*_source.tar.bz2 64 | 65 | # Virtual env 66 | /venv*/ 67 | 68 | # Test 69 | .coverage 70 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | Nicolas Hennion Nicolargo 2 | Nicolas Hennion Nicolas Hennion 3 | Nicolas Hennion nicolargo 4 | Nicolas Hennion nicolargo 5 | Nicolas Hennion nicolargo 6 | Nicolas Hennion nicolargo 7 | Nicolas Hennion Nicolargo 8 | Nicolas Hennion nicolargo 9 | Alessio Sergi asergi 10 | Nicolas Hart nclsHart 11 | Nicolas Hart Nicolas Hart 12 | Floran Brutel Floran Brutel 13 | Brandon Philips Brandon Philips 14 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/pre-commit/pre-commit-hooks 3 | rev: v5.0.0 4 | hooks: 5 | - id: check-ast 6 | - id: check-docstring-first 7 | - id: check-json 8 | - id: check-merge-conflict 9 | - id: check-shebang-scripts-are-executable 10 | - id: check-toml 11 | - id: check-yaml 12 | - id: debug-statements 13 | - id: detect-private-key 14 | - id: mixed-line-ending 15 | - id: requirements-txt-fixer 16 | 17 | - repo: https://github.com/astral-sh/ruff-pre-commit 18 | rev: v0.11.5 19 | hooks: 20 | - id: ruff-format 21 | - id: ruff 22 | args: [--fix, --exit-non-zero-on-fix] -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | # Read the Docs configuration file for Glances projects 2 | 3 | # Required 4 | version: 2 5 | 6 | # Set the OS, Python version and other tools you might need 7 | build: 8 | os: ubuntu-22.04 9 | tools: 10 | python: "3.12" 11 | # You can also specify other tool versions: 12 | # nodejs: "20" 13 | # rust: "1.70" 14 | # golang: "1.20" 15 | 16 | # Build documentation in the "docs/" directory with Sphinx 17 | sphinx: 18 | configuration: docs/conf.py 19 | # You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs 20 | # builder: "dirhtml" 21 | # Fail on all warnings to avoid broken references 22 | # fail_on_warning: true 23 | 24 | # Optionally build your docs in additional formats such as PDF and ePub 25 | # formats: 26 | # - pdf 27 | # - epub 28 | 29 | # Optional but recommended, declare the Python requirements required 30 | # to build your documentation 31 | # See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html 32 | python: 33 | install: 34 | - requirements: doc-requirements.txt -------------------------------------------------------------------------------- /.reuse/dep5: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: Glances 3 | Upstream-Contact: Nicolas Hennion 4 | Source: https://github.com/nicolargo/glances 5 | 6 | # Sample paragraph, commented out: 7 | # 8 | # Files: src/* 9 | # Copyright: $YEAR $NAME <$CONTACT> 10 | # License: ... 11 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | ========== 2 | Developers 3 | ========== 4 | 5 | Nicolas Hennion (aka) Nicolargo 6 | http://blog.nicolargo.com 7 | https://twitter.com/nicolargo 8 | https://github.com/nicolargo 9 | nicolashennion@gmail.com 10 | PGP Fingerprint: A0D9 628F 5A83 A879 48EA B1FE BA43 C11F 2C8B 4347 11 | PGP Public key: gpg --keyserver pgp.mit.edu --recv-keys 0xba43c11f2c8b4347 12 | 13 | RazCrimson (maintainer of the Glances project) 14 | https://github.com/RazCrimson 15 | 16 | Alessio Sergi (aka) Al3hex (thanks you for the great job on this project) 17 | https://twitter.com/al3hex 18 | https://github.com/asergi 19 | 20 | Floran Brutel (aka) notFloran (maintainer of the Web User Interface) 21 | https://github.com/notFloran 22 | 23 | fr4nc0is (maintainer of the Web User Interface) 24 | https://github.com/fr4nc0is 25 | 26 | Brandon Philips (aka) Philips 27 | http://ifup.org/ 28 | https://github.com/philips 29 | 30 | Jon Renner (aka) Jrenner 31 | https://github.com/jrenner 32 | 33 | Maxime Desbrus (aka) Desbma 34 | https://github.com/desbma 35 | 36 | Nicolas Hart (aka) NclsHart (for the Web user interface) 37 | https://github.com/nclsHart 38 | 39 | Sylvain Mouquet (aka) SylvainMouquet (for the Web user interface) 40 | http://github.com/sylvainmouquet 41 | 42 | Erik Eriksson (aka) Molobrakos (for the MQTT plugin and various PR) 43 | https://www.linkedin.com/in/error-errorsson/ 44 | 45 | ========= 46 | Packagers 47 | ========= 48 | 49 | 林博仁(Buo-ren Lin) Lin-Buo-Ren for the Snap package 50 | https://lin-buo-ren.github.io/ 51 | https://snapcraft.io/glances/releases 52 | 53 | Daniel Echeverry and Sebastien Badia for the Debian package 54 | https://tracker.debian.org/pkg/glances 55 | 56 | Philip Lacroix and Nicolas Kovacs for the Slackware (SlackBuild) package 57 | 58 | gasol.wu@gmail.com for the FreeBSD port 59 | 60 | Frederic Aoustin (https://github.com/fraoustin) and Nicolas Bourges (installer) for the Windows port 61 | 62 | Aljaž Srebrnič for the MacPorts package 63 | http://www.macports.org/ports.php?by=name&substr=glances 64 | 65 | John Kirkham for the conda package (at conda-forge) 66 | https://github.com/conda-forge/glances-feedstock 67 | 68 | Rui Chen for the Homebrew package 69 | https://chenrui.dev/ 70 | https://formulae.brew.sh/formula/glances 71 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include AUTHORS 2 | include CONTRIBUTING.md 3 | include COPYING 4 | include NEWS.rst 5 | include README.rst 6 | include SECURITY.md 7 | include conf/glances.conf 8 | include requirements.txt 9 | recursive-include docs * 10 | recursive-include glances *.py 11 | recursive-include glances/outputs/static * 12 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | | Version | Support security updates | 6 | | ------- | ------------------------ | 7 | | 4.x | :white_check_mark: | 8 | | < 4.0 | :x: | 9 | 10 | ## Reporting a Vulnerability 11 | 12 | If there are any vulnerabilities in {{cookiecutter.project_name}}, don't hesitate to report them. 13 | 14 | 1. Describe the vulnerability. 15 | 16 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 17 | * Full paths of source file(s) related to the manifestation of the issue 18 | * The location of the affected source code (tag/branch/commit or direct URL) 19 | * Any special configuration required to reproduce the issue 20 | * Step-by-step instructions to reproduce the issue 21 | * Proof-of-concept or exploit code (if possible) 22 | * Impact of the issue, including how an attacker might exploit the issue 23 | 24 | 2. If you have a fix, that is most welcome -- please attach or summarize it in your message! 25 | 26 | 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. 27 | 28 | 4. Please do not disclose the vulnerability publicly until a fix is released! 29 | 30 | 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. 31 | -------------------------------------------------------------------------------- /dev-requirements.txt: -------------------------------------------------------------------------------- 1 | codespell 2 | coverage 3 | fonttools>=4.43.0 # not directly required, pinned by Snyk to avoid a vulnerability 4 | gprof2dot 5 | matplotlib 6 | memory-profiler 7 | numpy>=1.22.2 # not directly required, pinned by Snyk to avoid a vulnerability 8 | pillow>=10.0.1 # not directly required, pinned by Snyk to avoid a vulnerability 9 | pre-commit 10 | py-spy 11 | pyright 12 | pytest 13 | requirements-parser 14 | rstcheck 15 | ruff 16 | selenium 17 | semgrep; platform_system == 'Linux' 18 | setuptools>=65.5.1 # not directly required, pinned by Snyk to avoid a vulnerability 19 | webdriver-manager 20 | -------------------------------------------------------------------------------- /doc-requirements.txt: -------------------------------------------------------------------------------- 1 | psutil 2 | defusedxml 3 | orjson 4 | reuse 5 | setuptools>=65.5.1 # not directly required, pinned by Snyk to avoid a vulnerability 6 | sphinx 7 | sphinx_rtd_theme 8 | -------------------------------------------------------------------------------- /docker-bin.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | /venv/bin/python3 -m glances "$@" 4 | -------------------------------------------------------------------------------- /docker-compose/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM glances:local-alpine-minimal as glancesminimal 2 | COPY glances.conf /glances/conf/glances.conf 3 | CMD python -m glances -C /glances/conf/glances.conf $GLANCES_OPT 4 | -------------------------------------------------------------------------------- /docker-compose/docker-compose-with-traefik.yml: -------------------------------------------------------------------------------- 1 | version: "3.9" 2 | services: 3 | reverse-proxy: 4 | image: traefik 5 | command: --api --docker 6 | ports: 7 | - "80:80" 8 | - "8080:8080" 9 | volumes: 10 | - /var/run/docker.sock:/var/run/docker.sock 11 | 12 | whoami: 13 | image: emilevauge/whoami 14 | labels: 15 | - "traefik.frontend.rule=Host:whoami.docker.localhost" 16 | 17 | monitoring: 18 | image: nicolargo/glances:dev 19 | restart: unless-stopped 20 | pid: host 21 | privileged: true 22 | network_mode: "host" 23 | volumes: 24 | - "/var/run/docker.sock:/var/run/docker.sock:ro" 25 | - "/run/user/1000/podman/podman.sock:/run/user/1000/podman/podman.sock:ro" 26 | - "./glances.conf:/glances/conf/glances.conf" 27 | environment: 28 | - TZ=${TZ} 29 | - "GLANCES_OPT=-C /glances/conf/glances.conf -w" 30 | # Uncomment for GPU compatibility (Nvidia) inside the container 31 | # deploy: 32 | # resources: 33 | # reservations: 34 | # devices: 35 | # - driver: nvidia 36 | # count: 1 37 | # capabilities: [gpu] 38 | labels: 39 | - "traefik.port=61208" 40 | - "traefik.frontend.rule=Host:glances.docker.localhost" 41 | -------------------------------------------------------------------------------- /docker-compose/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.9' 2 | services: 3 | glances: 4 | build: 5 | context: ./ 6 | dockerfile: Dockerfile 7 | restart: always 8 | pid: "host" 9 | privileged: true 10 | network_mode: "host" 11 | volumes: 12 | - "/var/run/docker.sock:/var/run/docker.sock:ro" 13 | - "/run/user/1000/podman/podman.sock:/run/user/1000/podman/podman.sock:ro" 14 | - "./glances.conf:/glances/conf/glances.conf" 15 | environment: 16 | - TZ=${TZ} 17 | - GLANCES_OPT=-C /glances/conf/glances.conf -w 18 | # # Uncomment for GPU compatibility (Nvidia) inside the container 19 | # deploy: 20 | # resources: 21 | # reservations: 22 | # devices: 23 | # - driver: nvidia 24 | # count: 1 25 | # capabilities: [gpu] 26 | # # Uncomment to protect Glances WebUI by a login/password (add --password to GLANCES_OPT) 27 | # secrets: 28 | # - source: glances_password 29 | # target: /root/.config/glances/.pwd 30 | 31 | # secrets: 32 | # glances_password: 33 | # file: ./secrets/glances_password 34 | -------------------------------------------------------------------------------- /docker-files/README.md: -------------------------------------------------------------------------------- 1 | # Dockerfiles 2 | 3 | ```bash 4 | make docker 5 | ``` 6 | 7 | Then test the image with: 8 | 9 | ```bash 10 | make run-docker-alpine-dev 11 | ``` 12 | -------------------------------------------------------------------------------- /docker-files/docker-logger.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "disable_existing_loggers": "False", 4 | "root": {"level": "INFO", "handlers": ["console"]}, 5 | "formatters": { 6 | "standard": {"format": "%(asctime)s -- %(levelname)s -- %(message)s"}, 7 | "short": {"format": "%(levelname)s -- %(message)s"}, 8 | "long": {"format": "%(asctime)s -- %(levelname)s -- %(message)s (%(funcName)s in %(filename)s)"}, 9 | "free": {"format": "%(message)s"} 10 | }, 11 | "handlers": { 12 | "console": {"class": "logging.StreamHandler", "formatter": "standard"} 13 | }, 14 | "loggers": { 15 | "debug": {"handlers": ["console"], "level": "DEBUG"}, 16 | "verbose": {"handlers": ["console"], "level": "INFO"}, 17 | "standard": {"handlers": ["console"], "level": "INFO"}, 18 | "requests": {"handlers": ["console"], "level": "ERROR"}, 19 | "elasticsearch": {"handlers": ["console"], "level": "ERROR"}, 20 | "elasticsearch.trace": {"handlers": ["console"], "level": "ERROR"} 21 | } 22 | } -------------------------------------------------------------------------------- /docker-requirements.txt: -------------------------------------------------------------------------------- 1 | # install with base requirements file 2 | -r requirements.txt 3 | 4 | docker>=6.1.1 5 | orjson # JSON Serialization speedup 6 | podman 7 | python-dateutil 8 | requests 9 | six 10 | urllib3 11 | -------------------------------------------------------------------------------- /docs/README.txt: -------------------------------------------------------------------------------- 1 | Building the docs 2 | ================= 3 | 4 | First install Sphinx and the RTD theme: 5 | 6 | make venv 7 | 8 | or update it if already installed: 9 | 10 | make venv-upgrade 11 | 12 | Go to the docs folder: 13 | 14 | cd docs 15 | 16 | Then build the HTML documentation: 17 | 18 | make html 19 | 20 | and the man page: 21 | 22 | LC_ALL=C make man 23 | -------------------------------------------------------------------------------- /docs/_static/amp-dropbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/amp-dropbox.png -------------------------------------------------------------------------------- /docs/_static/amp-python-warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/amp-python-warning.png -------------------------------------------------------------------------------- /docs/_static/amp-python.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/amp-python.png -------------------------------------------------------------------------------- /docs/_static/amps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/amps.png -------------------------------------------------------------------------------- /docs/_static/aws.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/aws.png -------------------------------------------------------------------------------- /docs/_static/browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/browser.png -------------------------------------------------------------------------------- /docs/_static/cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/cloud.png -------------------------------------------------------------------------------- /docs/_static/connected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/connected.png -------------------------------------------------------------------------------- /docs/_static/connections.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/connections.png -------------------------------------------------------------------------------- /docs/_static/containers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/containers.png -------------------------------------------------------------------------------- /docs/_static/cpu-wide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/cpu-wide.png -------------------------------------------------------------------------------- /docs/_static/cpu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/cpu.png -------------------------------------------------------------------------------- /docs/_static/disconnected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/disconnected.png -------------------------------------------------------------------------------- /docs/_static/diskio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/diskio.png -------------------------------------------------------------------------------- /docs/_static/events.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/events.png -------------------------------------------------------------------------------- /docs/_static/folders.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/folders.png -------------------------------------------------------------------------------- /docs/_static/fs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/fs.png -------------------------------------------------------------------------------- /docs/_static/glances-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/glances-architecture.png -------------------------------------------------------------------------------- /docs/_static/glances-influxdb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/glances-influxdb.png -------------------------------------------------------------------------------- /docs/_static/glances-memory-profiling-with-history.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/glances-memory-profiling-with-history.png -------------------------------------------------------------------------------- /docs/_static/glances-memory-profiling-without-history.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/glances-memory-profiling-without-history.png -------------------------------------------------------------------------------- /docs/_static/glances-responsive-webdesign.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/glances-responsive-webdesign.png -------------------------------------------------------------------------------- /docs/_static/glances-summary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/glances-summary.png -------------------------------------------------------------------------------- /docs/_static/gpu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/gpu.png -------------------------------------------------------------------------------- /docs/_static/grafana.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/grafana.png -------------------------------------------------------------------------------- /docs/_static/hddtemp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/hddtemp.png -------------------------------------------------------------------------------- /docs/_static/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/header.png -------------------------------------------------------------------------------- /docs/_static/ip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/ip.png -------------------------------------------------------------------------------- /docs/_static/irq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/irq.png -------------------------------------------------------------------------------- /docs/_static/load.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/load.png -------------------------------------------------------------------------------- /docs/_static/loadpercent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/loadpercent.png -------------------------------------------------------------------------------- /docs/_static/mem-wide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/mem-wide.png -------------------------------------------------------------------------------- /docs/_static/mem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/mem.png -------------------------------------------------------------------------------- /docs/_static/monitored.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/monitored.png -------------------------------------------------------------------------------- /docs/_static/network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/network.png -------------------------------------------------------------------------------- /docs/_static/per-cpu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/per-cpu.png -------------------------------------------------------------------------------- /docs/_static/pergpu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/pergpu.png -------------------------------------------------------------------------------- /docs/_static/ports.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/ports.png -------------------------------------------------------------------------------- /docs/_static/processlist-extended.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/processlist-extended.png -------------------------------------------------------------------------------- /docs/_static/processlist-filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/processlist-filter.png -------------------------------------------------------------------------------- /docs/_static/processlist-top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/processlist-top.png -------------------------------------------------------------------------------- /docs/_static/processlist-wide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/processlist-wide.png -------------------------------------------------------------------------------- /docs/_static/processlist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/processlist.png -------------------------------------------------------------------------------- /docs/_static/prometheus_exporter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/prometheus_exporter.png -------------------------------------------------------------------------------- /docs/_static/prometheus_server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/prometheus_server.png -------------------------------------------------------------------------------- /docs/_static/quicklook-percpu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/quicklook-percpu.png -------------------------------------------------------------------------------- /docs/_static/quicklook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/quicklook.png -------------------------------------------------------------------------------- /docs/_static/raid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/raid.png -------------------------------------------------------------------------------- /docs/_static/reddit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/reddit.png -------------------------------------------------------------------------------- /docs/_static/screencast.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/screencast.gif -------------------------------------------------------------------------------- /docs/_static/screenshot-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/screenshot-web.png -------------------------------------------------------------------------------- /docs/_static/screenshot-web2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/screenshot-web2.png -------------------------------------------------------------------------------- /docs/_static/screenshot-wide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/screenshot-wide.png -------------------------------------------------------------------------------- /docs/_static/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/screenshot.png -------------------------------------------------------------------------------- /docs/_static/sensors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/sensors.png -------------------------------------------------------------------------------- /docs/_static/smart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/smart.png -------------------------------------------------------------------------------- /docs/_static/sparkline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/sparkline.png -------------------------------------------------------------------------------- /docs/_static/trend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/trend.png -------------------------------------------------------------------------------- /docs/_static/twitter-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/twitter-icon.png -------------------------------------------------------------------------------- /docs/_static/wifi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/_static/wifi.png -------------------------------------------------------------------------------- /docs/_templates/links.html: -------------------------------------------------------------------------------- 1 |

Useful Links

2 | 8 | -------------------------------------------------------------------------------- /docs/aoa/actions.rst: -------------------------------------------------------------------------------- 1 | .. _actions: 2 | 3 | Actions 4 | ======= 5 | 6 | Glances can trigger actions on events. 7 | 8 | By ``action``, we mean all shell command line. For example, if you want 9 | to execute the ``foo.py`` script if the last 5 minutes load are critical 10 | then add the ``_action`` line to the Glances configuration file: 11 | 12 | .. code-block:: ini 13 | 14 | [load] 15 | critical=5.0 16 | critical_action=python /path/to/foo.py 17 | 18 | All the stats are available in the command line through the use of the 19 | `Mustache`_ syntax. `Chevron`_ is required to render the mustache's template syntax. 20 | 21 | Another example would be to create a log file 22 | containing used vs total disk space if a space trigger warning is 23 | reached: 24 | 25 | .. code-block:: ini 26 | 27 | [fs] 28 | warning=70 29 | warning_action=echo {{mnt_point}} {{used}}/{{size}} > /tmp/fs.alert 30 | 31 | A last example would be to create a log file containing the total user disk 32 | space usage for a device and notify by email each time a space trigger 33 | critical is reached: 34 | 35 | .. code-block:: ini 36 | 37 | [fs] 38 | critical=90 39 | critical_action_repeat=echo {{device_name}} {{percent}} > /tmp/fs.alert && python /etc/glances/actions.d/fs-critical.py 40 | 41 | 42 | .. note:: 43 | Use && as separator for multiple commands 44 | 45 | 46 | Within ``/etc/glances/actions.d/fs-critical.py``: 47 | 48 | .. code-block:: python 49 | 50 | import subprocess 51 | from requests import get 52 | 53 | fs_alert = open('/tmp/fs.alert', 'r').readline().strip().split(' ') 54 | device = fs_alert[0] 55 | percent = fs_alert[1] 56 | system = subprocess.check_output(['uname', '-rn']).decode('utf-8').strip() 57 | ip = get('https://api.ipify.org').text 58 | 59 | body = 'Used user disk space for ' + device + ' is at ' + percent + '%.\nPlease cleanup the filesystem to clear the alert.\nServer: ' + str(system)+ '.\nIP address: ' + ip 60 | ps = subprocess.Popen(('echo', '-e', body), stdout=subprocess.PIPE) 61 | subprocess.call(['mail', '-s', 'CRITICAL: disk usage above 90%', '-r', 'postmaster@example.com', 'glances@example.com'], stdin=ps.stdout) 62 | 63 | .. note:: 64 | 65 | You can use all the stats for the current plugin. See 66 | https://github.com/nicolargo/glances/wiki/The-Glances-RESTFULL-JSON-API 67 | for the stats list. 68 | 69 | It is also possible to repeat action until the end of the alert. 70 | Keep in mind that the command line is executed every refresh time so 71 | use with caution: 72 | 73 | .. code-block:: ini 74 | 75 | [load] 76 | critical=5.0 77 | critical_action_repeat=/home/myhome/bin/bipper.sh 78 | 79 | .. _Mustache: https://mustache.github.io/ 80 | .. _Chevron: https://github.com/noahmorrison/chevron 81 | -------------------------------------------------------------------------------- /docs/aoa/cloud.rst: -------------------------------------------------------------------------------- 1 | .. _cloud: 2 | 3 | CLOUD 4 | ===== 5 | 6 | This plugin displays information about the cloud provider if your host is running on OpenStack. 7 | 8 | The plugin use the standard OpenStack `metadata`_ service to retrieve the information. 9 | 10 | This plugin is disable by default, please use the --enable-plugin cloud option 11 | to enable it. 12 | 13 | .. image:: ../_static/cloud.png 14 | 15 | .. _metadata: https://docs.openstack.org/nova/latest/user/metadata.html -------------------------------------------------------------------------------- /docs/aoa/connections.rst: -------------------------------------------------------------------------------- 1 | .. _connections: 2 | 3 | Connections 4 | =========== 5 | 6 | .. image:: ../_static/connections.png 7 | 8 | This plugin display extended information about network connections. 9 | 10 | The states are the following: 11 | 12 | - Listen: all ports created by server and waiting for a client to connect 13 | - Initialized: All states when a connection is initialized (sum of SYN_SENT and SYN_RECEIVED) 14 | - Established: All established connections between a client and a server 15 | - Terminated: All states when a connection is terminated (FIN_WAIT1, CLOSE_WAIT, LAST_ACK, FIN_WAIT2, TIME_WAIT and CLOSE) 16 | - Tracked: Current number and maximum Netfilter tracker connection (nf_conntrack_count/nf_conntrack_max) 17 | 18 | The configuration should be done in the ``[connections]`` section of the 19 | Glances configuration file. 20 | 21 | By default the plugin is **disabled**. Please change your configuration file as following to enable it 22 | 23 | .. code-block:: ini 24 | 25 | [connections] 26 | disable=False 27 | # nf_conntrack thresholds in % 28 | nf_conntrack_percent_careful=70 29 | nf_conntrack_percent_warning=80 30 | nf_conntrack_percent_critical=90 31 | -------------------------------------------------------------------------------- /docs/aoa/containers.rst: -------------------------------------------------------------------------------- 1 | .. _containers: 2 | 3 | Containers 4 | ========== 5 | 6 | If you use ``containers``, Glances can help you to monitor your Docker or Podman containers. 7 | Glances uses the containers API through the `docker-py`_ and `podman-py`_ libraries. 8 | 9 | You can install this dependency using: 10 | 11 | .. code-block:: console 12 | 13 | pip install glances[containers] 14 | 15 | .. image:: ../_static/containers.png 16 | 17 | Note: Memory usage is compute as following "display memory usage = memory usage - inactive_file" 18 | 19 | It is possible to define limits and actions from the configuration file 20 | under the ``[containers]`` section: 21 | 22 | .. code-block:: ini 23 | 24 | [containers] 25 | disable=False 26 | # Only show specific containers (comma-separated list of container name or regular expression) 27 | show=thiscontainer,andthisone,andthoseones.* 28 | # Hide some containers (comma-separated list of container name or regular expression) 29 | hide=donotshowthisone,andthose.* 30 | # Show only specific containers (comma-separated list of container name or regular expression) 31 | #show=showthisone,andthose.* 32 | # Define the maximum containers size name (default is 20 chars) 33 | max_name_size=20 34 | # List of stats to disable (not display) 35 | # Following stats can be disabled: name,status,uptime,cpu,mem,diskio,networkio,command 36 | disable_stats=diskio,networkio 37 | # Global containers' thresholds for CPU and MEM (in %) 38 | cpu_careful=50 39 | cpu_warning=70 40 | cpu_critical=90 41 | mem_careful=20 42 | mem_warning=50 43 | mem_critical=70 44 | # Per container thresholds 45 | containername_cpu_careful=10 46 | containername_cpu_warning=20 47 | containername_cpu_critical=30 48 | containername_cpu_critical_action=echo {{Image}} {{Id}} {{cpu}} > /tmp/container_{{name}}.alert 49 | # By default, Glances only display running containers 50 | # Set the following key to True to display all containers 51 | all=False 52 | # Define Podman sock 53 | #podman_sock=unix:///run/user/1000/podman/podman.sock 54 | 55 | You can use all the variables ({{foo}}) available in the containers plugin. 56 | 57 | Filtering (for hide or show) is based on regular expression. Please be sure that your regular 58 | expression works as expected. You can use an online tool like `regex101`_ in 59 | order to test your regular expression. 60 | 61 | .. _regex101: https://regex101.com/ 62 | .. _docker-py: https://github.com/containers/containers-py 63 | .. _podman-py: https://github.com/containers/podman-py -------------------------------------------------------------------------------- /docs/aoa/diskio.rst: -------------------------------------------------------------------------------- 1 | .. _disk: 2 | 3 | Disk I/O 4 | ======== 5 | 6 | .. image:: ../_static/diskio.png 7 | 8 | Glances displays the disk I/O throughput. The unit is adapted 9 | dynamically. 10 | 11 | You can display: 12 | 13 | - bytes per second (default behavior / Bytes/s, KBytes/s, MBytes/s, etc) 14 | - requests per second (using --diskio-iops option or *B* hotkey) 15 | 16 | There is no alert on this information. 17 | 18 | It's possible to define: 19 | 20 | - a list of disk to show (white list) 21 | - a list of disks to hide 22 | - aliases for disk name 23 | 24 | under the ``[diskio]`` section in the configuration file. 25 | 26 | For example, if you want to hide the loopback disks (loop0, loop1, ...) 27 | and the specific ``sda5`` partition: 28 | 29 | .. code-block:: ini 30 | 31 | [diskio] 32 | hide=sda5,loop.* 33 | 34 | or another example: 35 | 36 | .. code-block:: ini 37 | 38 | [diskio] 39 | show=sda.* 40 | 41 | Filtering is based on regular expression. Please be sure that your regular 42 | expression works as expected. You can use an online tool like `regex101`_ in 43 | order to test your regular expression. 44 | 45 | It is also possible to define thesholds for bytes read and write per second: 46 | 47 | .. code-block:: ini 48 | 49 | [diskio] 50 | # Alias for sda1 and sdb1 51 | #alias=sda1:SystemDisk,sdb1:DataDisk 52 | # Set thresholds (in bytes per second) for a given disk name (rx = read / tx = write) 53 | dm-0_rx_careful=4000000000 54 | dm-0_rx_warning=5000000000 55 | dm-0_rx_critical=6000000000 56 | dm-0_rx_log=True 57 | dm-0_tx_careful=700000000 58 | dm-0_tx_warning=900000000 59 | dm-0_tx_critical=1000000000 60 | dm-0_tx_log=True 61 | 62 | You also can automatically hide disk with no read or write using the 63 | ``hide_zero`` configuration key. The optional ``hide_threshold_bytes`` option 64 | can also be used to set a threshold higher than zero. 65 | 66 | .. code-block:: ini 67 | 68 | [diskio] 69 | hide_zero=True 70 | hide_threshold_bytes=0 71 | 72 | .. _regex101: https://regex101.com/ -------------------------------------------------------------------------------- /docs/aoa/events.rst: -------------------------------------------------------------------------------- 1 | .. _events: 2 | 3 | events 4 | ====== 5 | 6 | .. image:: ../_static/events.png 7 | 8 | Events list is displayed in the bottom of the screen if and only if: 9 | 10 | - at least one ``WARNING`` or ``CRITICAL`` alert was occurred 11 | - space is available in the bottom of the console/terminal 12 | 13 | Each event message displays the following information: 14 | 15 | 1. start datetime 16 | 2. duration if alert is terminated or `ongoing` if the alert is still in 17 | progress 18 | 3. alert name 19 | 4. {min,avg,max} values or number of running processes for monitored 20 | processes list alerts 21 | 22 | The configuration should be done in the ``[alert]`` section of the 23 | Glances configuration file: 24 | 25 | .. code-block:: ini 26 | 27 | [alert] 28 | disable=False 29 | # Maximum number of events to display (default is 10 events) 30 | max_events=10 31 | # Minimum duration for an event to be taken into account (default is 6 seconds) 32 | min_duration=6 33 | # Minimum time between two events of the same type (default is 6 seconds) 34 | # This is used to avoid too many alerts for the same event 35 | # Events will be merged 36 | min_interval=6 37 | 38 | -------------------------------------------------------------------------------- /docs/aoa/folders.rst: -------------------------------------------------------------------------------- 1 | .. _folders: 2 | 3 | Folders 4 | ======= 5 | 6 | The folders plugin allows user, through the configuration file, to 7 | monitor size of a predefined folders list. 8 | 9 | .. image:: ../_static/folders.png 10 | 11 | If the size cannot be computed, a ``'?'`` (non-existing folder) or a 12 | ``'!'`` (permission denied) is displayed. 13 | 14 | Each item is defined by: 15 | 16 | - ``path``: absolute path to monitor (mandatory) 17 | - ``careful``: optional careful threshold (in MB) 18 | - ``warning``: optional warning threshold (in MB) 19 | - ``critical``: optional critical threshold (in MB) 20 | - ``refresh``: interval in second between two refresh (default is 30 seconds) 21 | 22 | Up to ``10`` items can be defined. 23 | 24 | For example, if you want to monitor the ``/tmp`` folder every minute, 25 | the following definition should do the job: 26 | 27 | .. code-block:: ini 28 | 29 | [folders] 30 | folder_1_path=/tmp 31 | folder_1_careful=2500 32 | folder_1_warning=3000 33 | folder_1_critical=3500 34 | folder_1_refresh=60 35 | 36 | In client/server mode, the list is defined on the ``server`` side. 37 | 38 | .. warning:: 39 | Symbolic links are not followed. 40 | 41 | .. warning:: 42 | Do **NOT** define folders containing lot of files and subfolders or use an 43 | huge refresh time... 44 | -------------------------------------------------------------------------------- /docs/aoa/fs.rst: -------------------------------------------------------------------------------- 1 | .. _fs: 2 | 3 | File System 4 | =========== 5 | 6 | .. image:: ../_static/fs.png 7 | 8 | Glances displays the used and total file system disk space. The unit is 9 | adapted dynamically. 10 | 11 | Alerts are set for `user disk space usage `_. 12 | 13 | Legend: 14 | 15 | ===================== ============ 16 | User disk space usage Status 17 | ===================== ============ 18 | ``<50%`` ``OK`` 19 | ``>50%`` ``CAREFUL`` 20 | ``>70%`` ``WARNING`` 21 | ``>90%`` ``CRITICAL`` 22 | ===================== ============ 23 | 24 | .. note:: 25 | Limit values can be overwritten in the configuration file under 26 | the ``[fs]`` section. 27 | 28 | By default, the plugin only displays physical devices (hard disks, USB 29 | keys). To allow other file system types, you have to enable them in the 30 | configuration file. For example, if you want to allow the ``shm`` file 31 | system: 32 | 33 | .. code-block:: ini 34 | 35 | [fs] 36 | allow=shm 37 | 38 | Also, you can hide mount points using regular expressions. 39 | 40 | To hide all mount points starting with /boot and /snap: 41 | 42 | .. code-block:: ini 43 | 44 | [fs] 45 | hide=/boot.*,/snap.* 46 | 47 | Filtering are also applied on device name (Glances 3.1.4 or higher). 48 | 49 | It is also possible to configure a white list of devices to display. 50 | Example to only show /dev/sdb mount points: 51 | 52 | .. code-block:: ini 53 | 54 | [fs] 55 | show=/dev/sdb.* 56 | 57 | Filtering is based on regular expression. Please be sure that your regular 58 | expression works as expected. You can use an online tool like `regex101`_ in 59 | order to test your regular expression. 60 | 61 | .. _regex101: https://regex101.com/ -------------------------------------------------------------------------------- /docs/aoa/gpu.rst: -------------------------------------------------------------------------------- 1 | .. _gpu: 2 | 3 | GPU 4 | === 5 | 6 | For the moment, only following GPU are supported: 7 | - NVidia (thanks to the `nvidia-ml-py`_ library) 8 | - AMD (only on Linux Operating system with kernel 5.14 or higher) 9 | 10 | The GPU stats are shown as a percentage of value and for the configured 11 | refresh time. It displays: 12 | 13 | - total GPU usage 14 | - memory consumption 15 | - temperature 16 | 17 | .. image:: ../_static/gpu.png 18 | 19 | If you click on the ``6`` short key, the per-GPU view is displayed: 20 | 21 | .. image:: ../_static/pergpu.png 22 | 23 | .. note:: 24 | You can also start Glances with the ``--meangpu`` option to display 25 | the first view by default. 26 | 27 | You can change the threshold limits in the configuration file: 28 | 29 | .. code-block:: ini 30 | 31 | [gpu] 32 | # Default processor values if not defined: 50/70/90 33 | proc_careful=50 34 | proc_warning=70 35 | proc_critical=90 36 | # Default memory values if not defined: 50/70/90 37 | mem_careful=50 38 | mem_warning=70 39 | mem_critical=90 40 | # Temperature 41 | temperature_careful=60 42 | temperature_warning=70 43 | temperature_critical=80 44 | 45 | Legend: 46 | 47 | ============== ============ 48 | GPU (PROC/MEM) Status 49 | ============== ============ 50 | ``<50%`` ``OK`` 51 | ``>50%`` ``CAREFUL`` 52 | ``>70%`` ``WARNING`` 53 | ``>90%`` ``CRITICAL`` 54 | ============== ============ 55 | 56 | .. _nvidia-ml-py: https://pypi.org/project/nvidia-ml-py/ 57 | -------------------------------------------------------------------------------- /docs/aoa/hddtemp.rst: -------------------------------------------------------------------------------- 1 | .. _sensors: 2 | 3 | HDD temperature sensor 4 | ====================== 5 | 6 | *Availability: Linux* 7 | 8 | This plugin will add HDD temperature to the sensors plugin. 9 | 10 | On your Linux system, you will need to have: 11 | - hddtemp package installed 12 | - hddtemp service up and running (check it with systemctl status hddtemp) 13 | - the TCP port 7634 opened on your local firewall (if it is enabled on your system) 14 | 15 | For example on a CentOS/Redhat Linux operating system, you have to: 16 | 17 | $ sudo yum install hddtemp 18 | 19 | $ sudo systemctl enable hddtemp 20 | 21 | $ sudo systemctl enable hddtemp 22 | 23 | Test it in the console: 24 | 25 | $ hddtemp 26 | 27 | /dev/sda: TOSHIBA MQ01ACF050: 41°C 28 | 29 | /dev/sdb: ST1000LM044 HN-M101SAD: 38°C 30 | 31 | It should appears in the sensors plugin. 32 | 33 | .. image:: ../_static/hddtemp.png 34 | 35 | There is no alert on this information. 36 | 37 | .. note:: 38 | Limit values and sensors alias names can be defined in the 39 | configuration file under the ``[sensors]`` section. 40 | -------------------------------------------------------------------------------- /docs/aoa/index.rst: -------------------------------------------------------------------------------- 1 | .. _aoa: 2 | 3 | Anatomy Of The Application 4 | ========================== 5 | 6 | This document is meant to give an overview of the Glances interface. 7 | 8 | Legend: 9 | 10 | =========== ============ 11 | ``GREEN`` ``OK`` 12 | ``BLUE`` ``CAREFUL`` 13 | ``MAGENTA`` ``WARNING`` 14 | ``RED`` ``CRITICAL`` 15 | =========== ============ 16 | 17 | .. note:: 18 | Only stats with colored background will be shown in the alert view. 19 | 20 | .. toctree:: 21 | :maxdepth: 2 22 | 23 | header 24 | quicklook 25 | cpu 26 | gpu 27 | memory 28 | load 29 | network 30 | connections 31 | wifi 32 | ports 33 | diskio 34 | fs 35 | irq 36 | folders 37 | cloud 38 | raid 39 | smart 40 | sensors 41 | hddtemp 42 | ps 43 | containers 44 | vms 45 | amps 46 | events 47 | actions 48 | -------------------------------------------------------------------------------- /docs/aoa/irq.rst: -------------------------------------------------------------------------------- 1 | .. _irq: 2 | 3 | IRQ 4 | === 5 | 6 | *Availability: Linux* 7 | 8 | This plugin is disable by default, please use the --enable irq option 9 | to enable it. 10 | 11 | .. image:: ../_static/irq.png 12 | 13 | Glances displays the top ``5`` interrupts rate. 14 | 15 | This plugin is only available on GNU/Linux (stats are grabbed from the 16 | ``/proc/interrupts`` file). 17 | 18 | .. note:: 19 | ``/proc/interrupts`` file doesn't exist inside OpenVZ containers. 20 | 21 | How to read the information: 22 | 23 | - The first column is the IRQ number / name 24 | - The second column says how many times the CPU has been interrupted 25 | during the last second 26 | -------------------------------------------------------------------------------- /docs/aoa/load.rst: -------------------------------------------------------------------------------- 1 | .. _load: 2 | 3 | Load 4 | ==== 5 | 6 | *Availability: Unix and Windows with a PsUtil version >= 5.6.2* 7 | 8 | .. image:: ../_static/load.png 9 | 10 | On the *No Sheep* blog, Zachary Tirrell defines the `load average`_ 11 | on GNU/Linux operating system: 12 | 13 | "In short it is the average sum of the number of processes 14 | waiting in the run-queue plus the number currently executing 15 | over 1, 5, and 15 minutes time periods." 16 | 17 | Be aware that Load on Linux, BSD and Windows are different things, high 18 | `load on BSD`_ does not means high CPU load. The Windows load is emulated 19 | by the PsUtil lib (see `load on Windows`_) 20 | 21 | Glances gets the number of CPU core (displayed on the first line) to adapt 22 | the alerts. Alerts on load average are only set on 15 minutes time period. 23 | 24 | Thresholds are computed by dividing the 5 and 15 minutes average load per 25 | CPU(s) number. For example, if you have 4 CPUs and the 5 minutes load is 26 | 1.0, then the warning threshold will be set to 2.8 (0.7 * 4 * 1.0). 27 | 28 | From Glances 3.1.4, if Irix/Solaris mode is off ('0' key), the value is 29 | divided by logical core number and multiple by 100 to have load as a 30 | percentage. 31 | 32 | .. image:: ../_static/loadpercent.png 33 | 34 | A character is also displayed just after the LOAD header and shows the 35 | trend value (for the 1 minute load stat): 36 | 37 | ======== ============================================================== 38 | Trend Status 39 | ======== ============================================================== 40 | ``-`` Mean 15 lasts values equal mean 15 previous values 41 | ``↓`` Mean 15 lasts values is lower mean 15 previous values 42 | ``↑`` Mean 15 lasts values is higher mean 15 previous values 43 | ======== ============================================================== 44 | 45 | Legend: 46 | 47 | ============= ============ 48 | Load avg Status 49 | ============= ============ 50 | ``<0.7*core`` ``OK`` 51 | ``>0.7*core`` ``CAREFUL`` 52 | ``>1*core`` ``WARNING`` 53 | ``>5*core`` ``CRITICAL`` 54 | ============= ============ 55 | 56 | .. note:: 57 | Limit values can be overwritten in the configuration file under 58 | the ``[load]`` section. 59 | 60 | .. _load average: http://nosheep.net/story/defining-unix-load-average/ 61 | .. _load on BSD: http://undeadly.org/cgi?action=article&sid=20090715034920 62 | .. _load on Windows: https://psutil.readthedocs.io/en/latest/#psutil.getloadavg 63 | -------------------------------------------------------------------------------- /docs/aoa/memory.rst: -------------------------------------------------------------------------------- 1 | .. _memory: 2 | 3 | Memory 4 | ====== 5 | 6 | Glances uses two columns: one for the ``RAM`` and one for the ``SWAP``. 7 | 8 | .. image:: ../_static/mem.png 9 | 10 | If enough space is available, Glances displays extended information for 11 | the ``RAM``: 12 | 13 | .. image:: ../_static/mem-wide.png 14 | 15 | Stats description: 16 | 17 | - **percent**: the percentage usage calculated as (total-available)/total*100. 18 | - **total**: total physical memory available. 19 | - **used**: memory used, calculated differently depending on the platform and 20 | designed for informational purposes only. 21 | It's compute as following: 22 | used memory = total - free (with free = available + buffers + cached) 23 | - **free**: memory not being used at all (zeroed) that is readily available; 24 | note that this doesn’t reflect the actual memory available (use ‘available’ 25 | instead). 26 | - **active**: (UNIX): memory currently in use or very recently used, and so it 27 | is in RAM. 28 | - **inactive**: (UNIX): memory that is marked as not used. 29 | - **buffers**: (Linux, BSD): cache for things like file system metadata. 30 | - **cached**: (Linux, BSD): cache for various things. 31 | 32 | Additional stats available in through the API: 33 | 34 | - **available**: the actual amount of available memory that can be given 35 | instantly to processes that request more memory in bytes; this is calculated 36 | by summing different memory values depending on the platform (e.g. free + 37 | buffers + cached on Linux) and it is supposed to be used to monitor actual 38 | memory usage in a cross platform fashion. 39 | - **wired**: (BSD, macOS): memory that is marked to always stay in RAM. It is 40 | never moved to disk. 41 | - **shared**: (BSD): memory that may be simultaneously accessed by multiple 42 | processes. 43 | 44 | A character is also displayed just after the MEM header and shows the 45 | trend value: 46 | 47 | ======== ============================================================== 48 | Trend Status 49 | ======== ============================================================== 50 | ``-`` Mean 15 lasts values equal mean 15 previous values 51 | ``↓`` Mean 15 lasts values is lower mean 15 previous values 52 | ``↑`` Mean 15 lasts values is higher mean 15 previous values 53 | ======== ============================================================== 54 | 55 | Alerts are only set for used memory and used swap. 56 | 57 | Legend: 58 | 59 | ======== ============ 60 | RAM/Swap Status 61 | ======== ============ 62 | ``<50%`` ``OK`` 63 | ``>50%`` ``CAREFUL`` 64 | ``>70%`` ``WARNING`` 65 | ``>90%`` ``CRITICAL`` 66 | ======== ============ 67 | 68 | .. note:: 69 | Limit values can be overwritten in the configuration file under 70 | the ``[memory]`` and/or ``[memswap]`` sections. 71 | -------------------------------------------------------------------------------- /docs/aoa/ports.rst: -------------------------------------------------------------------------------- 1 | .. _ports: 2 | 3 | Ports 4 | ===== 5 | 6 | *Availability: All* 7 | 8 | .. image:: ../_static/ports.png 9 | 10 | This plugin aims at providing a list of hosts/port and URL to scan. 11 | 12 | You can define ``ICMP`` or ``TCP`` ports scans and URL (head only) check. 13 | 14 | The list should be defined in the ``[ports]`` section of the Glances 15 | configuration file. 16 | 17 | .. code-block:: ini 18 | 19 | [ports] 20 | # Ports scanner plugin configuration 21 | # Interval in second between two scans 22 | refresh=30 23 | # Set the default timeout (in second) for a scan (can be overwrite in the scan list) 24 | timeout=3 25 | # If port_default_gateway is True, add the default gateway on top of the scan list 26 | port_default_gateway=True 27 | # 28 | # Define the scan list (1 < x < 255) 29 | # port_x_host (name or IP) is mandatory 30 | # port_x_port (TCP port number) is optional (if not set, use ICMP) 31 | # port_x_description is optional (if not set, define to host:port) 32 | # port_x_timeout is optional and overwrite the default timeout value 33 | # port_x_rtt_warning is optional and defines the warning threshold in ms 34 | # 35 | port_1_host=192.168.0.1 36 | port_1_port=80 37 | port_1_description=Home Box 38 | port_1_timeout=1 39 | port_2_host=www.free.fr 40 | port_2_description=My ISP 41 | port_3_host=www.google.com 42 | port_3_description=Internet ICMP 43 | port_3_rtt_warning=1000 44 | port_4_host=www.google.com 45 | port_4_description=Internet Web 46 | port_4_port=80 47 | port_4_rtt_warning=1000 48 | # 49 | # Define Web (URL) monitoring list (1 < x < 255) 50 | # web_x_url is the URL to monitor (example: http://my.site.com/folder) 51 | # web_x_description is optional (if not set, define to URL) 52 | # web_x_timeout is optional and overwrite the default timeout value 53 | # web_x_rtt_warning is optional and defines the warning respond time in ms (approximately) 54 | # 55 | web_1_url=https://blog.nicolargo.com 56 | web_1_description=My Blog 57 | web_1_rtt_warning=3000 58 | web_2_url=https://github.com 59 | web_3_url=http://www.google.fr 60 | web_3_description=Google Fr 61 | -------------------------------------------------------------------------------- /docs/aoa/quicklook.rst: -------------------------------------------------------------------------------- 1 | .. _quicklook: 2 | 3 | Quick Look 4 | ========== 5 | 6 | The ``quicklook`` plugin is only displayed on wide screen and proposes a 7 | bar view for cpu, memory, swap and load (this list is configurable). 8 | 9 | In the terminal interface, click on ``3`` to enable/disable it. 10 | 11 | .. image:: ../_static/quicklook.png 12 | 13 | If the per CPU mode is on (by clicking the ``1`` key): 14 | 15 | .. image:: ../_static/quicklook-percpu.png 16 | 17 | In the Curses/terminal interface, it is also possible to switch from bar to 18 | sparkline using 'S' hot key or --sparkline command line option (need the 19 | sparklines Python lib on your system). Please be aware that sparklines use 20 | the Glances history and will not be available if the history is disabled 21 | from the command line. For the moment sparkline is not available in 22 | client/server mode (see issue ). 23 | 24 | .. image:: ../_static/sparkline.png 25 | 26 | .. note:: 27 | Limit values can be overwritten in the configuration file under 28 | the ``[quicklook]`` section. 29 | 30 | You can also configure the stats list and the bat character used in the 31 | user interface. 32 | 33 | .. code-block:: ini 34 | 35 | [quicklook] 36 | # Stats list (default is cpu,mem,load) 37 | # Available stats are: cpu,mem,load,swap 38 | list=cpu,mem,load 39 | # Graphical percentage char used in the terminal user interface (default is |) 40 | bar_char=| 41 | -------------------------------------------------------------------------------- /docs/aoa/raid.rst: -------------------------------------------------------------------------------- 1 | .. _raid: 2 | 3 | RAID 4 | ==== 5 | 6 | *Availability: Linux* 7 | 8 | *Dependency: this plugin uses the optional pymdstat Python lib* 9 | 10 | This plugin is disable by default, please use the --enable-plugin raid option 11 | to enable it or enable it in the glances.conf file: 12 | 13 | .. code-block:: ini 14 | 15 | [raid] 16 | # Documentation: https://glances.readthedocs.io/en/latest/aoa/raid.html 17 | # This plugin is disabled by default 18 | disable=False 19 | 20 | In the terminal interface, click on ``R`` to enable/disable it. 21 | 22 | .. image:: ../_static/raid.png 23 | 24 | This plugin is only available on GNU/Linux. 25 | -------------------------------------------------------------------------------- /docs/aoa/sensors.rst: -------------------------------------------------------------------------------- 1 | .. _sensors: 2 | 3 | Sensors 4 | ======= 5 | 6 | *Availability: Linux* 7 | 8 | .. image:: ../_static/sensors.png 9 | 10 | Glances can display the sensors information using ``psutil``, 11 | ``hddtemp`` and ``batinfo``: 12 | - motherboard and CPU temperatures 13 | - hard disk temperature 14 | - battery capacity 15 | 16 | Limit values and sensors alias names can be defined in the configuration 17 | file under the ``[sensors]`` section. 18 | 19 | Limit can be defined for a specific sensor, a type of sensor or defineby the system 20 | thresholds (default behavor). 21 | 22 | .. code-block:: ini 23 | 24 | [sensors] 25 | # Sensors core thresholds (in Celsius...) 26 | # By default values are grabbed from the system 27 | # Overwrite thresholds for a specific sensor 28 | temperature_core_Ambient_careful=45 29 | temperature_core_Ambient_warning=65 30 | temperature_core_Ambient_critical=80 31 | temperature_core_Ambient_log=False 32 | # Overwrite thresholds for a specific type of sensor 33 | #temperature_core_careful=45 34 | #temperature_core_warning=65 35 | #temperature_core_critical=80 36 | 37 | .. note 1:: 38 | The support for multiple batteries is only available if 39 | you have the batinfo Python lib installed on your system 40 | because for the moment PSUtil only support one battery. 41 | 42 | .. note 2:: 43 | If a sensors has temperature and fan speed with the same name unit, 44 | it is possible to alias it using: 45 | alias=unitname_temperature_core_alias:Alias for temp,unitname_fan_speed_alias:Alias for fan speed 46 | 47 | .. note 3:: 48 | If a sensors has multiple identical features names (see #2280), then 49 | Glances will add a suffix to the feature name. 50 | For example, if you have one sensor with two Composite features, the 51 | second one will be named Composite_1. 52 | 53 | .. note 4:: 54 | The plugin could crash on some operating system (FreeBSD) with the 55 | TCP or UDP blackhole option > 0 (see issue #2106). In this case, you 56 | should disable the sensors (--disable-plugin sensors or from the 57 | configuration file). -------------------------------------------------------------------------------- /docs/aoa/smart.rst: -------------------------------------------------------------------------------- 1 | .. _smart: 2 | 3 | SMART 4 | ===== 5 | 6 | *Availability: all but Mac OS* 7 | 8 | *Dependency: this plugin uses the optional pySMART Python lib* 9 | 10 | This plugin is disable by default, please use the --enable-plugin smart option 11 | to enable it. 12 | 13 | .. image:: ../_static/smart.png 14 | 15 | Glances displays all the SMART attributes. 16 | 17 | How to read the information: 18 | 19 | - The first line display the name and model of the device 20 | - The first column is the SMART attribute name 21 | - The second column is the SMART attribute raw value 22 | 23 | .. warning:: 24 | This plugin needs administrator rights. Please run Glances as root/admin. 25 | 26 | Also, you can hide driver using regular expressions. 27 | 28 | To hide device you should use the hide option: 29 | 30 | .. code-block:: ini 31 | 32 | [smart] 33 | hide=.*Hide_this_device.* 34 | 35 | It is also possible to configure a white list of devices to display. 36 | Example to show only the specified drive: 37 | 38 | .. code-block:: ini 39 | 40 | [smart] 41 | show=.*Show_this_device.* 42 | 43 | Filtering is based on regular expression. Please be sure that your regular 44 | expression works as expected. You can use an online tool like `regex101`_ in 45 | order to test your regular expression. 46 | 47 | .. _regex101: https://regex101.com/ -------------------------------------------------------------------------------- /docs/aoa/vms.rst: -------------------------------------------------------------------------------- 1 | .. _vms: 2 | 3 | VMs 4 | === 5 | 6 | Glances ``vms`` plugin is designed to display stats about VMs ran on the host. 7 | 8 | It's actually support two engines: `Multipass` and `Virsh`. 9 | 10 | No Python dependency is needed but Multipass and Virsh binary should be available: 11 | - multipass should be executable from /snap/bin/multipass 12 | - virsh should be executable from /usr/bin/virsh 13 | 14 | Note: CPU information is not availble for Multipass VM. Load is not available for Virsh VM. 15 | 16 | Configuration file options: 17 | 18 | .. code-block:: ini 19 | 20 | [vms] 21 | disable=True 22 | # Define the maximum VMs size name (default is 20 chars) 23 | max_name_size=20 24 | # By default, Glances only display running VMs with states: 25 | # 'Running', 'Paused', 'Starting' or 'Restarting' 26 | # Set the following key to True to display all VMs regarding their states 27 | all=False 28 | 29 | You can use all the variables ({{foo}}) available in the containers plugin. 30 | 31 | Filtering (for hide or show) is based on regular expression. Please be sure that your regular 32 | expression works as expected. You can use an online tool like `regex101`_ in 33 | order to test your regular expression. 34 | 35 | .. _Multipass: https://canonical.com/multipass 36 | .. _Virsh: https://www.libvirt.org/manpages/virsh.html 37 | -------------------------------------------------------------------------------- /docs/aoa/wifi.rst: -------------------------------------------------------------------------------- 1 | .. _wifi: 2 | 3 | Wi-Fi 4 | ===== 5 | 6 | *Availability: Linux (with an /proc/net/wireless file) only* 7 | 8 | .. image:: ../_static/wifi.png 9 | 10 | In the configuration file, you can define signal quality thresholds: 11 | 12 | - ``"Poor"`` quality is between -100 and -85dBm 13 | - ``"Good"`` quality between -85 and -60dBm 14 | - ``"Excellent"`` between -60 and -40dBm 15 | 16 | Thresholds for the signal quality can be defined in the configuration file: 17 | 18 | .. code-block:: ini 19 | 20 | [wifi] 21 | disable=False 22 | careful=-65 23 | warning=-75 24 | critical=-85 25 | 26 | You can disable this plugin using the ``--disable-plugin wifi`` option or by 27 | hitting the ``W`` key from the user interface. 28 | -------------------------------------------------------------------------------- /docs/build.sh: -------------------------------------------------------------------------------- 1 | make html 2 | LC_ALL=C make man 3 | -------------------------------------------------------------------------------- /docs/dev/README.txt: -------------------------------------------------------------------------------- 1 | Glances profiling 2 | ================= 3 | 4 | First install Sphinx and the RTD theme: 5 | 6 | apt install graphviz 7 | pip install gprof2dot 8 | 9 | Then generate the profiling diagram: 10 | 11 | cd 12 | python -m cProfile -o /tmp/glances.pstats ./glances/__main__.py 13 | gprof2dot -f pstats /tmp/glances.pstats | dot -Tpng -o /tmp/glances-cprofile.png 14 | 15 | Example: 16 | 17 | .. image:: https://raw.githubusercontent.com/nicolargo/glances/develop/docs/dev/glances-cprofile.png 18 | -------------------------------------------------------------------------------- /docs/dev/glances-cprofile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/dev/glances-cprofile.png -------------------------------------------------------------------------------- /docs/faq.rst: -------------------------------------------------------------------------------- 1 | .. _faq: 2 | 3 | F.A.Q 4 | ===== 5 | 6 | Any encoding issue ? 7 | -------------------- 8 | 9 | Try to run Glances with the following command line: 10 | 11 | LANG=en_US.UTF-8 LC_ALL= glances 12 | 13 | Container memory stats not displayed ? 14 | -------------------------------------- 15 | 16 | On ARM64, Docker needs to be configured to allow access to the memory stats. 17 | 18 | Edit the /boot/firmware/cmdline.txt and add the following configuration key: 19 | 20 | cgroup_enable=memory 21 | -------------------------------------------------------------------------------- /docs/glances.rst: -------------------------------------------------------------------------------- 1 | :orphan: 2 | 3 | glances 4 | ======= 5 | 6 | SYNOPSIS 7 | -------- 8 | 9 | **glances** [OPTIONS] 10 | 11 | DESCRIPTION 12 | ----------- 13 | 14 | **glances** is a cross-platform curses-based monitoring tool that aims 15 | to present a maximum of information in a minimum of space, ideally fitting 16 | in a classic 80x24 terminal or larger for more details. It can adapt 17 | dynamically to the displayed information depending on the terminal size. 18 | It can also work in client/server mode. 19 | Remote monitoring can be performed via a terminal or web interface. 20 | 21 | **glances** is written in Python and uses the *psutil* library to get 22 | information from your system. 23 | 24 | OPTIONS 25 | ------- 26 | 27 | .. include:: cmds.rst 28 | 29 | CONFIGURATION 30 | ------------- 31 | 32 | .. include:: config.rst 33 | 34 | EXAMPLES 35 | -------- 36 | 37 | Monitor local machine, also called standalone mode, 38 | with the Text-based user interface (TUI): 39 | 40 | $ glances 41 | 42 | To monitor the local machine with the Web user interface (WebUI), 43 | , run the following command line: 44 | 45 | $ glances -w 46 | 47 | then, open a Web Browser to the provided URL. 48 | 49 | Monitor local machine and export stats to a CSV file: 50 | 51 | $ glances --export csv --export-csv-file /tmp/glances.csv 52 | 53 | Monitor local machine and export stats to an InfluxDB server with 5s 54 | refresh time (also possible to export to OpenTSDB, Cassandra, Statsd, 55 | ElasticSearch, RabbitMQ, and Riemann): 56 | 57 | $ glances -t 5 --export influxdb 58 | 59 | It is also possible to export stats to multiple endpoints: 60 | 61 | $ glances -t 5 --export influxdb,statsd,csv 62 | 63 | Start a Glances server (server mode): 64 | 65 | $ glances -s 66 | 67 | Connect Glances to a Glances server (client mode): 68 | 69 | $ glances -c 70 | 71 | Connect to a Glances server and export stats to a StatsD server: 72 | 73 | $ glances -c --export statsd 74 | 75 | Start the TUI Central Glances Browser: 76 | 77 | $ glances --browser 78 | 79 | Start the WebUI Central Glances Browser (new in Glances 4.3 or higher): 80 | 81 | $ glances --browser -w 82 | 83 | If you do not want to see the local Glances Web Server in the browser list please use --disable-autodiscover option. 84 | 85 | AUTHOR 86 | ------ 87 | 88 | Nicolas Hennion aka Nicolargo 89 | -------------------------------------------------------------------------------- /docs/gw/cassandra.rst: -------------------------------------------------------------------------------- 1 | .. _cassandra: 2 | 3 | Cassandra 4 | ========= 5 | 6 | You can export statistics to a ``Cassandra`` or ``Scylla`` server. 7 | The connection should be defined in the Glances configuration file as 8 | following: 9 | 10 | .. code-block:: ini 11 | 12 | [cassandra] 13 | host=localhost 14 | port=9042 15 | protocol_version=3 16 | keyspace=glances 17 | replication_factor=2 18 | table=localhost 19 | 20 | and run Glances with: 21 | 22 | .. code-block:: console 23 | 24 | $ glances --export cassandra 25 | 26 | The data model is the following: 27 | 28 | .. code-block:: ini 29 | 30 | CREATE TABLE (plugin text, time timeuuid, stat map, PRIMARY KEY (plugin, time)) 31 | 32 | Only numerical stats are stored in the Cassandra table. All the stats 33 | are converted to float. If a stat cannot be converted to float, it is 34 | not stored in the database. 35 | -------------------------------------------------------------------------------- /docs/gw/couchdb.rst: -------------------------------------------------------------------------------- 1 | .. _couchdb: 2 | 3 | CouchDB 4 | ======= 5 | 6 | You can export statistics to a ``CouchDB`` server. 7 | The connection should be defined in the Glances configuration file as 8 | following: 9 | 10 | .. code-block:: ini 11 | 12 | [couchdb] 13 | host=localhost 14 | port=5984 15 | db=glances 16 | user=root 17 | password=example 18 | 19 | and run Glances with: 20 | 21 | .. code-block:: console 22 | 23 | $ glances --export couchdb 24 | 25 | Documents are stored in native ``JSON`` format. Glances adds ``"type"`` 26 | and ``"time"`` entries: 27 | 28 | - ``type``: plugin name 29 | - ``time``: timestamp (format: "2016-09-24T16:39:08.524Z") 30 | 31 | Example of Couch Document for the load stats: 32 | 33 | .. code-block:: json 34 | 35 | { 36 | "_id": "36cbbad81453c53ef08804cb2612d5b6", 37 | "_rev": "1-382400899bec5615cabb99aa34df49fb", 38 | "min15": 0.33, 39 | "time": "2016-09-24T16:39:08.524Z", 40 | "min5": 0.4, 41 | "cpucore": 4, 42 | "load_warning": 1, 43 | "min1": 0.5, 44 | "history_size": 28800, 45 | "load_critical": 5, 46 | "type": "load", 47 | "load_careful": 0.7 48 | } 49 | 50 | You can view the result using the CouchDB utils URL: http://127.0.0.1:5984/_utils/database.html?glances. 51 | -------------------------------------------------------------------------------- /docs/gw/csv.rst: -------------------------------------------------------------------------------- 1 | .. _csv: 2 | 3 | CSV 4 | === 5 | 6 | It's possible to export stats to a CSV file. 7 | 8 | .. code-block:: console 9 | 10 | $ glances --export csv --export-csv-file /tmp/glances.csv --quiet 11 | 12 | CSV file description: 13 | 14 | - first line: Stats description (header) 15 | - others lines: Stats (data) 16 | 17 | By default, data will be append any existing CSV file (if header are compliant). 18 | 19 | If the header did not match with a previous one, an error is logged. 20 | 21 | The --export-csv-overwrite tag should be used if you want to delete the existing CSV file when Glances starts. 22 | 23 | It is possible to remove some exported data using the --disable-plugin tag: 24 | 25 | $ glances --export csv --export-csv-file /tmp/glances.csv --disable-plugin load,swap --quiet 26 | 27 | or by only enable some plugins: 28 | 29 | $ glances --export csv --export-csv-file /tmp/glances.csv --disable-plugin all --enable-plugin cpu,mem,load --quiet 30 | -------------------------------------------------------------------------------- /docs/gw/elastic.rst: -------------------------------------------------------------------------------- 1 | .. _elastic: 2 | 3 | Elasticsearch 4 | ============= 5 | .. note:: 6 | You need to install the `elasticsearch`_ library on your system. 7 | 8 | You can export statistics to an ``Elasticsearch`` server. The connection 9 | should be defined in the Glances configuration file as following: 10 | 11 | .. code-block:: ini 12 | 13 | [elasticsearch] 14 | host=localhost 15 | port=9200 16 | index=glances 17 | 18 | and run Glances with: 19 | 20 | .. code-block:: console 21 | 22 | $ glances --export elasticsearch 23 | 24 | .. _elasticsearch: https://pypi.org/project/elasticsearch/ 25 | -------------------------------------------------------------------------------- /docs/gw/graph.rst: -------------------------------------------------------------------------------- 1 | .. _graph: 2 | 3 | Graph 4 | ====== 5 | 6 | You can generate dynamic graphs (SVG format) in a target folder. The generation 7 | starts every time the 'g' key is pressed in the CLI interface (if Glances has been 8 | started with the --export graph option). 9 | 10 | The graph export module can be configured through the Glances configuration file: 11 | 12 | .. code-block:: ini 13 | 14 | [graph] 15 | # Configuration for the --export graph option 16 | # Set the path where the graph (.svg files) will be created 17 | # Can be overwrite by the --graph-path command line option 18 | path=/tmp 19 | # It is possible to generate the graphs automatically by setting the 20 | # generate_every to a non zero value corresponding to the seconds between 21 | # two generation. Set it to 0 to disable graph auto generation. 22 | generate_every=60 23 | # See following configuration keys definitions in the Pygal lib documentation 24 | # http://pygal.org/en/stable/documentation/index.html 25 | width=800 26 | height=600 27 | style=DarkStyle 28 | 29 | and run Glances with: 30 | 31 | .. code-block:: console 32 | 33 | $ glances --export graph --export-graph-path /tmp 34 | 35 | Example of output (load graph) 36 | 37 | .. image:: ../_static/graph-load.svg 38 | -------------------------------------------------------------------------------- /docs/gw/graphite.rst: -------------------------------------------------------------------------------- 1 | .. _graphite: 2 | 3 | Graphite 4 | ======== 5 | 6 | You can export statistics to a ``Graphite`` server (time series server). 7 | 8 | The connection should be defined in the Glances configuration file as 9 | following: 10 | 11 | .. code-block:: ini 12 | 13 | [graphite] 14 | host=localhost 15 | port=2003 16 | # Prefix will be added for all measurement name 17 | # Ex: prefix=foo 18 | # => foo.cpu 19 | # => foo.mem 20 | # You can also use dynamic values 21 | #prefix=`hostname` 22 | prefix=glances 23 | 24 | and run Glances with: 25 | 26 | .. code-block:: console 27 | 28 | $ glances --export graphite 29 | 30 | Note 1: the port defines the TCP port where the Graphite listen plain-text requests. 31 | 32 | Note 2: As many time-series database, only integer and float are supported in the Graphite datamodel. 33 | 34 | Note 3: Under the wood, Glances uses GraphiteSender Python lib (https://github.com/NicoAdrian/graphitesender). 35 | -------------------------------------------------------------------------------- /docs/gw/index.rst: -------------------------------------------------------------------------------- 1 | .. _gw: 2 | 3 | Gateway To Other Services 4 | ========================= 5 | 6 | Glances can exports stats to a CSV file. Also, it can act as a gateway 7 | to providing stats to multiple services (see list below). 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | 12 | csv 13 | cassandra 14 | couchdb 15 | elastic 16 | graph 17 | influxdb 18 | json 19 | kafka 20 | mqtt 21 | mongodb 22 | opentsdb 23 | prometheus 24 | rabbitmq 25 | restful 26 | riemann 27 | statsd 28 | zeromq 29 | -------------------------------------------------------------------------------- /docs/gw/json.rst: -------------------------------------------------------------------------------- 1 | .. _json: 2 | 3 | JSON 4 | ==== 5 | 6 | It's possible to export stats to a JSON file. 7 | 8 | .. code-block:: console 9 | 10 | $ glances --export json --export-json-file /tmp/glances.json 11 | -------------------------------------------------------------------------------- /docs/gw/kafka.rst: -------------------------------------------------------------------------------- 1 | .. _kafka: 2 | 3 | Kafka 4 | ===== 5 | 6 | You can export statistics to a ``Kafka`` server. 7 | The connection should be defined in the Glances configuration file as 8 | following: 9 | 10 | .. code-block:: ini 11 | 12 | [kafka] 13 | host=localhost 14 | port=9092 15 | topic=glances 16 | #compression=gzip 17 | # Tags will be added for all events 18 | #tags=foo:bar,spam:eggs 19 | # You can also use dynamic values 20 | #tags=hostname:`hostname -f` 21 | 22 | Note: you can enable the compression but it consume CPU on your host. 23 | 24 | and run Glances with: 25 | 26 | .. code-block:: console 27 | 28 | $ glances --export kafka 29 | 30 | Stats are sent in native ``JSON`` format to the topic: 31 | 32 | - ``key``: plugin name 33 | - ``value``: JSON dict 34 | 35 | Example of record for the memory plugin: 36 | 37 | .. code-block:: ini 38 | 39 | ConsumerRecord(topic=u'glances', partition=0, offset=1305, timestamp=1490460592248, timestamp_type=0, key='mem', value=u'{"available": 2094710784, "used": 5777428480, "cached": 2513543168, "mem_careful": 50.0, "percent": 73.4, "free": 2094710784, "mem_critical": 90.0, "inactive": 2361626624, "shared": 475504640, "history_size": 28800.0, "mem_warning": 70.0, "total": 7872139264, "active": 4834361344, "buffers": 160112640}', checksum=214895201, serialized_key_size=3, serialized_value_size=303) 40 | 41 | Python code example to consume Kafka Glances plugin: 42 | 43 | .. code-block:: python 44 | 45 | from kafka import KafkaConsumer 46 | import json 47 | 48 | consumer = KafkaConsumer('glances', value_deserializer=json.loads) 49 | for s in consumer: 50 | print(s) 51 | -------------------------------------------------------------------------------- /docs/gw/mongodb.rst: -------------------------------------------------------------------------------- 1 | .. _couchdb: 2 | 3 | MongoDB 4 | ======= 5 | 6 | You can export statistics to a ``MongoDB`` server. 7 | The connection should be defined in the Glances configuration file as 8 | following: 9 | 10 | .. code-block:: ini 11 | 12 | [mongodb] 13 | host=localhost 14 | port=27017 15 | db=glances 16 | user=root 17 | password=example 18 | 19 | and run Glances with: 20 | 21 | .. code-block:: console 22 | 23 | $ glances --export mongodb 24 | 25 | Documents are stored in native the configured database (glances by default) 26 | with one collection per plugin. 27 | 28 | Example of MongoDB Document for the load stats: 29 | 30 | .. code-block:: json 31 | 32 | { 33 | _id: ObjectId('63d78ffee5528e543ce5af3a'), 34 | min1: 1.46337890625, 35 | min5: 1.09619140625, 36 | min15: 1.07275390625, 37 | cpucore: 4, 38 | history_size: 1200, 39 | load_disable: 'False', 40 | load_careful: 0.7, 41 | load_warning: 1, 42 | load_critical: 5 43 | } 44 | -------------------------------------------------------------------------------- /docs/gw/mqtt.rst: -------------------------------------------------------------------------------- 1 | .. _mqtt: 2 | 3 | MQTT 4 | ======== 5 | 6 | You can export statistics to an ``MQTT`` server. The 7 | connection should be defined in the Glances configuration file as 8 | following: 9 | 10 | .. code-block:: ini 11 | 12 | [mqtt] 13 | host=localhost 14 | # Overwrite device name in the topic (see detail in PR#2701) 15 | #devicename=localhost 16 | port=883 17 | tls=true 18 | user=glances 19 | password=glances 20 | topic=glances 21 | topic_structure=per-metric 22 | callback_api_version=2 23 | 24 | and run Glances with: 25 | 26 | .. code-block:: console 27 | 28 | $ glances --export mqtt 29 | 30 | The topic_structure field aims at configuring the way stats are exported to MQTT (see #1798): 31 | - per-metric: one event per metric (default behavior) 32 | - per-plugin: one event per plugin 33 | -------------------------------------------------------------------------------- /docs/gw/opentsdb.rst: -------------------------------------------------------------------------------- 1 | .. _opentsdb: 2 | 3 | OpenTSDB 4 | ======== 5 | 6 | You can export statistics to an ``OpenTSDB`` server (time series server). 7 | The connection should be defined in the Glances configuration file as 8 | following: 9 | 10 | .. code-block:: ini 11 | 12 | [opentsdb] 13 | host=localhost 14 | port=4242 15 | prefix=glances 16 | tags=foo:bar,spam:eggs 17 | 18 | and run Glances with: 19 | 20 | .. code-block:: console 21 | 22 | $ glances --export opentsdb 23 | -------------------------------------------------------------------------------- /docs/gw/prometheus.rst: -------------------------------------------------------------------------------- 1 | .. _prometheus: 2 | 3 | Prometheus 4 | ========== 5 | 6 | You can export statistics to a ``Prometheus`` server through an exporter. 7 | When the *--export prometheus* is used, Glances creates a Prometheus exporter 8 | listening on (defined in the Glances configuration file). 9 | 10 | .. code-block:: ini 11 | 12 | [prometheus] 13 | host=localhost 14 | port=9091 15 | prefix=glances 16 | labels=src:glances 17 | 18 | .. note:: 19 | 20 | When running Glances in a container, set ``host=0.0.0.0`` in the Glances configuration file. 21 | 22 | .. note:: 23 | 24 | You can use dynamic fields for the label (ex: labels=system:`uname -s`) 25 | 26 | and run Glances with: 27 | 28 | .. code-block:: console 29 | 30 | $ glances --export prometheus 31 | 32 | You can check that Glances exports the stats using this URL: http://localhost:9091 33 | 34 | .. image:: ../_static/prometheus_exporter.png 35 | 36 | In order to store the metrics in a Prometheus server, you should add this 37 | exporter to your Prometheus server configuration with the following lines 38 | (in the prometheus.yml configuration file): 39 | 40 | .. code-block:: ini 41 | 42 | scrape_configs: 43 | - job_name: 'glances_exporter' 44 | scrape_interval: 5s 45 | static_configs: 46 | - targets: ['localhost:9091'] 47 | 48 | .. image:: ../_static/prometheus_server.png 49 | -------------------------------------------------------------------------------- /docs/gw/rabbitmq.rst: -------------------------------------------------------------------------------- 1 | .. _rabbitmq: 2 | 3 | RabbitMQ 4 | ======== 5 | 6 | You can export statistics to an ``RabbitMQ`` server (AMQP Broker). The 7 | connection should be defined in the Glances configuration file as 8 | following: 9 | 10 | .. code-block:: ini 11 | 12 | [rabbitmq] 13 | host=localhost 14 | port=5672 15 | user=glances 16 | password=glances 17 | queue=glances_queue 18 | #protocol=amqps 19 | 20 | and run Glances with: 21 | 22 | .. code-block:: console 23 | 24 | $ glances --export rabbitmq 25 | -------------------------------------------------------------------------------- /docs/gw/restful.rst: -------------------------------------------------------------------------------- 1 | .. _restful: 2 | 3 | RESTful 4 | ======= 5 | 6 | You can export statistics to a ``RESTful`` JSON server. All the available stats 7 | will be exported in one big (~15 KB) POST request to the RESTful endpoint. 8 | 9 | The RESTful endpoint should be defined in the Glances configuration file as 10 | following: 11 | 12 | .. code-block:: ini 13 | 14 | [restful] 15 | # Configuration for the --export-restful option 16 | # Example, export to http://localhost:6789/ 17 | host=localhost 18 | port=6789 19 | protocol=http 20 | path=/ 21 | 22 | URL Syntax: 23 | 24 | .. code-block:: ini 25 | 26 | http://localhost:6789/ 27 | | | | | 28 | | | | path 29 | | | port 30 | | host 31 | protocol 32 | 33 | and run Glances with: 34 | 35 | .. code-block:: console 36 | 37 | $ glances --export restful 38 | 39 | Glances will generate stats as a big JSON dictionary (see example `here`_). 40 | 41 | 42 | .. _here: https://pastebin.com/7U3vXqvF 43 | -------------------------------------------------------------------------------- /docs/gw/riemann.rst: -------------------------------------------------------------------------------- 1 | .. _riemann: 2 | 3 | Riemann 4 | ======= 5 | 6 | You can export statistics to a ``Riemann`` server (using TCP protocol). 7 | The connection should be defined in the Glances configuration file as 8 | following: 9 | 10 | .. code-block:: ini 11 | 12 | [riemann] 13 | host=localhost 14 | port=5555 15 | 16 | and run Glances with: 17 | 18 | .. code-block:: console 19 | 20 | $ glances --export riemann 21 | -------------------------------------------------------------------------------- /docs/gw/statsd.rst: -------------------------------------------------------------------------------- 1 | .. _statsd: 2 | 3 | StatsD 4 | ====== 5 | 6 | You can export statistics to a ``StatsD`` server (welcome to Graphite!). 7 | The connection should be defined in the Glances configuration file as 8 | following: 9 | 10 | .. code-block:: ini 11 | 12 | [statsd] 13 | host=localhost 14 | port=8125 15 | prefix=glances 16 | 17 | .. note:: The ``prefix`` is optional (``glances`` by default) 18 | 19 | and run Glances with: 20 | 21 | .. code-block:: console 22 | 23 | $ glances --export statsd 24 | 25 | Glances will generate stats as: 26 | 27 | :: 28 | 29 | 'glances.cpu.user': 12.5, 30 | 'glances.cpu.total': 14.9, 31 | 'glances.load.cpucore': 4, 32 | 'glances.load.min1': 0.19, 33 | ... 34 | -------------------------------------------------------------------------------- /docs/gw/zeromq.rst: -------------------------------------------------------------------------------- 1 | .. _zeromq: 2 | 3 | ZeroMQ 4 | ====== 5 | 6 | You can export statistics to a ``ZeroMQ`` server. 7 | 8 | The connection should be defined in the Glances configuration file as 9 | following: 10 | 11 | .. code-block:: ini 12 | 13 | [zeromq] 14 | host=127.0.0.1 15 | port=5678 16 | prefix=G 17 | 18 | Glances `envelopes`_ the stats before publishing it. The message is 19 | composed of three frames: 20 | 21 | 1. the prefix configured in the [zeromq] section (as STRING) 22 | 2. the Glances plugin name (as STRING) 23 | 3. the Glances plugin stats (as JSON) 24 | 25 | Run Glances with: 26 | 27 | .. code-block:: console 28 | 29 | $ glances --export zeromq 30 | 31 | Following is a simple Python client to subscribe to the Glances stats: 32 | 33 | .. code-block:: python 34 | 35 | # -*- coding: utf-8 -*- 36 | # 37 | # ZeroMQ subscriber for Glances 38 | # 39 | 40 | import json 41 | import zmq 42 | 43 | context = zmq.Context() 44 | 45 | subscriber = context.socket(zmq.SUB) 46 | subscriber.setsockopt(zmq.SUBSCRIBE, 'G') 47 | subscriber.connect("tcp://127.0.0.1:5678") 48 | 49 | while True: 50 | _, plugin, data_raw = subscriber.recv_multipart() 51 | data = json.loads(data_raw) 52 | print('{} => {}'.format(plugin, data)) 53 | 54 | subscriber.close() 55 | context.term() 56 | 57 | .. _envelopes: http://zguide.zeromq.org/page:all#Pub-Sub-Message-Envelopes 58 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | Glances 2 | ======= 3 | 4 | .. image:: _static/screenshot-wide.png 5 | 6 | Glances is a cross-platform monitoring tool that aims to present 7 | maximum information in minimal space through either a curses-based 8 | or Web-based interface. It can dynamically adapt the displayed 9 | information depending on the terminal size. 10 | 11 | It can also work in client/server mode. Remote monitoring can be 12 | done via terminal, Web interface, or API (XMLRPC and RESTful). 13 | 14 | Glances is written in Python and uses the `psutil`_ library to get 15 | information from your system. 16 | 17 | Stats can also be exported to external time/value databases. 18 | 19 | .. _psutil: https://github.com/giampaolo/psutil 20 | 21 | Table of Contents 22 | ================= 23 | 24 | .. toctree:: 25 | :maxdepth: 2 26 | 27 | install 28 | quickstart 29 | cmds 30 | config 31 | aoa/index 32 | gw/index 33 | api 34 | docker 35 | faq 36 | support 37 | -------------------------------------------------------------------------------- /docs/install.rst: -------------------------------------------------------------------------------- 1 | .. _install: 2 | 3 | Install 4 | ======= 5 | 6 | Glances is available on ``PyPI``. By using PyPI, you are sure to have the 7 | latest stable version. 8 | 9 | To install, simply use ``pip``: 10 | 11 | .. code-block:: console 12 | 13 | pip install glances 14 | 15 | *Note*: Python headers are required to install `psutil`_. For instance, 16 | on Debian/Ubuntu, you must first install the *python-dev* package. 17 | On Fedora/CentOS/RHEL, first, install the *python-devel* package. For Windows, 18 | psutil can be installed from the binary installation file. 19 | 20 | You can also install the following libraries to use the optional 21 | features (such as the web interface, export modules, etc.): 22 | 23 | .. code-block:: console 24 | 25 | pip install glances[all] 26 | 27 | To upgrade Glances and all its dependencies to the latest versions: 28 | 29 | .. code-block:: console 30 | 31 | pip install --upgrade glances 32 | pip install --upgrade psutil 33 | pip install --upgrade glances[all] 34 | 35 | For additional installation methods, read the official `README`_ file. 36 | 37 | Shell tab completion 38 | ==================== 39 | 40 | Glances 4.3.2 and higher includes shell tab autocompletion thanks to the --print-completion option. 41 | 42 | For example, on a Linux operating system with Bash shell: 43 | 44 | .. code-block:: console 45 | 46 | $ glances --print-completion bash | sudo tee -a /etc/bash_completion.d/glances 47 | $ source /etc/bash_completion.d/glances 48 | 49 | Following shells are supported: bash, zsh and tcsh. 50 | 51 | .. _psutil: https://github.com/giampaolo/psutil 52 | .. _README: https://github.com/nicolargo/glances/blob/master/README.rst 53 | -------------------------------------------------------------------------------- /docs/objects.inv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/docs/objects.inv -------------------------------------------------------------------------------- /docs/support.rst: -------------------------------------------------------------------------------- 1 | .. _support: 2 | 3 | Support 4 | ======= 5 | 6 | To post a question about Glances use cases, please post it to the 7 | official Q&A `forum 8 | `_. 9 | 10 | To report a bug or a feature request, use the GitHub `issue 11 | `_ tracker. 12 | 13 | Feel free to contribute! 14 | -------------------------------------------------------------------------------- /glances/README.txt: -------------------------------------------------------------------------------- 1 | You are in the main Glances source folder. This page is **ONLY** for developers. 2 | 3 | If you are looking for the user manual, please follow this link: 4 | https://glances.readthedocs.io/en/stable/ 5 | -------------------------------------------------------------------------------- /glances/__main__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Glances - An eye on your system 3 | # 4 | # SPDX-FileCopyrightText: 2022 Nicolas Hennion 5 | # 6 | # SPDX-License-Identifier: LGPL-3.0-only 7 | # 8 | 9 | """Allow user to run Glances as a module.""" 10 | 11 | # Execute with: 12 | # $ python -m glances (2.7+) 13 | 14 | import glances 15 | 16 | if __name__ == '__main__': 17 | glances.main() 18 | -------------------------------------------------------------------------------- /glances/amps/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/glances/amps/__init__.py -------------------------------------------------------------------------------- /glances/amps/default/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Glances. 3 | # 4 | # SPDX-FileCopyrightText: 2022 Nicolas Hennion 5 | # 6 | # SPDX-License-Identifier: LGPL-3.0-only 7 | # 8 | 9 | r""" 10 | Default AMP 11 | ========= 12 | 13 | Monitor a process by executing a command line. This is the default AMP's behavior 14 | if no AMP script is found. 15 | 16 | Configuration file example 17 | -------------------------- 18 | 19 | [amp_foo] 20 | enable=true 21 | regex=\/usr\/bin\/foo 22 | refresh=10 23 | one_line=false 24 | command=foo status 25 | """ 26 | 27 | from glances.amps.amp import GlancesAmp 28 | from glances.logger import logger 29 | from glances.secure import secure_popen 30 | 31 | 32 | class Amp(GlancesAmp): 33 | """Glances' Default AMP.""" 34 | 35 | NAME = '' 36 | VERSION = '1.1' 37 | DESCRIPTION = '' 38 | AUTHOR = 'Nicolargo' 39 | EMAIL = 'contact@nicolargo.com' 40 | 41 | def __init__(self, name=None, args=None): 42 | """Init the AMP.""" 43 | self.NAME = name.capitalize() 44 | super().__init__(name=name, args=args) 45 | 46 | def update(self, process_list): 47 | """Update the AMP""" 48 | # Get the systemctl status 49 | logger.debug('{}: Update AMP stats using command {}'.format(self.NAME, self.get('service_cmd'))) 50 | # Get command to execute 51 | try: 52 | res = self.get('command') 53 | except OSError as e: 54 | logger.debug(f'{self.NAME}: Error while executing command ({e})') 55 | return self.result() 56 | # No command found, use default message 57 | if res is None: 58 | # Set the default message if command return None 59 | # Default sum of CPU and MEM for the matching regex 60 | self.set_result( 61 | 'CPU: {:.1f}% | MEM: {:.1f}%'.format( 62 | sum([p['cpu_percent'] for p in process_list]), sum([p['memory_percent'] for p in process_list]) 63 | ) 64 | ) 65 | return self.result() 66 | # Run command(s) 67 | # Comma separated commands can be executed 68 | try: 69 | self.set_result(secure_popen(res).rstrip()) 70 | except Exception as e: 71 | self.set_result(e.output) 72 | return self.result() 73 | -------------------------------------------------------------------------------- /glances/amps/systemv/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Glances. 3 | # 4 | # SPDX-FileCopyrightText: 2022 Nicolas Hennion 5 | # 6 | # SPDX-License-Identifier: LGPL-3.0-only 7 | # 8 | 9 | r""" 10 | SystemV AMP 11 | =========== 12 | 13 | Monitor the state of the System V init system and service. 14 | 15 | How to read the stats 16 | --------------------- 17 | 18 | Running: Number of running services. 19 | Stopped: Number of stopped services. 20 | Upstart: Number of service managed by Upstart. 21 | 22 | Source reference: http://askubuntu.com/questions/407075/how-to-read-service-status-all-results 23 | 24 | Configuration file example 25 | -------------------------- 26 | 27 | [amp_systemv] 28 | # Systemv 29 | enable=true 30 | regex=\/sbin\/init 31 | refresh=60 32 | one_line=true 33 | service_cmd=/usr/bin/service --status-all 34 | """ 35 | 36 | from glances.amps.amp import GlancesAmp 37 | from glances.logger import logger 38 | from glances.secure import secure_popen 39 | 40 | 41 | class Amp(GlancesAmp): 42 | """Glances' Systemd AMP.""" 43 | 44 | NAME = 'SystemV' 45 | VERSION = '1.1' 46 | DESCRIPTION = 'Get services list from service (initd)' 47 | AUTHOR = 'Nicolargo' 48 | EMAIL = 'contact@nicolargo.com' 49 | 50 | # def __init__(self, args=None): 51 | # """Init the AMP.""" 52 | # super(Amp, self).__init__(args=args) 53 | 54 | def update(self, process_list): 55 | """Update the AMP""" 56 | # Get the systemctl status 57 | logger.debug('{}: Update stats using service {}'.format(self.NAME, self.get('service_cmd'))) 58 | try: 59 | # res = check_output(self.get('service_cmd').split(), stderr=STDOUT).decode('utf-8') 60 | res = secure_popen(self.get('service_cmd')) 61 | except Exception as e: 62 | logger.debug(f'{self.NAME}: Error while executing service ({e})') 63 | else: 64 | status = {'running': 0, 'stopped': 0, 'upstart': 0} 65 | # For each line 66 | for r in res.split('\n'): 67 | # Split per space .* 68 | line = r.split() 69 | if len(line) < 4: 70 | continue 71 | if line[1] == '+': 72 | status['running'] += 1 73 | elif line[1] == '-': 74 | status['stopped'] += 1 75 | elif line[1] == '?': 76 | status['upstart'] += 1 77 | # Build the output (string) message 78 | output = 'Services\n' 79 | for k, v in status.items(): 80 | output += f'{k}: {v}\n' 81 | self.set_result(output, separator=' ') 82 | 83 | return self.result() 84 | -------------------------------------------------------------------------------- /glances/exports/README.rst: -------------------------------------------------------------------------------- 1 | =============== 2 | Glances experts 3 | =============== 4 | 5 | This is the Glances exporters folder. 6 | 7 | A Glances exporter is a Python module hosted in a folder. 8 | 9 | The name of the foo Glances exporter folder is foo (glances_foo). 10 | 11 | The exporter is a Python class named Export inherits the GlancesExport object: 12 | 13 | .. code-block:: python 14 | 15 | class Export(GlancesExport): 16 | """Glances foo exporter.""" 17 | 18 | def __init__(self, args=None, config=None): 19 | super(Export, self).__init__(config=config, args=args) 20 | pass 21 | 22 | A plugin should implement the following methods: 23 | 24 | - export(): export the self.stats variable to the exporter destination. 25 | 26 | Have a look of all Glances exporter's methods in the export.py file. 27 | -------------------------------------------------------------------------------- /glances/exports/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/glances/exports/__init__.py -------------------------------------------------------------------------------- /glances/exports/glances_json/__init__.py: -------------------------------------------------------------------------------- 1 | """JSON interface class.""" 2 | 3 | import sys 4 | 5 | from glances.exports.export import GlancesExport 6 | from glances.globals import json_dumps, listkeys 7 | from glances.logger import logger 8 | 9 | 10 | class Export(GlancesExport): 11 | """This class manages the JSON export module.""" 12 | 13 | def __init__(self, config=None, args=None): 14 | """Init the JSON export IF.""" 15 | super().__init__(config=config, args=args) 16 | 17 | # JSON file name 18 | self.json_filename = args.export_json_file 19 | 20 | # Set the JSON output file 21 | try: 22 | self.json_file = open(self.json_filename, 'w') 23 | self.json_file.close() 24 | except OSError as e: 25 | logger.critical(f"Cannot create the JSON file: {e}") 26 | sys.exit(2) 27 | 28 | logger.info(f"Exporting stats to file: {self.json_filename}") 29 | 30 | self.export_enable = True 31 | 32 | # Buffer for dict of stats 33 | self.buffer = {} 34 | 35 | def exit(self): 36 | """Close the JSON file.""" 37 | logger.debug(f"Finalise export interface {self.export_name}") 38 | self.json_file.close() 39 | 40 | def export(self, name, columns, points): 41 | """Export the stats to the JSON file.""" 42 | 43 | # Check for completion of loop for all exports 44 | if name == self.last_exported_list()[0] and self.buffer != {}: 45 | # One whole loop has been completed 46 | # Flush stats to file 47 | logger.debug(f"Exporting stats ({listkeys(self.buffer)}) to JSON file ({self.json_filename})") 48 | 49 | # Export stats to JSON file 50 | with open(self.json_filename, "wb") as self.json_file: 51 | try: 52 | self.json_file.write(json_dumps(self.buffer) + b'\n') 53 | except Exception as e: 54 | logger.error(f'Can not export data to JSON ({e})') 55 | 56 | # Reset buffer 57 | self.buffer = {} 58 | 59 | # Add current stat to the buffer 60 | self.buffer[name] = dict(zip(columns, points)) 61 | -------------------------------------------------------------------------------- /glances/exports/glances_mongodb/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Glances. 3 | # 4 | # SPDX-FileCopyrightText: 2024 Nicolas Hennion 5 | # 6 | # SPDX-License-Identifier: LGPL-3.0-only 7 | # 8 | 9 | """MongoDB interface class.""" 10 | 11 | import sys 12 | from urllib.parse import quote_plus 13 | 14 | import pymongo 15 | 16 | from glances.exports.export import GlancesExport 17 | from glances.logger import logger 18 | 19 | 20 | class Export(GlancesExport): 21 | """This class manages the MongoDB export module.""" 22 | 23 | def __init__(self, config=None, args=None): 24 | """Init the MongoDB export IF.""" 25 | super().__init__(config=config, args=args) 26 | 27 | # Mandatory configuration keys (additional to host and port) 28 | self.db = None 29 | 30 | # Optional configuration keys 31 | self.user = None 32 | self.password = None 33 | 34 | # Load the Cassandra configuration file section 35 | self.export_enable = self.load_conf('mongodb', mandatories=['host', 'port', 'db'], options=['user', 'password']) 36 | if not self.export_enable: 37 | sys.exit(2) 38 | 39 | # Init the CouchDB client 40 | self.client = self.init() 41 | 42 | def init(self): 43 | """Init the connection to the CouchDB server.""" 44 | if not self.export_enable: 45 | return None 46 | 47 | server_uri = f'mongodb://{quote_plus(self.user)}:{quote_plus(self.password)}@{self.host}:{self.port}' 48 | 49 | try: 50 | client = pymongo.MongoClient(server_uri) 51 | client.admin.command('ping') 52 | except Exception as e: 53 | logger.critical(f"Cannot connect to MongoDB server {self.host}:{self.port} ({e})") 54 | sys.exit(2) 55 | else: 56 | logger.info("Connected to the MongoDB server") 57 | 58 | return client 59 | 60 | def database(self): 61 | """Return the CouchDB database object""" 62 | return self.client[self.db] 63 | 64 | def export(self, name, columns, points): 65 | """Write the points to the MongoDB server.""" 66 | logger.debug(f"Export {name} stats to MongoDB") 67 | 68 | # Create DB input 69 | data = dict(zip(columns, points)) 70 | 71 | # Write data to the MongoDB database 72 | try: 73 | self.database()[name].insert_one(data) 74 | except Exception as e: 75 | logger.error(f"Cannot export {name} stats to MongoDB ({e})") 76 | -------------------------------------------------------------------------------- /glances/exports/glances_opentsdb/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Glances. 3 | # 4 | # SPDX-FileCopyrightText: 2022 Nicolas Hennion 5 | # 6 | # SPDX-License-Identifier: LGPL-3.0-only 7 | # 8 | 9 | """OpenTSDB interface class.""" 10 | 11 | import sys 12 | from numbers import Number 13 | 14 | import potsdb 15 | 16 | from glances.exports.export import GlancesExport 17 | from glances.logger import logger 18 | 19 | 20 | class Export(GlancesExport): 21 | """This class manages the OpenTSDB export module.""" 22 | 23 | def __init__(self, config=None, args=None): 24 | """Init the OpenTSDB export IF.""" 25 | super().__init__(config=config, args=args) 26 | 27 | # Mandatory configuration keys (additional to host and port) 28 | # N/A 29 | 30 | # Optionals configuration keys 31 | self.prefix = None 32 | self.tags = None 33 | 34 | # Load the configuration file 35 | self.export_enable = self.load_conf('opentsdb', mandatories=['host', 'port'], options=['prefix', 'tags']) 36 | if not self.export_enable: 37 | exit('Missing OPENTSDB config') 38 | 39 | # Default prefix for stats is 'glances' 40 | if self.prefix is None: 41 | self.prefix = 'glances' 42 | 43 | # Init the OpenTSDB client 44 | self.client = self.init() 45 | 46 | def init(self): 47 | """Init the connection to the OpenTSDB server.""" 48 | if not self.export_enable: 49 | return None 50 | 51 | try: 52 | db = potsdb.Client(self.host, port=int(self.port), check_host=True) 53 | except Exception as e: 54 | logger.critical(f"Cannot connect to OpenTSDB server {self.host}:{self.port} ({e})") 55 | sys.exit(2) 56 | 57 | return db 58 | 59 | def export(self, name, columns, points): 60 | """Export the stats to the Statsd server.""" 61 | for i in range(len(columns)): 62 | if not isinstance(points[i], Number): 63 | continue 64 | stat_name = f'{self.prefix}.{name}.{columns[i]}' 65 | stat_value = points[i] 66 | tags = self.parse_tags(self.tags) 67 | try: 68 | self.client.send(stat_name, stat_value, **tags) 69 | except Exception as e: 70 | logger.error(f"Can not export stats {name} to OpenTSDB ({e})") 71 | logger.debug(f"Export {name} stats to OpenTSDB") 72 | 73 | def exit(self): 74 | """Close the OpenTSDB export module.""" 75 | # Waits for all outstanding metrics to be sent and background thread closes 76 | self.client.wait() 77 | # Call the father method 78 | super().exit() 79 | -------------------------------------------------------------------------------- /glances/exports/glances_restful/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Glances. 3 | # 4 | # SPDX-FileCopyrightText: 2022 Nicolas Hennion 5 | # 6 | # SPDX-License-Identifier: LGPL-3.0-only 7 | # 8 | 9 | """RESTful interface class.""" 10 | 11 | from requests import post 12 | 13 | from glances.exports.export import GlancesExport 14 | from glances.globals import listkeys 15 | from glances.logger import logger 16 | 17 | 18 | class Export(GlancesExport): 19 | """This class manages the RESTful export module. 20 | Be aware that stats will be exported in one big POST request""" 21 | 22 | def __init__(self, config=None, args=None): 23 | """Init the RESTful export IF.""" 24 | super().__init__(config=config, args=args) 25 | 26 | # Mandatory configuration keys (additional to host and port) 27 | self.protocol = None 28 | self.path = None 29 | 30 | # Load the RESTful section in the configuration file 31 | self.export_enable = self.load_conf('restful', mandatories=['host', 'port', 'protocol', 'path']) 32 | if not self.export_enable: 33 | exit('Missing RESTFUL config') 34 | 35 | # Init the stats buffer 36 | # It's a dict of stats 37 | self.buffer = {} 38 | 39 | # Init the Statsd client 40 | self.client = self.init() 41 | 42 | def init(self): 43 | """Init the connection to the RESTful server.""" 44 | if not self.export_enable: 45 | return None 46 | # Build the RESTful URL where the stats will be posted 47 | url = f'{self.protocol}://{self.host}:{self.port}{self.path}' 48 | logger.info(f"Stats will be exported to the RESTful endpoint {url}") 49 | return url 50 | 51 | def export(self, name, columns, points): 52 | """Export the stats to the Statsd server.""" 53 | if name == self.last_exported_list()[0] and self.buffer != {}: 54 | # One complete loop have been done 55 | logger.debug(f"Export stats ({listkeys(self.buffer)}) to RESTful endpoint ({self.client})") 56 | # Export stats 57 | post(self.client, json=self.buffer, allow_redirects=True) 58 | # Reset buffer 59 | self.buffer = {} 60 | 61 | # Add current stat to the buffer 62 | self.buffer[name] = dict(zip(columns, points)) 63 | -------------------------------------------------------------------------------- /glances/exports/glances_riemann/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Glances. 3 | # 4 | # SPDX-FileCopyrightText: 2022 Nicolas Hennion 5 | # 6 | # SPDX-License-Identifier: LGPL-3.0-only 7 | # 8 | 9 | """Riemann interface class.""" 10 | 11 | import socket 12 | from numbers import Number 13 | 14 | # Import bernhard for Riemann 15 | import bernhard 16 | 17 | from glances.exports.export import GlancesExport 18 | from glances.logger import logger 19 | 20 | 21 | class Export(GlancesExport): 22 | """This class manages the Riemann export module.""" 23 | 24 | def __init__(self, config=None, args=None): 25 | """Init the Riemann export IF.""" 26 | super().__init__(config=config, args=args) 27 | 28 | # Mandatory configuration keys (additional to host and port) 29 | # N/A 30 | 31 | # Optional configuration keys 32 | # N/A 33 | 34 | # Load the Riemann configuration 35 | self.export_enable = self.load_conf('riemann', mandatories=['host', 'port'], options=[]) 36 | if not self.export_enable: 37 | exit('Missing RIEMANN config') 38 | 39 | # Get the current hostname 40 | self.hostname = socket.gethostname() 41 | 42 | # Init the Riemann client 43 | self.client = self.init() 44 | 45 | def init(self): 46 | """Init the connection to the Riemann server.""" 47 | if not self.export_enable: 48 | return None 49 | try: 50 | return bernhard.Client(host=self.host, port=self.port) 51 | except Exception as e: 52 | logger.critical(f"Connection to Riemann failed : {e} ") 53 | return None 54 | 55 | def export(self, name, columns, points): 56 | """Write the points in Riemann.""" 57 | for i in range(len(columns)): 58 | if not isinstance(points[i], Number): 59 | continue 60 | 61 | data = {'host': self.hostname, 'service': name + " " + columns[i], 'metric': points[i]} 62 | logger.debug(data) 63 | try: 64 | self.client.send(data) 65 | except Exception as e: 66 | logger.error(f"Cannot export stats to Riemann ({e})") 67 | -------------------------------------------------------------------------------- /glances/exports/glances_statsd/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Glances. 3 | # 4 | # SPDX-FileCopyrightText: 2022 Nicolas Hennion 5 | # 6 | # SPDX-License-Identifier: LGPL-3.0-only 7 | # 8 | 9 | """Statsd interface class.""" 10 | 11 | from numbers import Number 12 | 13 | from statsd import StatsClient 14 | 15 | from glances.exports.export import GlancesExport 16 | from glances.logger import logger 17 | 18 | 19 | class Export(GlancesExport): 20 | """This class manages the Statsd export module.""" 21 | 22 | def __init__(self, config=None, args=None): 23 | """Init the Statsd export IF.""" 24 | super().__init__(config=config, args=args) 25 | 26 | # Mandatory configuration keys (additional to host and port) 27 | # N/A 28 | 29 | # Optional configuration keys 30 | self.prefix = None 31 | 32 | # Load the configuration file 33 | self.export_enable = self.load_conf('statsd', mandatories=['host', 'port'], options=['prefix']) 34 | if not self.export_enable: 35 | exit('Missing STATSD config') 36 | 37 | # Default prefix for stats is 'glances' 38 | if self.prefix is None: 39 | self.prefix = 'glances' 40 | 41 | # Init the Statsd client 42 | self.client = self.init() 43 | 44 | def init(self): 45 | """Init the connection to the Statsd server.""" 46 | if not self.export_enable: 47 | return None 48 | logger.info(f"Stats will be exported to StatsD server: {self.host}:{self.port}") 49 | return StatsClient(self.host, int(self.port), prefix=self.prefix) 50 | 51 | def export(self, name, columns, points): 52 | """Export the stats to the Statsd server.""" 53 | for i in range(len(columns)): 54 | if not isinstance(points[i], Number): 55 | continue 56 | stat_name = f'{name}.{columns[i]}' 57 | stat_value = points[i] 58 | try: 59 | self.client.gauge(normalize(stat_name), stat_value) 60 | except Exception as e: 61 | logger.error(f"Can not export stats to Statsd ({e})") 62 | logger.debug(f"Export {name} stats to Statsd") 63 | 64 | 65 | def normalize(name): 66 | """Normalize name for the Statsd convention""" 67 | 68 | # Name should not contain some specials chars (issue #1068) 69 | ret = name.replace(':', '') 70 | ret = ret.replace('%', '') 71 | return ret.replace(' ', '_') 72 | -------------------------------------------------------------------------------- /glances/history.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Glances. 3 | # 4 | # SPDX-FileCopyrightText: 2022 Nicolas Hennion 5 | # 6 | # SPDX-License-Identifier: LGPL-3.0-only 7 | # 8 | 9 | """Manage stats history""" 10 | 11 | from glances.attribute import GlancesAttribute 12 | 13 | 14 | class GlancesHistory: 15 | """This class manage a dict of GlancesAttribute 16 | - key: stats name 17 | - value: GlancesAttribute""" 18 | 19 | def __init__(self): 20 | """ 21 | items_history_list: list of stats to historized (define inside plugins) 22 | """ 23 | self.stats_history = {} 24 | 25 | def add(self, key, value, description='', history_max_size=None): 26 | """Add an new item (key, value) to the current history.""" 27 | if key not in self.stats_history: 28 | self.stats_history[key] = GlancesAttribute(key, description=description, history_max_size=history_max_size) 29 | self.stats_history[key].value = value 30 | 31 | def reset(self): 32 | """Reset all the stats history""" 33 | for a in self.stats_history: 34 | self.stats_history[a].history_reset() 35 | 36 | def get(self, nb=0): 37 | """Get the history as a dict of list""" 38 | return {i: self.stats_history[i].history_raw(nb=nb) for i in self.stats_history} 39 | 40 | def get_json(self, nb=0): 41 | """Get the history as a dict of list (with list JSON compliant)""" 42 | return {i: self.stats_history[i].history_json(nb=nb) for i in self.stats_history} 43 | -------------------------------------------------------------------------------- /glances/outputs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/glances/outputs/__init__.py -------------------------------------------------------------------------------- /glances/outputs/glances_stdout_json.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Glances. 3 | # 4 | # SPDX-FileCopyrightText: 2022 Nicolas Hennion 5 | # 6 | # SPDX-License-Identifier: LGPL-3.0-only 7 | # 8 | 9 | """Stdout interface class.""" 10 | 11 | import time 12 | 13 | from glances.globals import printandflush 14 | 15 | 16 | class GlancesStdoutJson: 17 | """This class manages the Stdout JSON display.""" 18 | 19 | def __init__(self, config=None, args=None): 20 | # Init 21 | self.config = config 22 | self.args = args 23 | 24 | # Build the list of plugin to display 25 | self.plugins_list = self.build_list() 26 | 27 | def build_list(self): 28 | """Return a list of tuples taken from self.args.stdout_json 29 | 30 | :return: A list of tuples. Example -[(plugin, attribute), ... ] 31 | """ 32 | return self.args.stdout_json.split(',') 33 | 34 | def end(self): 35 | pass 36 | 37 | def update(self, stats, duration=3): 38 | """Display stats in JSON format to stdout. 39 | 40 | Refresh every duration second. 41 | """ 42 | for plugin in self.plugins_list: 43 | # Check if the plugin exist and is enable 44 | if plugin in stats.getPluginsList() and stats.get_plugin(plugin).is_enabled(): 45 | stat = stats.get_plugin(plugin).get_json() 46 | else: 47 | continue 48 | # Display stats 49 | printandflush(f'{plugin}: {stat.decode()}') 50 | 51 | # Wait until next refresh 52 | if duration > 0: 53 | time.sleep(duration) 54 | -------------------------------------------------------------------------------- /glances/outputs/glances_unicode.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Glances. 3 | # 4 | # SPDX-FileCopyrightText: 2022 Nicolas Hennion 5 | # 6 | # SPDX-License-Identifier: LGPL-3.0-only 7 | # 8 | 9 | """Manage unicode message for Glances output.""" 10 | 11 | _unicode_message = { 12 | 'ARROW_LEFT': ['\u2190', '<'], 13 | 'ARROW_RIGHT': ['\u2192', '>'], 14 | 'ARROW_UP': ['\u2191', '^'], 15 | 'ARROW_DOWN': ['\u2193', 'v'], 16 | 'CHECK': ['\u2713', ''], 17 | 'PROCESS_SELECTOR': ['>', '>'], 18 | 'MEDIUM_LINE': ['\u2500', '─'], 19 | 'LOW_LINE': ['\u2581', '_'], 20 | } 21 | 22 | 23 | def unicode_message(key, args=None): 24 | """Return the unicode message for the given key.""" 25 | if args and hasattr(args, 'disable_unicode') and args.disable_unicode: 26 | return _unicode_message[key][1] 27 | return _unicode_message[key][0] 28 | -------------------------------------------------------------------------------- /glances/outputs/static/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 100, 3 | arrowParens: 'always', 4 | bracketSpacing: true, 5 | semi: true, 6 | singleQuote: true, 7 | tabWidth: 4, 8 | trailingComma: 'none', 9 | useTabs: false 10 | }; 11 | -------------------------------------------------------------------------------- /glances/outputs/static/README.md: -------------------------------------------------------------------------------- 1 | # Focus on the Glances Web User Interface 2 | 3 | In order to build the assets of the Web UI, you'll need [NPM](https://docs.npmjs.com/getting-started/what-is-npm). 4 | 5 | NPM is a package manager for JavaScript related to [Node.js](https://nodejs.org/en/). 6 | 7 | NodeJS should be installed/updated on your system. 8 | 9 | ## Pre-requisites 10 | 11 | ### Install NodeJS 12 | 13 | Example on Ubuntu OS: 14 | 15 | ```bash 16 | sudo apt install nodejs npm 17 | ``` 18 | 19 | ### Upgrade NodeJS 20 | 21 | Example on Ubuntu OS: 22 | 23 | ```bash 24 | sudo apt update 25 | sudo apt install nodejs npm 26 | sudo npm install -g n 27 | sudo n lts 28 | hash -r 29 | ``` 30 | 31 | ## Build Glances WebUI 32 | 33 | You must run the following command from the `glances/outputs/static/` directory. 34 | 35 | ```bash 36 | cd glances/outputs/static/ 37 | ``` 38 | 39 | ### Install dependencies 40 | 41 | ```bash 42 | npm ci 43 | ``` 44 | 45 | ### Update dependencies 46 | 47 | To update all the dependencies to the latest version and package.json and package-lock.json, 48 | you can use the command "npm update --save": 49 | 50 | ```bash 51 | npm update --save 52 | npx npm-check-updates -u 53 | npm install 54 | ``` 55 | 56 | ### Build assets 57 | 58 | Run the build command to build assets once : 59 | 60 | ```bash 61 | npm run build 62 | ``` 63 | 64 | or use the watch command to rebuild only modified files : 65 | 66 | ```bash 67 | npm run watch 68 | ``` 69 | 70 | ## Anatomy 71 | 72 | ```bash 73 | static 74 | | 75 | |--- css 76 | | 77 | |--- images 78 | | 79 | |--- js 80 | | 81 | |--- public # path where builds are put 82 | | 83 | |--- templates 84 | ``` 85 | 86 | ## Data 87 | 88 | Each plugin receives the data in the following format: 89 | 90 | * stats 91 | * views 92 | * isBsd 93 | * isLinux 94 | * isMac 95 | * isWindows 96 | -------------------------------------------------------------------------------- /glances/outputs/static/css/custom.scss: -------------------------------------------------------------------------------- 1 | // Custom.scss 2 | 3 | // Option A: Include all of Bootstrap 4 | // ================================== 5 | 6 | // Include any default variable overrides here (though functions won't be available) 7 | 8 | // @import "../node_modules/bootstrap/scss/bootstrap"; 9 | 10 | // Then add additional custom code here 11 | 12 | 13 | 14 | // // Option B: Include parts of Bootstrap 15 | // // ==================================== 16 | 17 | // // 1. Include functions first (so you can manipulate colors, SVGs, calc, etc) 18 | @import "../node_modules/bootstrap/scss/functions"; 19 | 20 | // // 2. Include any default variable overrides here 21 | // $body-bg: black; 22 | 23 | // // 3. Include remainder of required Bootstrap stylesheets (including any separate color mode stylesheets) 24 | @import "../node_modules/bootstrap/scss/variables"; 25 | @import "../node_modules/bootstrap/scss/variables-dark"; 26 | 27 | // // 4. Include any default map overrides here 28 | 29 | // // 5. Include remainder of required parts 30 | @import "../node_modules/bootstrap/scss/maps"; 31 | @import "../node_modules/bootstrap/scss/mixins"; 32 | @import "../node_modules/bootstrap/scss/root"; 33 | 34 | // // 6. Optionally include any other parts as needed 35 | @import "../node_modules/bootstrap/scss/utilities"; 36 | @import "../node_modules/bootstrap/scss/reboot"; 37 | @import "../node_modules/bootstrap/scss/type"; 38 | @import "../node_modules/bootstrap/scss/images"; 39 | @import "../node_modules/bootstrap/scss/containers"; 40 | @import "../node_modules/bootstrap/scss/grid"; 41 | @import "../node_modules/bootstrap/scss/helpers"; 42 | @import "../node_modules/bootstrap/scss/tables"; 43 | @import "../node_modules/bootstrap/scss/progress"; 44 | 45 | // // 7. Optionally include utilities API last to generate classes based on the Sass map in `_utilities.scss` 46 | @import "../node_modules/bootstrap/scss/utilities/api"; 47 | 48 | // // 8. Add additional custom code here 49 | -------------------------------------------------------------------------------- /glances/outputs/static/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import eslint from '@eslint/js'; 2 | import eslintConfigPrettier from 'eslint-config-prettier'; 3 | import eslintPluginVue from 'eslint-plugin-vue'; 4 | import globals from 'globals'; 5 | import typescriptEslint from 'typescript-eslint'; 6 | 7 | export default typescriptEslint.config( 8 | { ignores: ['*.d.ts', '**/coverage', '**/dist'] }, 9 | { 10 | extends: [ 11 | eslint.configs.recommended, 12 | ...typescriptEslint.configs.recommended, 13 | ...eslintPluginVue.configs['flat/recommended'], 14 | ], 15 | files: ['**/*.{ts,vue}'], 16 | languageOptions: { 17 | ecmaVersion: 'latest', 18 | sourceType: 'module', 19 | globals: globals.browser, 20 | parserOptions: { 21 | parser: typescriptEslint.parser, 22 | }, 23 | }, 24 | rules: { 25 | // your rules 26 | }, 27 | }, 28 | eslintConfigPrettier 29 | ); 30 | -------------------------------------------------------------------------------- /glances/outputs/static/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/glances/outputs/static/images/favicon.ico -------------------------------------------------------------------------------- /glances/outputs/static/images/glances.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/glances/outputs/static/images/glances.png -------------------------------------------------------------------------------- /glances/outputs/static/js/app.js: -------------------------------------------------------------------------------- 1 | /* global module */ 2 | if (module.hot) { 3 | module.hot.accept(); 4 | } 5 | 6 | import '../css/custom.scss'; 7 | import '../css/style.scss'; 8 | 9 | import * as bootstrap from 'bootstrap'; 10 | 11 | import { createApp } from 'vue'; 12 | import App from './App.vue'; 13 | import * as filters from "./filters.js"; 14 | 15 | const app = createApp(App); 16 | app.config.globalProperties.$filters = filters; 17 | app.mount('#app'); 18 | -------------------------------------------------------------------------------- /glances/outputs/static/js/browser.js: -------------------------------------------------------------------------------- 1 | /* global module */ 2 | if (module.hot) { 3 | module.hot.accept(); 4 | } 5 | 6 | import '../css/custom.scss'; 7 | import '../css/style.scss'; 8 | 9 | import * as bootstrap from 'bootstrap'; 10 | 11 | import { createApp } from 'vue'; 12 | import App from './Browser.vue'; 13 | import * as filters from "./filters.js"; 14 | 15 | const app = createApp(App); 16 | app.config.globalProperties.$filters = filters; 17 | app.mount('#browser'); 18 | -------------------------------------------------------------------------------- /glances/outputs/static/js/components/plugin-amps.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | -------------------------------------------------------------------------------- /glances/outputs/static/js/components/plugin-cloud.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /glances/outputs/static/js/components/plugin-connections.vue: -------------------------------------------------------------------------------- 1 | 37 | 38 | -------------------------------------------------------------------------------- /glances/outputs/static/js/components/plugin-folders.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | -------------------------------------------------------------------------------- /glances/outputs/static/js/components/plugin-hostname.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | -------------------------------------------------------------------------------- /glances/outputs/static/js/components/plugin-ip.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | -------------------------------------------------------------------------------- /glances/outputs/static/js/components/plugin-irq.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | -------------------------------------------------------------------------------- /glances/outputs/static/js/components/plugin-load.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | -------------------------------------------------------------------------------- /glances/outputs/static/js/components/plugin-memswap.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | -------------------------------------------------------------------------------- /glances/outputs/static/js/components/plugin-now.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 21 | -------------------------------------------------------------------------------- /glances/outputs/static/js/components/plugin-processcount.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | -------------------------------------------------------------------------------- /glances/outputs/static/js/components/plugin-sensors.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | -------------------------------------------------------------------------------- /glances/outputs/static/js/components/plugin-smart.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 53 | -------------------------------------------------------------------------------- /glances/outputs/static/js/components/plugin-system.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | -------------------------------------------------------------------------------- /glances/outputs/static/js/components/plugin-uptime.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /glances/outputs/static/js/components/plugin-wifi.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | -------------------------------------------------------------------------------- /glances/outputs/static/js/store.js: -------------------------------------------------------------------------------- 1 | import { reactive } from 'vue'; 2 | 3 | export const store = reactive({ 4 | args: undefined, 5 | config: undefined, 6 | data: undefined, 7 | status: 'IDLE' 8 | }); 9 | -------------------------------------------------------------------------------- /glances/outputs/static/js/uiconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "leftMenu": [ 3 | "network", 4 | "ports", 5 | "wifi", 6 | "connections", 7 | "diskio", 8 | "fs", 9 | "irq", 10 | "folders", 11 | "raid", 12 | "smart", 13 | "sensors" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /glances/outputs/static/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "dependencies": { 4 | "bootstrap": "^5.3.5", 5 | "favico.js": "^0.3.10", 6 | "hotkeys-js": "^3.13.9", 7 | "lodash": "^4.17.21", 8 | "sanitize-html": "^2.16.0", 9 | "vue": "^3.5.13" 10 | }, 11 | "devDependencies": { 12 | "@vue/compiler-sfc": "^3.5.13", 13 | "copy-webpack-plugin": "^13.0.0", 14 | "css-loader": "^7.1.2", 15 | "del": "^8.0.0", 16 | "eslint": "^9.25.0", 17 | "eslint-config-prettier": "^10.1.2", 18 | "eslint-plugin-vue": "^10.0.0", 19 | "globals": "^16.0.0", 20 | "html-webpack-plugin": "^5.6.3", 21 | "less": "^4.3.0", 22 | "less-loader": "^12.2.0", 23 | "sass": "^1.86.3", 24 | "sass-loader": "^16.0.5", 25 | "style-loader": "^4.0.0", 26 | "typescript-eslint": "^8.30.1", 27 | "url-loader": "^4.1.1", 28 | "vue-loader": "^17.4.2", 29 | "webpack": "^5.99.6", 30 | "webpack-cli": "^6.0.1", 31 | "webpack-dev-server": "^5.2.1" 32 | }, 33 | "scripts": { 34 | "build": "webpack --progress --mode=production", 35 | "start": "webpack serve --mode=development", 36 | "watch": "webpack --progress --watch", 37 | "lint": "eslint ./ --ext .js,.vue", 38 | "lint-fix": "eslint ./ --ext .js,.vue --fix", 39 | "clean": "rm -rf node_modules" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /glances/outputs/static/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/glances/outputs/static/public/favicon.ico -------------------------------------------------------------------------------- /glances/outputs/static/templates/browser.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Glances Central Browser 8 | 9 | 10 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /glances/outputs/static/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Glances 8 | 9 | 10 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /glances/outputs/static/webpack.config.js: -------------------------------------------------------------------------------- 1 | 2 | const webpack = require('webpack'); 3 | const path = require("path"); 4 | const CopyWebpackPlugin = require("copy-webpack-plugin"); 5 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 6 | const TerserWebpackPlugin = require('terser-webpack-plugin'); 7 | const { VueLoaderPlugin } = require('vue-loader'); 8 | const PORT = process.env.PORT || 61209; 9 | 10 | module.exports = (_, env) => { 11 | const isProd = env.mode === 'production'; 12 | 13 | return { 14 | mode: isProd ? 'production' : 'development', 15 | entry: { 16 | glances: "./js/app.js", 17 | browser: "./js/browser.js" 18 | }, 19 | output: { 20 | path: path.join(__dirname, "public"), 21 | filename: "[name].js", 22 | publicPath: '/', 23 | clean: true 24 | }, 25 | devtool: isProd ? false : 'eval-source-map', 26 | module: { 27 | rules: [ 28 | { 29 | test: /\.vue$/i, 30 | loader: 'vue-loader' 31 | }, 32 | { 33 | test: /\.scss$/i, 34 | use: [{ 35 | loader: "style-loader", 36 | }, { 37 | loader: "css-loader", 38 | }, { 39 | loader: "sass-loader", 40 | }] 41 | }, 42 | { 43 | test: /\.css$/i, 44 | use: [{ 45 | loader: "style-loader", 46 | }, { 47 | loader: "css-loader", 48 | }] 49 | } 50 | ], 51 | }, 52 | plugins: [ 53 | new webpack.DefinePlugin({ 54 | __VUE_OPTIONS_API__: true, 55 | __VUE_PROD_DEVTOOLS__: false 56 | }), 57 | new CopyWebpackPlugin({ 58 | patterns: [ 59 | { from: "./images/favicon.ico" } 60 | ] 61 | }), 62 | !isProd && new HtmlWebpackPlugin({ 63 | template: './templates/index.html', 64 | inject: false 65 | }), 66 | isProd && new TerserWebpackPlugin({ extractComments: false }), 67 | new VueLoaderPlugin() 68 | ].filter(Boolean), 69 | devServer: { 70 | host: '0.0.0.0', 71 | port: PORT, 72 | hot: true, 73 | proxy: { 74 | '/api': { 75 | target: 'http://0.0.0.0:61208' 76 | } 77 | } 78 | } 79 | 80 | }; 81 | }; 82 | -------------------------------------------------------------------------------- /glances/password_list.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Glances. 3 | # 4 | # SPDX-FileCopyrightText: 2022 Nicolas Hennion 5 | # 6 | # SPDX-License-Identifier: LGPL-3.0-only 7 | # 8 | 9 | """Manage the Glances passwords list.""" 10 | 11 | from glances.logger import logger 12 | from glances.password import GlancesPassword 13 | 14 | 15 | class GlancesPasswordList(GlancesPassword): 16 | """Manage the Glances passwords list for the client|browser/server.""" 17 | 18 | _section = "passwords" 19 | 20 | def __init__(self, config=None, args=None): 21 | super().__init__() 22 | # password_dict is a dict (JSON compliant) 23 | # {'host': 'password', ... } 24 | # Load the configuration file 25 | self._password_dict = self.load(config) 26 | 27 | def load(self, config): 28 | """Load the password from the configuration file.""" 29 | password_dict = {} 30 | 31 | if config is None: 32 | logger.warning("No configuration file available. Cannot load password list.") 33 | elif not config.has_section(self._section): 34 | logger.warning(f"No [{self._section}] section in the configuration file. Cannot load password list.") 35 | else: 36 | logger.info(f"Start reading the [{self._section}] section in the configuration file") 37 | 38 | password_dict = dict(config.items(self._section)) 39 | 40 | # Password list loaded 41 | logger.info(f"{len(password_dict)} password(s) loaded from the configuration file") 42 | 43 | return password_dict 44 | 45 | def get_password(self, host=None): 46 | """Get the password from a Glances client or server. 47 | 48 | If host=None, return the current server list (dict). 49 | Else, return the host's password (or the default one if defined or None) 50 | """ 51 | if host is None: 52 | return self._password_dict 53 | 54 | try: 55 | return self._password_dict[host] 56 | except (KeyError, TypeError): 57 | try: 58 | return self._password_dict['default'] 59 | except (KeyError, TypeError): 60 | return None 61 | 62 | def set_password(self, host, password): 63 | """Set a password for a specific host.""" 64 | self._password_dict[host] = password 65 | -------------------------------------------------------------------------------- /glances/plugins/README.rst: -------------------------------------------------------------------------------- 1 | =============== 2 | Glances plugins 3 | =============== 4 | 5 | This is the Glances plugins folder. 6 | 7 | A Glances plugin is a Python module hosted in a folder. 8 | 9 | It should implement a Class named Plugin inherited from GlancesPluginModel (example for foo plugin: FooPlugin). 10 | 11 | This class should be based on the MVC model. 12 | - model: where the stats are updated (update method) 13 | - view: where the stats are prepare to be displayed (update_views) 14 | - controller: where the stats are displayed (msg_curse method) 15 | 16 | A plugin should define the following global variables: 17 | 18 | - fields_description: a dict twith the field description/option 19 | - items_history_list (optional): define items history 20 | 21 | Have a look of all Glances plugin's methods in the plugin folder (where the GlancesPluginModel is defined). 22 | -------------------------------------------------------------------------------- /glances/plugins/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/glances/plugins/__init__.py -------------------------------------------------------------------------------- /glances/plugins/__pycache__/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/glances/plugins/__pycache__/__init__.py -------------------------------------------------------------------------------- /glances/plugins/containers/engines/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Glances. 3 | # 4 | # SPDX-FileCopyrightText: 2024 Nicolas Hennion 5 | # 6 | # SPDX-License-Identifier: LGPL-3.0-only 7 | # 8 | 9 | from typing import Any, Protocol 10 | 11 | 12 | class ContainersExtension(Protocol): 13 | def stop(self) -> None: 14 | raise NotImplementedError 15 | 16 | def update(self, all_tag) -> tuple[dict, list[dict[str, Any]]]: 17 | raise NotImplementedError 18 | -------------------------------------------------------------------------------- /glances/plugins/core/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Glances. 3 | # 4 | # SPDX-FileCopyrightText: 2022 Nicolas Hennion 5 | # 6 | # SPDX-License-Identifier: LGPL-3.0-only 7 | # 8 | 9 | """CPU core plugin.""" 10 | 11 | import psutil 12 | 13 | from glances.plugins.plugin.model import GlancesPluginModel 14 | 15 | # Fields description 16 | fields_description = { 17 | 'phys': {'description': 'Number of physical cores (hyper thread CPUs are excluded).', 'unit': 'number'}, 18 | 'log': { 19 | 'description': 'Number of logical CPU cores. A logical CPU is the number of \ 20 | physical cores multiplied by the number of threads that can run on each core.', 21 | 'unit': 'number', 22 | }, 23 | } 24 | 25 | 26 | class CorePlugin(GlancesPluginModel): 27 | """Glances CPU core plugin. 28 | 29 | Get stats about CPU core number. 30 | 31 | stats is integer (number of core) 32 | """ 33 | 34 | def __init__(self, args=None, config=None): 35 | """Init the plugin.""" 36 | super().__init__(args=args, config=config, fields_description=fields_description) 37 | 38 | # We dot not want to display the stat in the curse interface 39 | # The core number is displayed by the load plugin 40 | self.display_curse = False 41 | 42 | # Do *NOT* uncomment the following line 43 | # @GlancesPluginModel._check_decorator 44 | @GlancesPluginModel._log_result_decorator 45 | def update(self): 46 | """Update core stats. 47 | 48 | Stats is a dict (with both physical and log cpu number) instead of a integer. 49 | """ 50 | # Init new stats 51 | stats = self.get_init_value() 52 | 53 | if self.input_method == 'local': 54 | # Update stats using the standard system lib 55 | 56 | # The psutil 2.0 include psutil.cpu_count() and psutil.cpu_count(logical=False) 57 | # Return a dict with: 58 | # - phys: physical cores only (hyper thread CPUs are excluded) 59 | # - log: logical CPUs in the system 60 | # Return None if undefined 61 | try: 62 | stats["phys"] = psutil.cpu_count(logical=False) 63 | stats["log"] = psutil.cpu_count() 64 | except NameError: 65 | self.reset() 66 | 67 | elif self.input_method == 'snmp': 68 | # Update stats using SNMP 69 | # http://stackoverflow.com/questions/5662467/how-to-find-out-the-number-of-cpus-using-snmp 70 | pass 71 | 72 | # Update the stats 73 | self.stats = stats 74 | 75 | return self.stats 76 | -------------------------------------------------------------------------------- /glances/plugins/gpu/cards/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/glances/plugins/gpu/cards/__init__.py -------------------------------------------------------------------------------- /glances/plugins/plugin/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/glances/plugins/plugin/__init__.py -------------------------------------------------------------------------------- /glances/plugins/psutilversion/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Glances. 3 | # 4 | # SPDX-FileCopyrightText: 2022 Nicolas Hennion 5 | # 6 | # SPDX-License-Identifier: LGPL-3.0-only 7 | # 8 | 9 | """psutil plugin. 10 | Just a simple plugin to get the Psutil version.""" 11 | 12 | from glances import psutil_version_info 13 | from glances.plugins.plugin.model import GlancesPluginModel 14 | 15 | 16 | class PsutilversionPlugin(GlancesPluginModel): 17 | """Get the Psutil version. 18 | 19 | stats is a string 20 | """ 21 | 22 | def __init__(self, args=None, config=None): 23 | """Init the plugin.""" 24 | super().__init__(args=args, config=config) 25 | 26 | self.reset() 27 | 28 | def reset(self): 29 | """Reset/init the stats.""" 30 | self.stats = None 31 | 32 | @GlancesPluginModel._check_decorator 33 | @GlancesPluginModel._log_result_decorator 34 | def update(self): 35 | """Update the stats.""" 36 | # Reset stats 37 | self.reset() 38 | 39 | # Return psutil version as a tuple 40 | if self.input_method == 'local': 41 | # psutil version only available in local 42 | try: 43 | self.stats = '.'.join([str(i) for i in psutil_version_info]) 44 | except NameError: 45 | pass 46 | else: 47 | pass 48 | 49 | return self.stats 50 | -------------------------------------------------------------------------------- /glances/plugins/sensors/sensor/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicolargo/glances/a6de55bfcaa0f656a294aa92b615a06c1d6f56e4/glances/plugins/sensors/sensor/__init__.py -------------------------------------------------------------------------------- /glances/plugins/uptime/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Glances. 3 | # 4 | # SPDX-FileCopyrightText: 2022 Nicolas Hennion 5 | # 6 | # SPDX-License-Identifier: LGPL-3.0-only 7 | # 8 | 9 | """Uptime plugin.""" 10 | 11 | from datetime import datetime, timedelta 12 | 13 | import psutil 14 | 15 | from glances.plugins.plugin.model import GlancesPluginModel 16 | 17 | # SNMP OID 18 | snmp_oid = {'_uptime': '1.3.6.1.2.1.1.3.0'} 19 | 20 | 21 | class UptimePlugin(GlancesPluginModel): 22 | """Glances uptime plugin. 23 | 24 | stats is date (string) 25 | """ 26 | 27 | def __init__(self, args=None, config=None): 28 | """Init the plugin.""" 29 | super().__init__(args=args, config=config) 30 | 31 | # We want to display the stat in the curse interface 32 | self.display_curse = True 33 | 34 | # Set the message position 35 | self.align = 'right' 36 | 37 | # Init the stats 38 | self.uptime = datetime.now() - datetime.fromtimestamp(psutil.boot_time()) 39 | 40 | def get_export(self): 41 | """Overwrite the default export method. 42 | 43 | Export uptime in seconds. 44 | """ 45 | # Convert the delta time to seconds (with cast) 46 | # Correct issue #1092 (thanks to @IanTAtWork) 47 | return {'seconds': int(self.uptime.total_seconds())} 48 | 49 | @GlancesPluginModel._check_decorator 50 | @GlancesPluginModel._log_result_decorator 51 | def update(self): 52 | """Update uptime stat using the input method.""" 53 | # Init new stats 54 | stats = self.get_init_value() 55 | 56 | if self.input_method == 'local': 57 | # Update stats using the standard system lib 58 | self.uptime = datetime.now() - datetime.fromtimestamp(psutil.boot_time()) 59 | 60 | # Convert uptime to string (because datetime is not JSONifi) 61 | stats = str(self.uptime).split('.')[0] 62 | elif self.input_method == 'snmp': 63 | # Update stats using SNMP 64 | uptime = self.get_stats_snmp(snmp_oid=snmp_oid)['_uptime'] 65 | try: 66 | # In hundredths of seconds 67 | stats = str(timedelta(seconds=int(uptime) / 100)) 68 | except Exception: 69 | pass 70 | 71 | # Update the stats 72 | self.stats = stats 73 | 74 | return self.stats 75 | 76 | def msg_curse(self, args=None, max_width=None): 77 | """Return the string to display in the curse interface.""" 78 | # Init the return message 79 | ret = [] 80 | 81 | # Only process if stats exist and plugin not disabled 82 | if not self.stats or self.is_disabled(): 83 | return ret 84 | 85 | return [self.curse_add_line(f'Uptime: {self.stats}')] 86 | -------------------------------------------------------------------------------- /glances/plugins/version/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Glances. 3 | # 4 | # SPDX-FileCopyrightText: 2024 Nicolas Hennion 5 | # 6 | # SPDX-License-Identifier: LGPL-3.0-only 7 | # 8 | 9 | """version plugin. 10 | Just a simple plugin to get the Glances version. 11 | """ 12 | 13 | from glances import __version__ as glances_version 14 | from glances.plugins.plugin.model import GlancesPluginModel 15 | 16 | 17 | class VersionPlugin(GlancesPluginModel): 18 | """Get the Glances versions. 19 | 20 | stats is a string 21 | """ 22 | 23 | def __init__(self, args=None, config=None): 24 | """Init the plugin.""" 25 | super().__init__(args=args, config=config) 26 | 27 | self.reset() 28 | 29 | def reset(self): 30 | """Reset/init the stats.""" 31 | self.stats = None 32 | 33 | @GlancesPluginModel._check_decorator 34 | @GlancesPluginModel._log_result_decorator 35 | def update(self): 36 | """Update the stats.""" 37 | # Reset stats 38 | self.reset() 39 | 40 | # Return psutil version as a tuple 41 | if self.input_method == 'local': 42 | # psutil version only available in local 43 | try: 44 | self.stats = glances_version 45 | except NameError: 46 | pass 47 | else: 48 | pass 49 | 50 | return self.stats 51 | -------------------------------------------------------------------------------- /glances/plugins/vms/engines/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Glances. 3 | # 4 | # SPDX-FileCopyrightText: 2024 Nicolas Hennion 5 | # 6 | # SPDX-License-Identifier: LGPL-3.0-only 7 | # 8 | 9 | from typing import Any, Protocol 10 | 11 | 12 | class VmsExtension(Protocol): 13 | def stop(self) -> None: 14 | raise NotImplementedError 15 | 16 | def update(self, all_tag) -> tuple[dict, list[dict[str, Any]]]: 17 | raise NotImplementedError 18 | -------------------------------------------------------------------------------- /glances/secure.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Glances. 3 | # 4 | # SPDX-FileCopyrightText: 2022 Nicolas Hennion 5 | # 6 | # SPDX-License-Identifier: LGPL-3.0-only 7 | # 8 | 9 | """Secures functions for Glances""" 10 | 11 | import re 12 | from subprocess import PIPE, Popen 13 | 14 | from glances.globals import nativestr 15 | 16 | 17 | def secure_popen(cmd): 18 | """A more or less secure way to execute system commands 19 | 20 | Multiple command should be separated with a && 21 | 22 | :return: the result of the commands 23 | """ 24 | ret = '' 25 | 26 | # Split by multiple commands (only '&&' separator is supported) 27 | for c in cmd.split('&&'): 28 | ret += __secure_popen(c) 29 | 30 | return ret 31 | 32 | 33 | def __secure_popen(cmd): 34 | """A more or less secure way to execute system command 35 | 36 | Manage redirection (>) and pipes (|) 37 | """ 38 | # Split by redirection '>' 39 | cmd_split_redirect = cmd.split('>') 40 | if len(cmd_split_redirect) > 2: 41 | return f'Glances error: Only one file redirection allowed ({cmd})' 42 | if len(cmd_split_redirect) == 2: 43 | stdout_redirect = cmd_split_redirect[1].strip() 44 | cmd = cmd_split_redirect[0] 45 | else: 46 | stdout_redirect = None 47 | 48 | sub_cmd_stdin = None 49 | p_last = None 50 | # Split by pipe '|' 51 | for sub_cmd in cmd.split('|'): 52 | # Split by space character, but do no split spaces within quotes (remove surrounding quotes, though) 53 | tmp_split = [_ for _ in list(filter(None, re.split(r'(\s+)|(".*?"+?)|(\'.*?\'+?)', sub_cmd))) if _ != ' '] 54 | sub_cmd_split = [_[1:-1] if (_[0] == _[-1] == '"') or (_[0] == _[-1] == '\'') else _ for _ in tmp_split] 55 | p = Popen(sub_cmd_split, shell=False, stdin=sub_cmd_stdin, stdout=PIPE, stderr=PIPE) 56 | if p_last is not None: 57 | # Allow p_last to receive a SIGPIPE if p exits. 58 | p_last.stdout.close() 59 | p_last.kill() 60 | p_last.wait() 61 | p_last = p 62 | sub_cmd_stdin = p.stdout 63 | 64 | p_ret = p_last.communicate() 65 | 66 | if nativestr(p_ret[1]) == '': 67 | # No error 68 | ret = nativestr(p_ret[0]) 69 | if stdout_redirect is not None: 70 | # Write result to redirection file 71 | with open(stdout_redirect, "w") as stdout_redirect_file: 72 | stdout_redirect_file.write(ret) 73 | else: 74 | # Error 75 | ret = nativestr(p_ret[1]) 76 | 77 | return ret 78 | -------------------------------------------------------------------------------- /glances/stats_client.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Glances. 3 | # 4 | # SPDX-FileCopyrightText: 2022 Nicolas Hennion 5 | # 6 | # SPDX-License-Identifier: LGPL-3.0-only 7 | # 8 | 9 | """The stats server manager.""" 10 | 11 | import importlib 12 | import sys 13 | 14 | from glances.globals import sys_path 15 | from glances.logger import logger 16 | from glances.stats import GlancesStats 17 | 18 | 19 | class GlancesStatsClient(GlancesStats): 20 | """This class stores, updates and gives stats for the client.""" 21 | 22 | def __init__(self, config=None, args=None): 23 | """Init the GlancesStatsClient class.""" 24 | super().__init__(config=config, args=args) 25 | 26 | # Init the configuration 27 | self.config = config 28 | 29 | # Init the arguments 30 | self.args = args 31 | 32 | def set_plugins(self, input_plugins): 33 | """Set the plugin list according to the Glances server.""" 34 | header = "glances.plugins." 35 | for item in input_plugins: 36 | # Import the plugin 37 | try: 38 | plugin = importlib.import_module(header + item) 39 | except ImportError as e: 40 | # Server plugin can not be imported from the client side 41 | logger.error(f"Can not import {item} plugin ({e}). Please upgrade your Glances client/server version.") 42 | else: 43 | # Add the plugin to the dictionary 44 | # The key is the plugin name 45 | # for example, the file glances_xxx.py 46 | # generate self._plugins_list["xxx"] = ... 47 | logger.debug(f"Server uses {item} plugin") 48 | if hasattr(plugin, 'PluginModel'): 49 | # Old fashion way to load the plugin (before Glances 5.0) 50 | # Should be removed in Glances 5.0 - see #3170 51 | self._plugins[item] = getattr(plugin, 'PluginModel')(args=self.args) 52 | elif hasattr(plugin, item.capitalize() + 'Plugin'): 53 | # New fashion way to load the plugin (after Glances 5.0) 54 | self._plugins[item] = getattr(plugin, item.capitalize() + 'Plugin')(args=self.args) 55 | 56 | # Restoring system path 57 | sys.path = sys_path 58 | 59 | def update(self, input_stats): 60 | """Update all the stats.""" 61 | # For Glances client mode 62 | for p in input_stats: 63 | # Update plugin stats with items sent by the server 64 | self._plugins[p].set_stats(input_stats[p]) 65 | # Update the views for the updated stats 66 | self._plugins[p].update_views() 67 | -------------------------------------------------------------------------------- /glances/stats_server.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Glances. 3 | # 4 | # SPDX-FileCopyrightText: 2022 Nicolas Hennion 5 | # 6 | # SPDX-License-Identifier: LGPL-3.0-only 7 | # 8 | 9 | """The stats server manager.""" 10 | 11 | import collections 12 | 13 | from glances.logger import logger 14 | from glances.stats import GlancesStats 15 | 16 | 17 | class GlancesStatsServer(GlancesStats): 18 | """This class stores, updates and gives stats for the server.""" 19 | 20 | def __init__(self, config=None, args=None): 21 | # Init the stats 22 | super().__init__(config=config, args=args) 23 | 24 | # Init the all_stats dict used by the server 25 | # all_stats is a dict of dicts filled by the server 26 | self.all_stats = collections.defaultdict(dict) 27 | 28 | # In the update method, disable extended process stats 29 | logger.info("Disable extended processes stats in server mode") 30 | 31 | def update(self, input_stats=None): 32 | """Update the stats.""" 33 | input_stats = input_stats or {} 34 | 35 | # Force update of all the stats 36 | super().update() 37 | 38 | # Disable the extended processes stats because it cause an high CPU load 39 | self._plugins['processcount'].disable_extended() 40 | 41 | # Build all_stats variable (concatenation of all the stats) 42 | self.all_stats = self._set_stats(input_stats) 43 | 44 | def _set_stats(self, input_stats): 45 | """Set the stats to the input_stats one.""" 46 | # Build the all_stats with the get_raw() method of the plugins 47 | return {p: self._plugins[p].get_raw() for p in self._plugins if self._plugins[p].is_enabled()} 48 | 49 | def getAll(self): 50 | """Return the stats as a list.""" 51 | return self.all_stats 52 | -------------------------------------------------------------------------------- /glances/timer.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Glances. 3 | # 4 | # SPDX-FileCopyrightText: 2022 Nicolas Hennion 5 | # 6 | # SPDX-License-Identifier: LGPL-3.0-only 7 | # 8 | 9 | """The timer manager.""" 10 | 11 | from datetime import datetime 12 | from time import time 13 | 14 | # Global list to manage the elapsed time 15 | last_update_times = {} 16 | 17 | 18 | def getTimeSinceLastUpdate(key): 19 | """Return the elapsed time since last update.""" 20 | global last_update_times 21 | current_time = time() 22 | last_time = last_update_times.get(key) 23 | if not last_time: 24 | time_since_update = 1 25 | else: 26 | time_since_update = current_time - last_time 27 | last_update_times[key] = current_time 28 | return time_since_update 29 | 30 | 31 | class Timer: 32 | """The timer class. A simple chronometer.""" 33 | 34 | def __init__(self, duration): 35 | self.duration = duration 36 | self.start() 37 | 38 | def start(self): 39 | self.target = time() + self.duration 40 | 41 | def reset(self, duration=None): 42 | if duration is not None: 43 | self.set(duration) 44 | self.start() 45 | 46 | def get(self): 47 | return self.duration - (self.target - time()) 48 | 49 | def set(self, duration): 50 | self.duration = duration 51 | 52 | def finished(self): 53 | return time() > self.target 54 | 55 | 56 | class Counter: 57 | """The counter class.""" 58 | 59 | def __init__(self): 60 | self.start() 61 | 62 | def start(self): 63 | self.target = datetime.now() 64 | 65 | def reset(self): 66 | self.start() 67 | 68 | def get(self): 69 | return (datetime.now() - self.target).total_seconds() 70 | -------------------------------------------------------------------------------- /glances/webserver.py: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of Glances. 3 | # 4 | # SPDX-FileCopyrightText: 2024 Nicolas Hennion 5 | # 6 | # SPDX-License-Identifier: LGPL-3.0-only 7 | # 8 | 9 | """Glances Restful/API and Web based interface.""" 10 | 11 | from glances.globals import WINDOWS 12 | from glances.outputs.glances_restful_api import GlancesRestfulApi 13 | from glances.processes import glances_processes 14 | from glances.stats import GlancesStats 15 | 16 | 17 | class GlancesWebServer: 18 | """This class creates and manages the Glances Web server session.""" 19 | 20 | def __init__(self, config=None, args=None): 21 | # Init stats 22 | self.stats = GlancesStats(config, args) 23 | 24 | if not WINDOWS and args.no_kernel_threads: 25 | # Ignore kernel threads in process list 26 | glances_processes.disable_kernel_threads() 27 | 28 | # Set the args for the glances_processes instance 29 | glances_processes.set_args(args) 30 | 31 | # Initial system information update 32 | self.stats.update() 33 | 34 | # Init the Web server 35 | self.web = GlancesRestfulApi(config=config, args=args) 36 | 37 | def serve_forever(self): 38 | """Main loop for the Web server.""" 39 | self.web.start(self.stats) 40 | 41 | def end(self): 42 | """End of the Web server.""" 43 | self.web.end() 44 | self.stats.end() 45 | -------------------------------------------------------------------------------- /optional-requirements.txt: -------------------------------------------------------------------------------- 1 | # install with base requirements file 2 | -r requirements.txt 3 | 4 | batinfo; platform_system == 'Linux' 5 | bernhard 6 | cassandra-driver 7 | chevron 8 | docker>=6.1.1 9 | elasticsearch 10 | fastapi>=0.82.0 11 | graphitesender 12 | hddtemp 13 | influxdb>=1.0.0 # For InfluxDB < 1.8 14 | influxdb-client # For InfluxDB >= 1.8 and < 3.x 15 | influxdb3-python # For InfluxDB 3.x 16 | jinja2 17 | kafka-python 18 | netifaces2 19 | nvidia-ml-py 20 | orjson 21 | paho-mqtt 22 | pika 23 | podman 24 | potsdb 25 | prometheus_client 26 | pycouchdb 27 | pydantic 28 | pygal 29 | pymdstat 30 | pymongo 31 | pySMART.smartx 32 | pysnmp-lextudio<6.2.0 # Pinned witing implementation of #2874 33 | python-dateutil 34 | pyzmq 35 | requests 36 | six 37 | sparklines 38 | statsd 39 | uvicorn 40 | zeroconf 41 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:recommended" 5 | ], 6 | "prHourlyLimit": 3, 7 | "updateLockFiles": false 8 | } 9 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | defusedxml 2 | packaging 3 | psutil>=5.6.7 4 | shtab; platform_system != 'Windows' 5 | windows-curses; platform_system == 'Windows' 6 | -------------------------------------------------------------------------------- /run-venv.py: -------------------------------------------------------------------------------- 1 | #!./venv/bin/python 2 | import re 3 | import sys 4 | 5 | from glances import main 6 | 7 | if __name__ == '__main__': 8 | sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) 9 | sys.exit(main()) 10 | -------------------------------------------------------------------------------- /run.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import re 3 | import sys 4 | 5 | from glances import main 6 | 7 | if __name__ == '__main__': 8 | sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) 9 | sys.exit(main()) 10 | -------------------------------------------------------------------------------- /snap/local/launchers/glances-launch: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # This is the maintenance launcher for the snap, make necessary runtime 3 | # environment changes to make the snap work here. You may also insert 4 | # security confinement/deprecation/obsoletion notice of the snap here. 5 | set \ 6 | -o errexit \ 7 | -o errtrace \ 8 | -o nounset \ 9 | -o pipefail 10 | 11 | # Use user's real home directory for canonical configuration path access 12 | HOME="$( 13 | getent passwd "${USER}" \ 14 | | cut --delimiter=: --fields=6 15 | )" 16 | 17 | # Use snap's own folder for cache directory 18 | declare XDG_CACHE_HOME 19 | mkdir \ 20 | --parents \ 21 | "${SNAP_USER_DATA}"/.cache 22 | XDG_CACHE_HOME="${SNAP_USER_DATA}"/.cache 23 | export XDG_CACHE_HOME 24 | 25 | # Finally run the next part of the command chain 26 | exec "${@}" 27 | -------------------------------------------------------------------------------- /snap/snapcraft.yaml: -------------------------------------------------------------------------------- 1 | name: glances 2 | version: '4.3.1+build01' # Put the current stable version+buildXX 3 | 4 | summary: Glances an Eye on your system. A top/htop alternative. 5 | description: | 6 | Glances is a cross-platform monitoring tool which aims to present 7 | a maximum of information in a minimum of space through a curses or 8 | Web based interface. It can adapt dynamically the displayed information 9 | depending on the user interface size. 10 | 11 | base: core24 12 | grade: stable # devel 13 | confinement: strict 14 | 15 | apps: 16 | glances: 17 | command: bin/glances 18 | plugs: # https://snapcraft.io/docs/supported-interfaces 19 | - network 20 | - system-observe # This one should give read access to all the system 21 | - mount-observe 22 | - hardware-observe 23 | - log-observe 24 | - network-observe 25 | - physical-memory-observe 26 | - upower-observe 27 | - home 28 | - network-bind 29 | - uio 30 | - raw-volume 31 | - removable-media 32 | - power-control 33 | - process-control 34 | - network-setup-observe 35 | environment: 36 | LANG: C.UTF-8 37 | LC_ALL: C.UTF-8 38 | 39 | plugs: 40 | home-glances-config: 41 | interface: personal-files 42 | read: 43 | - $HOME/.config/glances/glances.conf 44 | etc-glances-config: 45 | interface: system-files 46 | read: 47 | - /etc/glances/glances.conf 48 | proc-sys: 49 | interface: system-observe 50 | 51 | parts: 52 | glances: 53 | plugin: python 54 | source: https://github.com/nicolargo/glances.git 55 | source-branch: master # develop 56 | python-requirements: 57 | - requirements.txt 58 | - webui-requirements.txt 59 | - docker-requirements.txt 60 | 61 | -------------------------------------------------------------------------------- /sonar-project.properties: -------------------------------------------------------------------------------- 1 | # Required metadata 2 | sonar.projectKey=glances 3 | sonar.projectName=Glances 4 | sonar.projectVersion=4.0 5 | 6 | # Path to the parent source code directory. 7 | # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. 8 | # Since SonarQube 4.2, this property is optional if sonar.modules is set. 9 | # If not set, SonarQube starts looking for source code from the directory containing 10 | # the sonar-project.properties file. 11 | sonar.sources=glances 12 | 13 | # Language 14 | sonar.language=py 15 | 16 | # Encoding of the source code 17 | sonar.sourceEncoding=UTF-8 18 | 19 | # Additional parameters 20 | #sonar.my.property=value 21 | -------------------------------------------------------------------------------- /tests-data/issues/issue2849.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | 4 | sys.path.insert(0, '../glances') 5 | 6 | ########### 7 | 8 | # from glances.cpu_percent import cpu_percent 9 | 10 | # for _ in range(0, 5): 11 | # print([i['total'] for i in cpu_percent.get_percpu()]) 12 | # time.sleep(2) 13 | 14 | ########### 15 | 16 | from glances.main import GlancesMain 17 | from glances.stats import GlancesStats 18 | 19 | core = GlancesMain() 20 | stats = GlancesStats(config=core.get_config(), args=core.get_args()) 21 | 22 | for _ in range(0, 5): 23 | stats.update() 24 | print([i['total'] for i in stats.get_plugin('percpu').get_raw()]) 25 | time.sleep(2) 26 | -------------------------------------------------------------------------------- /tests-data/plugins/gpu/amd/sys/class/drm/card0/device/gpu_busy_percent: -------------------------------------------------------------------------------- 1 | 10 2 | -------------------------------------------------------------------------------- /tests-data/plugins/gpu/amd/sys/class/drm/card0/device/hwmon/hwmon0/temp1_input: -------------------------------------------------------------------------------- 1 | 24000 2 | -------------------------------------------------------------------------------- /tests-data/plugins/gpu/amd/sys/class/drm/card0/device/mem_info_vram_total: -------------------------------------------------------------------------------- 1 | 2147483648 2 | -------------------------------------------------------------------------------- /tests-data/plugins/gpu/amd/sys/class/drm/card0/device/mem_info_vram_used: -------------------------------------------------------------------------------- 1 | 79949824 2 | -------------------------------------------------------------------------------- /tests-data/plugins/gpu/amd/sys/class/drm/card0/device/pp_dpm_mclk: -------------------------------------------------------------------------------- 1 | 0: 300Mhz * 2 | 1: 1000Mhz 3 | 2: 1500Mhz 4 | -------------------------------------------------------------------------------- /tests-data/plugins/gpu/amd/sys/class/drm/card0/device/pp_dpm_sclk: -------------------------------------------------------------------------------- 1 | 0: 214Mhz 2 | 1: 551Mhz * 3 | 2: 734Mhz 4 | 3: 1000Mhz 5 | 4: 1046Mhz 6 | 5: 1098Mhz 7 | 6: 1124Mhz 8 | 7: 1183Mhz 9 | -------------------------------------------------------------------------------- /tests-data/plugins/gpu/amd/sys/kernel/debug/dri/0/amdgpu_pm_info: -------------------------------------------------------------------------------- 1 | GFX Clocks and Power: 2 | 300 MHz (MCLK) 3 | 214 MHz (SCLK) 4 | 734 MHz (PSTATE_SCLK) 5 | 1000 MHz (PSTATE_MCLK) 6 | 700 mV (VDDGFX) 7 | 3.213 W (average GPU) 8 | 9 | GPU Temperature: 24 C 10 | GPU Load: 0 % 11 | MEM Load: 0 % 12 | 13 | UVD: Disabled 14 | 15 | VCE: Disabled 16 | Clock Gating Flags Mask: 0x3fbcf 17 | Graphics Fine Grain Clock Gating: Off 18 | Graphics Medium Grain Clock Gating: On 19 | Graphics Medium Grain memory Light Sleep: On 20 | Graphics Coarse Grain Clock Gating: On 21 | Graphics Coarse Grain memory Light Sleep: On 22 | Graphics Coarse Grain Tree Shader Clock Gating: Off 23 | Graphics Coarse Grain Tree Shader Light Sleep: Off 24 | Graphics Command Processor Light Sleep: On 25 | Graphics Run List Controller Light Sleep: On 26 | Graphics 3D Coarse Grain Clock Gating: Off 27 | Graphics 3D Coarse Grain memory Light Sleep: Off 28 | Memory Controller Light Sleep: On 29 | Memory Controller Medium Grain Clock Gating: On 30 | System Direct Memory Access Light Sleep: Off 31 | System Direct Memory Access Medium Grain Clock Gating: On 32 | Bus Interface Medium Grain Clock Gating: Off 33 | Bus Interface Light Sleep: On 34 | Unified Video Decoder Medium Grain Clock Gating: On 35 | Video Compression Engine Medium Grain Clock Gating: On 36 | Host Data Path Light Sleep: On 37 | Host Data Path Medium Grain Clock Gating: On 38 | Digital Right Management Medium Grain Clock Gating: Off 39 | Digital Right Management Light Sleep: Off 40 | Rom Medium Grain Clock Gating: On 41 | Data Fabric Medium Grain Clock Gating: Off 42 | VCN Medium Grain Clock Gating: Off 43 | Host Data Path Deep Sleep: Off 44 | Host Data Path Shutdown: Off 45 | Interrupt Handler Clock Gating: Off 46 | JPEG Medium Grain Clock Gating: Off 47 | Repeater Fine Grain Clock Gating: Off 48 | Perfmon Clock Gating: Off 49 | Address Translation Hub Medium Grain Clock Gating: Off 50 | Address Translation Hub Light Sleep: Off 51 | 52 | -------------------------------------------------------------------------------- /tests/conftest.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Glances - An eye on your system 4 | # 5 | # SPDX-FileCopyrightText: 2024 Nicolas Hennion 6 | # 7 | # SPDX-License-Identifier: LGPL-3.0-only 8 | # 9 | 10 | """Glances unitary tests suite for the WebUI. 11 | 12 | Need chromedriver command line (example on Ubuntu system): 13 | $ sudo apt install chromium-chromedriver 14 | 15 | The chromedriver command line should be in your path (/usr/bin) 16 | """ 17 | 18 | import logging 19 | import os 20 | import shlex 21 | import subprocess 22 | import time 23 | 24 | import pytest 25 | from selenium import webdriver 26 | from selenium.webdriver import ChromeOptions 27 | from selenium.webdriver.chrome.service import Service as ChromeService 28 | 29 | from glances.main import GlancesMain 30 | from glances.stats import GlancesStats 31 | 32 | SERVER_PORT = 61234 33 | URL = f"http://localhost:{SERVER_PORT}" 34 | 35 | 36 | @pytest.fixture(scope="session") 37 | def logger(): 38 | return logging.getLogger(__name__) 39 | 40 | 41 | @pytest.fixture(scope="session") 42 | def glances_stats(): 43 | core = GlancesMain(args_begin_at=2) 44 | stats = GlancesStats(config=core.get_config(), args=core.get_args()) 45 | yield stats 46 | stats.end() 47 | 48 | 49 | @pytest.fixture(scope="module") 50 | def glances_stats_no_history(): 51 | core = GlancesMain(args_begin_at=2) 52 | args = core.get_args() 53 | args.time = 1 54 | args.cached_time = 1 55 | args.disable_history = True 56 | stats = GlancesStats(config=core.get_config(), args=args) 57 | yield stats 58 | stats.end() 59 | 60 | 61 | @pytest.fixture(scope="session") 62 | def glances_webserver(): 63 | if os.path.isfile('./venv/bin/python'): 64 | cmdline = "./venv/bin/python" 65 | else: 66 | cmdline = "python" 67 | cmdline += f" -m glances -B 0.0.0.0 -w --browser -p {SERVER_PORT} -C ./conf/glances.conf" 68 | args = shlex.split(cmdline) 69 | pid = subprocess.Popen(args) 70 | time.sleep(3) 71 | yield pid 72 | pid.terminate() 73 | time.sleep(1) 74 | 75 | 76 | @pytest.fixture(scope="session") 77 | def web_browser(): 78 | """Init Firefox browser.""" 79 | opt = ChromeOptions() 80 | opt.add_argument("--headless") 81 | opt.add_argument("--start-maximized") 82 | srv = ChromeService() 83 | driver = webdriver.Chrome(options=opt, service=srv) 84 | 85 | # Yield the WebDriver instance 86 | driver.implicitly_wait(10) 87 | yield driver 88 | 89 | # Close the WebDriver instance 90 | driver.quit() 91 | -------------------------------------------------------------------------------- /tests/test_export_csv.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Exit on error 4 | set -e 5 | 6 | # Run glances with export to CSV file, stopping after 10 writes 7 | # This will run synchronously now since we're using --stop-after 8 | echo "Glances starts to export system stats to CSV file /tmp/glances.csv (duration: ~ 20 seconds)" 9 | rm -f /tmp/glances.csv 10 | ./venv/bin/python -m glances --export csv --export-csv-file /tmp/glances.csv --stop-after 10 --quiet 11 | 12 | echo "Checking CSV file..." 13 | ./venv/bin/python ./tests-data/tools/csvcheck.py -i /tmp/glances.csv -l 9 14 | -------------------------------------------------------------------------------- /tests/test_export_influxdb_v1.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Pre-requisites: 3 | # - docker 4 | # - jq 5 | 6 | # Exit on error 7 | set -e 8 | 9 | echo "Starting InfluxDB version 1 container..." 10 | docker run -d --name influxdb-v1-for-glances \ 11 | -p 8086:8086 \ 12 | influxdb:1.11 13 | 14 | # Wait for InfluxDB to be ready (retry for up to 30 seconds) 15 | echo "Waiting for InfluxDB to start..." 16 | for i in {1..30}; do 17 | if curl -s "http://localhost:8086/ping" > /dev/null; then 18 | echo "InfluxDB is up and running!" 19 | break 20 | fi 21 | 22 | if [ $i -eq 30 ]; then 23 | echo "Error: Timed out waiting for InfluxDB to start" 24 | docker stop influxdb-v1-for-glances 25 | docker rm influxdb-v1-for-glances 26 | exit 1 27 | fi 28 | 29 | echo "Waiting for InfluxDB to start... ($i/30)" 30 | sleep 1 31 | done 32 | 33 | # Create the glances database 34 | echo "Creating 'glances' database..." 35 | docker exec influxdb-v1-for-glances influx -execute 'DROP DATABASE glances' 36 | docker exec influxdb-v1-for-glances influx -execute 'CREATE DATABASE glances' 37 | 38 | # Run glances with export to InfluxDB, stopping after 10 writes 39 | # This will run synchronously now since we're using --stop-after 40 | echo "Glances to export system stats to InfluxDB (duration: ~ 20 seconds)" 41 | ./venv/bin/python -m glances --export influxdb --stop-after 10 --quiet 42 | 43 | echo "Checking if Glances data was successfully exported to InfluxDB..." 44 | # Query to check if data exists in the glances database 45 | MEASUREMENT_COUNT=$(docker exec influxdb-v1-for-glances influx -database 'glances' -format json -execute 'SHOW MEASUREMENTS' | jq '.results[0].series[0].values' | jq length) 46 | if [ "$MEASUREMENT_COUNT" -eq 0 ]; then 47 | echo "Error: No Glances measurement found in the InfluxDB database" 48 | docker stop influxdb-v1-for-glances 49 | docker rm influxdb-v1-for-glances 50 | exit 1 51 | else 52 | echo "Success! Found $MEASUREMENT_COUNT measurements in the Glances database." 53 | fi 54 | 55 | # Query to check if data exists in the glances database 56 | SERIE_COUNT=$(docker exec influxdb-v1-for-glances influx -database 'glances' -format json -execute 'SELECT * FROM cpu' | jq '.results[0].series[0].values' | jq length) 57 | if [ "$SERIE_COUNT" -eq 9 ]; then 58 | echo "Success! Found $SERIE_COUNT series in the Glances database (CPU plugin)." 59 | else 60 | echo "Error: Found $SERIE_COUNT series instead of 9" 61 | docker stop influxdb-v1-for-glances 62 | docker rm influxdb-v1-for-glances 63 | exit 1 64 | fi 65 | 66 | # Stop and remove the InfluxDB container 67 | echo "Stopping and removing InfluxDB container..." 68 | docker stop influxdb-v1-for-glances 69 | docker rm influxdb-v1-for-glances 70 | 71 | echo "Script completed successfully!" -------------------------------------------------------------------------------- /tests/test_export_json.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Exit on error 4 | set -e 5 | 6 | # Run glances with export to JSON file, stopping after 3 writes (to be sure rates are included) 7 | # This will run synchronously now since we're using --stop-after 8 | echo "Glances starts to export system stats to JSON file /tmp/glances.json (duration: ~ 10 seconds)" 9 | rm -f /tmp/glances.json 10 | ./venv/bin/python -m glances --export json --export-json-file /tmp/glances.json --stop-after 3 --quiet 11 | 12 | echo "Checking JSON file..." 13 | jq . /tmp/glances.json 14 | jq .cpu /tmp/glances.json 15 | jq .cpu.total /tmp/glances.json 16 | jq .mem /tmp/glances.json 17 | jq .mem.total /tmp/glances.json 18 | jq .processcount /tmp/glances.json 19 | jq .processcount.total /tmp/glances.json 20 | -------------------------------------------------------------------------------- /tests/test_memoryleak.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Glances - An eye on your system 4 | # 5 | # SPDX-FileCopyrightText: 2024 Nicolas Hennion 6 | # 7 | # SPDX-License-Identifier: LGPL-3.0-only 8 | # 9 | 10 | """Glances unitary tests suite for Glances memory leak.""" 11 | 12 | import time 13 | import tracemalloc 14 | 15 | 16 | def test_memoryleak_no_history(glances_stats_no_history, logger): 17 | """ 18 | Test Glances memory leak. 19 | """ 20 | tracemalloc.start() 21 | # First iterations just to init the stats and fill the memory 22 | logger.info('Please wait during memory leak test initialisation') 23 | iteration = 3 24 | for _ in range(iteration): 25 | glances_stats_no_history.update() 26 | time.sleep(1) 27 | 28 | # Then iteration to measure memory leak 29 | logger.info('Please wait during memory leak test') 30 | iteration = 10 31 | snapshot_begin = tracemalloc.take_snapshot() 32 | for _ in range(iteration): 33 | glances_stats_no_history.update() 34 | time.sleep(1) 35 | snapshot_end = tracemalloc.take_snapshot() 36 | snapshot_diff = snapshot_end.compare_to(snapshot_begin, 'filename') 37 | memory_leak = sum([s.size_diff for s in snapshot_diff]) // iteration 38 | logger.info(f'Memory consume per iteration: {memory_leak} bytes') 39 | assert memory_leak < 15000, f'Memory leak: {memory_leak} bytes' 40 | -------------------------------------------------------------------------------- /tests/test_perf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Glances - An eye on your system 4 | # 5 | # SPDX-FileCopyrightText: 2024 Nicolas Hennion 6 | # 7 | # SPDX-License-Identifier: LGPL-3.0-only 8 | # 9 | 10 | """Glances unitary tests suite for Glances perf.""" 11 | 12 | from glances.timer import Timer 13 | 14 | 15 | def test_perf_update(glances_stats): 16 | """ 17 | Test Glances perf. 18 | """ 19 | perf_timer = Timer(6) 20 | counter = 0 21 | while not perf_timer.finished(): 22 | glances_stats.update() 23 | counter += 1 24 | assert counter > 6 25 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | # Tox (http://tox.testrun.org/) is a tool for running tests 2 | # Install: 3 | # pip install tox 4 | # Run: 5 | # tox 6 | 7 | [tox] 8 | envlist = 9 | py39 10 | py310 11 | py311 12 | py312 13 | py313 14 | 15 | [testenv] 16 | deps = 17 | flake8 18 | psutil 19 | defusedxml 20 | packaging 21 | orjson 22 | fastapi 23 | uvicorn 24 | jinja2 25 | requests 26 | pytest 27 | commands = 28 | python -m pytest tests/test_core.py 29 | -------------------------------------------------------------------------------- /uninstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ $(id -u) -ne 0 ]; then 4 | echo -e "* ERROR: User $(whoami) is not root, and does not have sudo privileges" 5 | exit 1 6 | fi 7 | 8 | if [ ! -f "setup.py" ]; then 9 | echo -e "* ERROR: Setup file doesn't exist" 10 | exit 1 11 | fi 12 | 13 | 14 | 15 | python setup.py install --record install.record 16 | 17 | for i in $(cat install.record); do 18 | rm $i 19 | done 20 | 21 | echo -e "\n\n* SUCCESS: Uninstall complete." 22 | rm install.record 23 | -------------------------------------------------------------------------------- /webui-requirements.txt: -------------------------------------------------------------------------------- 1 | # install with base requirements file 2 | -r requirements.txt 3 | 4 | fastapi>=0.82.0; # ReST API Framework 5 | jinja2 # Template engine 6 | orjson # JSON Serialization speedup 7 | uvicorn # Webserver 8 | --------------------------------------------------------------------------------