\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/DatabaseBackupMasterv7/ |
|
B-Con CMD Config cPanel C-Rdp D-Log Info Jump Mass Ransom Symlink vHost Zone-H |
| Current File : /var/www/html/yedekledb24/DatabaseBackupMasterv7/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]")