\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/DatabaseBackupMasterv8/
(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/DatabaseBackupMasterv8/performance_charts.py


"""
PostgreSQL performans verilerini görselleştirmek için script.

Bu script, PostgreSQL'den alınan sorgu performans verilerini Pandas DataFrame'e dönüştürür 
ve Matplotlib kullanarak statik grafikler oluşturur.
"""

import os
import sys
import json
import logging
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl
from datetime import datetime
import psycopg2

# Türkçe karakterleri düzgün gösterme
plt.rcParams['font.family'] = 'DejaVu Sans'

# Log yapılandırması
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

# Grafik dizini
CHART_DIR = os.path.join('static', 'charts')
os.makedirs(CHART_DIR, exist_ok=True)

def get_top_queries(connection_info, limit=10, order_by='total_exec_time'):
    """
    PostgreSQL veritabanından en çok kaynak tüketen sorguları alır ve DataFrame olarak döndürür.
    """
    try:
        # Bağlantı kur
        conn_str = f"host={connection_info['host']} port={connection_info['port']} user={connection_info['username']} password={connection_info['password']} dbname={connection_info['database']}"
        connection = psycopg2.connect(conn_str)
        cursor = connection.cursor()
        
        # Sıralama sütununu belirle
        order_column = "total_exec_time DESC"
        if order_by == "calls":
            order_column = "calls DESC"
        elif order_by == "rows":
            order_column = "rows DESC"
        
        # Sorguyu çalıştır
        query = f"""
        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 {order_column}
        LIMIT %s
        """
        
        cursor.execute(query, (limit,))
        
        # Sonuçları DataFrame'e dönüştür
        rows = cursor.fetchall()
        columns = [desc[0] for desc in cursor.description]
        df = pd.DataFrame(rows, columns=columns)
        
        # Ö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_row = cursor.fetchone()
        summary = {
            'total_calls': int(summary_row[0]),
            'total_rows': int(summary_row[1]),
            'total_exec_time': float(summary_row[2]),
            'query_count': int(summary_row[3])
        }
        
        # Bağlantıyı kapat
        cursor.close()
        connection.close()
        
        # DataFrame'i biraz düzenle
        # Kısa sorgu etiketleri oluştur
        df['short_query'] = df['query'].apply(lambda x: (x[:20] + '...') if len(x) > 20 else x)
        
        return df, summary
        
    except Exception as e:
        logger.error(f"Sorgu verisi alınırken hata: {str(e)}")
        # Boş DataFrame ve özet bilgi döndür
        return pd.DataFrame(), {'total_calls': 0, 'total_rows': 0, 'total_exec_time': 0, 'query_count': 0}

def create_charts(df, db_id, timestamp=None):
    """
    DataFrame'deki verilerden dört farklı grafik oluşturur ve kaydeder.
    
    Returns:
        dict: Grafik dosyalarının yollarını içeren bir sözlük
    """
    if df.empty:
        logger.warning("Boş DataFrame, grafikler oluşturulamadı.")
        return {}
    
    # Zaman damgası
    ts = timestamp or datetime.now().strftime("%Y%m%d%H%M%S")
    
    # Grafik dosya adları
    chart_files = {
        'execution_time': f"{CHART_DIR}/exec_time_{db_id}_{ts}.png",
        'cpu_percentage': f"{CHART_DIR}/cpu_pct_{db_id}_{ts}.png",
        'calls': f"{CHART_DIR}/calls_{db_id}_{ts}.png",
        'scatter': f"{CHART_DIR}/scatter_{db_id}_{ts}.png"
    }
    
    # Görsel stil ayarları
    plt.style.use('dark_background')
    mpl.rcParams['axes.edgecolor'] = '#666'
    mpl.rcParams['axes.facecolor'] = '#222'
    mpl.rcParams['figure.facecolor'] = '#222'
    mpl.rcParams['grid.color'] = '#444'
    mpl.rcParams['text.color'] = '#DDD'
    mpl.rcParams['axes.labelcolor'] = '#DDD'
    mpl.rcParams['xtick.color'] = '#DDD'
    mpl.rcParams['ytick.color'] = '#DDD'
    
    # Renkler
    colors = ['#3498db', '#e74c3c', '#2ecc71', '#f39c12', '#9b59b6', 
              '#1abc9c', '#d35400', '#34495e', '#7f8c8d', '#27ae60']
    
    try:
        # 1. Çalışma Süresi Grafiği
        plt.figure(figsize=(10, 6))
        bars = plt.bar(range(len(df)), df['total_exec_time'], color=colors[:len(df)])
        plt.xticks(range(len(df)), df['short_query'], rotation=45, ha='right')
        plt.xlabel('Sorgular')
        plt.ylabel('Çalışma Süresi (ms)')
        plt.title('Sorgu Çalışma Süresi Dağılımı')
        plt.tight_layout()
        plt.savefig(chart_files['execution_time'], dpi=100)
        plt.close()
        
        # 2. CPU Yüzdesi Grafiği (Pasta)
        plt.figure(figsize=(10, 6))
        plt.pie(df['percentage_cpu'], labels=df['short_query'], autopct='%1.1f%%', startangle=90, colors=colors[:len(df)])
        plt.axis('equal')
        plt.title('CPU Kullanım Yüzdesi')
        plt.tight_layout()
        plt.savefig(chart_files['cpu_percentage'], dpi=100)
        plt.close()
        
        # 3. Çağrı Sayısı Grafiği
        plt.figure(figsize=(10, 6))
        plt.bar(range(len(df)), df['calls'], color='#2ecc71')
        plt.xticks(range(len(df)), df['short_query'], rotation=45, ha='right')
        plt.xlabel('Sorgular')
        plt.ylabel('Çağrı Sayısı')
        plt.title('Sorgu Çağrı Sayısı')
        plt.tight_layout()
        plt.savefig(chart_files['calls'], dpi=100)
        plt.close()
        
        # 4. Scatter Plot (Çalışma Süresi vs CPU Yüzdesi)
        plt.figure(figsize=(10, 6))
        scatter = plt.scatter(df['total_exec_time'], df['percentage_cpu'], s=df['calls'], 
                             alpha=0.6, c=range(len(df)), cmap='viridis')
        
        # Nokta etiketleri
        for i, txt in enumerate(df['short_query']):
            plt.annotate(txt, (df['total_exec_time'].iloc[i], df['percentage_cpu'].iloc[i]),
                         xytext=(5, 5), textcoords='offset points', fontsize=8)
            
        plt.xlabel('Çalışma Süresi (ms)')
        plt.ylabel('CPU Kullanımı (%)')
        plt.title('Süre ve CPU Kullanımı İlişkisi (Boyut = Çağrı Sayısı)')
        plt.tight_layout()
        plt.savefig(chart_files['scatter'], dpi=100)
        plt.close()
        
        logger.info(f"Grafikler başarıyla oluşturuldu ve {CHART_DIR} dizinine kaydedildi.")
        return chart_files
        
    except Exception as e:
        logger.error(f"Grafikler oluşturulurken hata: {str(e)}")
        return {}

def main(db_id=None, limit=10, order_by='total_exec_time'):
    """
    Ana fonksiyon - veritabanı ID'si için grafikleri oluşturur.
    """
    from models import DatabaseConnection
    from sqlalchemy.orm import scoped_session, sessionmaker
    from app import db
    
    try:
        # Oturum oluştur
        Session = scoped_session(sessionmaker(bind=db.engine))
        session = Session()
        
        # Veritabanı bağlantısını al
        db_conn = session.query(DatabaseConnection).filter_by(id=db_id).first()
        
        if not db_conn:
            logger.error(f"ID={db_id} olan veritabanı bulunamadı.")
            return None
            
        # Bağlantı bilgilerini hazırla
        connection_info = {
            'host': db_conn.host,
            'port': db_conn.port,
            'username': db_conn.username,
            'password': db_conn.password,
            'database': db_conn.database
        }
        
        # Sadece PostgreSQL için çalışır
        if db_conn.db_type != 'postgresql':
            logger.error("Bu script sadece PostgreSQL için çalışır.")
            return None
            
        # Verileri al ve grafikleri oluştur
        df, summary = get_top_queries(connection_info, limit, order_by)
        charts = create_charts(df, db_id)
        
        Session.remove()
        
        return {
            'charts': charts,
            'summary': summary,
            'query_count': len(df)
        }
        
    except Exception as e:
        logger.error(f"Hata: {str(e)}")
        return None

if __name__ == "__main__":
    # Komut satırından çalıştırıldığında
    if len(sys.argv) > 1:
        db_id = int(sys.argv[1])
        limit = int(sys.argv[2]) if len(sys.argv) > 2 else 10
        order_by = sys.argv[3] if len(sys.argv) > 3 else 'total_exec_time'
        
        result = main(db_id, limit, order_by)
        print(json.dumps(result, indent=2))
    else:
        print("Kullanım: python performance_charts.py <db_id> [limit] [order_by]")

© KUJUNTI.ID