백엔드 오류 로그 추적(Track Backend Error Logs)
백엔드 언어의 오류 로그를 추적해 Error Tracking에서 그룹화하고 조사해요.
출처: 문서
본문
개요
아직 Datadog로 로그를 수집하고 있지 않다면 로그 문서를 참고해 로그를 설정하세요. source 태그(언어 지정)가 올바르게 구성되어 있는지 확인하세요. Datadog는 에이전트 기반 로그 수집 설정을 권장해요.
셋업
Python, Java, Ruby 같은 언어에서는 로그의 source 태그가 올바르게 구성되어 있다면 추가 구성이 필요 없어요. 필요한 모든 속성이 자동으로 태그되어 Datadog로 전송돼요.
C#, .NET, Go, Node.js 같은 백엔드 언어에서는 각 섹션의 코드 예제가 오류 로그를 올바르게 구성하고 필수 스택 트레이스를 로그의 error.stack에 첨부하는 방법을 보여 줘요.
이미 스택 트레이스를 Datadog로 보내고 있지만 error.stack에 없다면, 일반 로그 리매퍼를 설정해 스택 트레이스를 Datadog의 올바른 속성에 다시 매핑할 수 있어요.
이슈의 인라인 코드 스니펫을 구성하려면 소스 코드 통합을 설정하세요. Error Tracking for Logs에 코드 스니펫을 추가하는 데 APM은 필요하지 않아요. 강화 태그와 연결된 저장소는 둘 다 동일해요.
Error Tracking용 속성
Error Tracking을 활성화하려면 로그에 다음 속성이 포함되어야 해요.
error.kind또는error.stack필드 중 하나. 참고:error.stack을 사용한다면 유효한 스택 트레이스여야 해요.Service속성.ERROR,CRITICAL,ALERT또는EMERGENCY의 상태 레벨.
아래 나열된 나머지 속성은 선택 사항이지만, 그 존재가 오류 그룹화를 개선해요.
특정 속성은 Datadog 내에서 전용 UI 표시가 있어요. Error Tracking용으로 이 기능을 활성화하려면 다음 속성 이름을 사용하세요.
| 속성 | 설명 |
|---|---|
error.stack |
실제 스택 트레이스 |
error.message |
스택 트레이스에 포함된 오류 메시지 |
error.kind |
오류의 유형 또는 "종류"(예: "Exception" 또는 "OSError") |
참고: 기본적으로 통합 파이프라인은 기본 로깅 라이브러리 파라미터를 이 특정 속성에 다시 매핑하고, error.message와 error.kind를 자동으로 추출하기 위해 스택 트레이스 또는 트레이스백을 파싱하려고 해요.
자세한 내용은 전체 소스 코드 속성 문서를 참고하세요.
C# 및 .NET
Serilog
C#용 로그 수집을 설정하지 않았다면 C# 로그 수집 문서를 참고하세요.
잡힌 예외를 직접 로깅하려면 선택적으로 다음을 사용할 수 있어요.
var log = new LoggerConfiguration()
.WriteTo.File(new JsonFormatter(renderMessage: true), "log.json")
.Enrich.WithExceptionDetails()
.CreateLogger();
try {
// …
} catch (Exception ex) {
// pass exception as first argument of log call
log.Error(ex, "an exception occurred");
}
NLog
C#용 로그 수집을 설정하지 않았다면 C# 로그 수집 문서를 참고하세요.
잡힌 예외를 직접 로깅하려면 선택적으로 다음을 사용할 수 있어요.
private static Logger log = LogManager.GetCurrentClassLogger();
static void Main(string[] args)
{
try {
// …
} catch (Exception ex) {
// pass exception as second argument of log call
log.ErrorException("an exception occurred", ex);
}
}
Log4Net
C#용 로그 수집을 설정하지 않았다면 C# 로그 수집 문서를 참고하세요.
잡힌 예외를 직접 로깅하려면 선택적으로 다음을 사용할 수 있어요.
class Program
{
private static ILog logger = LogManager.GetLogger(typeof(Program));
static void Main(string[] args)
{
try {
// …
} catch (Exception ex) {
// pass exception as second argument of log call
log.Error("an exception occurred", ex);
}
}
}
Go
Logrus
Go용 로그 수집을 설정하지 않았다면 Go 로그 수집 문서를 참고하세요.
잡힌 예외를 직접 로깅하려면 선택적으로 다음을 사용할 수 있어요.
// for https://github.com/pkg/errors
type stackTracer interface {
StackTrace() errors.StackTrace
}
type errorField struct {
Kind string `json:"kind"`
Stack string `json:"stack"`
Message string `json:"message"`
}
func ErrorField(err error) errorField {
var stack string
if serr, ok := err.(stackTracer); ok {
st := serr.StackTrace()
stack = fmt.Sprintf("%+v", st)
if len(stack) > 0 && stack[0] == '\n' {
stack = stack[1:]
}
}
return errorField{
Kind: reflect.TypeOf(err).String(),
Stack: stack,
Message: err.Error(),
}
}
log.WithFields(log.Fields{
"error": ErrorField(err)
}).Error("an exception occurred")
Java(파싱됨)
Java용 로그 수집을 설정하지 않았다면 Java 로그 수집 문서를 참고하세요. 로그가 source:java로 태그되어 있는지 확인하세요.
Log4j
잡힌 예외를 직접 로깅하려면 선택적으로 다음을 사용할 수 있어요.
Logger logger = LogManager.getLogger("HelloWorld");
try {
// …
} catch (Exception e) {
// pass exception as last argument of log call
logger.error("an exception occurred", e)
}
SLF4J
잡힌 예외를 직접 로깅하려면 선택적으로 다음을 사용할 수 있어요.
Logger logger = LoggerFactory.getLogger(NameOfTheClass.class);
try {
// …
} catch (Exception e) {
// pass exception as last argument of log call
logger.error("an exception occurred", e)
}
Node.js
Winston (JSON)
Node.js용 로그 수집을 설정하지 않았다면 Node.js 로그 수집 문서를 참고하세요.
잡힌 예외를 직접 로깅하려면 선택적으로 다음을 사용할 수 있어요.
try {
// …
} catch (e) {
logger.error("an exception occurred", {
error: {
message: e.message,
stack: e.stack
}
});
}
PHP
Monolog (JSON)
PHP용 로그 수집을 설정하지 않았다면 PHP 로그 수집 문서를 참고하세요.
잡힌 예외를 직접 로깅하려면 선택적으로 다음을 사용할 수 있어요.
try {
// ...
} catch (\Exception $e) {
$logger->error('An error occurred', [
'error.message' => $e->getMessage(),
'error.kind' => get_class($e),
'error.stack' => $e->getTraceAsString(),
]);
}
Python
Logging
Python용 로그 수집을 설정하지 않았다면 Python 로그 수집 문서를 참고하세요. 로그가 source:python으로 태그되어 있는지 확인하세요.
잡힌 예외를 직접 로깅하려면 선택적으로 다음을 사용할 수 있어요.
try:
// …
except:
logging.exception('an exception occurred')
Ruby on Rails
커스텀 로거 포맷터
Ruby on Rails용 로그 수집을 설정하지 않았다면 Ruby on Rails 로그 수집 문서를 참고하세요.
오류를 수동으로 로깅하려면 JSON을 사용해 포맷터를 만들고 예외 값을 올바른 필드에 매핑하세요.
require 'json'
require 'logger'
class JsonWithErrorFieldFormatter < ::Logger::Formatter
def call(severity, datetime, progname, message)
log = {
timestamp: "#{datetime.to_s}",
level: severity,
}
if message.is_a?(Hash)
log = log.merge(message)
elsif message.is_a?(Exception)
log['message'] = message.inspect
log['error'] = {
kind: message.class,
message: message.message,
stack: message.backtrace.join("\n"),
}
else
log['message'] = message.is_a?(String) ? message : message.inspect
end
JSON.dump(log) + "\n"
end
end
그리고 로거에서 사용하세요.
logger = Logger.new(STDOUT)
logger.formatter = JsonWithErrorFieldFormatter.new
Lograge를 사용한다면 포맷된 오류 로그를 보내도록 설정할 수도 있어요.
Rails.application.configure do
jsonLogger = Logger.new(STDOUT) # STDOUT or file depending on your agent configuration
jsonLogger.formatter = JsonWithErrorFieldFormatter.new
# Replacing Rails default TaggedLogging logger with a new one with the json formatter.
# TaggedLogging is incompatible with more complex json format messages
config.logger = jsonLogger
# Lograge config
config.lograge.enabled = true
config.lograge.formatter = Lograge::Formatters::Raw.new
# Disables log coloration
config.colorize_logging = false
# Configure logging of exceptions to the correct fields
config.lograge.custom_options = lambda do |event|
if event.payload[:exception_object]
return {
level: 'ERROR',
message: event.payload[:exception_object].inspect,
error: {
kind: event.payload[:exception_object].class,
message: event.payload[:exception_object].message,
stack: event.payload[:exception_object].backtrace.join("\n")
}
}
end
end
end
더 알아보기 (Learn more)
추가로 도움이 되는 문서, 링크, 아티클: