diff --git a/usage-monitoring/README.md b/usage-monitoring/README.md index 19d3986..7e608d3 100644 --- a/usage-monitoring/README.md +++ b/usage-monitoring/README.md @@ -9,10 +9,16 @@ Create a conda environment with the necessary additional dependencies with: ## Usage For usage run `python usage_monitoring.py`. When running this script, you will -need to `source` a valid `openrc.sh`. +need to `source` a valid `openrc.sh` or have a valid `clouds.yaml` in `~/.config/openstack/`. See the [Jetstream2 docs](https://docs.jetstream-cloud.org/ui/cli/auth/) for -information on how to acquire an `openrc.sh` file. +information on how to acquire an `openrc.sh` or `clouds.yaml` file. + +### Installing + +Run the included `install.sh` script. This will create the appropriate directories if necessary and soft/symlink the appropriate files. To "uninstall" the script, simply remove the symlinks. + +Finally, ensure that `~/.local/bin` is in your `PATH`. ### Activating the Environment @@ -26,6 +32,10 @@ environment, use `conda run`, as in `usage_monitoring.sh`: `conda run -n usage-monitoring python usage_monitoring.py [options]` +Additionally, if you've configured your shell to include `~/.local/bin` in your `PATH`, you can run `usage_monitoring.py` as an executable, as the script includes the appropriate "hashbang" (a.k.a. "shebang" `#!`): + +`usage_monitoring.py [options]` + # Cron To collect usage data on a daily basis, run the wrapper script (after setting diff --git a/usage-monitoring/usage_monitoring.py b/usage-monitoring/usage_monitoring.py index 4ff485a..1c59532 100755 --- a/usage-monitoring/usage_monitoring.py +++ b/usage-monitoring/usage_monitoring.py @@ -1,7 +1,8 @@ -#! /usr/bin/env conda run -n usage-monitoring python +#! /usr/bin/env -S conda run -n usage-monitoring python -from subprocess import run +from subprocess import run, CalledProcessError from os.path import isfile, expanduser +from sys import stderr import argparse @@ -21,15 +22,25 @@ def load_config(config_path): c['test_csv_file'] = expanduser(c['test_csv_file']) return c except FileNotFoundError: - print(f'File {config_path} not found! Exiting ...') + print(f'File {config_path} not found! Exiting ...', file=stderr) exit(1) def create_os_token(token_file): - token = run( - ['openstack', 'token', 'issue', '-f', 'json'], - capture_output=True, - check=True - ) + try: + token = run( + ['openstack', 'token', 'issue', '-f', 'json'], + capture_output=True, + check=True + ) + except CalledProcessError as ex: + print( + f'{ex}\n', + f'STDOUT: {ex.stdout.decode()}\n', + f'STDERR: {ex.stderr.decode()}\n' + 'It is possible that a valid openrc.sh was not sourced. Exiting ...', + file=stderr + ) + exit(1) with open(token_file, 'w') as f: f.write(token.stdout.decode()) @@ -54,7 +65,7 @@ def query_accounting_api(token): try: response.raise_for_status() except Exception as ex: - print(ex) + print(ex, file=stderr) exit(1) query = json.loads(response.text) return query @@ -265,7 +276,7 @@ def generate_usage_plot(resources, analyses, allocation_resources): for resource_type in allocation_resources: data = get_data_by_resource(resources, resource_type) if data.empty: - print(f'No available data for {resource_type}') + print(f'No available data for {resource_type}', file=stderr) continue timestamps = pd.array(data['timestamp']) @@ -324,10 +335,10 @@ def main(): for resource_type in c['allocation_resources']: data = get_data_by_resource(resources, resource_type) if data.empty: - print(f'No available data for {resource_type}. Skipping ...') + print(f'No available data for {resource_type}. Skipping ...', file=stderr) continue if len(data) < 2: - print(f'Not enough data for {resource_type}: len(data) = {len(data)}. Skipping ...') + print(f'Not enough data for {resource_type}: len(data) = {len(data)}. Skipping ...', file=stderr) # Perform analysis (usage rates, "forecast", ) analyses.append(usage_analysis(data,args['analysis_days']))