Gunicorn: تنسيق تاريخ تسجيل الخطأ الافتراضي من Gunicorn ليس معيار ISO8601

تم إنشاؤها على ٣ مايو ٢٠١٨  ·  34تعليقات  ·  مصدر: benoitc/gunicorn

https://github.com/benoitc/gunicorn/blob/e73ca252f7e1d0286998a0ae4254164291020a0c/gunicorn/glogging.py#L88

الدافع وراء هذه المشكلة هو بيان grok التالي في logstash:

grok { match => { "message" => "\[(?<gunicorn.time>%{YEAR}-%{MONTHNUM}-%{MONTHDAY}[T ]%{HOUR}:?%{MINUTE}(?::?%{SECOND})? %{ISO8601_TIMEZONE})\] \[%{NUMBER:[gunicorn][worker_id]}\] \[%{LOGLEVEL:[gunicorn][level]}\] %{GREEDYDATA:[gunicorn][message]}" } remove_field => "message" }

لو لم يتضمن تنسيق التاريخ أي مسافة بين الوقت والمنطقة الزمنية ، لكان البيان التالي لقطعه:

grok { match => { "message" => "\[%{TIMESTAMP_ISO8601:[gunicorn][time]}\] \[%{NUMBER:[gunicorn][worker_id]}\] \[%{LOGLEVEL:[gunicorn][level]}\] %{GREEDYDATA:[gunicorn][message]}" } remove_field => "message" }

أود أن أزعم أن تنسيق التاريخ القياسي سيكون أكثر ملاءمة للتكوين الافتراضي. أعتقد أن إضافة مساحة إضافية هناك لا تضيف أي قيمة ولكنها تخلق مشاكل بدلاً من ذلك. إما الاضطرار إلى استبدال logconfig الافتراضي بالكامل ، وهو أمر مفرط ، أو الاضطرار إلى كتابة تعبيرات مخصصة في موزعي السجلات لتلبية ذلك.

Improvement Discussion FeaturLogging

التعليق الأكثر فائدة

حسنًا ، هذا يعني أن grok في logstash محمّل مسبقًا بنمط صارم بدلاً من النمط المتساهل. لقد عملت مع أشخاص معياريين من قبل في BBC / EBU وأتذكر هذا النوع من الصياغة الرهيبة. لسهولة القراءة "(قل) حرف مسافة" هذا غير قابل للتنفيذ .... ما هو هذا الحرف؟ بالطبع يمكنك السماح بأي شخصية في هذه المرحلة وهذا ليس جيدًا. لذلك قام الرجال في Logstash بتنفيذ هذه الطريقة التالية لتكون إما T أو فضاء

TIMESTAMP_ISO8601 %{YEAR}-%{MONTHNUM}-%{MONTHDAY}[T ]%{HOUR}:?%{MINUTE}(?::?%{SECOND})?%{ISO8601_TIMEZONE}?

علاوة على ذلك ، لم يكن هذا هو موضوع المشكلة. موضوع المشكلة هو أن لاحقة المنطقة الزمنية لها مساحة لا يسمح بها المعيار.

لذا لا ، للأسف هذا التنسيق ليس شائعًا. هذا التنسيق غير تقليدي خاص بـ gunicorn. أعلم كم يبدو هذا غباءًا أننا نتجادل حول الفضاء ولكن عندما يتعلق الأمر باللغات ، فإن تركيب الإنسان الآلي هو كل شيء.

ال 34 كومينتر

يتبع تنسيق التاريخ تنسيق السجل العام: https://en.wikipedia.org/wiki/Common_Log_Format

أوه ، اعتذاري. ردي حول تنسيق سجل الوصول. هذا التقرير حول تنسيق سجل الأخطاء.

يبدو أنه يمكنك استخدام %{DATESTAMP} %{ISO8601_TIMEZONE}

بالنسبة لـ 19.x ، فات الأوان لإجراء أي تغيير. سوف يكسر الكثير من استخدام التسجيل حولها. هل هذا شيء نريد تغييره في الإصدار الرئيسي التالي؟

tilgovi فهل هذا مطلوب؟

يعتمد الكثير من الأنظمة التي تم نشرها على التنسيق الحالي. أشعر بالقلق من أنه تغيير كبير جدًا لا يحقق الكثير من القيمة حيث يمكن دائمًا كتابة قاعدة حوله في مخبأ السجل مثل الأنظمة. أفكار؟

قد يكون هناك حل وسط محتمل هو التبديل والإيقاف. يمكنك البدء في التخلص التدريجي من تنسيق التاريخ الفردي (ولكن بشكل طفيف) الذي لا يتبع المعايير وتزويد المستخدم بمحول إلى تنسيق سطر سجل ثابت. أعلم أنه يمكنني تجاوز أداة التسجيل عبر الثعبان ولكن نظرًا لأن gunicorn يأتي مع إعداداته المتنافسة المخبوزة فيه فلن يكون خياري المفضل: DI لست شخصًا الوسواس القهري ولكن إعداد استعلام grok هو نوع حديث من التعذيب خاصة عند الاختلاف أنت تحتسب مساحة واحدة: D ومن ثم فإن الأمر متروك للمطور للحفاظ على تلك المطابقة الأطول من اللازم في حالة تغيير أي شيء. إنها ليست نهاية العالم إذا كان على المرء أن يفعل ذلك ، لكننا نستمر في إصلاح الأخطاء حتى لو اعتمد الناس على برنامج عربات التي تجرها الدواب ... هذا ما أعتقده ... لست متأكدًا مما إذا كان السؤال موجهًا إلي ...

يمكننا النظر في تغيير الإعداد الافتراضي لـ R20.

هذا الشكل شائع جدًا في الواقع. يحتوي RFC 3339 على ملاحظة حول هذا الموضوع:

ملاحظة: تحدد المواصفة القياسية ISO 8601 التاريخ والوقت مفصولين بحرف "T". قد تختار التطبيقات التي تستخدم بناء الجملة هذا ، من أجل سهولة القراءة ، تحديد تاريخ كامل ووقت كامل مفصولة (على سبيل المثال) بحرف مسافة.

تتم طباعة سجل الأخطاء أيضًا على سطر الأوامر ويجب أن يقرأه إنسان وأود الاحتفاظ به على هذا النحو. هل هناك مشكلة في تنسيق المنطقة الزمنية؟

حسنًا ، هذا يعني أن grok في logstash محمّل مسبقًا بنمط صارم بدلاً من النمط المتساهل. لقد عملت مع أشخاص معياريين من قبل في BBC / EBU وأتذكر هذا النوع من الصياغة الرهيبة. لسهولة القراءة "(قل) حرف مسافة" هذا غير قابل للتنفيذ .... ما هو هذا الحرف؟ بالطبع يمكنك السماح بأي شخصية في هذه المرحلة وهذا ليس جيدًا. لذلك قام الرجال في Logstash بتنفيذ هذه الطريقة التالية لتكون إما T أو فضاء

TIMESTAMP_ISO8601 %{YEAR}-%{MONTHNUM}-%{MONTHDAY}[T ]%{HOUR}:?%{MINUTE}(?::?%{SECOND})?%{ISO8601_TIMEZONE}?

علاوة على ذلك ، لم يكن هذا هو موضوع المشكلة. موضوع المشكلة هو أن لاحقة المنطقة الزمنية لها مساحة لا يسمح بها المعيار.

لذا لا ، للأسف هذا التنسيق ليس شائعًا. هذا التنسيق غير تقليدي خاص بـ gunicorn. أعلم كم يبدو هذا غباءًا أننا نتجادل حول الفضاء ولكن عندما يتعلق الأمر باللغات ، فإن تركيب الإنسان الآلي هو كل شيء.

هذا مفيد ، @ kozmaz87. شكرا للتنقيب في المواصفات.

ولكن نظرًا لأننا هنا ، أود أن أشير أيضًا إلى تنسيق سجل الوصول ، والذي يعد أسوأ من ذلك. لم أتمكن حتى من العثور في الكود على أي مكان يأتي منه ... إنه مبني من بعض آليات التكوين الغامضة جدًا. معين من مكان آخر. لم أقم بسحب الكود للتحقيق ولكنه ينتج هذا الناتج:

127.0.0.1 - - [13/Aug/2018:15:03:26 +0000] "GET /debug/sms HTTP/1.1" 400 74 "-" "python-requests/2.18.4"

