diff --git a/Makefile b/Makefile index 2989c78..2f83227 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,11 @@ -build: ##build python patckage +build: clean ##build python patckage python setup.py sdist bdist_wheel -list: ##list all files from archive file of python package - tar tzf dist/awsinsights-1.0.0.tar.gz - check: #check python package using twine tool twine check dist/* -publish: build list check #publish python package to PyPI using twine tool +publish: build check #publish python package to PyPI using twine tool twine upload -r pypi dist/* clean: diff --git a/awsinsights/__main__.py b/awsinsights/__main__.py index 1d4007d..3063267 100644 --- a/awsinsights/__main__.py +++ b/awsinsights/__main__.py @@ -81,6 +81,8 @@ def main(): 'Format: YYYY-MM-DD HH:MM:SS') parser.add_argument('--filter', help='Regular expression for filtering logs', default="") + parser.add_argument('--tail', help='TAIL MODE. If set to "true", It will listen for ' + 'live logs forever', dest='tail', action="store_true") group = parser.add_mutually_exclusive_group(required=True) group.add_argument('--appname', help='name of the app which logs should ' \ @@ -128,6 +130,9 @@ def main(): logging.error("ERROR => Neither start/end pair nor timedelta is defined") parser.print_help() + if args.tail: + logging.info(bcolors.OKGREEN + "\n\n LISTENING IN TAIL MODE...\n" + bcolors.ENDC) + #start grabbing logs awsinsights.get_logs( start_time=start, @@ -135,7 +140,8 @@ def main(): query=args.query, appname=args.appname, log_groups=args.log_groups, - wait_sec=int(args.wait) + wait_sec=int(args.wait), + is_tail=args.tail, ) if __name__ == "__main__": diff --git a/awsinsights/awsinsights.py b/awsinsights/awsinsights.py index 87fea43..75d3461 100755 --- a/awsinsights/awsinsights.py +++ b/awsinsights/awsinsights.py @@ -28,7 +28,7 @@ class bcolors: def _is_recent_event_reached(recent_log_event, log_event): - if recent_log_event == None: + if recent_log_event is None: return True log_fields = {field['field'] : field['value'] for field in log_event} @@ -47,7 +47,14 @@ def _utc_to_local(utc_datetime): return utc_datetime + offset -def get_logs(start_time, end_time, query, appname=None, log_groups=None, wait_sec=10): +def get_logs(start_time, + end_time, + query, + appname=None, + log_groups=None, + wait_sec=10, + is_tail=False + ): insights = boto3.client('logs') @@ -59,29 +66,38 @@ def get_logs(start_time, end_time, query, appname=None, log_groups=None, wait_se logging.error(bcolors.FAIL + "0 log groups configured" + bcolors.ENDC) return - log_limit=10000 + log_limit = 10000 results = {'results' : []} recent_timestamp = None recent_log_event = None with open(filename, "w+") as output_file: - while len(results['results']) in (0, log_limit): + while len(results['results']) in (0, log_limit) or is_tail: if recent_timestamp: - start_time = datetime.datetime.strptime(str(recent_timestamp), "%Y-%m-%d %H:%M:%S.%f") + start_time = datetime.datetime.strptime(str(recent_timestamp), + "%Y-%m-%d %H:%M:%S.%f") start_time = _utc_to_local(start_time) + if is_tail: + end_time = datetime.datetime.now() + + logging.debug(f"start_time: {start_time}") + logging.debug(f"end_time: {end_time}") + async_resp = insights.start_query( - logGroupNames = log_groups, - startTime = int(start_time.timestamp()), - endTime = int(end_time.timestamp()), - queryString = query, - limit = log_limit, - ) + logGroupNames=log_groups, + startTime=int(start_time.timestamp()), + endTime=int(end_time.timestamp()), + queryString=query, + limit=log_limit, + ) status = 'Running' while status not in ('Complete', 'Failed', 'Cancelled', 'Timeout'): - logging.info(bcolors.HEADER + f"waiting {wait_sec} seconds for query results - status: {status}" + bcolors.ENDC) + if not is_tail: + logging.info(bcolors.HEADER + f"waiting {wait_sec} seconds for " + f"query results - status: {status}" + bcolors.ENDC) time.sleep(wait_sec) results = insights.get_query_results(queryId=async_resp['queryId']) status = results['status'] @@ -107,6 +123,7 @@ def get_logs(start_time, end_time, query, appname=None, log_groups=None, wait_se if len(results['results']) > 0: recent_log_event = results['results'][-1] else: - logging.warn(bcolors.WARNING + " => 0 logs found which match defined filter..." + bcolors.ENDC) - break - + if not is_tail: + logging.warn(bcolors.WARNING + " => 0 logs found which " + "match defined filter..." + bcolors.ENDC) + break diff --git a/setup.py b/setup.py index b1c1f1b..fdf07b7 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ # This call to setup() does all the work setup( name="awsinsights", - version="1.0.1", + version="1.0.2", description="Get, sort and analyse AWS CloudWatch logs from multiple log groups using AWS CloudWatch Insights service", long_description=README, long_description_content_type="text/markdown",