Kaynağa Gözat

funboost测试代码

peng 2 yıl önce
ebeveyn
işleme
932496ce55

+ 0 - 18
Controller/TestApi.py

@@ -38,7 +38,6 @@ from Object.TokenObject import TokenObject
 from Object.m3u8generate import PlaylistGenerator
 from Service.CommonService import CommonService
 from Service.VodHlsService import SplitVodHlsObject
-# from funboost import boost, BrokerEnum, funboost_aps_scheduler
 
 ACCESS_KEY = "AKIA2E67UIMD3CYTIWPA"
 SECRET_KEY = "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"
@@ -128,8 +127,6 @@ class testView(View):
             return self.ali_text_review(request_dict, response)
         elif operation == 'ali_image_review':  # 阿里云图片审核
             return self.ali_image_review(request_dict, response)
-        # elif operation == 'funboost':  # funboost测试
-        #     return self.funboost_test(request_dict, response)
         else:
             return response.json(414)
 
@@ -939,18 +936,3 @@ class testView(View):
         except Exception as e:
             return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
-    # @staticmethod
-    # @boost("task_queue_name1", qps=0.5, broker_kind=BrokerEnum.REDIS_ACK_ABLE)  # 入参包括20种,运行控制方式非常多,想得到的控制都会有。
-    # def task_fun(x, y):
-    #     print(f'{x} + {y} = {x + y}')
-    #     return True
-    #
-    #
-    # def funboost_test(self, request_dict, response):
-    #     # self.task_fun.push(x=5, y=6)
-    #     self.task_fun.clear()
-    #     funboost_aps_scheduler.start()
-    #     funboost_aps_scheduler.add_push_job(self.task_fun, 'interval', id='3_second_job', seconds=60,
-    #                                         kwargs={"x": 5, "y": 6})  # 每隔3秒发布一次任务,自然就能每隔3秒消费一次任务了。
-    #     self.task_fun.consume()
-    #     return response.json(0)

+ 157 - 0
Object/FunboostFrameWork/funboost_config.py

