콘텐츠로 이동

수동 추적 추가

스팬, 로그 및 추적

다음은 Logfire를 사용하는 간단한 예입니다.

import time

import logfire

logfire.configure()

with logfire.span('This is a span'):
    time.sleep(1)
    logfire.info('This is an info log')
    time.sleep(2)

이것을 실행하면 다음과 같이 인쇄됩니다.

Logfire project URL: https://logfire.pydantic.dev/my_username/my_project_name
21:02:55.078 This is a span
21:02:56.084   This is an info log

오프닝 프로젝트 URL은 라이브 보기에 다음을 표시해야 합니다.

라이브 뷰의 간단한 예

1+ 가 있는 파란색 상자는 스팬에 즉시 어린이 1명이 포함되어 있음을 나타냅니다. 상자를 클릭하여 스팬을 확장하여 하위 항목을 표시합니다.

스팬이 열린 라이브 뷰의 간단한 예

참고:

  1. with logfire.span(...): 블록에서 생성된 모든 스팬 또는 로그는 해당 스팬의 하위 항목이 됩니다. 이렇게 하면 구조화된 트리에서 로그를 멋지게 구성할 수 있습니다. 들여쓰기 기반 콘솔 로그에서 이 부모-자녀 관계를 볼 수도 있습니다.

  2. 스팬에는 시작 시간과 종료 시간이 있으므로 지속 시간이 있습니다. 이 스팬을 완료하는 데 3 초가 걸립니다.

  3. 로그의 경우 시작 시간과 종료 시간이 동일하므로 지속 시간이 없습니다. 그러나 여전히 UI에서 스팬이 시작된 후 1초, 스팬이 종료되기 2초 전에 로그가 생성되는 것을 볼 수 있습니다.

상단 탐색 모음에서 "탐색" 링크를 클릭하면 다음과 같은 추가 탐색을 위해 SQL을 작성할 수 있습니다.

탐색 보기의쿼리: start_time에서 주문한 레코드에서 추출('초')을 기간, 종류, 메시지, _id, span_id로 선택합니다.

주의:

  1. 스팬과 로그는 동일한 记录 테이블에 함께 저장됩니다.

  2. 로그 的parent_span_id 는 span_id 의 범위입니다.

  3. 둘 다 동일한 trace_id 를 가지고 있습니다. 이 탭을 클릭하여 "라이브" 보기에서 새 탭을 열 수 있습니다. 이 탭은 해당_추적_로 필터링되었습니다.

__는 동일한 루트를 공유하는 스팬/로그 트리입니다. 활성 스팬 없이 새 스팬/로그가 생성될 때마다 새 트레이스가 생성됩니다. 스팬이면 해당 스팬의 후손이 동일한 트레이스의 일부가 됩니다. 로그를 추적으로 잘 구성하려면 웹 서버 요청 처리와 같은 고급 작업을 나타내는 최상위 수준의 범위를 만드는 것이 가장 좋습니다.

속성

범위 및 로그는 다음과 같은 구조화된 데이터로 추가할 수 있습니다.

logfire.info('안녕하세요', 이름 = '세계')

라이브 뷰에 "Hello" 로그인을 클릭하면 오른쪽의 세부 정보 패널에 다음이 표시됩니다.

라이브 뷰의 이름 속성

이 데이터는 记录 테이블의 属性 열에 JSON 형식으로 저장됩니다. 예를 들어 라이브 뷰 상단에 있는 SQL 필터에서 attributes->>'name' = 'world' 를 사용하여 이 로그만 표시할 수 있습니다. 이것은 记录 테이블에 있는 SQL 쿼리의 WHERE 절로 사용됩니다.

스팬과 로그 모두 필요에 따라 JSON에 지능적으로 직렬화되는 임의 값을 포함하는 속성을 가질 수 있습니다. 밑줄(_)로 시작하지 않는 한 속성을 설정하기 위해 키워드 인수를 전달할 수 있습니다. 이 네임스페이스는 logfire 관련 의미를 가진 추가 키워드 매개 변수를 위해 예약되었습니다.

때로는 속성을 만든 후 완료하기 전에 스코프에 연결하는 것이 유용합니다.span.set_attribute 메서드를 호출하여 이 작업을 수행할 수 있습니다.

with logfire.span('Calculating...') as span:
    result = 1 + 2
    span.set_attribute('result', result)

메시지 및 범위 이름

이 코드를 실행하는 경우:

import logfire

logfire.configure()

for name in ['Alice', 'Bob', 'Carol']:
    logfire.info('Hello {name}', name=name)

탐색 보기에서 쿼리: span_name, tes-> 'name'을 이름으로 선택하고 start_time 에서 주문한 레코드의 메시지를 선택합니다.

여기에서 볼 수 있습니다.

  1. 첫 번째 인수 “Hello {name}” 는 span_name 열의 값이 됩니다. 메시지가 다른 경우에도 동일한 코드에서 모든 레코드를 찾는 데 사용할 수 있습니다. 예를 들어 SQL 필터 span_name = 'Hello {name}' 를 사용합니다.

  2. 스팬 이름도 사용됩니다. str.format 생성할 속성으로 포맷된 스타일 템플릿 消息 열. 메시지는 콘솔 로그 및 라이브 보기에 표시됩니다.

예를 들어 스팬이 시작된 후 스팬이 완료되기 전에 span.message 를 설정할 수도 있습니다.

with logfire.span('Calculating...') as span:
    result = 1 + 2
    span.message = f'Calculated: {result}'

사용할 수 있습니다 消息 다음과 같은 관련 레코드를 필터링하려면 “Hello%”之类的消息 예, 하지만 예 span_name 열 필터링은 색인화되기 때문에 더 효율적입니다. 다시, 사용 span_name = 'Hello {name}' 和 attributes->>'name' = 'Alice' 사용하는 것보다 message = 'Hello Alice' 더 나은.

관련 레코드를 효과적으로 필터링할 수 있도록 스팬 이름_베이스_낮아야 합니다. 즉, 너무 많이 변화해서는 안 됩니다. 예를 들어, 이것은 좋지 않습니다.

name = get_username()
logfire.info('Hello ' + name, name=name)

이제 span_name 열은 각 사용자 이름에 대해 다른 값을 가질 것이기 때문입니다. 하지만 괜찮습니다.

span_name 열에는 이제 두 가지 값('Goodbye {name}' 및 'Hello {name}')만 있기 때문에 span_name = 'Hello {name}' 를 필터링하는 것이 span_name = '{word} {name}' 和 attributes->>'word' = 'Hello' 를 필터링하는 것보다 쉽고 효율적입니다.

스팬 이름을 메시지 템플릿과 다르게 하려면 다음과 같은 _span_name 매개 변수를 사용할 수 있습니다.

word = 'Goodbye' if leaving else 'Hello'
logfire.info(word + ' {name}', name=name)

이것은 span_name 를 “Hello” 로,消息 를 “Hello world”。 로 설정합니다._span_name 매개 변수는 속성과 구별하기 위해 밑줄로 시작합니다.

logfire.info('Hello {name}', name='world', _span_name='Hello')

f-스트링


그 자리에:

logfire.info('Hello {name}', name=name)

NAME 를 세 번 반복하지 않으려면 F-String을 사용하는 것이 훨씬 편리합니다.

logfire.info(f'Hello {name}')

