আমি পাইথন লগিং আউটপুটটিকে কীভাবে রঙ করতে পারি?


352

কিছু সময় আগে, আমি রঙিন আউটপুট সহ একটি মনো অ্যাপ্লিকেশনটি দেখেছি সম্ভবত এটির লগ সিস্টেমের কারণে (কারণ সমস্ত বার্তা মানকযুক্ত ছিল)।

এখন, পাইথনের loggingমডিউল রয়েছে যা আপনাকে আউটপুট কাস্টমাইজ করার জন্য প্রচুর বিকল্প নির্দিষ্ট করতে দেয়। সুতরাং, আমি কল্পনা করছি যে পাইথনের সাথেও তেমন কিছু সম্ভব হবে তবে কোথাও এটি কীভাবে করা যায় তা আমি খুঁজে পাচ্ছি না।

পাইথন loggingমডিউল আউটপুটটিকে রঙিন করার কোনও উপায় আছে কি ?

আমি যা চাই (উদাহরণস্বরূপ) লাল ত্রুটিগুলি, নীল বা হলুদে ডিবাগ বার্তাগুলি, এবং এগুলি on

অবশ্যই এটির জন্য সম্ভবত একটি সামঞ্জস্যপূর্ণ টার্মিনাল প্রয়োজন (বেশিরভাগ আধুনিক টার্মিনালগুলি হ'ল); তবে loggingরঙটি সমর্থিত না হলে আমি আসল আউটপুটে ফ্যালব্যাক করতে পারি ।

লগিং মডিউলটি দিয়ে আমি কীভাবে রঙিন আউটপুট পেতে পারি কোনও ধারণা?


1
আপনাকে উল্লেখ করতে হবে যে আপনি একটি মাল্টিপ্লাটফর্ম সমাধান চান - লিনাক্স এবং উইন্ডোজ উভয়ই।
সোরিন

1
সম্পর্কিত যদি আপনি Eclipse / PyDev ব্যবহার করেন: গ্রহন কনসোলে লগগুলি রঙ করুন
টোবিয়াস কেইনজলার

5
সম্ভবত আপনি
রঙিন

5
আপনি ক্রোমলগও চেষ্টা করতে পারেন যা আমি সমস্ত অপারেটিং সিস্টেম এবং পাইথন সংস্করণ (2.7 এবং 3. *) সমর্থন করতে লিখেছিলাম

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

উত্তর:


192

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

BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)

#The background is set with 40 plus the number of the color, and the foreground with 30

#These are the sequences need to get colored ouput
RESET_SEQ = "\033[0m"
COLOR_SEQ = "\033[1;%dm"
BOLD_SEQ = "\033[1m"

def formatter_message(message, use_color = True):
    if use_color:
        message = message.replace("$RESET", RESET_SEQ).replace("$BOLD", BOLD_SEQ)
    else:
        message = message.replace("$RESET", "").replace("$BOLD", "")
    return message

COLORS = {
    'WARNING': YELLOW,
    'INFO': WHITE,
    'DEBUG': BLUE,
    'CRITICAL': YELLOW,
    'ERROR': RED
}

class ColoredFormatter(logging.Formatter):
    def __init__(self, msg, use_color = True):
        logging.Formatter.__init__(self, msg)
        self.use_color = use_color

    def format(self, record):
        levelname = record.levelname
        if self.use_color and levelname in COLORS:
            levelname_color = COLOR_SEQ % (30 + COLORS[levelname]) + levelname + RESET_SEQ
            record.levelname = levelname_color
        return logging.Formatter.format(self, record)

এবং এটি ব্যবহার করতে, আপনার নিজস্ব লগার তৈরি করুন:

# Custom logger class with multiple destinations
class ColoredLogger(logging.Logger):
    FORMAT = "[$BOLD%(name)-20s$RESET][%(levelname)-18s]  %(message)s ($BOLD%(filename)s$RESET:%(lineno)d)"
    COLOR_FORMAT = formatter_message(FORMAT, True)
    def __init__(self, name):
        logging.Logger.__init__(self, name, logging.DEBUG)                

        color_formatter = ColoredFormatter(self.COLOR_FORMAT)

        console = logging.StreamHandler()
        console.setFormatter(color_formatter)

        self.addHandler(console)
        return


logging.setLoggerClass(ColoredLogger)

অন্য কারও প্রয়োজনে সেক্ষেত্রে।

আপনি যদি একাধিক লগার বা হ্যান্ডলার ব্যবহার করেন তবে সাবধান হন: ColoredFormatterরেকর্ড অবজেক্টটি পরিবর্তন করছে, যা অন্য হ্যান্ডলারের কাছে প্রেরণ করা হয় বা অন্য লগারে প্রচার করা হয়। আপনি যদি ফাইল লগার ইত্যাদি কনফিগার করেছেন তবে সম্ভবত লগ ফাইলগুলিতে রঙ থাকতে চান না। যে এড়ানোর জন্য, এটি সম্ভবত শ্রেষ্ঠ কেবল একটি অনুলিপি তৈরি করার recordসঙ্গে copy.copy()levelname অ্যাট্রিবিউট সাধিত আগে, অথবা পূর্ববর্তী মান levelname পুনরায় সেট করতে, (কৃতিত্ব বিন্যস্ত স্ট্রিং ফেরার আগে মাইকেল মন্তব্য)।


ইয়েলো, হোয়াইট, ব্লু ইত্যাদির সংজ্ঞা কোথায় দেওয়া হয়েছে?
স্বরূপ সিএইচ

1
@Swaroop - ঐ ANSI পালাবার কোড, যা আপনি Google এ সন্ধান পড়তে পারেন অথবা এখানে খুঁজে আছেন: en.wikipedia.org/wiki/ANSI_escape_code , বা অন্যভাবে pueblo.sourceforge.net/doc/manual/ansi_color_codes.html
ব্রায়ান এম । হান্ট

53
আমি বিশ্বাস করি না যে আপনার কেবল এই জন্য একটি লগার সাবক্লাস তৈরি করা উচিত - আপনার উত্তরটি একটি বিশেষীকরণ তৈরি করা Formatterএবং এটির উপর এর ব্যবহার নির্দিষ্টকরণের ক্ষেত্রে যথাযথ StreamHandler। তবে লগার সাবক্লাসের প্রয়োজন নেই। প্রকৃতপক্ষে লগার শ্রেণির ব্যবহার তৈরি প্রতিটি লগারে একটি হ্যান্ডলার যুক্ত করে, যা আপনি সাধারণত চান না।
বিনয় সাজিপ


6
একদিকে নোট ColoredFormatter। এটি রেকর্ড অবজেক্টটি পরিবর্তন করছে, যা অন্য হ্যান্ডলারের কাছে আরও প্রেরণ করা হয় বা অন্য লগারে প্রচার করা হয়। আপনি যদি ফাইল লগার ইত্যাদি কনফিগার করেছেন তবে সম্ভবত লগ ফাইলগুলিতে রঙ থাকতে চান না। এটি এড়ানোর জন্য, সম্ভবত লেভেলনামের বৈশিষ্ট্যটি হেরফের recordকরার copy.copy()আগে একটি অনুলিপি তৈরি করা, বা বিন্যাসিত স্ট্রিংটি ফেরার আগে স্তরের নামটি পূর্বের মানটিতে পুনরায় সেট করতে, এটি সম্ভবত সেরা ।
মাইকেল

148

