콘텐츠로 이동

2024 12 05

2024-12-05

Sentry with logback

참고: https://leeeeeyeon-dev.tistory.com/43 참고: https://escapefromcoding.tistory.com/694

  • Why Sentry?
    • 슬랙같은걸로 에러로그 던져주긴 하는데, 그냥 메신저로 받다보니 로그 관리는 어려움
    • 에러 트래킹 및 성능 모니터링 도구로 유명한 sentry를 써보자
  • Sentry로 에러보내는 법

    1. 직접 코드레벨에서 던지기

      import io.sentry.Sentry;
      
      try {
          aMethodThatMightFail();
      } catch (Exception e) {
          Sentry.captureException(e);
      }
      

    2. logback 활용하기

      • implementation 'io.sentry:sentry-logback:6.19.0'
  • logback을 활용한 sentry

    1. resources 디렉토리에 sentry.properties 만들고 DSN 주소 작성 (logback.xml에 dsn 주소가 없다면, sentry.properties에서 dsn 주소 읽어옴)
      • dsn={dsn 주소}
    2. logback.xml에 센트리 어펜더 추가

      <appender name="Sentry" class="io.sentry.logback.SentryAppender">
          <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
              <level>ERROR</level>
          </filter>
      </appender>
      

    3. 에러 발생 시 정상 트래킹

Kamon with logback

참고: https://kamon.io/docs/latest/instrumentation/logback/#logging-with-context
참고: https://kamon.io/docs/latest/guides/how-to/log-trace-id-and-context-info/
참고: https://kamon.io/docs/latest/core/context/

  • build.sbt
    libraryDependencies += "io.kamon" %% "kamon-logback" % "2.6.0"
    libraryDependencies += "io.kamon" %% "kamon-core" % "2.6.0"
    libraryDependencies += "io.kamon" %% "kamon-play" % "2.6.0"
    
  • plugins.sbt
    addSbtPlugin("io.kamon" % "sbt-kanela-runner-play-2.8" % "2.0.12")
    
  • 개요
    • AsyncAppender를 쓸 때, Context를 보관하며 로그 레벨별로 항목 계산하는 어펜더 제공
  • Logging with Context

    • TraceIDConverter
      <conversionRule conversionWord="traceID" converterClass="kamon.instrumentation.logback.tools.TraceIDConverter"/>
      <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${appender.file.pathname}</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
          <fileNamePattern>${appender.file.pattern}</fileNamePattern>
          <maxHistory>${appender.file.maxHistory}</maxHistory>
        </rollingPolicy>
        <encoder>
          <pattern>%date %-5level [%traceID] %thread{10} [%logger{26}] %msg%n%rEx{full}%n</pattern>
        </encoder>
      </appender>
      
    • 어떻게 각 request가 공통의 traceId를 가지는거지?
      • Kamon: Context propagation mechanism이 있음
  • Context Propagation
    • 카몬은 Context 라는 request-specific information 사용
    • Context는 immutable key-value set
  • Automatic Instruction
    • Kamon은 Play의 incoming/outcoming 요청에 대해 Context Propagation을 진행
    • 각 HTTP 요청에 대해 kamon은...
      1. 신규 unique traceId Context 생성
      2. 해당 Context를 request 처리되는 시간동안 현재 Context에 담음
      3. 해당 Context를 요청에 연관된 각기 다른 쓰레드에 propagate를 진행함
  • Thread-Local
    • Kamon은 thread-local storage를 사용함!
    • 이거 트랜잭션할때 본건데...!
      // Store a Context and get a Scope
      val scope = Kamon.storeContext(context)
      
      // Run code with a specific Context
      Kamon.runWithContext(context) {
        // Your code here
      }
      

Akka with play framework