首页 > 编程语言 >3、【java程序运行监控byteman】Byteman脚本详解及javaagent和byteman结合使用详细示例

3、【java程序运行监控byteman】Byteman脚本详解及javaagent和byteman结合使用详细示例

时间:2023-06-18 11:34:59浏览次数:49  
标签:javaagent java byteman 程序运行 示例 规则 main

java程序运行监控byteman 系列文章

1、【java程序运行监控byteman】之安装部署和入门示例 2、【java程序运行监控byteman】使用示例(运行中方法耗时监控、javaagent监控、jvm监控、规则的检查、是否运行以及查看等) 3、【java程序运行监控byteman】Byteman脚本详解及javaagent和byteman结合使用详细示例


(文章目录)


本文简单的介绍了byteman脚本编写及示例、javaagent和byteman结合三种情况使用详细示例。 本文分为2个部分,及byteman的脚本介绍、javaagent与byteman结合使用。

一、Byteman脚本介绍

官网地址:https://github.com/bytemanproject/byteman

1、脚本结构

1)、脚本示例

RULE example rule
# comment line in rule body
. . .
ENDRULE

2)、脚本说明

RULE <rule name>
CLASS <class name>
METHOD <method name>
BIND <bindings>
IF  <condition>
DO  <actions>
ENDRULE

全部的合法定位点或者说注入点,更多的信息参考官方文档说明

AT ENTRY
AT EXIT
AT LINE number
AT READ [type .] field [count | ALL ]
AT READ $var-or-idx [count | ALL ]
AFTER READ [ type .] field [count | ALL ]
AFTER READ $var-or-idx [count | ALL ]
AT WRITE [ type .] field [count | ALL ]
AT WRITE $var-or-idx [count | ALL ]
AFTER WRITE [ type .] field [count | ALL ]
AFTER WRITE $var-or-idx [count | ALL ]
AT INVOKE [ type .] method [ ( argtypes ) ] [count | ALL ]
AFTER INVOKE [ type .] method [ ( argtypes ) ][count | ALL ]
AT SYNCHRONIZE [count | ALL ]
AFTER SYNCHRONIZE [count | ALL ]
AT THROW [count | ALL ]
AT EXCEPTION EXIT

2、自定义规则

1)、自定义规则源码

class HelperSub extends Helper {
  public boolean debug(String message) {
      super("!!! IMPORTANT EVENT !!! " + message);
  }
}

本示例中的子规则是继承制org.jboss.byteman.rule.helper.Helper

2)、规则示例

RULE help yourself but rely on others
CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
METHOD commit
HELPER HelperSub
AT ENTRY
IF NOT flagged($this)
DO debug("throwing wrong state");
 flag($this);
 throw new WrongStateException()
ENDRULE

3、Byteman环境变量

在Byteman中,环境变量有如下这些,如果了解更多的信息则参考官方文档。

  • org.jboss.byteman.compileToBytecode
  • org.jboss.byteman.dump.generated.classes
  • org.jboss.byteman.dump.generated.classes.directory
  • org.jboss.byteman.dump.generated.classes.intermediate
  • org.jboss.byteman.verbose 如果设置将显示执行的各种跟踪信息到System.out,包括类型检查,编译,和执行规则
  • org.jboss.byteman.debug
  • org.jboss.byteman.transform.all 如果设置了将允许注入java.lang和其子包的class
  • org.jboss.byteman.skip.overriding.rules
  • org.jboss.byteman.allow.config.updates
  • org.jboss.byteman.sysprops.strict

4、Byteman其它命令

在解压的Byteman的bin目录下,有非常多的脚本(更多脚本参考官方文档),简单介绍如下所示:

  • bmcheck 在注入规则文件之前,该命令可以在线下对你的规则脚本进行解析和类型检查
  • bminstall 安装agent到一个正在运行的程序中
  • bmjava 该脚本包装了-javaagent选项。它的用法很像java命令,但是它能以-javaagent script:选项的方式接受Byteman规则脚本。并且自动以boot:的方式绑定了Byteman的Jar文件
  • bmsetenv 该脚本用来设置环境,agent对配置其行为的各种环境设置非常敏感
  • bmsubmit 提交和卸载规则脚本

二、javaagent与byteman使用示例

javaagent 技术是一个开发者可以构建一个独立于应用程序的代理程序(Agent),用来监测和协助运行在 JVM 上的程序,甚至能够替换和修改某些类的定义。有了这样的功能,开发者就可以实现更为灵活的运行时虚拟机监控和 Java 类操作了,这样的特性实际上提供了一种虚拟机级别支持的 AOP 实现方式,使得开发者无需对 JDK 做任何升级和改动,就可以实现某些 AOP 的功能了。 javaagent 选项支持在所有的JVM中使用Byteman。

1、示例1:加载规则文件并启动程序

1)、示例类

package com.win.byteman;
 
class App1
{
     public static void main(String[] args)
     {
         for (int i = 0; i < args.length; i++) {
             System.out.println(args[i]);
         }
     }
}

编译命令:javac -g com/win/byteman/App1.java

2)、规则

app1.btm

RULE trace main entry
CLASS App1
METHOD main
AT ENTRY
IF true
DO traceln("entry main")
ENDRULE
 
RULE trace main exit
CLASS App1
METHOD main
AT EXIT
IF true
DO traceln("exit main")
ENDRULE

3)、提交规则

script用于指示 Byteman 规则文件的位置。 Byteman agent 读取到这个选项之后从规则文件中加载和注入Byteman规则。如果要加载多个script:file规则文件,使用逗号(,)分隔即可。 执行命令:

java -javaagent:%BYTEMAN_HOME%/lib/byteman.jar=script:app1.btm com.win.byteman.App1 foo bar baz

4)、验证

在这里插入图片描述

2、示例2:启动程序并动态加载规则文件

这种方式利用javaagent启动程序,然后加载规则文件。

1)、示例类

package com.win.byteman;
 
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
class App4
{
           public static void main(String[] args) {
              new App4().start();
       }
 
       private void start() {
              new Thread(() -> {
                     DataInputStream in = new DataInputStream(System.in);
                     BufferedReader buf = new BufferedReader(new InputStreamReader(in));
                     try {
                            String next = buf.readLine();
                            while (next != null && !next.contains("end")) {
                                   consume(next);
                                   next = buf.readLine();
                            }
                     } catch (IOException e) {
                            e.printStackTrace();
                     }
              }).start();
       }
 
       public void consume(String text) {
              // 这是个局部变量,将会在byteman中追踪她
              final String arg = text;
              Thread thread = new Thread(() -> System.out.println("program confirm " + arg));
              thread.start();
              try {
                     thread.join();
              } catch (InterruptedException e) {
                     e.printStackTrace();
              }
              return;
       }
}

编译命令:javac -g com/win/byteman/App4.java

2)、规则

app4.btm

RULE trace main entry
CLASS App4
METHOD main
AT ENTRY
IF true
DO traceln("entry main")
ENDRULE
 
RULE trace main exit
CLASS App4
METHOD main
AT EXIT
IF true
DO traceln("exit main")
ENDRULE

3)、启动程序

在cmd中执行命令:

java -javaagent:%BYTEMAN_HOME%\lib\byteman.jar=listener:true,boot:%BYTEMAN_HOME%\lib\byteman.jar -Dorg.jboss.byteman.transform.all com.win.byteman.App4

Linux系统只需要把%BYTEMAN_HOME%换成${BYTEMAN_HOME}即可,注意Linux上分隔符是正斜杠,这个监听器会开启一个网络监听。 注意:当没有规则加载的时候,程序的行为不会发生任何变化,仅输出我们输入的内容。 如果执行成功,则出现如下界面 在这里插入图片描述

4)、提交规则

新打开一个cmd 执行命令:bmsubmit -l app4.btm 执行成功,如下界面 在这里插入图片描述

5)、验证

在另外一个cmd中输入要测试的字符串,成功则如下图 在这里插入图片描述

6)、卸载脚本

在执行bmsubmit的cmd中执行命令:bmsubmit -u app4.btm 卸载完成后的界面: 在这里插入图片描述 运行程序的界面测试结果如下: 在这里插入图片描述 在实际生产中,该种方法基本上不会使用到,因为要么是程序已经运行,要么是没有运行。已经运行的程序基本不会使用javaagent作为参数来运行,没有运行的程序一般使用第一种方式或其他的方式。常见的运行程序加载规则的是第三种方式,也即针对已经运行的程序进行监控。

3、示例3:动态安装agent到正在运行的程序中

1)、 示例类

package com.win.byteman;
 
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
class App4
{
           public static void main(String[] args) {
              new App4().start();
       }
 
       private void start() {
              new Thread(() -> {
                     DataInputStream in = new DataInputStream(System.in);
                     BufferedReader buf = new BufferedReader(new InputStreamReader(in));
                     try {
                            String next = buf.readLine();
                            while (next != null && !next.contains("end")) {
                                   consume(next);
                                   next = buf.readLine();
                            }
                     } catch (IOException e) {
                            e.printStackTrace();
                     }
              }).start();
       }
 
       public void consume(String text) {
              // 这是个局部变量,将会在byteman中追踪她
              final String arg = text;
              Thread thread = new Thread(() -> System.out.println("program confirm " + arg));
              thread.start();
              try {
                     thread.join();
              } catch (InterruptedException e) {
                     e.printStackTrace();
              }
              return;
       }
}

2)、规则

app4.btm

RULE trace main entry
CLASS App4
METHOD main
AT ENTRY
IF true
DO traceln("entry main")
ENDRULE
 
RULE trace main exit
CLASS App4
METHOD main
AT EXIT
IF true
DO traceln("exit main")
ENDRULE

3)、启动程序

在cmd中执行。 编译程序

Javac com/win/byteman/App4.java

启动程序

Java com.win.byteman.App4

测试程序 在这里插入图片描述

4)、建立监控

在新的cmd中找到进程号

1、执行jps

在这里插入图片描述

2、建立监控命令

在这里插入图片描述 如果成功,则在运行程序控制台输出: Setting org.jboss.byteman.transform.all=

5)、提交规则

在cmd中执行命令:bmsubmit -l app4.btm 执行成功,则如下图 在这里插入图片描述 下载规则,执行命令:bmsubmit -u app4.btm

6)、验证

在程序运行控制台输入testing again,则出现如下界面 在这里插入图片描述 完整的操作两个cmd截图如下: 一个是程序运行控制台,一个是监控cmd 在这里插入图片描述

以上,简单的介绍了byteman脚本编写及示例、javaagent和byteman结合三种情况使用详细示例。

标签:javaagent,java,byteman,程序运行,示例,规则,main
From: https://blog.51cto.com/alanchan2win/6507879

相关文章

  • 2、【java程序运行监控byteman】使用示例(运行中方法耗时监控、javaagent监控、jvm监控
    (文章目录)本文介绍了byteman的其他几种应用场景及示例,比如javaagent、监控jvm、bmjava命令、如何查看运行的规则、检查规则的正确性、检查规则是否在运行中等。本文分为2个部分,即运行中方法耗时监控和其他示例。一、统计方法耗时(程序运行中)该类是实时显示控制台输入的结果以......
  • 京东api接口获得jd商品分类源代码调用示例
    ​  京东商品分类接口的作用是提供一种获取商品分类信息的方式,可以帮助开发者在自己的应用程序中快速获取商品分类数据,从而实现更加精准的商品分类展示、搜索等功能。具体而言,京东商品分类接口(获取免费测试)的作用包括:1.精准地获取商品分类信息:通过商品分类接口,开发者可以获......
  • 京东api接口获得jd商品分类源代码调用示例
     京东商品分类接口的作用是提供一种获取商品分类信息的方式,可以帮助开发者在自己的应用程序中快速获取商品分类数据,从而实现更加精准的商品分类展示、搜索等功能。具体而言,京东商品分类接口(获取免费测试请私信)的作用包括:1.精准地获取商品分类信息:通过商品分类接口,开发者可以获取最......
  • Python使用HTTP隧道代码示例
    在本地代码中,嵌入隧道模式HTTP,HTTP模式:服务器端口账号密码,即可使用HTTP隧道代理来做访问#!-*-encoding:utf-8-*-importrequests#要访问的目标页面targetUrl="http://ip.hahado.cn/ip"#代理服务器proxyHost="ip.hahado.cn"proxyPort......
  • Unity 编辑器直接运行正常,打包后的程序运行异常问题
     打包后的程序运行报错:base="System.MissingMethodException:Defaultconstructornotfoundfortypelog4net.Repository.Hierarchy.Hierarchy\r\natSystem.RuntimeType.CreateInstanceMono(System.BooleannonPublic,System.BooleanwrapExceptions)[0x00076]in&l......
  • SpringMVC基础详解(包含示例)
    SpringMVC简介SpringMVC是一种基于Java的实现MVC设计模型的请求驱动类型的轻量级Web框架,跟Spring,Mybatis框架并称为SSM。是由Spring官方提供的基于MVC设计理念的web框架也是基于Servlet封装的用于实现MVC控制的框架,实现前端和服务端的交互与Servlet技术功能相同,均是......
  • iptables规则示例之只允许本地访问特定端口
    一、背景说明Iptables指的是用来管理Linux防火墙的命令程序,通常位于/sbin/iptables,属于“用户态”(UserSpace,又称用户空间)的防火墙管理体系;IPtables是工作在用户空间中,定义规则的工具,本身并不算是防火墙。我们可以理解为一个客户端工具,用户通过ipatbles这个客户端,将用户......
  • log4j.xml示例
    <?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPElog4j:configurationSYSTEM"log4j.dtd"><log4j:configurationxmlns:log4j="http://jakarta.apache.org/log4j/"debug="false"><ap......
  • log4xx/log4j异步日志配置示例
    <?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPElog4j:configurationSYSTEM"log4j.dtd"><log4j:configurationxmlns:log4j='http://jakarta.apache.org/log4j/'debug="false"><append......
  • 协程示例
    协程(Coroutine)与线程类似,可看成用户线程,由用户调度,而不是系统调度。示例创建1W个协程对象(TestCoro),然后随机调度运行。1W个协程运行于同一个线程中。协程构造绑定到CoroFun(),与boost::thread的创建相同。#include<iostream>#include<vector>#include<boost/bind.hpp>#inclu......