Skip to content

Commit

Permalink
feat: add metric config gen
Browse files Browse the repository at this point in the history
  • Loading branch information
Bryanthelol committed Nov 20, 2023
1 parent dfebe7e commit 4ae5d09
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 12 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "pychassiscli"
version = "0.3.3"
version = "0.3.4"
description = "A lightweight Python distributed microservice command line tool"
authors = [
{ name = "BryantHe", email = "[email protected]" },
Expand Down
5 changes: 3 additions & 2 deletions src/pychassiscli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import click
from rich import print as rich_print

from pychassiscli.utils import get_directory, status, copy_files, check_docker
from pychassiscli.utils import get_directory, status, copy_files, check_docker, generate_metric_config

from pychassiscli.utils import (start_metric_servers, stop_metric_servers, start_prometheus, start_statsd_exporter,
start_statsd_agent, start_grafana, start_metric_network, stop_metric_network, stop_grafana,
Expand Down Expand Up @@ -62,13 +62,14 @@ def gen(directory, _type, nameko_module, class_name_str):
Generate a bunch of files of the project via templates.
"""
if _type == 'metrics':
rich_print('To be done')
if not nameko_module:
# TODO input 让用户在命令行输入
pass
if not class_name_str:
# TODO input 让用户在命令行输入
pass
generate_metric_config(nameko_module, class_name_str)

if _type == 'unit_test':
if not os.access(directory, os.F_OK) or not os.listdir(directory):
rich_print('Directory {} dose not exist or is empty'.format(directory))
Expand Down
3 changes: 2 additions & 1 deletion src/pychassiscli/templates/nameko/all_demo/all_demo.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import json

from nameko import config
from nameko.events import EventDispatcher, event_handler
from nameko.rpc import rpc, ServiceRpc
from nameko.timer import timer
Expand All @@ -15,7 +16,7 @@ class HttpDemoService:

tracer = Tracer()
sentry = init_sentry()
statsd = init_statsd('prod')
statsd = init_statsd(config['STATSD_PREFIX'], config['STATSD_HOST'])

@http("GET", "/broken")
@statsd.timer('broken')
Expand Down
11 changes: 3 additions & 8 deletions src/pychassiscli/templates/nameko/all_demo/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,9 @@ SENTRY:
CLIENT_CONFIG:
site: ${SENTRY_SITE}

STATSD:
prod:
enabled: true
protocol: "udp"
host: ${STATSD_HOST}
port: ${STATSD_PORT}
prefix: ${STATSD_PREFIX}
maxudpsize: 512
STATSD_HOST: ${STATSD_HOST}
STATSD_PORT: ${STATSD_PORT}
STATSD_PREFIX: ${STATSD_PREFIX}

DEBUG: ${DEBUG}

Expand Down
60 changes: 60 additions & 0 deletions src/pychassiscli/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,66 @@ def template_to_file(
f.write(output)


def generate_metric_config(nameko_module, class_name_str):
import sys
import inspect
import uuid
sys.path.append(os.getcwd())
for root, dirs, files in os.walk(os.getcwd()):
for _dir in dirs:
sys.path.append(os.path.join(root, _dir))

# Extract information of statsd config from the class of nameko service
file_name = nameko_module.split('.')[-1]
_module = __import__(nameko_module)

config_list = []
for class_name in class_name_str.split(','):
members = inspect.getmembers(getattr(getattr(_module, file_name), class_name), predicate=inspect.isfunction)
for member_tuple in members:
name, _obj = member_tuple
unwrap = inspect.getclosurevars(_obj)
if unwrap.nonlocals.get('self') and getattr(unwrap.nonlocals['self'], 'client'):
statsd_prefix = unwrap.nonlocals['self'].client._prefix
stat_name = unwrap.nonlocals['self'].stat
config_list.append({
'statsd_prefix': statsd_prefix,
'stat_name': stat_name,
'class_name': class_name
})

# Generate one file of statsd config yaml for statsd exporter
with status(f'Creating statsd_mapping.yml'):
metric_configs_dir = os.path.join(get_directory('templates'), 'metric-configs')
template_file_path = os.path.join(metric_configs_dir, 'statsd_mapping.yml.mako')
output_file = os.path.join('.', f'statsd_mapping.yml')
template_to_file(template_file=template_file_path, dest=output_file, output_encoding='utf-8',
**{'config_list': config_list})

# Generate files of json for grafana dashboard
if not os.access('grafana_dashboards', os.F_OK):
with status(f'Creating directory {os.path.abspath("grafana_dashboards")!r}'):
os.makedirs('grafana_dashboards')

with status(f'Creating files of Grafana.json into the directory of grafana_dashboards'):
for class_name in class_name_str.split(','):
grafana_list = []
for config in config_list:
if config['class_name'] == class_name:
grafana_list.append(config)
for idx, grafana_dict in enumerate(grafana_list):
if idx + 1 == len(grafana_list):
grafana_dict['is_last'] = 1
else:
grafana_dict['is_last'] = 0
grafana_configs_dir = os.path.join(get_directory('templates'), 'metric-configs')
grafana_file_path = os.path.join(grafana_configs_dir, 'grafana.json.mako')
output_file = os.path.join('grafana_dashboards', f'{class_name}_Grafana.json')
template_to_file(template_file=grafana_file_path, dest=output_file, output_encoding='utf-8',
**{'service_name': class_name, 'uid': uuid.uuid4(),
'grafana_list': grafana_list})


def start_network(network_name):
with status(f'Starting network {network_name}'):
docker.network.create(network_name, driver='bridge')
Expand Down

0 comments on commit 4ae5d09

Please sign in to comment.