{"id":21731344,"url":"https://github.com/ymm-tech/gravity","last_synced_at":"2025-04-13T00:26:46.274Z","repository":{"id":40004641,"uuid":"483943079","full_name":"ymm-tech/gravity","owner":"ymm-tech","description":"Java Byte Code Editor","archived":false,"fork":false,"pushed_at":"2022-05-19T09:23:03.000Z","size":4250,"stargazers_count":21,"open_issues_count":1,"forks_count":7,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-26T18:21:47.238Z","etag":null,"topics":["advice","aop","bytecode","interceptor","javaagent","plugin"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ymm-tech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-04-21T07:05:23.000Z","updated_at":"2025-02-14T10:59:04.000Z","dependencies_parsed_at":"2022-07-26T11:47:14.320Z","dependency_job_id":null,"html_url":"https://github.com/ymm-tech/gravity","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ymm-tech%2Fgravity","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ymm-tech%2Fgravity/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ymm-tech%2Fgravity/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ymm-tech%2Fgravity/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ymm-tech","download_url":"https://codeload.github.com/ymm-tech/gravity/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248650619,"owners_count":21139665,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["advice","aop","bytecode","interceptor","javaagent","plugin"],"created_at":"2024-11-26T04:24:14.256Z","updated_at":"2025-04-13T00:26:46.255Z","avatar_url":"https://github.com/ymm-tech.png","language":"Java","readme":"# gravity 满帮agent方案\n\n## gravity agent\ngravity是满帮基于[java agent](https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html#package.description)自研的一款字节码层面AOP框架，目的是基于满帮业务场景，为插件开发同学降低字节码增强难度，目前满帮内部基于gravity开发出了六十余款插件，大致覆盖的业务场景如下：\n\n|场景名称|简介|业务场景|\n|  ----  | ----  |----  |\n| ironman | 满帮mesh方案 |涵盖rpc，mq，redis，config等多种中间件组件，彻底隔离api与实现，让开发同学无痛无感升级，后续也将开源，敬请期待 |\n| venom   | 满帮混沌场景 |故障演练，模拟测试，涵盖多种中间件，可模拟多场景异常 |\n| mock    | 满帮测试框架 |mock演练测试，涵盖多场景，多种组件的模拟 |\n| hubble  | 满帮APM解决方案 |业务系统性能实时监控，链路埋点 |\n| common  | 常规增强 |一些常规场景的增强，比如[TTL](https://github.com/alibaba/transmittable-thread-local)集成 |\n\n## 1.简单使用\n首先简单模拟一笔发货订单场景\n```java\n/**\n * 货主\n */\npublic class Shippers {\n    /**\n     * 发布订单\n     */\n    public String postOrder() {\n        return \"南京市 雨花台区 万博科技园 运满满总部 50立方 10吨\";\n    }\n}\n\n/**\n * 司机\n */\npublic class Driver {\n    /**\n     * 接单\n     */\n    public boolean acceptOrder(String address) {\n        if (Objects.nonNull(address) \u0026\u0026 address.startsWith(\"南京市\")) {\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * 装货\n     */\n    public String loadCargo() {\n        return \"load cargo success.\";\n    }\n\n    /**\n     * 运货\n     */\n    public String deliverCargo() {\n        return \"deliver cargo success.\";\n    }\n}\n\n/**\n * 发货订单\n */\npublic class Order {\n\n    public static void main(String[] args) {\n        new Order().trade();\n    }\n\n    public void trade() {\n        final Shippers shippers = new Shippers();\n        final Driver driver = new Driver();\n        final String address = shippers.postOrder();\n        driver.acceptOrder(address);\n        driver.loadCargo();\n        driver.deliverCargo();\n    }\n}\n```\n\n这时候，我们希望可以监控该笔订单的行为，决定通过无侵入方式打印出入参\u003cbr\u003e\n首先引入pom依賴:\n```\n\u003cdependency\u003e\n   \u003cgroupId\u003eio.manbang\u003c/groupId\u003e\n   \u003cartifactId\u003egravity-plugin-api\u003c/artifactId\u003e\n   \u003cversion\u003e1.0.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n插件定义，描述目标的织入点:\n```java\n/**\n * @since 2022/05/19 10:55\n */\npublic class AopPluginDefine implements PluginDefine {\n    @Override\n    public ElementMatcher\u003cTypeDescription\u003e getTypeMatcher() {\n        return ElementMatchers.named(\"io.manbang.gravity.trade.Driver\")\n                .or(ElementMatchers.named(\"io.manbang.gravity.trade.Shippers\"));\n    }\n\n    @Override\n    public Plugin[] getPlugins() {\n        return new Plugin[]{Plugin.advice(ElementMatchers.isMethod(), \"io.manbang.gravity.plugin.monitor.AopAdvice\").withMethod()};\n    }\n}\n```\n具体织入的逻辑：\n```java\n/**\n * @since 2022/05/19 11:05\n */\npublic class AopAdvice implements Advice {\n    private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(AopAdvice.class.getName());\n\n    @Override\n    public void enterMethod(ExecuteContext context) {\n        final Method method = context.getMethod();\n        final Object[] argument = context.getArguments();\n        final StringBuilder builder = new StringBuilder();\n        builder.append(\"method enter:\").append(method.getName());\n        for (int i = 0; i \u003c argument.length; i++) {\n            builder.append(\" arg  number:\").append(i).append(\" arg :\").append(argument[i]);\n        }\n        log.info(builder.toString());\n    }\n\n    @Override\n    public void exitMethod(ExecuteContext context) {\n        final Method method = context.getMethod();\n        final Object result = context.getResult();\n        final StringBuilder builder = new StringBuilder();\n        builder.append(\"method exit:\").append(method.getName());\n        builder.append(\"result:\").append(result);\n        log.info(builder.toString());\n    }\n}\n```\n新建`SPI`文件：`/META-INF/services/io.manbang.gravity.plugin.PluginDefine`，内容为新创建的插件定义`AopPluginDefine` \u003cbr\u003e\u003cbr\u003e\n打包该插件，并将打包好的插件放置于`{user.home}/.gravity/cargo-publish-app/agent`目录下(`user.home`路径可以通过执行`java -XshowSettings:properties -version`得到，`cargo-publish-app`为应用名，可以自行定义)\u003cbr\u003e\u003cbr\u003e\n执行`Order`的`main`方法在启动时，新增`VM`命令：`-javaagent:XXXX/XXXX/gravity-agent.jar=appName=cargo-publish-app`，`gravity-agent.jar`下载路径：[agent](https://github.com/ymm-tech/gravity/blob/27c4399955cc0961c7c2538ea37bb3cdf93bc182/gravity-agent.jar)\u003cbr\u003e\n可以观察到控制台输出预期想要的业务出入参：\n```\n五月 19, 2022 4:49:05 下午 io.manbang.gravity.agent.GravityAgent instrument\n信息: 加载插件：AopPluginDefine\n五月 19, 2022 4:49:05 下午 io.manbang.gravity.agent.PluginTransformer transform\n信息: io.manbang.gravity.trade.Shippers\n五月 19, 2022 4:49:05 下午 io.manbang.gravity.agent.PluginTransformer getClassLoader\n信息: The current classLoader is sun.misc.Launcher$AppClassLoader@18b4aac2 , pluginDefine: AopPluginDefine , transform: io.manbang.gravity.trade.Shippers\n五月 19, 2022 4:49:06 下午 io.manbang.gravity.agent.GravityServiceBoot startServices\n信息: 开始启动重力服务……\n五月 19, 2022 4:49:06 下午 io.manbang.gravity.agent.PluginTransformer transform\n信息: io.manbang.gravity.trade.Driver\n五月 19, 2022 4:49:06 下午 io.manbang.gravity.agent.PluginTransformer getClassLoader\n信息: The current classLoader is sun.misc.Launcher$AppClassLoader@18b4aac2 , pluginDefine: AopPluginDefine , transform: io.manbang.gravity.trade.Driver\n五月 19, 2022 4:49:06 下午 io.manbang.gravity.plugin.monitor.AopAdvice enterMethod\n信息: method enter:postOrder\n五月 19, 2022 4:49:06 下午 io.manbang.gravity.plugin.monitor.AopAdvice exitMethod\n信息: method exit:postOrderresult:南京市 雨花台区 万博科技园 运满满总部 50立方 10吨\n五月 19, 2022 4:49:06 下午 io.manbang.gravity.plugin.monitor.AopAdvice enterMethod\n信息: method enter:acceptOrder arg  number:0 arg :南京市 雨花台区 万博科技园 运满满总部 50立方 10吨\n五月 19, 2022 4:49:06 下午 io.manbang.gravity.plugin.monitor.AopAdvice exitMethod\n信息: method exit:acceptOrderresult:true\n五月 19, 2022 4:49:06 下午 io.manbang.gravity.plugin.monitor.AopAdvice enterMethod\n信息: method enter:loadCargo\n五月 19, 2022 4:49:06 下午 io.manbang.gravity.plugin.monitor.AopAdvice exitMethod\n信息: method exit:loadCargoresult:load cargo success.\n五月 19, 2022 4:49:06 下午 io.manbang.gravity.plugin.monitor.AopAdvice enterMethod\n信息: method enter:deliverCargo\n五月 19, 2022 4:49:06 下午 io.manbang.gravity.plugin.monitor.AopAdvice exitMethod\n信息: method exit:deliverCargoresult:deliver cargo success.\n```\n具体示例已经放在`gravity-demo`和`gravity-plugin`中\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fymm-tech%2Fgravity","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fymm-tech%2Fgravity","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fymm-tech%2Fgravity/lists"}