Python Hints
کانفیگ logging برای من همیشه اذیت کننده هست. بخش عمدهای از تسکهای من مربوط میشه به Deep learning, ML engineering اما وجه دیگه کارم backend هست و software engineer برای همین خیلی کم پیش میاد نیاز داشته باشم ی لاگر با جزئیات بنویسم از طرفی هم ۹۰٪ کدهایی…
این روش log نوشتن برای پروژه کوچک خوبه که تعداد
برای پروژه بزرگتر یا فریمورک و ابزارهای دیگه اصلا این روش توصیه نمیشه
چون امروز با یکی از نیروها بحث شد، قرار شد یک سمپل بهشون بدم
دیدم موضوع مهمی هست مخصوصاً بعد از اینکه به این پست اشاره کردند
گفتم بهتر توی کانال هم بصورت نوشتاری بذارم
سری پستهای این هفته در مورد
request
کمی هم داره، برای پروژه بزرگتر یا فریمورک و ابزارهای دیگه اصلا این روش توصیه نمیشه
چون امروز با یکی از نیروها بحث شد، قرار شد یک سمپل بهشون بدم
دیدم موضوع مهمی هست مخصوصاً بعد از اینکه به این پست اشاره کردند
گفتم بهتر توی کانال هم بصورت نوشتاری بذارم
سری پستهای این هفته در مورد
logging
خواهد بود.👍35😍4❤2🎉1
Python Hints
این روش log نوشتن برای پروژه کوچک خوبه که تعداد request کمی هم داره، برای پروژه بزرگتر یا فریمورک و ابزارهای دیگه اصلا این روش توصیه نمیشه چون امروز با یکی از نیروها بحث شد، قرار شد یک سمپل بهشون بدم دیدم موضوع مهمی هست مخصوصاً بعد از اینکه به این پست اشاره…
یکی از دوستان زنگ زد؛ میگه نمیشه زودتر بگی داستان چی هست دارم لاگر پروژه شرکت رو مینویسم؛
کل منبع صحبتهای این هفته :
Logging Cookbook, python documentation
این صحبتم که میگن داکیومنت خوبی نداره و ... هرکی گفت بهش بگید : چون درست نخوندی.
اگر شما هم مثل ای رفیق من خواستید زودتر شروع کنید به خوندن؛ توی داکیومنت بالا چندتا
قبلا صحبت شده راجب اولی؛ دومی هم برای
توی این ۳ مورد هم مورد اول داخل داکر بدرد بخور هست؛
معمولا خود من از این ۵ مورد توی پروژههای بزرگ استفاده میکنم؛ البته خیلی وقتا شرکتها
کل منبع صحبتهای این هفته :
Logging Cookbook, python documentation
این صحبتم که میگن داکیومنت خوبی نداره و ... هرکی گفت بهش بگید : چون درست نخوندی.
اگر شما هم مثل ای رفیق من خواستید زودتر شروع کنید به خوندن؛ توی داکیومنت بالا چندتا
log handler
رو حتما بهش توجه ویژه کنید.RotatingFileHandler, QueueHandler
قبلا صحبت شده راجب اولی؛ دومی هم برای
multi thread
کردن هست که لاگ نویسی باعث کند شدن پردازش نشه.StreamHandler, SMTPHandler, SocketHandler
توی این ۳ مورد هم مورد اول داخل داکر بدرد بخور هست؛
smpt
رو هم احتمالا حدس زدید برای ارسال ایمیل هست (معمولا لاگهای critical
رو برای خودمون یا ادمین یا ... ارسال میکنیم) و در نهایت هم SocketHandler
که برای ارسال لاگ با پروتکل tcp
به سرور دیگری استفاده میشه که خیلی خیلی مهم هست (باور ندارید از بچههای امنیت بپرسید)معمولا خود من از این ۵ مورد توی پروژههای بزرگ استفاده میکنم؛ البته خیلی وقتا شرکتها
SocketHandler
نمیگرین و براساس event
یا ساعتی یا ... بکاپ لاگ فایل رو به S3 bucket
میفرستند روی آمازون که هزینه کمتری داره برای نگهداری.Python documentation
Logging Cookbook
Author, Vinay Sajip <vinay_sajip at red-dove dot com>,. This page contains a number of recipes related to logging, which have been found useful in the past. For links to tutorial and reference info...
👍31❤🔥2
Python Hints
یکی از دوستان زنگ زد؛ میگه نمیشه زودتر بگی داستان چی هست دارم لاگر پروژه شرکت رو مینویسم؛ کل منبع صحبتهای این هفته : Logging Cookbook, python documentation این صحبتم که میگن داکیومنت خوبی نداره و ... هرکی گفت بهش بگید : چون درست نخوندی. اگر شما هم مثل…
#یادم_باشه
حتماً یادم باشه نوشتن
Log filter
کاستوم رو یاد بدم،
شرکت با یکی از شرکتهای خدمات دهنده اروپایی قرارداد بسته
و برای تست قرار شد، ۱ هفته یک کپی از دیتاهاشون رو بفرستند سمت log server ما.
شاید باورتون نشه، ولی تمامی شمارههای مشتریها بدون اینکه حتی بخشی از شمارهها مخفی بشه بصورت کامل داخل Json log ها هست.
یکی اینجا استفاده از logging رو بلد نبوده 😁
پ.ن : توی پستهای بعدی آموزش داده شد.
حتماً یادم باشه نوشتن
Log filter
کاستوم رو یاد بدم،
شرکت با یکی از شرکتهای خدمات دهنده اروپایی قرارداد بسته
و برای تست قرار شد، ۱ هفته یک کپی از دیتاهاشون رو بفرستند سمت log server ما.
شاید باورتون نشه، ولی تمامی شمارههای مشتریها بدون اینکه حتی بخشی از شمارهها مخفی بشه بصورت کامل داخل Json log ها هست.
یکی اینجا استفاده از logging رو بلد نبوده 😁
پ.ن : توی پستهای بعدی آموزش داده شد.
👍22🌚5😁3❤🔥1🤯1🆒1
با یک مثال خیلی ساده شروع کنیم تا مطلب جا بیوفته قشنگ؛ توجه کنید من توقع دارم کار با
اصلی ترین عنصر
وظیفهاش اینه که یک پیام از شما دریافت کنه و بر اساس
با این تعریف عنصر بعدی که راجبش صحبت میکنیم
وظیفهاش ارسال لاگ به مقصدی هست که براش تعریف شده.
اما ۲ مورد دیگه هم وجود داره که استفاده ازش میتونه زندگی رو بعدا براتون شیرین کنه:
اینکه چه اطلاعاتی توی لاگ فایل (علاوه بر پیام شما) بصورت خودکار قرار بگیره و اینکه این اطلاعات چطور نمایش داده بشه همش وظیفه این عزیز دل هست.
وظیفه فیلتر کردن لاگها رو داره؛ چه اینکه نوشته نشه یا تغییراتی روش انجام بشه و بعد نوشته بشه.
استیج آماده شد؛ بریم سراغ مثال تصویر
استفاده از
ادامه پست بعدی ....
logging
رو مقدماتش رو بلد باشید.اصلی ترین عنصر
logger
هست؛ اگر بخوام خیلی خلاصه بگم:وظیفهاش اینه که یک پیام از شما دریافت کنه و بر اساس
level
اون رو به handler
درستش ارسال کنه.با این تعریف عنصر بعدی که راجبش صحبت میکنیم
handler
هست.وظیفهاش ارسال لاگ به مقصدی هست که براش تعریف شده.
اما ۲ مورد دیگه هم وجود داره که استفاده ازش میتونه زندگی رو بعدا براتون شیرین کنه:
formatter
اینکه چه اطلاعاتی توی لاگ فایل (علاوه بر پیام شما) بصورت خودکار قرار بگیره و اینکه این اطلاعات چطور نمایش داده بشه همش وظیفه این عزیز دل هست.
filters
وظیفه فیلتر کردن لاگها رو داره؛ چه اینکه نوشته نشه یا تغییراتی روش انجام بشه و بعد نوشته بشه.
استیج آماده شد؛ بریم سراغ مثال تصویر
استفاده از
logging.basicConfig
چیزی نیست که برای پروژههای مهم و بزرگ بخواید داشته باشید؛ چون معمولا بیش از ۳ مورد handler
خواهید داشت که این یعنی تعداد زیادی logger
که هرکدوم formatter, filter
های خودشون رو خواهند داشت.ادامه پست بعدی ....
👍39❤🔥8🤔2❤1
Python Hints
با یک مثال خیلی ساده شروع کنیم تا مطلب جا بیوفته قشنگ؛ توجه کنید من توقع دارم کار با logging رو مقدماتش رو بلد باشید. اصلی ترین عنصر logger هست؛ اگر بخوام خیلی خلاصه بگم: وظیفهاش اینه که یک پیام از شما دریافت کنه و بر اساس level اون رو به handler درستش…
log_config.py
1 KB
source code
👍31❤5
Python Hints
با یک مثال خیلی ساده شروع کنیم تا مطلب جا بیوفته قشنگ؛ توجه کنید من توقع دارم کار با logging رو مقدماتش رو بلد باشید. اصلی ترین عنصر logger هست؛ اگر بخوام خیلی خلاصه بگم: وظیفهاش اینه که یک پیام از شما دریافت کنه و بر اساس level اون رو به handler درستش…
برای همین گزینه بهتر استفاده از
همینجا بگم؛ توی سورس کدهای مختلف ممکن هست که این کانفیگها (دیکشنری) رو توی فایلهای
اول از همه
موارد بعدی یعنی
و اما
مورد بعدی
ولی داستان
اولش چیه پس ؟ هیجی فقط بهش میگه که این مورد رو از یک ماژول
در نهایت
کلید بعدی یعنی
حالا فقط کافیه توی کل پروژه یکبار این تابع صدا زده بشه تا
خط 32 اما خیلی مهمه دارم میگم برو ی لاگر برام بیار اسمش رو بذار
اینجا
من سعی کردم خیلی ساده توضیح بدم؛ تا همه این موارد رو متوجه بشوند (این رو درک کنید و البته جایگاه هرکدوم رو)
امیدوارم مفید باشه. 🌹
logging.config.dictConfig
هست؛ این تابع تنظیمات رو بصورت dictionary
از شما تحویل میگیره و logger رو برای شما میسازه.همینجا بگم؛ توی سورس کدهای مختلف ممکن هست که این کانفیگها (دیکشنری) رو توی فایلهای
json, yaml, ini
نوشته باشند؛ اما شخصا موقع نوشتن کد سعی میکنم مستقیم اینکار رو انجام بدم (داخل py
). دروغ چرا مغزم رو درگیر حفظ کردن کلیدهای دیکشنری نمیکنم و اینطوری خود vscode
کلیدهای موجود رو بهم میده اما راجب config
مثال بالا که خیلی خیلی ساده هم هست.اول از همه
version
فعلا فقط 1
وجود داره (ورژن دیگه اومد همدیگر رو خبر میکنیم)؛ disable_exisiting_logger
اگر True
بذارید هر لاگر دیگهای که توی این کانفیگ نیست غیرفعال میشه ۹۹٪
موارد روی False
بذارید.موارد بعدی یعنی
filters, formatters
رو برای این مثال کاری نداریم (ساده شروع کنیم و کم کم بهش برسیم).و اما
handlers
؛ اولین چیزی که براش لازم هست اسمش میشه (باید بدونیم چی صداش کنیم) که توی مثال بالا من اسمش رو گذاشتم console
چون قراره لاگ هارو توی ترمینال نمایش بده؛ توی خط بعدی یک کلید داره به اسم 'class'
اگر قرار بود از Handler
هایی که خود ماژول logging
یا ماژولهای دیگه براتون فراهم میکنند استفاده کنید از کلیدواژه 'class'
استفاده میشه و مقداری که بهش میدید کلاسی از اون ماژول هست و باید قابل import
باشه توی این مثال من StreamHandler
رو استفاده کردم یعنی شما میتونید ی جایی تست کنید :from logging import StreamHandler
مورد بعدی
stream
این کلید ثابت نیست؛ دلیلش هم واضح هست (حداقل برای من) هر کلاس یک سری پارامتر ورودی مختص به خودش داره StreamHandler
هم توی ورودی میتونه یک کلید به اسم stream
دریافت کنه که البته optional هست؛ یعنی حتی اگه توی مثال بالا این خط کانفیگ رو پاک کنید بازم کار میکنه ولی بصورت دیفالت مقدارش روی sys.stderr
تعریف شده که تحت شرایطی ممکنه نخواهید اینطوری باشه پس میتونید تغییرش بدید. که من گفتم از ماژول sys
و stdout
یا همون standard output
استفاده کنه و خروجی اینجا نمایش بده ( اگر فرق stdout
, stderr
رو نمیدونید؛ ی ذره لینوکس بخونید )ولی داستان
ext://
اولش چیه پس ؟ هیجی فقط بهش میگه که این مورد رو از یک ماژول
external
باید بگیری (لازم بود برو import
کن).در نهایت
logger
؛ مثل مورد قبل اولین مورد اسم هست این اسم مثل handler
دلبخواهی نیست؛ و بهتر اسم بالاترین سطح پوشهای باشه که این لاگر براش تعریف میشه؛ من اسم پروژهام رو گذاشتم pyhints
و این پوشه رو تبدیل به یک ماژول / پکیج کردم و میخوام برای تمام py
فایلهای داخلش از این logger
بتونم استفاده کنم. برای همین هم اسم logger
ام رو pyhints
گذاشتم. توی ساده ترین حالت شما نیاز به دوتا کلید دارید؛ اولیش level
که من اینجا گفتم مثلا از یک فایل .env
پروژه میخونم (پیادهسازیش تمرین برای شما) و اگر توی محیط develop
نبودم نمیخوام لاگهای debug
دیده بشه فقط از info
به بالا رو قبول کن.کلید بعدی یعنی
handlers
لیستی از handler
هارو میگیره و اگر یک لاگ مسیج هر دو شرایط رو داشت (هم از پکیج pyhints
بود؛ هم level
بالاتر از آنچه توی خط قبل تعریف شده داشت) اون موقع اون پیام رو برای handler
ها میفرسته تا کار درست رو باهاش انجام بدند.حالا فقط کافیه توی کل پروژه یکبار این تابع صدا زده بشه تا
logger
ما تنظیمات اختصاصی خودش رو دریافت کنه؛ اتفاقی که توی مثال بالا توی خط 30
داره میوفته.خط 32 اما خیلی مهمه دارم میگم برو ی لاگر برام بیار اسمش رو بذار
pyhints.log_config
اینجا به عمد ی همچین اسمی دادم تا نشون بدم چقدر اسمی که برای logger
انتخاب میکنید مهم هست؛ اما توی کدها و پروژههاتون از __name__
استفاده میکنید ( درصورت import
همین فرمت اسم رو میسازه که من بهش دستی دادم).اینجا
logging
نگاه میکنه که کانفیگ اختصاصی داریم که logger
ایی به اسم pyhints
داخلش تعریف شده و ماهم توی درخواست getLogger
اسمی دادیم که اگر با .
جداسازی بشه pyhints
بخش بالاتر هست پس این دو مورد باهم مچ میشه و میتونه از این لاگر خاص برای اسکریپت فعلی استفاده کنه حالا متغییر logger
از تنظیمات pyhints.logger
استفاده خواهد کرد برای نمایش log messages
داخل ترمینال. من سعی کردم خیلی ساده توضیح بدم؛ تا همه این موارد رو متوجه بشوند (این رو درک کنید و البته جایگاه هرکدوم رو)
۷۰٪
کار حله.امیدوارم مفید باشه. 🌹
👍40❤🔥11👏1🆒1
Python Hints
برای همین گزینه بهتر استفاده از logging.config.dictConfig هست؛ این تابع تنظیمات رو بصورت dictionary از شما تحویل میگیره و logger رو برای شما میسازه. همینجا بگم؛ توی سورس کدهای مختلف ممکن هست که این کانفیگها (دیکشنری) رو توی فایلهای json, yaml, ini نوشته…
نکته بعدی تنظیم
برای مثال توی این کد (ادامه کد قبلی) من یک فرمتر استاندارید اضافه کردم.
همیشه سعی میکنم توی فرمترهایی که مینویسم چندتا فیلد رو داشته باشم :
اون 10s بغلش برای اینه که میخوام حتما اندازه ۱۰ کاراکتر فضا داشته باشه حداقل توی
باید بدونیم وضعیت لاگ چطوری هست؛ لاگ
برای اینه که بدونیم لاگ از کدوم اسکریپت اومده؛ راحتی خودمون هست.
این مورد رو توی کدهای نیروهام نبینم؛
داستان اینه که ترکیب این مورد و اسم فایل من رو دقیقا میبرم روی تابع / متد یا ... ایی که باعث خطا شده.
اصل جنس هم اینجاس پیامی که باید ارسال بشه
باقی موارد هم برای قشنگیش هست.
اما چرا دروغ؛ شمارو نمیدونم من چشمام اینطوری اذیت میشه یک سری لاگ سفید روی پس زمینه سیاه خوندنش برام سخت هست.
formatters
هست؛ همیشه سعی میکنیم ساده شروع کنیم.برای مثال توی این کد (ادامه کد قبلی) من یک فرمتر استاندارید اضافه کردم.
همیشه سعی میکنم توی فرمترهایی که مینویسم چندتا فیلد رو داشته باشم :
1- asctime
اون 10s بغلش برای اینه که میخوام حتما اندازه ۱۰ کاراکتر فضا داشته باشه حداقل توی
levelname
بهتر خودشو نشون میده2- levelname
باید بدونیم وضعیت لاگ چطوری هست؛ لاگ
debug, info
چیزی نیست که روزانه بخواید چشمتون بهش باشه3- name
برای اینه که بدونیم لاگ از کدوم اسکریپت اومده؛ راحتی خودمون هست.
4- lineno
این مورد رو توی کدهای نیروهام نبینم؛
merge
نمیشه داستان اینه که ترکیب این مورد و اسم فایل من رو دقیقا میبرم روی تابع / متد یا ... ایی که باعث خطا شده.
5- message
اصل جنس هم اینجاس پیامی که باید ارسال بشه
باقی موارد هم برای قشنگیش هست.
اما چرا دروغ؛ شمارو نمیدونم من چشمام اینطوری اذیت میشه یک سری لاگ سفید روی پس زمینه سیاه خوندنش برام سخت هست.
👍30❤🔥4🫡2❤1🍓1
Python Hints
نکته بعدی تنظیم formatters هست؛ همیشه سعی میکنیم ساده شروع کنیم. برای مثال توی این کد (ادامه کد قبلی) من یک فرمتر استاندارید اضافه کردم. همیشه سعی میکنم توی فرمترهایی که مینویسم چندتا فیلد رو داشته باشم : 1- asctime اون 10s بغلش برای اینه که میخوام حتما…
از
مهمترین بخشش اما توی
رو زدم و به
تصویر خروجی رو اگر بازکنید و نگاه کنید:
۱- بر اساس زمان گروه بندی شده لاگها
۲- سطح لاگ قبل پیام بصورت رنگی نوشته شده
۳- باقی موارد هم رنگی شده که توی کنسول خوندن و پیدا کردنش راحت تر هست.
البته من فقط طرفدار ۲ مورد اول هستم توی
formatter
استفاده کنیم؛ همیشه خوبه که class
رو تعریف کنیم واجب نیست اما اگر نیرویی توی تیم باشه که اون کلاس رو نشناسه اینطوری میدونه کجا میتونه پارامترهاش رو بخونه (شمارو نمیدونم ولی من هیچوقت پارامتر حفظ نمیکنم). بعد از اون اومد از datefmt
استفاده کردمم تا فرمت استانداردی که ابزار مانیتورینگ باهاش کار میکنه رو بهش بدم در نهایت هم کلید levelname
رو حذف کردم.مهمترین بخشش اما توی
handler
هست.pip install rich
رو زدم و به
console handler
گفتم از کلاس rich.logging.RichHandler
استفاده کنه (میتونستم خودمم بنویسم ولی rich
محبوبه و موجودم هست).تصویر خروجی رو اگر بازکنید و نگاه کنید:
۱- بر اساس زمان گروه بندی شده لاگها
۲- سطح لاگ قبل پیام بصورت رنگی نوشته شده
۳- باقی موارد هم رنگی شده که توی کنسول خوندن و پیدا کردنش راحت تر هست.
البته من فقط طرفدار ۲ مورد اول هستم توی
rich
و بنظرم مورد سوم خیلی جنگولک هست ولی خب.👍31❤🔥4🫡2❤1
Python Hints
از formatter استفاده کنیم؛ همیشه خوبه که class رو تعریف کنیم واجب نیست اما اگر نیرویی توی تیم باشه که اون کلاس رو نشناسه اینطوری میدونه کجا میتونه پارامترهاش رو بخونه (شمارو نمیدونم ولی من هیچوقت پارامتر حفظ نمیکنم). بعد از اون اومد از datefmt استفاده…
تیمهای مختلف از ابزارهای مختلفی برای بررسی و خوندن لاگ استفاده میکنند؛ حتی ممکنه توی یک شرکت توی بخشهای مختلف از ابزارهای مختلف استفاده بشه (اتفاقی که برای ما وجود داره)
برای همین یک استاندارد مشترک باید وجود داشته باشه؛ لاگهای تیم من بخشهای بیشتری رو لازم داره و کانفیگ میکنه اما لاگ های تجهیزات
پس زبان مشترک همه ما میشه
برای اینکار توی پایتون یک پکیج از قبل نوشته شده پس ابتدا :
توی کد بالا توی بخش
به عمد اینکارو کردم که ببینید به اسم نیست؛ به عکلکرد و چیدمان هست.
ی درخواست لاگ وقتی توی کد ارسال میشه؛ اول از همه میرسه به
بعد بررسی سطح لاگ
برای همین یک استاندارد مشترک باید وجود داشته باشه؛ لاگهای تیم من بخشهای بیشتری رو لازم داره و کانفیگ میکنه اما لاگ های تجهیزات
iot
ممکنه اینطور نباشه یا لاگهای سرور.پس زبان مشترک همه ما میشه
jsonl
هر خط لاگ یک json
کامل هست اینطوری حداقل کلیدهای لازم رو باید داشته باشیم و هر تیم کلیدهای ابزار مانیتورینگ خودش رو هم میتونه اضافه کنه و هیچ ابزاری توی خوندنش به مشکل نمیخوره.برای اینکار توی پایتون یک پکیج از قبل نوشته شده پس ابتدا :
pip install python-json-logger
توی کد بالا توی بخش
formatters
یک کلید جدید استفاده شده من اسمش رو گذاشتم file
ولی فعلا برای نمایش دارم اون رو به console handler
میفرستم.به عمد اینکارو کردم که ببینید به اسم نیست؛ به عکلکرد و چیدمان هست.
ی درخواست لاگ وقتی توی کد ارسال میشه؛ اول از همه میرسه به
loggers
گه اگر از داخل پوشه پروژه pyhints
باشه این بخش مسئول هندل کردنش هست.بعد بررسی سطح لاگ
👍32❤🔥2🫡2❤1⚡1🆒1
Python Hints
تیمهای مختلف از ابزارهای مختلفی برای بررسی و خوندن لاگ استفاده میکنند؛ حتی ممکنه توی یک شرکت توی بخشهای مختلف از ابزارهای مختلف استفاده بشه (اتفاقی که برای ما وجود داره) برای همین یک استاندارد مشترک باید وجود داشته باشه؛ لاگهای تیم من بخشهای بیشتری رو…
تنها هندلر تعریف شده براش چون
استفاده میکنه من بازم فرمت
یعنی تا هزارم میلی ٍثانیه رو هم اضافه کردم.
خط آخر یعنی
لیست کامل این موارد رو روی داکیو.منت
توی مثال بعدی
همون باگی که گفتم دولوپرهای اون شرکت داشتند.
console
هست درخواست به handlers
و console
ارسال میشه و اینجا کلاس تعریف شده براش rich
هست (برای همین خروجی توی کنسول همچنان رنگی هست) و برای فرمت لاگ handlers
درخواست رو باید برای formatters
و بطور خاص file
ارسال کنه. قشنگی داستان اینجاس که file
از کلاس
pythonjsonlogger.jsonlogger.JsonFormatter
استفاده میکنه من بازم فرمت
datetime
رو استاندارد کردم و فرض کردم تعداد درخواست های به سرورم زیاد و در حد هزارم میلیثانیه هست برای همین %(msecs)03d
یعنی تا هزارم میلی ٍثانیه رو هم اضافه کردم.
خط آخر یعنی
format
خیلی باشعور هست python-json-logger
میگه تو فقط به من بگو چی رو لاگ بندازم فرمت معنی نداره من از اون مقدار بعنوان key
استفاده خواهم کرد؛ و چیزی که برای اون میاد رو value
در نظر میگیرم.لیست کامل این موارد رو روی داکیو.منت
logging
میتونید بخونید و حتی میتونید format
خودتون رو هم تعریف کنید (مثلا شماره موبایل رو جدا بگیره) اما حواستون باشه حتما باید json serializable
باشه.توی مثال بعدی
fileRotate
رو میگم که بسیار استفاده میشه؛ و بعد هم یکم کاستوم کلاس برای فیلتر مینویسیم که شماره موبایل اگر توی لاگ بود بصورت کامل نمایش داده نشه همون باگی که گفتم دولوپرهای اون شرکت داشتند.
👍35❤🔥2🫡2❤1
Python Hints
تنها هندلر تعریف شده براش چون console هست درخواست به handlers و console ارسال میشه و اینجا کلاس تعریف شده براش rich هست (برای همین خروجی توی کنسول همچنان رنگی هست) و برای فرمت لاگ handlers درخواست رو باید برای formatters و بطور خاص file ارسال کنه. قشنگی داستان…
ازینجا به بعدش رو دوس دارم (الان در سطح مدیور این پکیج رو میشناسید.)
اولین حرکت؛ به
کنسول رو همیشه نگه میداریم برای داکر که راحت باشیم؛ فایل رو برای شرکتهای قدیمیتر که بکاپ زمانی یا توی مثال بر اساس حجم نگه میدارند.
تغییر بعدی که داره اضافه شدن
اول از همه؛ گفتم کلاسش باید
باشه؛ جلوتر میگم معنی
توی خط بعدی بهش گفتم که فقط لاگهای سطح
اسم لاگ فایل رو گفتم
و اما ۲ خط بعدی؛ وقتی از
اولین حرکت؛ به
pyhinst logger
گفتم اگر درخواست log
برات اومد. باید برای دوتا هندلر بفرستی؛1- console
2- file
کنسول رو همیشه نگه میداریم برای داکر که راحت باشیم؛ فایل رو برای شرکتهای قدیمیتر که بکاپ زمانی یا توی مثال بر اساس حجم نگه میدارند.
تغییر بعدی که داره اضافه شدن
file
به handlers
هست.اول از همه؛ گفتم کلاسش باید
logging.handlers.RotatingFileHan
dler
باشه؛ جلوتر میگم معنی
Rotate File
چی هست (قبلا هم مثال زده بودم البته)توی خط بعدی بهش گفتم که فقط لاگهای سطح
warning
یا بالاتر رو توی فایل بنویسه و برای formatter
هم همون jsonl
رو استفاده کنه.اسم لاگ فایل رو گفتم
pyhints.log
بذاره (تبلیفات نداریم دیگه)و اما ۲ خط بعدی؛ وقتی از
log rotate
حرف میزنیم باید براش ی محدودیت بذاریم اینجا من گفتم بر اساس سایز باشه maxBytes
روی 10mb
یعنی اینکه اگر حجم فایل pyhints.log
به 10mb رسید اسم فایل رو عوض کن (معمولا ی عدد به آخرش اضافه میکنه مثلا pyhinst.log.1
) و این فایل رو کنار بذار و یک فایل جدید شروع کن دوباره به اسم pyhints.log
.❤12👍9❤🔥3🫡1
Python Hints
ازینجا به بعدش رو دوس دارم (الان در سطح مدیور این پکیج رو میشناسید.) اولین حرکت؛ به pyhinst logger گفتم اگر درخواست log برات اومد. باید برای دوتا هندلر بفرستی؛ 1- console 2- file کنسول رو همیشه نگه میداریم برای داکر که راحت باشیم؛ فایل رو برای شرکتهای قدیمیتر…
اما خب شاید بگید چقدر از این فایلهای
یک کانفیگ اشتباه اینجا میتونه هارد سرور رو به راحتی پر کنه (این اتفاق هم میوفته)
پس توی خط بعدی بهش
هیچی قدیمی ترین فایل لاگ حذف میشه تا لاگ جدید نوشته بشه؛ یعنی توی این مثال وقتی
در نهایت هم
ولی وقتی کدها ممکنه دست افراد و تیم بینالمللی و چندزبانی بیوفته شخصا ترجیخ میدم دیفالت رو بذارم؛ اینجوری مثلا اگر دست یک شرکت چینی هم بدم کدهام رو اونها میدونند درصورت نیاز کجای کد رو باید تغییر بدهند و
پس این یعنی دردسر کمتر
و چه بهتر که وجود داشته باشه این دیفالت.
10mb
درست میکنه ؟یک کانفیگ اشتباه اینجا میتونه هارد سرور رو به راحتی پر کنه (این اتفاق هم میوفته)
پس توی خط بعدی بهش
backupCount
میدم؛ و اینجا بهش گفتم 10 تا ازون فایلهای 10mb
رو میتونی نهایتا نگهداری کنی؛ سوال: بعد از ۱۰ تا چی میشه ؟ هیچی قدیمی ترین فایل لاگ حذف میشه تا لاگ جدید نوشته بشه؛ یعنی توی این مثال وقتی
pyhinst.log.10
ساخته شد دفعه بعدی که قرار باشه فایل نوشته بشه pyhints.log.1
حذف میشه و بار بعدی pyhints.log.2
و این چرخه تا لازم باشه تکرار میشه.در نهایت هم
encoding: utf8
خیلیها میگن من حساس هستم و نیاز نیست و ... حق هم میدم بهشون.ولی وقتی کدها ممکنه دست افراد و تیم بینالمللی و چندزبانی بیوفته شخصا ترجیخ میدم دیفالت رو بذارم؛ اینجوری مثلا اگر دست یک شرکت چینی هم بدم کدهام رو اونها میدونند درصورت نیاز کجای کد رو باید تغییر بدهند و
utf16
بذارند و ...پس این یعنی دردسر کمتر
و چه بهتر که وجود داشته باشه این دیفالت.
👍20❤4❤🔥2🫡1
Python Hints
اما خب شاید بگید چقدر از این فایلهای 10mb درست میکنه ؟ یک کانفیگ اشتباه اینجا میتونه هارد سرور رو به راحتی پر کنه (این اتفاق هم میوفته) پس توی خط بعدی بهش backupCount میدم؛ و اینجا بهش گفتم 10 تا ازون فایلهای 10mb رو میتونی نهایتا نگهداری کنی؛ سوال: بعد…
اینم یک مثال (شروع سطح سنیور کار با logging)
مثال آخر.
اولین نکته؛
خط ۷ تا ۱۸ من یک کلاس فلیتر تعریف کردم که قرار اگر توی لاگ رکورد چیزی به اسم
اگر لاگ رو برای دیتاساینس و .. میخواید بفرستید و شماره همراه مهم هست میتونید اونو با
توجه کنید این کلاس فقط ی متغییر مهم داده
اگر متوجه نشدید بریم روی خط 26 جایی که برای اولین بار دارید
مثال آخر.
اولین نکته؛
environment = "production"
خط ۷ تا ۱۸ من یک کلاس فلیتر تعریف کردم که قرار اگر توی لاگ رکورد چیزی به اسم
phone
وجود داشت بخش اول اون رو با *
بپوشونه و بصورت دیفالت فقط ۴ رقم آخر رو نشون بده.اگر لاگ رو برای دیتاساینس و .. میخواید بفرستید و شماره همراه مهم هست میتونید اونو با
hash
یا ... که unique
باشه برای هر شماره موبایل جایگزین کنید. اینطوری تیم دیتا میتونه کارهاش رو انجام بده و میدونه که یوزر چیکار داره میکنه اما هیچوقت نمیدونه اون یوزر کی هست duckduckgo
و شرکتهای vpn
و ... که تاییدیه عدم افشای هویت دارند هم از تکنیک مشابه برای recommendation
, ... استفاده میکنند؛ برگردیم سراغ کار خودمون.توجه کنید این کلاس فقط ی متغییر مهم داده
display_digits
لازم نبود ولی گذاشتم که یاد پست اول این موضوع بیوفتید که گفتم هرچیزی بعد از کلاس argument
های اون کلاس هست.اگر متوجه نشدید بریم روی خط 26 جایی که برای اولین بار دارید
filters
رو میبینید اولین مورد که اسمش هست hide_phone
چون کلاسی که استفاده کردم کاستوم و داخل پروژه و همین فایل هست.❤🔥13👍9❤1🫡1
Python Hints
اینم یک مثال (شروع سطح سنیور کار با logging) مثال آخر. اولین نکته؛ environment = "production" خط ۷ تا ۱۸ من یک کلاس فلیتر تعریف کردم که قرار اگر توی لاگ رکورد چیزی به اسم phone وجود داشت بخش اول اون رو با * بپوشونه و بصورت دیفالت فقط ۴ رقم آخر رو نشون بده.…
بنابراین بجای کلید
و همونطور که قبلا هم گفتم هر چیزی که بعد از این بیاد ورودیهایی هست که اون کلاس قبول میکنه؛ من اینجا گفتم اگر توی
حالا فقط کافیه
سوال : چطوری phone رو به
خط ۷۵ رو ببینید؛ وقتی یک کلیدی داریم که بصورت دیفالت روی
خروجی میشه چیزی که توی تصویر میبینید.
class
از ()
استفاده میشه.و همونطور که قبلا هم گفتم هر چیزی که بعد از این بیاد ورودیهایی هست که اون کلاس قبول میکنه؛ من اینجا گفتم اگر توی
dev
نبودم فقط ۴ کاراکتر آخر شماره تلفن رو نشون بده ولی اگر روی dev
بودم ۱۰ تاش رو نشون بده.حالا فقط کافیه
filter
ایی که تعریف کردم رو به هرکدوم از handler
هایی که لازم هست پاس بدم که توی خط 57 دارم اینکار رو برای file handler
انجام میدم.سوال : چطوری phone رو به
logRecord
اضافه کنیم ؟خط ۷۵ رو ببینید؛ وقتی یک کلیدی داریم که بصورت دیفالت روی
logger
تعریف نشده؛ راه قشنگش اینه که اون رو توی extra
برای logger
های مورد نظر ارسال کنیم:logger.critical("Call meeeeeeee", extra={"phone": "09121212122"})
خروجی میشه چیزی که توی تصویر میبینید.
👍14❤🔥5❤2🫡1
Python Hints
بنابراین بجای کلید class از () استفاده میشه. و همونطور که قبلا هم گفتم هر چیزی که بعد از این بیاد ورودیهایی هست که اون کلاس قبول میکنه؛ من اینجا گفتم اگر توی dev نبودم فقط ۴ کاراکتر آخر شماره تلفن رو نشون بده ولی اگر روی dev بودم ۱۰ تاش رو نشون بده. حالا…
در نهایت باید اشاره به یک موضوع دیگه هم بکنم (یادم نیست قبلا گفتم یا نه)
خط ۷۲ یک اشتباه؛ یا
هیچوقت توی
اینجوری وقتی دارید از logger توی پروژه استفاده میکنید با توجه به اسم پوشه پروژه
خواهشا همیشه؛
رو اول اسکریپت بذارید؛ من فقط برای نمایش دمو خط ۷۲ به بعد رو توی این فایل و بدین صورت گذاشتم.
خط ۷۲ یک اشتباه؛ یا
bad practice
هست من برای اینکه بتونم دمو بدم اینکار رو کردمlogging.getLogger("pyhints.log_config")
هیچوقت توی
getLogger
اسم رو بصورت دستی نمیدیم راهکار درست:logging.getLogger(__name__)
اینجوری وقتی دارید از logger توی پروژه استفاده میکنید با توجه به اسم پوشه پروژه
logger
درست صدا زده میشه و هیچوقت هم لازم نیست یادتون بمونه کدوم logger
رو کی و کجا با چه اسمی راه اندازی کردید.خواهشا همیشه؛
logger = logging.getLogger(__name__)
رو اول اسکریپت بذارید؛ من فقط برای نمایش دمو خط ۷۲ به بعد رو توی این فایل و بدین صورت گذاشتم.
👍19❤🔥5❤3🫡2
نوروز این زیباترین جشن ایرانی پیشاپیش بر همگان مبارک.
توی سال جدید
برای وطنم ایران؛ آرزوی آزادی آزادی آزادی و آبادی دارم.
برای مردمم و خودم؛ آرزوی آگاهی آگاهی آگاهی و سلامتی و شادابی دارم.
یادی هم بکنیم از همهی بچههای پاک وطن که به جرم دادخواهی؛ آزادی و آگاهی شکنجه یا کشته شدند.
سالی سراسر آزادی؛ آگاهی و شادابی رو برای همگی آرزو می کنم.
منبع تصویر، گوگل سرچ.
توی سال جدید
برای وطنم ایران؛ آرزوی آزادی آزادی آزادی و آبادی دارم.
برای مردمم و خودم؛ آرزوی آگاهی آگاهی آگاهی و سلامتی و شادابی دارم.
یادی هم بکنیم از همهی بچههای پاک وطن که به جرم دادخواهی؛ آزادی و آگاهی شکنجه یا کشته شدند.
سالی سراسر آزادی؛ آگاهی و شادابی رو برای همگی آرزو می کنم.
منبع تصویر، گوگل سرچ.
❤82🍾5❤🔥3👍2😁2🤷♀1👎1🎉1👌1
لطفاً پیامهای پین شده کانال رو بطور کامل نگاه کنید، قبل از هرگونه سوال و جواب : 🌹
زحمت این پست رو یکی از اعضا کشیدند 🌹
logging :
https://t.iss.one/pyHints/446
https://t.iss.one/pyHints/81
https://t.iss.one/pyHints/127
Dunder methods
https://t.iss.one/pyHints/12
https://t.iss.one/pyHints/14
https://t.iss.one/pyHints/20
https://t.iss.one/pyHints/29
https://t.iss.one/pyHints/43
https://t.iss.one/pyHints/320
Cache
https://t.iss.one/pyHints/30
https://t.iss.one/pyHints/33
https://t.iss.one/pyHints/107
Linux:
https://t.iss.one/pyHints/401
https://t.iss.one/pyHints/258
https://t.iss.one/pyHints/271
https://t.iss.one/pyHints/273
https://t.iss.one/pyHints/347
https://t.iss.one/pyHints/401
Data structer in python:
https://t.iss.one/pyHints/15
https://t.iss.one/pyHints/64
https://t.iss.one/pyHints/115
https://t.iss.one/pyHints/283
https://t.iss.one/pyHints/294
https://t.iss.one/pyHints/373
https://t.iss.one/pyHints/408
Exception :
https://t.iss.one/pyHints/56
https://t.iss.one/pyHints/57
https://t.iss.one/pyHints/58
https://t.iss.one/pyHints/60
https://t.iss.one/pyHints/77
https://t.iss.one/pyHints/367
Dis-Disassembler for Python bytecode:
https://t.iss.one/pyHints/96
https://t.iss.one/pyHints/99
Async:
https://t.iss.one/pyHints/117
https://t.iss.one/pyHints/137
https://t.iss.one/pyHints/150
Profiling:
https://t.iss.one/pyHints/148
https://t.iss.one/pyHints/109
https://t.iss.one/pyHints/146
https://t.iss.one/pyHints/277
https://t.iss.one/pyHints/279
https://t.iss.one/pyHints/280
https://t.iss.one/pyHints/288
decorator:
https://t.iss.one/pyHints/37
https://t.iss.one/pyHints/41
https://t.iss.one/pyHints/47
Duck tpye & dynamic protocl:
https://t.iss.one/pyHints/328
https://t.iss.one/pyHints/331
https://t.iss.one/pyHints/336
https://t.iss.one/pyHints/338
Book &roadmap &video :
https://t.iss.one/pyHints/16
https://t.iss.one/pyHints/101
https://t.iss.one/pyHints/123
https://t.iss.one/pyHints/168
https://t.iss.one/pyHints/194
https://t.iss.one/pyHints/196
https://t.iss.one/pyHints/210
https://t.iss.one/pyHints/223
https://t.iss.one/pyHints/231
Income:
https://t.iss.one/pyHints/50
https://t.iss.one/pyHints/87
https://t.iss.one/pyHints/394
Package management:
https://t.iss.one/pyHints/73
https://t.iss.one/pyHints/402
Experiments:
https://t.iss.one/pyHints/85
https://t.iss.one/pyHints/93
https://t.iss.one/pyHints/108
Standard file for software and backend developers:
https://t.iss.one/pyHints/178
https://t.iss.one/pyHints/180
https://t.iss.one/pyHints/181
https://t.iss.one/pyHints/186
https://t.iss.one/pyHints/190
Other important post:
https://t.iss.one/pyHints/111
https://t.iss.one/pyHints/27
#summary #all_in_one_1402
زحمت این پست رو یکی از اعضا کشیدند 🌹
logging :
https://t.iss.one/pyHints/446
https://t.iss.one/pyHints/81
https://t.iss.one/pyHints/127
Dunder methods
https://t.iss.one/pyHints/12
https://t.iss.one/pyHints/14
https://t.iss.one/pyHints/20
https://t.iss.one/pyHints/29
https://t.iss.one/pyHints/43
https://t.iss.one/pyHints/320
Cache
https://t.iss.one/pyHints/30
https://t.iss.one/pyHints/33
https://t.iss.one/pyHints/107
Linux:
https://t.iss.one/pyHints/401
https://t.iss.one/pyHints/258
https://t.iss.one/pyHints/271
https://t.iss.one/pyHints/273
https://t.iss.one/pyHints/347
https://t.iss.one/pyHints/401
Data structer in python:
https://t.iss.one/pyHints/15
https://t.iss.one/pyHints/64
https://t.iss.one/pyHints/115
https://t.iss.one/pyHints/283
https://t.iss.one/pyHints/294
https://t.iss.one/pyHints/373
https://t.iss.one/pyHints/408
Exception :
https://t.iss.one/pyHints/56
https://t.iss.one/pyHints/57
https://t.iss.one/pyHints/58
https://t.iss.one/pyHints/60
https://t.iss.one/pyHints/77
https://t.iss.one/pyHints/367
Dis-Disassembler for Python bytecode:
https://t.iss.one/pyHints/96
https://t.iss.one/pyHints/99
Async:
https://t.iss.one/pyHints/117
https://t.iss.one/pyHints/137
https://t.iss.one/pyHints/150
Profiling:
https://t.iss.one/pyHints/148
https://t.iss.one/pyHints/109
https://t.iss.one/pyHints/146
https://t.iss.one/pyHints/277
https://t.iss.one/pyHints/279
https://t.iss.one/pyHints/280
https://t.iss.one/pyHints/288
decorator:
https://t.iss.one/pyHints/37
https://t.iss.one/pyHints/41
https://t.iss.one/pyHints/47
Duck tpye & dynamic protocl:
https://t.iss.one/pyHints/328
https://t.iss.one/pyHints/331
https://t.iss.one/pyHints/336
https://t.iss.one/pyHints/338
Book &roadmap &video :
https://t.iss.one/pyHints/16
https://t.iss.one/pyHints/101
https://t.iss.one/pyHints/123
https://t.iss.one/pyHints/168
https://t.iss.one/pyHints/194
https://t.iss.one/pyHints/196
https://t.iss.one/pyHints/210
https://t.iss.one/pyHints/223
https://t.iss.one/pyHints/231
Income:
https://t.iss.one/pyHints/50
https://t.iss.one/pyHints/87
https://t.iss.one/pyHints/394
Package management:
https://t.iss.one/pyHints/73
https://t.iss.one/pyHints/402
Experiments:
https://t.iss.one/pyHints/85
https://t.iss.one/pyHints/93
https://t.iss.one/pyHints/108
Standard file for software and backend developers:
https://t.iss.one/pyHints/178
https://t.iss.one/pyHints/180
https://t.iss.one/pyHints/181
https://t.iss.one/pyHints/186
https://t.iss.one/pyHints/190
Other important post:
https://t.iss.one/pyHints/111
https://t.iss.one/pyHints/27
#summary #all_in_one_1402
😍80❤31👍20🙏4🎉3❤🔥1👏1