로그가 데이터베이스에 기록됩니다

  • 파일 로그: 서버에 로그인한 뒤 텍스트 파일을 다운로드하거나 열어서 확인해야 하며 검색이 불편합니다;
  • 데이터베이스 로그: 백엔드에 로그 관리 페이지를 직접 구현할 수 있으며 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

-- ========== 필드 주석(선택, 데이터베이스 확인 편의용) ==========
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사용하는 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이름·계정·비밀번호를 본인 환경에 맞춰 수정 -->
      <connectionString value="DATABASE=log4netdemo;SERVER=.;UID=sa;PWD=pwdpwd;Connect Timeout=15;" />

      <!-- INSERT SQL, 컬럼과 파라미터 순서를 일치시켜야 합니다 -->
      <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:Logger 이름 -->
      <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>

    <!-- 루트 로거, DB 출력 활성화 -->
    <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 웹 프로젝트(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)

로그가 데이터베이스에 기록됩니다

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다