单机使用手册

1 服务管理

1.1 配置管理

1.1.1 配置全览

conf/config.py(APP 配置)

# coding:utf8
"""
Butterfly config
"""
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__)))

SERVER_LISTEN_ADDR = ("0.0.0.0", 8585)
SERVER_THREAD_NUM = 16
SERVER_NAME = "Butterfly_app"
# Reqid prefix, two characters
SERVER_ID = "BF"
SERVER_IDC = "default"

# static
STATIC_PATH = "static"
STATIC_PREFIX = "static"

# DB
"""
# wuxing/ruqi use default database
"""
DATABASES = {
    "default": "mysql+retrypool://root:password@127.0.0.1:3306/test?max_connections=300&stale_timeout=300",
}

# Redis
"""
# eg1:"redis://[[username]:[password]]@localhost:6379/0"
# eg2:"redis://@localhost:6379/0?socket_timeout=2&socket_connect_timeout=1&retry_on_timeout=true"
"""
CACHES = {
    "default": "redis://@localhost:6379/0",
    # for cache: connect_timeout 100ms, read_timeout 200ms
    # "wuxing": "redis://@localhost:6379/0?socket_timeout=0.2&socket_connect_timeout=0.1&retry_on_timeout=false",
    # for mq: connect_timeout 500ms, read_timeout 2000ms
    # "baichuan": "redis://@localhost:6379/0?socket_timeout=2&socket_connect_timeout=0.5&retry_on_timeout=false",
}

# Local data or cache
LOCALDATA_DIR = os.path.join(BASE_DIR, "data")

# Auth
SECRET_KEY = None               # If it is None, a key will be randomly generated each time butterfly is started
JWT_TOKEN_TTL = 28800           # default 8 hours
HEADER_USERNAME = "HTTP_X_USERNAME"

# Scheduler
scheduler_store = "memory"      # ("mysql"/"memory")

# Adaptor
"""
# {"stat":"ERR", "data":{}} --> {"stat":"ERR", "success":False, "message":"ERR", "data":{}}
STAT_ADAPTOR={"status_name":"success", "status_map":{"OK":True,"default":False}, "message_name":"message"}
"""
STAT_ADAPTOR = None

config/logger_conf.py(日志配置)

1.1.2 SERVER

1.1.3 LOG

1.1.4 STATIC

1.1.5 DB

1.1.6 Redis

1.1.7 LOCALDATA

存储本地数据目录

1.1.8 AUTH

  • SECRET_KEY : jwt SECRET_KEY

  • JWT_TOKEN_TTL : jwt token ttl

  • HEADER_USERNAME : 用户名 handler

    • 请求方法:若此项配置的 "HTTP_X_USERNAME" 则请求时可传 -H "x_username:meetbill" header

1.1.9 Scheduler

主要用于【如期】使用

1.1.10 Adaptor

用于扩展 API 接口的状态字段

STAT_ADAPTOR 需要有三个信息

  • status_name: 状态名

  • status_map: 状态映射,默认值为 "default" value, 若可以匹配到映射中的值,则以映射值为值

  • message_name: 信息名

1.2 启动管理

备注:bash run.sh docker_start 用于打 docker 镜像时使用

如何修改启动项标识

在日常使用中可能会在同一台机器上启动多个 butterfly,不同的 butterfly 提供着不同的服务,可能是测试服务,可能是做配置管理服务使用的,等等,当然这些 butterfly 的端口是不一样的,那如何根据进程看出是什么服务尼?

只需要在服务启动前修改下,run.sh 的 PROC_SIG="954216e9" 修改为想要使用的用途即可,比如 PROC_SIG="test_dev"

1.3 日志管理

1.3.1 启动日志

启动相关信息日志会记录在 __stdout

如果启动失败,可以在这个日志文件中找到原因

1.3.2 butterfly 框架日志

1.3.2.1 acc 访问日志

acc 日志路径在 logs/acc.log

日志内容

  • DATE: 2021-02-08

  • TIME: 21:35:30

  • PID : 91640

  • CODE_INFO: /meetbill/butterfly/xlib/httpgateway.py:259

  • IP: 127.0.0.1

  • REQID: 1FA15BDE4B6CD7A0 (请求 ID)

  • METHOD: GET

  • PATH: /demo_api/hello

  • COST: cost:0.000162 (整体耗时,单位是秒)

  • STAT: stat:OK (执行结果状态,若自定义 HTTP 方式时,则此处会是 HTTP 状态码)

  • USER: user:- (用户名)

  • TALK: talk:ceshi1=0.098;ceshi2=0.002 (代码片段耗时,比如一个 SQL 语句,请求 Redis 的耗时等)

  • PARAMS: params:str_info=hello (请求参数)

  • ERROR_MSG: error_msg:(错误信息)

  • RES: res:ceshi2=5.4;ceshi1=5.3 (需要记录的结果数据信息)

在 handler 逻辑中可以通过如下方式写入日志到 logs/acc.log

记录额外参数

记录程序运行耗时

记录错误信息(推荐)

使用此方式,错误日志不但可以记录到 acc.log , 而且响应头中也会返回给客户端此信息,如下:

记录 response 信息

req.log_res:(set)

1.3.2.2 err 异常日志

err 日志路径在 logs/err.log

例子(不常用,主要用于 butterfly 框架捕获未处理的异常逻辑使用)

1.3.2.3 init 日志

init 日志路径在 logs/init.log, 日志中会记录如下信息

  • 日志中会打印自动加载的 handler 的日志信息

  • 如果开启了 scheduler, 则打印 scheduler 是否启动成功

1.3.3 自定义日志输出

acc.log 和 err.log 均为框架本身产生的日志,用于接口统计以及服务异常排查问题等等

这里的自定义日志内容有两种方式

  • 将需要的日志,通过接口写入到 acc.log

  • 使用 logging 模块『推荐』,将日志写入 common.log 和 common.log.wf

这个来说明下如何使用 logging 将日志写入 common.log 和 common.log.wf

备注:

2 接口开发

2.1 编写函数(根据返回值,区分为两种方式)

2.1.1 推荐方式

(1) 函数文件

例子

返回值分别为:状态信息字段数据信息字段, 自定义 HTTP 报文头信息列表

2.1.2 自定义 HTTP 码返回方式

(1) 函数文件

(2) 编写对应方法

  • 参数

    • 第一个参数为 req, 固定

  • 返回值 (httpstatus, [content], [headers])

    • httpstatus: (int) 必须有

    • content: (str/dict) 非必须(当返回值为 2 个的时候,第 2 个返回值为 Content)

      • 当 content 为 dict 时,会自动转为 json ,并且设置 header("Content-Type","application/json")

      • 当 content 为其他时,会自动设置为 ("Content-Type","text/html")

    • headers: 非必须(当返回值为 3 个的时候,第 3 个返回值为 headers)

      如:

      返回值分别为:HTTP 返回码状态信息字段 + 数据信息字段, 自定义 HTTP 报文头信息列表

2.2 路由注册

(1) 函数文件

handlers package 和 handlers 下的 package 都会默认注册到路由中

2.3 访问接口函数

get 请求

Request:

同时可以使用 -v 查看额外 headers 信息,如下:

Response:

post 请求

request:

Response:

备注 1 :JSON 格式数据属性必须用双引号包裹

备注 2 :可传多级 json

python post 方式提交 json 字符串

2.4 handler 访问本目录文件

通过 cur_path 与文件进行拼接

3 手动测试 handler

测试方法

Last updated