কয়েক বছর আগে আমি নিজের ব্যবহারের জন্য একটি রঙিন স্ট্রিম হ্যান্ডলার লিখেছিলাম। তারপরে আমি এই পৃষ্ঠাটি জুড়ে এসে কোড স্নিপেটের একটি সংগ্রহ পেয়েছি যা লোকেরা অনুলিপি / পেস্ট করছে :-( আমার স্ট্রিম হ্যান্ডলারটি বর্তমানে কেবল ইউনিক্স (লিনাক্স, ম্যাক ওএস এক্স) এ কাজ করে তবে সুবিধাটি হ'ল এটি পিপিআইতে উপলব্ধ রয়েছে (এবং গিটহাব) ) এবং এটি ব্যবহার করা সহজ মৃত It এটিতে একটি ভিম সিনট্যাক্স মোডও রয়েছে :-)। ভবিষ্যতে আমি এটি উইন্ডোজে কাজ করার জন্য বাড়িয়ে দিতে পারি।

প্যাকেজটি ইনস্টল করতে:

$ pip install coloredlogs

এটি কাজ করে তা নিশ্চিত করার জন্য:

$ coloredlogs --demo

আপনার নিজস্ব কোড দিয়ে শুরু করতে:

$ python
> import coloredlogs, logging
> coloredlogs.install()
> logging.info("It works!")
2014-07-30 21:21:26 peter-macbook root[7471] INFO It works!

উপরের উদাহরণে প্রদর্শিত ডিফল্ট লগ ফর্ম্যাটটিতে তারিখ, সময়, হোস্টনাম, লগারের নাম, পিআইডি, লগ স্তর এবং লগ বার্তা রয়েছে। এটি বাস্তবে এটির মতো দেখাচ্ছে:

রঙিনব্লগ আউটপুট এর স্ক্রিনশট

দ্রষ্টব্য: গিট ব্যাশ ডাব্লু / মিনিটওয়াই ব্যবহার করার সময়

উইন্ডোতে গিট ব্যাশের কিছু ডকুমেন্টেড কুইর্ক রয়েছে : উইনপ্টি এবং গিট বাশ

এএনএসআই এস্কেপ কোডগুলির জন্য এবং ncurses স্টাইলের অক্ষর রাইটিং এবং অ্যানিমেশনগুলির জন্য, আপনাকে কমান্ডগুলির সাথে প্রিফিক্স করতে হবে winpty

$ winpty coloredlogs --demo
$ winpty python your_colored_logs_script.py

2
যথেষ্ট মজার, আমি এই থ্রেডে কেবল " pypi.python.org/pypi/coloredlogs/0.4.7 " এ একটি লিঙ্ক যুক্ত করতে যাচ্ছি !
আইওসু এস

1
কোনও কারণে AttributeError: 'module' object has no attribute 'install'ব্যবহারের সময় আমি পেতে থাকি coloredlogs.install()। আপনি কি এটি সর্বশেষতম সংস্করণ সহ নিশ্চিত করতে পারেন?
কনফ-এ-ব্যবহার

11
এটি দেখতে সুন্দর লাগছে। দুর্ভাগ্যক্রমে, এটি অনেক কিছুই ভেঙে দেয়; বিশেষত, এটি লগিং.বেসিক কনফিগকে কল দেয়। উদাহরণস্বরূপ এটি কাস্টম ফর্ম্যাটর ব্যবহার করা অসম্ভব করে তোলে।
ক্লাইমেন্ট

@ ক্লিমেট: দুটি (ওভারল্যাপিং?) প্রশ্ন: (1) "ভয়েডস লগিং.বেসিক কনফাইগ" এর মাধ্যমে আপনি কী বলতে চাচ্ছেন এবং (২) বিকল্পটি কী হবে? উভয় logging.basicConfig()এবং coloredlogs.install()একটি স্ট্রিম হ্যান্ডলার রয়েছে যা কনসোলে লগ, তাই ছাড়া "voiding" আপনি সদৃশ বার্তাগুলি পাবে ইনস্টল করুন ...
xolox

আমি (1), বা (আরও যুক্তিসঙ্গত) প্যাকেজের coloredlogs.installমতো কোন ফর্ম্যাটটি ব্যবহার করব তা বলার উপায়ের জন্য যাদুটি প্রত্যাশা করেছি colorlog
ক্লাইমেন্ট

74

এখানে একটি সমাধান যা কোনও প্ল্যাটফর্মে কাজ করা উচিত। যদি এটি কেবল আমাকে না বলে এবং আমি এটি আপডেট করব।

এটি কীভাবে কাজ করে: এএনএসআই পলায়নের সমর্থনে প্ল্যাটফর্মে তাদের (নন-উইন্ডোজ) ব্যবহার করা হয় এবং উইন্ডোজটিতে এটি কনসোলের রং পরিবর্তন করতে API কলগুলি ব্যবহার করে।

স্ক্রিপ্টটি লগিংকে হ্যাক করে standard স্ট্রিমহ্যান্ডলিআরমিটি পদ্ধতিটিকে স্ট্যান্ডার্ড লাইব্রেরি থেকে এতে একটি মোড়ক যুক্ত করে।

TestColorer.py

# Usage: add Colorer.py near you script and import it.
import logging
import Colorer

logging.warn("a warning")
logging.error("some error")
logging.info("some info")

Colorer.py

#!/usr/bin/env python
# encoding: utf-8
import logging
# now we patch Python code to add color support to logging.StreamHandler
def add_coloring_to_emit_windows(fn):
        # add methods we need to the class
    def _out_handle(self):
        import ctypes
        return ctypes.windll.kernel32.GetStdHandle(self.STD_OUTPUT_HANDLE)
    out_handle = property(_out_handle)

    def _set_color(self, code):
        import ctypes
        # Constants from the Windows API
        self.STD_OUTPUT_HANDLE = -11
        hdl = ctypes.windll.kernel32.GetStdHandle(self.STD_OUTPUT_HANDLE)
        ctypes.windll.kernel32.SetConsoleTextAttribute(hdl, code)

    setattr(logging.StreamHandler, '_set_color', _set_color)

    def new(*args):
        FOREGROUND_BLUE      = 0x0001 # text color contains blue.
        FOREGROUND_GREEN     = 0x0002 # text color contains green.
        FOREGROUND_RED       = 0x0004 # text color contains red.
        FOREGROUND_INTENSITY = 0x0008 # text color is intensified.
        FOREGROUND_WHITE     = FOREGROUND_BLUE|FOREGROUND_GREEN |FOREGROUND_RED
       # winbase.h
        STD_INPUT_HANDLE = -10
        STD_OUTPUT_HANDLE = -11
        STD_ERROR_HANDLE = -12

        # wincon.h
        FOREGROUND_BLACK     = 0x0000
        FOREGROUND_BLUE      = 0x0001
        FOREGROUND_GREEN     = 0x0002
        FOREGROUND_CYAN      = 0x0003
        FOREGROUND_RED       = 0x0004
        FOREGROUND_MAGENTA   = 0x0005
        FOREGROUND_YELLOW    = 0x0006
        FOREGROUND_GREY      = 0x0007
        FOREGROUND_INTENSITY = 0x0008 # foreground color is intensified.

        BACKGROUND_BLACK     = 0x0000
        BACKGROUND_BLUE      = 0x0010
        BACKGROUND_GREEN     = 0x0020
        BACKGROUND_CYAN      = 0x0030
        BACKGROUND_RED       = 0x0040
        BACKGROUND_MAGENTA   = 0x0050
        BACKGROUND_YELLOW    = 0x0060
        BACKGROUND_GREY      = 0x0070
        BACKGROUND_INTENSITY = 0x0080 # background color is intensified.     

        levelno = args[1].levelno
        if(levelno>=50):
            color = BACKGROUND_YELLOW | FOREGROUND_RED | FOREGROUND_INTENSITY | BACKGROUND_INTENSITY 
        elif(levelno>=40):
            color = FOREGROUND_RED | FOREGROUND_INTENSITY
        elif(levelno>=30):
            color = FOREGROUND_YELLOW | FOREGROUND_INTENSITY
        elif(levelno>=20):
            color = FOREGROUND_GREEN
        elif(levelno>=10):
            color = FOREGROUND_MAGENTA
        else:
            color =  FOREGROUND_WHITE
        args[0]._set_color(color)

        ret = fn(*args)
        args[0]._set_color( FOREGROUND_WHITE )
        #print "after"
        return ret
    return new

def add_coloring_to_emit_ansi(fn):
    # add methods we need to the class
    def new(*args):
        levelno = args[1].levelno
        if(levelno>=50):
            color = '\x1b[31m' # red
        elif(levelno>=40):
            color = '\x1b[31m' # red
        elif(levelno>=30):
            color = '\x1b[33m' # yellow
        elif(levelno>=20):
            color = '\x1b[32m' # green 
        elif(levelno>=10):
            color = '\x1b[35m' # pink
        else:
            color = '\x1b[0m' # normal
        args[1].msg = color + args[1].msg +  '\x1b[0m'  # normal
        #print "after"
        return fn(*args)
    return new

import platform
if platform.system()=='Windows':
    # Windows does not support ANSI escapes and we are using API calls to set the console color
    logging.StreamHandler.emit = add_coloring_to_emit_windows(logging.StreamHandler.emit)
else:
    # all non-Windows platforms are supporting ANSI escapes so we use them
    logging.StreamHandler.emit = add_coloring_to_emit_ansi(logging.StreamHandler.emit)
    #log = logging.getLogger()
    #log.addFilter(log_filter())
    #//hdlr = logging.StreamHandler()
    #//hdlr.setFormatter(formatter())

3
আমি এর ভিত্তিতে একটি স্ট্রিমহ্যান্ডলার ক্লাস লিখেছি, gist.github.com/mooware/a1ed40987b6cc9ab9c65 দেখুন
mooware

2
এই আমার জন্য কাজ! লাইন 90: হওয়া উচিত args[1].msg = color + str(args[1].msg) + '\x1b[0m' # normal
রসিকা পেরেরা

আমি এই সমাধানটি পছন্দ করি। বর্তমানে এটি ব্যবহার করে। আমি দেখতে পেয়েছি সেখানে একটি বৈশিষ্ট্য _set_color আছে, কোনও নির্দিষ্ট লগ বার্তার জন্য এটি করার কোনও উপায় আছে? সম্পাদনা করুন , ওহ দেখুন এটি উইন্ডোজ মেশিনগুলির জন্য কেবল একটি প্যাচ। বিভিন্ন ব্যবহারের ক্ষেত্রে কাস্টম যুক্ত করতে ভাল লাগবে।
ব্রিজ

এএনএসআই রঙের জন্য +1। এক্সটারেমে আপনি একসাথে 256 টি রঙও পেতে পারেন এবং আপনি প্যালেটটি গতিশীলভাবে সংজ্ঞায়িত করতে পারেন! নোট, তবে, লগিং ফাংশনগুলিতে সমস্ত কল একটি ফাংশন সংজ্ঞার বাইরে লগ ইন করার সময় সম্ভাব্য আমদানি লক সমস্যা এড়াতে কোনও ফাংশন সংজ্ঞায়নের মধ্যে থাকা উচিত । আপনার কোডটি বেশিরভাগই ভাল দেখাচ্ছে; TestColorer.pyআমাকে উদ্বিগ্ন করার সামান্য কিছুটা ।
ব্যক্তিগত_ক্লাউড

প্রকৃত লগ ফাইলগুলিতে লগ বার্তাগুলির শুরু এবং শেষে রঙিন কোডের ফলাফল।
মেহমেডবি

74

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

কালারলগ এটির জন্য দুর্দান্ত। এটি পিপিআইতে উপলব্ধ (এবং এর মাধ্যমে এটি ইনস্টলযোগ্য pip install colorlog) এবং সক্রিয়ভাবে রক্ষণাবেক্ষণ করা হয়

লগিং সেট আপ এবং শালীন-সন্ধান লগ বার্তা মুদ্রণের জন্য এখানে একটি দ্রুত অনুলিপি-এবং-পেষ্টযোগ্য স্নিপেট রয়েছে:

import logging
LOG_LEVEL = logging.DEBUG
LOGFORMAT = "  %(log_color)s%(levelname)-8s%(reset)s | %(log_color)s%(message)s%(reset)s"
from colorlog import ColoredFormatter
logging.root.setLevel(LOG_LEVEL)
formatter = ColoredFormatter(LOGFORMAT)
stream = logging.StreamHandler()
stream.setLevel(LOG_LEVEL)
stream.setFormatter(formatter)
log = logging.getLogger('pythonConfig')
log.setLevel(LOG_LEVEL)
log.addHandler(stream)

log.debug("A quirky message only developers care about")
log.info("Curious users might want to know this")
log.warn("Something is wrong and any user should be informed")
log.error("Serious stuff, this is red for a reason")
log.critical("OH NO everything is on fire")

আউটপুট:

কালারলগ আউটপুট


4
দুর্দান্ত উত্তর; +1 টি। কোড উদাহরণটি ছাঁটাই করা যেতে পারে (তিনটি কল setLevelকি সত্যই প্রয়োজন?)
ক্লাইমেন্ট

1
আমি আশা করছিলাম যে আমি যদি উত্তরগুলি দীর্ঘায়িত করতে পারি তবে আমি এই জাতীয় একটি উত্তর খুঁজে পাই। ☺ আমি আশা করি @ মাইরমাইন্ড এটি স্বীকৃত উত্তর তৈরির বিষয়ে বিবেচনা করবে, তাই ভবিষ্যতের শ্রম-স্মার্ট লোকেরা সর্বোত্তম অলসতার সাথে সেরা গ্রন্থাগার বলে মনে করতে পারে। 😉
মাইকেল শ্যাপার

আমি কেবল এই আউটপুট the
আগস্টিন ব্যারাচিনা

69

পূর্বনির্ধারিত লগ স্তরের জন্য এবং কোনও নতুন শ্রেণীর সংজ্ঞা ছাড়াই দ্রুত এবং নোংরা সমাধান।

logging.addLevelName( logging.WARNING, "\033[1;31m%s\033[1;0m" % logging.getLevelName(logging.WARNING))
logging.addLevelName( logging.ERROR, "\033[1;41m%s\033[1;0m" % logging.getLevelName(logging.ERROR))

@ স্পাইডারপ্ল্যান্ট0 আমদানি লগিং; # এএবসি থেকে কোডটি পেস্ট করুন; লগিং.ওয়ার্নিং দিয়ে চেষ্টা করুন ('এটি একটি পরীক্ষা')। আপনি "সতর্কতা: এটি একটি পরীক্ষা" রঙ্গিন রঙের বড় অংশ দেখতে পাবেন। এটি কেবল বিটিডব্লুতে লিনাক্সে কাজ করে
রিকার্ডো গালি

3
যেহেতু শুধুমাত্র লগলেভেলের নাম রঙিন তাই আপনাকে অবশ্যই নিশ্চিত করতে হবে যে লগলিভেলের নামটি আদৌ কনসোল করার জন্য মুদ্রিত হয়েছে। এটি আমার জন্য বাক্সের বাইরে ঘটে না। এই লাইন বরাবর কিছু সাহায্য করবে: logging.basicConfig(format='%(asctime)s [%(name)s] [%(levelname)s] %(message)s')অবশ্যই %(levelnames)sগুরুত্বপূর্ণ যেখানে ।
সেবাস্তিয়ান

4
প্রয়োগ এবং বুঝতে সর্বাধিক সহজ এবং পরিষ্কার সমাধান।
এফ। সান্টিয়াগো

1
লিনাক্স কনসোলে চেষ্টা করুন। echo -e "Normal texst \033[1;31mred bold text\033[0m normal text again"। প্রতিস্থাপন -eবিকল্পটি "\ 033" কে এস্কেপ এএসসিআইআই চিহ্নের অষ্টাল রূপ হিসাবে ব্যাখ্যা করে। এই বিশেষ চিহ্নটি কিছু সামঞ্জস্যপূর্ণ টার্মিনালকে পরবর্তী ক্যারেক্টারগুলিকে ( mবিশেষত অন্তর্ভুক্ত করতে) বিশেষ কমান্ড হিসাবে ব্যাখ্যা করে। en.wikedia.org/wiki/ANSI_escape_code
ইউজিন-উজ্জ্বল

1
গৌণ উন্নতি: এই কোডটি ভিতরে রাখুন if sys.sdterr.isatty():। এই ক্ষেত্রে যদি আপনি আউটপুট ফাইলে পুনর্নির্দেশ করেন তবে ফাইলটিতে এই পালানো অক্ষর থাকবে না।
লেসনিক

35

2020 কোড, অতিরিক্ত প্যাকেজগুলির প্রয়োজন নেই, পাইথন 3

একটি ক্লাস সংজ্ঞায়িত করুন

import logging

class CustomFormatter(logging.Formatter):
    """Logging Formatter to add colors and count warning / errors"""

    grey = "\x1b[38;21m"
    yellow = "\x1b[33;21m"
    red = "\x1b[31;21m"
    bold_red = "\x1b[31;1m"
    reset = "\x1b[0m"
    format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)"

    FORMATS = {
        logging.DEBUG: grey + format + reset,
        logging.INFO: grey + format + reset,
        logging.WARNING: yellow + format + reset,
        logging.ERROR: red + format + reset,
        logging.CRITICAL: bold_red + format + reset
    }

    def format(self, record):
        log_fmt = self.FORMATS.get(record.levelno)
        formatter = logging.Formatter(log_fmt)
        return formatter.format(record)

