পাইথন-অনুরোধ মডিউল থেকে সমস্ত অনুরোধ লগ ইন করুন


98

আমি পাইথন অনুরোধগুলি ব্যবহার করছি । আমার কিছু OAuthক্রিয়াকলাপ ডিবাগ করা দরকার এবং এর জন্য আমি এটি চাই যে সমস্ত অনুরোধ সম্পাদিত হচ্ছে log আমি এই তথ্যটি সাথে পেতে পারি ngrep, তবে দুর্ভাগ্যক্রমে https সংযোগগুলি গ্রেপ করা সম্ভব নয় (যার জন্য প্রয়োজনীয় OAuth)

Requestsঅ্যাক্সেস করা সমস্ত ইউআরএল (+ পরামিতি) এর লগিং আমি কীভাবে সক্রিয় করতে পারি ?


@Yohann এর প্রতিক্রিয়া দেখায় যে আপনি পাঠাচ্ছেন এমন শিরোনাম সহ আরও লগিং আউটপুট কীভাবে পাবেন। এটি মার্টিজন-এর পরিবর্তে গ্রহণযোগ্য উত্তর হওয়া উচিত, যা শিরোনামগুলি দেখায় না যে আপনি ওয়্যারশার্কের মাধ্যমে পৌঁছেছেন এবং এর পরিবর্তে একটি অনুরোধ হাতে কাস্টমাইজ করেছেন।
নীলাম্যাকবি

উত্তর:


97

অন্তর্নিহিত urllib3গ্রন্থাগারটি loggingমডিউলটির সাথে সমস্ত নতুন সংযোগ এবং URL গুলি লগ করে , তবে POSTমৃতদেহগুলি নয় । GETঅনুরোধের জন্য এটি যথেষ্ট হওয়া উচিত:

import logging

logging.basicConfig(level=logging.DEBUG)

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

সংক্ষিপ্ত ডেমো:

>>> import requests
>>> import logging
>>> logging.basicConfig(level=logging.DEBUG)
>>> r = requests.get('http://httpbin.org/get?foo=bar&baz=python')
DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): httpbin.org:80
DEBUG:urllib3.connectionpool:http://httpbin.org:80 "GET /get?foo=bar&baz=python HTTP/1.1" 200 366

Urllib3 এর সঠিক সংস্করণ অনুসারে, নিম্নলিখিত বার্তাগুলি লগ করা হয়েছে:

  • INFO: পুনঃনির্দেশ
  • WARN: সংযোগ পুল পূর্ণ (যদি এটি প্রায়শই সংযোগ পুলের আকার বাড়ায়)
  • WARN: শিরোনাম পার্স করতে ব্যর্থ হয়েছে (অবৈধ ফর্ম্যাট সহ প্রতিক্রিয়া শিরোনাম)
  • WARN: সংযোগটি আবার চেষ্টা করা হচ্ছে
  • WARN: শংসাপত্র প্রত্যাশিত হোস্টনামের সাথে মেলে না
  • WARN: খণ্ডিত প্রতিক্রিয়ার প্রক্রিয়াকরণের সময়, সামগ্রী-দৈর্ঘ্য এবং স্থানান্তর-এনকোডিং উভয়ই দিয়ে প্রতিক্রিয়া পেয়েছি
  • DEBUG: নতুন সংযোগ (HTTP বা HTTPS)
  • DEBUG: ড্রপড সংযোগগুলি
  • DEBUG: সংযোগের বিশদ: পদ্ধতি, পথ, এইচটিটিপি সংস্করণ, স্থিতি কোড এবং প্রতিক্রিয়া দৈর্ঘ্য
  • DEBUG: গণনা বৃদ্ধি পুনরায় চেষ্টা করুন

এটিতে শিরোলেখ বা বডি অন্তর্ভুক্ত নয়। গ্রান্ট-ওয়ার্কটি করার urllib3জন্য http.client.HTTPConnectionক্লাসটি ব্যবহার করে , তবে সেই শ্রেণিটি লগিং সমর্থন করে না, এটি সাধারণত কেবল স্টডআউট-এ মুদ্রণের জন্য কনফিগার করা যায় । তবে, আপনি printএই মডিউলে কোনও বিকল্প নাম পরিচয় করিয়ে পরিবর্তে সমস্ত ডিবাগ তথ্য লগিংয়ে প্রেরণে এটি ছদ্মবেশী করতে পারেন :

import logging
import http.client

