دليل شامل لوحدة logging في بايثون لإدارة سجلات التطبيقات

1. ما هي وحدة تسجيل (logging) في بايثون؟

تُعد وحدة logging في بايثون أداة قياسية لتسجيل حالة عمل البرنامج ومعلومات الأخطاء، واستخدامها في تصحيح الأخطاء ومراقبة التشغيل. يكمن الاختلاف عن عبارات print في أن وحدة logging متعددة الوظائف وتسمح بالتحكم الدقيق في مستوى السجل، وجهة الإخراج، والتنسيق. يتيح ذلك للمطورين فهم حالات البرنامج الشاذة وحالاته بكفاءة.

أنواع ومجالات استخدام مستويات السجل

     

  • DEBUG: معلومات تصحيح تفصيلية. تستخدم بشكل أساسي في مرحلة التطوير.
  •  

  • INFO: معلومات تشغيل عامة. تستخدم للتحقق من العمليات الطبيعية.
  •  

  • WARNING: مشاكل بسيطة أو ملاحظات. لا تؤثر على عمل البرنامج ولكنها تشير إلى مشاكل محتملة.
  •  

  • ERROR: رسائل خطأ عند عدم عمل بعض الوظائف بشكل طبيعي. تشير إلى حالة تؤثر على تنفيذ البرنامج.
  •  

  • CRITICAL: أخطاء جسيمة. تشير إلى مشكلة قاتلة لا يمكن معها متابعة تنفيذ البرنامج بأكمله.

من خلال استخدام مستويات السجل المختلفة بشكل مناسب، يمكن تحسين جودة المعلومات المستفادة من السجلات، مما يتيح تصحيح الأخطاء والمراقبة بكفاءة.

2. الاستخدام الأساسي لوحدة logging

لنتعرف على الطريقة الأساسية لإخراج السجلات باستخدام وحدة logging.

import logging

# Configure log level and format
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')

# Log output for each level
logging.debug('Debug information: Detailed diagnostic information')
logging.info('Information message: Confirmation of normal operation')
logging.warning('Warning message: State requiring attention')
logging.error('Error message: A problem occurred')
logging.critical('Critical message: System shutdown')

باستخدام logging.basicConfig()، يتم تعيين وجهة إخراج السجل (الإخراج القياسي افتراضيًا)، مستوى السجل، والتنسيق. في المثال أعلاه، نظرًا لتعيين level=logging.DEBUG، سيتم إخراج جميع السجلات على مستوى DEBUG وما فوق.

侍エンジニア塾

3. تخصيص وجهة إخراج السجل والتنسيق

يمكن أيضًا تغيير وجهة الإخراج الافتراضية أو تخصيص تنسيق السجل. على سبيل المثال، لإخراج السجلات إلى ملف، نستخدم FileHandler.

الإخراج إلى ملف وتنسيقه

import logging

# Configure file handler
file_handler = logging.FileHandler('app.log')
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)

# Configure logger
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logger.addHandler(file_handler)

# Log output
logger.debug('Debug information to file')
logger.info('Information message to file')

في الكود أعلاه، يتم إخراج السجلات إلى app.log باستخدام FileHandler. يتم كتابة رسائل السجل بناءً على التنسيق المحدد بواسطة Formatter.

4. تدوير ملفات السجل

في التشغيل طويل الأمد، يعد تدوير ملفات السجل مهمًا لمنع تضخم حجم ملفات السجل بشكل كبير. باستخدام RotatingFileHandler، يمكن التحكم في حجم ملفات السجل وعدد الملفات.

مثال على استخدام RotatingFileHandler

import logging
from logging.handlers import RotatingFileHandler

# Configure rotating handler
handler = RotatingFileHandler('app.log', maxBytes=5000, backupCount=3)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)

# Configure logger
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logger.addHandler(handler)

# Log output
for i in range(100):
    logger.debug(f'Rotation test {i}')

في هذا الكود، تم تعيين الحد الأقصى لحجم ملف السجل إلى 5000 بايت باستخدام maxBytes، وتم تعيين عدد ملفات النسخ الاحتياطي إلى 3 باستخدام backupCount. عندما يتجاوز ملف السجل الحجم المحدد، يتم كتابة السجلات في ملف جديد ويتم الاحتفاظ بالملف القديم كنسخة احتياطية.

RUNTEQ(ランテック)|超実戦型エンジニア育成スクール

5. إخراج ملف لكل مستوى سجل

من خلال إخراج السجلات لكل مستوى سجل محدد إلى ملفات مختلفة، يمكن تحسين قابلية قراءة السجلات وكفاءة تحليلها. يتطلب ذلك استخدام مرشحات مخصصة وFileHandler متعددة.

مثال على إخراج ملف لكل مستوى سجل

import logging

class ErrorFilter(logging.Filter):
    def filter(self, record):
        return record.levelno == logging.ERROR

# Output ERROR level logs to a separate file
error_handler = logging.FileHandler('error.log')
error_handler.setLevel(logging.ERROR)
error_handler.addFilter(ErrorFilter())
error_handler.setFormatter(formatter)

# Configure logger
logger.addHandler(error_handler)

# Log output
logger.error('ERROR level logs will be output to file')

في هذا المثال، تم إنشاء الفئة ErrorFilter لتصفية السجلات على مستوى ERROR فقط، ويتم إخراجها إلى error.log. يتيح ذلك تسجيل سجلات الأخطاء فقط في ملف منفصل.

6. أفضل الممارسات والنقاط التي يجب الانتباه إليها

لاستخدام السجلات بشكل صحيح، يجب مراعاة أفضل الممارسات والنقاط التالية.

الاستخدام المناسب لمستويات السجل

     

  • أثناء التطوير، استخدم مستوى DEBUG لتسجيل معلومات تفصيلية، وفي مرحلة التشغيل، قم بالتبديل إلى مستويات INFO أو WARNING لتسجيل المعلومات المهمة فقط.
  •  

  • قد يتسبب الإخراج المفرط للسجلات في تدهور الأداء، لذا تأكد من تسجيل المعلومات الضرورية فقط.

أمان وخصوصية السجلات

     

  • احرص على عدم تسجيل المعلومات الشخصية أو السرية في السجلات. قد تكون هناك حاجة لتدابير مثل إخفاء البيانات حسب الضرورة.
  •  

  • قم بتعيين الأذونات المناسبة لملفات السجل لمنع الوصول غير المصرح به.

7. الخلاصة

تُعد وحدة logging أداة مفيدة للغاية لتسجيل حالة عمل البرنامج بكفاءة والمساعدة في تصحيح الأخطاء والتشغيل. من خلال تعيين مستوى السجل، وجهة الإخراج، التنسيق، والتدوير بشكل مناسب، وفهم حالة تشغيل البرنامج بالتفصيل، يمكن اكتشاف المشاكل وحلها مبكرًا. دعنا نطبق أفضل الممارسات ونمارس إدارة السجلات المناسبة.