Skip to content

Commit

Permalink
Merge pull request #7 from niaid/dev
Browse files Browse the repository at this point in the history
Add presets feature
  • Loading branch information
stolarczyk authored Nov 8, 2022
2 parents fa5dbcd + 3849e85 commit bdd2f01
Show file tree
Hide file tree
Showing 32 changed files with 1,760 additions and 1,677 deletions.
21 changes: 21 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
version: "3"

tasks:
jupyter:
cmds:
- poetry run jupyter nbconvert docs/API_usage.ipynb --to markdown --output API_usage.md
serve_docs:
deps:
- jupyter
cmds:
- poetry run mkdocs serve
build_docs:
deps:
- jupyter
cmds:
- poetry run mkdocs build
deploy_docs:
deps:
- jupyter
cmds:
- poetry run mkdocs gh-deploy
28 changes: 0 additions & 28 deletions cloudwatcher/__init__.py
Original file line number Diff line number Diff line change
@@ -1,28 +0,0 @@
from ._version import __version__
from .cloudwatcher import CloudWatcher
from .logwatcher import LogWatcher
from .metric_handlers import (
ResponseLogger,
ResponseSaver,
TimedMetricCsvSaver,
TimedMetricJsonSaver,
TimedMetricLogger,
TimedMetricPlotter,
TimedMetricSummarizer,
)
from .metricwatcher import MetricWatcher

__classes__ = [
"CloudWatcher",
"MetricWatcher",
"LogWatcher",
"ResponseLogger",
"ResponseSaver",
"TimedMetricCsvSaver",
"TimedMetricJsonSaver",
"TimedMetricLogger",
"TimedMetricPlotter",
"TimedMetricSummarizer",
]

__all__ = __classes__ + ["__version__"]
2 changes: 1 addition & 1 deletion cloudwatcher/__main__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging
import sys

from .cli import main
from cloudwatcher.cli import main

if __name__ == "__main__":

Expand Down
1 change: 0 additions & 1 deletion cloudwatcher/_version.py

This file was deleted.

79 changes: 46 additions & 33 deletions cloudwatcher/argparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@

import argparse

from ._version import __version__
from .const import CLI_DEFAULTS, LOG_CMD, METRIC_CMD, SUBPARSER_MESSAGES
from cloudwatcher.const import CLI_DEFAULTS, LOG_CMD, METRIC_CMD, SUBPARSER_MESSAGES
from importlib.metadata import version

cloudwatcher_version = version("cloudwatcher")


class _VersionInHelpParser(argparse.ArgumentParser):
def format_help(self):
"""Add version information to help text."""
return (
f"version: {__version__}\nDocumentation available at: https://niaid.github.io/cloudwatcher\n\n"
f"version: {cloudwatcher_version}\nDocumentation available at: "
"https://niaid.github.io/cloudwatcher\n\n"
+ super(_VersionInHelpParser, self).format_help()
)

Expand Down Expand Up @@ -42,7 +45,7 @@ def add_subparser(cmd, msg, subparsers):
"--version",
help="Print version and exit",
action="version",
version="%(prog)s {}".format(__version__),
version=f"%(prog)s {cloudwatcher_version}",
)
sps[cmd].add_argument(
"--debug",
Expand Down Expand Up @@ -93,46 +96,19 @@ def add_subparser(cmd, msg, subparsers):
default=CLI_DEFAULTS["dir"],
)

sps[METRIC_CMD].add_argument(
"-q",
"--query-json",
help="Path to a query JSON file. This is not implemented yet.",
required=False,
default=None,
metavar="Q",
)
sps[METRIC_CMD].add_argument(
"-i",
"--id",
help="The unique identifier to assign to the metric data. Must be of the form '^[a-z][a-zA-Z0-9_]*$'.",
default=CLI_DEFAULTS["id"],
required=False,
metavar="ID",
)
sps[METRIC_CMD].add_argument(
"-m",
"--metric",
help="Name of the metric collected by CloudWatchAgent (default: %(default)s)",
default=CLI_DEFAULTS["metric_name"],
required=False,
metavar="N",
)
sps[METRIC_CMD].add_argument(
"-dn",
"--dimension-name",
help="The name of the dimension to query. (default: %(default)s)",
required=False,
type=str,
metavar="N",
default=CLI_DEFAULTS["dimension_name"],
)
sps[METRIC_CMD].add_argument(
"-dv",
"--dimension-value",
help="The value of the dimension to filter on.",
required=True,
type=str,
metavar="V",
)
sps[METRIC_CMD].add_argument(
"--uptime",
Expand Down Expand Up @@ -166,6 +142,44 @@ def add_subparser(cmd, msg, subparsers):
type=int,
metavar="M",
)
sps[METRIC_CMD].add_argument(
"--dimensions",
help="Elements of the dimensions list to use. Must be of the form: name1:value1 name2:value2",
default=None,
type=str,
metavar="A",
nargs="+",
)
preset = sps[METRIC_CMD].add_argument_group(
"PRESETS", "Use one of the predefined presets to collect metrics."
)
preset.add_argument(
"--preset-list",
help="List all available presets.",
action="store_true",
)
preset.add_argument(
"--preset-dir",
help="Path to the preset directory",
default=None,
type=str,
metavar="D",
)
preset.add_argument(
"--preset-name",
help="Name of the preset to use.",
default=None,
type=str,
metavar="N",
)
preset.add_argument(
"--preset-path",
help="Path to the preset file to use.",
default=None,
type=str,
metavar="P",
)

