NXLog CEでCSVの操作ログをJSONに変換してみた

NXLog CEでCSVの操作ログをJSONに変換してみた

以前WindowsServerにNXLogをインストールしたりしてみました。前回はNXLogからJSONを送信してみましたが、今回はCSVファイルをJSONに変換するというのをやってみます。

今回のゴール

CSVファイルをJSONに変換するというのをNXLogでやってみます。

なぜそんなことをするのか?

NXLogはWindowsサーバーなどにインストールして、JSON形式でSIEMなどにログを送付できるツールです。

ログを送りたいソフトウェアによってはJSON出力に対応しておらず、CSV出力しかできないというケースが多いと思います。CSVのままだとSIEMには送れないことが多いため、JSONに変換する必要があります。

NXLogで変換可能なのか?

可能です。NXLogにはCSVを扱うモジュール(xm_csv)とJSONを扱うモジュール(xm_json)が標準で用意されているので、設定ファイルを書くだけで変換できます。

SIEMには転送しない?

今回はJSONファイルとして出力するところまでです。転送はしませんが、設定ファイル内にSIEM送信用の設定も書いてあるので、送信先を書き換えるだけで転送できるようになっています。

どんなログを想定するか?

CSV出力できるソフトは色々ありますが、ここではSKYSEAやLANSCOPEのような、Windowsにインストールして動くエンドポイント管理ソフトの操作ログを想定しています。

NXLogのインストール

インストールに関しては Windows ServerにNXLogをインストールする手順 をご覧ください。


サンプルCSV

CSVはUTF-8で用意します。エンドポイント管理ソフトが出力するような48列の操作ログを想定しました。


イベント日時,コンピュータ名,ユーザー名,ドメイン名,操作種別,操作詳細,フルパス,ファイル名,拡張子,ファイルサイズ,ウィンドウタイトル,実行プロセス名,プロセスID,デバイス種別,ベンダー名,製品名,シリアル番号,接続アクション,ドライブレター,許可状態,送信元IPアドレス,送信元ポート,送信先IPアドレス,送信先ポート,通信プロトコル,送信データ量,受信データ量,URL/ドメイン,HTTPメソッド,ブラウザ名,ログイン時刻,ログアウト時刻,セッション持続時間,端末IPアドレス,MACアドレス,OSバージョン,パッチ適用日,ドキュメント名,プリンタ名,ページ数,複写枚数,カラー設定,両面印刷設定,送信者アドレス,宛先アドレス,件名,添付ファイル名,添付ファイルサイズ
2026-04-02 08:32:51,logw-PC-SALES-05,yamada,logw-domain,ログイン,画面ロック解除,,,,,,explorer.exe,8075,,,,,,,,192.168.1.50,,,,,,,,,,2026-04-02 08:32:51,,,192.168.1.50,22-33-44-55-66-77,Windows 11,2026-03-15,,,,,,,,,,,
2026-04-02 08:36:20,logw-PC-ADMIN-01,hirabayashi,logw-domain,ログイン,サインイン,,,,,,explorer.exe,5489,,,,,,,,192.168.1.10,,,,,,,,,,2026-04-02 08:36:20,,,192.168.1.10,00-11-22-33-44-55,Windows 11,2026-03-25,,,,,,,,,,,
2026-04-02 09:05:02,logw-PC-ADMIN-01,hirabayashi,logw-domain,メール送信,SMTP,,,,,,,,,,,,,,,192.168.1.10,587,203.0.113.10,587,SMTP,20569,1703,,,,,,,192.168.1.10,00-11-22-33-44-55,Windows 11,2026-03-25,,,,,,,hirabayashi@logw-sample.co.jp,partner@example.com,見積書送付,report.pdf,12000

1行目がヘッダー、2行目以降がデータです。操作の種類によって値が入る列が異なり、空の列も多くあります。


設定ファイル

実際の設定ファイル(.conf)を書いていきます。この設定ファイルは C:\Program Files\nxlog\conf\nxlog.d\ に配置します。nxlog.conf 本体の include %CONFDIR%\\*.conf で自動的に読み込まれます。

設定ファイルとサンプルCSVはGitHubにも置いてあります。
GitHub - nxlog-csv-to-json


# CSV → JSONL(ヘッダー無視)NXLog CE用
# ==============================================

define CSV_DIR C:\Users\arknode\csv
define JSON_DIR C:\Users\arknode\csv\output

define TARGET_HOST XXX.XXX.XXX.XXX  # ここにIPアドレスを入れる
define TARGET_PORT 516

<extension sample_csv>
Module xm_csv

