This paper is a group[ 905329304 (my QQ water blowing group)], a big man asked a question I will share solutions to interesting problems. It is convenient for leaders to put forward their valuable opinions
Handlers
Intercepting the words in the document: the Handler is the engine that determines how to process each message in the logger. It describes specific logging behaviors, such as outputting messages to screens, files, or network socket s.
Based on this short passage, the problem was solved Then the next step is to find the corresponding Handlers and set them
Django only provides an AdminEmailHandler, which will report to the site for each log message received ADMINS Send an email. But the official introduction of Django doesn't say that messages can be output to the network socket
class AdminEmailHandler(include_html=False, email_backend=None, reporter_class=None)
SocketHandler
Sure enough Python 3 official documentation The corresponding for the response was found in SocketHandler , the official introduced it as follows: SocketHandler Class at logging.handlers modular. It can send log output to a network socket The base class uses TCP sockets.
class SocketHandler(host, port)
setting. Add configuration to PY
SocketHandler Two parameters need to be passed The parameter can be passed as long as it follows the class configuration You can see the socket key of handlers This is a custom name
LOGGING = { 'version': 1, 'handlers': { 'socket': { 'class': 'logging.handlers.SocketHandler', 'host': "127.0.0.1", 'port': 8848, } }, 'root': { 'handlers': ['socket'], }, }
Server (receiver Demo)
Here is a simple Socket server. If you can't, you can refer to what I wrote before
Python hacker programming -- socket Foundation,Python uses Socket to write an HTTP server from zero,Python uses Socket to write an HTTP server from zero (2), Python uses Socket to write an HTTP server from zero (3)
import socket server = socket.socket() server.bind(("127.0.0.1", 8848)) server.listen(5) client, addr = server.accept() print(client.recv(1024))
Add view Views
Add a view for testing to facilitate testing. Remember to add routes Not here
import logging from django.http.response import JsonResponse def index(request): print(logging) logging.error("Something is warning") return JsonResponse({"request": "ok!"})
test
Start Django service Open the Socket server Then visit the website in the browser. success
Custom Handler
Of course, you can also customize the Handler, as long as you inherit logging Just Handler We just need to implement the emit method
def emit(self, record): """ Do whatever it takes to actually log the specified logging record. This version is intended to be implemented by subclasses and so raises a NotImplementedError. """ raise NotImplementedError('emit must be implemented ' 'by Handler subclasses')
This method will pass in a parameter record, which is a class under logging LogRecord , here is the meaning of common parameters (copied)
- Name – the name of the recorder used to record the events represented by this LogRecord. Note that this name will always have this value, even if it may be issued by a handler attached to a different (ancestor) logger.
- Level – the numeric level of the log event (one of DEBUG, INFO, etc.). Note that this will be converted to the two properties of LogRecord: the levelno value and the corresponding level name of levelname.
- Pathname – the full pathname of the source file for the logging call.
- lineno – the line number in the source file where the logging call is made.
- msg – event description message, which may be a format string with variable data placeholders.
- args – variable data to be merged into msg parameter to get event description.
- exc_info – exception tuple with current exception information, or None if no exception information is available.
- func – the name of the function or method called by the call logging.
- sinfo – a text string representing stack information from the bottom of the stack in the current thread to the logging call.
In settings Py creates a file in the same directory, myhandler Py simply wrote a demo
from socket import socket from logging import Handler, LogRecord class SocketHandler(Handler): def __init__(self, host, port): Handler.__init__(self) self.host = host self.port = port if port is None: self.address = host else: self.address = (host, port) def emit(self, record: LogRecord) -> None: c = socket() c.connect(self.address) c.send(("[{}] {} {} \"{}\"".format(record.levelname, record.pathname, record.lineno, record.msg)).encode()) c.close()
The same server Demo, modify settings Py configuration
LOGGING = { 'version': 1, 'handlers': { 'socket': { 'class': 'common.myHandler.SocketHandler', 'host': "127.0.0.1", 'port': 8848, } }, 'root': { 'handlers': ['socket'], }, }
Data received successfully
Possible pit
Here are some problems (pits) I encountered in the process of use
ValueError: Unable to configure handler 'xxxx'
This error is an error when loading the logging configuration Here is a hint that there is an error, as shown in the figure
In fact, I have less configuration here. I need to pass in the parameters host and port. Therefore, when this error occurs, check whether the configuration is correct If it is a custom Handler, check whether there is an internal error
No processing logic entered
After the configuration, the desired effect was not achieved The following is the processing logic for demonstration
def emit(self, record: LogRecord) -> None: print('*-'*55) print(("[{}] {} {} \"{}\"".format(record.levelname, record.pathname, record.lineno, record.msg)).encode())
The request did not achieve the desired effect Or no logic at all
In the first case, the level of * * log events is not enough * *. In fact, I use info in my views, but I can notice that level is not set in my configuration Failed to capture the log
def index(request): print(logging) logging.info("Something is warning") return JsonResponse({"request": "ok!"})
My solution is to set the level directly to 0
The second case is Handlers are set but not used. Just add them to the following handlers