이전 섹션과 달리 Python 3.11+에 있습니다._효과_좋아, Logfire는 특별한 마법을 사용할 것이기 때문에 span_name 로 설정 “Hello {name}” 그리고 의지 name 속성이 로 설정되었습니다. name 변수의 값이므로 이전 코드 조각과 동일합니다. 알아야 할 사항은 다음과 같습니다.

  • 이 기능은 기본적으로 파이썬 3.11+에서 사용 가능합니다. 사용할 수 있습니다. [logfire.configure(inspect_arguments=False)][logfire.configure(inspect_arguments)] 비활성화하세요. 파이썬 3.9와 3.10에서도 활성화할 수 있지만 제대로 작동하지 않을 가능성이 높습니다.

  • 정상적인 상황에서는 파라미터가 항상 유효해야 합니다. 소스 코드를 사용할 수 있어야 하므로 예를 들어 .pyc 파일만 배포하면 실패합니다.

  • 매개 변수 확인에 실패하면 경고가 표시되고 f-문자열 매개 변수가 형식 템플릿으로 사용됩니다. 즉,“Hello Alice” 와 같은 높은 카디널리티 스팬 이름과 名称 속성이 없지만 정보가 완전히 손실되지는 않습니다.

  • 파라미터 확인이 활성화된 경우 f 문자열 사용 여부를 파라미터가 확인됩니다. 따라서 logfire.info('Hello {name}', name=name) 를 작성하고 파라미터 확인이 실패하더라도 여전히 경고가 표시됩니다.

  • f-문자열의 값은 Logfire에 의해 다시 평가되고 포맷됩니다. 즉,get_username()(또는 반환되는 모든 문자열 변환)가 비싸거나 부작용이 있는 경우 logfire.info(f'Hello {get_username()}') 와 같은 코드를 사용하지 않아야 합니다.

  • 첫 번째 인수는 실제 f 문자열이어야합니다.logfire.info(f'Hello {name}') 는 작동하지만 message = f'Hello {name}'; logfire.info(message) 는 작동하지 않으며 logfire.info('Hello ' + name) 도 작동하지 않습니다.

  • 동일한 f 문자열을 반복적으로 확인하면 성능 오버헤드가 최소화되도록 매개 변수 확인이 캐시됩니다. 그러나 대용량 소스 파일을 구문 분석하면 처음으로 매개 변수를 확인할 때 상당한 오버헤드가 발생합니다. 어느 쪽이든 이 오버헤드를 피하려면 f 문자열을 피하는 것이 아니라 검사 매개 변수를 완전히 비활성화해야 합니다.

비정상

logfire.span 컨텍스트 관리자는 다음과 같은 예외를 자동으로 기록합니다.

import logfire

logfire.configure()

with logfire.span('This is a span'):
    raise ValueError('This is an error')

라이브 뷰에서 간격을 클릭하면 오른쪽 패널에 "예외 추적" 탭이 표시됩니다.

UI의 추적

잡혔지만 다시 제기되지 않은 예외는 기록되지 않습니다. 예를 들어 다음과 같습니다.

with logfire.span('This is a span'):
    try:
        raise ValueError('This is an acceptable error not worth recording')
    except ValueError:
        pass

처리된 예외를 기록하려면 span.record_exception방법:

with logfire.span('This is a span') as span:
    try:
        raise ValueError('Catch this error, but record it')
    except ValueError as e:
        span.record_exception(e)

또는 일반 사례에 대한 범위를 만들지 않고 예외를 기록하려면logfire.exception 를 사용할 수 있습니다.

try:
    raise ValueError('This is an error')
except ValueError:
    logfire.exception('Something went wrong')

logfire.exception(...) 는 logfire.error(..., _exc_info=True)。 와 같습니다. 오류 없는 수준의 추적 백을 기록하려면 다른 로깅 방법과 함께 _exc_info 를 사용할 수도 있습니다. 예외 개체가 처리 중인 개체가 아닌 경우 _exc_info 를 예외 개체로 설정할 수 있습니다. 선행 밑줄을 잊지 마세요!

@logfire.instrument 로 편리한 기능 범위

일반적으로 전체 기능을 스팬으로 포장합니다. 이렇게 하는 대신:

def my_function(x, y):
    with logfire.span('my_function', x=x, y=y):
        ...

@logfire.instrument 데코레이터를 사용할 수 있습니다.

