함수 로그 생성하기
함수 로그 생성하기
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 로그 시설 문서에서 확인할 수 있어요.