@@ -0,0 +1,157 @@
+# -*- coding: utf-8 -*-
+
+from pathlib import Path
+import pytz
+from funboost.constant import BrokerEnum, ConcurrentModeEnum
+from funboost.core.function_result_status_saver import FunctionResultStatusPersistanceConfig
+from funboost.utils.simple_data_class import DataClassBase
+'''
+此文件是第一次运行框架自动生成刀项目根目录的,不需要用由户手动创建。
+此文件里面可以写任意python代码。例如 中间件 帐号 密码自己完全可以从apola配置中心获取或者从环境变量获取。
+'''
+
+'''
+你项目根目录下自动生成的 funboost_config.py 文件中修改配置,会被自动读取到。
+用户不要动修改框架的源码 funboost/funboost_config_deafult.py 中的代码,此模块的变量会自动被 funboost_config.py 覆盖。
+
+此文件按需修改,例如你使用redis中间件作为消息队列,可以不用管rabbitmq mongodb kafka啥的配置。
+但有3个功能例外,如果你需要使用rpc模式或者分布式控频或者任务过滤功能,无论设置使用何种消息队列中间件都需要把redis连接配置好,
+如果@boost装饰器设置is_using_rpc_mode为True或者 is_using_distributed_frequency_control为True或do_task_filtering=True则需要把redis连接配置好,默认是False。
+
+
+框架使用文档是 https://funboost.readthedocs.io/zh_CN/latest/
+
+'''
+
+# $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$  以下是中间件连接配置    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
+
+
+MONGO_CONNECT_URL = f'mongodb://127.0.0.1:27017'  # 如果有密码连接 'mongodb://myUserAdmin:8mwTdy1klnSYepNo@192.168.199.202:27016/'   authSource 指定鉴权db,MONGO_CONNECT_URL = 'mongodb://root:123456@192.168.64.151:27017?authSource=admin'
+
+RABBITMQ_USER = 'rabbitmq_user'
+RABBITMQ_PASS = 'rabbitmq_pass'
+RABBITMQ_HOST = '127.0.0.1'
+RABBITMQ_PORT = 5672
+RABBITMQ_VIRTUAL_HOST = ''  # my_host # 这个是rabbitmq的虚拟子host用户自己创建的,如果你想直接用rabbitmq的根host而不是使用虚拟子host,这里写 空字符串 即可。
+RABBITMQ_URL= f'amqp://{RABBITMQ_USER}:{RABBITMQ_PASS}@{RABBITMQ_HOST}:{RABBITMQ_PORT}/{RABBITMQ_VIRTUAL_HOST}'
+
+REDIS_HOST = '127.0.0.1'
+REDIS_PASSWORD = ''
+REDIS_PORT = 6379
+REDIS_DB = 7  # redis消息队列所在db,请不要在这个db放太多其他键值对,框架里面有的功能会scan扫描unacked的键名,使用单独的db。
+REDIS_DB_FILTER_AND_RPC_RESULT = 8  # 如果函数做任务参数过滤 或者使用rpc获取结果,使用这个db,因为这个db的键值对多,和redis消息队列db分开
+REDIS_URL= f'redis://:{REDIS_PASSWORD}@{REDIS_HOST}:{REDIS_PORT}/{REDIS_DB}'
+
+NSQD_TCP_ADDRESSES = ['127.0.0.1:4150']
+NSQD_HTTP_CLIENT_HOST = '127.0.0.1'
+NSQD_HTTP_CLIENT_PORT = 4151
+
+KAFKA_BOOTSTRAP_SERVERS = ['127.0.0.1:9092']
+
+SQLACHEMY_ENGINE_URL = 'sqlite:////sqlachemy_queues/queues.db'
+
+# 如果broker_kind 使用 peewee 中间件模式会使用mysql配置
+MYSQL_HOST = '127.0.0.1'
+MYSQL_PORT = 3306
+MYSQL_USER = 'root'
+MYSQL_PASSWORD = '123456'
+MYSQL_DATABASE = 'testdb6'
+
+# persist_quque中间件时候采用本机sqlite的方式,数据库文件生成的位置。如果linux账号在根目录没权限建文件夹,可以换文件夹。
+SQLLITE_QUEUES_PATH = '/sqllite_queues'
+
+TXT_FILE_PATH = Path(__file__).parent / 'txt_queues'  # 不建议使用这个txt模拟消息队列中间件,本地持久化优先选择 PERSIST_QUQUE 中间件。
+
+ROCKETMQ_NAMESRV_ADDR = '192.168.199.202:9876'
+
+MQTT_HOST = '127.0.0.1'
+MQTT_TCP_PORT = 1883
+
+HTTPSQS_HOST = '127.0.0.1'
+HTTPSQS_PORT = '1218'
+HTTPSQS_AUTH = '123456'
+
+NATS_URL = 'nats://192.168.6.134:4222'
+
+KOMBU_URL = 'redis://127.0.0.1:6379/9'  # 这个就是celery依赖包kombu使用的消息队列格式,所以funboost支持一切celery支持的消息队列种类。
+# KOMBU_URL =  'sqla+sqlite:////dssf_kombu_sqlite.sqlite'  # 4个//// 代表磁盘根目录下生成一个文件。推荐绝对路径。3个///是相对路径。
+
+CELERY_BROKER_URL = 'redis://127.0.0.1:6379/12'  # 使用celery作为中间件。funboost新增支持celery框架来运行函数
+CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379/13'  # celery结果存放,可以为None
+
+DRAMATIQ_URL = RABBITMQ_URL
+
+PULSAR_URL = 'pulsar://192.168.70.128:6650'
+
+# $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 以上是中间件连接配置    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
+
+# nb_log包的第几个日志模板,内置了7个模板,可以在你当前项目根目录下的nb_log_config.py文件扩展模板。
+NB_LOG_FORMATER_INDEX_FOR_CONSUMER_AND_PUBLISHER = 11  # 7是简短的不可跳转,5是可点击跳转的,11是可显示ip 进程 线程的模板。
+FSDF_DEVELOP_LOG_LEVEL = 50  # 作者开发时候的调试代码的日志,仅供我自己用,所以日志级别跳到最高,用户不需要管。
+
+TIMEZONE = 'Asia/Shanghai'
+
+
+
+
+
+
+
+
+# *********************************************** 以下是 boost装饰器的默认全局配置 *******************************************
+"""
+BoostDecoratorDefaultParams是@boost装饰器默认的全局入参。如果boost没有亲自指定某个入参,就自动使用这里的配置。
+这里的值不用配置,在boost装饰器中可以为每个消费者指定不同的入参,除非你嫌弃每个 boost 装饰器相同入参太多了,那么可以设置这里的全局默认值。
+
+例如用户不想每次在boost装饰器指定broker_kind为哪种消息队列,可以设置broker_kind为用户自己希望的默认消息队列类型
+
+boost入参可以ide跳转到boost函数的docstring查看
+boost入参也可以看文档3.3章节  https://funboost.readthedocs.io/zh/latest/articles/c3.html  
+
+BoostDecoratorDefaultParams这个类的属性名字和boost装饰器的入参名字一模一样,只有 queue_name 必须每个装饰器是不同的名字,不能作为全局的。
+所以boost装饰器只有一个是必传参数。
+"""
+
+
+class BoostDecoratorDefaultParams(DataClassBase):
+    concurrent_mode = ConcurrentModeEnum.THREADING
+    concurrent_num = 50
+    specify_concurrent_pool = None
+    specify_async_loop = None
+    qps: float = 0
+    is_using_distributed_frequency_control = False
+    is_send_consumer_hearbeat_to_redis = False
+
+    max_retry_times = 3
+    is_push_to_dlx_queue_when_retry_max_times = False
+
+    consumin_function_decorator = None
+    function_timeout = 0
+
+    log_level = 10
+    logger_prefix = ''
+    create_logger_file = True
+    is_show_message_get_from_broker = False
+    is_print_detail_exception = True
+
+    msg_expire_senconds = 0
+
+    do_task_filtering = False
+    task_filtering_expire_seconds = 0
+
+    function_result_status_persistance_conf = FunctionResultStatusPersistanceConfig(False, False, 7 * 24 * 3600)
+    user_custom_record_process_info_func = None
+
+    is_using_rpc_mode = False
+    is_support_remote_kill_task = False
+
+    is_do_not_run_by_specify_time_effect = False
+    do_not_run_by_specify_time = ('10:00:00', '22:00:00')
+
+    schedule_tasks_on_main_thread = False
+
+    broker_exclusive_config = {}
+
+    broker_kind: int = BrokerEnum.PERSISTQUEUE  # 中间件选型见3.1章节 https://funboost.readthedocs.io/zh/latest/articles/c3.html
+
+# *********************************************** 以上是 boost装饰器的默认全局配置 *******************************************

