kubernetes pods的相对轻松的json日志记录
jslog4kube的Python项目详细描述
jslog4kube(kubernetes pod/containers的python/json日志记录)
为什么?
- 为python的stdout设置提供json
- 为gunicorn 的stdout设置提供相同的json
- 因为创建复杂的日志收集器配置为处理 那个当时被认为是个好主意的人是为了鸟。
我们想让我们的客户和我们自己更容易开始新的项目 发出很好的伐木声。
继续
两个环境变量配置此模块:
KUBE_META
:指定kubernetes向下api的装入点 volumes位(默认值:etc/meta)KUBE_META_ENV_PREFIX
:任何 environment variables 目标包括在此POD的日志记录中(默认值:x)
这些位已在Python2.7.13、3.5.3和3.6.1下验证为可用的
fromlogging.configimportdictConfigfromjslog4kubeimportLOGGINGdictConfig(LOGGING)
来自Django
项目settings.py
fromjslog4kubeimportLOGGING
gunicorn
gunicorn.conf
access_log_format='remote!%({X-Forwarded-For}i)s|method!%(m)s|url-path!%(U)s|query!%(q)s|username!%(u)s|protocol!%(H)s|status!%(s)s|response-length!%(b)s|referrer!%(f)s|user-agent!%(a)s|request-time!%(L)s'accesslog='-'logger_class='jslog4kube.GunicornLogger'
Gunicorn命令行
gunicorn -c /path/to/gunicorn.conf [rest of your options here]
这将产生以下类型的输出:
{"asctime":"2017-07-12 16:07:34,624","message":"Booting worker with pid: 6801","name":"gunicorn.error","created":1499893654.6243172,"filename":"glogging.py","module":"glogging","funcName":"info","lineno":247,"msecs":624.3171691894531,"pathname":"/home/gladiatr/.virtualenvs/json-logs-for-kube/lib/python3.6/site-packages/gunicorn/glogging.py","process":6801,"processName":"MainProcess","relativeCreated":70.62673568725586,"thread":140275859264576,"threadName":"MainThread","levelname":"INFO","x_node_name":"ip-10-70-59-190.eu-central-1.compute.internal","x_sa_name":"default","x_pod_ip":"100.96.1.11","build":"5000","builder":"Stephen Spencer","image":"gladiatr72/kube-demo","version":"1.0.2","app":"kube-demo","env":"dev","pod-template-hash":"2802633501","something":"else"}{"asctime":"2017-07-12 21:08:16,354","message":"in view: Chameleon","name":"efk.views","created":1499893696.3544216,"filename":"views.py","module":"views","funcName":"Chameleon","lineno":12,"msecs":354.42161560058594,"pathname":"/home/gladiatr/git/json-logs-for-kube/demo/efk/views.py","process":6800,"processName":"MainProcess","relativeCreated":41800.73118209839,"thread":140275726399232,"threadName":"<concurrent.futures.thread.ThreadPoolExecutor object at 0x7f947f4b0828>_0","levelname":"INFO","x_node_name":"ip-10-70-59-190.eu-central-1.compute.internal","x_sa_name":"default","x_pod_ip":"100.96.1.11","build":"5000","builder":"Stephen Spencer","image":"gladiatr72/kube-demo","version":"1.0.2","app":"kube-demo","env":"dev","pod-template-hash":"2802633501","something":"else","additional data":"whee"}{"asctime":"2017-07-12 21:08:16,369","message":"(access record)","name":"gunicorn.access","created":1499893696.3695881,"filename":"glogging.py","module":"glogging","funcName":"access","lineno":327,"msecs":369.58813667297363,"pathname":"/home/gladiatr/.virtualenvs/json-logs-for-kube/lib/python3.6/site-packages/gunicorn/glogging.py","process":6800,"processName":"MainProcess","relativeCreated":41815.89770317078,"thread":140275726399232,"threadName":"<concurrent.futures.thread.ThreadPoolExecutor object at 0x7f947f4b0828>_0","levelname":"INFO","x_node_name":"ip-10-70-59-190.eu-central-1.compute.internal","x_sa_name":"default","x_pod_ip":"100.96.1.11","build":"5000","builder":"Stephen Spencer","image":"gladiatr72/kube-demo","version":"1.0.2","app":"kube-demo","env":"dev","pod-template-hash":"2802633501","something":"else","access":{"remote":"10.0.1.195","method":"GET","url-path":"/","query":"","username":"-","protocol":"HTTP/1.0","status":"200","response-length":"140","referrer":"-","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36","request-time":"0.019269"}}
Kubernetes部署示例:
apiVersion:extensions/v1beta1kind:Deploymentmetadata:<<-- This is not the metadata you are looking forname:kube-demolabels:project:kube-demoenvironment:devspec:replicas:1selector:matchLabels:app:kube-demoenv:devtemplate:metadata:labels:app:kube-demoenv:devsomething:elseannotations:build:"5000"builder:"StephenSpencer"image:"gladiatr72/kube-demo"version:"1.0.2"
目前只有metadata.(labels|annotations)
支持通过音量进行曝光。
(原因,对吧?)
spec:volumes:name:podinfodownwardAPI:items:-path:labelsfieldRef:fieldPath:metadata.labels-path:annotationsfieldRef:fieldPath:metadata.annotationscontainers:-name:kube-demoimage:gladiatr72/kube-demo:1.0.2volumeMounts:-name:runmountPath:/run-name:podinforeadOnly:truemountPath:/etc/meta <<-- KUBE_META must equal this
环境变量前缀
(或者:当你在数据存储中发送垃圾邮件时,如何避免看起来像个十足的白痴) 登录系统的密码)
只要前缀匹配,就可以使用任何字母或序列作为前缀
值为KUBE_META_ENV_PREFIX
。
env:-name:MEMCACHE_HOSTvalue:unix:/run/memcache.sock-name:DJANGO_SETTINGS_MODULEvalue:"revsys.settings.dev"-name:DJANGO_FQDNvalue:kube-demo.dev.revsys.com-name:*X_NODE_NAMEvalueFrom:fieldRef:fieldPath:spec.nodeName-name:*X_POD_IPvalueFrom:fieldRef:fieldPath:status.podIP-name:*X_SA_NAMEvalueFrom:fieldRef:fieldPath:spec.serviceAccountName-name:REDIS_PASSWORD (oh, nos!)valueFrom:secretKeyRef:name:rediskey:passports:-containerPort:8000*unmagical prefix set in KUBE_META_ENV_PREFIX
日志配置
它只是一个标准的python字典。最明显的改变 是处理程序定义。
fromjslog4kubeimportLOGGINGLOGGING_HANDLERS={'mypackage':{'handlers':['json-stdout'],'formatters':['json'],'propagate’: False,'level’: 'ERROR',}}LOGGING['handlers'].update(LOGGING_HANDLERS)
设置您的python/django应用程序以正确登录
这里提供的LOGGING
dict设置要记录的“常规”内容,但是如果
您希望包含自己的python库或需要指定的django应用程序
他们。要指定一个名为“foo”的django应用程序,只需调整LOGGING
命令如下:
LOGGERS = {
'foo': {
'handlers': ['json-stdout'],
'formatters': ['json'],
'propagate': True,
'level': 'INFO',
}
}
LOGGING['loggers'].update(LOGGERS)
dictConfig(LOGGING)
或者,如果您想以DEBUG
级别记录所有内容,您可以设置一个空白(也称为默认)记录器:
LOGGERS = {
'': {
'handlers': ['json-stdout'],
'formatters': ['json'],
'propagate': True,
'level': 'DEBUG',
}
}
LOGGING['loggers'].update(LOGGERS)
dictConfig(LOGGING)
用法
这是普通的python日志记录,所以您可以做一些简单的事情,比如我们的info调用 下面或更复杂的内容,如调试调用,并将其他数据添加到日志信息:
import logging
logger = logging.getLogger(__name__)
logger.info("Simple log message")
foo = 12
bar = 'something else'
logger.debug("More complicated message", extra={
"foo": foo,
"bar": bar,
})
需要帮助吗?
REVSYS可以帮助您完成python、django和基础设施项目。如果您对这个项目有疑问,请打开一个github问题。如果您爱我们,并想了解我们的动态,可以在这里在线找到我们: