[.net] log4net을 처음부터 프로그래밍 방식으로 구성하는 방법 (구성 없음)

이것은 나쁜 생각이지만, 구성 파일없이 처음부터 log4net을 프로그래밍 방식으로 구성하고 싶습니다. 저는 저와 제 팀이 우리가 담당하는 비교적 작은 부서별 애플리케이션에 사용할 간단한 로깅 애플리케이션을 개발 중입니다. 모두 동일한 데이터베이스에 기록하기를 원합니다. 로깅 애플리케이션은 AdoNetAppender가 미리 구성된 log4net을 둘러싼 래퍼 일뿐입니다.

모든 응용 프로그램이 ClickOnce 배포되어 구성 파일 배포에 약간의 문제가 있습니다. 구성 파일이 핵심 프로젝트의 일부인 경우 어셈블리와 함께 배포 할 속성을 설정할 수 있습니다. 하지만 링크 된 애플리케이션의 일부이므로 기본 애플리케이션과 함께 배포 할 수있는 옵션이 없습니다. (그게 사실이 아니라면 누군가 알려주세요).

아마도 그것은 나쁜 생각이기 때문에 프로그래밍 방식으로 log4net을 처음부터 구성하는 데 사용할 수있는 샘플 코드가 많지 않은 것 같습니다. 여기 내가 지금까지 가지고있는 것입니다.

Dim apndr As New AdoNetAppender()
apndr.CommandText = "INSERT INTO LOG_ENTRY (LOG_DTM, LOG_LEVEL, LOGGER, MESSAGE, PROGRAM, USER_ID, MACHINE, EXCEPTION) VALUES (@log_date, @log_level, @logger, @message, @program, @user, @machine, @exception)"
apndr.ConnectionString = connectionString
apndr.ConnectionType = "System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
apndr.CommandType = CommandType.Text
Dim logDate As New AdoNetAppenderParameter()
logDate.ParameterName = "@log_date"
logDate.DbType = DbType.DateTime
logDate.Layout = New RawTimeStampLayout()
apndr.AddParameter(logDate)
Dim logLevel As New AdoNetAppenderParameter()
logLevel.ParameterName = "@log_level"
'And so forth...

에 대한 모든 매개 변수를 구성한 후 apndr처음에는 이것을 시도했습니다.

Dim hier As Hierarchy = DirectCast(LogManager.GetRepository(), Hierarchy)
hier.Root.AddAppender(apndr)

작동하지 않았습니다. 그런 다음 어둠 속에서 샷으로 대신 이것을 시도했습니다.

BasicConfigurator.Configure(apndr)

그것도 작동하지 않았습니다. 누구든지 구성 파일없이 처음부터 프로그래밍 방식으로 log4net을 구성하는 방법에 대한 좋은 참조가 있습니까?



답변

이전에이 작업을 수행 한 한 가지 방법은 구성 파일을 포함 된 리소스로 포함하고 방금 log4net.Config.Configure (Stream)을 사용하는 것 입니다.

이렇게하면 익숙한 구성 구문을 사용할 수 있고 파일 배포에 대해 걱정할 필요가 없습니다.


답변

다음은 코드에서 완전히 log4net 구성을 생성하는 예제 클래스입니다. 정적 메서드를 통해 로거를 만드는 것은 일반적으로 나쁜 것으로 간주되지만 내 맥락에서는 이것이 내가 원했던 것입니다. 어쨌든 필요에 맞게 코드를 조각 할 수 있습니다.

using log4net;
using log4net.Repository.Hierarchy;
using log4net.Core;
using log4net.Appender;
using log4net.Layout;

namespace dnservices.logging
{
public class Logger
{
    private PatternLayout _layout = new PatternLayout();
    private const string LOG_PATTERN = "%d [%t] %-5p %m%n";

    public string DefaultPattern
    {
        get { return LOG_PATTERN; }
    }

    public Logger()
    {
        _layout.ConversionPattern = DefaultPattern;
        _layout.ActivateOptions();
    }

    public PatternLayout DefaultLayout
    {
        get { return _layout; }
    }

    public void AddAppender(IAppender appender)
    {
        Hierarchy hierarchy =
            (Hierarchy)LogManager.GetRepository();

        hierarchy.Root.AddAppender(appender);
    }

