配置示例:

# https://docs.djangoproject.com/zh-hans/2.1/topics/logging/
LOGGING = {
'version': ,
'disable_existing_loggers': False,
'formatters': { # 格式器
'verbose': {
# 后缀d表示数据格式是整数,s表示数据格式是字符串
'format': '[%(levelname)s] [%(asctime)s] [%(module)s] %(filename)s:%(lineno)d %(funcName)s '
'%(processName)s:[%(process)d] %(threadName)s:[%(thread)d] %(message)s'
# 'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}',
# 'style': '{',
},
'simple': {
'format': '[%(levelname)s] [%(asctime)s] %(message)s',
# 'format': '[%(asctime)s] %(message)s',
# 后缀d表示数据格式是整数,s表示数据格式是字符串
# 'format': '[%(levelname)s] [%(asctime)s] [%(module)s] %(filename)s:%(lineno)d %(funcName)s '
# '%(processName)s:[%(process)d] %(threadName)s:[%(thread)d] %(message)s',
# 'style': '{',
},
'standard': {
# 'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s',
'format': '{asctime} [{levelname:6}] {name:30}: {message}',
# 设置上面格式样式;{lineno:}是行号,至少显示3个字符,少则补空格
# 这里style选择{,是指{asctime}这种形式。
# 如果选择%,则是%(asctime)s这种形式。
# 还有一种选择,是$,是$asctime或${asctime}这种形式。
'style': '{',
# 设置时间格式
'datefmt': '%Y-%m-%d %H:%M:%S',
},
'operation': {
'format': '%(message)s'
}
},
# 'filters': {
# # 'special': {
# # '()': 'erebus.logging.SpecialFilter',
# # 'foo': 'bar',
# # },
# 'require_debug_true': {
# '()': 'django.utils.log.RequireDebugTrue',
# },
# }, # Handler是决定如何处理logger中每一条消息的引擎。它描述特定的日志行为,比如把消息输出到屏幕、文件或网络socket。
# 和 logger 一样,handler 也有日志级别的概念。如果一条日志记录的级别不匹配或者低于 handler 的日志级别,
# 对应的消息会被 handler 忽略。
'handlers': { # 处理器
'default': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
'filename': 'logs/default.log',
'maxBytes': ***, # * MB
# 'maxBytes': *, # KB
# 保留7天的日志,没份5M,5份大概是一个小时的日志内容,主要是kafka日志
'backupCount': int(***/),
'formatter': 'standard',
},
'kafka': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
'filename': 'logs/kafka.log',
'maxBytes': ***, # * MB
# 'maxBytes': *, # KB
# 保留7天的日志,没份5M,5份大概是一个小时的日志内容,主要是kafka日志
'backupCount': int(***/),
'formatter': 'standard',
},
'output_to_server': { # 输出到http server,参数来自类HTTPHandler初始化函数里的参数
'level': 'WARNING', # 忽略debug/info信息
'class': 'logging.handlers.HTTPHandler',
'host': '127.0.0.1:8088',
'url': '/api/v1/log',
# 使用GET方法遇到url最大长度限制
'method': 'POST',
'formatter': 'verbose',
},
'django': {
'level': 'INFO', # 忽略debug信息
'class': 'logging.FileHandler',
'filename': '{}/{}.log'.format(BASE_LOG_DIR, conf.get('log', 'name')),
'formatter': 'simple' if DEBUG else 'verbose',
'encoding': 'utf8',
},
'console': {
'level': 'DEBUG', # 所有的日志都会被输出到console
# 'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'operation': {
'level': 'INFO',
'class': 'logging.FileHandler',
'filename': '{}/{}.log'.format(BASE_LOG_DIR, 'operation'),
'formatter': 'operation',
'encoding': 'utf8'
},
'test': {
'level': 'INFO',
'class': 'logging.FileHandler',
'filename': '{}/{}.log'.format(BASE_LOG_DIR, 'test'),
'formatter': 'standard',
'encoding': 'utf8'
}
# 'mail_admins': {
# 'level': 'ERROR',
# 'class': 'django.utils.log.AdminEmailHandler',
# # 'filters': ['special']
# }
},
'loggers': { # 记录器 # 可以通过使用空字符串:''来设置'catch all' logger
# 在以下设置中,将所有日志事件级别为WARNING及以上的日志发送给日志服务器,但配置为'propagate': False日志事件除外,
'': {
'handlers': ['default', 'output_to_server'],
# 这样情况下的level设置是无效的,所有级别的信息都会传给handlers处理,由handlers的level界别决定
'level': 'ERROR',
'propagate': False
},
# 记录所有kakfa相关的日志
'kafka': {
'handlers': ['kafka'],
'level': 'DEBUG',
'propagate': True
},
# 这里必须使用名字django和django.request,目的是为了捕获django框架的日志内容
'django': {
'handlers': ['django', 'console'],
# 当 logger 处理一条消息时,会将自己的日志级别和这条消息的日志级别做对比。
# 如果消息的日志级别匹配或者高于 logger 的日志级别,它就会被进一步处理。
# 否则这条消息就会被忽略掉。当 logger 确定了一条消息需要处理之后,会把它传给 Handler。
# 把INFO及以上级别的日志传给handlers,然后由handlers根据handlers的level进一步处理日志输出
'level': 'INFO',
'propagate': True, # 若值为False,表示日志不会传到上个层级,自然也不会传到default.log里
},
# 使用logger = logging.getLogger('django.request'), logger.info('info'),
# 可以把日志输出到'handlers': ['django', 'console'],
'django.request': {
# 即使和django的handlers一样,level也一样,也并不会产生2次相同的日志内容,应该是个并集。
'handlers': ['django', 'console'],
'level': 'DEBUG',
# 会把日志向django.request的上层django传播
'propagate': True,
},
# sql语句
'django.db.backends': {
# 即使和django的handlers一样,level也一样,也并不会产生2次相同的日志内容,应该是个并集。
'handlers': ['django', 'console'],
'level': 'DEBUG',
# 会把日志向django.request的上层django传播
'propagate': True,
},
# 'erebus.custom': {
# 'handlers': ['console', 'mail_admins'],
# 'level': 'INFO',
# # 'filters': ['special']
# },
# 名字随意起,用时,使用logger = logging.getLogger(conf.get('log', 'name'))获取,传到相应的loggers里就可以
'operation': {
'handlers': ['operation'],
'level': 'INFO',
'propagate': True,
},
'test': {
'handlers': ['console', 'test'],
'level': 'INFO',
'propagate': False, # 不要传给上一层级
}
}
}

查看使用的class HTTPHandler,注意参数对应

class HTTPHandler(logging.Handler):
"""
A class which sends records to a Web server, using either GET or
POST semantics.
"""
def __init__(self, host, url, method="GET", secure=False, credentials=None,
context=
None):
"""
Initialize the instance with the host, the request URL, and the method
("GET" or "POST")
"""
logging.Handler.__init__(self)
method = method.upper()
if method not in ["GET", "POST"]:
raise ValueError("method must be GET or POST")
if not secure and context is not None:
raise ValueError("context parameter only makes sense "
"with secure=True")
self.host = host
self.url = url
self.method = method
self.secure = secure
self.credentials = credentials
self.context = context def mapLogRecord(self, record):
"""
Default implementation of mapping the log record into a dict
that is sent as the CGI data. Overwrite in your class.
Contributed by Franz Glasner.
"""
return record.__dict__ def emit(self, record):
"""
Emit a record. Send the record to the Web server as a percent-encoded dictionary
"""
try:
import http.client, urllib.parse
host = self.host
if self.secure:
h = http.client.HTTPSConnection(host, context=self.context)
else:
h = http.client.HTTPConnection(host)
url = self.url
data = urllib.parse.urlencode(self.mapLogRecord(record))
if self.method == "GET":
if (url.find('?') >= ):
sep = '&'
else:
sep = '?'
url = url + "%c%s" % (sep, data)
h.putrequest(self.method, url)
# support multiple hosts on one IP address...
# need to strip optional :port from host, if present
i = host.find(":")
if i >= :
host = host[:i]
# See issue #: putrequest call above already adds this header
# on Python .x.
# h.putheader("Host", host)
if self.method == "POST":
h.putheader("Content-type",
"application/x-www-form-urlencoded")
h.putheader("Content-length", str(len(data)))
if self.credentials:
import base64
s = ('%s:%s' % self.credentials).encode('utf-8')
s = 'Basic ' + base64.b64encode(s).strip().decode('ascii')
h.putheader('Authorization', s)
h.endheaders()
if self.method == "POST":
h.send(data.encode('utf-8'))
h.getresponse() #can't do anything with the result
except Exception:
self.handleError(record)