httpclient_logger = logging.getLogger("http.client")

def httpclient_logging_patch(level=logging.DEBUG):
    """Enable HTTPConnection debug logging to the logging framework"""

    def httpclient_log(*args):
        httpclient_logger.log(level, " ".join(args))

    # mask the print() built-in in the http.client module to use
    # logging instead
    http.client.print = httpclient_log
    # enable debugging
    http.client.HTTPConnection.debuglevel = 1

কলিংয়ের httpclient_logging_patch()ফলে http.clientসমস্ত ডিবাগের তথ্য স্ট্যান্ডার্ড লগারে আউটপুট দেওয়ার সংযোগ ঘটে এবং তাই এগুলি বেছে নেওয়া হয় logging.basicConfig():

>>> httpclient_logging_patch()
>>> r = requests.get('http://httpbin.org/get?foo=bar&baz=python')
DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): httpbin.org:80
DEBUG:http.client:send: b'GET /get?foo=bar&baz=python HTTP/1.1\r\nHost: httpbin.org\r\nUser-Agent: python-requests/2.22.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\n\r\n'
DEBUG:http.client:reply: 'HTTP/1.1 200 OK\r\n'
DEBUG:http.client:header: Date: Tue, 04 Feb 2020 13:36:53 GMT
DEBUG:http.client:header: Content-Type: application/json
DEBUG:http.client:header: Content-Length: 366
DEBUG:http.client:header: Connection: keep-alive
DEBUG:http.client:header: Server: gunicorn/19.9.0
DEBUG:http.client:header: Access-Control-Allow-Origin: *
DEBUG:http.client:header: Access-Control-Allow-Credentials: true
DEBUG:urllib3.connectionpool:http://httpbin.org:80 "GET /get?foo=bar&baz=python HTTP/1.1" 200 366

4
আশ্চর্যজনকভাবে যথেষ্ট, আমি access_tokenOAuth অনুরোধটিতে দেখতে পাচ্ছি না । লিংকডিন অননুমোদিত অনুরোধ সম্পর্কে অভিযোগ করছে এবং আমি যে লাইব্রেরিটি ব্যবহার করছি ( rauthউপরে requests) অনুরোধের সাথে সেই টোকেনটি প্রেরণ করছে কিনা তা আমি যাচাই করতে চাই । আমি একটি ক্যোয়ারী প্যারামিটার হিসাবে এটি দেখার প্রত্যাশা করছিলাম, তবে সম্ভবত এটি অনুরোধ শিরোনামগুলিতে রয়েছে? আমি কীভাবে urllib3হেডারগুলিকে প্রদর্শন করতে বাধ্য করতে পারি ? আর অনুরোধের বডি? কেবল এটি সহজ করার জন্য: আমি কীভাবে পূর্ণ অনুরোধটি দেখতে পারি ?
ব্লুফাস্ট

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

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

4
@ নিউম্যাকবি: গাহ, হ্যাঁ, একটি বিশ্বব্যাপী শ্রেণীর বৈশিষ্ট্য নির্ধারণ করা সত্যই ডিবাগিং সক্ষম করবে httplib। আমি চাই যে loggingপরিবর্তে লাইব্রেরিটি ব্যবহার করা হত; ডিবাগ আউটপুট সরাসরি আপনার পছন্দসই লগ গন্তব্য এ আপনাকে পুনর্নির্দেশের চেয়ে স্টডআউটে লিখিত হয়।
মার্টিজন পিটারস


112

আপনাকে httplibস্তরে ডিবাগিং সক্ষম করতে হবে ( requestsurllib3httplib)।

টগল ( ..._on()এবং ..._off()) উভয়টির জন্য এখানে কিছু ফাংশন রয়েছে বা অস্থায়ীভাবে এটি চালু রয়েছে:

import logging
import contextlib
try:
    from http.client import HTTPConnection # py3
except ImportError:
    from httplib import HTTPConnection # py2

def debug_requests_on():
    '''Switches on logging of the requests module.'''
    HTTPConnection.debuglevel = 1

    logging.basicConfig()
    logging.getLogger().setLevel(logging.DEBUG)
    requests_log = logging.getLogger("requests.packages.urllib3")
    requests_log.setLevel(logging.DEBUG)
    requests_log.propagate = True

