ログがデータベースへ書き込まれます

  • ファイルログ:サーバーにログインしテキストファイルをダウンロード・閲覧する必要があり、検索が手間;
  • データベースログ:管理画面を実装すればSQLによる条件検索、フィルタリング、ページングに対応可能;
  1. 一括保守、ログ監査、例外トラブルシューティングに適します。

デメリット:大量ログ出力時はデータベース負荷が上昇します。本番環境ではバッファ書き込み、テーブル分割、古いログの定期削除で調整してください。

1 ログテーブル作成(SQL Server)

-- ログテーブル Log
create table Log (
    Id bigint identity,
    AddTime datetime not null,
    Thread nvarchar(100) not null,
    Level nvarchar(200) not null,
    Logger nvarchar(500) not null,
    Message nvarchar(3000) not null,
    Exception nvarchar(4000) null,
    constraint PK_LOG primary key (Id)
)
go

-- ========== フィールドコメント(任意、DB閲覧用) ==========
declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description',
'Log4netログテーブル',
'user', @CurrentUser, 'table', 'Log'
go

declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description',
'ログの主キー',
'user', @CurrentUser, 'table', 'Log', 'column', 'Id'
go

declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description',
'記録日時',
'user', @CurrentUser, 'table', 'Log', 'column', 'AddTime'
go

declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description',
'実行元スレッド',
'user', @CurrentUser, 'table', 'Log', 'column', 'Thread'
go

declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description',
'ログレベル(Info/Debug/Errorなど)',
'user', @CurrentUser, 'table', 'Log', 'column', 'Level'
go

declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description',
'ロガー名',
'user', @CurrentUser, 'table', 'Log', 'column', 'Logger'
go

declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description',
'ログメッセージ本文',
'user', @CurrentUser, 'table', 'Log', 'column', 'Message'
go

declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description',
'例外スタック情報',
'user', @CurrentUser, 'table', 'Log', 'column', 'Exception'
goCode language: PHP (php)

フィールド解説:

フィールド説明
Id自動インクリメント主キー
AddTimeログ出力日時
Threadログを出力したスレッド名
Levelログレベル:DEBUG/INFO/WARN/ERROR/FATAL
Loggerロガー名(クラス完全名)
Message通常ログテキスト
Exception例外スタック、例外なし時は空

2 NuGetパッケージインストール

Install-Package log4net

.NET Framework はそのまま利用可能。.NET Core/.NET5+/ASP.NET Core でも互換性があります。

3 log4net完全設定(App.config / Web.config)

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- log4net設定ノードを登録 -->
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>

  <log4net>
    <!-- ADONetAppender:データベース書き込み用アペンダー -->
    <appender name="ADONetAppender" type="log4net.Appender.ADONetAppender">
      <!-- bufferSize=1:バッファなし即時書き込み。数値を大きくすると一括書き込みでDB負荷を抑えられる -->
      <bufferSize value="1" />

      <!-- SqlServer接続ドライバ -->
      <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

      <!-- DB接続文字列。DB名・アカウント・パスワードを環境に合わせて変更 -->
      <connectionString value="DATABASE=log4netdemo;SERVER=.;UID=sa;PWD=pwdpwd;Connect Timeout=15;" />

      <!-- INSERT文。テーブルのカラムとパラメータを一致させる必要がある -->
      <commandText value="INSERT INTO Log ([AddTime],[Thread],[Level],[Logger],[Message],[Exception])
VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" />

      <!-- パラメータ1:ログ出力時刻 -->
      <parameter>
        <parameterName value="@log_date" />
        <dbType value="DateTime" />
        <layout type="log4net.Layout.RawTimeStampLayout" />
      </parameter>

      <!-- パラメータ2:スレッド名 -->
      <parameter>
        <parameterName value="@thread" />
        <dbType value="String" />
        <size value="100" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%t" />
        </layout>
      </parameter>

      <!-- パラメータ3:ログレベル -->
      <parameter>
        <parameterName value="@log_level" />
        <dbType value="String" />
        <size value="200" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%p" />
        </layout>
      </parameter>

      <!-- パラメータ4:ロガー名 -->
      <parameter>
        <parameterName value="@logger" />
        <dbType value="String" />
        <size value="500" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%c" />
        </layout>
      </parameter>

      <!-- パラメータ5:ログメッセージ -->
      <parameter>
        <parameterName value="@message" />
        <dbType value="String" />
        <size value="3000" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%m" />
        </layout>
      </parameter>

      <!-- パラメータ6:例外情報 -->
      <parameter>
        <parameterName value="@exception" />
        <dbType value="String" />
        <size value="4000" />
        <layout type="log4net.Layout.ExceptionLayout" />
      </parameter>
    </appender>

    <!-- ルートロガー、データベース出力を有効化 -->
    <root>
      <level value="Info" />
      <appender-ref ref="ADONetAppender" />
      <!-- ファイルログと併用する場合:<appender-ref ref="ファイル用アペンダー名"/> -->
    </root>
  </log4net>
</configuration>Code language: HTML, XML (xml)

重要補足:スクリーンショットにパラメータが2つだけ表示されている場合があります。起動エラー回避のため6つ全てのパラメータを記述してください!

4 コード上でlog4netを有効化

1. .NET Framework Webプロジェクト(Global.asax)
protected void Application_Start(object sender, EventArgs e)
{
    // log4net設定読み込み
    log4net.Config.XmlConfigurator.Configure();
}Code language: JavaScript (javascript)
2. コンソール / WinFormsアプリ

Program.cs のMainメソッドの最初に記述:

log4net.Config.XmlConfigurator.Configure();Code language: CSS (css)
3. 実際の利用コード
// ロガーインスタンス取得
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

// 通常ログ出力
log.Info("システム起動完了");

// 例外ログ出力
try
{
    int a = 1 / 0;
}
catch (Exception ex)
{
    log.Error("計算処理で例外発生", ex);
}Code language: PHP (php)

ログがデータベースへ書き込まれます

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です