পাইথন লগিং: সময় বিন্যাসে মিলিসেকেন্ড ব্যবহার করুন


163

গতানুগতিক logging.Formatter('%(asctime)s')নিম্নলিখিত বিন্যাস সহ মুদ্রণ :

2011-06-09 10:54:40,638

যেখানে 8৩৮ মিলি সেকেন্ড। আমার কমাটি বিন্দুতে পরিবর্তন করতে হবে:

2011-06-09 10:54:40.638

আমি যে সময়টি ব্যবহার করতে পারি তা ফর্ম্যাট করতে:

logging.Formatter(fmt='%(asctime)s',datestr=date_format_str)

তবে ডকুমেন্টেশনটি কীভাবে মিলিসেকেন্ডগুলিকে ফর্ম্যাট করবেন তা নির্দিষ্ট করে না। আমি এই এসও প্রশ্নটি পেয়েছি যা মাইক্রোসেকেন্ডের বিষয়ে কথা বলেছে, তবে ক) আমি মিলিসেকেন্ডগুলি পছন্দ করব এবং খ) নিম্নলিখিতটি পাইথন ২.6 (যাতে আমি কাজ করছি) -এ কাজ করে না %f:

logging.Formatter(fmt='%(asctime)s',datefmt='%Y-%m-%d,%H:%M:%S.%f')

1
সম্ভবত লোকেল পরিবর্তন সাহায্য করতে পারে?
pajton

1
@ পাজটন - নীচের লিঙ্কে এটি বলেছে "স্থানীয় তথ্য অ্যাসটাইম () দ্বারা ব্যবহার করা হয় না" - ডকস.প্যাথথন.আর.গ্রিবারি
জোনাথন

%fঅজগর ২.7.৯ বা
3.5.৩.১

4
এখানে ভাল কথোপকথন। আমি এখানে এসেছি কারণ loggingএর ডিফল্ট সময় বিন্যাসটি আইএসও 8601 অনুসরণ করে বলে দাবি করে It দশমিক বিন্দু নয়, ভগ্নাংশ সেকেন্ডের জন্য সময় এবং কমা পৃথক করতে এটি "টি" নয়, এটি স্থান ব্যবহার করে। তারা এত ভুল হতে পারে কিভাবে?
এলএস

উত্তর:


76

দয়া করে নোট করুন ক্রেগ ম্যাকডানিয়েলের সমাধানটি আরও ভাল।


লগিং.ফর্ম্যাটটারের formatTimeপদ্ধতিটি দেখতে এরকম দেখাচ্ছে:

def formatTime(self, record, datefmt=None):
    ct = self.converter(record.created)
    if datefmt:
        s = time.strftime(datefmt, ct)
    else:
        t = time.strftime("%Y-%m-%d %H:%M:%S", ct)
        s = "%s,%03d" % (t, record.msecs)
    return s

কমাটি লক্ষ্য করুন "%s,%03d"। এটি নির্দিষ্ট করে নির্দিষ্ট করা যায় না datefmtকারণ ctএটি একটি time.struct_timeএবং এই বস্তুগুলি মিলি সেকেন্ড রেকর্ড করে না।

যদি আমরা ctএটির datetimeপরিবর্তে এটি কোনও বস্তু তৈরির সংজ্ঞা পরিবর্তন করি তবে আমরা struct_time(কমপক্ষে পাইথনের আধুনিক সংস্করণ সহ) কল করতে পারি ct.strftimeএবং তারপরে আমরা %fমাইক্রোসেকেন্ডগুলিকে ফর্ম্যাট করতে পারি :

import logging
import datetime as dt

class MyFormatter(logging.Formatter):
    converter=dt.datetime.fromtimestamp
    def formatTime(self, record, datefmt=None):
        ct = self.converter(record.created)
        if datefmt:
            s = ct.strftime(datefmt)
        else:
            t = ct.strftime("%Y-%m-%d %H:%M:%S")
            s = "%s,%03d" % (t, record.msecs)
        return s

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

console = logging.StreamHandler()
logger.addHandler(console)

formatter = MyFormatter(fmt='%(asctime)s %(message)s',datefmt='%Y-%m-%d,%H:%M:%S.%f')
console.setFormatter(formatter)

logger.debug('Jackdaws love my big sphinx of quartz.')
# 2011-06-09,07:12:36.553554 Jackdaws love my big sphinx of quartz.

অথবা, মিলিসেকেন্ডগুলি পেতে, কমাটি দশমিক বিন্দুতে পরিবর্তন করুন এবং datefmtযুক্তিটি বাদ দিন :

class MyFormatter(logging.Formatter):
    converter=dt.datetime.fromtimestamp
    def formatTime(self, record, datefmt=None):
        ct = self.converter(record.created)
        if datefmt:
            s = ct.strftime(datefmt)
        else:
            t = ct.strftime("%Y-%m-%d %H:%M:%S")
            s = "%s.%03d" % (t, record.msecs)
        return s

...
formatter = MyFormatter(fmt='%(asctime)s %(message)s')
...
logger.debug('Jackdaws love my big sphinx of quartz.')
# 2011-06-09 08:14:38.343 Jackdaws love my big sphinx of quartz.

