পাইথন লগারগুলি লগ ফাইল ছাড়াও সমস্ত বার্তাকে স্টডআউটে আউটপুট দেয়


450

সেখানে ব্যবহার পাইথন লগিং করতে একটি উপায় আছে কি loggingমডিউল স্বয়ংক্রিয়ভাবে stdout- এ আউটপুট জিনিষ ছাড়াও তারা কোথায় যেতে অনুমিত হয় লগ ফাইল কিভাবে? উদাহরণ হিসেবে বলা যায়, আমি সব কল চাই logger.warning, logger.critical, logger.errorতাদের উদ্দেশ্যে জায়গায় যেতে কিন্তু ছাড়াও সবসময় অনুলিপি করা stdout। এটি হ'ল নকল বার্তা এড়ানোর জন্য:

mylogger.critical("something failed")
print "something failed"

1
এই উত্তরটি দয়া করে চেক করুন stackoverflow.com/questions/9321741/...
SeF

উত্তর:


635

সমস্ত লগিং আউটপুট হ্যান্ডলারগুলি দ্বারা পরিচালিত হয়; logging.StreamHandler()রুট লগারে কেবল একটি যুক্ত করুন ।

এখানে স্ট্রিম হ্যান্ডলারটি কনফিগার করার একটি উদাহরণ রয়েছে ( stdoutডিফল্টের পরিবর্তে ব্যবহার করে stderr) এবং এটি রুট লগারে যুক্ত করা:

import logging
import sys

root = logging.getLogger()
root.setLevel(logging.DEBUG)

handler = logging.StreamHandler(sys.stdout)
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
root.addHandler(handler)

4
এটি ঠিক আছে তবে যদি এটি ইতিমধ্যে কোনও ফাইলে পুনঃনির্দেশিত হয় তবে কীভাবে আমি এটি যুক্ত করতে মুদ্রণ করতে পারি stdout?

54
@ ব্যবহারকারী 248237: চিত্রিত হিসাবে একটি নতুন হ্যান্ডলার যুক্ত করে । নতুন হ্যান্ডলারগুলি বিদ্যমান হ্যান্ডলারগুলি প্রতিস্থাপন করে না, তারা লগ এন্ট্রিগুলি প্রক্রিয়া করতেও পারা যায় ।
মার্টিজন পিটারস

@ মার্তিজজনপিটারগুলি কি প্রতিটি মুদ্রিত মুদ্রণ বিবৃতিতে একটি স্ট্রিং যুক্ত করার উপায় আছে?
প্রখর মোহন শ্রীবাস্তব

7
@ প্রচারমোহনশ্রীবাস্তব আমার ধারণা, আপনি কেবল এটিকে স্ট্রিংয়ের সাথে যুক্ত করতে পারেন logging.Formatter
এ.ওয়ান

3
@ হিমানশু 219: ব্যবহারের ক্ষেত্রে হ'ল আপনি একাধিক হ্যান্ডলার যোগ করা শুরু করার সাথে সাথে আপনি সাধারণত আলাদা করতে চান। কনসোল, সতর্কতা এবং কোনও ফাইল ইত্যাদিতে ডিবাগ করুন
মার্টিজন পিটার

505

স্টডআউটে লগ করার সহজ উপায়:

import logging
import sys
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)

57
এইচএম, কিন্তু এটি কোনও ফাইলে লগ নেই, তাই না? প্রশ্নটি ছিল ফাইল এবং কনসোলে লগিং কীভাবে করা যায় ।
ওয়েডেনরিন্ডে


পাইথন 3-তে কমপক্ষে, দেখে মনে হচ্ছে বাদ দেওয়া stream=sys.stdoutএখনও আমার জন্য কনসোলে লগ করার জন্য কাজ করে।
টেলর এডমিস্টন

3
@ টেলরএডমিস্টন হ্যাঁ, তবে এটি স্টাডার স্ট্রিম আফাইক। শেল থেকে আউটপুট পুনর্নির্দেশ চেষ্টা করুন।
Sorin

1
ঠিক আছে. এটি উভয়টির জবাব দেয় না: ফাইল এবং কনসোলে লগিং করা, তবে 3 লাইনে বা তার চেয়ে কম ক্ষেত্রে আমার কী প্রয়োজন তা খুঁজে পেয়ে ভাল লাগল।
স্টিভ

67

একাধিক হ্যান্ডলার ব্যবহার করে এটি সম্ভব।

import logging
import auxiliary_module

# create logger with 'spam_application'
log = logging.getLogger('spam_application')
log.setLevel(logging.DEBUG)

# create formatter and add it to the handlers
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# create file handler which logs even debug messages
fh = logging.FileHandler('spam.log')
fh.setLevel(logging.DEBUG)
fh.setFormatter(formatter)
log.addHandler(fh)

# create console handler with a higher log level
ch = logging.StreamHandler()
ch.setLevel(logging.ERROR)
ch.setFormatter(formatter)
log.addHandler(ch)

log.info('creating an instance of auxiliary_module.Auxiliary')
a = auxiliary_module.Auxiliary()
log.info('created an instance of auxiliary_module.Auxiliary')

log.info('calling auxiliary_module.Auxiliary.do_something')
a.do_something()
log.info('finished auxiliary_module.Auxiliary.do_something')

log.info('calling auxiliary_module.some_function()')
auxiliary_module.some_function()
log.info('done with auxiliary_module.some_function()')

# remember to close the handlers
for handler in log.handlers:
    handler.close()
    log.removeFilter(handler)

দয়া করে দেখুন: https://docs.python.org/2/howto/logging-cookbook.html