sps[METRIC_CMD].add_argument(
"-u",
"--unit",
Expand All @@ -189,7 +203,7 @@ def add_subparser(cmd, msg, subparsers):
"-p",
"--period",
help="""
The granularity, in seconds, of the returned data points. Choices: 1, 5, 10, 30, 60, or any multiple of 60 (default: %(default)s).
The granularity, in seconds, of the returned data points. Choices: 1, 5, 10, 30, 60, or any multiple of 60 (default: %(default)s).
It affects the data availability. See the docs 'Usage' section for more details.
""",
default=CLI_DEFAULTS["period"],
Expand All @@ -205,7 +219,6 @@ def add_subparser(cmd, msg, subparsers):
"--namespace",
help="Namespace to monitor the metrics within. This value must match the 'Namespace' value in the CloudWatchAgent config.",
type=str,
required=True,
metavar="N",
)
sps[LOG_CMD].add_argument(
Expand Down
32 changes: 15 additions & 17 deletions cloudwatcher/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
import sys

from rich.logging import RichHandler
from rich.console import Console
from pathlib import Path

from cloudwatcher.const import LOG_CMD, METRIC_CMD
from cloudwatcher.logwatcher import LogWatcher

from .argparser import build_argparser
from .metricwatcher import MetricWatcher
from .preset import get_metric_watcher_setup, PresetFilesInventory


def main():
Expand All @@ -33,25 +36,19 @@ def main():
_LOGGER.debug(f"CLI arguments: {args}")

if args.command == METRIC_CMD:
if args.query_json is not None:
raise NotImplementedError("Querying via JSON is not yet implemented")

if args.preset_list:
Console().print(
PresetFilesInventory(presets_dir=args.preset_dir).presets_table
)
sys.exit(0)

if not os.path.exists(args.dir):
_LOGGER.info(f"Creating directory: {args.dir}")
os.makedirs(args.dir, exist_ok=True)

metric_watcher = MetricWatcher(
namespace=args.namespace,
metric_name=args.metric,
metric_id=args.id,
metric_unit=args.unit,
dimension_value=args.dimension_value,
dimension_name=args.dimension_name,
aws_access_key_id=args.aws_access_key_id,
aws_secret_access_key=args.aws_secret_access_key,
aws_session_token=args.aws_session_token,
aws_region_name=args.aws_region,
)
mw_setup = get_metric_watcher_setup(namespace=args, presets_dir=args.preset_dir)
metric_watcher = MetricWatcher(**mw_setup.to_dict())

response = metric_watcher.query_ec2_metrics(
days=args.days,
Expand All @@ -65,7 +62,7 @@ def main():
metric_watcher.log_metric(response=response)
metric_watcher.log_metric_summary(response=response)

name_prefix = f"{args.dimension_name}_{args.dimension_value}_{args.metric}"
name_prefix = f"{metric_watcher.metric_id}_{metric_watcher.metric_name}"
if args.save:
metric_watcher.save_metric_json(
file_path=os.path.join(args.dir, f"{name_prefix}.json"),
Expand All @@ -87,10 +84,11 @@ def main():
)

if args.uptime:
if not args.dimension_value.startswith("i-"):
if not args.dimension_name == "InstanceId":
_LOGGER.error(
"Uptime is only available for EC2 instances. "
"Please provide an EC2 instance ID as the dimension value."
"Please provide 'InstanceId' as dimension name and EC2 instance id"
" as the dimension value."
)
sys.exit(1)
try:
Expand Down
11 changes: 6 additions & 5 deletions cloudwatcher/cloudwatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ def __init__(
"""
Initialize CloudWatcher
:param str service_name: The name of the service
:param str region_name: The name of the region. Defaults to 'us-east-1'
:param Optional[str] aws_access_key_id: The AWS access key ID
:param Optional[str] aws_secret_access_key: The AWS secret access key
:param Optional[str] aws_session_token: The AWS session token
Args:
service_name (str): The name of the service to use
aws_region_name (Optional[str]): The AWS region name. Defaults to 'us-east-1'
aws_access_key_id (Optional[str]): The AWS access key ID. Defaults to None
aws_secret_access_key (Optional[str]): The AWS secret access key. Defaults to None
aws_session_token (Optional[str]): The AWS session token. Defaults to None
"""
self.aws_region_name = aws_region_name or "us-east-1"
self.service_name = service_name
Expand Down
8 changes: 1 addition & 7 deletions cloudwatcher/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,10 @@
"stat": "Maximum",
"period": 5,
}
QUERY_KWARGS_PRESETS = {
"day": {"days": 1, "hours": 0, "minutes": 0, "stat": "Maximum", "period": 10},
"hour": {"days": 0, "hours": 1, "minutes": 0, "stat": "Maximum", "period": 1},
"minute": {"days": 0, "hours": 0, "minutes": 1, "stat": "Maximum", "period": 1},
}

CLI_DEFAULTS = {
"metric_name": "mem_used",
"id": "memory_usage",
"dimension_name": "InstanceId",
"id": "provide_metric_id",
"days": 1,
"hours": 0,
"minutes": 0,
Expand Down
Loading

0 comments on commit bdd2f01

Please sign in to comment.