1
সুতরাং% f আসলে মাইক্রোসেকেন্ড দেবে, মিলিসেকেন্ড নয়, তাই না?
জোনাথন

@ জোনাথন: ওফ, আপনি ঠিক বলেছেন, %fমাইক্রোসেকেন্ড দেয়। আমি মনে করি মিলসেকেন্ডগুলি পাওয়ার সবচেয়ে সহজ উপায় হ'ল কমাটি দশমিক বিন্দুতে পরিবর্তন করা (উপরে সম্পাদনা দেখুন)।
unutbu

3
আমি প্রকৃতপক্ষে স্ট্যান্ডার্ড বিন্যাসকরণ বিকল্পগুলি ব্যবহার করতে সক্ষম হওয়ায় এটি আপনাকে সঠিকভাবে ফিরে আসার কারণে এটি সেরা উত্তর বলে মনে করি। আমি আসলে মাইক্রোসেকেন্ডগুলি চেয়েছিলাম এবং এটিই করতে পারে এটিই একমাত্র বিকল্প!
ট্রাম্প্লিক্লিকস

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

337

এটিও কাজ করা উচিত:

logging.Formatter(fmt='%(asctime)s.%(msecs)03d',datefmt='%Y-%m-%d,%H:%M:%S')

12
ধন্যবাদ: এগুলির জন্য এখানে ডক্স রয়েছে: docs.python.org/2/library/logging.html#logrecord-attributes docs.python.org/3/library/logging.html#logrecord-attributes .. কী উপায় আছে? এখনও সময় অঞ্চলটি (% z) অন্তর্ভুক্ত করবেন? ... পাইথন লগগুলিতে আইএসও 8601 ফর্ম্যাট বার (, ->।) দুর্দান্ত হবে।
ওয়েস টার্নার

19
এই সমাধানটি প্রতিবন্ধী, কারণ আপনি যদি %zবা %Zআপনার মধ্যে থাকেন তবে datefmtএটি এমসিসের পরে প্রদর্শিত হবে, আগে নয়।
উইমিং

1
এবং আপনি যদি 12 AMPM
ঘন্টাের

1
আমার আগের মন্তব্যের একটি ফলো আপ হিসাবে (সম্পাদনা আর যায়নি ...) @wim, এখানে আমি কি করেছো হল: from time import gmtime- # Use UTC rather than local date/time- logging.Formatter.converter = gmtime-logging.basicConfig(datefmt='%Y-%m-%dT%H:%M:%S', format='%(name)s | %(asctime)s.%(msecs)03dZ | %(message)s', level=log_level)
মার্ক

1
@ মার্ক আপনি সময় অঞ্চলটি default_msec_format(পাইথন ৩.7 হিসাবে) এম্বেড করতে পারবেন না কারণ কেবলমাত্র সময় এবং মিলিসেকেন্ডগুলিই প্রতিস্থাপিত হয় the loggingউত্স থেকে :self.default_msec_format % (t, record.msecs)
এম ডুডলি

27

ধন্যবাদ, ম্যাসেকস যুক্ত করা আরও ভাল বিকল্প ছিল। ব্লেন্ডারে পাইথন 3.5.3 এর সাথে এটি ব্যবহার করে আমার সংশোধন করা হল is

import logging
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s.%(msecs)03d %(levelname)s:\t%(message)s', datefmt='%Y-%m-%d %H:%M:%S')
log = logging.getLogger(__name__)
log.info("Logging Info")
log.debug("Logging Debug")

1
এখনও পর্যন্ত সহজ এবং পরিষ্কার বিকল্প। আপনি যখন লগিং.ইন.পি.ও (_) ইত্যাদি কল করতে পারেন তখন আপনি লগার কেন পাচ্ছেন তা নিশ্চিত নন তবে ফর্ম্যাটটি হ'ল আমি যা খুঁজছিলাম। অন্য যে সমস্ত ব্যবহারযোগ্য বৈশিষ্ট্যগুলি অনুসন্ধান করছে তারা এখানে দেখতে পাবেন: ডকস.পিথথন.আর.
.6./

হুঁ মজাদার পয়েন্ট, মন্তব্যের জন্য ধন্যবাদ এটি নিশ্চিতভাবে চিন্তার জন্য খাদ্য। ইয়া আমি সম্ভবত এটি কেবল সেখানে কী চলছে তার একটি পাঠ হিসাবে এটি যুক্ত করেছি এবং এটি সেখানে রয়েছে তা নিশ্চিত করার জন্য এবং আমি একাধিক জিনিস জিজ্ঞাসা করেছি যাতে এটি আনতে পিতামাতার কাছে একাধিক কল প্রয়োজন হয় না ('মাধ্যমে')। যদি আপনি .info বা .debug আবার কল করেন তবে আমি সম্ভবত আবার সেগুলি সংরক্ষণ করব কারণ আপনি একটি রেফারেন্স সন্ধানের চক্রটি সংরক্ষণ করার পরামর্শ দিচ্ছেন। [তথ্য = লগিং.ইন.ফো দিন]
মাস্টার জেমস

