오픈 트레이싱 맛보기 - NodeJS
오픈 트레이싱의 기본적인 내용을 테스트 해보았는데, 실제로 어떻게 적용할 수 있는지 확인해보려고 한다. 분산추적 Lab에서 오픈 트레이싱이 무엇인지 그리고 간단하게 코드를 수정해서 분산 추적을 테스트 해볼 수 있다.
HTTP 요청 트레이싱
예제코드가 담겨있는 코드를 다운 받고 node js코드가 있는 폴더로 이동한다.
git clone https://github.com/ibm-cloud-architecture/learning-distributed-tracing-101.git
cd learning-distributed-tracing-101/lab-jaeger-nodejs
service-a 수정
먼저 jaeger-client 라이브러리를 추가한다.
지금은 사용되지 않는 라이브러리임 공식적으로는 opentelementry-js 라이브러리가 있다
cd service-a
npm install --save jaeger-client
실행 후 package.json 파일을 확인해보면 jaeger-client가 추가된 것을 확인할 수 있다.
{
"name": "service",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node app.js",
"debug": "npm start",
"vscode": "node --inspect-brk=9229 app.js"
},
"dependencies": {
"bent": "^6.0.5",
"express": "^4.17.1",
"jaeger-client": "^3.18.1"
},
"devDependencies": {
"standard": "^16.0.4"
}
}
코드 수정
jaeger 트레이서를 초기화하는 코드를 app.js의 맨 아래에 삽입하자.
function initTracer (serviceName) {
const initJaegerTracer = require('jaeger-client').initTracerFromEnv
// Sampler set to const 1 to capture every request, do not do this for production
const config = {
serviceName: serviceName
}
// Only for DEV the sampler will report every span
// Other sampler types are described here: https://www.jaegertracing.io/docs/1.7/sampling/
config.sampler = { type: 'const', param: 1 }
return initJaegerTracer(config)
}
함수를 하나씩 살펴보면 처음에 jaeger-client 모듈을 갖고온다.
트레이싱에 필요한 정보가 필요한데 initTracerFromEnv를 이용하면 환경변수로 설정되어있는 값을 가져올 수 있다.
이 예제에서는 config 값을 이용하여 서비스의 이름을 설정하고, 샘플러 설정을 1로 하여 모든 요청을 수집 한다. (실제 서비스 환경에서는 모든 서비스를 수집하지 않음)
이제 이 initTracer 함수를 이용해 Tracer를 초기화 하고 opentracing 모듈에 tracer를 설정 한다.
app.js의 7번 째 줄에 아래의 코드를 삽입하자
const tracer = initTracer(serviceName)
const opentracing = require('opentracing')
opentracing.initGlobalTracer(tracer)
들어오는 모든 HTTP 요청을 추적하기 위해 아래의 함수를 service-a/app.js 의 맨 아래에 추가한다.
function tracingMiddleWare (req, res, next) {
const tracer = opentracing.globalTracer();
// 들어온 http 요청으로 부터 트레이싱 헤더들을 추출
const wireCtx = tracer.extract(opentracing.FORMAT_HTTP_HEADERS, req.headers)
// 들어온 요청의 context 정보를 이용해 span을 생성
const span = tracer.startSpan(req.path, { childOf: wireCtx })
// 로그 API를 이용하여 로그를 캡쳐
span.log({ event: 'request_received' })
// setTag API를 사용해 HTTP 추적을 위한 일반적인 스팬 태그를 캡쳐
span.setTag(opentracing.Tags.HTTP_METHOD, req.method)
span.setTag(opentracing.Tags.SPAN_KIND, opentracing.Tags.SPAN_KIND_RPC_SERVER)
span.setTag(opentracing.Tags.HTTP_URL, req.path)
// 응답 헤더에서 추적 ID를 찾아
// 브라우저에서 볼 수 있는 느린 요청을 디버깅 할 수 있도록
// trace ID를 포함시킨다.
const responseHeaders = {}
tracer.inject(span, opentracing.FORMAT_HTTP_HEADERS, responseHeaders)
res.set(responseHeaders)
// 스팬 정보를 다른 곳에서도 사용할 수 있도록 요청 object에 스팬 추가
Object.assign(req, { span })
// finalize the span when the response is completed
const finishSpan = () => {
if (res.statusCode >= 500) {
// 샘플링 우선순위를 높여 무조건 HTTP 에러가 수집 되도록 함
span.setTag(opentracing.Tags.SAMPLING_PRIORITY, 1)
// 에러가 발생한 경우 Span에 error 태그를 추가
span.setTag(opentracing.Tags.ERROR, true)
// 응답에는 트러블 슈팅을 위한 의미있는 정보가 포함되어야 함
span.log({ event: 'error', message: res.statusMessage })
}
// 상태 코드 캡쳐
span.setTag(opentracing.Tags.HTTP_STATUS_CODE, res.statusCode)
span.log({ event: 'request_end' })
span.finish()
}
res.on('finish', finishSpan)
next()
}
마지막으로 모든 HTTP 요청을 처리하기 위해 tracingMiddleWare
함수를 첫 미들웨어로 사용할 수 있도록 12번째 라인에 아래의 코드를 추가한다.
app.use(tracingMiddleWare)
앱 실행과 추적해보기
이제 서비스를 실행시켜 보자
docker-compose build
docker-compose up
이제 같은 API를 여러번 호출해 추적을 캡처해본다.
curl http://localhost:8080/sayHello/Carlos
Hello Carlos!
http://localhost:16686/jaeger로 접속해 Jaeger를 실행시키고 추적 정보를 살펴보자.
처음에 넣었던 request_received 로그와 마지막에 넣은 request_end 로그가 들어있는걸 확인할 수 있다.
이제 에러가 발생하도록 아래의 주소를 호출해보자
curl http://localhost:8080/error
some error (ノ ゜Д゜)ノ ︵ ┻━┻
에러 태그가 붙은걸 확인할 수 있다.
태그와 로그를 보면 응답 코드가 500인 것과 로그에 Internal Server Error를 확인할 수 있다.
Author And Source
이 문제에 관하여(오픈 트레이싱 맛보기 - NodeJS), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@nueah/오픈-트레이싱-맛보기-NodeJS저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)