Last active
November 27, 2017 16:05
-
-
Save mdellavo/4a810db6d47e441a97d53391dc74cbb1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# sudo zcat /db/logs/mongodb.log.6.gz | /tmp/mongo_slow_log.py 100 2017-01-01T00:00:00 2017-01-01T00:01:00 | |
import re | |
import sys | |
import datetime | |
DATETIME_ARG_FORMAT = "%Y-%m-%dT%H:%M:%S" | |
MONGO_TIMESTAMP_FORMAT = "%Y-%m-%dT%H:%M:%S.%f+0000" | |
ELAPSED_PATTERN = re.compile(r' (\d+)ms$') | |
def is_slow_op(line, threshold): | |
match = ELAPSED_PATTERN.search(line.strip()) | |
return match and int(match.group(1)) >= threshold | |
# FIXME need to handle truncated warning lines | |
def parse_line(line): | |
timestamp, severity, component, context, message = line.split(None, 4) | |
operation, namespace, tail = message.split(None, 2) | |
if namespace.endswith(".$cmd"): | |
namespace = namespace[:-5] | |
op_specific, protocol, duration = tail.rsplit(None, 2) | |
op = { | |
"timestamp": datetime.datetime.strptime(timestamp, MONGO_TIMESTAMP_FORMAT), | |
"severity": severity, | |
"component": component, | |
"context": context, | |
"operation": { | |
"operation": operation, | |
"namespace": namespace, | |
}, | |
"protocol": protocol, | |
"duration": duration, | |
} | |
if operation == "command": | |
_, command, document = op_specific.split(None, 2) | |
op["operation"]["command"] = command | |
op["operation"]["document"] = document | |
return op | |
def display_operation(op): | |
print "[{timestamp}] {operation[command]} {operation[namespace]} {duration}".format(**op) | |
print op["operation"]["document"] | |
def main(): | |
threshold = int(sys.argv[1]) if len(sys.argv) > 1 else 500 # in ms | |
def get_date_arg(pos, default): | |
return datetime.datetime.strptime(sys.argv[pos], DATETIME_ARG_FORMAT) if len(sys.argv) > pos else default | |
start = get_date_arg(2, datetime.datetime.min) | |
end = get_date_arg(3, datetime.datetime.max) | |
source = sys.stdin | |
slow_ops = (parse_line(line) for line in source if is_slow_op(line, threshold)) | |
for op in slow_ops: | |
if start <= op["timestamp"] <= end: | |
display_operation(op) | |
if __name__ == "__main__": | |
main() | |
sys.exit(0) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment