পাইথন লগিং - আমদানি করা মডিউলগুলি থেকে লগিং অক্ষম করুন


100

আমি পাইথন লগিং মডিউলটি ব্যবহার করছি, এবং আমি আমদানি করা তৃতীয় পক্ষের মডিউলগুলি দ্বারা মুদ্রিত লগ বার্তাগুলি অক্ষম করতে চাই। উদাহরণস্বরূপ, আমি নিম্নলিখিতগুলির মতো কিছু ব্যবহার করছি:

logger = logging.getLogger()
logger.setLevel(level=logging.DEBUG)
fh = logging.StreamHandler()
fh_formatter = logging.Formatter('%(asctime)s %(levelname)s %(lineno)d:%(filename)s(%(process)d) - %(message)s')
fh.setFormatter(fh_formatter)
logger.addHandler(fh)

আমি লগার.ডিবেগ ("আমার বার্তা!") করার পরে এটি আমার ডিবাগ বার্তাগুলি মুদ্রণ করে তবে এটি আমদানি করা কোনও মডিউল (যেমন অনুরোধ এবং অন্যান্য কিছু বিষয়) থেকেও ডিবাগ বার্তাগুলি প্রিন্ট করে।

আমি আগ্রহী মডিউলগুলি থেকে কেবল লগ বার্তা দেখতে চাই। লগিং মডিউলটি এটি করা সম্ভব?

আদর্শভাবে, আমি লগারকে "মডিউলএক্স, মডিউলওয়াই" থেকে বার্তা মুদ্রণ করতে এবং অন্য সকলকে উপেক্ষা করতে সক্ষম হতে চাই।

আমি নীচের দিকে নজর রেখেছি, তবে আমদানি করা ফাংশনে প্রতিটি কল করার আগে লগিং অক্ষম / সক্ষম করতে চাই না: লগিং - কীভাবে আমদানি করা মডিউল লগগুলি উপেক্ষা করবেন?

উত্তর:


69

সমস্যাটি হ'ল getLoggerআর্গুমেন্ট ব্যতীত কল করা রুট লগারকে ফেরত দেয় তাই আপনি যখন স্তরটি সেট করেন তখন logging.DEBUGঅন্যান্য মডিউলগুলির জন্য যে স্তরটি সেই লগার ব্যবহার করে সেগুলিও সেট করে।

আপনি কেবল রুট লগার ব্যবহার না করে এটি সমাধান করতে পারেন । এটি করার জন্য একটি যুক্তি হিসাবে কেবল একটি নাম দিন, উদাহরণস্বরূপ আপনার মডিউলটির নাম:

logger = logging.getLogger('my_module_name')
# as before

এটি একটি নতুন লগার তৈরি করবে এবং এইভাবে এটি অন্য মডিউলগুলির জন্য অবিচ্ছিন্নভাবে লগিং স্তর পরিবর্তন করবে না।


স্পষ্টতই আপনাকে তার logger.debugপরিবর্তে ব্যবহার করতে হবে logging.debugযেহেতু পরেরটি একটি সুবিধাজনক ফাংশন যা debugরুট লগারের পদ্ধতিটিকে কল করে ।

এটি অ্যাডভান্সড লগিং টিউটোরিয়ালে উল্লেখ করা হয়েছে । কোন মডিউলটি লগ বার্তাটিকে একটি সহজ উপায়ে ট্রিগার করেছে তা এটি আপনাকে জানতে দেয়।


37
আমি আর দিয়ে লগার তৈরি করছি __name__তবে আমি এখনও আমদানি করা মডিউলগুলি থেকে লগগুলি দেখতে পাচ্ছি। আমি একটি ini কনফিগারেশন ফাইল দিয়ে লগিং কনফিগার করার চেষ্টা করছি that এর জন্য আমার কী করা উচিত?
দুর্গা স্বরূপ

8
দিয়ে লগার তৈরি করা __name__আমার পক্ষেও কার্যকর হয়নি। সম্ভবত কারণ আমি একটি স্বতন্ত্র স্ক্রিপ্ট ব্যবহার করছি এবং "মডিউল" না? আমার জন্য যা কাজ করেছিল তা হ'ল আমদানি করা মডিউলগুলির ( matpplotlibএবং আমার ক্ষেত্রে) লগিং কনফিগার করার মাধ্যমে logging.getLogger("matplotlib").setLevel(logging.WARNING)এবং আমার স্ক্রিপ্টের মাধ্যমে logging.basicConfig
bli

4
আমি কেবল আপনার লাইনের মানটি হাইলাইট করতে চেয়েছিলাম "অবশ্যই logger.debugপরিবর্তে আপনার ব্যবহার করতে হবে logging.debug"। এটি ব্যবহার করা একটি সহজ ভুল লগিং পরিবর্তে এটির কিন্তু এটি চালাক কনফিগারেশন আপনি সেট আপ করতে চান সব usurps। আমি এই বেঁচে থাকার ঘন্টা কয়েক কাটিয়েছি!
টিমদাবাদে

@ বিলি একটি এক্সিকিউটেবল বিকাশ করার সময় বনাম একটি লাইব্রেরি বিকাশ করার সময় লগিংয়ের মধ্যে একটি বড় পার্থক্য রয়েছে। মূলত: আপনি যদি মডিউল / প্যাকেজটি লিখতে থাকেন যা আমদানি করা বোঝানো হয় আপনি কোনও কিছু কনফিগার করবেন না । মডিউলটিতে কেবল logger = logging.getLogger('package.my_module')এবং আপনার করা কলগুলি থাকতে হবে logger.debug/warning, লগিং স্তর বা হ্যান্ডলারের কোনও কনফিগারেশন নেই। যখন আপনি বাইনারি অ্যাপ্লিকেশন লিখতে সেখানে আপনি বিভিন্ন লগ এবং হ্যান্ডলার অনুসন্ধান স্তর সিদ্ধান্ত নিতে হবে। লগইন কনফিগারেশন সহ গ্রন্থাগারগুলি সর্বদা একটি সমস্যা হবে।
বাকুরিউ

আমার ক্ষেত্রে, আমি যে প্যাকেজটি আমদানি করি তা রুট লগার (মাধ্যমে logging.info) ব্যবহার করে । এই প্যাকেজ থেকে রুট লগগুলি বিশেষভাবে অক্ষম করার কোনও উপায় আছে কি?
আইয়ানএস

45

আপনি যদি অজগর loggingপ্যাকেজটি ব্যবহার করতে চলেছেন , এটি প্রতিটি মডিউলে লগারকে সংজ্ঞায়িত করার জন্য একটি সাধারণ সম্মেলন convention

logger = logging.getLogger(__name__)

অনেক জনপ্রিয় পাইথন প্যাকেজগুলি এটি সহ করে requests। যদি কোনও প্যাকেজ এই কনভেনশনটি ব্যবহার করে তবে এর জন্য লগিং সক্ষম / অক্ষম করা সহজ, কারণ লগারের নাম প্যাকেজটির একই নাম হবে (বা সেই লগারের সন্তান হবে)। এমনকি আপনি অন্যান্য লগারের মতো একই ফাইলটিতে এটি লগ করতে পারেন।

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

requests_logger = logging.getLogger('requests')
requests_logger.setLevel(logging.DEBUG)

handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)
logger.addHandler(handler)
requests_logger.addHandler(handler)

15
সচেতন থাকুন, আপনি যখন logging.basicConfig(...)সমস্ত লগারের সাথে অফিসিয়াল বেসিক টিউটোরিয়ালের মতো আপনার লগারগুলি কনফিগার করার চেষ্টা করবেন তখন logging.lastResortকোনও হ্যান্ডলার দেওয়া হয়নি বা আপনি যে হ্যান্ডলারটি সেট করেছেন তা যদি হয় তবে পাইথন ৩.২ দিয়ে শুরু হবে, যা স্ট্যাডার হয়। সুতরাং এটি ব্যবহার করবেন না বা আপনি যে কোনও উপায়ে সমস্ত লগ বার্তা পাওয়া চালিয়ে যাবেন।
ব্যবহারকারী 136036

44

এটি পোস্ট করা উপযুক্ত কিনা তা নিশ্চিত না, তবে আমি দীর্ঘদিন ধরে আটকে ছিলাম এবং একই ইস্যুতে কাউকে সাহায্য করতে চেয়েছিলাম, কারণ আমি অন্য কোথাও এটি খুঁজে পাইনি!

লগিং অ্যাডভান্সড টিউটোরিয়াল এবং ট্রাবলশুটিংয়ের সুস্পষ্ট সোজা ডকুমেন্টেশন অনুসরণ করেও আমি ম্যাটপ্ল্লোব থেকে ডিবাগ লগগুলি পাচ্ছিলাম । আমি আমার লগারের main()একটি ফাইলের সূচনা করছিলাম এবং অন্য ফাইল থেকে প্লট তৈরি করার জন্য একটি ফাংশন আমদানি করছিলাম (যেখানে আমি ম্যাটপ্ল্লোটিব আমদানি করেছি)।

আমার জন্য যা কাজ করেছিল তা হ'ল ম্যাটপ্লটলিবের স্তরটি আমদানির আগে নির্ধারণ করা হয়েছিল , আমার প্রধান ফাইলে অন্য মডিউলগুলির জন্য তার চেয়ে বেশি। এটি আমার কাছে বিপরীতমুখী বলে মনে হয়েছিল তাই যদি কারও অন্তর্দৃষ্টি থাকে তবে কীভাবে আপনি কোনও লগারের জন্য কীভাবে কনফিগার সেট করতে পারেন যা আমদানি করা হয়নি এখনও আমি কীভাবে এটি কাজ করে তা জানতে আগ্রহী হব। ধন্যবাদ!

আমার মূল ফাইলে:

import logging
import requests
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logging.getLogger('requests').setLevel(logging.DEBUG)

def main():
  ...

আমার plot.pyফাইলে:

import logging
logging.getLogger('matplotlib').setLevel(logging.WARNING)
import matplotlib.pyplot as plt

def generatePlot():
  ...

আমি ত্রুটি পেয়েছি: 'লগার' অবজেক্টটির কোনও ডিবিবিজি নেই। logger.DEBUGহওয়া উচিতlogging.DEBUG
ফক্সিরিস

ধন্যবাদ! এটি সত্যিই সাহায্য করে! আমি আমার প্রধান লগিং কনফিগারেশনের পরে এবং কমান্ডের আগে ম্যাটপ্ল্লিটিব লগিং স্তর সেট করেছি যা ম্যাটপ্ল্লিটিব আমদানি করবে। সলভ!
gph

আমি মডিউলটি আমদানি matplotlibকরার WARNING পরে লগইন সেট করেছি, যেহেতু আমদানির আগে এটি যুক্ত করা একটি লিন্ট-ত্রুটি দেয়। এটি এখনও আমার জন্য কাজ করে। আমি matplotlib==3.3.2পাইথন ৩.7 এ ব্যবহার করছি যদি এটি সাহায্য করে।
শেষ-2-সমাপ্তি

9

@ বাকুরিউ খুব সুন্দরভাবে ফাংশনটি ব্যাখ্যা করেছেন। বিপরীতে, আপনি getLogger()অযাচিত লগারগুলি পুনরুদ্ধার এবং পুনরায় কনফিগার / অক্ষম করার জন্য পদ্ধতিটি ব্যবহার করতে পারেন ।

আমি logging.fileConfig()পদ্ধতিটি যুক্ত করতে চেয়েছিলাম এমন একটি প্যারামিটার গ্রহণ করে disable_existing_loggersযা পূর্বে নির্ধারিত কোনও লগার অক্ষম করে (অর্থাত, আমদানি করা মডিউলগুলিতে)


9

এটি এখনও বিদ্যমান রুট লগার ব্যবহার করার সময় (এবং কোনও বাহ্যিক ফাইল লোড না করে) আমদানি করা মডিউলগুলির দ্বারা তৈরি করা সমস্ত বিদ্যমান লগারকে অক্ষম করে।

logging.config.dictConfig({
    'version': 1,
    'disable_existing_loggers': True,
})

নোট করুন যে আপনি যে সমস্ত মডিউলগুলি প্রথমে লগইন করতে চান তা আমদানি করতে হবে! অন্যথায় এগুলিকে "বিদ্যমান লগার" হিসাবে বিবেচনা করা হবে না। এটি তখন সেই মডিউলগুলি থেকে সমস্ত লগার অক্ষম করবে। এটি আপনাকে গুরুত্বপূর্ণ ত্রুটিগুলিও মিস করতে পারে!

কনফিগারেশনের জন্য সম্পর্কিত বিকল্পগুলি ব্যবহার করে আরও বিশদ উদাহরণগুলির জন্য, https://gist.github.com/st4lk/6287746 দেখুন , এবং এখানে একটি (আংশিকভাবে কাজ করা) উদাহরণটি রয়েছে coloredlogলাইব্রেরির সাথে কনফিগার করার জন্য YAML ব্যবহার করে ।


