目录结构
- 官方默认自带的插件所在位置为:skywalking/plugins目录内
- 官方加载插件时会自动加载该目录内符合条件的全部模,详细加载判断逻辑可以查看plugins/init.py中的install方法
插件代码结构
- 官方默认提供了很多插件,用于处理常见的第三方库,其实现方式主要是利用猴子补丁在启动时对原有的第三方库中方法/函数对象进行替换,在原本的方法前后包裹需要的定制代码,用于在方法执行前后获取参数和返回值,进行记录/发送等处理。从某种程度上可以看作是装饰器。
- 插件模块的实现方式主要就是实现install方法,在后续加载时skywalking会自动运行插件模块中的install方法,实现对内容的替换,达到抓取数据的目的
修改抓取数据
- 相关数据记录到skywalking中的方法为:
- span.tag(TagHttpParams()) 用于记录该请求的参数,抓取到的数据会展示skywalking界面的http.params字段内
- span.tag(TagHttpMethod()) 用于记录该请求的请求方法,抓取到的数据会展示skywalking界面的http.method字段内
- span.tag(TagHttpURL()) 用于记录该请求的URL,抓取到的数据会展示skywalking界面的http.url字段内
- span.tag(TagHttpStatusCode()) 用于记录该请求的返回状态码,抓取到的数据会展示skywalking界面的http.status_code字段内
- span.tag(TagHttpStatusMsg()) 用于记录该请求的返回消息,抓取到的数据会展示skywalking界面的http.status_msg字段内
实现flask抓取json请求参数数据
with span:
span.layer = Layer.Http
span.component = Component.Flask
if all(environ_key in req.environ for environ_key in ('REMOTE_ADDR', 'REMOTE_PORT')):
span.peer = f"{req.environ['REMOTE_ADDR']}:{req.environ['REMOTE_PORT']}"
span.tag(TagHttpMethod(method))
span.tag(TagHttpURL(req.url.split('?')[0]))
if config.flask_collect_http_params:
# 获取form或者args格式的参数数据
if req.values:
span.tag(TagHttpParams(params_tostring(req.values)[0:config.http_params_length_threshold]))
# 获取json格式的请求参数数据
elif req.is_json and req.json:
span.tag(TagHttpParams(json.dumps(req.json, ensure_ascii=False, indent=2)[0:config.http_params_length_threshold]))
resp = _full_dispatch_request(this)
- 额外添加获取json格式数据的逻辑,当请求数据为json时将数据记录到params中,解决无法获取到json数据的问题
实现requests请求抓取请求参数
span.tag(TagHttpMethod(method.upper()))
span.tag(TagHttpURL(url_param.geturl()))
res = _request(this, method, url, params, data, headers, cookies, files, auth, timeout,allow_redirects,proxies, hooks, stream, verify, cert, json)
# 获取get方法的请求参数
if method.upper() == 'GET':
params_string = dict_params_tostring(params)[0:config.http_params_length_threshold]
# 获取其它方法的请求参数(byte类型)
else:
params_string = res.request.body[0:config.http_params_length_threshold]
span.tag(TagHttpParams(params_string))
span.tag(TagHttpStatusCode(res.status_code))
if res.status_code >= 400:
span.error_occurred = True
- 通过添加requests的参数获取逻辑,并将获取到的参数通过TagHttpParams方法保存到参数中,体现在skywalking内
skywalking python打包的坑
- 由于项目中使用了子模块protocol,并且子模块本身的位置并不在项目实际目录中,无法直接通过pip安装git仓库的方式进行项目的安装,改版的项目也需要打包成whl包,才能用来给环境安装。
- 首先保证拉取的代码中protocol子模块内容完整,之后在项目根目录运行命令
python3 tools/codegen.py
将protocol目录中的内容生成到skywalking目录下。
- 再使用
python3 setup.py bdist_wheel
命令,将代码打包成whl包,用于后续环境安装使用。