জেসন বলার জন্য ধন্যবাদ। কখনও কখনও বিশ্বকে দেখার একটি সহজ উপায় রয়েছে, অনেকের মধ্যে সেই সত্যটি চেষ্টা করার এবং আবিষ্কার করতে ভয় পাবেন না যদি কোনও / প্রতিটি পরিস্থিতি না থাকে।
মাস্টার জেমস

15

আমি খুঁজে পাওয়া সবচেয়ে সহজ উপায় হ'ল ডিফল্ট_ম্যাক_ফর্ম্যাট ওভাররাইড করা:

formatter = logging.Formatter('%(asctime)s')
formatter.default_msec_format = '%s.%03d'

1
আকর্ষণীয়, ধন্যবাদ। তবে পাইথন ২.7 এ এটি আমার পক্ষে কার্যকর হয়নি। এটি কেবলমাত্র x এর কিছু মূল্যের জন্য পাইথন 3.x এ কাজ করতে পারে।
nealmcb

1
@nealmcb এই পাইথন 3.3 পর্যন্ত প্রতি উপলব্ধ নয় ডক্স
মার্ক

3

ইনস্ট্যান্ট করার পরে Formatterআমি সাধারণত সেট করি formatter.converter = gmtime। সুতরাং @ আনটবুর উত্তরের ক্ষেত্রে এই ক্ষেত্রে কাজ করার জন্য আপনার প্রয়োজন হবে:

class MyFormatter(logging.Formatter):
    def formatTime(self, record, datefmt=None):
        ct = self.converter(record.created)
        if datefmt:
            s = time.strftime(datefmt, ct)
        else:
            t = time.strftime("%Y-%m-%d %H:%M:%S", ct)
            s = "%s.%03d" % (t, record.msecs)
        return s

2

একটি সাধারণ প্রসার যা datetimeমডিউলটির প্রয়োজন হয় না এবং অন্যান্য সমাধানগুলির মতো প্রতিবন্ধী নয় সেগুলি হ'ল সরল স্ট্রিং প্রতিস্থাপনটি ব্যবহার করা:

import logging
import time

class MyFormatter(logging.Formatter):
    def formatTime(self, record, datefmt=None):
    ct = self.converter(record.created)
    if datefmt:
        if "%F" in datefmt:
            msec = "%03d" % record.msecs
            datefmt = datefmt.replace("%F", msec)
        s = time.strftime(datefmt, ct)
    else:
        t = time.strftime("%Y-%m-%d %H:%M:%S", ct)
        s = "%s,%03d" % (t, record.msecs)
    return s

আপনি চাইলে এইভাবে একটি তারিখের ফর্ম্যাট লেখা যেতে পারে, এমনকি %Fমিলি সেকেন্ড ব্যবহার করে অঞ্চল পার্থক্যের অনুমতি দেয় । উদাহরণ স্বরূপ:

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

sh = logging.StreamHandler()
log.addHandler(sh)

fm = MyFormatter(fmt='%(asctime)s-%(levelname)s-%(message)s',datefmt='%H:%M:%S.%F')
sh.setFormatter(fm)

log.info("Foo, Bar, Baz")
# 03:26:33.757-INFO-Foo, Bar, Baz

1

আপনি যদি তীর ব্যবহার করছেন বা যদি তীর ব্যবহার করতে আপনার আপত্তি না থাকে। আপনি অ্যারোর একটির জন্য পাইথনের সময় বিন্যাসের বিকল্প দিতে পারেন।

import logging

from arrow.arrow import Arrow


class ArrowTimeFormatter(logging.Formatter):

    def formatTime(self, record, datefmt=None):
        arrow_time = Arrow.fromtimestamp(record.created)

        if datefmt:
            arrow_time = arrow_time.format(datefmt)

        return str(arrow_time)


logger = logging.getLogger(__name__)

default_handler = logging.StreamHandler()
default_handler.setFormatter(ArrowTimeFormatter(
    fmt='%(asctime)s',
    datefmt='YYYY-MM-DD HH:mm:ss.SSS'
))

logger.setLevel(logging.DEBUG)
logger.addHandler(default_handler)

এখন তোমরা সবাই ব্যবহার করতে পারেন তীর এর সময় বিন্যাস মধ্যে datefmtঅ্যাট্রিবিউট।


-1

tl; ডাঃ জনগণের জন্য এখানে একটি ISO বিন্যাসিত তারিখ খুঁজছেন:

ডেটফেম্ট: '% Y-% m-% d% এইচ:% এম:% এস।% 03 ডি% জেড'


-3

এখন হিসাবে নিম্নলিখিতটি অজগর 3 এর সাথে পুরোপুরি কাজ করে।

         logging.basicConfig(level=logging.DEBUG,
                     format='%(asctime)s %(levelname)-8s %(message)s',
                     datefmt='%Y/%m/%d %H:%M:%S.%03d',
                     filename=self.log_filepath,
                     filemode='w')

নিম্নলিখিত আউটপুট দেয়

2020/01/11 18: 51: 19.011 INFO


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