1
0
Fork 0
bill_man/bill_man.py

155 lines
5.8 KiB
Python
Raw Normal View History

2018-08-21 10:27:31 +09:00
#!/usr/bin/env python3
import logging
2018-08-21 11:02:09 +09:00
from datetime import time, datetime
2018-08-21 10:27:31 +09:00
2018-08-21 11:02:09 +09:00
from util import install_except_hook, KSTTZ, UTCTZ
2018-08-21 10:27:31 +09:00
def handle_daemon(name, action, args):
log = logging.getLogger("main_loop")
2018-08-21 11:02:09 +09:00
from signal import SIGTERM
from util.log import wrap
2018-08-21 10:27:31 +09:00
if action == 'start':
# load config
2018-08-21 11:02:09 +09:00
from util import EnteringLoop
2018-08-21 10:27:31 +09:00
with EnteringLoop(
name,
log_dir=args.log_location,
log_level=args.log_level,
is_forground=args.foreground,
pid_path=args.pid_path
) as loop:
2018-08-21 11:02:09 +09:00
from apscheduler.jobstores.memory import MemoryJobStore
from apscheduler.executors.asyncio import AsyncIOExecutor
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from apscheduler.util import undefined
from signal import SIGTERM, SIGABRT, SIGINT, SIGQUIT
from handler import Session
import ujson
2018-08-21 10:27:31 +09:00
jobstores = {
'default': MemoryJobStore()
}
executors = {
'default': AsyncIOExecutor(),
}
job_defaults = {
'coalesce': True,
'max_instances': 2
}
scheduler = AsyncIOScheduler(
jobstores=jobstores,
executors=executors,
job_defaults=job_defaults,
timezone=KSTTZ,
event_loop=loop)
2018-08-21 11:02:09 +09:00
2018-08-21 10:27:31 +09:00
with open(args.config) as cfgFile:
config = ujson.load(cfgFile)
sess = Session(loop=loop, **config)
del config
job = scheduler.add_job(sess.get_resources,
name="charger",
trigger='cron',
day_of_week='mon-fri',
hour=args.standard_time.hour,
minute=args.standard_time.minute,
second=args.standard_time.second,
args=(args.standard_time,),
2018-08-21 11:02:09 +09:00
next_run_time=datetime.utcnow().replace(tzinfo=UTCTZ).astimezone(
KSTTZ) if args.immediately else undefined
2018-08-21 10:27:31 +09:00
)
scheduler.start()
2018-08-21 11:02:09 +09:00
2018-08-21 10:27:31 +09:00
if not args.immediately:
log.info("job(%s) may be start in %s", job.name, job.next_run_time)
2018-08-21 11:02:09 +09:00
2018-08-21 10:27:31 +09:00
def stopme(*_):
scheduler.shutdown()
sess.close()
log.info("handler closed")
loop.stop()
log.info("loop closed")
2018-08-21 11:02:09 +09:00
2018-08-21 10:27:31 +09:00
loop.add_signal_handler(SIGQUIT, stopme)
loop.add_signal_handler(SIGTERM, stopme)
loop.add_signal_handler(SIGINT, stopme)
loop.add_signal_handler(SIGABRT, stopme)
loop.run_forever()
log.info("bye!")
elif action == 'stop':
2018-08-21 11:02:09 +09:00
from os import path, kill
2018-08-21 10:27:31 +09:00
wrap(name, level=args.log_level, stderr=True)
if not path.exists(args.pid_path):
log.warning("cannot find pidfile(%s)", args.pid_path)
return
with open(args.pid_path, 'r') as pidFile:
pid = int(pidFile.readline())
kill(pid, SIGTERM)
log.warning("pid(%d) sigterm!", pid)
else:
raise NotImplementedError()
if __name__ == '__main__':
2018-08-21 11:02:09 +09:00
import argparse
from functools import partial
2018-08-21 10:27:31 +09:00
install_except_hook()
2018-08-21 11:02:09 +09:00
2018-08-21 10:27:31 +09:00
# 실행 플래그 파싱
parser = argparse.ArgumentParser(
prog='bill_man',
epilog='contact @spi-ca.',
description='report aws billing .',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
2018-08-21 11:02:09 +09:00
2018-08-21 10:27:31 +09:00
parser.add_argument('--pid_path',
help='specify pidPath',
default='bill_man.pid')
parser.add_argument('--log_level',
help='set logging level',
type=lambda level: logging._nameToLevel[level.upper()],
choices=logging._nameToLevel.keys(),
default='INFO')
2018-08-21 11:02:09 +09:00
2018-08-21 10:27:31 +09:00
parser.set_defaults(func=lambda *_: parser.print_help())
2018-08-21 11:02:09 +09:00
2018-08-21 10:27:31 +09:00
sp = parser.add_subparsers()
2018-08-21 11:02:09 +09:00
2018-08-21 10:27:31 +09:00
sp_start = sp.add_parser('start', help='Starts %(prog)s daemon',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
sp_start.add_argument('--config',
help='specify config file path',
default='bill_man.json')
sp_start.add_argument('--foreground',
help='Don\'t daemonize!',
default=False,
action='store_true')
sp_start.add_argument('--immediately',
help='run batch now!',
default=False,
action='store_true')
sp_start.add_argument('--log_location',
help='specify location of logs!',
default='log')
sp_start.add_argument('--standard_time',
help='set standard time/HHMMSS',
type=lambda ti: time(
hour=int(ti[0:2]),
minute=int(ti[2:4]),
second=int(ti[4:6]),
tzinfo=KSTTZ
),
default='120000')
2018-08-21 11:02:09 +09:00
sp_start.set_defaults(func=partial(handle_daemon, parser.prog, 'start'))
2018-08-21 10:27:31 +09:00
sp_stop = sp.add_parser('stop', help='Stop %(prog)s daemon',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
2018-08-21 11:02:09 +09:00
sp_stop.set_defaults(func=partial(handle_daemon, parser.prog, 'stop'))
2018-08-21 10:27:31 +09:00
args = parser.parse_args()
args.func(args)