参考:https://cloud.tencent.com/developer/ask/183866

django的日志发往http server的更多相关文章

  1. python的日志模块:logging;django的日志系统;django日志输出时间修改

    Django的log,主要是复用Python标准库中的logging模块,在settings.py中进行配置 源代码 1.__init__.py包含以下类: StreamHandler Formatt ...

  2. Django多进程日志文件问题

    Django多进程日志文件问题 最近使用Django做一个项目.在部署的时候发现日志文件不能滚动(我使用的是RotatingFileHandler),只有一个日志文件. 查看Log发现一个错误消息:P ...

  3. tomcat日志警告WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'debug' to '0' did not find a matching property.

    日志中有警告: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'debug' to '0' did ...

  4. 分布式计算 要不要把写日志独立成一个Server Remote Procedure Call Protocol

    w https://en.wikipedia.org/wiki/Remote_procedure_call In distributed computing a remote procedure ca ...

  5. django开发日志配置

    做django开发离不开 日志,这用于保存我门的服务器的日志信息,便于开发人员的维护. 直接上代码: 在setting.py文件里直接配置即可 LOGGING = { 'version': 1, 'd ...

  6. Django中日志管理

    在settings中设置日志的相关信息,然后再逻辑代码区就可以保存相应的信息了 #简单设置: LOGGING = { 'version': 1, 'disable_existing_loggers': ...

  7. django 自定义日志配置

    如果不想使用 python 的 dictConfig 格式来配置 logger,可以制定自己的配置架构. LOGGING_CONFIG 配置定义了用来配置 django logger 的可调用函数,默 ...

  8. DJango错误日志生成

    DJango错误日志生成 setting.py设置 LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'formatters': ...

  9. 网络编程(client发信息给server)

    client发信息给server

随机推荐

  1. ubuntu18.04 安装mysql不出现设置 root 帐户的密码问题(装)

    ubuntu18.04 安装mysql不出现设置 root 帐户的密码问题      https://blog.csdn.net/NeptuneClouds/article/details/80995 ...

  2. MySQL服务器发生OOM的案例分析

    [问题] 有一台MySQL5.6.21的服务器发生OOM,分析下来与多种因素有关 [分析过程] 1.服务器物理内存相对热点数据文件偏小,62G物理内存+8G的SWAP,数据文件大小约550G 触发OO ...

  3. shell 父子传值

    通过一个中间文件进行: #!/bin/bash   (  subvar="hello shell"  echo "$subvar" > temp.txt ...

  4. yield, async

    yield实现斐波那契序列: import sys, time def fib(): a,b,c = 0,1,0 while True: yield c a,b = b, c c = a + b if ...

  5. Ⅳ.Catalan数

    Catalan数首先是由Euler在精确计算对凸n边形的不同的对角三角形剖分的个数问题时得到的,它经常出现在组合计数问题中.     问题的提出:在一个凸n边形中,通过不相交于n边形内部的对角线,把n ...

  6. 「BZOJ 4228」Tibbar的后花园

    「BZOJ 4228」Tibbar的后花园 Please contact lydsy2012@163.com! 警告 解题思路 可以证明最终的图中所有点的度数都 \(< 3\) ,且不存在环长是 ...

  7. bsgs算法详解

    例题  poj 2417bsgs  http://poj.org/problem?id=2417 这是一道bsgs题目,用bsgs算法,又称大小步(baby step giant step)算法,或者 ...

  8. hash tree算法

    本文转载自:http://blog.csdn.net/yuanrxdu/article/details/22474697 Merkle Tree是Dynamo中用来同步数据一致性的算法,Merkle ...

  9. BZOJ4045 : [Cerc2014] bricks

    首先求出B和W的个数,如果只出现了一种那么直接输出sum(k). 否则依次扫描,能割就割,时间复杂度$O(n)$. #include<cstdio> #define N 100010 ty ...

  10. URAL 1963 Kite 计算几何

    Kite 题目连接: http://acm.hust.edu.cn/vjudge/contest/123332#problem/C Description Vova bought a kite con ...