Skip to content

Instantly share code, notes, and snippets.

@mdellavo
Last active November 27, 2017 16:05
Show Gist options
  • Save mdellavo/4a810db6d47e441a97d53391dc74cbb1 to your computer and use it in GitHub Desktop.
Save mdellavo/4a810db6d47e441a97d53391dc74cbb1 to your computer and use it in GitHub Desktop.
#!/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"]
print
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