기본적으로 함수 매개 변수가 스팬에 속성으로 추가됩니다. 이 기능을 비활성화하려면(예: 매개 변수가 수집할 가치가 없는 큰 개체인 경우), instrument(extract_args=False)。

기본 스팬 이름은 다음과 같습니다. Calling module_name.my_function 첫 번째 인수로 대체 스팬 이름을 전달할 수 있습니다. instrument 다음과 같은 템플릿에 대한 인수로 형식을 지정할 수도 있습니다.

@logfire.instrument('Applying my_function to {x=} and {y=}')
def my_function(x, y):
    ...

my_function(3, 4)
# Logs: Applying my_function to x=3 and y=4

주의

  • '@Logfire' 데코레이터는 먼저, 즉 다른 데코레이터 아래에 적용되어야 합니다.
  • 함수의 소스 코드에 액세스할 수 있어야 합니다.

로그 레벨

다양한 수준의 로그를 만드는 방법은 다음과 같습니다.

  • logfire.trace
  • logfire.debug
  • logfire.info
  • logfire.notice(日志火灾通知)
  • logfire.warn
  • logfire.error
  • logfire.fatal

기본적으로 跟踪 및 调试 로그는 숨겨집니다. 라이브 뷰에서 "기본 수준" 드롭다운 메뉴를 클릭하여 이 설정을 변경할 수 있습니다.

기본 수준 드롭다운

사용할 수도 있습니다 logfire.configure 예를 들어 콘솔 로깅의 최소 수준을 설정합니다.

import logfire

logfire.configure(console=logfire.ConsoleOptions(min_log_level='debug'))

가변 수준으로 메시지를 기록하려면 logfire.log 를 사용할 수 있습니다. 예를 들어 logfire.log('info', 'This is an info log') 는 logfire.info('This is an info log')。 와 동일합니다.

기본적으로 스팬은 레벨입니다.信息 사용할 수 있습니다 _level 매개 변수 이 매개 변수 변경(예:使用 logfire.span('This is a debug span', _level='debug'): 스팬이 시작된 후 스팬이 완료되기 전에 사용할 수도 있습니다. span.set_level 레벨을 변경합니다. Logfire Span set_Level](예:

with logfire.span('Doing a thing') as span:
    success = do_thing()
    if not success:
        span.set_level('error')

"실시간" 보기에서스팬은 최고 등급과 후손에 따라 색상이 지정됩니다.예를 들어 다음 코드:

import logfire

logfire.configure()

with logfire.span('Outer span'):
    with logfire.span('Inner span'):
        logfire.info('This is an info message')
        logfire.error('This is an error message')

다음과 같이 나타납니다.

레벨별 색상 스팬

여기서 스팬 자체의 레벨은 여전히 로 설정됩니다.默认 정보는 있지만 오류 로그가 포함되어 있기 때문에 파란색 대신 빨간색으로 표시됩니다.

스팬이 처리되지 않은 예외로 끝나는 경우 스팬의 로그 레벨도 다음으로 설정됩니다.错误 사용 span.record_exception 이것은 일어나지 않습니다. Logfire Span. d_] 메서드.

데이터베이스에서 로그 수준은 级别 열에 숫자로 저장됩니다. 이러한 값은 OpenTelemetry를 기반으로 합니다. 예를 들어 info 는 9 입니다.level_num SQL 함수를 사용하여 수준 이름을 숫자로 변환할 수 있습니다. 예를 들어 级别 > level_num('info') 는 모든 "예외" 레코드를 찾습니다. 또한 level_name SQL 함수를 사용하여 숫자를 SELECT level_name(level)、... 와 같은 이름으로 변환하여 "탐색" 보기에서 사람이 읽을 수 있는 수준을 볼 수 있습니다.level 열은 색인화되므로 level = level_num('error') 에 대한 필터링은 유효하지만 level_name(level) = 'error' 에 대한 필터링은 유효하지 않습니다.


本文总阅读量次