함수 로그 생성하기

함수 로그 생성하기

Pulsar 함수에서 로그를 남기는 방법을 언어별로 정리해 볼게요. Java·Python·Go 모두 함수 로그를 만들 수 있고, 로그 레벨도 직접 조절할 수 있어요. 함수 로그를 제대로 처리해 두면 장애 추적과 디버깅이 훨씬 편해져요.

함수가 로그를 생성하려면 함수를 만들거나 실행할 때 로그 토픽(log topic)을 지정해야 해요. 지정한 토픽으로 모든 함수 로그가 흘러들어 오니까, 이 토픽을 소비하며 로그를 확인하면 돼요.

출처: 문서

본문

Java 함수 로그 생성하기 (Produce logs for Java functions)

Java SDK를 사용하는 Pulsar 함수는 SLF4j Logger 객체에 접근할 수 있어요. 이 로거 객체로 지정한 로그 레벨의 로그를 만들 수 있죠.

예를 들어 아래 함수는 입력 문자열에 danger라는 단어가 들어 있는지에 따라 WARNING 또는 INFO 레벨 로그를 남겨요.

import org.apache.pulsar.functions.api.Context;
import org.apache.pulsar.functions.api.Function;
import org.slf4j.Logger;

public class LoggingFunction implements Function<String, Void> {
    @Override
    public void apply(String input, Context context) {
        Logger LOG = context.getLogger();
        String messageId = new String(context.getMessageId());

        if (input.contains("danger")) {
            LOG.warn("A warning was received in message {}", messageId);
        } else {
            LOG.info("Message {} received\nContent: {}", messageId, input);
        }

        return null;
    }
}

함수가 로그를 생성하도록 하려면, 함수를 만들거나 실행할 때 로그 토픽을 지정해야 해요. 다음은 그 예시예요.

bin/pulsar-admin functions create \
  --jar $PWD/my-functions.jar \
  --classname my.package.LoggingFunction \
  --log-topic persistent://public/default/logging-function-logs \
  # Other function configs

LoggingFunction이 생성한 모든 로그는 persistent://public/default/logging-function-logs 토픽을 통해 접근할 수 있어요.

Java 함수 로그 레벨 커스터마이징 (Customize log levels for Java functions)

기본적으로 Java 함수의 로그 레벨은 info예요. 로그 레벨을 예를 들어 debug로 바꾸고 싶다면 functions_log4j2.xml 파일을 수정하면 돼요.

팁: functions_log4j2.xml 파일은 Pulsar 설정 디렉터리, 즉 베어메탈에서는 /etc/pulsar/, Kubernetes에서는 /pulsar/conf 아래에 있어요.

먼저 Property의 값을 설정해요.

     <Property>
         <name>pulsar.log.level</name>
         <value>debug</value>
     </Property>

그 다음 이 로그 레벨을 참조하는 곳에 적용해요. 아래 예시에서 debug는 모든 함수 로그에 적용돼요.

     <Root>
         <level>${sys:pulsar.log.level}</level>
         <AppenderRef>
             <ref>${sys:pulsar.log.appender}</ref>
             <level>${sys:pulsar.log.level}</level>
         </AppenderRef>
     </Root>

더 세밀하게 제어하고 싶다면, 클래스나 모듈별로 서로 다른 로그 레벨을 적용할 수 있어요. 예를 들어:

     <Logger>
         <name>com.example.module</name>
         <level>info</level>
         <additivity>false</additivity>
         <AppenderRef>
             <ref>${sys:pulsar.log.appender}</ref>
         </AppenderRef>
     </Logger>

모듈 안의 특정 클래스에 더 상세한 로그 레벨을 적용하려면 아래 예시를 참고하면 돼요.

     <Logger>
         <name>com.example.module.className</name>
         <level>debug</level>
         <additivity>false</additivity>
         <AppenderRef>
             <ref>Console</ref>
         </AppenderRef>
     </Logger>
  • additivity는 여러 <Logger> 항목이 겹칠 때 로그 메시지가 중복될지 여부를 나타내요. additivity를 비활성화(false)하면, 클래스나 모듈이 겹치는 <Logger> 항목이 하나 이상 있어도 로그 메시지가 중복되지 않아요.
  • AppenderRef는 Appender 섹션 정의에서 지정한 대상을 로그로 출력할 수 있게 해줘요. 예를 들어:
   <Console>
     <name>Console</name>
     <target>SYSTEM_OUT</target>
     <PatternLayout>
       <Pattern>%d{ISO8601_OFFSET_DATE_TIME_HHMM} [%t] %-5level %logger{36} - %msg%n</Pattern>
     </PatternLayout>
   </Console>

Python 함수 로그 생성하기 (Produce logs for Python functions)

Python SDK를 사용하는 Pulsar 함수는 logger 객체에 접근할 수 있어요. 지정한 로그 레벨로 로그를 만들 수 있죠.

아래 함수는 입력 문자열에 danger가 들어 있는지에 따라 WARNING 또는 INFO 레벨 로그를 남겨요.

from pulsar import Function

class LoggingFunction(Function):
    def process(self, input, context):
        logger = context.get_logger()
        msg_id = context.get_message_id()
        if 'danger' in input:
            logger.warn("A warning was received in message {0}".format(context.get_message_id()))
        else:
            logger.info("Message {0} received\nContent: {1}".format(msg_id, input))

함수가 로그를 생성하려면 함수를 만들거나 실행할 때 로그 토픽을 지정해야 해요. 다음은 그 예시예요.

bin/pulsar-admin functions create \
  --py logging_function.py \
  --classname logging_function.LoggingFunction \
  --log-topic logging-function-logs \
  # Other function configs

LoggingFunction이 생성한 모든 로그는 logging-function-logs 토픽을 통해 접근할 수 있어요. 또한 context.get_logger().setLevel(level)로 함수 로그 레벨을 지정할 수도 있어요. 자세한 내용은 Python 로그 기능 문서를 참고해요.

Go 함수 로그 생성하기 (Produce logs for Go functions)

Go 함수에서 logTopic 관련 기능을 쓸 때는 getLogger() 컨텍스트 객체 대신 github.com/apache/pulsar/pulsar-function-go/logutil을 임포트하면 돼요.

아래 함수는 함수 입력에 따라 서로 다른 로그 레벨을 보여줘요.

import (
    "context"

    "github.com/apache/pulsar/pulsar-function-go/pf"

    log "github.com/apache/pulsar/pulsar-function-go/logutil"
)

func loggerFunc(ctx context.Context, input []byte) {
	if len(input) <= 100 {
		log.Infof("This input has a length of: %d", len(input))
	} else {
		log.Warnf("This input is getting too long! It has {%d} characters", len(input))
	}
}

func main() {
	pf.Start(loggerFunc)
}

더 알아보기 (Learn more)

  • 함수 개발에 필요한 다른 기능은 함수 개발 API 문서에서 살펴보세요.
  • 로그를 소비하는 방법이 궁금하다면 토픽 구독 문서를 참고해요.
  • Python 로그 기능의 상세 내용은 Python 로그 시설 문서에서 확인할 수 있어요.