4
অসাধারণ উত্তর, যদিও কিছুটা অগোছালো। কীভাবে আপনি স্ট্রিম এবং ফাইলগুলির জন্য বিভিন্ন স্তর এবং ফর্ম্যাট ব্যবহার করবেন তা দেখান Love +1, তবে স্পিরিটে +2।
আনফুন বিড়াল

আমার জন্য এটি sys.stdoutপ্যারামিটারটি ছাড়া কাজ করে নিch = logging.StreamHandler()
সুস্বাদু

64

আপনি ফাইল এবং স্টডআউটের জন্য দুটি হ্যান্ডলার তৈরি করতে পারেন এবং তারপরে handlersযুক্তি সহ একটি লগার তৈরি করতে পারেন basicConfig। এটি কার্যকর হতে পারে যদি আপনার উভয় হ্যান্ডলারের জন্য একই লগ_লেভেল এবং ফর্ম্যাট আউটপুট থাকে:

import logging
import sys

file_handler = logging.FileHandler(filename='tmp.log')
stdout_handler = logging.StreamHandler(sys.stdout)
handlers = [file_handler, stdout_handler]

logging.basicConfig(
    level=logging.DEBUG, 
    format='[%(asctime)s] {%(filename)s:%(lineno)d} %(levelname)s - %(message)s',
    handlers=handlers
)

logger = logging.getLogger('LOGGER_NAME')

32

ফাইল এবং স্টার্ডার লগ ইন করার সহজ উপায়:

import logging

logging.basicConfig(filename="logfile.txt")
stderrLogger=logging.StreamHandler()
stderrLogger.setFormatter(logging.Formatter(logging.BASIC_FORMAT))
logging.getLogger().addHandler(stderrLogger)

এটি কনসোলে লগিং বার্তার আগে INFO, DEBUG এবং ERROR লেবেল প্রদর্শন করে না। এটি ফাইলটিতে সেই লেবেলগুলি প্রদর্শন করে। কনসোলে লেবেলগুলি প্রদর্শন করতে কোনও ধারণা?
JahMyst

1
ধন্যবাদ, @ জাহমাইস্ট, আমি ফর্ম্যাটারটি যুক্ত করেছি। দুর্ভাগ্যক্রমে, এটি আর এত সংক্ষিপ্ত নয়, তবে এখনও সহজতম উপায়। :-)
ওয়েডেনরিন্ডে

12

এখানে শক্তিশালী তবে দুর্বল নথিভুক্ত logging.config.dictConfigপদ্ধতির ভিত্তিতে একটি সমাধান দেওয়া হয়েছে । এতে প্রতিটি লগ বার্তা প্রেরণের পরিবর্তে stdout, এটি লগ স্তর ERRORএবং উচ্চতর stderrএবং সমস্ত কিছুতে বার্তা প্রেরণ করে stdout। যদি সিস্টেমের অন্যান্য অংশগুলি শুনতে stderrবা শুনতে পায় তবে এটি কার্যকর হতে পারে stdout

import logging
import logging.config
import sys

class _ExcludeErrorsFilter(logging.Filter):
    def filter(self, record):
        """Filters out log messages with log level ERROR (numeric value: 40) or higher."""
        return record.levelno < 40


config = {
    'version': 1,
    'filters': {
        'exclude_errors': {
            '()': _ExcludeErrorsFilter
        }
    },
    'formatters': {
        # Modify log message format here or replace with your custom formatter class
        'my_formatter': {
            'format': '(%(process)d) %(asctime)s %(name)s (line %(lineno)s) | %(levelname)s %(message)s'
        }
    },
    'handlers': {
        'console_stderr': {
            # Sends log messages with log level ERROR or higher to stderr
            'class': 'logging.StreamHandler',
            'level': 'ERROR',
            'formatter': 'my_formatter',
            'stream': sys.stderr
        },
        'console_stdout': {
            # Sends log messages with log level lower than ERROR to stdout
            'class': 'logging.StreamHandler',
            'level': 'DEBUG',
            'formatter': 'my_formatter',
            'filters': ['exclude_errors'],
            'stream': sys.stdout
        },
        'file': {
            # Sends all log messages to a file
            'class': 'logging.FileHandler',
            'level': 'DEBUG',
            'formatter': 'my_formatter',
            'filename': 'my.log',
            'encoding': 'utf8'
        }
    },
    'root': {
        # In general, this should be kept at 'NOTSET'.
        # Otherwise it would interfere with the log levels set for each handler.
        'level': 'NOTSET',
        'handlers': ['console_stderr', 'console_stdout', 'file']
    },
}

logging.config.dictConfig(config)

রুট লগারটি পেতে আসলে একটি খালি স্ট্রিংতে লগারের নামকরণ করতে হয়েছিল। অন্যথায় খুব সহায়ক, ধন্যবাদ!
নিউটোপিয়ান

8

যেহেতু কেউ ঝরঝরে দুটি লাইন ভাগ করে নি, তাই আমি নিজের ভাগ করে নেব:

logging.basicConfig(filename='logs.log', level=logging.DEBUG, format="%(asctime)s:%(levelname)s: %(message)s")
logging.getLogger().addHandler(logging.StreamHandler())

2

এখানে একটি অত্যন্ত সাধারণ উদাহরণ:

import logging
l = logging.getLogger("test")

# Add a file logger
f = logging.FileHandler("test.log")
l.addHandler(f)

# Add a stream logger
s = logging.StreamHandler()
l.addHandler(s)

# Send a test message to both -- critical will always log
l.critical("test msg")

স্ট্যান্ডআউট এবং ফাইলটিতে আউটপুট "পরীক্ষার চিত্র" প্রদর্শন করবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.