(57)【特許請求の範囲】
【請求項１】
対象となるアプリケーションに処理単位毎のログ出力処理を実装するログ出力処理実装手段と、前記対象となるアプリケーションが処理単位毎に出力したログデータを読み込み、そのログデータを分析するログ分析手段とから構成され、
前記ログ分析手段が、
前記処理単位毎のログデータから前記アプリケーションを構成する各処理単位の呼び出し関係を示すコールフローグラフを作成し、コールフローグラフ記憶手段に記憶させるコールフローグラフ作成手段と、
前記コールフローグラフ作成手段が作成したコールフローグラフを表示し、当該コールフローグラフ中において前記アプリケーションの障害原因の一要因となる処理単位のログデータを比較元ログデータとしてユーザ選択操作によって受け付けるコールフローグラフ表示手段と、
ユーザ操作によって選択された比較元ログデータの処理単位と同一処理単位を含む他の処理単位群のログデータを前記コールフローグラフ記憶手段から取得し、当該他の処理単位群のログデータを比較先ログデータリストとして生成する比較ログデータリスト生成手段と、
前記比較元ログデータと前記比較先ログデータリスト内の各ログデータとを比較し、処理単位の呼び出し関係が異なるログデータを抽出して出力するログデータ比較手段と
を備えることを特徴とするアプリケーションの障害原因の特定作業支援システム。
【請求項２】
前記アプリケーションが処理単位毎に出力したログデータには当該処理単位のソースコード中の行番号を含み、前記ログデータ比較手段は前記比較元ログデータと前記比較先ログデータリスト内の各ログデータとの比較により、処理単位の呼び出し関係が異なるログデータを抽出すると共に、同一処理が異なるソースコード行に存在することを抽出して出力することを特徴とする請求項１に記載のアプリケーションの障害原因の特定作業支援システム。
【請求項３】
前記対象となるアプリケーションのソースコードを記憶したソースコード記憶手段と、前記ログデータ比較手段が出力した処理単位の呼び出し関係が異なるログデータ及び同一処理が異なるソースコード行に存在する処理単位のログデータの行番号により、前記ソースコード記憶手段から該当する行のソースコードを取得し、表示画面に予め設定した表示形式で強調表示出力する出力手段をさらに備えることを特徴とする請求項２に記載のアプリケーションの障害原因の特定作業支援システム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、アプリケーションのログから当該アプリケーションの動作を追跡し、障害が発生した原因を特定する作業を支援するアプリケーションの障害原因の特定作業支援システムに関するものである。
【背景技術】
【０００２】
アプリケーションに含まれるバグが原因で障害が発生し、ユーザに大きな損害を与えるという事例がよく見られる。このため、バグを一切含まないアプリケーションを開発することが求められるが、そのようなアプリケーションを開発するのは非常に困難である。そこで、仮にアプリケーションが障害を起こしたとしても、早急に障害の原因を突き止め、対策をとるための手段が重要となる。
アプリケーションの障害の原因を突き止めるための効果的な手段の１つとして、アプリケーションにログを出力する処理を実装する方法がある。この方法によれば、アプリケーション管理者は、アプリケーションが出力するログを監視することでアプリケーションに障害が発生したことを検知できる。また、ログには障害の直接の原因となった処理を行っている箇所（ソースコードの行番号）の情報が記録されているため、アプリケーション管理者はログを確認し、ログとアプリケーションのソースコードを比較することで、ソースコード中から障害の直接の原因箇所を突き止めることが可能となる。
【０００３】
しかし、上述の作業は全てアプリケーション管理者の目視と推測によって行われるため、アプリケーションの規模、もしくは出力されるログの量が大きくなるにつれて、作業のコストは増大し、また人手による作業であるためミスが発生する可能性も高まる。
【０００４】
上述の問題を解決するために、ログ分析ツールなどを使用して障害の原因を突き止める方法がある。ログ分析ツールとは、アプリケーションが出力したログを読み込み、ログを確認し易いような形式で一覧表示し、各ログとアプリケーションのソースコードを関連付けて表示するツールである。障害の発生を示すログを一覧から選択することで、その障害の直接の原因となった処理を行っているソースコード中の箇所をツールが強調表示（ハイライト表示）するため、迅速な障害追跡が可能となる。
【０００５】
なお、本発明に関連する公知技術文献としては下記の特許文献１が挙げられる。
特許文献１では、保守用端末が計算機から受け取ったメッセージのログと、保守用端末が計算機へ送信したメッセージのログがあり、一方のログを閲覧する際、もう一方のログも同時に表示し、さらに一方のログに含まれる時刻情報から、近い時間帯に出力されたもう一方のログのメッセージを追従して表示している。同時間帯に出力された複数のログ同士の関係を即座に把握することができるため、障害追跡の支援に有効である。
【０００６】
【特許文献１】特開２００１−１０１０３５号公報
【発明の開示】
【発明が解決しようとする課題】
【０００７】
しかしながら、上述のログ分析ツールにあっては、障害の直接の原因となった処理を行っている箇所は発見できるものの、その障害が発生した根本的な原因は発見できない。
すなわち、多くのアプリケーションでは、障害の直接の原因となった処理を行っている一箇所のみを修正するだけで障害が解決するようなケースは稀である。障害の直接の原因となった処理を行っている箇所以外に、その障害の根本的な原因となる処理を行っている箇所が別に存在し、その部分を修正して初めて障害が完全に解決する、といったケースが多々見られる。
上述のツールでは、障害発生を示すログと、そのログが出力される直前のログを見ることで、根本的な原因を大まかに突き止めることは可能であるが、これは比較的困難な作業である。また、特許文献１においても、この問題は解決できていない。
【０００８】
本発明の目的は、アプリケーションの障害の根本的な原因箇所を突き止めるために、アプリケーションが出力するログを分析し、障害の根本的な原因箇所を突き止める作業を大幅に軽減することができるアプリケーションの障害原因の特定作業支援システムを提供することにある。
【課題を解決するための手段】
【０００９】
上記目的を達成するために、本発明のアプリケーション障害原因の特定支援システムは、対象となるアプリケーションに処理単位毎のログ出力処理を実装するログ出力処理実装手段と、前記対象となるアプリケーションが処理単位毎に出力したログデータを読み込み、そのログデータを分析するログ分析手段とから構成され、
前記ログ分析手段が、
前記処理単位毎のログデータから前記アプリケーションを構成する各処理単位の呼び出し関係を示すコールフローグラフを作成し、コールフローグラフ記憶手段に記憶させるコールフローグラフ作成手段と、前記コールフローグラフ作成手段が作成したコールフローグラフを表示し、当該コールフローグラフ中において前記アプリケーションの障害原因の一要因となる処理単位のログデータを比較元ログデータとしてユーザ選択操作によって受け付けるコールフローグラフ表示手段と、ユーザ操作によって選択された比較元ログデータの処理単位と同一処理単位を含む他の処理単位群のログデータを前記コールフローグラフ記憶手段から取得し、当該他の処理単位群のログデータを比較先ログデータリストとして生成する比較ログデータリスト生成手段と、前記比較元ログデータと前記比較先ログデータリスト内の各ログデータとを比較し、処理単位の呼び出し関係が異なるログデータを抽出して出力するログデータ比較手段とを備えることを特徴とする。
また、前記アプリケーションが処理単位毎に出力したログデータには当該処理単位のソースコード中の行番号を含み、前記ログデータ比較手段は前記比較元ログデータと前記比較先ログデータリスト内の各ログデータとの比較により、処理単位の呼び出し関係が異なるログデータを抽出すると共に、同一処理が異なるソースコード行に存在することを抽出して出力することを特徴とする。
また、前記対象となるアプリケーションのソースコードを記憶したソースコード記憶手段と、前記ログデータ比較手段が出力した処理単位の呼び出し関係が異なるログデータ及び同一処理が異なるソースコード行に存在する処理単位のログデータの行番号により、前記ソースコード記憶手段から該当する行のソースコードを取得し、表示画面に予め設定した表示形式で強調表示出力する出力手段をさらに備えることを特徴とする。
【発明の効果】
【００１０】
本発明のアプリケーションの障害原因の特定作業支援システムによれば、次のような効果がある。
（１）アプリケーションに障害が発生した場合、アプリケーションが出力するログを分析することで、障害の根本的な原因を突き止める作業を容易なものにし、作業の負担を大幅に軽減することができる。
【発明を実施するための最良の形態】
【００１１】
以下、本発明の実施の形態を図面を参照して詳細に説明する。
図１は、本発明に係るアプリケーションの障害原因の特定作業支援システムの全体構成図である。
本実施形態のシステムは、障害原因の特定対象となるアプリケーション（１０１）にログ出力処理を実装し、ログ出力処理実装済みアプリケーション（１０３）を作成するログ出力処理実装装置（１０２）と、対象アプリケーション（１０１）が出力したログファイルを格納するログファイル格納部（１０４）と、ログファイル格納部（１０４）に格納されているログを読み込み、分析し、対象アプリケーション（１０１）の障害の根本的な原因箇所を特定するためのログ分析装置（１０５）と、対象アプリケーション（１０１）のソースコードを格納した対象アプリケーションソースコード格納部（１１８）とから構成される。
【００１２】
ログ分析装置（１０５）は、ログファイル格納部（１０４）に格納されているログファイルをログデータとしてメモリ上に読み込むための、ログ読み込み部（１０６）と、読み込んだログデータを一時的に記憶しておくメモリ上の領域である、ログデータ記憶部（１０７）と、ログデータ記憶部（１０７）に記憶されたログデータを読み込み、分類処理を行うためのログデータ分類部（１０８）と、ログデータ分類部（１０８）で分類したログデータを一時的に記憶しておくメモリ上の領域である分類済みログデータ記憶部（１０９）と、分類済みログデータ記憶部（１０９）に記憶されているログデータから、メソッドの呼び出し関係を表すコールグラフデータを構築するコールグラフデータ構築部（１１０）と、コールグラフ構築部（１１０）で作成したコールグラフデータを一時的に記憶しておくメモリ上の領域であるコールグラフデータ記憶部（１１１）と、コールグラフデータをツリー構造のコールグラフとしてディスプレイ（１１７）に表示するためのコールグラフ表示装置（１１２）と、ユーザが指定したログ同士を比較するための比較範囲を計算するためのログ比較範囲計算部（１１３）と、比較処理を行うための比較ログデータリストを作成する比較ログデータリスト生成部（１１４）と、生成した比較ログデータを元に比較処理を行う比較処理部（１１５）と、比較処理部（１１５）で処理された結果を記憶する比較結果記憶部（１１５Ｍ）と、比較処理部（１１５）で処理された結果をディスプレイ（１１７）に表示するログ比較結果表示装置（１１６）と、コールグラフツリー、ログデータ比較結果を表示するためのディスプレイ（１１７）、ディスプレイ（１１７）に表示されたコールグラフから任意のログデータを選択するなどの操作を行う入力装置（１１９）から構成される。
【００１３】
なお、本実施例はJava言語（Javaは登録商標）によるアプリケーション開発を前提としている。
また、ログ分析装置（１０５）は具体的にはコンピュータで構成され、各要素のうち記憶部以外の要素は、コンピュータプログラムによって構成されるものである。
【００１４】
本システムでは、対象となるアプリケーション（１０１）が出力する、本システム特有のフォーマットを持つログ（以下、追跡ログと表記する）を分析し、障害の根本的な原因箇所を特定する作業を支援する。そのため、予め対象となるアプリケーション（１０１）に追跡ログの出力処理を実装しておく必要があり、それを実現するのがログ出力処理実装装置（１０２）である。ビルド済みの対象アプリケーション（１０１）をログ出力処理実装装置（１０２）の入力として与えることで、同装置（１０２）は対象アプリケーション（１０１）に追跡ログ出力処理を実装し、ログ出力処理実装済みアプリケーション（１０３）として出力する。
本実施形態では、例えばバイトコード操作ライブラリであるJavassistを使用し、追跡ログ出力処理の実装を行っている。これにより、対象アプリケーション（１０１）を構成するクラスのソースコードには一切変更を加えることなく、追跡ログ出力処理を実装することが可能となる。
【００１５】
図２は、SampleクラスのソースコードであるSample.java（２０１）と、そのクラスに対し追跡ログ出力処理の実装を行った場合に出力される追跡ログ（２０２）の例を示したものである。
ログ出力処理実装装置（１０２）は、ソースコード上の全ての行に対応する処理の直前に、追跡ログ出力処理を実装する（ただし、空行、コメント行や、クラスの動作とは直接対応しない行に対しては、同処理は実装されない）。例えば、図２のSampleクラスに追跡ログ出力処理を実装した場合は、ソースコード上の２，３，５，６，７，９行目に対応する処理の直前に追跡ログ出力処理が実装される。４，８行目はクラスの動作には直接対応していない行であり、追跡ログ出力処理は実装されない。
【００１６】
図３は、追跡ログファイルのフォーマットを示したものである。
追跡ログファイルは各項目がカンマで区切られたテキストファイルであり、追跡ログファイル中の１行が、１件の追跡ログに対応する。
スレッドＩＤ（３０１）には、この追跡ログの出力処理が実行されたスレッドの識別子（スレッドＩＤ）が出力される。スレッドさえ識別できれば、この項目はどのような形式であってもよい。本実施形態では３桁の整数値をスレッドＩＤとして使用している。
ファイル名（３０２）は、この追跡ログ出力処理が実装されたクラスに紐づくソースコードのファイル名が出力される。
同様に、行番号（３０３）には、この追跡ログ出力処理が実装されたソースコード上の行番号が出力される。
分類（３０４）は、この追跡ログの出力処理が設定された箇所の種類を示す文字列が出力される。この追跡ログがメソッドの開始時に出力されるよう実装されていれば、“ENTRY”、メソッドの終了時に出力されるよう実装されていれば“EXIT”、例外オブジェクトのキャッチ時に出力されるよう実装されていれば、“CATCH”が出力され、それら以外は“-”が出力される。
クラス名（３０５）、メソッド名（３０６）は、この追跡ログの出力処理が実装されたクラス名とメソッド名を示す。
最後に、エラー情報（３０７）は、分類（３０４）が“CATCH”の時にだけ出力される項目であり、キャッチした例外オブジェクトのエラー情報（エラーメッセージやスタックトレース情報）を出力する。このフォーマットにしたがって出力された追跡ログは、図２の（２０２）に示すようなものとなる。
【００１７】
図４は、対象アプリケーション（１０１）が出力した追跡ログをログ分析装置（１０５）が読み込む処理を図示したものである。
ログ読み込み部（１０６）は、出力された追跡ログ（２０２）を１行ずつ読み込み、各項目をカンマごとに区切り、各項目の値を抽出し、それらの値からログデータ（４０１）を生成し、ログデータ記憶部（１０７）に格納する。
ログデータ（４０１）は、追跡ログ（２０２）と同じようなデータをもつデータ構造であり、スレッドＩＤ、ファイル名、行番号、分類、クラス名、メソッド名、エラー情報をデータとして保持する。
上記のログ読み込み処理を繰り返し、全ての追跡ログ（２０２）をログデータとしてログデータ記憶部（１０７）に格納する。
【００１８】
図５は、ログデータ記憶部（１０７）に格納された複数のログデータをログデータ分類部（１０８）が読み込み、ログデータ分類部（１０８）はそれぞれのログデータが保持するスレッドＩＤの値ごとにログデータを分類し、分類済みログデータ（５０１）、（５０２）、（５０３）を作成し、分類済みログデータ記憶部（１０７）に格納する処理を示している。
分類済みログデータのデータ構造は、図６に示すように、スレッドＩＤ（６０１）と、ログデータのリスト（６０２）を保持する。
例えば、図５では分類済みログデータ（５０１）は、“スレッドＩＤ”として“００１”を保持しており、そのログデータのリストには、ログデータ記憶部（１０７）に格納されているログデータのうち、“スレッドＩＤ”データが“００１”であるもののみを格納している。
【００１９】
図７は、コールグラフデータ構築部（１１０）が、分類済みログデータ記憶部（１０９）から分類済みログデータ（７０１）を読み込み、コールグラフデータ（７０２）を作成する処理を示している。
コールグラフデータ（７０２）はツリー構造のデータであり、ツリーの頂点に「ルート」オブジェクト（７０２１）があり、その子要素として「スレッド」オブジェクト（７０２２）が複数結合している。さらに、「スレッド」オブジェクト（７０２２）の子要素としてログデータ（７０２３）が複数結合している）。
ログデータ同士の間にも、メソッドを呼び出した側／呼び出された側の関係に対応したツリーの親子関係が存在する。生成したコールグラフデータ（７０２）は、コールグラフデータ記憶部（１１１）に格納される。
【００２０】
図８は、「ルート」オブジェクト、「スレッド」オブジェクトのデータ構造を示したものである。
「ルート」オブジェクト（７０２１）は内部にデータを持たないオブジェクトであり、「スレッド」オブジェクト（７０２２）はスレッドＩＤ（７０２２１）を保持するオブジェクトである。
【００２１】
図９は、コールグラフデータ構築部（１１０）がコールグラフデータ（７０２）を構築するアルゴリズムを示すフローチャートである。
まず、コールグラフデータ構築部（１１０）は「ルート」オブジェクトを１つ作成する（ステップ９０１）。
次に、分類済みログデータ記憶部（１０９）から分類済みログデータ（７０１）を１件取得する（ステップ９０２）。
次に、取得した分類済みログデータ（７０２）が保持する“スレッドＩＤ”を取得し、その値を使用して「スレッド」オブジェクトを作成し、ステップ９０１で作成した「ルート」オブジェクトの子要素として設定する（ステップ９０３）。
次に、一時変数“直前の要素”にステップ９０３で作成した「スレッド」オブジェクトを設定する（ステップ９０４）。これはコールグラフデータのツリー構造を構築するために使用する一時的な変数である。
次に、ステップ９０２で取得した分類済みログデータ（７０１）が保持するログデータを１件取得する（ステップ９０５）。
次に、取得したログデータ（７０１）の“分類”の値を取得し、この値を評価する（ステップ９０６）。
【００２２】
“分類”が“ENTRY”である場合は、一時変数“親要素”に、一時変数“直前の要素”に格納されている要素を設定する（ステップ９０７）。そして、一時変数“親要素”に設定されている要素の子要素として、ステップ９０５で取得したログデータを設定する（ステップ９１０）。
“分類”が“EXIT”である場合は、ステップ９０５で取得したログデータを、一時変数“親要素”に設定されている要素の子要素として設定する（ステップ９０８）。そして、一時変数“親要素”に、一時変数“親要素”に設定されている要素の親要素を設定する（ステップ９０９）。
“分類”が“EXIT”“ENTRY”以外である場合は、ステップ９０５で取得したログデータを、一時変数“親要素”に設定されている要素の子要素として設定する（ステップ９１０）。
以上の処理が完成したならば、次に、一時変数“直前の要素”に、ステップ９０５で取得したログデータを設定する（ステップ９１１）。
以上、ステップ９０２で取得した分類済みログデータ（７０１）が保持する全てのログデータに関して、ステップ９０５からステップ９１１までの処理を繰り返し行う（ステップ９１２）。
また、分類済みログデータ記憶部（１０９）に記憶されている全ての分類済みログデータ（７０１）に関して、ステップ９０２からステップ９１２までの処理を繰り返し行う（ステップ９１３）。
以上で、コールグラフデータの構築処理は完了である。
【００２３】
図１０は、コールグラフ表示装置（１１２）が、コールグラフデータ構築部（１１０）が構築したコールグラフデータを読み込み、ディスプレイ（１１７）に表示したコールグラフ（１００１）の例を示す図である。
コールグラフデータはツリー構造をもつデータであるため、コールグラフ表示装置（１１２）はツリー構造をそのままツリー形式で表示している。
図１０では、はじめに「スレッド[001]」（１００２）、「スレッド[002]（１００３）、「スレッド[003]（１００４）のノードが表示されており、そのうち「スレッド[001]」（１００２）のツリーノードを展開すると、スレッドIDが001であるスレッド上で実行された処理に関する全てのログ（１００５）が表示される。
このツリーを見れば、アプリケーションの実行経路を用意に把握することができ、また、メソッドの呼び出し関係がツリー構造で表現されているため、例えば、あるメソッドが、どのメソッドから呼び出されたものであるか、などといった関係を容易に把握することができる。
【００２４】
図１１は、対象アプリケーション（１０１）にエラーが発生した際の追跡ログを読み込み、コールグラフ表示装置（１１２）で表示したものの一部を示す図である。
コールグラフ表示装置（１１２）は、ログデータの“分類”データの値が“CATCH”であるものは、コールグラフを表示する際に、そのログデータにエラーが発生したことを示すマーク（１１０１）を表示する。
このように表示することにより、多数の追跡ログの中からエラーの発生を示すログを探し易くなる。この場合、エラーが発生したことを示すマーク（１１０１）はログデータ「Sample.run(String):21」（１１０３）に表示されているため、当該Sampleクラス（１１０３）のソースコード（１１０４）上の21行目（１１０５）で例外オブジェクトをキャッチしていることがわかり、このログデータの１つ前のログデータ「Sample.run(String):20」（１１０２）を参照すると、Sampleクラス（１１０３）のソースコード（１１０４）上の２０行目（１１０６）に記述されている処理の実行中にエラーが発生したことが推測できる。
【００２５】
しかしこの場合、何故２０行目で例外が発生したのか、根本的な原因を明確にすることはできない。そこで、本発明では「比較」機能を用いて、ログを比較することにより、例外の根本的な原因を特定する。「比較」機能は、指定したエラーログが示す例外が発生するまでの一連のログと、その一連のログと同一の動作経路を示す別の一連のログとを比較し、その差分を表示することで、障害の根本的な原因を特定する作業を支援する機能を提供する。
【００２６】
図１２は、「比較」機能を実行している様子を示している。「比較」機能を実行するには、エラーを示すマークが表示されているログデータ（１２０１）を選択し、表示されるメニューから「比較」（１２０２）を指定する。すると、ログ比較範囲計算部（１１３）は図１３のフロ−チャ−トに示すアルゴリズムに従って処理を行う。
【００２７】
図１３に示すアルゴリズムでは、まずコールグラフで選択されているログデータを取得する（ステップ１３０１）。
次に、一時変数“対象データ”に選択されたログデータを設定する（ステップ１３０２）。
次に、一時変数“対象データ”に設定されているデータが「スレッド」オブジェクトであるかどうかを評価する（ステップ１３０３）。
「スレッド」オブジェクトでない場合は、一時変数“対象データ”に設定されているログデータを、対象ログデータリストに追加する（ステップ１３０４）。対象ログデータリストはリスト構造をもつ一時データである。
次に、一時変数“対象データ”に、“対象データ”に設定されているデータの親要素のデータを設定する（ステップ１３０５）。そして、一時変数“対象データ”に設定されているデータが「スレッド」オブジェクトになるまで、ステップ１３０３からステップ１３０５の処理を繰り返し、ステップ１３０３の判定処理において、対象データが「スレッド」オブジェクトであると評価された場合は、対象ログデータリストに格納されたログデータを、「比較範囲設定」ダイアログ上にツリー形式で表示する（ステップ１３０６）。
すると、「比較範囲設定」ダイアログ（１４０１）が図１４のように表示される。
【００２８】
図１４は、「比較範囲の設定」ダイアログ（１４０１）が表示され、コールグラフデータ表示装置（１１２）でユーザが選択指定したログデータ（１４０５）と、その全ての親要素のログデータ（１４０２、１４０３、１４０４）がツリー形式で表示される様子を示している。
このダイアログ（１４０１）では、図１２のコールグラフでユーザが選択指定したエラーログが出力されるまでに、どのようなメソッドの呼び出し経路を辿ったかを示している。
例えば、図１４の例では、まずSampleクラスのmain(String[])メソッド内の処理中（ソースコードの３００行目に記述されている処理）でservice()メソッドが呼び出され、呼び出されたservice()メソッドはさらにメソッド内の処理中（ソースコードの２５０行目に記述されている処理）で、action()メソッドを呼び出し、さらにaction()メソッドの処理中（ソースコードの１６行目に記述されている処理）で、run(String)メソッドを呼び出し、run(String)メソッド内の処理（ソースコードの２１行目に記述されている処理）で、例外が発生したことを示している。
【００２９】
次に、「比較範囲の設定」ダイアログ（１４０１）に表示されているメソッドの呼び出し関係から、比較を行うログの範囲を決定する。ここで選択したメソッド呼び出しの経路と同一の処理経路を示すログが比較の対象となる。例えば図１４の場合は「Sample.service():250」（１４０３）と「Sample.action():16」（１４０４）と「Sample.run(String):21」（１４０５）を選択しており、この場合は「Sampleクラスのserviceメソッドが実行され、250行目の処理でaction(String)メソッドを呼び出し、actionメソッドが実行され、16行目の処理でrun(String)メソッドを呼び出し、run(String)メソッドが実行され、run(String)メソッドが終了するまで」を示すログを、比較の対象として指定していることになる。
この状態で「比較開始」ボタン（１４０６）を押す操作を行う。
すると、比較ログデータリスト生成部（１１４）は、図１５のフロ−チャ−トに示す処理を行い、比較先ログデータリストを作成する。
【００３０】
図１５では、まず「比較範囲の設定」ダイアログ（１４０１）で指定したログデータのリスト（比較範囲データ）を取得する（ステップ１５０１）。比較範囲データ（１６０１）は、図１６に示すようなツリー構造のデータであり、「比較範囲の設定」ダイアログ（１４０１）で指定したログデータと同様の構造を持っている。
次に、取得した比較範囲データ（１６０１）から、葉のデータ（つまりツリー構造のデータの末端に存在するデータ）を取得する（ステップ１５０２）。図１６の例では、ログデータ（１６０４）が、葉のデータに該当する。
次に、コールグラフデータ記憶部（１１１）からコールグラフデータを１件ずつ取得する（ステップ１５０３）。
次に、取得したコールグラフデータが保持するログデータを１件ずつ取得する（ステップ１５０４）。
次に、ステップ１５０４で取得したログデータの“分類”データが“ENTRY”であり、かつ“クラス名”“メソッド名”データが、ステップ１５０２で取得した葉データの“クラス名”“メソッド名”データと一致するかどうか、評価する（ステップ１５０５）。
【００３１】
図１６を例にとると、取得したログデータの“分類”データが“ENTRY”であり、かつ“クラス名”データが“C”、“メソッド名”データが“c()”であるかどうかを評価する。
ステップ１５０５の評価結果が“真”であれば、次にステップ１５０４で取得したログデータの親ノードの構造と、ステップ１５０２で取得した葉データの親ノードの構造が一致しているかどうかを評価する（ステップ１５０６）。
一致している場合は、一致している部分の最上位の親ノードが示すメソッドの、開始時を示すログデータから、ステップ１５０４で取得したログデータが示すメソッドの終了時を示すログデータまでの一連のログデータ（一致ログデータ）を、一致ログデータリストに追加する（ステップ１５０７）。
なお、一致ログデータリストとは、一致ログデータを格納するリストである。
例えば、図１６では、（１６０１）に示す比較範囲データがある。これは、（行番号＝“４０”、分類＝”-“、クラス名＝“C”、メソッド名＝“c()”」というデータを持つ葉ログデータ（１６０４）があり、その親ノードとして（行番号＝“３０”、種別＝”-“、クラス名＝“B”、メソッド名＝“b()”」というデータをもつログデータ（１６０３）が存在し、さらにその親ノードとして、（行番号＝“２０”、種別＝”-“、クラス名＝“A”、メソッド名＝“a()”」というデータをもつログデータ（１６０２）が存在する、という構造を持つ比較範囲データである。
【００３２】
このような比較範囲データ（１６０１）に対して、図１５に示す処理を適用すると、ステップ１５０５の評価の結果、図１７に示すような、（１７０１）、（１７０４）という２つのログデータが抽出されたとする。これらのデータに対し、ステップ１５０６の評価を適用する。
ログデータ（１７０１）の親ノードを見てみると、その親ノードは、（行番号＝“３０”、分類＝”-“、クラス名＝“B”、メソッド名＝“b()”」というデータをもつログデータ（１７０２）であり、さらにその親ノードは（行番号＝“２０”、分類＝”-“、クラス名＝“A”、メソッド名＝“a()”」というデータを持つログデータ（１７０３）であるため、比較範囲データの葉ノード（１６０４）と、ログデータ（１７０１）の親ノードの構造は一致しているといえる。
【００３３】
一方、ログデータ（１７０４）の親ノードを見てみると、その親ノードは、（行番号＝“９９”、分類＝”-“、クラス名＝“Z”、メソッド名＝“z()”）というデータを持つログデータ（１７０５）であり、さらにその親ノードは（行番号＝“６０”、分類＝”-“、クラス名＝“E”、メソッド名＝“e()”」というデータを持つログデータ（１７０６）であるため、比較範囲データの葉ノード（１６０４）と、ログデータ（１７０４）の親ノードの構造は一致しない。
これにより、（１７０７）が示す範囲の一連のログデータが一致ログデータとして抽出される。この一致ログデータは、一致ログデータリストに格納される。
コールグラフデータ記憶部（１１１）が保持する全てのコールグラフデータを取得し、さらにそのコールグラフデータが保持する全てのログデータに関して、ステップ１５０３からステップ１５０９までの処理を繰り返し、全て完了したら、比較先ログデータリストの作成に関する処理は全て終了である。
【００３４】
ところで、図１５に示す処理では、全てのログデータから、比較範囲データ（１６０１）が保持するログデータと親データの構造が一致するものを取得していたため、当然、比較元となる一連のログデータも、その他の一致ログデータと一緒に一致ログリストに格納されてしまっている。
そのため、図１５に示す処理の完了後に、一致ログデータリストから、比較元の一連のログデータを分離する必要がある。この処理は、一致ログデータリストに格納されている一致ログデータの中から、比較範囲データが保持する各ログデータを構成要素としている一致ログデータを探し出すことにより実現できる。
【００３５】
例えば、図１８では、一致ログデータリスト（１８１２）に格納されている、一致ログデータ（１８１３）を構成しているログデータ（１８０１、１８０２、１８０３）と、比較範囲データ（１８０７）が保持するログデータ（１８０４，１８０５，１８０６）は、それぞれ同一のオブジェクトであるため、一致ログデータ（１８１３）は比較元の一連のログデータ（比較元ログデータ）であることがわかる。そこで、一致ログデータ（１８１３）を一致ログデータリストから取り出す（１８１１）。
以降、一致ログデータリスト（１８１２）から取り出した一致ログデータ（１８１３）を、“比較元ログデータ”（１８１４）、そして比較元ログデータを取り除いた状態の一致ログデータリストを“比較先ログデータリスト”（１８１５）と称する。
【００３６】
比較元ログデータ（１８１４）と、比較先ログデータリスト（１８１５）の取得が完了したならば、次に実際にこれらのログデータを比較する処理を行うが、その前に、図１９に示すように比較元ログデータ（１８１４）と、比較先ログデータリスト（１８１５）に格納されている全ての比較先ログデータに関して、そのデータ構造を、一旦、非階層構造のフラットなリスト構造に変換する（１９０３、１９０４）。ログデータは、枝の分岐を持たないツリー構造のデータであるため、リスト構造に変換する場合は、単純に先頭ノードのログデータから順番に、リスト構造のデータに値を格納するだけである。
【００３７】
ログデータのデータ構造の変換が完了したならば、比較処理部（１１５）を使用して、フラット化した比較元ログデータ（１９０３）と、比較先ログデータリスト（１９０４）に格納されている全ての比較先ログデータの比較を行う。
比較処理部（１１５）は、diffプログラムと同等機能のプログラムである。diffプログラムとは２つのデータの相違点を取得するためのプログラムであり、有名なものとしてはUNIX（登録商標）のdiffコマンドなどが挙げられる。diffプログラムは通常２つのテキストファイルに対し、それぞれの各行の文字列を比較の対象とし、その相違を取得するが、比較処理部（１１５）は比較元ログデータ（１９０３）と比較先ログデータリスト（１９０４）に格納されるログデータのデータの相違を取得する。なお、diffプログラムの比較アルゴリズムに関しては、公知の技術であるため説明を省略する。
【００３８】
図２０〜図２２は、比較元ログデータ（１９０３）と、比較先ログデータリスト（１９０４）から取得した比較先ログデータ（１）（２００２）との比較処理の様子を示したものである。
図２０では、比較処理部（１１５）が、比較元ログデータ（１９０３）のログデータ（２００３）と、比較先ログデータ（１）（２００２）のログデータ（２００４）とが“衝突”していることを検知している様子を示している。“衝突”とは、同様の行に存在するデータが異なっている状態を示す。この例では比較元のログデータ（２００３）の行番号データは“８”であるのに対し、比較先のログデータ（２００４）の行番号データは“１０”であるため、衝突が発生している。この場合、比較処理部（１１５）、比較情報データ（２００６）を作成し、比較情報データリスト（２００５）に追加する。比較情報データリスト（２００５）は、ログデータを比較した結果に関する情報を格納するためのデータリストであり、“相違の種類”（２００７）、“比較元の相違開始インデックス”（２００８）、“比較元の相違終了インデックス”（２００９）、“比較先の相違開始インデックス”（２０１０）、“比較先の相違終了インデックス”（２０１１）というデータを保持する。
【００３９】
“相違の種類”データには、“衝突”、“追加”、“削除”のいずれかの値が格納される。
“比較元の相違開始インデックス”、“比較元の相違終了インデックス”、“比較先の相違開始インデックス”、“比較先の相違終了インデックス”データには、相違箇所を特定するためのインデックス情報が格納される。なお、比較元ログデータ、比較先ログデータはリスト構造を持ったデータであり、要素の位置を示すためのインデックス情報を持っている。
図２０の場合は、“相違の種類”データ（２００７）には“衝突”を格納し、また比較元ログデータのインデックス２〜３の間のログデータと、比較先ログデータのインデックス２〜３の間のログデータに関して衝突が発生しているため、“比較元の相違開始インデックス”（２００８）には“２”を、“比較元の相違終了インデックス”（２００９）には“３”を、“比較先の相違開始インデックス”（２０１０）には“２”を、“比較先の相違終了インデックス”（２０１１）には“３”を格納している。
【００４０】
図２１は、比較処理部（１１５）が“挿入”を検知している様子を示している。
“挿入”とは、ある箇所において、比較元ログデータ（１９０３）には存在せず、比較先のログデータ（１）（２００２）には存在するログデータがある状態を示す。
図２１の例では、比較元ログデータ（１９０３）の（２１０１）の位置（インデックス５の位置）にはログデータは存在しないが、比較先ログデータ（２００２）の同じ位置には（２１０２）に示すログデータが存在するため、挿入が発生していることがわかる。このような場合、比較処理部（１１５）は比較情報データ（２１０３）を、比較情報データリスト（２００５）に追加する。
【００４１】
図２２は、比較処理部（１１５）が“削除”を検知している様子を示している。
“削除”とは、ある箇所において、比較元ログデータ（１９０３）には存在しているが、比較先のログデータ（２００２）には存在しないログデータがある状態を示す。
図２２の例では、比較元ログデータ（１９０３）の（２２０１）の位置（インデックス８〜１０の間）には存在するが、比較先ログデータ（２００２）の（２２０２）の位置（インデックス９の位置）には存在しないログデータがあるため、削除が発生していることがわかる。このような場合、比較処理部（１１５）は比較情報データ（２２０３）を比較情報データリスト（２００５）に追加する。
【００４２】
このように、比較元ログデータ（１９０３）と、比較先ログデータ（１）（２００２）を比較して作成した比較情報データは、比較先ログデータ（１）（２００２）に紐付けられ、保存される。
比較処理部（１１５）は、上記と同様の手順で全ての比較先ログデータ（１９０４）と、比較元ログデータ（１９０３）に関して比較処理を行い、それぞれの比較先ログデータに対応する比較情報データ（２３０３）を作成する。そして、図２３に示すように、比較情報データ（２３０３）はフラット化前の比較先ログデータ（１８１５）と紐付け、フラット化前の比較元ログデータ（１８１４）と共に比較結果記憶部（１１５Ｍ）に保存する。
比較元ログデータと、比較先データリスト、そしてそれに紐づく比較情報データ、それぞれが作成できたならば、最後にこれらのデータをログ比較結果表示装置（１１６）に渡し、ディスプレイ（１１７）に表示する。
【００４３】
図２４に示すように、比較元ログデータ（１８１４）は比較元ビュー（２４０１）に表示し、比較先ログデータリストに格納されている比較先ログデータ（１８１５）は、それぞれ比較先ビュー（２４０２）の各タブビュー（２４０３）に表示する。
タブ（２４０４）を切り替えることにより、それぞれの比較先ログデータを見ることができる。また、比較情報データを元に、各ビュー内のログデータをハイライト表示することで、“衝突”、“挿入”、“削除”の状況が容易に把握できる。なお、“衝突”の箇所は黄色（２４０５）、“挿入”の箇所は青色（２４０６）、“削除”の箇所は赤色（２４０７）で表示される。
また、この状態でソースコードエディタを用いてソースコード記憶部１１８から対象アプリケーション（１０１）のソースコードを読み出し、ログ比較結果表示装置（１１６）に渡すと、ログ比較結果表示装置（１１６）はハイライト表示されているログデータが示すソースコード行を図２５に示すようにハイライト表示して明示する。
【００４４】
図２５では、Sampleクラスのソースコードをソースコードエディタ（２５０１）で取得してログ比較結果表示装置（１１６）で表示した例を示したものである。
ここでは、図２４でハイライト表示されているログデータが示す行（８，１０，１４，２１，２２行目）が（２５０２）、（２５０３）、（２５０４）、（２５０５）で示すように同色でハイライト表示される。また、図２４におけるタブ（２４０４）を切り替えることにより、別の比較先ログデータとの比較結果が同じようにハイライト表示される。
【００４５】
以上の機能により、対象アプリケーション（１０１）にエラーが発生した場合、そのエラーが発生するに至った処理経路を示すログと、同様の処理経路を示している過去のログを比較することができ、さらにその比較結果に基づきエラーが発生している処理経路中のソースコードをハイライト表示することにより、エラーの根本的な原因を解決する支援が可能となる。
【００４６】
例えば、対象アプリケーション（１０１）の運用者がエラーの原因追跡を行う場合は、まず対象アプリケーション（１０１）が出力するログをログ分析装置（１０５）に読み込み、「比較」機能を実行する。すると図２４、２５に示したように、エラー発生時点以前の過去のログとの比較結果が、ログ比較結果表示装置（１１２）でディスプレイ（１１７）にハイライト表示される。
図２５の例では２１，２２行目がハイライト表示されているため、この行で例外をキャッチしたことがエラーの直接の原因である、ということが即座に把握できる。
さらに、なぜ例外が発生したのか、すなわちこのエラーの根本的な原因は何なのかを調査する場合は、その他のハイライト表示箇所が根本的な原因を特定する手がかりとなる。
図２５のソースコードを見ると、８、１０行目に黄色のハイライト表示（２５０２）、（２５０３）があり、言い換えると、以前にこのメソッドが実行した際は１０行目が実行されたが、今回（エラーが発生時）は、８行目が実行されていた、ということがわかる。そこで、アプリケーション開発者は８，１０行目の処理を中心にソースコードを精査することで、エラーの根本的な原因を突き止めることができる。
【００４７】
なお、上記の説明では対象アプリケーションのエラーの原因箇所を特定する作業を行う場合の処理について説明したが、エラーが発生しない場合において、ユーザが設定した特定の処理経路を持つメソッドを抽出する場合にも利用することができる。この場合には、図１１のコールグラフ中で任意のスレッドを選択し、このスレッド内の処理でエラーが発生したものと擬似的に設定した後、エラーが発生した場合と同様の処理を行えばよい。
また、比較結果については、ディスプレイ画面に出力しているが、印刷装置で印刷出力する構成にすることができることは言うまでもない。
【図面の簡単な説明】
【００４８】
【図１】本発明に係るアプリケーションの障害原因の特定作業支援システムの実施形態を示す全体構成図である。
【図２】Sampleクラスのソースコードとそのクラスに対し追跡ログ出力処理の実装を行った場合に出力される追跡ログの例を示す図である。
【図３】追跡ログファイルのフォーマットの例を示す図である。
【図４】対象アプリケーションが出力した追跡ログをログ分析装置が読み込む処理の概要を示す図である。
【図５】ログデータ記憶部に格納された複数のログデータをログデータ分類部が読み込み、それぞれのログデータが保持するスレッドＩＤの値ごとにログデータを分類し、分類済みログデータを作成し、分類済みログデータ記憶部に格納する処理の概要を示す図である。
【図６】分類済みログデータのデータ構造の例を示す図である。
【図７】コールグラフデータ構築部が分類済みログデータ記憶部から分類済みログデータを読み込み、コールグラフデータを作成する処理の概要を示す図である。
【図８】「ルート」オブジェクト、「スレッド」オブジェクトのデータ構造の例を示す図である。
【図９】コールグラフデータ構築部がコールグラフデータを構築するアルゴリズムを示すフローチャートである。
【図１０】コールグラフ表示装置がコールグラフデータ構築部で構築したコールグラフデータを読み込み、ディスプレイに表示したコールグラフの例を示す図である。
【図１１】対象アプリケーションにエラーが発生した際の追跡ログを読み込み、コールグラフ表示装置で表示したものの一部を示す図である。
【図１２】「比較」機能を実行させる様子を示す図である。
【図１３】ログ比較範囲計算部のアルゴリズムを示すフローチャートである。
【図１４】「比較範囲の設定」ダイアログ上にユーザが選択指定したログデータとその全ての親要素のログデータがツリー形式で表示される例を示す図である。
【図１５】比較ログデータリスト生成部のアルゴリズムを示すフローチャートである。
【図１６】比較範囲データのツリー構造を示す図である。
【図１７】比較範囲データに対して抽出される２つのログデータの例を示す図である。
【図１８】比較元ログデータと比較先ログデータの生成処理の概要を示す図である。
【図１９】比較元ログデータと比較先ログデータリストに格納されている全ての比較先ログデータのデータ構造を、非階層構造のフラットなリスト構造に変換する処理の概要を示す図である。
【図２０】比較元ログデータと比較先ログデータリストから取得した比較先ログデータとの比較処理の概要を示す図である。
【図２１】比較処理部が“挿入”を検知した例を示す図である。
【図２２】比較処理部が“削除”を検知した例を示す図である。
【図２３】比較先ログデータと比較情報データの紐付けを示す図である。
【図２４】ログ比較結果の表示例を示す図である。
【図２５】エラー原因と考えられるソースコードの行をハイライト表示した例を示す図である。
【符号の説明】
【００４９】
１０１…対象アプリケーション、１０２…ログ出力処理実装装置、１０３…ログ出力処理実装済みアプリケーション、１０４…ログファイル格納部、１０５…ログ分析装置、１０６…ログ読み込み部、１０７…ログデータ記憶部、１０８…ログデータ分類部、１０９…分類済みログデータ記憶部、１１０…コールグラフデータ構築部、１１１…コールグラフデータ記憶部、１１２…コールグラフ表示装置、１１３…ログ比較範囲計算部、１１４…比較ログデータリスト生成部、１１５…比較処理部、１１６…ログ比較結果表示装置、１１７…ディスプレイ、１１８…アプリケーションソースコード格納部。
【図１】
0004737624.tif 000002
【図２】
0004737624.tif 000003
【図３】
0004737624.tif 000004
【図４】
0004737624.tif 000005
【図５】
0004737624.tif 000006
【図６】
0004737624.tif 000007
【図７】
0004737624.tif 000008
【図８】
0004737624.tif 000009
【図９】
0004737624.tif 000010
【図１０】
0004737624.tif 000011
【図１１】
0004737624.tif 000012
【図１２】
0004737624.tif 000013
【図１３】
0004737624.tif 000014
【図１４】
0004737624.tif 000015
【図１５】
0004737624.tif 000016
【図１６】
0004737624.tif 000017
【図１７】
0004737624.tif 000018
【図１８】
0004737624.tif 000019
【図１９】
0004737624.tif 000020
【図２０】
0004737624.tif 000021
【図２１】
0004737624.tif 000022
【図２２】
0004737624.tif 000023
【図２３】
0004737624.tif 000024
【図２４】
0004737624.tif 000025
【図２５】
0004737624.tif 000026