তোমার প্রশ্নটি কি?
ব্যবহারকারী 1767754

4
এই কাজ requestউদাহরণস্বরূপ, কিন্তু এটা যখন আমদানিকৃত মডিউল তাদের শ্রেণীর ভিতরের তাদের গাছ কাটতে তৈরি তোমাকে পরে ফোন চাই, মত কাজ করবে না APSchedulerকরে আপনি কল যখন BackgroundScheduler.BackgroundScheduler()। : এখানে একটি সমাধান জন্য দেখুন stackoverflow.com/a/48891485/2441026
user136036

এটি yaml কনফিগারেশন ফাইলের সাথে আমার ক্ষেত্রে কাজ করে
user4015990

4

আপনি এর মতো কিছু ব্যবহার করতে পারেন:

logging.getLogger("imported_module").setLevel(logging.WARNING)
logging.getLogger("my_own_logger_name").setLevel(logging.DEBUG)

আমদানিকৃত মডিউলটিকে একই স্তরটি ব্যবহার করা থেকে বিরত রাখার সময় এটি আমার নিজের মডিউলটির লগ স্তর DEBUG এ সেট করবে

দ্রষ্টব্য: (উদ্ধৃতি ব্যতীত) "imported_module"দিয়ে প্রতিস্থাপন করা যেতে পারে imported_module.__name__, এবং যদি আপনি এটি করতে পছন্দ করেন তবে এটি "my_own_logger_name"প্রতিস্থাপন করা __name__যেতে পারে।


1

আমারও একই সমস্যা ছিল। আমার কাছে একটি লগিং_কনফিগ.পি ফাইল রয়েছে যা আমি অন্য সমস্ত পাই ফাইলগুলিতে আমদানি করি। লগিং_কনফিগ.পি.পি ফাইলটিতে আমি রুট লগার লগিং স্তরটি ইআরআরআর-এ সেট করেছি (ডিফল্টরূপে এর সতর্কতা)

logging.basicConfig(
    handlers=[
        RotatingFileHandler('logs.log',maxBytes=1000, backupCount=2),
        logging.StreamHandler(), #print to console
    ],
    level=logging.ERROR
)

অন্যান্য মডিউলগুলিতে আমি লগিং_কনফিগ.পি আমদানি করি এবং একটি নতুন লগার ঘোষণা করি এবং এটির স্তরটি ডিবাগ এ সেট করি:

log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)

এইভাবে আমি আমার পাই ফাইলগুলিতে লগইন করি এমন সমস্ত কিছু লগড করা হয় তবে আমদানি করা মডিউলগুলি যেমন urllib, অনুরোধ, বোটো 3 ইত্যাদি দ্বারা ডিবাগ এবং তথ্য স্তরে লগড করা স্টাফগুলি লগ হয় না। যদি সেগুলি আমদানি মডিউলে কিছু ত্রুটি থাকে তবে এর লগ হয়েছে, যেহেতু আমি রুট লগার্স স্তরটিকে ERROR এ সেট করেছি।


0

আরেকটি বিষয় বিবেচনা করা হ'ল লগার শ্রেণির প্রচারিত সম্পত্তি।

উদাহরণস্বরূপ, সাবান কলগুলি পরিচালনা করার জন্য পাই-সুড লাইব্রেরি, এমনকি এআরআরওরে রাখা

logging.getLogger('suds.client').setLevel(logging.ERROR)
logging.getLogger('suds.transport').setLevel(logging.ERROR)
logging.getLogger('suds.xsdschema').setLevel(logging.ERROR)
logging.getLogger('suds.wsdl').setLevel(logging.ERROR)

sxbasics.py নামে একটি মডিউল সম্পর্কে লগগুলি লগগুলি বিপুল পরিমাণে লগ করে

এখানে চিত্র বর্ণনা লিখুন

যেহেতু লগগুলির প্রচারটি ডিফল্টরূপে সত্য হয়, মিথ্যাতে সেট করে পরিবর্তে, আমি লগগুলির 514MB পুনরুদ্ধার করে।

import logging
logging.getLogger("suds").propagate = False
logging.getLogger('suds.client').setLevel(logging.ERROR)
logging.getLogger('suds.transport').setLevel(logging.ERROR)
logging.getLogger('suds.xsdschema').setLevel(logging.ERROR)
logging.getLogger('suds.wsdl').setLevel(logging.ERROR)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.