+ 20 - 0
Object/FunboostFrameWork/funboost_task.py

@@ -0,0 +1,20 @@
+import time
+from funboost import boost, BrokerEnum, run_forever, funboost_aps_scheduler
+
+
+@boost("task_queue_name1", qps=0.5, broker_kind=BrokerEnum.REDIS_ACK_ABLE)  # 入参包括20种,运行控制方式非常多,想得到的控制都会有。
+def task_fun(x, y):
+    print(f'{x} + {y} = {x + y}')
+    time.sleep(3)  # 框架会自动并发绕开这个阻塞,无论函数内部随机耗时多久都能自动调节并发达到每秒运行 5 次 这个 task_fun 函数的目的。
+    return True
+
+
+if __name__ == "__main__":
+    # for i in range(2):
+    #     task_fun.pub(dict(x=i, y=i * 2))
+    #     task_fun.push(i, y=i * 2)  # 发布者发布任务
+    funboost_aps_scheduler.add_push_job(task_fun, 'cron', day_of_week='*', hour=16, minute=50, second=00,
+                                        kwargs={"x": 5, "y": 6})  # 每隔3秒发布一次任务,自然就能每隔3秒消费一次任务了。
+    funboost_aps_scheduler.start()
+    task_fun.consume()  # 消费者启动循环调度并发消费任务
+    run_forever()

+ 150 - 0
Object/FunboostFrameWork/nb_log_config.py

