运维开发笔记整理-django日志配置
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
一.Django日志
Django使用python内建的logging模块打印日志,Python的logging配置由四个部分组成:
1>.记录器(Logger)
2>.处理程序(Handler)
3>.过滤器(Filter)
4>.格式化(Formatter)
更多关于logging模块的配置信息,详情请参考:https://yiyibooks.cn/xx/python_352/library/logging.html。
二.记录器(Logger)
1>.Logger为日志系统的入口。每个logger命名都是bucket,你可以向这个bucket写入需要处理的消息;
2>.每个logger都有一个日志级别。日志级别表示该logger将要处理的消息的严重性。Python定义以下几种日志级别:
DEBUG:
用于调试目的的底层系统信息
INFO:
普通的系统信息
WARNING:
表示出现一个较小的问题
ERROR:
表示出现一个较大的问题
CRITICAL:
表示出现一个致命的问题
3>.写入logger的每条消息都是一条日志。每条日志也具有一个日志级别,它表示对应的消息的严重性。每个日志记录还可以包含描述正在打印的时间的元信息;
4>.当一条消息传递给logger是,消息的日志级别将与logger的日志级别进行比较。如果消息的日志级别大雨等于logger的日志级别,该消息将会往下继续处理。如果小雨,该消息将被忽略;
5>.Logger一旦决定消息需要处理,它将传递消息给一个Handler;
三.logger的日志级别
级别 值 描述
CRITICAL 50 关键错误/消息
ERROR 40 错误
WARNING 30 警告消息
INFO 20 通知消息
DEBGU 10 调试
NOTSET 0 无级别
四.Logger配置
logger对应的值是个字典,其每一个键都是logger的名字,每一个值又是个字典,描述了如何配置对应的Logger实力。
level(可选的):
logger的级别。
propagate(可选的):
logger的传播设置。
filters(可选的):
logger的filter的标识符的列表。
handllers(可选的):
logger的handler的标识符的列表。
LOGGING = { 'loggers': { 'devops': { 'handlers': ['file_handler', 'console_handler'], 'level': 'DEBUG', }, }, }
想要了解更多logger,详情请参考:https://yiyibooks.cn/xx/python_352/library/logging.html#logger-objects。
五.处理程序(Handler)
1>.Handler决定如何处理logger中的每条消息。它表示一个特定的日志行为,例如将消息写到屏幕上,写到文件中或者写到网络socket。
2>.与logger一样,handler也有一个日志级别。如果消息的日志级别小雨handler的级别,handler将忽略该消息。
3>.Logger可以有多个handler,而每个handler可以有不同的日志级别。利用这种方式,可以根据消息的重要性提供不同形式的处理。
"handlers": { "file": { "level": "DEBUG", "class": "logging.handlers.TimedRotatingFileHandler", "filename": os.path.join(BASE_DIR, "logs", "debug.log"), "when":"S", "interval":5, "formatter": "default" }, },
想要了解更多handler,详情请参考:https://yiyibooks.cn/xx/python_352/library/logging.html#handler-objects。
想要了解更多loggin-handler,详情请参考:https://yiyibooks.cn/xx/python_352/library/logging.handlers.html。
六.过滤器(Filters)
1>.Filter用于对从logger传递给handler的日志记录进行额外的控制。
2>.默认情况下,满足日志级别的任何消息都将被处理。通过安装一个filter,你可以对日志处理添加额外的条件。例如,你可以安装一个filter,只允许处理来自特定源的ERROR消息;
3>.Filters还可以用于修改将要处理的日志记录的优先级。例如,如果日志记录满足特定的条件,你可以编写一个filter将日志记录从ERROR将为WARNING(我想说然而并没有什么乱用!);
4>.Filters可以安装在logger是那个或者多个handler上;多个filter可以串联起来实现多层filter行为;
七.格式化(Formatters)
日志记录需要转换成文本。Formatter表示文本的格式。Fomatter通常由包含日志记录属性的Python格式字符串组成;你也可以编写自定义的fomatter来实现自己的格式。
LOGGING = { 'formatters': { ‘devops’:{ 'format': '%(asctime)s - %(pathname)s:%(lineno)d[%(levelname)s] - %(message)s' } 'simple': { 'format': '%(asctime)s %(levelname)s %(message)s' }, }, }
更多formatters,详情请参考:https://yiyibooks.cn/xx/python_352/library/logging.html#formatter-objects。
Format日志消息格式 描述 %(name)s 记录器的名称 %(levelno)s 数字形式的日志记录级别 %(levelname)s 日志记录级别的文本名称 %(filename)s 执行日志记录调用的源文件的文件名称 %(pathname)s 执行日志记录调用的源文件的路径名称 %(funcName)s 执行日志记录调用的函数名称 %(module)s 执行日志记录调用的模块名称 %(lineno)s 执行日志记录调用的行号 %(created)s 执行日志记录的时间 %(asctime)s 日期和时间 %(msecs)s 毫秒部分 %(thread)s 线程ID %(threadName)s 线程名称 %(process)s 进程ID %(message)s 记录的消息
八.Django内置logger
1>.django
获取所有日志。
2>.django.request
处理与请求相关的日志,5xx响应报出error,400报出WARNING日志。
3>.django.db.backends
处理与数据库之间的交互的日志。
4>.django.security.*
处理与安全相关的日志。
5>.django.db.backends.schemea
处理数据库迁移时的日志。
想要了解更多Django内置的logger详情请参考:https://docs.djangoproject.com/en/1.11/topics/logging/#id3
九.使用python的logging模块案例展示
"""DevOps URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.11/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ from django.conf.urls import url,include from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), url(r"^dashboard/",include("dashboard.urls")) ]
#!/usr/bin/env python #_*_conding:utf-8_*_ #@author :yinzhengjie #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ from django.conf.urls import url from . import views urlpatterns = [ url(r"^login/",views.LoginView.as_view()), url(r"^index/", views.MyPageView.as_view()), ]
""" Django settings for DevOps project. Generated by 'django-admin startproject' using Django 1.11.11. For more information on this file, see https://docs.djangoproject.com/en/1.11/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/1.11/ref/settings/ """ import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'fobwai!6%)9$$-*+&5v9-s_p3-e5=5jb9%7ko131o_g&eu8d+@' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True ALLOWED_HOSTS = ["*"] # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'dashboard.apps.DashboardConfig', ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', # 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ROOT_URLCONF = 'DevOps.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')] , 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = 'DevOps.wsgi.application' # Database # https://docs.djangoproject.com/en/1.11/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # 连接的数据库类型 'HOST': '127.0.0.1', # 连接数据库的地址 'PORT': 3306, # 端口 'NAME': "devops", # 数据库名称 'USER': 'root', # 用户 'PASSWORD': 'yinzhengjie' # 密码 } } # Password validation # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] # Internationalization # https://docs.djangoproject.com/en/1.11/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.11/howto/static-files/ STATIC_URL = '/static/' LOGGING = { "version": 1, 'disable_existing_loggers': False, #一般情况下设置为False,表示不禁用Django的默认配置 'formatters': { 'devops': { 'format': '[%(asctime)s] [%(process)d] [%(thread)d] [%(filename)16s:%(lineno)4d] [%(levelname)-6s] %(message)s' }, 'simple': { 'format': '%(asctime)s %(levelname)s %(message)s' }, 'default': { 'format': '%(asctime)s %(levelname)s %(pathname)s [ %(lineno)s] %(message)s', "datefmt":"%Y-%m-%d %H:%M:%S" } }, "handlers": { "console": { "level": "DEBUG", "class": "logging.StreamHandler", "formatter": "simple" }, "file": { "level": "DEBUG", "class": "logging.FileHandler", "filename": os.path.join(BASE_DIR, "logs", "django.log"), "formatter": "default" }, }, "loggers":{ "yinzhnegjie-devops": { "level": "DEBUG", #配置日志级别 "handlers": ["console","file"], #指定具体的对象去写 'propagate': False, #是否向上传播日志 }, }, }
dashboard的APP对应的views.py视图函数编写的代码如下:
#!/usr/bin/env python #_*_conding:utf-8_*_ #@author :yinzhengjie #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ from django.http import HttpResponse,JsonResponse from django.shortcuts import render from django.views import View from django.contrib.auth.models import User import logging # 注意,下面的“yinzhnegjie-devops”字符串摘自“setting.py”中LOGGING对应的loggers所属的value值。换句话说,就是这个字符串必须在setting.py中定义! logger = logging.getLogger("yinzhnegjie-devops") class LoginView(View): def get(self,request): return render(request,"login.html") def post(self,request): print("调用了POST方法!") return HttpResponse("post...") class MyPageView(View): def get(self,request,*args,**kwargs): #我们在代码中写入日志 logger.debug("这是第一条日志") #定义每个页码显示信息的条数 Number_of_per_page = 10 try: #获取到用户传递过来的查询页码 page = int(request.GET.get("page",1)) except: #如果用户没有传递要查询的页码,我们这里给其设置一个默认值1,即显示第一页。 page = 1 #定义查询的起始位置 end = page * 10 start = end - 10 #定义查询的语句,注意这里并没有去数据库直接查询语句,这里只是定义好了要查询的SQL语句 queryset = User.objects.all()[start:end] #触发SQL语句,并将查询的结果转换成JSON格式 data = list(queryset.values("id","username","email")) return JsonResponse(data,safe=False)
访问浏览器,查看对应的服务器URL配置,如下图所示:
十.使用Django内置的logger案例展示
"""DevOps URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.11/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ from django.conf.urls import url,include from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), url(r"^dashboard/",include("dashboard.urls")) ]
""" Django settings for DevOps project. Generated by 'django-admin startproject' using Django 1.11.11. For more information on this file, see https://docs.djangoproject.com/en/1.11/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/1.11/ref/settings/ """ import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'fobwai!6%)9$$-*+&5v9-s_p3-e5=5jb9%7ko131o_g&eu8d+@' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True ALLOWED_HOSTS = ["*"] # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'dashboard.apps.DashboardConfig', ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', # 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ROOT_URLCONF = 'DevOps.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')] , 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = 'DevOps.wsgi.application' # Database # https://docs.djangoproject.com/en/1.11/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # 连接的数据库类型 'HOST': '127.0.0.1', # 连接数据库的地址 'PORT': 3306, # 端口 'NAME': "devops", # 数据库名称 'USER': 'root', # 用户 'PASSWORD': 'yinzhengjie' # 密码 } } # Password validation # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] # Internationalization # https://docs.djangoproject.com/en/1.11/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.11/howto/static-files/ STATIC_URL = '/static/' LOGGING = { "version": 1, 'disable_existing_loggers': False, #一般情况下设置为False,表示不禁用Django的默认配置 'formatters': { 'devops': { 'format': '[%(asctime)s] [%(process)d] [%(thread)d] [%(filename)16s:%(lineno)4d] [%(levelname)-6s] %(message)s' }, 'simple': { 'format': '%(asctime)s %(message)s' }, 'default': { 'format': '%(asctime)s %(name)s %(levelno)s %(levelname)s %(message)s', "datefmt":"%Y-%m-%d %H:%M:%S" } }, "handlers": { "console": { "level": "DEBUG", "class": "logging.StreamHandler", "formatter": "simple" }, "file": { "level": "DEBUG", "class": "logging.FileHandler", "filename": os.path.join(BASE_DIR, "logs", "debug.log"), "formatter": "default" }, "request":{ "level": "DEBUG", "class": "logging.FileHandler", "filename": os.path.join(BASE_DIR, "logs", "request.log"), "formatter": "default" }, "server": { "level": "DEBUG", "class": "logging.FileHandler", "filename": os.path.join(BASE_DIR, "logs", "server.log"), "formatter": "default" }, "root": { "level": "DEBUG", "class": "logging.FileHandler", "filename": os.path.join(BASE_DIR, "logs", "root.log"), "formatter": "default" }, "db_backends":{ "level": "DEBUG", "class": "logging.FileHandler", "filename": os.path.join(BASE_DIR, "logs", "db_backends.log"), "formatter": "default" } }, "loggers":{ "yinzhnegjie-devops": { "level": "DEBUG", #配置日志级别 "handlers": ["console","file"], #指定具体的对象去写 'propagate': False, #是否向上传播日志 }, "django":{ "level": "DEBUG", "handlers": [ "console","file"], 'propagate': False, }, "django.request": { "level": "DEBUG", "handlers": ["request"], 'propagate': False, }, "django.sever": { "level": "DEBUG", "handlers": ["server"], 'propagate': False, }, "django.db.backends":{ "level": "DEBUG", "handlers": ["db_backends"], 'propagate': False, } }, #定义自己的日志,我们需要下级的 'propagate'的值设置为False。 "root": { "level": "DEBUG", "handlers": ["root"], }, }
#!/usr/bin/env python #_*_conding:utf-8_*_ #@author :yinzhengjie #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ from django.conf.urls import url from . import views urlpatterns = [ url(r"^login/",views.LoginView.as_view()), url(r"^index/", views.MyPageView.as_view()), ]
dashboard的APP对应的views.py视图函数编写的代码如下:
#!/usr/bin/env python #_*_conding:utf-8_*_ #@author :yinzhengjie #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ from django.http import HttpResponse,JsonResponse from django.shortcuts import render from django.views import View from django.contrib.auth.models import User import logging # 定义logger的名字,默认情况下我们都会写成“__name__”,表示当前模块或者当前文件的相对路径。 logger = logging.getLogger(__name__) class LoginView(View): def get(self,request): return render(request,"login.html") def post(self,request): print("调用了POST方法!") return HttpResponse("post...") class MyPageView(View): def get(self,request,*args,**kwargs): #我们在代码中写入日志 logger.debug("这是第一条日志!") #定义每个页码显示信息的条数 Number_of_per_page = 10 try: #获取到用户传递过来的查询页码 page = int(request.GET.get("page",1)) except: #如果用户没有传递要查询的页码,我们这里给其设置一个默认值1,即显示第一页。 page = 1 #定义查询的起始位置 end = page * 10 start = end - 10 logger.warning("再来一条日志!") #定义查询的语句,注意这里并没有去数据库直接查询语句,这里只是定义好了要查询的SQL语句 queryset = User.objects.all()[start:end] #触发SQL语句,并将查询的结果转换成JSON格式 data = list(queryset.values("id","username","email")) return JsonResponse(data,safe=False)
访问浏览器,查看对应的服务器URL配置,如下图所示: