Javaダイナミック、セキュリティ追跡ツール

7041 ワード

Javaダイナミック、セキュリティ追跡ツール
私たちの日常の開発では、オンラインの問題を解決することは避けられない.もしオンラインの問題がローカルでデバッグしている間に何度デバッグしてもローカルでこの方法が呼び出されているのに、どうしてオンラインでは調整されていないのですか?また、問題が発生した場合、ログを打っていないため、価格のloggerに行かなければならなくて、それからかばんを交換して、それから再起動して、それから呼び出して、もしユーザーが多い時にこのようにすれば、間違いなく巨大なリスクに直面して、またユーザーの大量の苦情を処理しなければならなくて、指導者の前でも黙って頭を下げて批判に耐えるしかありません
では、アプリケーションを再起動せずに、オンラインでコードを追跡する方法はありませんか?答えはもちろんありますが、Btraceというツールを使っています.
BTraceはsun社が発売したJava動態、安全追跡(監視)ツールで、再起動せずにシステムの運行状況を監視することができ、プログラムの運行時のデータ情報、例えば方法パラメータ、戻り値、グローバル変数とスタック情報などを便利に取得することができ、しかも最小限の侵入を実現し、最小限のシステム資源を占有する.
適用シーン:
  • サービスは遅いですが、どのステップが遅いのか、どの関数が
  • 遅いのか分かりません.
  • 誰かがシステムを呼び出したgc()、呼び出しスタックはどうですか?
  • 誰が超大きなArrayListを作ったの?
  • あるメソッドを実行して異常を放出する場合、実行時パラメータ
  • を解析する.
    ......
    クイックスタート
    btraceの公式サイトはhttp://github.com/btraceio/btrace、中から最新のバージョンをダウンロードすることができて、現在のバージョンは1.3.11.2です
    ダウンロードしたらdocにはいろいろな例がありますが、ここではUserGuideの例を走りましょう.
    import com.sun.btrace.annotations.BTrace;
    import com.sun.btrace.annotations.OnMethod;
    
    import static com.sun.deploy.trace.Trace.println;
    
    /**
     * @author luozhiyun on 2019-01-06.
     */
    @BTrace
    public class HelloWorld {
    
        @OnMethod(clazz="java.lang.Thread", method="start")
        public static void onThreadStart() {
            println("thread start!");
    
        }
    
    }

    それから監視する機械の上でjpsを打って、応用するpidを探し当てて、それからbtrace$pid HelloWorld.JAvaは走れる
    他のコンテンツを監視したい場合は、HelloWorldを直接変更します.JAvaの内容は、もう一度btraceを実行すればいいので、アプリケーションを再起動する必要はありません!!!
    ブロッキング
    1.HelloWorldの例のようなクラスと方法を直接指摘する
    2.正規表現ブロック
    次のように、InputStreamクラスに関するreadXXXメソッドをすべてブロックします.正規表現は2つ/中間に書きます.
    package com.sun.btrace.samples;
    
    import com.sun.btrace.annotations.*;
    import static com.sun.btrace.BTraceUtils.*;
    
    /**
     * This BTrace class demonstrates that we can
     * probe into multiple classes and methods by a
     * single probe specification using regular
     * expressions for class and/or method names as
     * given below. In the example, we put probe into
     * all readXXX methods of all InputStream classes.
     */
    @BTrace public class MultiClass {
        @OnMethod(
            clazz="/java\\.io\\..*Input.*/",
            method="/read.*/"
        )
        public static void onread(@ProbeClassName String pcn) {
            println("read on " + pcn);
        }
    }

    3.この注釈を持つすべてのクラスまたはメソッドをブロック
    例えば:@OnMethod( clazz="@javax.jws.WebService", method="@javax.jws.WebMethod" )4.ブロックインタフェースの実装クラス
    例えば:@OnMethod( clazz="+java.lang.Runnable", method="run" )5.ブロックコンストラクタ@OnMethod(clazz="java.net.ServerSocket", method="")
    6.静的内部クラスをブロックする@OnMethod(clazz="com.vip.MyServer$MyInnerClass", method="hello")クラスと内部クラスの前に$を追加すれば
    時機をさえぎる
    Kind.ENTRY
    @onMethodという注釈にlocationパラメータを付けて、ブロックするこの方法のブロックタイミングを表すことができます.追加しなければ、デフォルトはKindです.ENTRY
    Kind.RETURN
    戻り結果または実行時間を取得するにはKindを追加します.RETURN.
    OnMethod(clazz = "java.net.ServerSocket", method = "getLocalPort", location = @Location(Kind.RETURN))
    public static void onGetPort(@Return int port, @Duration long duration)
    
    duration      ,    1,000,000     。

    Kind.Error, Kind.ThrowとKind.Catch
    これらは主に異常状況の追跡に用いられる.
    ブロック関数のパラメータ定義にThrowableのパラメータを注入し,異常を表す.
    @OnMethod(clazz = "java.net.ServerSocket", method = "bind", location = @Location(Kind.ERROR))
    public static void onBind(Throwable exception, @Duration long duration)

    Kind.Line
    次の例では、コードがSocketクラスの363行目に到達したかどうかを監視します.
    @OnMethod(clazz = "java.net.ServerSocket", location = @Location(value = Kind.LINE, line = 363))
    
    public static void onBind4() {
    
       println("socket bind reach line:363");
    
    }

    Kind.Call
    次の例はrun()メソッドで呼び出された他のすべてのメソッドを印刷することです.
    import com.sun.btrace.annotations.*;
    
    import static com.sun.btrace.BTraceUtils.println;
    
    
    /**
     * @author luozhiyun on 2019-01-06.
     */
    @BTrace
    public class HelloWorld {
    
        @OnMethod(clazz="BtraceCase", method="run",
                location =@Location(value = Kind.CALL, clazz = "/.*/", method = "/.*/", where = Where.AFTER))
        public static void onThreadStart(@Self Object self, @TargetInstance Object instance,
                                         @TargetMethodOrField String method, @Duration long duration) {
            println("self: " + self);
            println("instance: " + instance);
            println("method: " + method);
            println("duration: " + duration);
    
        }
    }
    

    BtraceCase
    import java.util.Random;
    
    /**
     * @author luozhiyun on 2019-01-06.
     */
    public class BtraceCase {
        public static Random random = new Random();
        public int size;
    
        public static void main(String[] args) throws Exception {
            Thread.sleep(1000*15);
            new BtraceCase().run();
        }
    
        public void run() throws Exception {
            while (true) {
                add(random.nextInt(10), random.nextInt(10));
            }
        }
    
        public int add(int a, int b) throws Exception {
            Thread.sleep(random.nextInt(10) * 100);
            return a + b;
        }
    }
    

    印刷結果:
    self: BtraceCase@63947c6b
    instance: BtraceCase@63947c6b
    method: add
    duration: 402211413
    self: BtraceCase@63947c6b
    instance: java.util.Random@2b193f2d
    method: nextInt
    duration: 2602

    呼び出されたクラスおよびメソッド名は@TargetInstanceおよび@TargetMethodOrFieldに注入する.実行時間を取得するにはWhereをAFTERとして定義する必要があります
    thisを印刷し、パラメータと戻り値
    import com.sun.btrace.AnyType;
    
    @OnMethod(clazz = "java.io.File", method = "createTempFile", location = @Location(value = Kind.RETURN))
    
    public static void o(@Self Object self, String prefix, String suffix, @Return AnyType result)

    Self:
    静的関数であればselfは空であり,@Selfで現在のメソッド,すなわちthisを表すことができる.
    パラメータ:
    パラメータリストは定義しないか、定義するには完全に定義しなければならない.そうしないと、BTraceは異なるパラメータの同名関数を処理できない.
    結果:
    結果のタイプはAnyTypeで定義されており,特に正規表現で複数の関数をマッチングした場合にはvoidでも表すことができる.
    ちょっとした経験
  • マッチングメソッドのエントリまたは戻りタイプに使用する場合、面倒なので外部依存を導入したくない(一般的には必要ありません)、外部タイプはObjectではなくAnyTypeで置き換えてください!Objectを使用してパラメータまたは戻りタイプを正確に一致させることができます.
  • トレーススクリプトを起動する場合は、Javaプロセスの起動と同じLinuxアカウントを使用してください.そうしないと、権限の問題でattachが失敗します.
  • BTraceに似たもう一つのJava診断ツールgreys-anatomyは、アリから解放され、興味のある人も勉強することができます.
  • 「Port 2020 unavailable.」と間違えたら、btrace -p 2021 ...を使用して、他のポートを指定します.
  • Linuxの下にはすでにbtraceという命令があります.混同しないように注意してください.
  • Btraceはスクリプトロジックを実行するコードに直接侵入するため、使用上多くの制限を行う:1、オブジェクトを作成できない2、配列3を使用できない、異常を放出またはキャプチャできない4、ループ5を使用できない、synchronizedキーワード6を使用できない、属性と方法はstatic修飾を使用しなければならない公式声明によると、BTraceの不適切な使用は、誤ったclassファイルをBTraceスクリプトで使用するなど、JVMのクラッシュを引き起こす可能性があります.したがって、本番環境にアップロードする前に、スクリプトの正確性をローカルで十分に検証する必要があります.

  • 転載先:https://www.cnblogs.com/luozhiyun/p/10229018.html