    static Logger()
    {
        Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();
        TraceAppender tracer = new TraceAppender();
        PatternLayout patternLayout = new PatternLayout();

        patternLayout.ConversionPattern = LOG_PATTERN;
        patternLayout.ActivateOptions();

        tracer.Layout = patternLayout;
        tracer.ActivateOptions();
        hierarchy.Root.AddAppender(tracer);

        RollingFileAppender roller = new RollingFileAppender();
        roller.Layout = patternLayout;
        roller.AppendToFile = true;
        roller.RollingStyle = RollingFileAppender.RollingMode.Size;
        roller.MaxSizeRollBackups = 4;
        roller.MaximumFileSize = "100KB";
        roller.StaticLogFileName = true;
        roller.File = "dnservices.txt";
        roller.ActivateOptions();
        hierarchy.Root.AddAppender(roller);

        hierarchy.Root.Level = Level.All;
        hierarchy.Configured = true;
    }

    public static ILog Create()
    {
        return LogManager.GetLogger("dnservices");
    }
}

}


답변

더 간결한 솔루션 :

var layout = new PatternLayout("%-4timestamp [%thread] %-5level %logger %ndc - %message%newline");
var appender = new RollingFileAppender {
    File = "my.log",
    Layout = layout
};
layout.ActivateOptions();
appender.ActivateOptions();
BasicConfigurator.Configure(appender);

ActivateOptions 메서드 를 호출하는 것을 잊지 마십시오 .

구성 속성을 설정 한 후이 개체에서 ActivateOptions 메서드를 호출해야합니다. ActivateOptions가 호출 될 때까지이 개체는 정의되지 않은 상태에 있으며 사용해서는 안됩니다.


답변

조나단은 말한다, 자원을 사용하는 것은 좋은 솔루션입니다.

포함 된 리소스 내용이 컴파일 타임에 고정된다는 점에서 약간 제한적입니다. appSettings로 정의 된 변수를 사용하여 기본 Log4Net 구성으로 XmlDocument를 생성하는 로깅 구성 요소가 있습니다 (예 : RollingFileAppender의 파일 이름, 기본 로깅 수준, AdoNetAppender를 사용하려는 경우 연결 문자열 이름). 그런 다음 log4net.Config.XmlConfigurator.Configure생성 된 XmlDocument의 루트 요소를 사용하여 Log4Net을 구성하도록 호출 합니다.

그런 다음 관리자는 몇 가지 appSettings (일반적으로 수준, 파일 이름 등)를 수정하여 “표준”구성을 사용자 지정하거나 더 많은 제어를 위해 외부 구성 파일을 지정할 수 있습니다.


답변

Todd Stout의 대답에 표시된 매우 중요한 apndr.ActivateOptions ()가 ” ‘등등 …”에 포함되어 있는지 질문의 코드 조각에서 말할 수 없습니다. ActivateOptions ()없이 Appender는 비활성 상태이며 실패 이유를 설명 할 수있는 작업을 수행하지 않습니다.


답변

파티에 좀 늦었어요. 그러나 여기 저에게 일한 최소한의 구성이 있습니다.

샘플 클래스

public class Bar
{
    private readonly ILog log = LogManager.GetLogger(typeof(Bar));
    public void DoBar() { log.Info("Logged"); }
}

최소 log4net 추적 구성 (NUnit 테스트 내부)

[Test]
public void Foo()
{
    var tracer = new TraceAppender();
    var hierarchy = (Hierarchy)LogManager.GetRepository();
    hierarchy.Root.AddAppender(tracer);
    var patternLayout = new PatternLayout {ConversionPattern = "%m%n"};
    tracer.Layout = patternLayout;
    hierarchy.Configured = true;

    var bar = new Bar();
    bar.DoBar();
}

추적 수신기에 인쇄합니다.

Namespace+Bar: Logged


답변

Netjes 박사 는 다음과 같이 연결 문자열 을 프로그래밍 방식으로 설정합니다.

// Get the Hierarchy object that organizes the loggers
log4net.Repository.Hierarchy.Hierarchy hier =
  log4net.LogManager.GetLoggerRepository() as log4net.Repository.Hierarchy.Hierarchy;

if (hier != null)
{
  //get ADONetAppender
  log4net.Appender.ADONetAppender adoAppender =
    (log4net.Appender.ADONetAppender)hier.GetLogger("MyProject",
      hier.LoggerFactory).GetAppender("ADONetAppender");
  if (adoAppender != null)
  {
    adoAppender.ConnectionString =
      System.Configuration.ConfigurationSettings.AppSettings["MyConnectionString"];
    adoAppender.ActivateOptions(); //refresh settings of appender
  }
}