Metadata-Version: 2.1
Name: monero_health
Version: 1.1.3
Summary: Check health of monero daemons.
Home-page: https://github.com/normoes/monero_health
Author: Norman Moeschter-Schenck
Author-email: norman.moeschter@gmail.com
Maintainer: Norman Moeschter-Schenck
Maintainer-email: <norman.moeschter@gmail.com>
License: UNKNOWN
Download-URL: https://github.com/normoes/monero_health/archive/v1.1.3.tar.gz
Description: [![GitHub Release](https://img.shields.io/github/v/release/normoes/monero_health.svg)](https://github.com/normoes/monero_health/releases)
        [![GitHub Tags](https://img.shields.io/github/v/tag/normoes/monero_health.svg)](https://github.com/normoes/monero_health/tags?sort=semver)
        
        # Monero health
        
        Monero health is supposed to provide information about the Monero daemon health.
        
        There are 3 health checks at the moment:
        * Checking the Monero daemon RPC status using the `hard_fork_info` RPC.
        * Checking the Monero daemon P2P status (checks the given P2P port).
        * Checking the age of the last block on the daemon using a pre-configured offset.
        
        **_Note_**:
        
        The Monero daemon RPC information are retrieved using the Monero daemon JSON RPC.
        The RPC connection is established using [`python-monerorpc`](https://github.com/monero-ecosystem/python-monerorpc).
        
        ## Configuration
        
        ### Monero daemon RPC connection
        The connection to the Monero daemon RPC can be configured using environment variables:
        
        | environment variable | default value |
        |----------------------|---------------|
        | `MONEROD_URL` | `"127.0.0.1"` |
        | `MONEROD_RPC_PORT` | `18081` |
        | `MONEROD_P2P_PORT` | `18080` |
        | `MONEROD_RPC_USER` | `""` |
        | `MONEROD_RPC_PASSWORD` | `""` |
        
        **_Note_**:
        
        The RPC connection is established using [`python-monerorpc`](https://github.com/monero-ecosystem/python-monerorpc).
        
        ### Last block age
        ```
        from monero_health.monero_health import daemon_last_block_check
        ```
        
        The last block's timestamp is checked against a given pre-configured offset:
        
        | environment variable | default value |
        |----------------------|---------------|
        | `OFFSET` | `12` |
        | `OFFSET_UNIT` | `"minutes"` |
        
        I.e that the last block is considered out-of-date as soon as it becomes older than - in the default case - `12 [minutes]`.
        
        The Monero RPC method used is:
        * `get_last_block_header`
        
        ### Daemon RPC status
        ```
        from monero_health.mmonero_health import daemon_rpc_status_check
        ```
        
        No additional configuration needed.
        
        The Monero RPC method used is:
        * `hard_fork_info`
        
        ### Daemon P2P status
        ```
        from monero_health.mmonero_health import daemon_p2p_status_check
        ```
        
        No additional configuration is needed.
        
        A socket connection is established, which checks the connectivity to the P2P port.
        
        ## Results
        
        ### JSON response
        This module is not really supposed to be run as a script, rather as a module.
        
        However, it is possible to directly run it as a script. it will then output the complete information. The following only shows part of it, sepcifically the result of the method `daemon_combined_status_check`:
        ```python
            MONEROD_URL=mainnet.community.xmr.to python -m monero_health.monero_health
            ...
            {
                "last_block": {
                    "hash": "2931d04a73c4e286d1e568a0e61ba37fdf175ff6974d343ca136c62ecaaeeee4",
                    "block_age": "0:01:57",
                    "block_timestamp": "2020-09-23T19:40:02",
                    "check_timestamp": "2020-09-23T19:41:59",
                    "status": "OK",
                    "block_recent": true,
                    "block_recent_offset": 12,
                    "block_recent_offset_unit": "minutes",
                    "host": "mainnet.community.xmr.to:18081"
                },
                "monerod": {
                    "rpc": {
                        "status": "OK",
                        "host": "mainnet.community.xmr.to:18081"
                    },
                    "p2p": {
                        "status": "OK",
                        "host": "mainnet.community.xmr.to:18080"
                    },
                    "status": "OK",
                    "host": "mainnet.community.xmr.to",
                    "version": 12
                },
                "status": "OK",
                "host": "mainnet.community.xmr.to"
            }
        ```
        
        When imported as a module the functions can be imported/called separately, like this:
        * Last block age:
        ```python
            from monero_health.mmonero_health import (
                daemon_last_block_check,
            )
            ...
            result = daemon_last_block_check()
            ...
        ```
        * Monero daemaon status:
        ```python
            from monero_health.mmonero_health import (
                daemon_status_check,
            )
            ...
            result = daemon_status_check()
            ...
        ```
        * Combined daemon status:
        ```python
            from monero_health.mmonero_health import (
                daemon_combined_status_check,
            )
            ...
            result = daemon_combined_status_check()
            ...
        ```
        
        ### Possible status values
        
        The `status` returned can have the following values:
        * `OK`
          - For a last block that **is not** considered old: (`daemon_last_block_check`)
          - For a daemon with status `OK`: (`daemon_rpc_status_check`, `daemon_p2p_status_check`, `daemon_stati_check`)
          - Every possible status is `OK`: (`daemon_combined_status_check`)
        * `ERROR`
          - For a last block that **is** considered old: (`daemon_last_block_check`)
          - For a daemon with status `ERROR`: (`daemon_rpc_status_check`, `daemon_p2p_status_check`, `daemon_stati_check`)
          - At least one possible status is `ERROR`: (`daemon_combined_status_check`)
        * `UNKNOWN`
          - In case of a connection error not initiated by the peer (mostly related to HTTP requests): (`daemon_last_block_check`, `daemon_rpc_status_check`, `daemon_p2p_status_check`, `daemon_stati_check`)
          - At least one possible status is `UNKNOWN`: (`daemon_combined_status_check`)
        
        ### Errors
        
        In case of an error, an `error` key is added to the responses of:
        * `daemon_last_block_check`
        * `daemon_rpc_status_check`, `daemon_p2p_status_check`, `daemon_stati_check`
        but not to `daemon_combined_status_check`.
        
        This error key always contains the keys:
        * `error`
        * `message`
        
        Example - No Monero daemon running at `127.0.0.1:18081`:
        ```
        {
            "hash": "---",
            "block_age": -1,
            "block_timestamp": "---",
            "check_timestamp": "2020-09-24T11:52:30",
            "status": "UNKNOWN",
            "block_recent": false,
            "block_recent_offset": 12,
            "block_recent_offset_unit": "minutes",
            "host": "mainnet.community.xmr:18081",
            "error": {
                "message": "Cannot determine status.",
                "error": "-341: Could not establish a connection, original error: 'HTTPConnectionPool(host='mainnet.community.xmr', port=18081): Max retries exceeded with url: /json_rpc (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f0f3bb5b150>: Failed to establish a new connection: [Errno -5] No address associated with hostname'))'."
            }
        }
        ```
        
        ## Full example
        
        When run as a script (against the XMR.to public node `node.xmr.to`):
        ```
        MONEROD_URL=mainnet.community.xmr.to python -m monero_health.monero_health
        ```
        
        All health and status checks are run one after another against `mainnet.community.xmr.to`:
        * Last block (last block's timestamp).
        * Daemon RPC status (port `18081`, RPC method `hard_fork_info`).
        * Daemon P2P status (port `18080`).
        * Both dameon stati (combined `status` key).
        * Run all checks **but do not consider** the daemon P2P status in the resulting `status` key (dameon P2P result is still returned).
        * Run all checks **and consider** the daemon P2P status in the resulting `status` key.
        
        The result will look like this:
        ```
        ----Last block check----:
        INFO:DaemonHealth:Checking 'mainnet.community.xmr.to:18081'.
        {"hash": "441380be4c9f10e6ceaec1daeab716cfffab22a8c2adbf765d00fc8d34effe23", "block_age": "0:01:13", "block_timestamp": "2020-09-23T19:50:11", "check_timestamp": "2020-09-23T19:51:24", "status": "OK", "block_recent": true, "block_recent_offset": 12, "block_recent_offset_unit": "minutes", "host": "mainnet.community.xmr.to:18081"}
        ----Daemon rpc check----
        INFO:DaemonHealth:Checking 'mainnet.community.xmr.to:18081'.
        {"status": "OK", "version": 12, "host": "mainnet.community.xmr.to:18081"}
        ----Daemon p2p check----
        INFO:DaemonHealth:Checking 'mainnet.community.xmr.to:18080'.
        INFO:monero_scripts.connect_to_node:Trying to connect to 'mainnet.community.xmr.to:18080'.
        INFO:monero_scripts.connect_to_node:Successfully connected to 'mainnet.community.xmr.to:18080'.
        {"status": "OK", "host": "mainnet.community.xmr.to:18080"}
        ----Daemon stati check, not considering P2P status----
        INFO:DaemonHealth:Checking 'mainnet.community.xmr.to:18081'.
        INFO:DaemonHealth:{"message": "Combined daemon status (RPC, P2P) is 'OK'."}
        {"rpc": {"status": "OK", "host": "mainnet.community.xmr.to:18081"}, "status": "OK", "host": "mainnet.community.xmr.to", "version": 12}
        ----Daemon stati check, also considering P2P status----
        INFO:DaemonHealth:Checking 'mainnet.community.xmr.to:18081'.
        INFO:DaemonHealth:Checking 'mainnet.community.xmr.to:18080'.
        INFO:monero_scripts.connect_to_node:Trying to connect to 'mainnet.community.xmr.to:18080'.
        INFO:monero_scripts.connect_to_node:Successfully connected to 'mainnet.community.xmr.to:18080'.
        INFO:DaemonHealth:{"message": "Combined daemon status (RPC, P2P) is 'OK'."}
        {"rpc": {"status": "OK", "host": "mainnet.community.xmr.to:18081"}, "p2p": {"status": "OK", "host": "mainnet.community.xmr.to:18080"}, "status": "OK", "host": "mainnet.community.xmr.to", "version": 12}
        ----Overall check, not considering P2P status----
        INFO:DaemonHealth:Checking 'mainnet.community.xmr.to:18081'.
        INFO:DaemonHealth:Checking 'mainnet.community.xmr.to:18081'.
        INFO:DaemonHealth:{"message": "Combined daemon status (RPC, P2P) is 'OK'."}
        INFO:DaemonHealth:{"message": "Combined status is 'OK'."}
        {"last_block": {"hash": "441380be4c9f10e6ceaec1daeab716cfffab22a8c2adbf765d00fc8d34effe23", "block_age": "0:01:20", "block_timestamp": "2020-09-23T19:50:11", "check_timestamp": "2020-09-23T19:51:31", "status": "OK", "block_recent": true, "block_recent_offset": 12, "block_recent_offset_unit": "minutes", "host": "mainnet.community.xmr.to:18081"}, "monerod": {"rpc": {"status": "OK", "host": "mainnet.community.xmr.to:18081"}, "status": "OK", "host": "mainnet.community.xmr.to", "version": 12}, "status": "OK", "host": "mainnet.community.xmr.to"}
        ----Overall check, also considering P2P status----
        INFO:DaemonHealth:Checking 'mainnet.community.xmr.to:18081'.
        INFO:DaemonHealth:Checking 'mainnet.community.xmr.to:18081'.
        INFO:DaemonHealth:Checking 'mainnet.community.xmr.to:18080'.
        INFO:monero_scripts.connect_to_node:Trying to connect to 'mainnet.community.xmr.to:18080'.
        INFO:monero_scripts.connect_to_node:Successfully connected to 'mainnet.community.xmr.to:18080'.
        INFO:DaemonHealth:{"message": "Combined daemon status (RPC, P2P) is 'OK'."}
        INFO:DaemonHealth:{"message": "Combined status is 'OK'."}
        {"last_block": {"hash": "441380be4c9f10e6ceaec1daeab716cfffab22a8c2adbf765d00fc8d34effe23", "block_age": "0:01:21", "block_timestamp": "2020-09-23T19:50:11", "check_timestamp": "2020-09-23T19:51:32", "status": "OK", "block_recent": true, "block_recent_offset": 12, "block_recent_offset_unit": "minutes", "host": "mainnet.community.xmr.to:18081"}, "monerod": {"rpc": {"status": "OK", "host": "mainnet.community.xmr.to:18081"}, "p2p": {"status": "OK", "host": "mainnet.community.xmr.to:18080"}, "status": "OK", "host": "mainnet.community.xmr.to", "version": 12}, "status": "OK", "host": "mainnet.community.xmr.to"}
        ```
        
        ## Tests and development
        ```
        # Create and activate a virtual environment.
        python -m venv venv
        . venv/bin/activate
        
        # Install the dependencies.
        pip install --upgrade pip-tools
        pip-sync requirements.txt
        
        # Run tests.
        pytest
        ```
        
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: English
Classifier: Programming Language :: Python
Description-Content-Type: text/markdown
Provides-Extra: test