@@ -0,0 +1,150 @@
+# coding=utf8
+"""
+此文件nb_log_config.py是自动生成到python项目的根目录的,因为是自动生成到 sys.path[1]。
+在这里面写的变量会覆盖此文件nb_log_config_default中的值。对nb_log包进行默认的配置。用户是无需修改nb_log安装包位置里面的配置文件的。
+
+但最终配置方式是由get_logger_and_add_handlers方法的各种传参决定,如果方法相应的传参为None则使用这里面的配置。
+"""
+
+"""
+如果反对日志有各种彩色,可以设置 DEFAULUT_USE_COLOR_HANDLER = False
+如果反对日志有块状背景彩色,可以设置 DISPLAY_BACKGROUD_COLOR_IN_CONSOLE = False
+如果想屏蔽nb_log包对怎么设置pycahrm的颜色的提示,可以设置 WARNING_PYCHARM_COLOR_SETINGS = False
+如果想改变日志模板,可以设置 FORMATTER_KIND 参数,只带了7种模板,可以自定义添加喜欢的模板
+LOG_PATH 配置文件日志的保存路径的文件夹。
+"""
+import sys
+# noinspection PyUnresolvedReferences
+import logging
+import os
+# noinspection PyUnresolvedReferences
+from pathlib import Path  # noqa
+import socket
+from pythonjsonlogger.jsonlogger import JsonFormatter
+
+
+def get_host_ip():
+    ip = ''
+    host_name = ''
+    # noinspection PyBroadException
+    try:
+        sc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+        sc.connect(('8.8.8.8', 80))
+        ip = sc.getsockname()[0]
+        host_name = socket.gethostname()
+        sc.close()
+    except Exception:
+        pass
+    return ip, host_name
+
+
+computer_ip, computer_name = get_host_ip()
+
+
+class JsonFormatterJumpAble(JsonFormatter):
+    def add_fields(self, log_record, record, message_dict):
+        # log_record['jump_click']   = f"""File '{record.__dict__.get('pathname')}', line {record.__dict__.get('lineno')}"""
+        log_record[f"{record.__dict__.get('pathname')}:{record.__dict__.get('lineno')}"] = ''  # 加个能点击跳转的字段。
+        log_record['ip'] = computer_ip
+        log_record['host_name'] = computer_name
+        super().add_fields(log_record, record, message_dict)
+        if 'for_segmentation_color' in log_record:
+            del log_record['for_segmentation_color']
+
+
+DING_TALK_TOKEN = '3dd0eexxxxxadab014bd604XXXXXXXXXXXX'  # 钉钉报警机器人
+
+EMAIL_HOST = ('smtp.sohu.com', 465)
+EMAIL_FROMADDR = 'aaa0509@sohu.com'  # 'matafyhotel-techl@matafy.com',
+EMAIL_TOADDRS = ('cccc.cheng@silknets.com', 'yan@dingtalk.com',)
+EMAIL_CREDENTIALS = ('aaa0509@sohu.com', 'abcdefg')
+
+ELASTIC_HOST = '127.0.0.1'
+ELASTIC_PORT = 9200
+
+KAFKA_BOOTSTRAP_SERVERS = ['192.168.199.202:9092']
+ALWAYS_ADD_KAFKA_HANDLER_IN_TEST_ENVIRONENT = False
+
+MONGO_URL = 'mongodb://myUserAdmin:mimamiama@127.0.0.1:27016/admin'
+
+# 项目中的print是否自动写入到文件中。值为None则不重定向print到文件中。 自动每天一个文件, 2023-06-30.my_proj.print,生成的文件位置在定义的LOG_PATH
+# 如果你设置了环境变量,export PRINT_WRTIE_FILE_NAME="my_proj.print" (linux临时环境变量语法,windows语法自己百度这里不举例),那就优先使用环境变量中设置的文件名字,而不是nb_log_config.py中设置的名字
+PRINT_WRTIE_FILE_NAME = Path(sys.path[1]).name + '.print'
+
+# 项目中的所有标准输出(不仅包括print,还包括了streamHandler日志)都写入到这个文件,为None将不把标准输出重定向到文件。自动每天一个文件, 2023-06-30.my_proj.std,生成的文件位置在定义的LOG_PATH
+# 如果你设置了环境变量,export SYS_STD_FILE_NAME="my_proj.std"  (linux临时环境变量语法,windows语法自己百度这里不举例),那就优先使用环境变量中设置的文件名字,,而不是nb_log_config.py中设置的名字
+SYS_STD_FILE_NAME = Path(sys.path[1]).name + '.std'
+
+USE_BULK_STDOUT_ON_WINDOWS = True # 在win上是否每隔0.1秒批量stdout,win的io太差了
+
+DEFAULUT_USE_COLOR_HANDLER = True  # 是否默认使用有彩的日志。
+DISPLAY_BACKGROUD_COLOR_IN_CONSOLE = True  # 在控制台是否显示彩色块状的日志。为False则不使用大块的背景颜色。
+AUTO_PATCH_PRINT = True  # 是否自动打print的猴子补丁,如果打了猴子补丁,print自动变色和可点击跳转。
+SHOW_PYCHARM_COLOR_SETINGS = True  # 有的人很反感启动代码时候提示教你怎么优化pycahrm控制台颜色,可以把这里设置为False
+
+DEFAULT_ADD_MULTIPROCESSING_SAFE_ROATING_FILE_HANDLER = False  # 是否默认同时将日志记录到记log文件记事本中,就是用户不指定 log_filename的值,会自动写入日志命名空间.log文件中。
+LOG_FILE_SIZE = 100  # 单位是M,每个文件的切片大小,超过多少后就自动切割
+LOG_FILE_BACKUP_COUNT = 10  # 对同一个日志文件,默认最多备份几个文件,超过就删除了。
+
+LOG_PATH = '/pythonlogs'  # 默认的日志文件夹,如果不写明磁盘名,则是项目代码所在磁盘的根目录下的/pythonlogs
+# LOG_PATH = Path(__file__).absolute().parent / Path("pythonlogs")   #这么配置就会自动在你项目的根目录下创建pythonlogs文件夹了并写入。
+if os.name == 'posix':  # linux非root用户和mac用户无法操作 /pythonlogs 文件夹,没有权限,默认修改为   home/[username]  下面了。例如你的linux用户名是  xiaomin,那么默认会创建并在 /home/xiaomin/pythonlogs文件夹下写入日志文件。
+    home_path = os.environ.get("HOME", '/')  # 这个是获取linux系统的当前用户的主目录,不需要亲自设置
+    LOG_PATH = Path(home_path) / Path('pythonlogs')  # linux mac 权限很严格,非root权限不能在/pythonlogs写入,修改一下默认值。
+# print('LOG_PATH:',LOG_PATH)
+
+LOG_FILE_HANDLER_TYPE = 6  # 1 2 3 4 5 6
+"""
+LOG_FILE_HANDLER_TYPE 这个值可以设置为 1 2 3 4 5 四种值,
+1为使用多进程安全按日志文件大小切割的文件日志,这是本人实现的批量写入日志,减少操作文件锁次数,测试10进程快速写入文件,win上性能比第5种提高了100倍,linux提升5倍
+2为多进程安全按天自动切割的文件日志,同一个文件,每天生成一个新的日志文件。日志文件名字后缀自动加上日期。
+3为不自动切割的单个文件的日志(不切割文件就不会出现所谓进程安不安全的问题) 
+4为 WatchedFileHandler,这个是需要在linux下才能使用,需要借助lograte外力进行日志文件的切割,多进程安全。
+5 为第三方的concurrent_log_handler.ConcurrentRotatingFileHandler按日志文件大小切割的文件日志,
+   这个是采用了文件锁,多进程安全切割,文件锁在linux上使用fcntl性能还行,win上使用win32con性能非常惨。按大小切割建议不要选第5个个filehandler而是选择第1个。
+6 BothDayAndSizeRotatingFileHandler 使用本人完全彻底开发的,同时按照时间和大小切割,无论是文件的大小、还是时间达到了需要切割的条件就切割。
+"""
+
+LOG_LEVEL_FILTER = logging.DEBUG  # 默认日志级别,低于此级别的日志不记录了。例如设置为INFO,那么logger.debug的不会记录,只会记录logger.info以上级别的。
+# 强烈不建议调高这里的级别为INFO,日志是有命名空间的,单独提高打印啰嗦的日志命名空间的日志级别就可以了,不要全局提高日志级别。
+# https://nb-log-doc.readthedocs.io/zh_CN/latest/articles/c9.html#id2  文档9.5里面讲了几百次 python logging的命名空间的作用了,有些人到现在还不知道日志的name作用。
+
+# 屏蔽的字符串显示,用 if in {打印信息} 来判断实现的,如果打印的消息中包括 FILTER_WORDS_PRINT 数组中的任何一个字符串,那么消息就不执行打印。
+# 这个配置对 print 和 logger的控制台输出都生效。这个可以过滤某些啰嗦的print信息,也可以过滤同级别日志中的某些烦人的日志。可以用来过滤三方包中某些控制台打印。数组不要配置过多,否则有一丝丝影响性能会。
+FILTER_WORDS_PRINT = []  # 例如, 你希望消息中包括阿弥陀佛 或者 包括善哉善哉 就不打印,那么可以设置  FILTER_WORDS_PRINT = ['阿弥陀佛','善哉善哉']
+
+RUN_ENV = 'test'
+
+FORMATTER_DICT = {
+    1: logging.Formatter(
+        '日志时间【%(asctime)s】 - 日志名称【%(name)s】 - 文件【%(filename)s】 - 第【%(lineno)d】行 - 日志等级【%(levelname)s】 - 日志信息【%(message)s】',
+        "%Y-%m-%d %H:%M:%S"),
+    2: logging.Formatter(
+        '%(asctime)s - %(name)s - %(filename)s - %(funcName)s - %(lineno)d - %(levelname)s - %(message)s',
+        "%Y-%m-%d %H:%M:%S"),
+    3: logging.Formatter(
+        '%(asctime)s - %(name)s - 【 File "%(pathname)s", line %(lineno)d, in %(funcName)s 】 - %(levelname)s - %(message)s',
+        "%Y-%m-%d %H:%M:%S"),  # 一个模仿traceback异常的可跳转到打印日志地方的模板
+    4: logging.Formatter(
+        '%(asctime)s - %(name)s - "%(filename)s" - %(funcName)s - %(lineno)d - %(levelname)s - %(message)s -               File "%(pathname)s", line %(lineno)d ',
+        "%Y-%m-%d %H:%M:%S"),  # 这个也支持日志跳转
+    5: logging.Formatter(
+        '%(asctime)s - %(name)s - "%(pathname)s:%(lineno)d" - %(funcName)s - %(levelname)s - %(message)s',
+        "%Y-%m-%d %H:%M:%S"),  # 我认为的最好的模板,推荐
+    6: logging.Formatter('%(name)s - %(asctime)-15s - %(filename)s - %(lineno)d - %(levelname)s: %(message)s',
+                         "%Y-%m-%d %H:%M:%S"),
+    7: logging.Formatter('%(asctime)s - %(name)s - "%(filename)s:%(lineno)d" - %(levelname)s - %(message)s', "%Y-%m-%d %H:%M:%S"),  # 一个只显示简短文件名和所处行数的日志模板
+
+    8: JsonFormatterJumpAble('%(asctime)s - %(name)s - %(levelname)s - %(message)s - %(filename)s %(lineno)d  %(process)d %(thread)d', "%Y-%m-%d %H:%M:%S.%f",
+                             json_ensure_ascii=False),  # 这个是json日志,方便elk采集分析.
+
+    9: logging.Formatter(
+        '[p%(process)d_t%(thread)d] %(asctime)s - %(name)s - "%(pathname)s:%(lineno)d" - %(funcName)s - %(levelname)s - %(message)s',
+        "%Y-%m-%d %H:%M:%S"),  # 对5改进,带进程和线程显示的日志模板。
+    10: logging.Formatter(
+        '[p%(process)d_t%(thread)d] %(asctime)s - %(name)s - "%(filename)s:%(lineno)d" - %(levelname)s - %(message)s', "%Y-%m-%d %H:%M:%S"),  # 对7改进,带进程和线程显示的日志模板。
+    11: logging.Formatter(
+        f'({computer_ip},{computer_name})-[p%(process)d_t%(thread)d] %(asctime)s - %(name)s - "%(filename)s:%(lineno)d" - %(funcName)s - %(levelname)s - %(message)s', "%Y-%m-%d %H:%M:%S"),  # 对7改进,带进程和线程显示的日志模板以及ip和主机名。
+}
+
+FORMATTER_KIND = 5  # 如果get_logger不指定日志模板,则默认选择第几个模板