# ------------------------------------------------
# CSV列対応表(日本語)
# ------------------------------------------------
# 01: イベント日時        -> $eventtime
# 02: コンピュータ名      -> $hostname
# 03: ユーザー名          -> $username
# 04: ドメイン名          -> $domain
# 05: 操作種別            -> $action
# 06: 操作詳細            -> $detail
# 07: フルパス            -> $filepath
# 08: ファイル名          -> $filename
# 09: 拡張子              -> $extension
# 10: ファイルサイズ      -> $filesize
# 11: ウィンドウタイトル  -> $window_title
# 12: 実行プロセス名      -> $process
# 13: プロセスID          -> $process_id
# 14: デバイス種別        -> $device_type
# 15: ベンダー名          -> $vendor
# 16: 製品名              -> $product
# 17: シリアル番号        -> $serial_no
# 18: 接続アクション      -> $connect_action
# 19: ドライブレター      -> $drive_letter
# 20: 許可状態            -> $permit_state
# 21: 送信元IPアドレス    -> $src_ipv4
# 22: 送信元ポート        -> $src_port
# 23: 送信先IPアドレス    -> $dst_ipv4
# 24: 送信先ポート        -> $dst_port
# 25: 通信プロトコル      -> $protocol
# 26: 送信データ量        -> $send_bytes
# 27: 受信データ量        -> $recv_bytes
# 28: URL/ドメイン        -> $url
# 29: HTTPメソッド        -> $http_method
# 30: ブラウザ名          -> $browser
# 31: ログイン時刻        -> $login_time
# 32: ログアウト時刻      -> $logout_time
# 33: セッション持続時間  -> $session_duration
# 34: 端末IPアドレス      -> $device_ipv4
# 35: MACアドレス         -> $mac_address
# 36: OSバージョン        -> $os_version
# 37: パッチ適用日        -> $patch_date
# 38: ドキュメント名      -> $document_name
# 39: プリンタ名          -> $printer_name
# 40: ページ数            -> $page_count
# 41: 複写枚数            -> $copy_count
# 42: カラー設定          -> $color_mode
# 43: 両面印刷設定        -> $duplex_mode
# 44: 送信者アドレス      -> $mail_from
# 45: 宛先アドレス        -> $mail_to
# 46: 件名               -> $mail_subject
# 47: 添付ファイル名      -> $attach_name
# 48: 添付ファイルサイズ  -> $attach_size

Fields $eventtime, \
       $hostname, \
       $username, \
       $domain, \
       $action, \
       $detail, \
       $filepath, \
       $filename, \
       $extension, \
       $filesize, \
       $window_title, \
       $process, \
       $process_id, \
       $device_type, \
       $vendor, \
       $product, \
       $serial_no, \
       $connect_action, \
       $drive_letter, \
       $permit_state, \
       $src_ipv4, \
       $src_port, \
       $dst_ipv4, \
       $dst_port, \
       $protocol, \
       $send_bytes, \
       $recv_bytes, \
       $url, \
       $http_method, \
       $browser, \
       $login_time, \
       $logout_time, \
       $session_duration, \
       $device_ipv4, \
       $mac_address, \
       $os_version, \
       $patch_date, \
       $document_name, \
       $printer_name, \
       $page_count, \
       $copy_count, \
       $color_mode, \
       $duplex_mode, \
       $mail_from, \
       $mail_to, \
       $mail_subject, \
       $attach_name, \
       $attach_size

AllowMoreFields TRUE
</extension>

<extension json_ext>
Module xm_json
</extension>

<input sample_csv_in>
Module im_file
File "%CSV_DIR%\*.csv"
# 追記分だけ読み込む。通常はこちらを使用
ReadFromLast TRUE

# デバッグ用。過去分も読み込む
#ReadFromLast FALSE
SavePos TRUE

<exec>
# 空行スキップ
if $raw_event == '' { drop(); }

# ヘッダー行スキップ
if $raw_event =~ /^イベント日時/ { drop(); }

sample_csv->parse_csv();

# 製品メタ
$class     = "endpoint_client";
$metaclass = "Windows";

# デフォルト severity
$severity = "info";

# 書き込み系(コピー・移動・書き込み・アップロード等)
if ($detail =~ /コピー|移動|書き込み|アップロード/) $severity = "warning";

# 失敗・拒否・ブロック・削除系
if ($detail =~ /失敗|拒否|ブロック|削除/) $severity = "error";

# デバイス接続拒否
if ($permit_state =~ /拒否/) $severity = "error";

$raw_event = to_json();
</exec>



# デバッグ用JSONLファイル出力(Routeに含めていないため実際には出力しない)
<output sample_json_out>
Module om_file
File "%JSON_DIR%\sample.jsonl"
<exec>
to_json();
</exec>
</output>

# ------------------------------------------------
# Output
# ------------------------------------------------
<output sample_out>
    Module om_tcp
    Host %TARGET_HOST%
    Port %TARGET_PORT%
    OutputType LineBased
    Exec to_json();
</output>

<route sample_route>
Path sample_csv_in => sample_json_out
</route>

設定ファイルの解説

設定ファイルは大きく5つのブロックで構成されています。順番に見ていきます。

変数定義(define)


define CSV_DIR C:\Users\node\csv
define JSON_DIR C:\Users\node\csv\output

define TARGET_HOST XXX.XXX.XXX.XXX  # ここにIPアドレスを入れる
define TARGET_PORT 516

define は設定ファイル内で繰り返し使う値に名前を付けるものです。プログラミングでいう「定数」に近いイメージです。

  • CSV_DIR … 変換元のCSVファイルが置かれているフォルダ
  • JSON_DIR … 変換後のJSONLファイルを出力するフォルダ
  • TARGET_HOST … 将来SIEMに送信する際の送信先IPアドレス
  • TARGET_PORT … 同じく送信先ポート番号

ここで定義した値は、以降 %CSV_DIR% のように % で囲んで参照します。環境が変わったときもこの部分だけ書き換えればOKです。

CSV拡張モジュール(Extension sample_csv)


<extension sample_csv>
Module xm_csv
</extension>

<Extension> はNXLogの機能を拡張するブロックです。xm_csv モジュールを読み込んで、CSV形式のデータを扱えるようにしています。sample_csv は自分で付けた名前で、後から呼び出すときに使います。

