これは InterSystems FAQ サイトの記事です。
監査ログはシステムDB内テーブル(%SYS.Audit)に記録されていますので、そのテーブルに対するクエリを実行して抽出したり、%SYS.Auditテーブルに用意されていストアドプロシージャを利用して情報を取得しファイル出力するようにプログラムを用意することもできます。
以下にご紹介する内容は「監査ログをプログラムで出力(ユーザやイベント指定など)する方法」に関連した内容で、監査ログのファイル出力を管理ポータルの機能を利用した例とプログラムを利用した例でご紹介します。
1. 管理ポータルの印刷機能を使う
管理ポータル > [システムエクスプローラ] > [SQL]を開き、%SYSネームスペースに接続します。
システムのチェックを入れ、スキーマに%SYSを指定した後、プロシージャの階層を展開するとプロシージャリストが参照できます。
%SYS.Audit_ で始まるプロシージャが監査ログに対して実行できるプロシージャです。
SQL文例)InterSystems製品内ユーザのSuperUserに対する監査ログをストアドプロシージャ:%SYS,Audit_ListByUser を利用して出力しています。
call %SYS.Audit_ListByUser(,,,,,'SuperUser')
引数については、クラスリファレンス:%SYS.Audit_ListByUserをご参照ください。
管理ポータル内の「印刷」の機能を利用するとファイル出力できます。
2. プログラムでファイル出力する
%SYS上に以下のようなメソッド(またはルーチン)を用意すると任意のカラムのみを出力できます。
注意:クラスの場合はパッケージ名の先頭文字にZを、ルーチンの場合はルーチン名の先頭にZをつけて保存してください。
%SYS.AuditクラスのListByUserプロシージャはクラスクエリとしても実行できるため、コード例ではクラスクエリで実行しています。
また出力するカラムもTimeStampとEventDataのみとしています。
Class ZAudit.Utils
{
/// 第1引数:出力ファイル名をフルパスで指定します。
/// 第2引数:ユーザ名を指定します。
ClassMethod OutputToFile(fname As %String, user As %String = "SuperUser")
{
set fo=##class(%Stream.FileCharacter).%New()
do fo.LinkToFile(fname)
//SQL実行用インスタンスを生成
set stmt=##class(%SQL.Statement).%New()
//定義されているストアドプロシージャはクラスクエリの形式でも利用できます。
//例ではクラスクエリを実行する方法を記載しています。
set status=stmt.%PrepareClassQuery("%SYS.Audit","ListByUser")
set rset=stmt.%Execute(,,,,,user) //第6引数に調査したいユーザ名を指定
#dim rset As %SQL.StatementResult
//TimeStamp と EventDataを出力します
do fo.WriteLine("TimeStamp,EventData")
while rset.%Next() {
do fo.Write(rset.%Get("TimeStamp")_",")
do fo.WriteLine(rset.%Get("EventData"))
}
set status=fo.%Save()
kill fo
}
}
実行例は以下の通りです。
%SYS>do ##class(ZAudit.Utils).OutputToFile("/usr/irissys/mgr/user/t2.csv","SuperUser")
注意:バージョン2022.1.3以前で実行する場合
EventDataプロパティが参照できないので以下コード例のように実行してください。
ClassMethod OutputToFile2(fname As %String, user As %String = "SuperUser")
{
set fo=##class(%Stream.FileCharacter).%New()
do fo.LinkToFile(fname)
//SQL実行用インスタンスを生成
set stmt=##class(%SQL.Statement).%New()
//定義されているストアドプロシージャはクラスクエリの形式でも利用できます。
//例ではクラスクエリを実行する方法を記載しています。
set status=stmt.%PrepareClassQuery("%SYS.Audit","ListByUser")
set rset=stmt.%Execute(,,,,,user) //第6引数に調査したいユーザ名を指定
#dim rset As %SQL.StatementResult
//TimeStamp と EventDataを出力します
do fo.WriteLine("TimeStamp,EventData")
while rset.%Next() {
set utc=rset.%Get("UTCTimeStamp")
set sid=rset.%Get("SystemID")
set aid=rset.%Get("AuditIndex")
set stauts=##class(%SYS.Audit).Get(utc,sid,aid,.data)
do fo.Write(rset.%Get("TimeStamp")_",")
do fo.WriteLine($get(data("EventData")))
kill data
}
set status=fo.%Save()
kill fo
}