লগার ইনস্ট্যান্ট করুন

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

# create console handler with a higher log level
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)

ch.setFormatter(CustomFormatter())

logger.addHandler(ch)

আর ব্যবহার করুন!

logger.debug("debug message")
logger.info("info message")
logger.warning("warning message")
logger.error("error message")
logger.critical("critical message")

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

পুরো রঙের স্কিম এখানে চিত্র বর্ণনা লিখুন

উইন্ডোজ জন্য

এই সমাধানটি ম্যাক ওএস, আইডিই টার্মিনালগুলিতে কাজ করে। দেখে মনে হচ্ছে উইন্ডোর কমান্ড প্রম্পটে ডিফল্টরকম রঙ নেই। সেগুলি কীভাবে সক্ষম করবেন সে সম্পর্কে এখানে নির্দেশাবলী দেওয়া হয়েছে, যা আমি চেষ্টা করি নি https://www.howtogeek.com/322432/how-to-customize-your-command-prompts-color-scheme-with-microsofts-colortool/ ব্যবহার করে নি


1
আমি পরীক্ষাটি চালাই (অজগর 3.7, উইন্ডোজ), তবে লগিং রং দেখায় না:←[38;21m2019-11-12 19:29:50,994 - My_app - DEBUG - debug message (test_colored_log.py:43)←[0m ←[38;21m2019-11-12 19:29:50,994 - My_app - INFO - info message (test_colored_log.py:44)←[0m ←[33;21m2019-11-12 19:29:50,994 - My_app - WARNING - warning message (test_colored_log.py:45)←[0m ←[31;21m2019-11-12 19:29:50,994 - My_app - ERROR - error message (test_colored_log.py:46)←[0m ←[31;1m2019-11-12 19:29:50,994 - My_app - CRITICAL - critical message (test_colored_log.py:47)←[0m
কনস্ট্রাক্টর

দুর্ভাগ্যক্রমে এটি কাজ করে না।
জো

2
আমি এই উত্তরটি এত পছন্দ করেছি যে আমি কয়েকটি ইনক্রিমেন্ট এবং আনসির রঙের একটি চিট শীট সহ এর জন্য একটি রেপো তৈরি করেছি ।
তেওডোরো

@ কনস্ট্রাক্টর আপনি এটি কোথায় চালাচ্ছেন? আইডিই কনসোল? উইন্ডোজ টার্মিনাল?
সের্গে প্লেশাকভ

@ জো ঠিক কি কাজ করে না? আপনার পরিবেশ কি এবং আপনি কি ত্রুটি পেতে? প্ল্যাটফর্মগুলিতে এটি কাজ করার জন্য আমি সমাধানটি সংশোধন করতে চাই
সের্গেই প্ল্যাশাকভ

17

ভাল, আমার ধারণা আমি রঙিন লগারের সাথে আমার প্রকরণটিও যুক্ত করতে পারি।

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

আপনি যদি ইতিমধ্যে লগিং মডিউলটির ফর্ম্যাটর ব্যবহার করে থাকেন তবে রঙিন স্তরের নাম পেতে আপনাকে যা করতে হবে তা হ'ল আপনার পরামর্শ হ্যান্ডলারের ফর্ম্যাটারটি রঙিন ফোর্মেটারের সাথে প্রতিস্থাপন করা। আপনি যদি একটি সম্পূর্ণ অ্যাপ্লিকেশন লগইন করেন তবে কেবলমাত্র শীর্ষ স্তরের লগারের জন্য আপনাকে এটি করতে হবে।

colored_log.py

#!/usr/bin/env python

from copy import copy
from logging import Formatter

MAPPING = {
    'DEBUG'   : 37, # white
    'INFO'    : 36, # cyan
    'WARNING' : 33, # yellow
    'ERROR'   : 31, # red
    'CRITICAL': 41, # white on red bg
}

PREFIX = '\033['
SUFFIX = '\033[0m'

class ColoredFormatter(Formatter):

    def __init__(self, patern):
        Formatter.__init__(self, patern)

    def format(self, record):
        colored_record = copy(record)
        levelname = colored_record.levelname
        seq = MAPPING.get(levelname, 37) # default white
        colored_levelname = ('{0}{1}m{2}{3}') \
            .format(PREFIX, seq, levelname, SUFFIX)
        colored_record.levelname = colored_levelname
        return Formatter.format(self, colored_record)

ব্যবহারের উদাহরণ

app.py

#!/usr/bin/env python

import logging
from colored_log import ColoredFormatter

# Create top level logger
log = logging.getLogger("main")

# Add console handler using our custom ColoredFormatter
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
cf = ColoredFormatter("[%(name)s][%(levelname)s]  %(message)s (%(filename)s:%(lineno)d)")
ch.setFormatter(cf)
log.addHandler(ch)

# Add file handler
fh = logging.FileHandler('app.log')
fh.setLevel(logging.DEBUG)
ff = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(ff)
log.addHandler(fh)

# Set log level
log.setLevel(logging.DEBUG)

# Log some stuff
log.debug("app has started")
log.info("Logging to 'app.log' in the script dir")
log.warning("This is my last warning, take heed")
log.error("This is an error")
log.critical("He's dead, Jim")

# Import a sub-module 
import sub_module

sub_module.py

#!/usr/bin/env python

import logging
log = logging.getLogger('main.sub_module')

log.debug("Hello from the sub module")

ফলাফল

টার্মিনাল আউটপুট

টার্মিনাল আউটপুট

app.log সামগ্রী

2017-09-29 00:32:23,434 - main - DEBUG - app has started
2017-09-29 00:32:23,434 - main - INFO - Logging to 'app.log' in the script dir
2017-09-29 00:32:23,435 - main - WARNING - This is my last warning, take heed
2017-09-29 00:32:23,435 - main - ERROR - This is an error
2017-09-29 00:32:23,435 - main - CRITICAL - He's dead, Jim
2017-09-29 00:32:23,435 - main.sub_module - DEBUG - Hello from the sub module

টার্মিনাল এবং লগ ফাইল আউটপুটগুলির বিন্যাসকরণের সাথে আপনি যেমন চান তেমন অভিনবতা পেতে পারেন। কেবল লগ স্তর রঙ করা হবে।

আমি আশা করি যে কেউ এই দরকারী দরকারী এবং এটি খুব বেশি একই না। :)

পাইথন উদাহরণ ফাইলগুলি এই গিটহাব গিস্ট থেকে ডাউনলোড করা যাবে: https://gist.github.com/KurtJacobson/48e750701acec40c7161b5a2f79e6bfd


2
বিটিডাব্লু নিজেই বার্তায় রঙ যুক্ত করার আগে এই লাইনটি যুক্ত করুন return:colored_record.msg = ('{0}{1}m{2}{3}').format(self.PREFIX, seq, colored_record.getMessage(), self.SUFFIX)
দ্য গডফাদার

15

আমি অগ্রভাগ এবং পটভূমির জন্য এয়ারমাইন্ড সমর্থনকারী ট্যাগ থেকে উদাহরণ আপডেট করেছি। আপনার লগ ফর্ম্যাটারের স্ট্রিংয়ে কেবল রঙের ভেরিয়েবলগুলি LA কালো - $ সাদা ব্যবহার করুন। ব্যাকগ্রাউন্ড সেট করতে কেবল $ বিজি-ব্ল্যাক - G বিজি-হোয়াইট ব্যবহার করুন।

import logging

BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)

COLORS = {
    'WARNING'  : YELLOW,
    'INFO'     : WHITE,
    'DEBUG'    : BLUE,
    'CRITICAL' : YELLOW,
    'ERROR'    : RED,
    'RED'      : RED,
    'GREEN'    : GREEN,
    'YELLOW'   : YELLOW,
    'BLUE'     : BLUE,
    'MAGENTA'  : MAGENTA,
    'CYAN'     : CYAN,
    'WHITE'    : WHITE,
}

RESET_SEQ = "\033[0m"
COLOR_SEQ = "\033[1;%dm"
BOLD_SEQ  = "\033[1m"

class ColorFormatter(logging.Formatter):

    def __init__(self, *args, **kwargs):
        # can't do super(...) here because Formatter is an old school class
        logging.Formatter.__init__(self, *args, **kwargs)

    def format(self, record):
        levelname = record.levelname
        color     = COLOR_SEQ % (30 + COLORS[levelname])
        message   = logging.Formatter.format(self, record)
        message   = message.replace("$RESET", RESET_SEQ)\
                           .replace("$BOLD",  BOLD_SEQ)\
                           .replace("$COLOR", color)
        for k,v in COLORS.items():
            message = message.replace("$" + k,    COLOR_SEQ % (v+30))\
                             .replace("$BG" + k,  COLOR_SEQ % (v+40))\
                             .replace("$BG-" + k, COLOR_SEQ % (v+40))
        return message + RESET_SEQ

logging.ColorFormatter = ColorFormatter

সুতরাং এখন আপনি আপনার কনফিগার ফাইলে নিম্নলিখিতটি সহজ করতে পারেন:

[formatter_colorFormatter]
class=logging.ColorFormatter
format= $COLOR%(levelname)s $RESET %(asctime)s $BOLD$COLOR%(name)s$RESET %(message)s

মহান উন্নতি. তবে কেবলমাত্র মন্তব্যটি superআমার অনুমান কিছু প্রাচীন পাইথন সংস্করণের জন্য প্রযোজ্য? যেহেতু এই উত্তর 2010 থেকে এটা পাইথন 2.7 সঙ্গে আমার জন্য জরিমানা কাজ
Joakim

14

আপনি রঙিন মডিউলটি আমদানি করতে পারেন এবং ColoredFormatterলগ বার্তাগুলি রঙিন করার জন্য এটি ব্যবহার করতে পারেন ।

উদাহরণ

প্রধান মডিউল জন্য বয়লারপ্লেট:

import logging
import os
import sys
try:
    import colorlog
except ImportError:
    pass

def setup_logging():
    root = logging.getLogger()
    root.setLevel(logging.DEBUG)
    format      = '%(asctime)s - %(levelname)-8s - %(message)s'
    date_format = '%Y-%m-%d %H:%M:%S'
    if 'colorlog' in sys.modules and os.isatty(2):
        cformat = '%(log_color)s' + format
        f = colorlog.ColoredFormatter(cformat, date_format,
              log_colors = { 'DEBUG'   : 'reset',       'INFO' : 'reset',
                             'WARNING' : 'bold_yellow', 'ERROR': 'bold_red',
                             'CRITICAL': 'bold_red' })
    else:
        f = logging.Formatter(format, date_format)
    ch = logging.StreamHandler()
    ch.setFormatter(f)
    root.addHandler(ch)

setup_logging()
log = logging.getLogger(__name__)

কোডটি শুধুমাত্র লগ বার্তাগুলিতে রঙ সক্ষম করে, যদি রঙলগ মডিউল ইনস্টল থাকে এবং যদি আউটপুট আসলে টার্মিনালে যায়। এটি লগ আউটপুট পুনঃনির্দেশিত হয় যখন একটি ফাইল লিখিত পলায়ন ক্রম এড়ানো।

এছাড়াও, একটি কাস্টম রঙ স্কিম সেটআপ যা অন্ধকার ব্যাকগ্রাউন্ড সহ টার্মিনালের জন্য আরও উপযুক্ত।

কিছু উদাহরণ লগিং কল:

log.debug   ('Hello Debug')
log.info    ('Hello Info')
log.warn    ('Hello Warn')
log.error   ('Hello Error')
log.critical('Hello Critical')

আউটপুট:

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


2
colorlog.basicConfigপরিবর্তে logging.basicConfigকিছু ভাল ডিফল্ট রয়েছে এর পরিবর্তে ব্যবহার করতে পারেন
মারসফট

1
রেকর্ডের জন্য, রঙিনগ সর্বদা উইন্ডোজ প্ল্যাটফর্মগুলিতে সরাসরি কাজ করে না (নির্দিষ্ট হিসাবে কলোরামা নির্ভরতা প্রয়োজন)। এমনকি এটি সহ, আমি এটি অ্যানাকোন্ডা / স্পাইডার এনভির কাজ করতে পেতে সমস্যা হয়েছিল। আপনি পাল্টা_কোড.পিতে উদাহরণস্বরূপ কলারাম.ইনিট (স্ট্রিপ = মিথ্যা) উল্লেখ করতে হবে (এই থ্রেডে github.com/spyder-ide/spyder/issues/1917 হিসাবে নির্দেশিত )
ম্যাট-ম্যাক-মফিন

11

নিম্নলিখিত সমাধান দেখুন। স্ট্রিম হ্যান্ডলারটি রঙ করা জিনিস হওয়া উচিত, তারপরে আপনার কাছে কেবল পুরো লাইনটি (ফর্ম্যাটর সহ) বর্ণের পরিবর্তে শব্দ রঙ করার বিকল্প রয়েছে।

http://plumberjack.blogspot.com/2010/12/colorizing-logging-output-in-terminals.html


আপনি এই টুকরোটিতে একটি আপডেট বাস্তবায়ন পেতে পারেন (ব্লগ লেখক দ্বারা রক্ষণাবেক্ষণ)। আমি এটি ব্যবহার করছি এবং ঠিকঠাক কাজ করছি। ভাগ করে নেওয়ার জন্য ধন্যবাদ.
noisebleed

11

আমি সোরিন এবং সাবক্ল্যাসড স্ট্রিমহ্যান্ডলার দ্বারা সরবরাহিত মূল উদাহরণটি একটি কালারাইজড কনসোলহ্যান্ডলারের কাছে সংশোধন করেছি।

তাদের সমাধানের ক্ষতিটি হ'ল এটি বার্তাটি সংশোধন করে এবং যেহেতু এটি আসল লগমেসেজ পরিবর্তন করছে অন্য কোনও হ্যান্ডলাররাও পরিবর্তিত বার্তাটি পাবেন।

এটির ক্ষেত্রে আমাদের ক্ষেত্রে রঙিন কোড সহ লগফাইলে ফলাফল হয়েছে কারণ আমরা একাধিক লগার ব্যবহার করি।

নীচের শ্রেণিটি কেবল প্ল্যাটফর্মগুলিতে কাজ করে যা আনসিকে সমর্থন করে তবে এটিতে উইন্ডোজ রঙিন কোডগুলি যুক্ত করা তুচ্ছ হওয়া উচিত।

import copy
import logging


class ColoredConsoleHandler(logging.StreamHandler):
    def emit(self, record):
        # Need to make a actual copy of the record
        # to prevent altering the message for other loggers
        myrecord = copy.copy(record)
        levelno = myrecord.levelno
        if(levelno >= 50):  # CRITICAL / FATAL
            color = '\x1b[31m'  # red
        elif(levelno >= 40):  # ERROR
            color = '\x1b[31m'  # red
        elif(levelno >= 30):  # WARNING
            color = '\x1b[33m'  # yellow
        elif(levelno >= 20):  # INFO
            color = '\x1b[32m'  # green
        elif(levelno >= 10):  # DEBUG
            color = '\x1b[35m'  # pink
        else:  # NOTSET and anything else
            color = '\x1b[0m'  # normal
        myrecord.msg = color + str(myrecord.msg) + '\x1b[0m'  # normal
        logging.StreamHandler.emit(self, myrecord)

10

কাস্টমাইজযোগ্য রঙিন লগিং আউটপুট জন্য এখন একটি মুক্তি পাইপাই মডিউল রয়েছে:

https://pypi.python.org/pypi/rainbow_logging_handler/

এবং

https://github.com/laysakura/rainbow_logging_handler

  • উইন্ডোজ সমর্থন করে

  • জ্যাঙ্গো সমর্থন করে

  • কাস্টমাইজযোগ্য রঙ

এটি পাইথন ডিম হিসাবে বিতরণ করা হওয়ায় যে কোনও পাইথন অ্যাপ্লিকেশনটির জন্য এটি ইনস্টল করা খুব সহজ।


7

এখানে প্রচুর প্রতিক্রিয়া রয়েছে। তবে কেউই সাজসজ্জার কথা বলছেন না। সুতরাং এখানে আমার।

কারণ এটি অনেক বেশি সাধারণ।

কিছু আমদানি করার দরকার নেই, বা কোনও সাবক্লাস লেখার দরকার নেই:

#!/usr/bin/env python
# -*- coding: utf-8 -*-


import logging


NO_COLOR = "\33[m"
RED, GREEN, ORANGE, BLUE, PURPLE, LBLUE, GREY = \
    map("\33[%dm".__mod__, range(31, 38))

logging.basicConfig(format="%(message)s", level=logging.DEBUG)
logger = logging.getLogger(__name__)

# the decorator to apply on the logger methods info, warn, ...
def add_color(logger_method, color):
  def wrapper(message, *args, **kwargs):
    return logger_method(
      # the coloring is applied here.
      color+message+NO_COLOR,
      *args, **kwargs
    )
  return wrapper

for level, color in zip((
  "info", "warn", "error", "debug"), (
  GREEN, ORANGE, RED, BLUE
)):
  setattr(logger, level, add_color(getattr(logger, level), color))

# this is displayed in red.
logger.error("Launching %s." % __file__)

এটি লালতে ত্রুটিগুলি সেট করে, নীল রঙে মেসেজগুলি ডিবাগ করে on প্রশ্নে জিজ্ঞাসা মত।

আমরা এমনকি নিতে একটি মোড়ক মানিয়ে নিতে পারে color বার্তাটির রঙটি ব্যবহার করে গতিশীলতার পক্ষে যুক্তিlogger.debug("message", color=GREY)

সম্পাদনা: সুতরাং রানটাইমের সময় রঙ সেট করার জন্য অভিযোজিত ডেকোরেটরটি এখানে:

def add_color(logger_method, _color):
  def wrapper(message, *args, **kwargs):
    color = kwargs.pop("color", _color)
    if isinstance(color, int):
      color = "\33[%dm" % color
    return logger_method(
      # the coloring is applied here.
      color+message+NO_COLOR,
      *args, **kwargs
    )
  return wrapper

# blah blah, apply the decorator...

# this is displayed in red.
logger.error("Launching %s." % __file__)
# this is displayed in blue
logger.error("Launching %s." % __file__, color=34)
# and this, in grey
logger.error("Launching %s." % __file__, color=GREY)

6

এয়ারমাইন্ডের পদ্ধতির আরও একটি ছোট্ট রিমিক্স যা সমস্ত কিছু এক শ্রেণিতে রাখে:

class ColorFormatter(logging.Formatter):
  FORMAT = ("[$BOLD%(name)-20s$RESET][%(levelname)-18s]  "
            "%(message)s "
            "($BOLD%(filename)s$RESET:%(lineno)d)")

  BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)

  RESET_SEQ = "\033[0m"
  COLOR_SEQ = "\033[1;%dm"
  BOLD_SEQ = "\033[1m"

  COLORS = {
    'WARNING': YELLOW,
    'INFO': WHITE,
    'DEBUG': BLUE,
    'CRITICAL': YELLOW,
    'ERROR': RED
  }

  def formatter_msg(self, msg, use_color = True):
    if use_color:
      msg = msg.replace("$RESET", self.RESET_SEQ).replace("$BOLD", self.BOLD_SEQ)
    else:
      msg = msg.replace("$RESET", "").replace("$BOLD", "")
    return msg

  def __init__(self, use_color=True):
    msg = self.formatter_msg(self.FORMAT, use_color)
    logging.Formatter.__init__(self, msg)
    self.use_color = use_color

  def format(self, record):
    levelname = record.levelname
    if self.use_color and levelname in self.COLORS:
      fore_color = 30 + self.COLORS[levelname]
      levelname_color = self.COLOR_SEQ % fore_color + levelname + self.RESET_SEQ
      record.levelname = levelname_color
    return logging.Formatter.format(self, record)

হ্যান্ডলারের সাথে ফর্ম্যাটরটি সংযুক্ত করার জন্য, এরকম কিছু:

handler.setFormatter(ColorFormatter())
logger.addHandler(handler)

5

কোনও টার্মিনাল পাঠ্য রঙ করার জন্য একটি সহজ তবে খুব নমনীয় সরঞ্জাম হ'ল ' কলআউট '।

pip install colout
myprocess | colout REGEX_WITH_GROUPS color1,color2...

যেখানে রেগেক্সের গ্রুপ 1 এর সাথে মেলে এমন 'মাইপ্রোসেস' এর আউটপুটে কোনও পাঠ্য রঙ 1, রঙ 2 সহ গ্রুপ 2 ইত্যাদির সাথে বর্ণযুক্ত হবে etc.

উদাহরণ স্বরূপ:

tail -f /var/log/mylogfile | colout '^(\w+ \d+ [\d:]+)|(\w+\.py:\d+ .+\(\)): (.+)$' white,black,cyan bold,bold,normal

অর্থাত্ প্রথম রেজেক্স গোষ্ঠী (প্যারেনস) লগফাইলে প্রাথমিক তারিখের সাথে মেলে, দ্বিতীয় গ্রুপটি একটি পাইথন ফাইলের নাম, লাইন নম্বর এবং ফাংশনের নামের সাথে মেলে এবং তৃতীয় গোষ্ঠী তার পরে আসা লগ বার্তার সাথে মেলে। আমি 'বোল্ড / নরমালস' এর পাশাপাশি রঙের ক্রমগুলির সমান্তরাল সিকোয়েন্সও ব্যবহার করি। এটির মতো দেখাচ্ছে:

রঙিন বিন্যাস সহ লগফিল

নোট করুন যে রেখা বা রেখাগুলির অংশগুলি যা আমার কোনও রেগেক্সের সাথে মেলে না তা এখনও প্রতিধ্বনিত হয়, সুতরাং এটি 'গ্রেপ - রঙ' এর মতো নয় - আউটপুট থেকে কোনও কিছুই ফিল্টার হয় না।

স্পষ্টতই এটি যথেষ্ট নমনীয় যে আপনি এটি কোনও প্রক্রিয়াতে ব্যবহার করতে পারবেন, কেবল লগ-ফাইলে টেইলিং নয়। আমি যখনই কোনও কিছু রঙিন করতে চাই তখন আমি সাধারণত ফ্লাইতে একটি নতুন রেজেক্স হুইপ করি। এই কারণে, আমি যে কোনও কাস্টম লগফিল-কালারিংয়ের সরঞ্জামে কলআউট পছন্দ করি, কারণ আমি যা রঙ করছি তা নির্বিশেষে আমার কেবল একটি সরঞ্জাম শিখতে হবে: লগিং, পরীক্ষার আউটপুট, টার্মিনালে কোডের স্নিপেটগুলি সিনট্যাক্স হাইলাইটিং ইত্যাদি etc.

এটি লগফাইলে নিজেই এএনএসআই কোডগুলি ডাম্প করা এড়িয়ে যায়, যা আইএমএইচও একটি খারাপ ধারণা, কারণ এটি লগফাইলে নিদর্শনগুলির জন্য গ্রেপিংয়ের মতো জিনিসগুলি ভেঙে ফেলবে যদি না আপনি সর্বদা আপনার গ্রেপ রেজেক্সে এএনএসআই কোডগুলি মেলে মনে রাখেন।


4
import logging
import sys

colors = {'pink': '\033[95m', 'blue': '\033[94m', 'green': '\033[92m', 'yellow': '\033[93m', 'red': '\033[91m',
      'ENDC': '\033[0m', 'bold': '\033[1m', 'underline': '\033[4m'}

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


def str_color(color, data):
    return colors[color] + str(data) + colors['ENDC']

params = {'param1': id1, 'param2': id2}

logging.info('\nParams:' + str_color("blue", str(params)))`

[9*m"উজ্জ্বল" এএনএসআই রঙের কোডগুলির সাথে +1 দুর্দান্ত উদাহরণ ! পিএস আপনার শেষ লাইনটি আমাকে কিছুটা উদ্বেগ করেছে কারণ ফাংশন সংজ্ঞার বাইরে লগিং পাইথনে নিরাপদ কিনা তা এখনও জানা যায়নি
ব্যক্তিগত_ক্লাউড

2

এখানে আমার সমাধান:

class ColouredFormatter(logging.Formatter):
    RESET = '\x1B[0m'
    RED = '\x1B[31m'
    YELLOW = '\x1B[33m'
    BRGREEN = '\x1B[01;32m'  # grey in solarized for terminals

    def format(self, record, colour=False):
        message = super().format(record)

        if not colour:
            return message

        level_no = record.levelno
        if level_no >= logging.CRITICAL:
            colour = self.RED
        elif level_no >= logging.ERROR:
            colour = self.RED
        elif level_no >= logging.WARNING:
            colour = self.YELLOW
        elif level_no >= logging.INFO:
            colour = self.RESET
        elif level_no >= logging.DEBUG:
            colour = self.BRGREEN
        else:
            colour = self.RESET

        message = colour + message + self.RESET

        return message


class ColouredHandler(logging.StreamHandler):
    def __init__(self, stream=sys.stdout):
        super().__init__(stream)

    def format(self, record, colour=False):
        if not isinstance(self.formatter, ColouredFormatter):
            self.formatter = ColouredFormatter()

        return self.formatter.format(record, colour)

    def emit(self, record):
        stream = self.stream
        try:
            msg = self.format(record, stream.isatty())
            stream.write(msg)
            stream.write(self.terminator)
            self.flush()
        except Exception:
            self.handleError(record)


h = ColouredHandler()
h.formatter = ColouredFormatter('{asctime} {levelname:8} {message}', '%Y-%m-%d %H:%M:%S', '{')
logging.basicConfig(level=logging.DEBUG, handlers=[h])

1

আমি যে সমস্যাটি নিয়ে সমস্যায় পড়েছি তা হ'ল ফর্ম্যাটরটি সঠিকভাবে স্থাপন করা হয়েছিল:

class ColouredFormatter(logging.Formatter):    
    def __init__(self, msg):
        logging.Formatter.__init__(self, msg)
        self._init_colour = _get_colour()

    def close(self):
        # restore the colour information to what it was
        _set_colour(self._init_colour)

    def format(self, record):        
        # Add your own colourer based on the other examples
        _set_colour( LOG_LEVEL_COLOUR[record.levelno] )
        return logging.Formatter.format(self, record)         

def init():
    # Set up the formatter. Needs to be first thing done.
    rootLogger = logging.getLogger()
    hdlr = logging.StreamHandler()
    fmt = ColouredFormatter('%(message)s')
    hdlr.setFormatter(fmt)
    rootLogger.addHandler(hdlr)

এবং তারপরে ব্যবহার করুন:

import coloured_log
import logging

coloured_log.init()
logging.info("info")    
logging.debug("debug")    

coloured_log.close()    # restore colours

এটি সিউডো কোড হওয়ার কথা ছিল (যেমন _set_colour অনুপস্থিত), তবে কিছু যুক্ত করেছে। ফর্ম্যাটরটি কীভাবে সঠিকভাবে সংযুক্ত করতে হয় তা জানার বিষয়টি সেই জিনিসটির মধ্যে সবচেয়ে বেশি সমস্যা হয়েছিল।
নিক

"প্লাম্বার জ্যাক" সমাধান দেখুন। আমি মনে করি সমস্যাটি সমাধানের এটি সর্বোত্তম উপায় (অর্থাত্‍ হ্যান্ডলারের কলরিয়েশন করা উচিত)। stackoverflow.com/questions/384076/…
নিক

1

অন্য সমাধানগুলি সূক্ষ্ম মনে হলেও তাদের কিছু সমস্যা রয়েছে। কিছু পুরো লাইনে রঙ দেয় যা কিছু সময় না চাওয়া হয় এবং কিছু আপনার সাথে একসাথে থাকা কোনও কনফিগারেশন বাদ দেয়। নীচের সমাধানটি বার্তা ব্যতীত অন্য কোনও কিছুকে প্রভাবিত করে না।

কোড

class ColoredFormatter(logging.Formatter):
    def format(self, record):
        if record.levelno == logging.WARNING:
            record.msg = '\033[93m%s\033[0m' % record.msg
        elif record.levelno == logging.ERROR:
            record.msg = '\033[91m%s\033[0m' % record.msg
        return logging.Formatter.format(self, record)

উদাহরণ

logger = logging.getLogger('mylogger')
handler = logging.StreamHandler()

log_format = '[%(asctime)s]:%(levelname)-7s:%(message)s'
time_format = '%H:%M:%S'
formatter = ColoredFormatter(log_format, datefmt=time_format)
handler.setFormatter(formatter)
logger.addHandler(handler)

logger.warn('this should be yellow')
logger.error('this should be red')

আউটপুট

[17:01:36]:WARNING:this should be yellow
[17:01:37]:ERROR  :this should be red

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


যখন আমি এটি ব্যবহার করি, বার্তা দুটিবার মুদ্রিত হয়। তুমি কি জানো কেন?
ভ্যালিডাস ওকুলাস

@ আপনি বিস্তারিত বলতে পারেন? যথা আপনার অর্থ কিছু [17:01:36]:WARNING:this should be yellowthis should be yellowবা পুরো লাইন দু'বার মুদ্রিত হচ্ছে?
পিথিকোস

মন্তব্যটির বংশবৃদ্ধির জন্য দুঃখিত। পূর্বেরটি ঘটেছে: [17:01:36]: সতর্কতা: এটি হলুদ হওয়া উচিত th n এটি হলুদ হওয়া উচিত। যাইহোক, আমি কেবল ফর্ম্যাটযুক্তটি দেখানোর জন্য চাই অন্যথায় এটি অনর্থক লগগুলির কারণে আবর্জনার মতো দেখাচ্ছে।
ভ্যালিডাস ওকুলাস

@ মুরতকারাকুş নিশ্চিত হন না যে বাস্তবায়নের বিষয়ে সম্পূর্ণ দৃষ্টিভঙ্গি ছাড়াই কেন এমন হয়। আপনি যদি কোনও কাস্টম লগার ব্যবহার করছেন তবে আপনি কোনও সময়ে হস্তক্ষেপ করছেন? একটি দ্রুত ফিক্স 7s:%(message)sথেকে এটি অপসারণ করা যেতে পারে log_format
পিথিকোস

1

আমার যোগ করার জন্য আমার দুটি জমা রয়েছে, যার একটিতে কেবল বার্তাটি বর্ণিত (রঙিন ফরম্যাটার), এবং এর মধ্যে একটি সম্পূর্ণ লাইনে রঙিন করে তোলে (কালারাইজিংস্ট্রিমহ্যান্ডলার)। এর মধ্যে আগের সমাধানগুলির চেয়ে আরও এএনএসআই রঙ কোড অন্তর্ভুক্ত রয়েছে।

কিছু বিষয়বস্তু থেকে উত্সাহিত হয়েছে (পরিবর্তনের মাধ্যমে): উপরের পোস্টটি এবং http://plumberjack.blogspot.com/2010/12/colorizing-logging-output-in-teritions.html

শুধুমাত্র বার্তাটি রঙিন করে তোলে:

class ColoredFormatter(logging.Formatter):
    """Special custom formatter for colorizing log messages!"""

    BLACK = '\033[0;30m'
    RED = '\033[0;31m'
    GREEN = '\033[0;32m'
    BROWN = '\033[0;33m'
    BLUE = '\033[0;34m'
    PURPLE = '\033[0;35m'
    CYAN = '\033[0;36m'
    GREY = '\033[0;37m'

    DARK_GREY = '\033[1;30m'
    LIGHT_RED = '\033[1;31m'
    LIGHT_GREEN = '\033[1;32m'
    YELLOW = '\033[1;33m'
    LIGHT_BLUE = '\033[1;34m'
    LIGHT_PURPLE = '\033[1;35m'
    LIGHT_CYAN = '\033[1;36m'
    WHITE = '\033[1;37m'

    RESET = "\033[0m"

    def __init__(self, *args, **kwargs):
        self._colors = {logging.DEBUG: self.DARK_GREY,
                        logging.INFO: self.RESET,
                        logging.WARNING: self.BROWN,
                        logging.ERROR: self.RED,
                        logging.CRITICAL: self.LIGHT_RED}
        super(ColoredFormatter, self).__init__(*args, **kwargs)

    def format(self, record):
        """Applies the color formats"""
        record.msg = self._colors[record.levelno] + record.msg + self.RESET
        return logging.Formatter.format(self, record)

    def setLevelColor(self, logging_level, escaped_ansi_code):
        self._colors[logging_level] = escaped_ansi_code

পুরো লাইনটি রঙিন করে তোলে:

class ColorizingStreamHandler(logging.StreamHandler):

    BLACK = '\033[0;30m'
    RED = '\033[0;31m'
    GREEN = '\033[0;32m'
    BROWN = '\033[0;33m'
    BLUE = '\033[0;34m'
    PURPLE = '\033[0;35m'
    CYAN = '\033[0;36m'
    GREY = '\033[0;37m'

    DARK_GREY = '\033[1;30m'
    LIGHT_RED = '\033[1;31m'
    LIGHT_GREEN = '\033[1;32m'
    YELLOW = '\033[1;33m'
    LIGHT_BLUE = '\033[1;34m'
    LIGHT_PURPLE = '\033[1;35m'
    LIGHT_CYAN = '\033[1;36m'
    WHITE = '\033[1;37m'

    RESET = "\033[0m"

    def __init__(self, *args, **kwargs):
        self._colors = {logging.DEBUG: self.DARK_GREY,
                        logging.INFO: self.RESET,
                        logging.WARNING: self.BROWN,
                        logging.ERROR: self.RED,
                        logging.CRITICAL: self.LIGHT_RED}
        super(ColorizingStreamHandler, self).__init__(*args, **kwargs)

    @property
    def is_tty(self):
        isatty = getattr(self.stream, 'isatty', None)
        return isatty and isatty()

    def emit(self, record):
        try:
            message = self.format(record)
            stream = self.stream
            if not self.is_tty:
                stream.write(message)
            else:
                message = self._colors[record.levelno] + message + self.RESET
                stream.write(message)
            stream.write(getattr(self, 'terminator', '\n'))
            self.flush()
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            self.handleError(record)

    def setLevelColor(self, logging_level, escaped_ansi_code):
        self._colors[logging_level] = escaped_ansi_code


1

এটি রঙিন কোড সহ একটি এনুম:

class TerminalColour:
    """
    Terminal colour formatting codes
    """
    # /programming/287871/print-in-terminal-with-colors
    MAGENTA = '\033[95m'
    BLUE = '\033[94m'
    GREEN = '\033[92m'
    YELLOW = '\033[93m'
    RED = '\033[91m'
    GREY = '\033[0m'  # normal
    WHITE = '\033[1m'  # bright white
    UNDERLINE = '\033[4m'

এটি প্রতিটি লগ স্তরের নামের ক্ষেত্রে প্রয়োগ করা যেতে পারে । সচেতন থাকুন যে এটি একটি রাক্ষসী হ্যাক।

logging.addLevelName(logging.INFO, "{}{}{}".format(TerminalColour.WHITE, logging.getLevelName(logging.INFO), TerminalColour.GREY))
logging.addLevelName(logging.WARNING, "{}{}{}".format(TerminalColour.YELLOW, logging.getLevelName(logging.WARNING), TerminalColour.GREY))
logging.addLevelName(logging.ERROR, "{}{}{}".format(TerminalColour.RED, logging.getLevelName(logging.ERROR), TerminalColour.GREY))
logging.addLevelName(logging.CRITICAL, "{}{}{}".format(TerminalColour.MAGENTA, logging.getLevelName(logging.CRITICAL), .GREY))

নোট করুন যে আপনার লগ বিন্যাসে অবশ্যই লগ স্তরের নাম অন্তর্ভুক্ত করতে হবে

%(levelname)

উদাহরণ স্বরূপ:

    LOGGING = {
...
        'verbose': {
            'format': '%(asctime)s %(levelname)s %(name)s:%(lineno)s %(module)s %(process)d %(thread)d %(message)s'
        },
        'simple': {
            'format': '[%(asctime)s] %(levelname)s %(name)s %(message)s'
        },

1

ফ্রেন্ডলিলগ আরেকটি বিকল্প। এটি লিনাক্স, উইন্ডোজ এবং ম্যাকোসের অধীনে পাইথন 2 এবং 3 এর সাথে কাজ করে।


মডিউল পথের বিশৃঙ্খলা হ্রাস করতে নতুন জনসংযোগের অপেক্ষায়
রয়েছেন

1

স্তর দ্বারা রঙ করা ছাড়াও বিকল্প রঙের সাথে বার্তা যুক্তিগুলি লগ করার বিষয়ে কী? আমি সম্প্রতি এটির জন্য সহজ কোড লিখেছি। আর একটি সুবিধা হ'ল লগ কল পাইথন 3 ব্রেস-স্টাইল বিন্যাসের সাহায্যে করা হয়। ( "{}")।

সর্বশেষতম কোড এবং উদাহরণগুলি এখানে দেখুন: https://github.com/davidohana/colargulog

নমুনা লগিং কোড:

root_logger = logging.getLogger()
console_handler = logging.StreamHandler(stream=sys.stdout)
console_format = "%(asctime)s - %(levelname)-8s - %(name)-25s - %(message)s"
colored_formatter = ColorizedArgsFormatter(console_format)
console_handler.setFormatter(colored_formatter)
root_logger.addHandler(console_handler)

logger = logging.getLogger(__name__)
logger.info("Hello World")
logger.info("Request from {} handled in {:.3f} ms", socket.gethostname(), 11)
logger.info("Request from {} handled in {:.3f} ms", "127.0.0.1", 33.1)
logger.info("My favorite drinks are {}, {}, {}, {}", "milk", "wine", "tea", "beer")
logger.debug("this is a {} message", logging.getLevelName(logging.DEBUG))
logger.info("this is a {} message", logging.getLevelName(logging.INFO))
logger.warning("this is a {} message", logging.getLevelName(logging.WARNING))
logger.error("this is a {} message", logging.getLevelName(logging.ERROR))
logger.critical("this is a {} message", logging.getLevelName(logging.CRITICAL))
logger.info("Does old-style formatting also work? %s it is, but no colors (yet)", True)

আউটপুট:

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

বাস্তবায়ন:

"""
colargulog - Python3 Logging with Colored Arguments and new string formatting style

Written by david.ohana@ibm.com
License: Apache-2.0
"""

import logging
import logging.handlers
import re


class ColorCodes:
    grey = "\x1b[38;21m"
    green = "\x1b[1;32m"
    yellow = "\x1b[33;21m"
    red = "\x1b[31;21m"
    bold_red = "\x1b[31;1m"
    blue = "\x1b[1;34m"
    light_blue = "\x1b[1;36m"
    purple = "\x1b[1;35m"
    reset = "\x1b[0m"


class ColorizedArgsFormatter(logging.Formatter):
    arg_colors = [ColorCodes.purple, ColorCodes.light_blue]
    level_fields = ["levelname", "levelno"]
    level_to_color = {
        logging.DEBUG: ColorCodes.grey,
        logging.INFO: ColorCodes.green,
        logging.WARNING: ColorCodes.yellow,
        logging.ERROR: ColorCodes.red,
        logging.CRITICAL: ColorCodes.bold_red,
    }

    def __init__(self, fmt: str):
        super().__init__()
        self.level_to_formatter = {}

        def add_color_format(level: int):
            color = ColorizedArgsFormatter.level_to_color[level]
            _format = fmt
            for fld in ColorizedArgsFormatter.level_fields:
                search = "(%\(" + fld + "\).*?s)"
                _format = re.sub(search, f"{color}\\1{ColorCodes.reset}", _format)
            formatter = logging.Formatter(_format)
            self.level_to_formatter[level] = formatter

        add_color_format(logging.DEBUG)
        add_color_format(logging.INFO)
        add_color_format(logging.WARNING)
        add_color_format(logging.ERROR)
        add_color_format(logging.CRITICAL)

    @staticmethod
    def rewrite_record(record: logging.LogRecord):
        if not BraceFormatStyleFormatter.is_brace_format_style(record):
            return

        msg = record.msg
        msg = msg.replace("{", "_{{")
        msg = msg.replace("}", "_}}")
        placeholder_count = 0
        # add ANSI escape code for next alternating color before each formatting parameter
        # and reset color after it.
        while True:
            if "_{{" not in msg:
                break
            color_index = placeholder_count % len(ColorizedArgsFormatter.arg_colors)
            color = ColorizedArgsFormatter.arg_colors[color_index]
            msg = msg.replace("_{{", color + "{", 1)
            msg = msg.replace("_}}", "}" + ColorCodes.reset, 1)
            placeholder_count += 1

        record.msg = msg.format(*record.args)
        record.args = []

    def format(self, record):
        orig_msg = record.msg
        orig_args = record.args
        formatter = self.level_to_formatter.get(record.levelno)
        self.rewrite_record(record)
        formatted = formatter.format(record)

        # restore log record to original state for other handlers
        record.msg = orig_msg
        record.args = orig_args
        return formatted


class BraceFormatStyleFormatter(logging.Formatter):
    def __init__(self, fmt: str):
        super().__init__()
        self.formatter = logging.Formatter(fmt)

    @staticmethod
    def is_brace_format_style(record: logging.LogRecord):
        if len(record.args) == 0:
            return False

        msg = record.msg
        if '%' in msg:
            return False

        count_of_start_param = msg.count("{")
        count_of_end_param = msg.count("}")

        if count_of_start_param != count_of_end_param:
            return False

        if count_of_start_param != len(record.args):
            return False

        return True

    @staticmethod
    def rewrite_record(record: logging.LogRecord):
        if not BraceFormatStyleFormatter.is_brace_format_style(record):
            return

        record.msg = record.msg.format(*record.args)
        record.args = []

    def format(self, record):
        orig_msg = record.msg
        orig_args = record.args
        self.rewrite_record(record)
        formatted = self.formatter.format(record)

        # restore log record to original state for other handlers
        record.msg = orig_msg
        record.args = orig_args
        return formatted


0

জেটাসায়ানথিসের রঙ সহ আরও একটি সমাধান:

def config_log(log_level):

    def set_color(level, code):
        level_fmt = "\033[1;" + str(code) + "m%s\033[1;0m" 
        logging.addLevelName( level, level_fmt % logging.getLevelName(level) )

    std_stream = sys.stdout
    isatty = getattr(std_stream, 'isatty', None)
    if isatty and isatty():
        levels = [logging.DEBUG, logging.CRITICAL, logging.WARNING, logging.ERROR]
        for idx, level in enumerate(levels):
            set_color(level, 30 + idx )
        set_color(logging.DEBUG, 0)
    logging.basicConfig(stream=std_stream, level=log_level)

আপনার __main__ফাংশন থেকে একবার কল করুন । আমার এখানে এমন কিছু রয়েছে:

options, arguments = p.parse_args()
log_level = logging.DEBUG if options.verbose else logging.WARNING
config_log(log_level)

এটি আউটপুট একটি কনসোল যাচাইও করে, অন্যথায় কোনও রং ব্যবহার করা হয় না।


0
import logging

logging.basicConfig(filename="f.log" filemode='w', level=logging.INFO,
                    format = "%(logger_name)s %(color)s  %(message)s %(endColor)s")


class Logger(object):
    __GREEN = "\033[92m"
    __RED = '\033[91m'
    __ENDC = '\033[0m'

    def __init__(self, name):
        self.logger = logging.getLogger(name)
        self.extra={'logger_name': name, 'endColor': self.__ENDC, 'color': self.__GREEN}


    def info(self, msg):
        self.extra['color'] = self.__GREEN
        self.logger.info(msg, extra=self.extra)

    def error(self, msg):
        self.extra['color'] = self.__RED
        self.logger.error(msg, extra=self.extra)

ব্যবহার

Logger("File Name").info("This shows green text")


কনসোলের জন্য আপনি ফাইলের নাম ছেড়ে দিতে পারেন বা কেবল ফাইলের নাম = '' কাজ করা উচিত। ফাইল নম্বর, মডিউল
ইত্যাদির

0

নিম্নলিখিত সমাধানটি পাইথন 3 নিয়ে কেবল কাজ করে, তবে আমার জন্য এটি সবচেয়ে পরিষ্কার দেখাচ্ছে।

লগ রেকর্ড অবজেক্টগুলিতে 'রঙিন' বৈশিষ্ট্য যুক্ত করতে এবং লগ বিন্যাসে এই 'রঙিন' বৈশিষ্ট্যগুলি ব্যবহার করার চেয়ে লগ রেকর্ড কারখানাটি ব্যবহার করার ধারণা।

import logging
logger = logging.getLogger(__name__)

def configure_logging(level):

    # add 'levelname_c' attribute to log resords
    orig_record_factory = logging.getLogRecordFactory()
    log_colors = {
        logging.DEBUG:     "\033[1;34m",  # blue
        logging.INFO:      "\033[1;32m",  # green
        logging.WARNING:   "\033[1;35m",  # magenta
        logging.ERROR:     "\033[1;31m",  # red
        logging.CRITICAL:  "\033[1;41m",  # red reverted
    }
    def record_factory(*args, **kwargs):
        record = orig_record_factory(*args, **kwargs)
        record.levelname_c = "{}{}{}".format(
            log_colors[record.levelno], record.levelname, "\033[0m")
        return record

    logging.setLogRecordFactory(record_factory)

    # now each log record object would contain 'levelname_c' attribute
    # and you can use this attribute when configuring logging using your favorite
    # method.
    # for demo purposes I configure stderr log right here

    formatter_c = logging.Formatter("[%(asctime)s] %(levelname_c)s:%(name)s:%(message)s")

    stderr_handler = logging.StreamHandler()
    stderr_handler.setLevel(level)
    stderr_handler.setFormatter(formatter_c)

    root_logger = logging.getLogger('')
    root_logger.setLevel(logging.DEBUG)
    root_logger.addHandler(stderr_handler)


def main():
    configure_logging(logging.DEBUG)

    logger.debug("debug message")
    logger.info("info message")
    logger.critical("something unusual happened")


if __name__ == '__main__':
    main()

আপনি অন্যান্য বর্ণের বৈশিষ্ট্য তৈরি করতে সহজেই এই উদাহরণটি সংশোধন করতে পারেন (ফে ম্যাসেজ_সি) এবং তারপরে আপনি চান যেখানে রঙিন পাঠ্য (কেবল) পেতে এই বৈশিষ্ট্যগুলি ব্যবহার করুন।

(সহজ কৌশল আমি সম্প্রতি আবিষ্কার করেছি: রঙিন ডিবাগ লগ সহ আমার একটি ফাইল রয়েছে এবং যখনই আমি অস্থায়ীভাবে আমার অ্যাপ্লিকেশনটির লগের মাত্রা বাড়াতে চাই আমি কেবলমাত্র tail -fবিভিন্ন টার্মিনালে লগ লগ করব এবং স্ক্রিনে ডিবাগ লগগুলি দেখতে পাই / যে কোনও কনফিগারেশন পরিবর্তন করে পুনরায় আরম্ভ করার জন্য অ্যাপ্লিকেশন )


0

এটি এয়ারমাইন্ডের উদাহরণের আর একটি পাইথন 3 রূপ। আমি কিছু নির্দিষ্ট বৈশিষ্ট্য চেয়েছিলাম যা আমি অন্যান্য উদাহরণগুলিতে দেখিনি

  • টার্মিনালের জন্য রঙগুলি ব্যবহার করুন তবে ফাইল হ্যান্ডলারে মুদ্রণযোগ্য অক্ষরগুলি লিখবেন না (আমি এটির জন্য 2 ফর্ম্যাটর সংজ্ঞায়িত করেছি)
  • নির্দিষ্ট লগ বার্তার জন্য রঙকে ওভাররাইড করার ক্ষমতা
  • কোনও ফাইল থেকে লগারটি কনফিগার করুন (এই ক্ষেত্রে ইয়ামল)

দ্রষ্টব্য: আমি কলারোমা ব্যবহার করেছি তবে আপনি এটি পরিবর্তন করতে পারেন তাই এটির প্রয়োজন নেই। এছাড়াও আমার পরীক্ষার জন্য আমি কেবল পাইথন ফাইল চালাচ্ছিলাম তাই আমার ক্লাসটি মডিউলে রয়েছে আপনার মডিউলটি যাই হোক না কেন আপনাকে তা __main__পরিবর্তন (): __main__.ColoredFormatterকরতে হবে।

pip install colorama pyyaml

logging.yaml

---
version: 1
disable_existing_loggers: False
formatters:
  simple:
    format: "%(threadName)s - %(name)s - %(levelname)s - %(message)s"
  color:
    format: "%(threadName)s - %(name)s - %(levelname)s - %(message)s"
    (): __main__.ColoredFormatter
    use_color: true

handlers:
  console:
    class: logging.StreamHandler
    level: DEBUG
    formatter: color
    stream: ext://sys.stdout

  info_file_handler:
    class: logging.handlers.RotatingFileHandler
    level: INFO
    formatter: simple
    filename: app.log
    maxBytes: 20971520 
    backupCount: 20
    encoding: utf8

  error_file_handler:
    class: logging.handlers.RotatingFileHandler
    level: ERROR
    formatter: simple
    filename: errors.log
    maxBytes: 10485760 
    backupCount: 20
    encoding: utf8

root:
  level: DEBUG
  handlers: [console, info_file_handler, error_file_handler]

main.py

import logging
import logging.config
import os
from logging import Logger

import colorama
import yaml
from colorama import Back, Fore, Style

COLORS = {
    "WARNING": Fore.YELLOW,
    "INFO": Fore.CYAN,
    "DEBUG": Fore.BLUE,
    "CRITICAL": Fore.YELLOW,
    "ERROR": Fore.RED,
}


class ColoredFormatter(logging.Formatter):
    def __init__(self, *, format, use_color):
        logging.Formatter.__init__(self, fmt=format)
        self.use_color = use_color

    def format(self, record):
        msg = super().format(record)
        if self.use_color:
            levelname = record.levelname
            if hasattr(record, "color"):
                return f"{record.color}{msg}{Style.RESET_ALL}"
            if levelname in COLORS:
                return f"{COLORS[levelname]}{msg}{Style.RESET_ALL}"
        return msg


with open("logging.yaml", "rt") as f:
    config = yaml.safe_load(f.read())
    logging.config.dictConfig(config)

logger: Logger = logging.getLogger(__name__)
logger.info("Test INFO", extra={"color": Back.RED})
logger.info("Test INFO", extra={"color": f"{Style.BRIGHT}{Back.RED}"})
logger.info("Test INFO")
logger.debug("Test DEBUG")
logger.warning("Test WARN")

আউটপুট:

আউটপুট

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