본문 바로가기
WIKI 기술 지식 베이스

C# 로그 수집

원문 보기 위키 갱신

C# 로그를 Datadog로 보내려면 다음 방법 중 하나를 사용하세요:

  • 파일에 로그를 기록한 다음 Datadog Agent로 그 파일을 tail.
  • Agentless 로깅 활성화.
  • Serilog 싱크 사용.

출처: 문서

본문

Datadog Agent를 사용한 파일-tail 로깅

C# 로그 수집의 권장 방법은 로그를 파일로 출력한 다음 Datadog Agent로 그 파일을 tail하는 거예요. 이렇게 하면 Datadog Agent가 추가 메타데이터로 로그를 강화할 수 있어요.

Datadog는 사용자 정의 파싱 규칙이 필요 없도록 로깅 라이브러리가 JSON 형식으로 로그를 생성하게 설정하는 것을 강력히 권장해요.

파일-tail 로깅은 다음 프레임워크를 지원해요:

  • Serilog
  • NLog
  • log4net

로거 구성하기

{% tab title="Serilog" %} .NET용 다른 많은 라이브러리처럼 Serilog도 파일, 콘솔, 그 외 곳으로 진단 로깅을 제공해요. 깔끔한 API를 가지며 최근 .NET 플랫폼 간에 이식 가능해요.

다른 로깅 라이브러리와 달리 Serilog는 강력한 구조화된 이벤트 데이터를 염두에 두고 만들어졌어요.

NuGet으로 Serilog를 설치하려면 Package Manager Console에서 다음 명령을 실행하세요:

PM> Install-Package Serilog.Sinks.File

그런 다음 다음 코드를 추가해 애플리케이션에서 직접 로거를 초기화하세요:

// Instantiate the logger
var log = new LoggerConfiguration()  // using Serilog;

    // using Serilog.Formatting.Json;
    .WriteTo.File(new JsonFormatter(renderMessage: true), "log.json")

    // using Serilog.Formatting.Compact;
    // .WriteTo.File(new RenderedCompactJsonFormatter(), "log.json")

    .CreateLogger();

// An example
var position = new { Latitude = 25, Longitude = 134 };
var elapsedMs = 34;

log.Information("Processed {@Position} in {Elapsed:000} ms.", position, elapsedMs);

log.json 파일에서 로거가 성공적으로 인스턴스화됐는지 확인하세요:

  • JsonFormatter(renderMessage: true)를 사용한다면 다음 이벤트를 찾아 확인하세요:
{
  "MessageTemplate": "Processed {@Position} in {Elapsed:000} ms.",
  "Level": "Information",
  "Timestamp": "2016-09-02T15:02:29.648Z",
  "Renderings": {"Elapsed": [{"Format": "000", "Rendering": "034"}]},
  "RenderedMessage":"Processed { Latitude: 25, Longitude: 134 } in 034 ms.",
  "Properties": {"Position": {"Latitude": 25, "Longitude": 134}, "Elapsed": 34}
}
  • RenderedCompactJsonFormatter()를 사용한다면 다음 이벤트를 찾아 확인하세요:
{
  "@t": "2020-05-20T04:15:28.6898801Z",
  "@m": "Processed { Latitude: 25, Longitude: 134 } in 034 ms.",
  "@i": "d1eb2146",
  "Position": {"Latitude": 25, "Longitude": 134 },
  "Elapsed": 34
}

{% /tab %}

{% tab title="NLog" %} NLog는 풍부한 로그 라우팅·관리 기능을 갖춘 .NET용 로깅 플랫폼이에요. 애플리케이션의 규모나 복잡성과 무관하게 고품질의 로그를 생성·관리하는 데 도움이 돼요.

NuGet으로 NLog를 설치하려면 Package Manager Console에서 다음 명령을 실행하세요:

PM> Install-Package NLog

라이브러리가 클래스패스에 있으면 어떤 타깃에도 다음 레이아웃을 붙이세요. 프로젝트 루트 경로에 NLog.config 파일을 편집하거나 추가하세요. 그런 다음 그 파일에 다음 코드를 복사/붙여넣으세요(로그는 application-logs.json 파일에 기록됩니다):

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <!--
  See https://github.com/nlog/nlog/wiki/Configuration-file
  for information on customizing logging rules and outputs.
   -->
  <targets async="true">
    <!-- Write logs as Json into a file -->
    <target name="json-file" xsi:type="File" fileName="application-logs.json">
      <layout xsi:type="JsonLayout">
        <attribute name="date" layout="${date:universalTime=true:format=o}" />
        <attribute name="level" layout="${level:upperCase=true}"/>
        <attribute name="message" layout="${message}" />
        <attribute name="exception" layout="${exception:format=ToString}" />
      </layout>
    </target>

  </targets>
  <rules>
    <!-- Log all events to the json-file target -->
    <logger name="*" writeTo="json-file" minlevel="Trace" />
  </rules>