def debug_requests_off():
    '''Switches off logging of the requests module, might be some side-effects'''
    HTTPConnection.debuglevel = 0

    root_logger = logging.getLogger()
    root_logger.setLevel(logging.WARNING)
    root_logger.handlers = []
    requests_log = logging.getLogger("requests.packages.urllib3")
    requests_log.setLevel(logging.WARNING)
    requests_log.propagate = False

@contextlib.contextmanager
def debug_requests():
    '''Use with 'with'!'''
    debug_requests_on()
    yield
    debug_requests_off()

ডেমো ব্যবহার:

>>> requests.get('http://httpbin.org/')
<Response [200]>

>>> debug_requests_on()
>>> requests.get('http://httpbin.org/')
INFO:requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): httpbin.org
DEBUG:requests.packages.urllib3.connectionpool:"GET / HTTP/1.1" 200 12150
send: 'GET / HTTP/1.1\r\nHost: httpbin.org\r\nConnection: keep-alive\r\nAccept-
Encoding: gzip, deflate\r\nAccept: */*\r\nUser-Agent: python-requests/2.11.1\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: Server: nginx
...
<Response [200]>

>>> debug_requests_off()
>>> requests.get('http://httpbin.org/')
<Response [200]>

>>> with debug_requests():
...     requests.get('http://httpbin.org/')
INFO:requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): httpbin.org
...
<Response [200]>

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

সূত্র


httplib.HTTPConnection.debuglevel = 1শিরোনামগুলি পেতে ব্যবহার সম্পর্কে অন্তর্দৃষ্টি জন্য আপনাকে ধন্যবাদ - দুর্দান্ত! তবে আমি মনে করি কেবল logging.basicConfig(level=logging.DEBUG)আপনার অন্যান্য 5 টি লাইনের জায়গায় আমি একই ফলাফল পেয়েছি । আমি কিছু অনুপস্থিত করছি? আমি অনুমান করি যে urlib3 বনাম মূলের জন্য বিভিন্ন লগিং স্তর নির্ধারণের জন্য এটি একটি উপায় হতে পারে desired
nelpcb

আপনার সমাধান সহ আপনার শিরোনাম নেই।
ইয়াহান

7
httplib.HTTPConnection.debuglevel = 2পাশাপাশি পোষ্ট বডি মুদ্রণের অনুমতি দেবে।
মান্দিবেল79

4
httplib.HTTPConnection.debuglevel = 1$ curl https://raw.githubusercontent.com/python/cpython/master/Lib/http/client.py |grep debuglevelএটি সর্বদা @ ম্যান্ডিবল 79৯ যথেষ্টdebuglevel > 0
যোহান

4
কোনওভাবে লগ করা বিষয়বস্তু প্রমিত আউটপুটটিতে প্রেরণ করা যায়?
ইয়ুসার

47

যারা পাইথন 3+ ব্যবহার করেন তাদের জন্য

import requests
import logging
import http.client

http.client.HTTPConnection.debuglevel = 1

logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True

আমি কীভাবে এটি লগ ফাইলের সাথে কাজ করতে পারি? এটি কেবল কাজ করার জন্য মনে হয় stdout। এখানে সমস্যা উদাহরণ: stackoverflow.com/q/58738195/1090360
JackTheKnife

16

পাইথন লগিং সিস্টেমটি ( import logging) যখন নিম্ন স্তরের ডিবাগ লগ বার্তাগুলি ছড়িয়ে দেওয়ার চেষ্টা করার সময় , এটি প্রদত্তটি আবিষ্কার করে আমার অবাক করে তোলে:

requests --> urllib3 --> http.client.HTTPConnection

এটি কেবলমাত্র urllib3পাইথন loggingসিস্টেম ব্যবহার করে :

  • requests না
  • http.client.HTTPConnection না
  • urllib3 হ্যাঁ

অবশ্যই, আপনি HTTPConnectionসেটিংস দ্বারা ডিবাগ বার্তাগুলি নিষ্কাশন করতে পারেন :

HTTPConnection.debuglevel = 1

তবে এই ফলাফলগুলি printবিবৃতি দিয়ে কেবল নির্গত হয় । এটি প্রমাণ করার জন্য, পাইথন ৩.7 client.pyউত্স কোডটি গ্রেপ করুন এবং মুদ্রণ বিবৃতিগুলি নিজেরাই দেখুন (ধন্যবাদ @ যোহান):

curl https://raw.githubusercontent.com/python/cpython/3.7/Lib/http/client.py |grep -A1 debuglevel` 

সম্ভবত কোনওভাবে স্টডআউটকে পুনঃনির্দেশিত করা লগিং সিস্টেমে জুতো-হর্ন স্ট্ডআউটের কাজ করতে পারে এবং সম্ভবত লগ ফাইলের জন্য ক্যাপচার করতে পারে।

' urllib3' লগার নয় ' requests.packages.urllib3' বেছে নিন

urllib3পাইথন 3 loggingসিস্টেমের মাধ্যমে ডিবাগের তথ্য ক্যাপচার করতে , ইন্টারনেটে অনেক পরামর্শের বিপরীতে এবং @ মাইকস্মিথ উল্লেখ করেছেন যে, আপনার খুব ভাগ্য বাধা নেই:

log = logging.getLogger('requests.packages.urllib3')

পরিবর্তে আপনার প্রয়োজন:

log = logging.getLogger('urllib3')

urllib3একটি লগ ফাইল ডিবাগিং

urllib3পাইথন loggingসিস্টেমটি ব্যবহার করে একটি লগ ফাইলে কাজ করে এমন কিছু কোড এখানে রয়েছে :

import requests
import logging
from http.client import HTTPConnection  # py3

# log = logging.getLogger('requests.packages.urllib3')  # useless
log = logging.getLogger('urllib3')  # works

log.setLevel(logging.DEBUG)  # needed
fh = logging.FileHandler("requests.log")
log.addHandler(fh)

requests.get('http://httpbin.org/')

ফলাফল:

Starting new HTTP connection (1): httpbin.org:80
http://httpbin.org:80 "GET / HTTP/1.1" 200 3168

HTTPConnection.debuglevelমুদ্রণ () বিবৃতি সক্ষম করুন

আপনি যদি সেট HTTPConnection.debuglevel = 1

from http.client import HTTPConnection  # py3
HTTPConnection.debuglevel = 1
requests.get('http://httpbin.org/')

আপনি অতিরিক্ত সরস নিম্ন স্তরের তথ্যের মুদ্রণ বিবৃতি আউটপুট পাবেন :

send: b'GET / HTTP/1.1\r\nHost: httpbin.org\r\nUser-Agent: python- 
requests/2.22.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: Access-Control-Allow-Credentials header: Access-Control-Allow-Origin 
header: Content-Encoding header: Content-Type header: Date header: ...

মনে রাখবেন এই আউটপুটটি printপাইথন loggingসিস্টেমটি ব্যবহার করে না এবং ব্যবহার করে, এবং এটি কোনও traditional loggingতিহ্যবাহী স্ট্রিম বা ফাইল হ্যান্ডলার ব্যবহার করে ক্যাপচার করা যায় না (যদিও স্টাডাউট পুনর্নির্দেশের মাধ্যমে কোনও ফাইলে আউটপুট ক্যাপচার করা সম্ভব হতে পারে)

উপরের দুটি সংযুক্ত করুন - কনসোলে সমস্ত সম্ভাব্য লগিং সর্বাধিক করুন ize

সমস্ত সম্ভাব্য লগিং সর্বাধিকতর করতে, আপনাকে অবশ্যই এটি দিয়ে কনসোল / স্টডআউট আউটপুট স্থির করতে হবে:

import requests
import logging
from http.client import HTTPConnection  # py3

log = logging.getLogger('urllib3')
log.setLevel(logging.DEBUG)

# logging from urllib3 to console
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
log.addHandler(ch)

# print statements from `http.client.HTTPConnection` to console/stdout
HTTPConnection.debuglevel = 1

requests.get('http://httpbin.org/')

আউটপুট সম্পূর্ণ পরিসীমা প্রদান:

Starting new HTTP connection (1): httpbin.org:80
send: b'GET / HTTP/1.1\r\nHost: httpbin.org\r\nUser-Agent: python-requests/2.22.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
http://httpbin.org:80 "GET / HTTP/1.1" 200 3168
header: Access-Control-Allow-Credentials header: Access-Control-Allow-Origin 
header: Content-Encoding header: ...

4
এবং লগারে মুদ্রণের বিবরণ পুনর্নির্দেশ সম্পর্কে কী?
yucer

লগরের মুদ্রণের বিবরণ পেতে ইয়ুসার কোন সাফল্য?
এরিকা ডসুজা

3

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

requestsতথাকথিত ইভেন্ট হুক সমর্থন করে (২.২৩ পর্যন্ত আসলে কেবল responseহুক রয়েছে)। এটি মূলত ইভেন্ট শ্রোতা এবং ইভেন্টটি নিয়ন্ত্রণ থেকে ফিরে আসার আগেই নির্গত হয় requests.request। এই মুহুর্তে উভয় অনুরোধ এবং প্রতিক্রিয়া সম্পূর্ণরূপে সংজ্ঞায়িত করা হয়েছে, তাই লগ করা যায়।

import logging

import requests


logger = logging.getLogger('httplogger')

def logRoundtrip(response, *args, **kwargs):
    extra = {'req': response.request, 'res': response}
    logger.debug('HTTP roundtrip', extra=extra)

session = requests.Session()
session.hooks['response'].append(logRoundtrip)

এটি মূলত কোনও সেশনের সমস্ত এইচটিটিপি রাউন্ড-ট্রিপগুলিতে লগ করা যায়।

ফর্ম্যাট করা HTTP রাউন্ড-ট্রিপ লগ রেকর্ডগুলি

উপরের লগিংটি কার্যকর হওয়ার জন্য এখানে বিশেষায়িত লগিং ফর্ম্যাটর থাকতে পারে যা লগিং রেকর্ডগুলিতে বোঝে reqএবং resঅতিরিক্ত। এটি দেখতে এটি দেখতে পারেন:

import textwrap

class HttpFormatter(logging.Formatter):   

    def _formatHeaders(self, d):
        return '\n'.join(f'{k}: {v}' for k, v in d.items())

    def formatMessage(self, record):
        result = super().formatMessage(record)
        if record.name == 'httplogger':
            result += textwrap.dedent('''
                ---------------- request ----------------
                {req.method} {req.url}
                {reqhdrs}

                {req.body}
                ---------------- response ----------------
                {res.status_code} {res.reason} {res.url}
                {reshdrs}

                {res.text}
            ''').format(
                req=record.req,
                res=record.res,
                reqhdrs=self._formatHeaders(record.req.headers),
                reshdrs=self._formatHeaders(record.res.headers),
            )

        return result

formatter = HttpFormatter('{asctime} {levelname} {name} {message}', style='{')
handler = logging.StreamHandler()
handler.setFormatter(formatter)
logging.basicConfig(level=logging.DEBUG, handlers=[handler])

এখন আপনি যদি কিছুগুলি অনুরোধ করে sessionযেমন:

session.get('https://httpbin.org/user-agent')
session.get('https://httpbin.org/status/200')

আউটপুট নীচের মত দেখতে stderrহবে।

2020-05-14 22:10:13,224 DEBUG urllib3.connectionpool Starting new HTTPS connection (1): httpbin.org:443
2020-05-14 22:10:13,695 DEBUG urllib3.connectionpool https://httpbin.org:443 "GET /user-agent HTTP/1.1" 200 45
2020-05-14 22:10:13,698 DEBUG httplogger HTTP roundtrip
---------------- request ----------------
GET https://httpbin.org/user-agent
User-Agent: python-requests/2.23.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive

None
---------------- response ----------------
200 OK https://httpbin.org/user-agent
Date: Thu, 14 May 2020 20:10:13 GMT
Content-Type: application/json
Content-Length: 45
Connection: keep-alive
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

{
  "user-agent": "python-requests/2.23.0"
}


2020-05-14 22:10:13,814 DEBUG urllib3.connectionpool https://httpbin.org:443 "GET /status/200 HTTP/1.1" 200 0
2020-05-14 22:10:13,818 DEBUG httplogger HTTP roundtrip
---------------- request ----------------
GET https://httpbin.org/status/200
User-Agent: python-requests/2.23.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive

None
---------------- response ----------------
200 OK https://httpbin.org/status/200
Date: Thu, 14 May 2020 20:10:13 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 0
Connection: keep-alive
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

একটি জিইউআই উপায়

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

প্রথমত, loggingতারটি প্রেরণ করার সময় হুককে রেকর্ড তৈরি করতে পুনরায় রচনা করা যেতে পারে যা সিরিয়ালিয়াস করতে পারে । এটি দেখতে এটি দেখতে পারেন:

def logRoundtrip(response, *args, **kwargs): 
    extra = {
        'req': {
            'method': response.request.method,
            'url': response.request.url,
            'headers': response.request.headers,
            'body': response.request.body,
        }, 
        'res': {
            'code': response.status_code,
            'reason': response.reason,
            'url': response.url,
            'headers': response.headers,
            'body': response.text
        },
    }
    logger.debug('HTTP roundtrip', extra=extra)

session = requests.Session()
session.hooks['response'].append(logRoundtrip)

দ্বিতীয়ত, লগিং কনফিগারেশনটি ব্যবহারের জন্য অভিযোজিত করতে হবে logging.handlers.HTTPHandler(যা ক্রোনোলজার বুঝতে পারে)।

import logging.handlers

chrono = logging.handlers.HTTPHandler(
  'localhost:8080', '/api/v1/record', 'POST', credentials=('logger', ''))
handlers = [logging.StreamHandler(), chrono]
logging.basicConfig(level=logging.DEBUG, handlers=handlers)

অবশেষে, ক্রোনোলগার দৌড়ুন run যেমন ডকার ব্যবহার:

docker run --rm -it -p 8080:8080 -v /tmp/db \
    -e CHRONOLOGER_STORAGE_DSN=sqlite:////tmp/db/chrono.sqlite \
    -e CHRONOLOGER_SECRET=example \
    -e CHRONOLOGER_ROLES="basic-reader query-reader writer" \
    saaj/chronologer \
    python -m chronologer -e production serve -u www-data -g www-data -m

এবং অনুরোধগুলি আবার চালনা করুন:

session.get('https://httpbin.org/user-agent')
session.get('https://httpbin.org/status/200')

স্ট্রিম হ্যান্ডলার উত্পাদন করবে:

DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): httpbin.org:443
DEBUG:urllib3.connectionpool:https://httpbin.org:443 "GET /user-agent HTTP/1.1" 200 45
DEBUG:httplogger:HTTP roundtrip
DEBUG:urllib3.connectionpool:https://httpbin.org:443 "GET /status/200 HTTP/1.1" 200 0
DEBUG:httplogger:HTTP roundtrip

এখন আপনি যদি http: // লোকালহোস্ট: 8080 / (বেসিক লেখকের পপআপের জন্য ব্যবহারকারীর নাম এবং খালি পাসওয়ার্ডের জন্য "লগার" ব্যবহার করেন) এবং "ওপেন" বোতামটি ক্লিক করেন, আপনার কিছু দেখতে হবে:

ক্রোনোলজারের স্ক্রিনশট


2

আমি অজগর ব্যবহার করছি 3.4, অনুরোধ 2.19.1:

'urllib3' হ'ল লগার এখনই (এখন আর 'অনুরোধ.packages.urllib3' নেই)। বেসিক লগিং এখনও http.client.HTTPConnication.debuglevel সেট না করেই ঘটবে


4
আপনি আরও ব্যাখ্যা করলে এটি আরও ভাল হবে
জ্যামি লিন্ডসে

0

আমি logger_config.yamlআমার লগিং কনফিগার করতে একটি ফাইল ব্যবহার করছি , এবং সেই লগগুলি দেখানোর জন্য আমাকে যা করতে হবে তা হ'ল disable_existing_loggers: Falseএটির শেষে একটি যুক্ত করা।

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

https://docs.python.org/3/howto/logging.html#configuring-logging


0

শুধু এই উত্তর উন্নতি

এটি আমার পক্ষে এভাবে কাজ করেছে:

import logging
import sys    
import requests
import textwrap
    
root = logging.getLogger('httplogger')


def logRoundtrip(response, *args, **kwargs):
    extra = {'req': response.request, 'res': response}
    root.debug('HTTP roundtrip', extra=extra)
    

class HttpFormatter(logging.Formatter):

    def _formatHeaders(self, d):
        return '\n'.join(f'{k}: {v}' for k, v in d.items())

    def formatMessage(self, record):
        result = super().formatMessage(record)
        if record.name == 'httplogger':
            result += textwrap.dedent('''
                ---------------- request ----------------
                {req.method} {req.url}
                {reqhdrs}

                {req.body}
                ---------------- response ----------------
                {res.status_code} {res.reason} {res.url}
                {reshdrs}

                {res.text}
            ''').format(
                req=record.req,
                res=record.res,
                reqhdrs=self._formatHeaders(record.req.headers),
                reshdrs=self._formatHeaders(record.res.headers),
            )

        return result

formatter = HttpFormatter('{asctime} {levelname} {name} {message}', style='{')
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(formatter)
root.addHandler(handler)
root.setLevel(logging.DEBUG)


session = requests.Session()
session.hooks['response'].append(logRoundtrip)
session.get('http://httpbin.org')
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.