seitime-frappe/frappe/monitor.py
Aditya Hase cb3507f5e4 fix(monitor): Use datetime.utcnow() instead of timezone.utc
Python 2, 3 compatibility issue
2020-03-05 15:06:15 +05:30

103 lines
2.5 KiB
Python

# -*- coding: utf-8 -*-
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
from __future__ import unicode_literals
from datetime import datetime
import json
import traceback
import frappe
import os
import uuid
MONITOR_REDIS_KEY = "monitor-transactions"
def start(transaction_type="request", method=None, kwargs=None):
if frappe.conf.monitor:
frappe.local.monitor = Monitor(
transaction_type=transaction_type, method=method, kwargs=kwargs
)
def stop():
if frappe.conf.monitor and hasattr(frappe.local, "monitor"):
frappe.local.monitor.dump()
def log_file():
return os.path.join(frappe.utils.get_bench_path(), "logs", "monitor.json.log")
class Monitor:
def __init__(self, transaction_type=None, method=None, kwargs=None):
try:
self.site = frappe.local.site
self.timestamp = datetime.utcnow()
self.transaction_type = transaction_type
self.uuid = uuid.uuid4()
if self.transaction_type == "request":
self.data = frappe.form_dict
self.headers = dict(frappe.request.headers)
self.method = frappe.request.method
self.path = frappe.request.path
else:
self.kwargs = kwargs
self.method = method
except Exception:
traceback.print_exc()
def dump(self):
try:
timediff = datetime.utcnow() - self.timestamp
# Obtain duration in microseconds
self.duration = int(timediff.total_seconds() * 1000000)
data = {
"uuid": self.uuid,
"duration": self.duration,
"site": self.site,
"timestamp": self.timestamp.isoformat(sep=" "),
"transaction_type": self.transaction_type,
}
if self.transaction_type == "request":
update = {
"data": self.data,
"headers": self.headers,
"method": self.method,
"path": self.path,
}
else:
update = {
"kwargs": self.kwargs,
"method": self.method,
}
data.update(update)
json_data = json.dumps(data, sort_keys=True, default=str)
store(json_data)
except Exception:
traceback.print_exc()
def store(json_data):
MAX_LOGS = 1000000
if frappe.cache().llen(MONITOR_REDIS_KEY) > MAX_LOGS:
frappe.cache().ltrim(MONITOR_REDIS_KEY, 1, -1)
frappe.cache().rpush(MONITOR_REDIS_KEY, json_data)
def flush():
try:
# Fetch all the logs without removing from cache
logs = frappe.cache().lrange(MONITOR_REDIS_KEY, 0, -1)
logs = list(map(frappe.safe_decode, logs))
with open(log_file(), "a", os.O_NONBLOCK) as f:
f.write("\n".join(logs))
# Remove fetched entries from cache
frappe.cache().ltrim(MONITOR_REDIS_KEY, len(logs) - 1, -1)
except Exception:
traceback.print_exc()