</nlog>

첫 이벤트를 발생·기록하려면 코드에 다음을 추가하세요:

using NLog;

namespace Datadog
{
    class Program
    {
        // Initialize a logger
        private static Logger logger = LogManager.GetCurrentClassLogger();

        static void Main(string[] args)
        {
            // Log a simple debug message
            logger.Debug("This is my first step");

            // your code continues here ...
        }
    }
}

{% /tab %}

{% tab title="Log4Net" %} Log4Net은 Log4j에서 영감을 받은, 풍부한 로그 라우팅·관리 기능을 갖춘 .NET 로깅 플랫폼이에요. 애플리케이션의 규모나 복잡성과 무관하게 고품질의 로그를 생성·관리하는 데 도움이 돼요.

Log4Net을 설치하려면 Package Manager Console에서 다음 명령을 실행하세요:

PM> Install-Package log4net
PM> Install-Package log4net.Ext.Json

라이브러리가 설치되면 어떤 타깃에도 다음 레이아웃을 붙이세요. 프로젝트의 App.config를 편집하고 다음 섹션을 추가하세요:

<?xml version="1.0" encoding="utf-8"?>
<configuration>

  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>

  <log4net>
    <root>
      <level value="DEBUG" />
      <appender-ref ref="JsonFileAppender" />
    </root>
    <appender name="JsonFileAppender" type="log4net.Appender.FileAppender">
      <threshold value="DEBUG"/>
      <file value="application-logs.json" />
      <encoding type="System.Text.UTF8Encoding" />
      <appendToFile value="true" />
      <layout type="log4net.Layout.SerializedLayout, log4net.Ext.Json">
        <decorator type="log4net.Layout.Decorators.StandardTypesDecorator, log4net.Ext.Json" />
        <default />
        <!--explicit default members-->
        <remove value="ndc" />
        <remove value="message" />
        <!--remove the default preformatted message member-->
        <member value="message:messageobject" />
        <!--add raw message-->
      </layout>
    </appender>
  </log4net>

  <!-- The rest of your configuration starts here ... -->

로거를 인스턴스화하고 이벤트를 발생시키기 시작하세요:

using log4net;

namespace Datadog
{
    class Program
    {
        // Get the current class logger
        private static ILog logger = LogManager.GetLogger(typeof(Program));

        static void Main(string[] args)
        {

           // Load the configure fom App.config
           XmlConfigurator.Configure();

           // Log a simple debug message
           logger.Debug("This is my first debug message");

           // your code continues here ...
        }
    }
}

지침을 따랐다면 파일(예: C:\Projects\Datadog\Logs\log.json)에서 다음 이벤트를 볼 수 있어요:

{
  "level": "DEBUG",
  "message": "This is my debug message",
  "date": "2016-05-24 15:53:35.7175",
  "appname": "Datadog.vshost.exe",
  "logger": "Datadog.Program",
  "thread": "10"
}

JSON으로 로깅하는 장점에도 불구하고 원시 문자열 형식으로 로깅하고 싶다면, C# 통합 파이프라인으로 로그를 자동 파싱하도록 log4net conversion pattern을 다음과 같이 업데이트해 보세요:

<param name="ConversionPattern" value="%date{yyyy-MM-dd HH:mm:ss.SSS} %level [%thread] %logger %method:%line - %message%n" />

{% /tab %}

Datadog Agent 구성하기

log collection이 활성화되면 custom log collection을 설정해 로그 파일을 tail하고 Datadog로 보내세요.

  1. conf.d/ Agent 구성 디렉터리에 csharp.d/ 폴더를 만드세요.

  2. csharp.d/에 다음 내용으로 conf.yaml 파일을 만드세요:

    init_config:
    
    instances:
    
    ##Log section
    logs:
    
      - type: file
        path: "<path_to_your_csharp_log>.log"
        service: <service_name>
        source: csharp
        sourcecategory: sourcecode
        # For multiline logs, if they start by the date with the format yyyy-mm-dd uncomment the following processing rule
        #log_processing_rules:
        #  - type: multi_line
        #    name: new_log_start_with_date
        #    pattern: \d{4}\-(0?[1-9]|1[012])\-(0?[1-9]|[12][0-9]|3[01])
    
  3. Agent 사용자가 로그 파일에 대한 읽기 권한이 있는지 확인하세요.

  4. Agent를 재시작하세요.

  5. Agent의 status 하위 명령을 실행하고 Checks 섹션에서 csharp를 찾아 로그가 Datadog로 성공적으로 제출됐는지 확인하세요.

로그가 JSON 형식이라면 Datadog는 로그 속성을 추출하기 위해 로그 메시지를 자동으로 파싱해요. Log Explorer를 사용해 로그를 보고 문제를 해결하세요.

로그와 트레이스에 걸쳐 서비스 연결하기

이 애플리케이션에서 APM이 활성화되어 있다면 APM .NET 지침을 따라 로그에 트레이스 ID, 스팬 ID, env, service, version을 자동으로 추가해 로그와 트레이스를 연결하세요.

참고: Datadog SDK가 로그에 service를 주입하면 Agent 구성에 설정된 값을 재정의해요.

APM을 사용한 Agentless 로깅

코드를 전혀 수정하지 않고 .NET APM 자동 계측 라이브러리를 사용해 애플리케이션에서 Datadog로 직접 로그를 스트리밍할 수 있어요. 이 방식은 로그를 Datadog로 직접 보내므로 Datadog Agent가 제공하는 민감 데이터 스크러빙 같은 기능의 혜택을 받지 못해요. 따라서 가능하면 파일-tail 로깅을 사용할 것을 권장하지만, (예: Azure App Service를 사용할 때) 파일-tail이 불가능한 환경에서는 유용해요. 또한 Sensitive Data Scanner가 수행하는 서버 측 스크러빙 기능에는 여전히 의존할 수 있음을 기억하세요.

Agentless 로깅("직접 로그 제출"이라고도 함)은 다음 프레임워크를 지원해요:

  • Serilog (v1.0+)
  • NLog (v2.1+)
  • log4net (v1.0+)
  • Microsoft.Extensions.Logging (2.0+)

애플리케이션 코드를 수정하거나 애플리케이션에 추가 의존성을 설치할 필요가 없어요.

{% alert level="danger" %} 참고: log4net 또는 NLog를 사용한다면 Agentless 로깅을 활성화하려면 appender(log4net) 또는 logger(NLog)를 구성해야 해요. 그런 경우 추가 의존성을 추가하거나 Serilog 싱크를 사용한 agentless 로깅을 대신 사용할 수 있어요. {% /alert %}

Datadog SDK 구성하기

Agentless 로깅은 APM을 자동 계측과 함께 사용할 때만 사용할 수 있어요. 시작하려면 다음 문서에 설명된 대로 애플리케이션을 계측하세요:

설치 후에는 트레이스를 올바르게 수신하는지 확인하세요.

Agentless 로깅 활성화

Agentless 로깅을 활성화하려면 다음 환경 변수를 설정하세요:

{% dl %}

{% dt %} DD_API_KEY {% /dt %}

{% dd %} 로그를 Datadog로 보내기 위한 Datadog API 키. {% /dd %}

{% dt %} DD_SITE {% /dt %}

{% dd %} Datadog 사이트의 이름. 다음 예시 중 하나를 선택하세요: 예시: datadoghq.com (US1), datadoghq.eu (EU), us3.datadoghq.com (US3), us5.datadoghq.com (US5), ap1.datadoghq.com (AP1), ap2.datadoghq.com (AP2), ddog-gov.com (US1-FED), us2.ddog-gov.com (US2-FED) 기본값: datadoghq.com (US1) {% /dd %}

{% dt %} DD_LOGS_INJECTION {% /dt %}

{% dd %} 로그와 트레이스 연결을 활성화해요: 기본값: true — Tracer 버전 3.24.0부터 기본 활성화. {% /dd %}

{% dt %} DD_LOGS_DIRECT_SUBMISSION_INTEGRATIONS {% /dt %}

{% dd %} Agentless 로깅을 활성화해요. Serilog, NLog, Log4Net, ILogger(Microsoft.Extensions.Logging용)로 설정해 로깅 프레임워크를 활성화하세요. 여러 로깅 프레임워크를 사용한다면 세미콜론으로 구분된 변수 목록을 사용하세요. 예시: Serilog;Log4Net;NLog {% /dd %}

{% /dl %}

{% alert level="danger" %} 참고: 로깅 프레임워크를 Microsoft.Extensions.Logging과 함께 사용한다면 일반적으로 프레임워크 이름을 사용해야 해요. 예를 들어 Serilog.Extensions.Logging을 사용한다면 DD_LOGS_DIRECT_SUBMISSION_INTEGRATIONS=Serilog로 설정해야 해요. {% /alert %}

이 환경 변수를 설정한 후 애플리케이션을 재시작하세요.

추가 구성

다음 환경 변수로 Agentless 로그 수집의 일부 측면을 추가로 사용자 정의할 수 있어요:

{% dl %}

{% dt %} DD_LOGS_DIRECT_SUBMISSION_MINIMUM_LEVEL {% /dt %}

