摘要:是應(yīng)用性能管理監(jiān)控解決方案提供商。目錄是列出的命令腳本所在目錄。包含文件如下的函數(shù)是命令執(zhí)行的入口。而對于硬件信息的檢測則由進(jìn)行。文檔地址源碼仔細(xì)看下去,太復(fù)雜了。下一篇再分析一個(gè)請求到結(jié)束探針工作的完整過程吧。
Newrelic 是APM(Application Performance Management)(應(yīng)用性能管理/監(jiān)控)解決方案提供商。項(xiàng)目中,通常用它來追蹤應(yīng)用的性能。最近看了一下 newrelic-python-agent 源碼,這是查看源碼過程中的一些記錄。目錄結(jié)構(gòu)
newrelic 目錄結(jié)構(gòu)如下:
newrelic ├── admin # 常用命令 ├── api # 探針 ├── bootstrap ├── common ├── core ├── extras │ └── framework_django │ └── templatetags ├── hooks # 數(shù)據(jù)庫 web 各個(gè)庫的一些探針 │ ├── framework_tornado │ ├── framework_tornado_r3 │ └── framework_tornado_r4 ├── network ├── packages │ ├── requests │ │ └── packages │ │ ├── chardet │ │ └── urllib3 │ │ ├── packages │ │ │ └── ssl_match_hostname │ │ └── util │ └── wrapt └── samplers命令
使用 newrelic-admin help 可以列出所有命令:
$ newrelic-admin help Usage: newrelic-admin command [options] Type "newrelic-admin help"for help on a specific command. Available commands are: generate-config license-info license-key local-config network-config record-deploy run-program run-python server-config validate-config
通過 setup.py 代碼可以知道:
if with_setuptools: kwargs["entry_points"] = { "console_scripts": ["newrelic-admin = newrelic.admin:main"], }
newrelic-admin 命令調(diào)用的是 newrelic.admin:main,這是代碼的入口。首先看一下 newrelic/admin/目錄。
adminadmin 目錄是 newrelic-admin help 列出的命令腳本所在目錄。
包含文件如下:
$ tree admin ├── __init__.py ├── __main__.py ├── debug_console.py ├── generate_config.py ├── license_info.py ├── license_key.py ├── local_config.py ├── network_config.py ├── record_deploy.py ├── run_program.py ├── run_python.py ├── server_config.py └── validate_config.py
__init__.py 的 main 函數(shù) 是命令執(zhí)行的入口。
__init__.py 文件中代碼
load_internal_plugins() load_external_plugins()
用來加載 _builtin_plugins 中定義的命令。
run_program首先看下 run_program 命令,這個(gè)命令使用方式如下:
newrelic-admin run-program your command
newrelic/admin/run_program.py 中 run_program 函數(shù)有裝飾器 command,用來定義將命令以及相關(guān)說明添加到字典 _commands。
在 run_program 中代碼:
root_directory = os.path.dirname(root_directory) boot_directory = os.path.join(root_directory, "bootstrap") if "PYTHONPATH" in os.environ: path = os.environ["PYTHONPATH"].split(os.path.pathsep) if not boot_directory in path: python_path = "%s%s%s" % (boot_directory, os.path.pathsep, os.environ["PYTHONPATH"]) os.environ["PYTHONPATH"] = python_path
可以發(fā)現(xiàn)newrelic/bootstrap/sitecustomize.py 文件被加入到了 PYTHONPATH。
python 解釋器初始化的時(shí)候會(huì)自動(dòng) import PYTHONPATH 下存在的 sitecustomize 和 usercustomize 模塊。
之后的功能比較簡單,就是調(diào)用 os 模塊執(zhí)行命令。
現(xiàn)在看下newrelic/bootstrap/sitecustomize.py 代碼。
在 這個(gè)文件的最后一行:
newrelic.config.initialize(config_file, environment)
這里用來初始化newrelic,具體代碼在 newrelic/config.py文件。
以下是initialize函數(shù):
def initialize(config_file=None, environment=None, ignore_errors=None, log_file=None, log_level=None): if config_file is None: config_file = os.environ.get("NEW_RELIC_CONFIG_FILE", None) if environment is None: environment = os.environ.get("NEW_RELIC_ENVIRONMENT", None) if ignore_errors is None: ignore_errors = newrelic.core.config._environ_as_bool( "NEW_RELIC_IGNORE_STARTUP_ERRORS", True) _load_configuration(config_file, environment, ignore_errors, log_file, log_level) # 加載配置 if _settings.monitor_mode or _settings.developer_mode: _settings.enabled = True _setup_instrumentation() # 設(shè)置探針 _setup_data_source() # TODO _setup_extensions() # TODO _setup_agent_console() # TODO else: _settings.enabled = False
其中第14行 _load_configuration 是用來加載 newrelic 的相關(guān)配置。比如:日志目錄、各種環(huán)境變量、秘鑰、newrelic host 地址等等。
`_setup_instrumentation() 中 _process_module_builtin() 用來設(shè)置探針。
數(shù)據(jù)庫、外部請求 等監(jiān)控模塊都位于 hook 目錄下,通過 _process_module_builtin 函數(shù)將進(jìn)程與監(jiān)控模塊進(jìn)行綁定,包括 django 的主要模塊以及常用的數(shù)據(jù)庫等。在核心模塊執(zhí)行的時(shí)候觸發(fā)監(jiān)控,將數(shù)據(jù)回傳到 api.time_trace 模塊進(jìn)行處理。
而對于硬件信息的檢測則由 commo.system_info 進(jìn)行。
newrelic run_program 初始化過程以下為 flask 應(yīng)用初始化過程,其它應(yīng)用類似:
newrelic/admin/__init__.py main()
newrelic/admin/run_program.py 代碼中會(huì)把 newrelic/bootstrap/sitecustomize.py 添加到 PYTHONPATH,python 解釋器初始化的時(shí)候會(huì)自動(dòng) import PYTHONPATH 下存在的 sitecustomize 和 usercustomize 模塊
newrelic/bootstrap/sitecustomize.py 調(diào)用 newrelic.config.initialize(),_setup_instrumentation() 函數(shù)被調(diào)用,_process_module_builtin會(huì)把需要 wrap 的包先添加到_import_hooks。
newrelic/config.py 中 sys.meta_path.insert(0, newrelic.api.import_hook.ImportHookFinder()) 執(zhí)行
newrelic/api/import_hook.py ImportHookFinder().find_model()
newrelic/api/import_hook.py _ImportHookLoader() or _ImportHookChainedLoader()
newrelic/api/import_hook.py _notify_import_hooks callable 為 newrelic/config _module_import_hook _instrument
newrelic/hooks/framework_flask.py instrument_flask_app
newrelic/api/web_transaction.py wrap_wsgi_application
newrelic/common/object_wrapper.py wrap_object
在代碼中,使用到了第三方包 wrapt,以下是 wrapt 的官方描述(文檔地址)。
wrapt模塊的目的是為Python提供一個(gè)透明的對象代理,它可以作為構(gòu)建函數(shù)包裝器和裝飾函數(shù)的基礎(chǔ)。wrapt 提供了一個(gè)簡單易用的decorator工廠,利用它你可以簡單地創(chuàng)建decorator,并且在任何情況下都可以正確地使用它們。
wrapt簡單示例如下:
import wrapt # 普通裝飾器 @wrapt.decorator def pass_through(wrapped, instance, args, kwargs): return wrapped(*args, **kwargs) @pass_through def function(): pass # 帶參數(shù)的裝飾器 import wrapt def with_arguments(myarg1, myarg2): @wrapt.decorator def wrapper(wrapped, instance, args, kwargs): return wrapped(*args, **kwargs) return wrapper @with_arguments(1, 2) def function(): pass
要實(shí)現(xiàn)decorator,需要首先定義一個(gè)裝飾器函數(shù)。這將在每次調(diào)用修飾函數(shù)時(shí)調(diào)用。裝飾器函數(shù)需要使用四個(gè)位置參數(shù):
wrapped - The wrapped function which in turns needs to be called by your wrapper function.
instance - The object to which the wrapped function was bound when it was called.
args - The list of positional arguments supplied when the decorated function was called.
kwargs - The dictionary of keyword arguments supplied when the decorated function was called.
具體使用參考文檔吧。 文檔地址
newrelic 源碼仔細(xì)看下去,太...復(fù)雜了。下一篇再分析一個(gè) flask 請求到結(jié)束探針工作的完整過程吧。
最后,感謝女朋友支持和包容,比??
也可以在公號輸入以下關(guān)鍵字獲取歷史文章:公號&小程序 | 設(shè)計(jì)模式 | 并發(fā)&協(xié)程
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/41726.html
摘要:本文將簡單講述一下探針的實(shí)現(xiàn)原理。探針的實(shí)現(xiàn)主要涉及以下幾個(gè)知識點(diǎn)這個(gè)簡單的來說就是可以實(shí)現(xiàn)的功能,當(dāng)執(zhí)行相關(guān)的操作時(shí),會(huì)觸發(fā)列表中定義的對象。當(dāng)然,跟實(shí)際使用的探針程序相比肯定是有很大的差距的,這篇文章主要是講解一下探針背后的實(shí)現(xiàn)原理。 本文將簡單講述一下 Python 探針的實(shí)現(xiàn)原理。 同時(shí)為了驗(yàn)證這個(gè)原理,我們也會(huì)一起來實(shí)現(xiàn)一個(gè)簡單的統(tǒng)計(jì)指定函數(shù)執(zhí)行時(shí)間的探針程序。 探針的實(shí)現(xiàn)主...
摘要:本文主要分為三個(gè)部分,將介紹監(jiān)控系統(tǒng)的歷史流派及如何選型,希望對讀者能有所幫助。圖監(jiān)控系統(tǒng)發(fā)展歷史早期的監(jiān)控系統(tǒng)互聯(lián)網(wǎng)發(fā)展早期的監(jiān)控系統(tǒng),主要是指基于簡單網(wǎng)絡(luò)管理協(xié)議的網(wǎng)絡(luò)監(jiān)控和系統(tǒng)主要指操作系統(tǒng)監(jiān)控。 本文作者 劉俊微博平臺監(jiān)控技術(shù)負(fù)責(zé)人,負(fù)責(zé)微博平臺、PC微博大規(guī)模監(jiān)控系統(tǒng)的建設(shè),主要關(guān)注實(shí)時(shí)大數(shù)據(jù)、運(yùn)維自動(dòng)化、智能化方向,2014年加入微博,之前曾在新浪、搜狐等公司從事運(yùn)維監(jiān)控方面的工...
摘要:通過跟蹤請求的處理過程,來對應(yīng)用系統(tǒng)在前后端處理服務(wù)端調(diào)用的性能消耗進(jìn)行跟蹤,關(guān)于的介紹可以看這個(gè)鏈接,大規(guī)模分布式系統(tǒng)的跟蹤系統(tǒng)作者刀把五鏈接來源知乎著作權(quán)歸作者所有。 手把手教你搭A(yù)PM之Skywalking 前言 什么是APM?全稱:Application Performance Management 可以參考這里: 現(xiàn)代APM體系,基本都是參考Google的Dapper(大規(guī)模...
摘要:方案匯總一開源方案采集展示報(bào)警二商業(yè)方案三云廠商騰訊云阿里云百度云華為云四主機(jī)監(jiān)控五日志監(jiān)控六服務(wù)監(jiān)控七存儲(chǔ)后端腦圖本文為容器監(jiān)控實(shí)踐系列文章,完整內(nèi)容見 概述 隨著越來越多的線上服務(wù)docker化,對容器的監(jiān)控、報(bào)警變得越來越重要,容器監(jiān)控有多種形態(tài),有些是開源的(如promethues),而另一些則是商業(yè)性質(zhì)的(如Weave),有些是集成在云廠商一鍵部署的(Rancher、谷歌云)...
摘要:方案匯總一開源方案采集展示報(bào)警二商業(yè)方案三云廠商騰訊云阿里云百度云華為云四主機(jī)監(jiān)控五日志監(jiān)控六服務(wù)監(jiān)控七存儲(chǔ)后端腦圖本文為容器監(jiān)控實(shí)踐系列文章,完整內(nèi)容見 概述 隨著越來越多的線上服務(wù)docker化,對容器的監(jiān)控、報(bào)警變得越來越重要,容器監(jiān)控有多種形態(tài),有些是開源的(如promethues),而另一些則是商業(yè)性質(zhì)的(如Weave),有些是集成在云廠商一鍵部署的(Rancher、谷歌云)...
閱讀 1847·2021-11-22 15:25
閱讀 3912·2021-11-17 09:33
閱讀 2507·2021-10-12 10:12
閱讀 1802·2021-10-09 09:44
閱讀 3235·2021-10-08 10:04
閱讀 1313·2021-09-29 09:35
閱讀 1947·2019-08-30 12:57
閱讀 1303·2019-08-29 16:22