\x89PNG\r\n\x1a\n\x00\x00\x00\x0DIHDR\x00\x00\x00\x01\x00 \x00\x00\x01\x08\x06\x00\x00\x00\x1F\x15\xC4\x89\x00\x00\x00 \x0AIDATx\x9Ccb\x00\x00\x00\x06\x00\x03\x1A\x05\x9D\x00\x00 \x00\x00IEND\xAE\x42\x60\x82
| Path : /var/www/html/yedekledb24/DatabaseBackupMasterv6/ |
|
B-Con CMD Config cPanel C-Rdp D-Log Info Jump Mass Ransom Symlink vHost Zone-H |
| Current File : /var/www/html/yedekledb24/DatabaseBackupMasterv6/get_top_queries_simple.py |
import psycopg2
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def get_top_queries_simple(db_conn, limit=10, order_by='total_exec_time'):
"""
Sadece bağlı olunan veritabanı için pg_stat_statements verilerini döndürür.
Superuser gerektirmez. shared_preload_libraries kontrolü yapılmaz.
Args:
db_conn (dict): host, port, username, password, database bilgilerini içerir.
limit (int): Gösterilecek maksimum sorgu sayısı.
order_by (str): Sıralama ('total_exec_time', 'calls', 'rows')
Returns:
dict: success, message, data, summary
Not: JSON serileştirme ve şablon oluşturma hatalarını önlemek için
yüzde işaretleri, süslü parantezler ve diğer özel format karakterlerini
dikkatli bir şekilde işler ve ön-işlemden geçirir.
"""
data = []
summary_data = {
"total_calls": 0,
"total_rows": 0,
"total_exec_time": "0.00 ms",
"query_count": 0,
"pg_version": "N/A"
}
conn_str = "host={} port={} user={} password={} dbname={}".format(
db_conn['host'], db_conn['port'], db_conn['username'], db_conn['password'], db_conn['database']
)
order_column = "total_exec_time DESC"
if order_by == "calls":
order_column = "calls DESC"
elif order_by == "rows":
order_column = "rows DESC"
try:
# 1. Bağlantı kur ve sorguları al
connection = psycopg2.connect(conn_str)
connection.autocommit = True
cursor = connection.cursor()
# 2. PostgreSQL sürümünü al
cursor.execute("SHOW server_version")
pg_version_result = cursor.fetchone()
pg_version = pg_version_result[0] if pg_version_result else "N/A"
# 3. Ana sorguyu çalıştır
query = """
SELECT
query,
calls,
rows,
total_exec_time,
CASE WHEN calls > 0 THEN total_exec_time / calls ELSE 0 END as avg_time,
100.0 * total_exec_time / SUM(total_exec_time) OVER() as percentage_cpu
FROM pg_stat_statements
WHERE dbid = (SELECT oid FROM pg_database WHERE datname = current_database())
ORDER BY {}
LIMIT %s
""".format(order_column)
cursor.execute(query, (limit,))
results = cursor.fetchall()
# Cursor description NULL ise veya boşsa güvenli şekilde işle
if not cursor.description:
columns = []
else:
columns = [desc[0] for desc in cursor.description]
# 4. Sonuçları işle
if not columns:
logger.warning("Sütun bilgisi alınamadı, veri işlenemeyecek.")
else:
for row in results:
if not row:
continue # Boş satırları atla
row_dict = {}
try:
for i, col in enumerate(columns):
if i >= len(row):
logger.warning(f"Sütun indeksi ({i}) satır uzunluğunu ({len(row)}) aşıyor, atlanıyor.")
continue
value = row[i]
try:
if col == 'query' and value:
# Uzun sorguları kısalt
row_dict[col] = value[:500] + '...' if len(value) > 500 else value
elif col in ['total_exec_time', 'avg_time']:
# Süre değerlerini formatla - veriyi sayısal olarak sakla, birim template'de eklenir
try:
row_dict[col] = float(value) if value is not None else 0.0
except (ValueError, TypeError):
row_dict[col] = 0.0
elif col == 'percentage_cpu':
# CPU yüzdesini formatla - sayısal değer olarak sakla, % işareti template'de eklenir
try:
# Yüzde işareti yerine sayısal değer olarak sakla
row_dict[col] = float(value) if value is not None else 0.0
except (ValueError, TypeError):
row_dict[col] = 0.0
else:
# Diğer değerleri doğrudan aktar
row_dict[col] = value
except Exception as format_error:
logger.error(f"Sütun '{col}' için değer biçimlendirilirken hata: {format_error}")
# Hatada bile güvenli bir değer ata
row_dict[col] = "Error"
data.append(row_dict)
except Exception as row_error:
logger.error(f"Satır işlenirken hata: {row_error}")
# Hata durumunda bu satırı atla ve diğer satırlarla devam et
# 5. Özet bilgileri al
summary_query = """
SELECT
COALESCE(sum(calls), 0) as total_calls,
COALESCE(sum(rows), 0) as total_rows,
COALESCE(sum(total_exec_time), 0) as total_exec_time,
count(*) as query_count
FROM pg_stat_statements
WHERE dbid = (SELECT oid FROM pg_database WHERE datname = current_database())
"""
cursor.execute(summary_query)
summary = cursor.fetchone()
if summary and len(summary) >= 4:
# Float'a dönüştür
total_calls = float(summary[0]) if summary[0] is not None else 0
total_rows = float(summary[1]) if summary[1] is not None else 0
total_exec_time = float(summary[2]) if summary[2] is not None else 0
query_count = int(summary[3]) if summary[3] is not None else 0
# Sayısal değerleri sayısal olarak sakla
summary_data = {
"total_calls": int(total_calls),
"total_rows": int(total_rows),
"total_exec_time": total_exec_time, # Sayısal değer olarak sakla
"total_exec_time_ms": "{:.2f} ms".format(total_exec_time), # Görüntüleme için
"query_count": query_count,
"pg_version": pg_version
}
cursor.close()
connection.close()
return {
"success": True,
"message": "Sorgu verileri başarıyla alındı",
"data": data,
"summary": summary_data,
"pg_version": pg_version
}
except Exception as e:
logger.error("Hata: {}".format(str(e)))
return {
"success": False,
"message": "Hata oluştu: {}".format(str(e)),
"data": [],
"summary": summary_data,
"pg_version": "N/A"
}
# Test kodu
if __name__ == "__main__":
# Test bağlantısı
db_conn = {
"host": "localhost",
"port": 5432,
"username": "yedekle_user",
"password": "sifre",
"database": "yedekle24_db"
}
result = get_top_queries_simple(db_conn)
print("Başarı:", result["success"])
print("Mesaj:", result["message"])
print("Özet:", result["summary"])
print("\nEn yüksek kaynak tüketen sorgular:")
for i, row in enumerate(result["data"]):
print(f"{i+1}. Sorgu: {row['query'][:50]}... ({row['total_exec_time']})")