بالنظر إلى مستندات gunicorn ، نتعلم أن الجزء الثاني من هذا السجل هو "-" لأي سبب من الأسباب ... من المفترض أن يكون الجزء الثالث هو المستخدم ، والذي يقوم أيضًا بالتقييم لـ "-" لست متأكدًا من السبب ثم يأتي هذا الجميل تنسيق التاريخ حيث تقترن الساعة بالسنة بواسطة ":" وبالطبع لاحقة المنطقة الزمنية المفصولة بالمساحة المفضلة مرة أخرى. لكن بعد البحث وجدت أن هذه هي الطريقة التي يسجلها nginx لذلك أفترض أن هذا هو المكان الذي نشأ منه شيء المنطقة الزمنية المنفصلة عن طريق محاولة تقليد سجلات الوصول إلى nginx. لا يستخدم HAProxy هذا أيضًا إلا أنه لا يضع لاحقة منطقة زمنية على ...

تسجيل الدخول مجنون ... أحضر لي أحدهم دلو من الماء المثلج :)

تنسيق سجل الوصول "شائع" بالتأكيد: https://en.wikipedia.org/wiki/Common_Log_Format

ومع ذلك ، فإننا نضيف المُحيل ووكيل المستخدم إلى النهاية. ارجع إلى العلم --access-logformat : http://docs.gunicorn.org/en/latest/settings.html#access -log-format

أنا أدرك ذلك. أجد أنه من المضحك فقط أن العنصر الثاني هو "-": D يبدو الأمر كما لو أن كل من قام بتطبيقه قد حصل عليه مع هذا ووضع علامة "-"

سأحتفظ بتنسيق السجل الحالي. التنسيق الشائع لـ imo جيد ولست على علم بأي تغيير في الخوادم في المنبع. خواطر؟ سي سي تيلجوفي

Bumptilgovi أيضا berkerpeksag

