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应用程序以正确登录

这里提供的LOGGINGdict设置要记录的“常规”内容,但是如果 您希望包含自己的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问题。如果您爱我们,并想了解我们的动态,可以在这里在线找到我们:

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java无法在未设置数据源的情况下启动springboot应用程序   返回/泛型的类型?   java通过在navigationView中按id重新加载navigationView内容   java实现安卓的状态更新   java Equals()对于两个相等的字符串不返回true   java如何保存屏幕截图(matlab)   java GWT如何在重新加载页面之前确保函数已完全执行   java在Groovy中实现ObjectJSON映射的标准方法是什么?   java在ApacheTomcat中,是否可以通过连接器过滤多个访问日志文件?   java当JVM达到其Xmx限制时,它会强制垃圾收集吗?   如何在JAVA中生成包含特定数字的不同随机数列表?   rcp中透视图之间的java切换   java理解名为“分区”的Linkedlist算法中的无限循环   RestTemplate的java测微计统计信息   Android中使用自定义服务BLE的java读/写特性   java验证输入以确保负数   关于Java扫描器的io基本查询   java如何使用子字符串或其他函数将字符串拆分为单词?   java Storm群集重复元组