{"id":36187,"date":"2025-12-09T21:41:03","date_gmt":"2025-12-09T18:41:03","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/?p=36187"},"modified":"2025-12-09T21:41:03","modified_gmt":"2025-12-09T18:41:03","slug":"python-3te-logging-kullanimi-kapsamli-bir-rehber","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/python-3te-logging-kullanimi-kapsamli-bir-rehber\/","title":{"rendered":"Python 3&#8217;te Logging Kullan\u0131m\u0131: Kapsaml\u0131 Bir Rehber"},"content":{"rendered":"<p><body><\/p>\n<h2>Python 3&#8217;te Logging Kullan\u0131m\u0131: Kapsaml\u0131 Bir Rehber<\/h2>\n<h3>Giri\u015f: Neden Logging \u00d6nemlidir?<\/h3>\n<p>Yaz\u0131l\u0131m geli\u015ftirme s\u00fcrecinde, bir uygulaman\u0131n davran\u0131\u015f\u0131n\u0131 anlamak, hatalar\u0131 ay\u0131klamak ve sistemin genel sa\u011fl\u0131\u011f\u0131n\u0131 izlemek kritik \u00f6neme sahiptir. Geli\u015ftiriciler genellikle bu ama\u00e7la <code>print()<\/code> fonksiyonunu kullanmaya al\u0131\u015fk\u0131n olsa da, b\u00fcy\u00fck ve karma\u015f\u0131k uygulamalarda <code>print()<\/code>&#8216;in s\u0131n\u0131rl\u0131l\u0131klar\u0131 h\u0131zla ortaya \u00e7\u0131kar. \u0130\u015fte bu noktada &#8220;logging&#8221; devreye girer. Logging, uygulaman\u0131z\u0131n \u00e7al\u0131\u015fma zaman\u0131nda \u00fcretti\u011fi olaylar\u0131, mesajlar\u0131 ve hata bilgilerini yap\u0131land\u0131r\u0131lm\u0131\u015f bir \u015fekilde kaydetme s\u00fcrecidir. Bu kay\u0131tlar, sistem y\u00f6neticilerine, destek ekiplerine ve geli\u015ftiricilere, bir sorun ortaya \u00e7\u0131kt\u0131\u011f\u0131nda ne oldu\u011funu anlamalar\u0131 i\u00e7in de\u011ferli bilgiler sa\u011flar.<\/p>\n<p>Python&#8217;\u0131n standart k\u00fct\u00fcphanesinde yer alan <code>logging<\/code> mod\u00fcl\u00fc, bu ihtiyac\u0131 kar\u015f\u0131lamak i\u00e7in g\u00fc\u00e7l\u00fc ve esnek bir \u00e7er\u00e7eve sunar. <code>print()<\/code>&#8216;in aksine, <code>logging<\/code> mod\u00fcl\u00fc, mesajlar\u0131n \u00f6nem derecesine g\u00f6re filtrelenmesine, farkl\u0131 hedeflere (konsol, dosya, a\u011f, veritaban\u0131 vb.) y\u00f6nlendirilmesine ve \u00f6zelle\u015ftirilebilir formatlarda kaydedilmesine olanak tan\u0131r. Bu sayede, geli\u015ftirme a\u015famas\u0131nda detayl\u0131 hata ay\u0131klama mesajlar\u0131 al\u0131rken, \u00fcretim ortam\u0131nda yaln\u0131zca kritik hatalar\u0131 ve uyar\u0131lar\u0131 kaydetmek gibi farkl\u0131 senaryolar\u0131 kolayca y\u00f6netebilirsiniz. G\u00fcvenlik denetimleri, performans izleme ve kullan\u0131c\u0131 davran\u0131\u015flar\u0131n\u0131 analiz etme gibi alanlarda da logging vazge\u00e7ilmez bir ara\u00e7t\u0131r.<\/p>\n<h3>Python&#8217;da Temel Logging Kullan\u0131m\u0131<\/h3>\n<p>Python&#8217;da logging&#8217;e ba\u015flamak olduk\u00e7a basittir. <code>logging<\/code> mod\u00fcl\u00fc, varsay\u0131lan olarak k\u00f6k (root) bir logger ile gelir ve bu logger&#8217;\u0131 temel konfig\u00fcrasyonlarla hemen kullanmaya ba\u015flayabilirsiniz.<\/p>\n<h4>Log Seviyeleri ve Anlamlar\u0131<\/h4>\n<p><code>logging<\/code> mod\u00fcl\u00fc, mesajlar\u0131n \u00f6nem derecesini belirtmek i\u00e7in standart log seviyeleri tan\u0131mlar. Bu seviyeler, mesajlar\u0131 filtrelemek ve farkl\u0131 ba\u011flamlarda farkl\u0131 detay seviyeleriyle \u00e7al\u0131\u015fmak i\u00e7in kullan\u0131l\u0131r:<\/p>\n<p>*   <strong>DEBUG (10):<\/strong> Detayl\u0131 bilgi, genellikle bir sorunu te\u015fhis ederken ilgi \u00e7ekici olanlar. Yaln\u0131zca geli\u015ftirme a\u015famas\u0131nda veya \u00e7ok spesifik hata ay\u0131klama senaryolar\u0131nda kullan\u0131l\u0131r.<br \/>\n*   <strong>INFO (20):<\/strong> Uygulaman\u0131n beklendi\u011fi gibi \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 do\u011frulayan genel bilgiler. Kullan\u0131c\u0131 eylemleri, sistem ba\u015flang\u0131\u00e7\/durdurma gibi olaylar.<br \/>\n*   <strong>WARNING (30):<\/strong> Beklenmedik bir \u015feyin meydana geldi\u011fini veya yak\u0131n gelecekte bir sorunun ortaya \u00e7\u0131kabilece\u011fini g\u00f6steren bir uyar\u0131. Yaz\u0131l\u0131m hala beklendi\u011fi gibi \u00e7al\u0131\u015f\u0131yor.<br \/>\n*   <strong>ERROR (40):<\/strong> Ciddi bir sorun nedeniyle yaz\u0131l\u0131m\u0131n baz\u0131 i\u015flevleri yerine getiremedi\u011fini g\u00f6sterir. Ancak uygulama tamamen \u00e7\u00f6kmemi\u015f olabilir.<br \/>\n*   <strong>CRITICAL (50):<\/strong> Uygulaman\u0131n kendisinin veya kritik bir bile\u015feninin tamamen \u00e7\u00f6kt\u00fc\u011f\u00fcn\u00fc veya \u00e7al\u0131\u015fmay\u0131 durdurdu\u011funu g\u00f6steren \u00e7ok ciddi bir hata.<\/p>\n<p>Bu seviyeler, varsay\u0131lan olarak <code>logging.WARNING<\/code> seviyesinden itibaren mesajlar\u0131 i\u015fler. Yani, bir konfig\u00fcrasyon yapmad\u0131\u011f\u0131n\u0131zda, yaln\u0131zca WARNING, ERROR ve CRITICAL seviyesindeki mesajlar konsola yazd\u0131r\u0131l\u0131r.<\/p>\n<h4>Basit Bir Log Mesaj\u0131 \u00d6rne\u011fi<\/h4>\n<p>En basit haliyle, <code>logging<\/code> mod\u00fcl\u00fcn\u00fc a\u015fa\u011f\u0131daki gibi kullanabilirsiniz:<\/p>\n<pre><code class=\"language-python\">import logging\n\n<h2>Varsay\u0131lan konfig\u00fcrasyon ile loglama<\/h2>\nlogging.warning(\"Bu bir uyar\u0131 mesaj\u0131d\u0131r.\")\nlogging.info(\"Bu bir bilgi mesaj\u0131d\u0131r.\") # Varsay\u0131lan olarak g\u00f6r\u00fcnmez\nlogging.error(\"Bu bir hata mesaj\u0131d\u0131r.\")<\/code><\/pre>\n<p>Yukar\u0131daki kodu \u00e7al\u0131\u015ft\u0131rd\u0131\u011f\u0131n\u0131zda, konsolda \u015funa benzer bir \u00e7\u0131kt\u0131 g\u00f6receksiniz:<\/p>\n<pre><code class=\"language-\">WARNING:root:Bu bir uyar\u0131 mesaj\u0131d\u0131r.\nERROR:root:Bu bir hata mesaj\u0131d\u0131r.<\/code><\/pre>\n<p><code>INFO<\/code> mesaj\u0131n\u0131n neden g\u00f6r\u00fcnmedi\u011fini merak ediyorsan\u0131z, bunun nedeni varsay\u0131lan log seviyesinin <code>WARNING<\/code> olmas\u0131d\u0131r. <code>basicConfig()<\/code> fonksiyonu ile bu seviyeyi de\u011fi\u015ftirebilir ve daha fazla kontrol sa\u011flayabilirsiniz.<\/p>\n<h4><code>logging.basicConfig()<\/code> ile Temel Konfig\u00fcrasyon<\/h4>\n<p><code>logging.basicConfig()<\/code> fonksiyonu, k\u00f6k logger i\u00e7in h\u0131zl\u0131 ve kolay bir \u015fekilde temel konfig\u00fcrasyon yapman\u0131z\u0131 sa\u011flar. Bu fonksiyon genellikle uygulaman\u0131z\u0131n ba\u015flang\u0131c\u0131nda bir kez \u00e7a\u011fr\u0131l\u0131r ve loglama davran\u0131\u015f\u0131n\u0131 global olarak ayarlar.<\/p>\n<p><code>basicConfig()<\/code>&#8216;in baz\u0131 \u00f6nemli parametreleri \u015funlard\u0131r:<\/p>\n<p>*   <strong><code>level<\/code><\/strong>: Log seviyesini ayarlar (\u00f6rn. <code>logging.INFO<\/code>, <code>logging.DEBUG<\/code>). Bu seviyenin alt\u0131ndaki hi\u00e7bir mesaj i\u015flenmez.<br \/>\n*   <strong><code>format<\/code><\/strong>: Log mesajlar\u0131n\u0131n nas\u0131l g\u00f6r\u00fcnece\u011fini belirten bir dize.<br \/>\n*   <strong><code>filename<\/code><\/strong>: Log mesajlar\u0131n\u0131n yaz\u0131laca\u011f\u0131 dosyan\u0131n ad\u0131.<br \/>\n*   <strong><code>filemode<\/code><\/strong>: Dosya a\u00e7ma modu (&#8216;w&#8217; yazma, &#8216;a&#8217; ekleme). Varsay\u0131lan &#8216;a&#8217;.<br \/>\n*   <strong><code>stream<\/code><\/strong>: Log mesajlar\u0131n\u0131n yaz\u0131laca\u011f\u0131 bir ak\u0131\u015f (\u00f6rn. <code>sys.stdout<\/code>, <code>sys.stderr<\/code>). Genellikle <code>filename<\/code> ile birlikte kullan\u0131lmaz.<\/p>\n<p>\u015eimdi <code>basicConfig()<\/code> kullanarak hem seviyeyi hem de format\u0131 ayarlayal\u0131m ve loglar\u0131 bir dosyaya yazd\u0131ral\u0131m:<\/p>\n<pre><code class=\"language-python\">import logging\n\n<h2>Loglar\u0131 bir dosyaya yazacak ve DEBUG seviyesinden itibaren t\u00fcm mesajlar\u0131 g\u00f6sterecek \u015fekilde konfig\u00fcre et<\/h2>\nlogging.basicConfig(\n    level=logging.DEBUG,\n    format='%(asctime)s - %(levelname)s - %(message)s',\n    filename='app.log',\n    filemode='w' # Her \u00e7al\u0131\u015ft\u0131rmada dosyay\u0131 yeniden olu\u015ftur\n)\n\nlogging.debug(\"Bu bir hata ay\u0131klama mesaj\u0131d\u0131r.\")\nlogging.info(\"Kullan\u0131c\u0131 'admin' sisteme giri\u015f yapt\u0131.\")\nlogging.warning(\"Yap\u0131land\u0131rma dosyas\u0131nda eksik bir anahtar bulundu.\")\nlogging.error(\"Veritaban\u0131 ba\u011flant\u0131s\u0131 ba\u015far\u0131s\u0131z oldu.\")\nlogging.critical(\"Sistem kritik bir hata nedeniyle kapat\u0131l\u0131yor!\")\n\nprint(\"Loglar 'app.log' dosyas\u0131na yaz\u0131ld\u0131.\")<\/code><\/pre>\n<p>Bu kodu \u00e7al\u0131\u015ft\u0131rd\u0131\u011f\u0131n\u0131zda, konsolda hi\u00e7bir \u00e7\u0131kt\u0131 g\u00f6rmeyeceksiniz (\u00e7\u00fcnk\u00fc <code>filename<\/code> belirtildi\u011finde varsay\u0131lan olarak konsola yazmay\u0131 durdurur). Ancak <code>app.log<\/code> ad\u0131nda bir dosya olu\u015facak ve i\u00e7eri\u011fi \u015f\u00f6yle olacakt\u0131r:<\/p>\n<pre><code class=\"language-\">2023-10-27 10:30:00,123 - DEBUG - Bu bir hata ay\u0131klama mesaj\u0131d\u0131r.\n2023-10-27 10:30:00,124 - INFO - Kullan\u0131c\u0131 'admin' sisteme giri\u015f yapt\u0131.\n2023-10-27 10:30:00,125 - WARNING - Yap\u0131land\u0131rma dosyas\u0131nda eksik bir anahtar bulundu.\n2023-10-27 10:30:00,126 - ERROR - Veritaban\u0131 ba\u011flant\u0131s\u0131 ba\u015far\u0131s\u0131z oldu.\n2023-10-27 10:30:00,127 - CRITICAL - Sistem kritik bir hata nedeniyle kapat\u0131l\u0131yor!<\/code><\/pre>\n<p><code>%(asctime)s<\/code>, <code>%(levelname)s<\/code>, <code>%(message)s<\/code> gibi ifadeler, log format\u0131 i\u00e7in kullan\u0131lan \u00f6zel \u00f6zniteliklerdir. Bunlar\u0131 Formatter&#8217;lar b\u00f6l\u00fcm\u00fcnde daha detayl\u0131 inceleyece\u011fiz.<\/p>\n<h3>Logging Bile\u015fenleri: Derinlemesine Bak\u0131\u015f<\/h3>\n<p><code>logging<\/code> mod\u00fcl\u00fc, loglama s\u00fcrecini y\u00f6netmek i\u00e7in d\u00f6rt ana bile\u015fen etraf\u0131nda d\u00f6ner: <strong>Logger&#8217;lar<\/strong>, <strong>Handler&#8217;lar<\/strong>, <strong>Formatter&#8217;lar<\/strong> ve <strong>Filter&#8217;lar<\/strong>. Bu bile\u015fenlerin her biri, loglama ak\u0131\u015f\u0131n\u0131n belirli bir y\u00f6n\u00fcn\u00fc kontrol eder.<\/p>\n<h4>Logger&#8217;lar: Mesajlar\u0131n Kayna\u011f\u0131<\/h4>\n<p>Logger&#8217;lar, bir uygulaman\u0131n mesajlar\u0131 g\u00f6nderdi\u011fi ana aray\u00fczd\u00fcr. Her logger&#8217;\u0131n bir ad\u0131 vard\u0131r ve bu adlar genellikle hiyerar\u015fik bir yap\u0131 olu\u015fturur (noktalarla ayr\u0131lm\u0131\u015f isimler). \u00d6rne\u011fin, <code>my_app.module_a<\/code> adl\u0131 bir logger, <code>my_app<\/code> adl\u0131 logger&#8217;\u0131n alt\u0131ndad\u0131r.<\/p>\n<p>Bir logger nesnesi olu\u015fturmak i\u00e7in <code>logging.getLogger()<\/code> fonksiyonu kullan\u0131l\u0131r:<\/p>\n<pre><code class=\"language-python\">import logging\n\n<h2>K\u00f6k logger'\u0131 al\u0131r<\/h2>\nroot_logger = logging.getLogger()\n\n<h2>\u00d6zel bir logger olu\u015fturur<\/h2>\napp_logger = logging.getLogger(\"my_application\")\ndb_logger = logging.getLogger(\"my_application.database\")<\/code><\/pre>\n<p>Logger&#8217;lar kendi seviyelerini ayarlayabilirler. Bir logger&#8217;\u0131n seviyesi, o logger&#8217;dan ge\u00e7en mesajlar\u0131n i\u015flenip i\u015flenmeyece\u011fini belirler.<\/p>\n<pre><code class=\"language-python\">import logging\n\n<h2>Varsay\u0131lan k\u00f6k logger seviyesi WARNING'dir.<\/h2>\n<h2>K\u00f6k logger i\u00e7in basicConfig yapal\u0131m ki \u00e7\u0131kt\u0131y\u0131 g\u00f6relim.<\/h2>\nlogging.basicConfig(level=logging.INFO, format='%(name)s - %(levelname)s - %(message)s')\n\nmy_logger = logging.getLogger(\"my_module\")\nmy_logger.setLevel(logging.DEBUG) # Bu logger'dan ge\u00e7en DEBUG mesajlar\u0131 da i\u015flenecek.\n\nanother_logger = logging.getLogger(\"another_module\")\nanother_logger.setLevel(logging.ERROR) # Sadece ERROR ve CRITICAL mesajlar\u0131 i\u015flenecek.\n\nmy_logger.debug(\"Bu my_module'dan gelen bir debug mesaj\u0131d\u0131r.\")\nmy_logger.info(\"Bu my_module'dan gelen bir bilgi mesaj\u0131d\u0131r.\")\nanother_logger.warning(\"Bu another_module'dan gelen bir uyar\u0131 mesaj\u0131d\u0131r.\") # \u0130\u015flenmeyecek\nanother_logger.error(\"Bu another_module'dan gelen bir hata mesaj\u0131d\u0131r.\")<\/code><\/pre>\n<p>\u00c7\u0131kt\u0131:<\/p>\n<pre><code class=\"language-\">my_module - DEBUG - Bu my_module'dan gelen bir debug mesaj\u0131d\u0131r.\nmy_module - INFO - Bu my_module'dan gelen bir bilgi mesaj\u0131d\u0131r.\nanother_module - ERROR - Bu another_module'dan gelen bir hata mesaj\u0131d\u0131r.<\/code><\/pre>\n<p><strong>Logger Hiyerar\u015fisi ve Yay\u0131lma (Propagation):<\/strong><br \/>\nLogger&#8217;lar hiyerar\u015fik bir yap\u0131ya sahiptir. Bir logger, mesajlar\u0131 kendi seviyesinin \u00fczerindeyse i\u015fler ve ard\u0131ndan bu mesajlar\u0131 \u00fcst logger&#8217;\u0131na (parent logger) iletir. Bu s\u00fcrece &#8220;yay\u0131lma&#8221; (propagation) denir. K\u00f6k logger, t\u00fcm logger&#8217;lar\u0131n en \u00fcst\u00fcndedir.<\/p>\n<pre><code class=\"language-python\">import logging\n\n<h2>K\u00f6k logger'\u0131 INFO seviyesine ayarla ve konsola yaz.<\/h2>\nlogging.basicConfig(level=logging.INFO, format='%(name)s - %(levelname)s - %(message)s')\n\nparent_logger = logging.getLogger(\"parent\")\nparent_logger.setLevel(logging.WARNING) # Parent logger WARNING seviyesinde.\n\nchild_logger = logging.getLogger(\"parent.child\")\nchild_logger.setLevel(logging.DEBUG) # Child logger DEBUG seviyesinde.\nchild_logger.propagate = True # Varsay\u0131lan olarak True'dur.\n\nchild_logger.debug(\"\u00c7ocuktan gelen DEBUG mesaj\u0131.\") # Child logger i\u015fler, parent'a yay\u0131l\u0131r, parent seviyesi WARNING oldu\u011fu i\u00e7in parent i\u015fleyemez.\nchild_logger.info(\"\u00c7ocuktan gelen INFO mesaj\u0131.\")   # Child logger i\u015fler, parent'a yay\u0131l\u0131r, parent seviyesi WARNING oldu\u011fu i\u00e7in parent i\u015fleyemez.\nchild_logger.warning(\"\u00c7ocuktan gelen WARNING mesaj\u0131.\") # Child logger i\u015fler, parent'a yay\u0131l\u0131r, parent seviyesi WARNING oldu\u011fu i\u00e7in parent da i\u015fler.\n\n<h2>E\u011fer child_logger.propagate = False yapsayd\u0131k, child'dan gelen mesajlar parent'a yay\u0131lmazd\u0131.<\/code><\/pre>\n<\/h2>\n<p>\u00c7\u0131kt\u0131:<\/p>\n<pre><code class=\"language-\">parent.child - DEBUG - \u00c7ocuktan gelen DEBUG mesaj\u0131.\nparent.child - INFO - \u00c7ocuktan gelen INFO mesaj\u0131.\nparent.child - WARNING - \u00c7ocuktan gelen WARNING mesaj\u0131.\nparent - WARNING - \u00c7ocuktan gelen WARNING mesaj\u0131.<\/code><\/pre>\n<p>G\u00f6rd\u00fc\u011f\u00fcn\u00fcz gibi, <code>child_logger<\/code>&#8216;dan gelen WARNING mesaj\u0131 hem kendi handler&#8217;\u0131 (varsay\u0131lan olarak k\u00f6k logger&#8217;\u0131n handler&#8217;\u0131) taraf\u0131ndan hem de <code>parent_logger<\/code>&#8216;\u0131n handler&#8217;\u0131 taraf\u0131ndan i\u015flendi.<\/p>\n<h4>Handler&#8217;lar: Mesajlar\u0131n Hedefi<\/h4>\n<p>Handler&#8217;lar, logger&#8217;lar taraf\u0131ndan \u00fcretilen log kay\u0131tlar\u0131n\u0131 (LogRecords) al\u0131r ve bunlar\u0131 belirli hedeflere (konsol, dosya, e-posta, veritaban\u0131 vb.) g\u00f6nderir. Bir logger&#8217;a birden fazla handler ekleyebilirsiniz, b\u00f6ylece ayn\u0131 log mesaj\u0131 farkl\u0131 yerlere farkl\u0131 \u015fekillerde g\u00f6nderilebilir.<\/p>\n<p>Baz\u0131 yayg\u0131n Handler t\u00fcrleri:<\/p>\n<p>*   <strong><code>StreamHandler<\/code><\/strong>: Log mesajlar\u0131n\u0131 konsol veya herhangi bir ak\u0131\u015fa (stream) g\u00f6nderir.<br \/>\n*   <strong><code>FileHandler<\/code><\/strong>: Log mesajlar\u0131n\u0131 belirtilen bir dosyaya yazar.<br \/>\n*   <strong><code>RotatingFileHandler<\/code><\/strong>: Dosyaya yazar, ancak dosya belirli bir boyuta ula\u015ft\u0131\u011f\u0131nda otomatik olarak yeni bir dosyaya ge\u00e7er (dosya rotasyonu). Eski dosyalar\u0131 belirli bir say\u0131da tutar.<br \/>\n*   <strong><code>TimedRotatingFileHandler<\/code><\/strong>: Dosyaya yazar, ancak dosya belirli bir zaman aral\u0131\u011f\u0131na (g\u00fcnl\u00fck, saatlik vb.) g\u00f6re rotasyona u\u011frar.<br \/>\n*   <strong><code>SMTPHandler<\/code><\/strong>: Log mesajlar\u0131n\u0131 e-posta ile g\u00f6nderir.<br \/>\n*   <strong><code>HTTPHandler<\/code><\/strong>: Log mesajlar\u0131n\u0131 HTTP POST iste\u011fi olarak bir web sunucusuna g\u00f6nderir.<br \/>\n*   <strong><code>NullHandler<\/code><\/strong>: Hi\u00e7bir \u015fey yapmaz. K\u00fct\u00fcphane yazarlar\u0131 taraf\u0131ndan, k\u00fct\u00fcphanelerinin loglama \u00e7a\u011fr\u0131lar\u0131 yapmas\u0131n\u0131 sa\u011flamak ama ayn\u0131 zamanda bir uygulaman\u0131n loglama konfig\u00fcrasyonu yapmamas\u0131 durumunda hi\u00e7bir \u00e7\u0131kt\u0131 \u00fcretmemesini sa\u011flamak i\u00e7in kullan\u0131l\u0131r.<\/p>\n<p><strong>Birden Fazla Handler Kullan\u0131m\u0131:<\/strong><br \/>\nA\u015fa\u011f\u0131daki \u00f6rnek, hem konsola hem de bir dosyaya log yazan \u00f6zel bir logger&#8217;\u0131n nas\u0131l yap\u0131land\u0131r\u0131laca\u011f\u0131n\u0131 g\u00f6sterir:<\/p>\n<pre><code class=\"language-python\">import logging\nimport sys\n\n<h2>\u00d6zel bir logger olu\u015ftur<\/h2>\nmy_app_logger = logging.getLogger(\"my_application\")\nmy_app_logger.setLevel(logging.DEBUG) # En d\u00fc\u015f\u00fck seviyeden itibaren t\u00fcm mesajlar\u0131 yakala\n\n<h2>1. StreamHandler: Konsola INFO seviyesinden itibaren loglar\u0131 yaz<\/h2>\nconsole_handler = logging.StreamHandler(sys.stdout)\nconsole_handler.setLevel(logging.INFO)\nconsole_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')\nconsole_handler.setFormatter(console_formatter)\nmy_app_logger.addHandler(console_handler)\n\n<h2>2. FileHandler: Dosyaya DEBUG seviyesinden itibaren loglar\u0131 yaz<\/h2>\nfile_handler = logging.FileHandler(\"debug.log\")\nfile_handler.setLevel(logging.DEBUG)\nfile_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(module)s:%(lineno)d - %(message)s')\nfile_handler.setFormatter(file_formatter)\nmy_app_logger.addHandler(file_handler)\n\nmy_app_logger.debug(\"Bu sadece dosyada g\u00f6r\u00fcnen bir debug mesaj\u0131d\u0131r.\")\nmy_app_logger.info(\"Bu hem konsolda hem de dosyada g\u00f6r\u00fcnen bir bilgi mesaj\u0131d\u0131r.\")\nmy_app_logger.warning(\"Bu bir uyar\u0131d\u0131r.\")\nmy_app_logger.error(\"Bir hata meydana geldi.\")<\/code><\/pre>\n<p>Bu \u00f6rnekte, <code>my_app_logger<\/code>&#8216;a iki farkl\u0131 handler ekledik: biri konsola <code>INFO<\/code> seviyesinden itibaren yazarken, di\u011feri <code>debug.log<\/code> dosyas\u0131na <code>DEBUG<\/code> seviyesinden itibaren yaz\u0131yor. Her handler&#8217;\u0131n kendi formatlay\u0131c\u0131s\u0131 da var.<\/p>\n<p>Konsol \u00e7\u0131kt\u0131s\u0131:<\/p>\n<pre><code class=\"language-\">2023-10-27 10:30:00,123 - my_application - INFO - Bu hem konsolda hem de dosyada g\u00f6r\u00fcnen bir bilgi mesaj\u0131d\u0131r.\n2023-10-27 10:30:00,124 - my_application - WARNING - Bu bir uyar\u0131d\u0131r.\n2023-10-27 10:30:00,125 - my_application - ERROR - Bir hata meydana geldi.<\/code><\/pre>\n<p><code>debug.log<\/code> dosyas\u0131n\u0131n i\u00e7eri\u011fi:<\/p>\n<pre><code class=\"language-\">2023-10-27 10:30:00,122 - my_application - DEBUG - <module>:30 - Bu sadece dosyada g\u00f6r\u00fcnen bir debug mesaj\u0131d\u0131r.\n2023-10-27 10:30:00,123 - my_application - INFO - <module>:31 - Bu hem konsolda hem de dosyada g\u00f6r\u00fcnen bir bilgi mesaj\u0131d\u0131r.\n2023-10-27 10:30:00,124 - my_application - WARNING - <module>:32 - Bu bir uyar\u0131d\u0131r.\n2023-10-27 10:30:00,125 - my_application - ERROR - <module>:33 - Bir hata meydana geldi.<\/code><\/pre>\n<p><strong><code>RotatingFileHandler<\/code> ve <code>TimedRotatingFileHandler<\/code>:<\/strong><br \/>\n\u00dcretim ortamlar\u0131nda, log dosyalar\u0131n\u0131n s\u0131n\u0131rs\u0131z b\u00fcy\u00fcmesi disk alan\u0131n\u0131 t\u00fcketebilir. Bu durumu \u00f6nlemek i\u00e7in rotasyonlu dosya handler&#8217;lar\u0131 kullan\u0131l\u0131r.<\/p>\n<pre><code class=\"language-python\">from logging.handlers import RotatingFileHandler, TimedRotatingFileHandler\nimport time\n\n<h2>RotatingFileHandler \u00f6rne\u011fi<\/h2>\nrot_file_handler = RotatingFileHandler(\n    'rotating_app.log',\n    maxBytes=1024 * 10, # 10 KB\n    backupCount=5 # En fazla 5 eski log dosyas\u0131 tut\n)\nrot_file_handler.setLevel(logging.INFO)\nrot_file_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))\nmy_app_logger.addHandler(rot_file_handler)\n\n<h2>TimedRotatingFileHandler \u00f6rne\u011fi (g\u00fcnl\u00fck rotasyon)<\/h2>\ntimed_rot_file_handler = TimedRotatingFileHandler(\n    'timed_app.log',\n    when='midnight', # Her gece yar\u0131s\u0131 rotasyon yap\n    interval=1,\n    backupCount=7 # En fazla 7 g\u00fcnl\u00fck log dosyas\u0131 tut\n)\ntimed_rot_file_handler.setLevel(logging.INFO)\ntimed_rot_file_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))\nmy_app_logger.addHandler(timed_rot_file_handler)\n\n<h2>Bir s\u00fcre boyunca log mesajlar\u0131 g\u00f6nderelim<\/h2>\nfor i in range(200):\n    my_app_logger.info(f\"Test mesaj\u0131 {i}\")\n    time.sleep(0.01) # Biraz bekle ki dosya boyutu arts\u0131n<\/code><\/pre>\n<p>Bu \u00f6rnekler, log dosyalar\u0131n\u0131z\u0131n y\u00f6netilebilir boyutlarda kalmas\u0131n\u0131 sa\u011flar. <code>RotatingFileHandler<\/code> belirli bir boyuta ula\u015ft\u0131\u011f\u0131nda, <code>TimedRotatingFileHandler<\/code> ise belirli bir zaman aral\u0131\u011f\u0131 ge\u00e7ti\u011finde yeni bir log dosyas\u0131 olu\u015fturur ve eski dosyalar\u0131 adland\u0131rarak saklar.<\/p>\n<h4>Formatter&#8217;lar: Mesajlar\u0131n Bi\u00e7imi<\/h4>\n<p>Formatter&#8217;lar, log kay\u0131tlar\u0131n\u0131n \u00e7\u0131kt\u0131 format\u0131n\u0131 belirler. Bir <code>LogRecord<\/code> nesnesi, log mesaj\u0131n\u0131n kendisi, seviyesi, zaman damgas\u0131, logger ad\u0131, kaynak dosya ad\u0131 ve sat\u0131r numaras\u0131 gibi bir\u00e7ok \u00f6znitelik i\u00e7erir. Formatter&#8217;lar, bu \u00f6znitelikleri kullanarak \u00e7\u0131kt\u0131y\u0131 istedi\u011finiz \u015fekilde yap\u0131land\u0131rman\u0131za olanak tan\u0131r.<\/p>\n<p>Bir <code>Formatter<\/code> nesnesi olu\u015ftururken bir bi\u00e7im dizesi (format string) belirtilir. Bu dize, log kay\u0131tlar\u0131ndaki \u00f6zniteliklere kar\u015f\u0131l\u0131k gelen \u00f6zel y\u00fczde i\u015faretli ifadeler (<code>%<\/code>) i\u00e7erir.<\/p>\n<p>Yayg\u0131n kullan\u0131lan bi\u00e7im \u00f6znitelikleri:<\/p>\n<p>*   <strong><code>%(name)s<\/code><\/strong>: Logger&#8217;\u0131n ad\u0131.<br \/>\n*   <strong><code>%(levelname)s<\/code><\/strong>: Log seviyesi (DEBUG, INFO vb.).<br \/>\n*   <strong><code>%(asctime)s<\/code><\/strong>: \u0130nsan taraf\u0131ndan okunabilir zaman damgas\u0131.<br \/>\n*   <strong><code>%(filename)s<\/code><\/strong>: Log \u00e7a\u011fr\u0131s\u0131n\u0131n yap\u0131ld\u0131\u011f\u0131 dosyan\u0131n ad\u0131.<br \/>\n*   <strong><code>%(lineno)d<\/code><\/strong>: Log \u00e7a\u011fr\u0131s\u0131n\u0131n yap\u0131ld\u0131\u011f\u0131 sat\u0131r numaras\u0131.<br \/>\n*   <strong><code>%(module)s<\/code><\/strong>: Log \u00e7a\u011fr\u0131s\u0131n\u0131n yap\u0131ld\u0131\u011f\u0131 mod\u00fcl ad\u0131.<br \/>\n*   <strong><code>%(funcName)s<\/code><\/strong>: Log \u00e7a\u011fr\u0131s\u0131n\u0131n yap\u0131ld\u0131\u011f\u0131 fonksiyon ad\u0131.<br \/>\n*   <strong><code>%(message)s<\/code><\/strong>: Log mesaj\u0131n\u0131n kendisi.<br \/>\n*   <strong><code>%(process)d<\/code><\/strong>: \u0130\u015flem ID&#8217;si.<br \/>\n*   <strong><code>%(thread)d<\/code><\/strong>: \u0130\u015f par\u00e7ac\u0131\u011f\u0131 ID&#8217;si.<br \/>\n*   <strong><code>%(threadName)s<\/code><\/strong>: \u0130\u015f par\u00e7ac\u0131\u011f\u0131 ad\u0131.<\/p>\n<p><strong>Tarih\/Saat Bi\u00e7imlendirmesi:<\/strong><br \/>\n<code>Formatter<\/code>&#8216;a <code>datefmt<\/code> parametresi ile \u00f6zel bir tarih\/saat format\u0131 da sa\u011flayabilirsiniz. Bu, <code>strftime()<\/code> format kodlar\u0131n\u0131 kullan\u0131r.<\/p>\n<pre><code class=\"language-python\">import logging\n\n<h2>Logger olu\u015ftur<\/h2>\nmy_logger = logging.getLogger(\"custom_format_logger\")\nmy_logger.setLevel(logging.DEBUG)\n\n<h2>StreamHandler olu\u015ftur<\/h2>\nhandler = logging.StreamHandler()\n\n<h2>\u00d6zel formatlay\u0131c\u0131 olu\u015ftur<\/h2>\nformatter = logging.Formatter(\n    '%(asctime)s - [%(levelname)s] - (%(filename)s:%(lineno)d) - %(message)s',\n    datefmt='%Y-%m-%d %H:%M:%S' # YYYY-MM-DD HH:MM:SS format\u0131\n)\n\n<h2>Handler'a formatlay\u0131c\u0131y\u0131 ata<\/h2>\nhandler.setFormatter(formatter)\n\n<h2>Logger'a handler'\u0131 ekle<\/h2>\nmy_logger.addHandler(handler)\n\nmy_logger.debug(\"Bu bir hata ay\u0131klama mesaj\u0131d\u0131r.\")\nmy_logger.info(\"Uygulama ba\u015far\u0131yla ba\u015flat\u0131ld\u0131.\")\nmy_logger.error(\"Veri i\u015fleme s\u0131ras\u0131nda bir hata olu\u015ftu.\")<\/code><\/pre>\n<p>\u00c7\u0131kt\u0131:<\/p>\n<pre><code class=\"language-\">2023-10-27 10:30:00 - [DEBUG] - (example.py:19) - Bu bir hata ay\u0131klama mesaj\u0131d\u0131r.\n2023-10-27 10:30:00 - [INFO] - (example.py:20) - Uygulama ba\u015far\u0131yla ba\u015flat\u0131ld\u0131.\n2023-10-27 10:30:00 - [ERROR] - (example.py:21) - Veri i\u015fleme s\u0131ras\u0131nda bir hata olu\u015ftu.<\/code><\/pre>\n<h4>Filter&#8217;lar: Mesajlar\u0131n S\u00fcz\u00fclmesi<\/h4>\n<p>Filter&#8217;lar, log kay\u0131tlar\u0131n\u0131 i\u015flenmeden \u00f6nce dinamik olarak s\u00fczmek i\u00e7in kullan\u0131l\u0131r. Bir logger&#8217;a veya bir handler&#8217;a filtreler ekleyebilirsiniz. Bir log kayd\u0131, t\u00fcm filtrelerden ge\u00e7tikten sonra i\u015flenir. E\u011fer herhangi bir filtre kayd\u0131 reddederse, o kay\u0131t i\u015flenmez.<\/p>\n<p>Filter&#8217;lar, <code>logging.Filter<\/code> s\u0131n\u0131f\u0131ndan t\u00fcretilerek veya do\u011frudan bir <code>logging.Filter<\/code> nesnesi olu\u015fturularak kullan\u0131labilir. <code>Filter<\/code>&#8216;\u0131n <code>filter()<\/code> metodu, bir <code>LogRecord<\/code> nesnesini al\u0131r ve <code>True<\/code> (kabul) veya <code>False<\/code> (reddet) d\u00f6nd\u00fcr\u00fcr.<\/p>\n<pre><code class=\"language-python\">import logging\n\n<h2>Sadece belirli bir logger ad\u0131ndan gelen mesajlar\u0131 kabul eden \u00f6zel bir filtre<\/h2>\nclass MyCustomFilter(logging.Filter):\n    def __init__(self, name_starts_with):\n        super().__init__()\n        self.name_starts_with = name_starts_with\n\n    def filter(self, record):\n        return record.name.startswith(self.name_starts_with)\n\n<h2>Logger olu\u015ftur<\/h2>\nmain_logger = logging.getLogger(\"main_app\")\nmain_logger.setLevel(logging.DEBUG)\n\n<h2>Handler olu\u015ftur ve formatlay\u0131c\u0131 ata<\/h2>\nhandler = logging.StreamHandler()\nformatter = logging.Formatter('%(name)s - %(levelname)s - %(message)s')\nhandler.setFormatter(formatter)\n\n<h2>Filtreyi olu\u015ftur ve handler'a ekle<\/h2>\ncustom_filter = MyCustomFilter(\"main_app.submodule\")\nhandler.addFilter(custom_filter) # Handler'a filtre ekliyoruz\n\nmain_logger.addHandler(handler)\n\n<h2>Alt logger'lar<\/h2>\nsubmodule_logger = logging.getLogger(\"main_app.submodule_a\")\nsubmodule_logger.info(\"Submodule A'dan gelen bilgi mesaj\u0131.\")\n\nanother_submodule_logger = logging.getLogger(\"main_app.submodule_b\")\nanother_submodule_logger.warning(\"Submodule B'den gelen uyar\u0131 mesaj\u0131.\")\n\n<h2>Ana logger'dan gelen mesaj<\/h2>\nmain_logger.error(\"Ana uygulamadan gelen hata mesaj\u0131.\")<\/code><\/pre>\n<p>Yukar\u0131daki \u00f6rnekte, <code>MyCustomFilter<\/code> sadece <code>main_app.submodule<\/code> ile ba\u015flayan logger adlar\u0131ndan gelen mesajlar\u0131 kabul eder. Bu nedenle, <code>main_app.submodule_a<\/code> ve <code>main_app.submodule_b<\/code>&#8216;den gelen mesajlar filtreyi ge\u00e7ecek, ancak <code>main_app<\/code>&#8216;ten gelen mesaj ge\u00e7emeyecektir.<\/p>\n<p>\u00c7\u0131kt\u0131:<\/p>\n<pre><code class=\"language-\">main_app.submodule_a - INFO - Submodule A'dan gelen bilgi mesaj\u0131.\nmain_app.submodule_b - WARNING - Submodule B'den gelen uyar\u0131 mesaj\u0131.<\/code><\/pre>\n<p><code>main_app<\/code> logger&#8217;\u0131ndan gelen <code>ERROR<\/code> mesaj\u0131, <code>main_app.submodule<\/code> ile ba\u015flamad\u0131\u011f\u0131 i\u00e7in filtreden ge\u00e7emedi ve konsola yazd\u0131r\u0131lmad\u0131.<\/p>\n<h3>Geli\u015fmi\u015f Logging Konfig\u00fcrasyonlar\u0131<\/h3>\n<h4><code>logging.basicConfig()<\/code> ile Detayl\u0131 Konfig\u00fcrasyon<\/h4>\n<p>Daha \u00f6nce de belirtildi\u011fi gibi, <code>basicConfig()<\/code> basit senaryolar i\u00e7in harikad\u0131r. Ancak, karma\u015f\u0131k uygulamalarda farkl\u0131 handler&#8217;lar, filtreler ve logger hiyerar\u015fileri kurman\u0131z gerekti\u011finde yetersiz kalabilir. <code>basicConfig()<\/code> yaln\u0131zca k\u00f6k logger&#8217;\u0131 yap\u0131land\u0131r\u0131r ve yaln\u0131zca ilk \u00e7a\u011fr\u0131ld\u0131\u011f\u0131nda etkilidir. Birden fazla handler veya farkl\u0131 logger&#8217;lar i\u00e7in \u00f6zel ayarlar yapmak istiyorsan\u0131z, di\u011fer konfig\u00fcrasyon y\u00f6ntemlerine ba\u015fvurman\u0131z gerekir.<\/p>\n<h4>Dosya Tabanl\u0131 Konfig\u00fcrasyon (INI, YAML, JSON)<\/h4>\n<p>B\u00fcy\u00fck uygulamalarda, loglama konfig\u00fcrasyonunu kodun i\u00e7ine g\u00f6mmek yerine ayr\u0131 bir dosyada tutmak daha esnektir. Bu, uygulaman\u0131z\u0131 yeniden da\u011f\u0131tmadan loglama davran\u0131\u015f\u0131n\u0131 de\u011fi\u015ftirmenize olanak tan\u0131r. Python&#8217;\u0131n <code>logging.config<\/code> mod\u00fcl\u00fc, s\u00f6zl\u00fck tabanl\u0131 konfig\u00fcrasyonu (dictionary-based configuration) destekler ve bu da INI, YAML veya JSON gibi dosya formatlar\u0131ndan kolayca y\u00fcklenebilir.<\/p>\n<p><strong>INI Dosyas\u0131 ile Konfig\u00fcrasyon \u00d6rne\u011fi:<\/strong><br \/>\n<code>logging.conf<\/code> ad\u0131nda bir dosya olu\u015ftural\u0131m:<\/p>\n<pre><code class=\"language-ini\">[loggers]\nkeys=root,my_app\n\n[handlers]\nkeys=consoleHandler,fileHandler\n\n[formatters]\nkeys=simpleFormatter,detailedFormatter\n\n[logger_root]\nlevel=INFO\nhandlers=consoleHandler\n\n[logger_my_app]\nlevel=DEBUG\nhandlers=fileHandler\nqualname=my_app\npropagate=0 # K\u00f6k logger'a yay\u0131lmay\u0131 kapat\n\n[handler_consoleHandler]\nclass=StreamHandler\nlevel=INFO\nformatter=simpleFormatter\nargs=(sys.stdout,)\n\n[handler_fileHandler]\nclass=FileHandler\nlevel=DEBUG\nformatter=detailedFormatter\nargs=('app.log', 'a')\n\n[formatter_simpleFormatter]\nformat=%(name)s - %(levelname)s - %(message)s\ndatefmt=\n\n[formatter_detailedFormatter]\nformat=%(asctime)s - %(name)s - %(levelname)s - %(module)s:%(lineno)d - %(message)s\ndatefmt=%Y-%m-%d %H:%M:%S<\/code><\/pre>\n<p>\u015eimdi bu dosyay\u0131 Python kodumuzdan y\u00fckleyelim:<\/p>\n<pre><code class=\"language-python\">import logging.config\nimport sys # sys.stdout i\u00e7in gerekli\n\n<h2>logging.conf dosyas\u0131n\u0131 y\u00fckle<\/h2>\ntry:\n    logging.config.fileConfig('logging.conf')\nexcept Exception as e:\n    print(f\"Logging konfig\u00fcrasyonu y\u00fcklenirken hata olu\u015ftu: {e}\")\n    sys.exit(1)\n\n<h2>Logger'lar\u0131 al<\/h2>\nroot_logger = logging.getLogger()\nmy_app_logger = logging.getLogger(\"my_app\")\n\nroot_logger.info(\"Bu k\u00f6k logger'dan gelen bir bilgi mesaj\u0131d\u0131r.\")\nroot_logger.debug(\"Bu k\u00f6k logger'dan gelen bir debug mesaj\u0131d\u0131r. (G\u00f6r\u00fcnmez)\")\n\nmy_app_logger.debug(\"Bu my_app logger'dan gelen bir debug mesaj\u0131d\u0131r.\")\nmy_app_logger.info(\"Bu my_app logger'dan gelen bir bilgi mesaj\u0131d\u0131r.\")\nmy_app_logger.error(\"my_app'te bir hata olu\u015ftu.\")<\/code><\/pre>\n<p>Bu \u00f6rnek, INI dosyas\u0131n\u0131n nas\u0131l kullan\u0131ld\u0131\u011f\u0131n\u0131 g\u00f6sterir. <code>logging.config.dictConfig<\/code> fonksiyonu ile YAML veya JSON dosyalar\u0131n\u0131 da y\u00fckleyebilirsiniz, bu da daha karma\u015f\u0131k veri yap\u0131lar\u0131 i\u00e7in daha uygun olabilir.<\/p>\n<h4>Mod\u00fcller Aras\u0131 Logging<\/h4>\n<p>B\u00fcy\u00fck bir uygulamada, farkl\u0131 Python mod\u00fcllerinin kendi logger&#8217;lar\u0131na sahip olmas\u0131 iyi bir pratiktir. Bu, log mesajlar\u0131n\u0131n hangi mod\u00fclden geldi\u011fini kolayca takip etmenizi sa\u011flar ve loglama hiyerar\u015fisinin avantajlar\u0131ndan yararlanman\u0131za yard\u0131mc\u0131 olur. Her mod\u00fclde, logger&#8217;\u0131 <code>logging.getLogger(__name__)<\/code> ile almak standart bir yakla\u015f\u0131md\u0131r. <code>__name__<\/code> \u00f6zel de\u011fi\u015fkeni, o mod\u00fcl\u00fcn ad\u0131n\u0131 i\u00e7erir.<\/p>\n<p><code>my_module.py<\/code>:<\/p>\n<pre><code class=\"language-python\">import logging\n\nlogger = logging.getLogger(__name__) # Logger ad\u0131 'my_module' olacak\n\ndef do_something():\n    logger.debug(\"do_something fonksiyonu \u00e7al\u0131\u015f\u0131yor.\")\n    # ... baz\u0131 i\u015flemler ...\n    logger.info(\"do_something fonksiyonu tamamland\u0131.\")<\/code><\/pre>\n<p><code>main_app.py<\/code>:<\/p>\n<pre><code class=\"language-python\">import logging\nimport my_module\n\n<h2>Temel konfig\u00fcrasyon<\/h2>\nlogging.basicConfig(level=logging.DEBUG, format='%(name)s - %(levelname)s - %(message)s')\n\nmain_logger = logging.getLogger(__name__) # Logger ad\u0131 'main_app' olacak\n\nmain_logger.info(\"Uygulama ba\u015flat\u0131l\u0131yor.\")\nmy_module.do_something()\nmain_logger.info(\"Uygulama sona erdi.\")<\/code><\/pre>\n<p>\u00c7\u0131kt\u0131:<\/p>\n<pre><code class=\"language-\">main_app - INFO - Uygulama ba\u015flat\u0131l\u0131yor.\nmy_module - DEBUG - do_something fonksiyonu \u00e7al\u0131\u015f\u0131yor.\nmy_module - INFO - do_something fonksiyonu tamamland\u0131.\nmain_app - INFO - Uygulama sona erdi.<\/code><\/pre>\n<p>Bu yakla\u015f\u0131m, log \u00e7\u0131kt\u0131s\u0131nda mesaj\u0131n kayna\u011f\u0131n\u0131 net bir \u015fekilde g\u00f6rmenizi sa\u011flar ve her mod\u00fcl\u00fcn kendi loglama seviyesini ve handler&#8217;lar\u0131n\u0131 yap\u0131land\u0131rma esnekli\u011fi sunar.<\/p>\n<h4>\u0130stisna (Exception) Logging<\/h4>\n<p>Hatalar\u0131n loglanmas\u0131, herhangi bir uygulaman\u0131n kararl\u0131l\u0131\u011f\u0131 i\u00e7in hayati \u00f6neme sahiptir. <code>logging<\/code> mod\u00fcl\u00fc, istisnalar\u0131 (exceptions) ve onlar\u0131n izleme bilgilerini (traceback) kolayca loglamak i\u00e7in \u00f6zel y\u00f6ntemler sunar.<\/p>\n<p><em>   <strong><code>logger.exception(msg, <\/em>args, <\/strong>kwargs)<\/code><em><\/em>: Bu y\u00f6ntem, yaln\u0131zca <code>ERROR<\/code> seviyesindeki mesajlar i\u00e7in ge\u00e7erlidir ve \u00e7a\u011fr\u0131ld\u0131\u011f\u0131 anda mevcut istisna bilgisini (traceback dahil) otomatik olarak log mesaj\u0131na ekler. Genellikle bir <code>except<\/code> blo\u011fu i\u00e7inde kullan\u0131l\u0131r.<br \/>\n*   <strong><code>logger.error(msg, exc_info=True)<\/code><\/strong>: Bu y\u00f6ntem, <code>exc_info=True<\/code> parametresi ile kullan\u0131ld\u0131\u011f\u0131nda, <code>exception()<\/code> ile ayn\u0131 etkiyi yarat\u0131r ve istisna bilgisini loglar.<\/p>\n<pre><code class=\"language-python\">import logging\n\nlogging.basicConfig(level=logging.ERROR, format='%(asctime)s - %(levelname)s - %(message)s')\nlogger = logging.getLogger(\"exception_logger\")\n\ndef divide(a, b):\n    try:\n        result = a \/ b\n        logger.info(f\"B\u00f6lme sonucu: {result}\")\n    except ZeroDivisionError:\n        logger.exception(\"S\u0131f\u0131ra b\u00f6lme hatas\u0131 olu\u015ftu!\") # Traceback'i otomatik olarak loglar\n        # veya\n        # logger.error(\"S\u0131f\u0131ra b\u00f6lme hatas\u0131 olu\u015ftu!\", exc_info=True)\n    except TypeError:\n        logger.error(\"Ge\u00e7ersiz t\u00fcrde giri\u015f!\", exc_info=True) # exc_info=True ile traceback'i loglar\n    except Exception as e:\n        logger.error(f\"Beklenmedik bir hata olu\u015ftu: {e}\", exc_info=True)\n\ndivide(10, 2)\ndivide(10, 0)\ndivide(\"a\", 2)<\/code><\/pre>\n<p>\u00c7\u0131kt\u0131 (konsol ve\/veya dosya):<\/p>\n<pre><code class=\"language-\">2023-10-27 10:30:00,123 - ERROR - S\u0131f\u0131ra b\u00f6lme hatas\u0131 olu\u015ftu!\nTraceback (most recent call last):\n  File \"<stdin>\", line 13, in divide\nZeroDivisionError: division by zero\n2023-10-27 10:30:00,124 - ERROR - Ge\u00e7ersiz t\u00fcrde giri\u015f!\nTraceback (most recent call last):\n  File \"<stdin>\", line 12, in divide\nTypeError: unsupported operand type(s) for \/: 'str' and 'int'<\/code><\/pre>\n<p><code>logger.exception()<\/code> ve <code>exc_info=True<\/code> kullan\u0131m\u0131, hata ay\u0131klama s\u0131ras\u0131nda \u00e7ok de\u011ferli olan ayr\u0131nt\u0131l\u0131 hata izleme bilgilerini otomatik olarak yakalar.<\/p>\n<h4>Performans ve Logging<\/h4>\n<p>Loglama, uygulaman\u0131z\u0131n performans\u0131n\u0131 etkileyebilir, \u00f6zellikle y\u00fcksek hacimli veya disk G\/\u00c7 i\u015flemlerinin yo\u011fun oldu\u011fu senaryolarda. Performans\u0131 optimize etmek i\u00e7in dikkat edilmesi gerekenler:<\/p>\n<p>*   <strong>Log Seviyelerini Ak\u0131ll\u0131ca Kullan\u0131n:<\/strong> \u00dcretim ortam\u0131nda <code>DEBUG<\/code> seviyesinde loglama yapmak gereksiz yere disk alan\u0131 t\u00fcketir ve G\/\u00c7 y\u00fck\u00fcn\u00fc art\u0131r\u0131r. Yaln\u0131zca gerekli seviyeleri (\u00f6rn. <code>INFO<\/code>, <code>WARNING<\/code>, <code>ERROR<\/code>) kullan\u0131n.<br \/>\n*   <strong>Gereksiz Loglama \u00c7a\u011fr\u0131lar\u0131ndan Ka\u00e7\u0131n\u0131n:<\/strong> \u00d6zellikle d\u00f6ng\u00fcler i\u00e7inde veya s\u0131k\u00e7a \u00e7a\u011fr\u0131lan fonksiyonlarda, yaln\u0131zca gerekli oldu\u011funda loglama yap\u0131n.<\/p>\n<pre><code class=\"language-python\"># K\u00f6t\u00fc \u00f6rnek: mesaj her zaman olu\u015fturulur\n    logger.debug(f\"Karma\u015f\u0131k hesaplama sonucu: {very_complex_calculation()}\")\n\n    # \u0130yi \u00f6rnek: mesaj sadece DEBUG seviyesi etkinse olu\u015fturulur\n    if logger.isEnabledFor(logging.DEBUG):\n        logger.debug(f\"Karma\u015f\u0131k hesaplama sonucu: {very_complex_calculation()}\")<\/code><\/pre>\n<p>*   <strong>Asenkron Logging (QueueHandler):<\/strong> Performans kritik uygulamalarda, log mesajlar\u0131n\u0131 ayr\u0131 bir i\u015f par\u00e7ac\u0131\u011f\u0131nda veya i\u015flemde i\u015flemek i\u00e7in <code>QueueHandler<\/code> kullan\u0131labilir. Bu, ana uygulama i\u015f par\u00e7ac\u0131\u011f\u0131n\u0131n loglama G\/\u00c7 i\u015flemlerini beklemesini engeller.<br \/>\n*   <strong><code>logging.disable()<\/code>:<\/strong> Belirli bir log seviyesinin alt\u0131ndaki t\u00fcm loglama \u00e7a\u011fr\u0131lar\u0131n\u0131 ge\u00e7ici olarak devre d\u0131\u015f\u0131 b\u0131rakmak i\u00e7in kullan\u0131labilir.<\/p>\n<pre><code class=\"language-python\">logging.disable(logging.CRITICAL) # CRITICAL alt\u0131ndaki t\u00fcm loglar\u0131 devre d\u0131\u015f\u0131 b\u0131rak\n    logger.error(\"Bu mesaj g\u00f6r\u00fcnmez.\")\n    logging.disable(logging.NOTSET) # Loglamay\u0131 tekrar etkinle\u015ftir\n    logger.error(\"Bu mesaj \u015fimdi g\u00f6r\u00fcn\u00fcr.\")<\/code><\/pre>\n<h3>Logging&#8217;e Alternatifler ve En \u0130yi Uygulamalar<\/h3>\n<h4><code>print()<\/code> vs. <code>logging<\/code>: Neden logging tercih edilmeli?<\/h4>\n<p>| \u00d6zellik          | <code>print()<\/code>                                    | <code>logging<\/code>                                         |<br \/>\n| :&#8212;&#8212;&#8212;&#8212;&#8212; | :&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;- | :&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; |<br \/>\n| <strong>Kontrol<\/strong>      | Yok. Her zaman konsola yazar.                 | Seviye, hedef, format \u00fczerinde tam kontrol.       |<br \/>\n| <strong>Esneklik<\/strong>     | Yok.                                         | Birden fazla hedef, rotasyon, filtreleme.         |<br \/>\n| <strong>Performans<\/strong>   | Basit senaryolarda h\u0131zl\u0131.                    | Daha fazla overhead, ancak optimize edilebilir.   |<br \/>\n| <strong>Standartla\u015fma<\/strong>| Yok.                                         | End\u00fcstri standard\u0131 seviyeler ve formatlar.        |<br \/>\n| <strong>Kullan\u0131m<\/strong>     | H\u0131zl\u0131 hata ay\u0131klama, k\u00fc\u00e7\u00fck script&#8217;ler.       | \u00dcretim uygulamalar\u0131, hata ay\u0131klama, izleme.       |<br \/>\n| <strong>\u0130stisna Bilgisi<\/strong>| Manuel olarak eklenmeli.                     | Otomatik olarak traceback ekleyebilir (<code>exc_info=True<\/code>). |<\/p>\n<p><code>print()<\/code> sadece geli\u015ftirme a\u015famas\u0131nda h\u0131zl\u0131 denemeler i\u00e7in uygunken, <code>logging<\/code> mod\u00fcl\u00fc ger\u00e7ek d\u00fcnya uygulamalar\u0131nda sa\u011flaml\u0131k, esneklik ve s\u00fcrd\u00fcr\u00fclebilirlik sa\u011flar.<\/p>\n<h4>Yap\u0131land\u0131r\u0131lm\u0131\u015f Logging (Structured Logging)<\/h4>\n<p>Geleneksel log mesajlar\u0131 genellikle serbest metin format\u0131ndad\u0131r, bu da makine taraf\u0131ndan analiz edilmelerini zorla\u015ft\u0131r\u0131r. Yap\u0131land\u0131r\u0131lm\u0131\u015f logging, log kay\u0131tlar\u0131n\u0131 JSON veya di\u011fer makine taraf\u0131ndan okunabilir formatlarda \u00fcretme yakla\u015f\u0131m\u0131d\u0131r. Bu, loglar\u0131 merkezi bir log y\u00f6netimi sistemine (\u00f6rn. ELK Stack, Splunk) g\u00f6nderirken \u00e7ok faydal\u0131d\u0131r, \u00e7\u00fcnk\u00fc alanlara g\u00f6re kolayca sorgulanabilir ve analiz edilebilirler.<\/p>\n<pre><code class=\"language-python\">import logging\nimport json\n\nclass JsonFormatter(logging.Formatter):\n    def format(self, record):\n        log_record = {\n            \"timestamp\": self.formatTime(record, self.datefmt),\n            \"level\": record.levelname,\n            \"logger_name\": record.name,\n            \"message\": record.getMessage(),\n            \"module\": record.module,\n            \"funcName\": record.funcName,\n            \"lineno\": record.lineno,\n            # Ekstra verileri burada ekleyebilirsiniz\n            <em><\/em>getattr(record, 'extra_data', {})\n        }\n        return json.dumps(log_record)\n\nlogger = logging.getLogger(\"structured_logger\")\nlogger.setLevel(logging.INFO)\n\nhandler = logging.StreamHandler()\nhandler.setFormatter(JsonFormatter(datefmt='%Y-%m-%dT%H:%M:%S%z'))\nlogger.addHandler(handler)\n\n<h2>Ekstra veri ile loglama<\/h2>\nlogger.info(\"Kullan\u0131c\u0131 giri\u015fi ba\u015far\u0131l\u0131.\", extra={'extra_data': {'user_id': 123, 'ip_address': '192.168.1.1'}})\nlogger.error(\"Veritaban\u0131 ba\u011flant\u0131s\u0131 kesildi.\", extra={'extra_data': {'db_host': 'localhost', 'port': 5432}})<\/code><\/pre>\n<p>Bu \u00f6rnek, log mesajlar\u0131n\u0131 JSON format\u0131nda \u00e7\u0131kt\u0131lama yetene\u011fini g\u00f6sterir. <code>extra<\/code> parametresi ile log kayd\u0131na \u00f6zel veriler ekleyebilirsiniz.<\/p>\n<h4>Asenkron Logging (Async Logging)<\/h4>\n<p>Yukar\u0131da bahsedildi\u011fi gibi, loglama G\/\u00c7 i\u015flemleri (diske yazma, a\u011f \u00fczerinden g\u00f6nderme) uygulaman\u0131z\u0131n ana i\u015f par\u00e7ac\u0131\u011f\u0131n\u0131 bloke edebilir. Asenkron logging, bu G\/\u00c7 i\u015flemlerini ayr\u0131 bir i\u015f par\u00e7ac\u0131\u011f\u0131na veya s\u00fcrece devrederek uygulaman\u0131z\u0131n yan\u0131t verme h\u0131z\u0131n\u0131 art\u0131r\u0131r. <code>logging.handlers.QueueHandler<\/code> ve <code>logging.handlers.QueueListener<\/code> bu senaryo i\u00e7in tasarlanm\u0131\u015ft\u0131r.<\/p>\n<pre><code class=\"language-python\">import logging\nimport logging.handlers\nimport queue\nimport time\nimport threading\n\n<h2>Ana logger'\u0131 olu\u015ftur<\/h2>\nlogger = logging.getLogger(\"async_logger\")\nlogger.setLevel(logging.DEBUG)\n\n<h2>Bir kuyruk olu\u015ftur<\/h2>\nlog_queue = queue.Queue(-1) # S\u0131n\u0131rs\u0131z boyutlu kuyruk\n\n<h2>Kuyruk handler'\u0131 olu\u015ftur ve logger'a ekle<\/h2>\nqueue_handler = logging.handlers.QueueHandler(log_queue)\nlogger.addHandler(queue_handler)\n\n<h2>Kuyruk dinleyicisi i\u00e7in hedef handler'lar<\/h2>\nfile_handler = logging.FileHandler(\"async_app.log\")\nfile_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))\n\nconsole_handler = logging.StreamHandler()\nconsole_handler.setFormatter(logging.Formatter('ASYNC: %(levelname)s - %(message)s'))\n\n<h2>Kuyruk dinleyicisini olu\u015ftur ve ba\u015flat<\/h2>\nqueue_listener = logging.handlers.QueueListener(log_queue, file_handler, console_handler)\nqueue_listener.start() # Ayr\u0131 bir thread'de loglar\u0131 i\u015flemeye ba\u015flar\n\n<h2>Ana uygulama i\u015f par\u00e7ac\u0131\u011f\u0131nda log mesajlar\u0131 \u00fcret<\/h2>\nfor i in range(10):\n    logger.info(f\"Ana i\u015f par\u00e7ac\u0131\u011f\u0131ndan mesaj {i}\")\n    time.sleep(0.1)\n\nlogger.debug(\"Hata ay\u0131klama mesaj\u0131.\")\nlogger.error(\"Kritik bir hata meydana geldi.\")\n\n<h2>Uygulama kapan\u0131rken dinleyiciyi durdurmak \u00f6nemlidir<\/h2>\n<h2>Aksi takdirde kuyruktaki son mesajlar i\u015flenmeyebilir.<\/h2>\ntime.sleep(0.5) # Kuyruktaki mesajlar\u0131n i\u015flenmesi i\u00e7in biraz bekle\nqueue_listener.stop()\nprint(\"Asenkron loglama tamamland\u0131.\")<\/code><\/pre>\n<p>Bu kurulum, log mesajlar\u0131n\u0131 bir kuyru\u011fa atar ve bu kuyruktaki mesajlar ayr\u0131 bir i\u015f par\u00e7ac\u0131\u011f\u0131nda \u00e7al\u0131\u015fan <code>QueueListener<\/code> taraf\u0131ndan al\u0131narak ger\u00e7ek handler&#8217;lara (bu \u00f6rnekte <code>FileHandler<\/code> ve <code>StreamHandler<\/code>) iletilir. Bu, loglama i\u015fleminin ana uygulaman\u0131n performans\u0131n\u0131 do\u011frudan etkilemesini engeller.<\/p>\n<h3>Sonu\u00e7<\/h3>\n<p>Python&#8217;\u0131n <code>logging<\/code> mod\u00fcl\u00fc, uygulamalar\u0131n\u0131z i\u00e7in g\u00fc\u00e7l\u00fc, esnek ve \u00f6l\u00e7eklenebilir bir loglama \u00e7\u00f6z\u00fcm\u00fc sunar. <code>print()<\/code> fonksiyonunun basitli\u011fini a\u015farak, log seviyeleri, handler&#8217;lar, formatlay\u0131c\u0131lar ve filtreler gibi bile\u015fenlerle loglama davran\u0131\u015f\u0131n\u0131 tamamen kontrol etmenizi sa\u011flar. \u0130ster basit bir script i\u00e7in konsola bilgi mesajlar\u0131 yaz\u0131n, ister b\u00fcy\u00fck \u00f6l\u00e7ekli bir kurumsal uygulama i\u00e7in merkezi log y\u00f6netimi sistemlerine yap\u0131land\u0131r\u0131lm\u0131\u015f loglar g\u00f6nderin, <code>logging<\/code> mod\u00fcl\u00fc her ihtiyaca cevap verebilecek kapasitededir.<\/p>\n<p>Do\u011fru loglama stratejileri, geli\u015ftirme s\u00fcrecini h\u0131zland\u0131r\u0131r, \u00fcretim ortam\u0131ndaki sorunlar\u0131 te\u015fhis etmeyi kolayla\u015ft\u0131r\u0131r ve genel sistem sa\u011fl\u0131\u011f\u0131n\u0131 izlemek i\u00e7in paha bi\u00e7ilmez bir ara\u00e7 haline gelir. Bu rehberde ele al\u0131nan temel ve geli\u015fmi\u015f kavramlar\u0131 anlayarak, Python uygulamalar\u0131n\u0131zda etkili ve verimli bir loglama altyap\u0131s\u0131 kurabilirsiniz. Logging&#8217;i uygulaman\u0131z\u0131n vazge\u00e7ilmez bir par\u00e7as\u0131 haline getirerek, daha \u015feffaf, y\u00f6netilebilir ve g\u00fcvenilir yaz\u0131l\u0131mlar geli\u015ftireceksiniz.<\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Python 3&#8217;te Logging Kullan\u0131m\u0131: Kapsaml\u0131 Bir Rehber\nGiri\u015f: Neden Logging \u00d6nemlidir?\nYaz\u0131l\u0131m geli\u015ftirme s\u00fcrecinde, bir uygulaman\u0131n davran\u0131\u015f","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1403],"tags":[],"class_list":{"0":"post-36187","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-python","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Python 3&#039;te Logging Kullan\u0131m\u0131: Kapsaml\u0131 Bir Rehber - Kodlar\u0131n Gizemli D\u00fcnyas\u0131<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/python-3te-logging-kullanimi-kapsamli-bir-rehber\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Python 3&#039;te Logging Kullan\u0131m\u0131: Kapsaml\u0131 Bir Rehber\" \/>\n<meta property=\"og:description\" content=\"Python 3&#039;te Logging Kullan\u0131m\u0131: Kapsaml\u0131 Bir Rehber Giri\u015f: Neden Logging \u00d6nemlidir? Yaz\u0131l\u0131m geli\u015ftirme s\u00fcrecinde, bir uygulaman\u0131n davran\u0131\u015f\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/python-3te-logging-kullanimi-kapsamli-bir-rehber\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-12-09T18:41:03+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"25 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/python-3te-logging-kullanimi-kapsamli-bir-rehber\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/python-3te-logging-kullanimi-kapsamli-bir-rehber\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Python 3&#8217;te Logging Kullan\u0131m\u0131: Kapsaml\u0131 Bir Rehber\",\"datePublished\":\"2025-12-09T18:41:03+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/python-3te-logging-kullanimi-kapsamli-bir-rehber\/\"},\"wordCount\":2626,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"Python\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/python-3te-logging-kullanimi-kapsamli-bir-rehber\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/python-3te-logging-kullanimi-kapsamli-bir-rehber\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/python-3te-logging-kullanimi-kapsamli-bir-rehber\/\",\"name\":\"Python 3'te Logging Kullan\u0131m\u0131: Kapsaml\u0131 Bir Rehber - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-12-09T18:41:03+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/python-3te-logging-kullanimi-kapsamli-bir-rehber\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/python-3te-logging-kullanimi-kapsamli-bir-rehber\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/python-3te-logging-kullanimi-kapsamli-bir-rehber\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Python 3&#8217;te Logging Kullan\u0131m\u0131: Kapsaml\u0131 Bir Rehber\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Python 3'te Logging Kullan\u0131m\u0131: Kapsaml\u0131 Bir Rehber - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/python-3te-logging-kullanimi-kapsamli-bir-rehber\/","og_locale":"tr_TR","og_type":"article","og_title":"Python 3'te Logging Kullan\u0131m\u0131: Kapsaml\u0131 Bir Rehber","og_description":"Python 3'te Logging Kullan\u0131m\u0131: Kapsaml\u0131 Bir Rehber Giri\u015f: Neden Logging \u00d6nemlidir? Yaz\u0131l\u0131m geli\u015ftirme s\u00fcrecinde, bir uygulaman\u0131n davran\u0131\u015f","og_url":"https:\/\/fatihsoysal.com\/blog\/python-3te-logging-kullanimi-kapsamli-bir-rehber\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-12-09T18:41:03+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"25 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/python-3te-logging-kullanimi-kapsamli-bir-rehber\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/python-3te-logging-kullanimi-kapsamli-bir-rehber\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Python 3&#8217;te Logging Kullan\u0131m\u0131: Kapsaml\u0131 Bir Rehber","datePublished":"2025-12-09T18:41:03+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/python-3te-logging-kullanimi-kapsamli-bir-rehber\/"},"wordCount":2626,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["Python"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/python-3te-logging-kullanimi-kapsamli-bir-rehber\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/python-3te-logging-kullanimi-kapsamli-bir-rehber\/","url":"https:\/\/fatihsoysal.com\/blog\/python-3te-logging-kullanimi-kapsamli-bir-rehber\/","name":"Python 3'te Logging Kullan\u0131m\u0131: Kapsaml\u0131 Bir Rehber - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-12-09T18:41:03+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/python-3te-logging-kullanimi-kapsamli-bir-rehber\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/python-3te-logging-kullanimi-kapsamli-bir-rehber\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/python-3te-logging-kullanimi-kapsamli-bir-rehber\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Python 3&#8217;te Logging Kullan\u0131m\u0131: Kapsaml\u0131 Bir Rehber"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/36187","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=36187"}],"version-history":[{"count":1,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/36187\/revisions"}],"predecessor-version":[{"id":36188,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/36187\/revisions\/36188"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=36187"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=36187"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=36187"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}