{% dd %} 로그가 Datadog로 보내지기 전에 로그를 레벨별로 필터링할 수 있게 해요. 다음 값 중 하나로 설정하세요: Verbose, Debug, Information, Warning, Error, Critical. 이 값은 지원되는 로깅 프레임워크의 동등한 레벨에 대응해요. 기본값: Information {% /dd %}

{% dt %} DD_LOGS_DIRECT_SUBMISSION_HOST {% /dt %}

{% dd %} 로그와 연결된 호스트 머신의 이름을 설정해요. 제공되지 않으면 호스트 이름을 자동으로 찾으려고 시도해요. 기본값: 자동 결정 {% /dd %}

{% dt %} DD_LOGS_DIRECT_SUBMISSION_TAGS {% /dt %}

{% dd %} 지정하면 지정된 모든 태그를 생성된 모든 스팬에 추가해요. 제공되지 않으면 DD_TAGS를 대신 사용해요. 예시: layer:api, team:intake 구분자는 쉼표와 공백(,)이에요. {% /dd %}

{% /dl %}

다음 구성 값은 일반적으로 수정해서는 안 되지만 필요하면 설정할 수 있어요.

{% dl %}

{% dt %} DD_LOGS_DIRECT_SUBMISSION_URL {% /dt %}

{% dd %} 로그를 제출할 URL을 설정해요. 기본적으로 DD_SITE에 제공된 도메인을 사용해요. 기본값: :443 (DD_SITE 기준) {% /dd %}

{% dt %} DD_LOGS_DIRECT_SUBMISSION_SOURCE {% /dt %}

{% dd %} 제출되는 로그의 파싱 규칙을 설정해요. 사용자 정의 파이프라인이 없다면 항상 csharp로 설정해야 해요. 기본값: csharp {% /dd %}

{% dt %} DD_LOGS_DIRECT_SUBMISSION_MAX_BATCH_SIZE {% /dt %}

{% dd %} 한 번에 보낼 최대 로그 수를 설정해요. API에 적용되는 한도를 고려해요. 기본값: 1000 {% /dd %}

{% dt %} DD_LOGS_DIRECT_SUBMISSION_MAX_QUEUE_SIZE {% /dt %}

{% dd %} 로그 메시지를 삭제하기 전에 내부 큐에 보관할 최대 로그 수를 설정해요. 기본값: 100000 {% /dd %}

{% dt %} DD_LOGS_DIRECT_SUBMISSION_BATCH_PERIOD_SECONDS {% /dt %}

{% dd %} 보낼 새 로그가 있는지 확인하기 전에 대기하는 시간(초)을 설정해요. 기본값: 1 {% /dd %}

{% /dl %}

Microsoft.Extensions.Logging 통합을 사용한다면 ILogger에 내장된 표준 기능을 사용해 Datadog로 보내는 로그를 필터링할 수 있어요. "Datadog" 키를 사용해 직접 제출 프로바이더를 식별하고 각 네임스페이스의 최소 로그 레벨을 설정하세요. 예를 들어 appSettings.json에 다음을 추가하면 Warning 아래 레벨의 로그를 Datadog로 보내지 않게 할 수 있어요. .NET SDK v2.20.0에서 도입됨.

{
  "Logging": {
    "Datadog": {
      "LogLevel": {
        "Microsoft.AspNetCore": "Warning"
      },
    }
  }
}

Serilog 싱크를 사용한 Agentless 로깅

{% alert level="info" %} 0.2.0부터 Serilog.Setting.Configuration 패키지로 appsettings.json 파일을 사용해 Datadog 싱크를 구성할 수 있어요. 자세한 내용은 Serilog.Sinks.Datadog.Logs 패키지를 참고하세요. {% /alert %}

파일-tail 로깅이나 APM Agentless 로깅을 사용할 수 없고 Serilog 프레임워크를 사용한다면 Datadog Serilog 싱크를 사용해 로그를 Datadog로 직접 보낼 수 있어요.

Datadog Serilog 싱크를 애플리케이션에 설치하면 이벤트와 로그를 Datadog로 보내요. 기본적으로 싱크는 HTTPS로 포트 443을 통해 로그를 전달해요. Package Manager Console에서 다음 명령을 실행하세요:

PM> Install-Package Serilog.Sinks.Datadog.Logs

그런 다음 애플리케이션에서 직접 로거를 초기화하세요. <API_KEY>를 추가했는지 확인하세요.

using (var log = new LoggerConfiguration()
    .WriteTo.DatadogLogs("<API_KEY>", configuration: new DatadogConfiguration(){ Url = "<YOUR_HTTP_ENDPOINT_URL>" })
    .CreateLogger())
{
    // Some code
}

이제 새 로그가 Datadog로 직접 보내져요.

더 알아보기 (Learn more)