إغلاق المشكلة حيث لن يتم إصلاحها. كما ذكر tilgovi ، فإننا نستخدم [تنسيق السجل العام] (
https://en.wikipedia.org/wiki/Common_Log_Format.

أعتقد أننا يمكن أن نبقي هذا مفتوحا. نحن لا نستخدم تنسيق السجل العام لسجل الأخطاء. تنسيق السجل الشائع هو تنسيق سجل الوصول ونستخدمه هناك.

في الواقع ، لا تهتم. لقد راجعت الآن للتو ونستخدم نفس سلسلة تنسيق الوقت لكليهما. هذا يبدو أفضل بالنسبة لي من أي بديل آخر. لا أريد أن يكون لسجل الوصول وسجل الأخطاء تنسيقات تاريخ مختلفة.

أنا أفهم المشكلة بشكل أفضل الآن وأعتقد أنه يجب علينا إعادة فتحها.

فيما يلي مثال لإخراج من Gunicorn بالإعدادات الافتراضية:

[2019-01-25 11:44:34 -0800] [22794] [INFO] بدء تشغيل gunicorn 19.9.0
[2019-01-25 11:44:34 -0800] [22794] [INFO] الاستماع على: http://127.0.0.1 : 8000 (22794)
[2019-01-25 11:44:34 -0800] [22794] [INFO] استخدام العامل: المزامنة
[2019-01-25 11:44:34 -0800] [22797] [INFO] تمهيد العامل مع pid: 22797
[2019-01-25 11:44:36 -0800] [22797] [INFO] 127.0.0.1 - - [25 / يناير / 2019: 11: 44: 36 -0800] "GET / HTTP / 1.1" 200 14 " - "" curl / 7.54.0 "

لا تتعلق المشكلة بتحليل تنسيق السجل الشائع لسجل الوصول ، إنها تتعلق بتحليل سطر السجل الكامل.

يقوم Gunicorn بإخراج طابع زمني ومعرف معرف ومستوى في بداية سطر السجل. تحتوي أسطر سجل الوصول _also_ على رسالة بتنسيق سجل مشترك بطابع زمني خاص بها.

لاحظ كيف أن الطوابع الزمنية ليست بنفس التنسيق. كان الطلب الأصلي لهذه المشكلة هو جعل الطابع الزمني في بداية سطر السجل لا يحتوي على مساحة _ تمامًا مثل تنسيق السجل الشائع_.

سيبدو هذا كالتالي:

[25 / يناير / 2019: 11:44: 34 -0800] [22794] [INFO] بدء تشغيل Gunicorn 19.9.0
[25 / كانون الثاني / 2019: 11: 44: 34 -0800] [22794] [INFO] الاستماع على: http://127.0.0.1 : 8000 (22794)
[25 / يناير / 2019: 11: 44: 34 -0800] [22794] [INFO] استخدام العامل: المزامنة
[25 / كانون الثاني / 2019: 11: 44: 34 -0800] [22797] [INFO] تمهيد العامل مع pid: 22797
[25 / كانون الثاني / 2019: 11: 44: 36 -0800] [22797] [INFO] 127.0.0.1 - - [25 / كانون الثاني / 2019: 11: 44: 36 -0800] "GET / HTTP / 1.1" 200 14 "-" "curl / 7.54.0"

أعتقد أن الإجابة ربما لا تكون كذلك ، لأن تنسيق السجل الشائع ليس دوليًا (له اسم شهر قصير).

ومع ذلك ، يمكننا تغيير الطابع الزمني في بداية كل سطر سجل ليكون طابعًا زمنيًا ISO8601.

https://ar.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representations

يُسمح فعليًا بالمسافة بين التاريخ والوقت بدلاً من الحرف T ، لكن المسافة بين الوقت وإزاحة المنطقة غير مسموح بها.

إليك تنسيقات ISO8601 الصالحة التي يمكن أن نحصل عليها:

  • [2019-01-25T11:44:34-0800]
  • [2019-01-25 11:44:34-0800]

قارن بما لدينا الآن:

[2019-01-25 11:44:34 -0800]
                    ^ there is a space here

ومع ذلك ، سأقلق كثيرًا بشأن كسر الأنظمة التي تم نشرها.

يمكن بسهولة التعامل مع سجلات التحليل / إعادة التنسيق بشكل جيد مثل أدوات logstash ، لذلك لست متأكدًا من أنها مشكلة. سأحتفظ بها بهذه الطريقة في الوقت الحالي.

إذا أراد الأشخاص تنسيقًا مختلفًا لسجلات الوصول ، فربما يمكننا إضافة معرف محدد له؟ بهذه الطريقة لن نكسر التنسيق. ومع ذلك ، تمثل سجلات الأخطاء مشكلة نظرًا لأننا لا نقدم طريقة لتنسيقها. في مثل هذه الحالة ، ربما متغير البيئة سيفعل ذلك؟

لا أعتقد أن تنسيق سجل الوصول يجب أن يتغير. إنه تنسيق سجل شائع الآن ولدينا إعداد --access-log-format .

يقوم تنسيق سجل الوصول فقط بتنسيق _message_ الخاص بسجل الوصول الذي يتم تمريره إلى المعالج. المعالج ثم له منسق خاص به.

وضع المنسق الافتراضي لمعالجات الدفق على stdout و stderr طابعًا زمنيًا في البداية. هذا يعني أنه مع التكوين الافتراضي ، يحتوي سجل الوصول على _two_ طابع زمني: واحد في البداية والآخر في الرسالة.

يتطلب تغيير المنسق للمعالج استخدام أحد الخيارات --logconfig (ملف أو ديكت).

يجب أن نفكر في وجود طابع زمني ISO8601 في المنسق الافتراضي.

يمكن بسهولة التعامل مع سجلات الإعراب / إعادة التنسيق مثل أدوات logstash

نعم ، ولكن من الملائم جدًا أن تتمكن هذه الأدوات من تحليل الطابع الزمني باستخدام الأنماط المضمنة حتى لا يضطر المستخدم إلى كتابة تعبير عادي. تم فتح الإصدار الأصلي لأن grok يحتوي على نمط مدمج للطوابع الزمنية ISO8601.

tilgovi لا أريد كسر التوافق. تقدم NGINX أيضًا إمكانية ضبط الوقت إما باستخدام تنسيق ISO8601 أو تنسيق السجل العام:

$time_iso8601
local time in the ISO 8601 standard format
$time_local
local time in the Common Log Format

https://nginx.org/en/docs/http/ngx_http_log_module.html

سأفعل نفس الشيء لأنه لا يكسر الإرث. راجع للشغل ألا يجب أن نعرض فقط سطر سجل الوصول إلى الإخراج؟ يبدو أنه لا ينبغي أن يكون لدينا العنوان الأول مع PID. أفكار؟

حول جعله جزءًا من المنسق الافتراضي ، أشعر بالقلق من أنه يفسد بعض الأدوات. ماذا عن وجود متغير بيئة مخصص TIME_ISO8601=true لفرضه؟

لا أريد كسر التوافق.

أنا لا أفعل. أردت فقط إعادة فتح التذكرة لأنني أعتقد أننا أغلقناها لسبب خاطئ. استجاب كلانا كما لو كانت المشكلة تتعلق بالتغيير من تنسيق السجل العام. المشكلة هي الطابع الزمني في التنسيق الافتراضي ، وليس تنسيق رسالة سجل الوصول. أنا سعيد لأننا نستطيع مناقشة الأمر أكثر ، لكن الجواب ربما هو عدم فعل أي شيء.

راجع للشغل ألا يجب أن نعرض فقط سطر سجل الوصول إلى الإخراج؟ يبدو أنه لا ينبغي أن يكون لدينا العنوان الأول مع PID. أفكار؟

المستطاع. لست متأكد.

ماذا عن وجود متغير بيئة مخصص

ربما بخير. يمكن للمستخدم دائمًا التحكم في السجل بالكامل باستخدام تكوين التسجيل المتقدم. نحاول أن نجعل بعض الإعدادات بسيطة لـ CLI ، مثل --log-level ، حتى لا يضطر المستخدمون إلى استخدام ملفات التكوين. ربما يمكننا إضافة --log-date-format ؟ يمكنه حتى التعرف على سلاسل رمزية مثل iso8601 . سيكون هذا الإعداد للمستخدمين الذين لا يريدون استخدام --log-config أو log_config_dict .

tilgovi في الوقت نفسه ، يعد الإصدار 20.0 وقتًا مناسبًا لتغيير التنسيق نظرًا لأننا نكسر التوافق مع python 2.

أعتقد أن ما يقلقني أكثر بشأن أي إرث هو أن ISO8601 يصعب تحليله للعين البشرية وأن الكثير من الناس ، بمن فيهم أنا ، يستخدمون وحدة التحكم كفرصة لمراقبة ما يحدث.

أود أن أقترح ما يلي:

  • [] إضافة خيار -iso8601 يفرض على سجلات stdout و stderr استخدام هذا التنسيق (مثلما تقترح)
  • [] في سجل الوصول أضف خيارًا بالتنسيق لعرض الوقت تحت هذا التنسيق

أثناء وجودنا هنا ، ربما يمكننا أيضًا الحصول على خيار -utc لاستخدام التوقيت العالمي المنسق في ذلك الوقت؟ أفكار؟

فقط للتأكد ، سيكون هذا هو الفرق المقترح إذا قمنا بتغيير الافتراضي:

diff --git a/gunicorn/glogging.py b/gunicorn/glogging.py
index 56cc5bd..0735e58 100644
--- a/gunicorn/glogging.py
+++ b/gunicorn/glogging.py
@@ -80,7 +80,7 @@ CONFIG_DEFAULTS = dict(
         formatters={
             "generic": {
                 "format": "%(asctime)s [%(process)d] [%(levelname)s] %(message)s",
-                "datefmt": "[%Y-%m-%d %H:%M:%S %z]",
+                "datefmt": "[%Y-%m-%d %H:%M:%S%z]",
                 "class": "logging.Formatter"
             }
         }
@@ -175,7 +175,7 @@ class Logger(object):
     loglevel = logging.INFO

     error_fmt = r"%(asctime)s [%(process)d] [%(levelname)s] %(message)s"
-    datefmt = r"[%Y-%m-%d %H:%M:%S %z]"
+    datefmt = r"[%Y-%m-%d %H:%M:%S%z]"

     access_fmt = "%(message)s"
     syslog_fmt = "[%(process)d] %(message)s"

أعتقد أن خيار استخدام تاريخ ووقت ISO8601 في الرموز المميزة لسجل الوصول مثير للاهتمام ، لكنه منفصل عما حفز هذه المشكلة.

بالمناسبة ، لا أشعر بقوة تجاه هذا الأمر. 😄 أريد فقط أن أمثل المشكلة بدقة.

ربما نحتاج إلى التفكير أكثر في الأمر. أقوم بتأجيله إلى 20.1 للسماح لنا في بعض الأحيان.

devels الأعزاء ،
أواجه مشكلة فقدان طلب (لا علاقة لها بـ Gunicorn). سأحتاج إلى أن أكون قادرًا على الحصول على طابع زمني دقيق بما في ذلك الميكروثانية ، كما في هذا المثال من أحد خوادم Apache لدينا: 2019-10-30 14:27:16.960421 . سيكون تحسينًا رائعًا ، شكرًا للنظر فيه.

أي أمل إذا كان العلم ، log-date-format iso8601 ، سيكون متاحًا في الإصدار التالي من gunicorn؟

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات