함수 로그와 스팬 계측
함수는 로그와 실행 구간인 스팬(Span)을 남겨 운영 흐름을 조사할 수 있습니다. 모든 함수에는 전체 실행시간을 감싸는 스팬 하나와 요청 로그 하나가 자동 생성됩니다. 기록은 온톨로지 및 AIP 관측에서 확인합니다.
언어별 지원
| 언어 | 사용자 로그 | 스팬 | 지표 |
|---|---|---|---|
| TSv1 | 지원 | 객체 로드와 쿼리 등 제품이 정의한 스팬만 지원 | 제품 지표만 지원 |
| TSv2 | 지원 | 자동 외부 요청 계측과 사용자 지정 스팬 | 제품 지표만 지원 |
| Python | 지원 | 자동 외부 요청 계측과 사용자 지정 스팬 | 제품 지표만 지원 |
제품 지표에는 전체 실행시간이 포함됩니다. 위 표의 지표는 텔레메트리 기록 기능이며 차트에 반환하는 사용자 계산값과는 다른 범위입니다.
로그 기록
다음 예제의 사용자 로그에는 입력 문자열의 길이만 기록합니다. 반환값은 입력한 이름을 포함한 인사말입니다.
TypeScript v1
import { Function } from "@foundry/functions-api";
export class TelemetryFunctions {
@Function()
public myFunction(name: string): string {
console.log(`Greeting input length: ${name.length}.`);
return `Hello, ${name}!`;
}
}
클래스를 함수 저장소의 index.ts에서 내보냅니다.
TypeScript v2
myFunction.ts에서 작성합니다. Foundry가 전역 OpenTelemetry Logger provider를 설정하므로 거기서 로거를 가져옵니다. 별도 provider로 교체하지 않습니다.
import { logs } from "@opentelemetry/api-logs";
const logger = logs.getLogger("my-function");
export default function myFunction(name: string): string {
logger.emit({
body: "Greeting requested.",
attributes: { inputLength: name.length }
});
return `Hello, ${name}!`;
}
전역 console도 사용할 수 있습니다. 같은 이벤트를 두 경로로 중복 기록할 필요는 없습니다. 타사 로깅 라이브러리를 사용한다면 전역 provider에서 얻은 로거로 보내도록 설정해야 합니다.
Python
import logging
from functions.api import function
logger = logging.getLogger(__name__)
@function
def my_function(name: str) -> str:
logger.info("Greeting input length: %d", len(name))
return f"Hello, {name}!"
일반 작업은 INFO, 복구 가능한 문제는 WARN, 실패는 ERROR, 자세한 진단은 DEBUG로 구분합니다. 필요한 식별자나 개수와 작업 맥락을 남기되 자격 증명, 민감한 전체 API 응답이나 비밀값을 기록하지 않습니다.
사용자 지정 스팬
TSv2와 Python은 Foundry가 설정한 전역 Tracer provider를 사용합니다. 타사 추적 라이브러리도 이 provider에서 얻은 tracer를 사용하도록 해야 합니다.
다음 예제는 정수 입력의 제곱근을 계산합니다. 제곱근은 소수가 될 수 있으므로 결과는 Double입니다. 음수는 사용자 오류로 알립니다.
TSv2의 sqrt.ts입니다. 반환이나 오류와 무관하게 finally에서 스팬을 닫습니다.
import { trace } from "@opentelemetry/api";
import { Double, Integer, UserFacingError } from "@osdk/functions";
const tracer = trace.getTracer("my-function");
export default function sqrt(n: Integer): Double {
return tracer.startActiveSpan("my-custom-span", span => {
try {
if (n < 0) {
throw new UserFacingError("제곱근의 입력은 0 이상이어야 합니다.");
}
return Math.sqrt(n);
} finally {
span.end();
}
});
}
Python은 스팬 문맥 관리자의 블록을 사용합니다.
import math
from functions.api import Double, Integer, UserFacingError, function
from opentelemetry import trace
tracer = trace.get_tracer(__name__)
@function
def sqrt(n: Integer) -> Double:
with tracer.start_as_current_span("my-custom-span"):
if n < 0:
raise UserFacingError("제곱근의 입력은 0 이상이어야 합니다.")
return math.sqrt(n)
스팬을 끝내지 않으면 내보내지지 않을 수 있으므로 실행 경로마다 종료해야 합니다.