\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 csarite.com
KUJUNTI.ID MINISH3LL
Path : /var/www/html/yedekledb24/DatabaseBackupMaster/
(S)h3ll Cr3at0r :
F!le Upl0ad :

B-Con CMD Config cPanel C-Rdp D-Log Info Jump Mass Ransom Symlink vHost Zone-H

Current File : /var/www/html/yedekledb24/DatabaseBackupMaster/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']})")

© KUJUNTI.ID