コメント部分の列対応表(# 01: イベント日時 -> $eventtime 等)は処理に影響しませんが、CSVの何列目がどの変数に対応しているかの備忘録です。

Fields が一番重要なポイントで、「CSVの各列に、どんな変数名を割り当てるか」を定義しています。

  • CSVの1列目 → $eventtime
  • 2列目 → $hostname
  • 3列目 → $username

というように、左から順番に対応します。この変数名がそのままJSONのキー名になります。たとえば $hostnamelogw-PC-ADMIN-01 という値が入っていれば、JSONでは "hostname": "logw-PC-ADMIN-01" と出力されます。

行末の \(バックスラッシュ)は「次の行に続く」という意味です。48列分を1行に書くと読みにくいので、複数行に分けています。

AllowMoreFields TRUE は、CSVの列数がFieldsの定義より多かった場合にエラーにせず無視する設定です。ログソフトのバージョンアップなどで列が増えた場合の保険です。

JSON拡張モジュール(Extension json_ext)


<extension json_ext>
Module xm_json
</extension>

xm_json モジュールを読み込みます。これにより to_json() という関数が使えるようになり、データをJSON形式に変換できます。

入力定義(Input)


<input sample_csv_in>
Module im_file
File "%CSV_DIR%\*.csv"
ReadFromLast TRUE
SavePos TRUE

各設定の意味は以下の通りです。

  • Module im_file … ファイルからデータを読み込むモジュール
  • File "%CSV_DIR%\*.csv"CSV_DIR フォルダ内のすべての .csv ファイルを対象にする
  • ReadFromLast TRUE … 前回読んだ位置から続きだけを読む(最初から全部読み直さない)
  • SavePos TRUE … 読み込み位置を保存する(NXLog再起動後も続きから読める)

つまりCSVファイルに新しい行が追記されると、NXLogが自動的にその行だけを拾って処理します。

<Exec> ブロックの中に、読み込んだデータに対する処理を順番に書いていきます。

まず if $raw_event == '' { drop(); }if $raw_event =~ /^イベント日時/ { drop(); } で空行とヘッダー行を読み飛ばします。drop() は「この行は捨てて次へ進む」という命令です。

次に sample_csv->parse_csv(); で、先ほど定義した sample_csv の設定を使ってCSVの行を分解します。この処理が実行されると、CSVの各列の値が $eventtime$hostname などの変数に格納されます。

$class$metaclass はすべてのログに共通で付けるメタ情報です。SIEM側でログの種別を判別するときに使えます。

severityの自動判定では、ログの操作内容に応じて重要度を3段階で振り分けます。

  • info … 上記に該当しない通常操作(閲覧、ログオン、参照、印刷など)
  • warning … データの持ち出しにつながりうる操作(ファイルのコピー、移動、書き込み、アップロード)
  • error … セキュリティ上の問題が疑われる操作(ファイル削除、操作失敗、アクセス拒否、未登録USBの接続拒否)

=~ は正規表現によるマッチングで、/コピー|移動|書き込み|アップロード/ は「この中のどれかが含まれていたら」という意味になります。

最後の $raw_event = to_json(); で、ここまでの変数すべてをJSON形式に変換して出力データとして確定します。値が空の変数はJSONに含まれないため、イベントの種類ごとに必要な項目だけが出力されます。

出力定義(Output / Route)


<output sample_json_out>
Module om_file
File "%JSON_DIR%\sample.jsonl"
</output>

変換結果をファイルに出力します。om_file はファイル出力用のモジュールです。


<output sample_out>
    Module om_tcp
    Host %TARGET_HOST%
    Port %TARGET_PORT%
    OutputType LineBased
    Exec to_json();
</output>

将来SIEMに送信するための設定です。om_tcp はTCP通信で別のサーバーにデータを送るモジュールで、OutputType LineBased は1行ずつ送信する設定です。現時点では使っていませんが、送信先が決まったらすぐ使えるように定義だけしてあります。


<route sample_route>
Path sample_csv_in => sample_json_out
</route>

<Route> は「どの入力を、どの出力に流すか」を決めるブロックです。現在は sample_csv_in(CSV読み込み)→ sample_json_out(ファイル出力)の経路だけが有効です。SIEM送信に切り替えたい場合は sample_csv_in => sample_out に変更するだけです。両方に同時に流すこともできます。


Path sample_csv_in => sample_json_out, sample_out

出力結果

設定ファイルを配置してNXLogを起動すると、CSVの各行がJSON形式に変換されて出力されます。

たとえばログインイベントの場合、値がある項目だけが出力されます。


{
  "EventReceivedTime": "2026-04-12 22:05:59",
  "SourceModuleName": "sample_csv_in",
  "SourceModuleType": "im_file",
  "eventtime": "2026-04-02 09:00:01",
  "hostname": "logw-PC-ADMIN-01",
  "username": "hirabayashi",
  "domain": "logw-domain",
  "action": "ログイン",
  "detail": "サインイン",
  "process": "explorer.exe",
  "process_id": "1200",
  "src_ipv4": "192.168.1.10",
  "login_time": "2026-04-02 09:00:01",
  "device_ipv4": "192.168.1.10",
  "mac_address": "00-11-22-33-44-55",
  "os_version": "Windows 11",
  "patch_date": "2026-03-25",
  "class": "endpoint_client",
  "metaclass": "Windows",
  "severity": "info"
}

メール送信のように多くの項目に値があるイベントでは、それに応じたフィールドが出力されます。


{
  "EventReceivedTime": "2026-04-12 22:05:59",
  "SourceModuleName": "sample_csv_in",
  "SourceModuleType": "im_file",
  "eventtime": "2026-04-02 11:00:22",
  "hostname": "logw-PC-ADMIN-01",
  "username": "hirabayashi",
  "domain": "logw-domain",
  "action": "メール送信",
  "detail": "SMTP",
  "src_ipv4": "192.168.1.10",
  "src_port": "587",
  "dst_ipv4": "203.0.113.10",
  "dst_port": "587",
  "protocol": "SMTP",
  "send_bytes": "15000",
  "recv_bytes": "800",
  "device_ipv4": "192.168.1.10",
  "mac_address": "00-11-22-33-44-55",
  "os_version": "Windows 11",
  "patch_date": "2026-03-25",
  "mail_from": "hirabayashi@logw-sample.co.jp",
  "mail_to": "partner@example.com",
  "mail_subject": "打ち合わせの件",
  "attach_name": "agenda.pptx",
  "attach_size": "8500",
  "class": "endpoint_client",
  "metaclass": "Windows",
  "severity": "info"
}

48列のCSVでも、値がない列はJSONに出力されないため、スッキリした構造になっています。


動画は以下になります

まとめ

NXLog CEを使うことで、CSVの操作ログをJSON形式に変換できることを確認しました。設定ファイルでやっていることをまとめると以下の通りです。

  • CSVの各列に意味のある英語名を割り当てる
  • 操作内容に応じて重要度(severity)を自動判定する
  • 値がある項目だけをJSONとして出力する
  • 将来的にSIEMへ転送する場合はRouteの出力先を変えるだけで対応できる

CSV出力しかできないソフトウェアのログをSIEMに取り込みたい場合、NXLogは有力な選択肢になると思います。

この記事に関する技術サポート・ご相談

「手順通りにいかない」「自社環境への構築を代行してほしい」など、
インフラ・サーバー周りでハマった際はお気軽にご相談ください。

相談・問い合わせフォームを開く

※ Googleフォームへ移動します(初回相談無料)

個人支援・寄付について

サイトラボでは個人支援・寄付を受けております。ご協力いただける方はお願いいたします。当サイトではビットコインで受け付けております。

  • ビットコイン:3LHnADwZwUbic2L45EnVJEykiG6KfbqrwS