ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • opensource contribute를 하다
    흔적 2021. 8. 2. 21:26
    반응형

    opensource contributor란?

    오픈 소스 소프트웨어는 소스 코드를 공개해 누구나 특별한 제한 없이 그 코드를 보고 사용할 수 있는 오픈 소스 라이선스를 만족하는 소프트웨어를 말한다 - 위키백과

     

     

     

    계기 

    제목을 적고 나니 뭔가 대단한 것을 한 것 같은데 그렇지 않다 정말 사소한 기여였다 그런데 하고 나니 별거 없는 나도 기여할 수 있구나라고 느꼈고 일 때문에 우연히 opensource에 commit 할 수 있는 계기가 되었다

    우리는 scouter로 x-log를 모니터링하고 알람을 받으면 grafana와 es log를 확인하고 에러를 해결한다 물론 scouter만으로도 해결되는 경우도 있다 그런데 scouter는 python(나는 fastapi를 사용했음)을 직접적으로 지원하지는 않고 zipkin에 storage를 scouter-storage를 사용해서 모니터링을 지원한다 그래서 어쩔 수 없이 zipkin을 아래 이미지와 가이 사용하기로 했다

     

    과정

    fastapi를 사용하고 있기 때문에 비동기, non-blocking을 지원해야 했고 python module을 찾아보았는데 여러개 있었다

    1. aiozipkin
    2. starlette-zipkin
    3. py-zipkin

     1,2,3 다 테스트를 하였는데 1, 2번은 zipkin을 경유해서 scouter로 x-log가 찍히지 않았고 3번은 x-log가 생성되었다 그러나 비동기 방식을 지원하지 않았다 물론 예제를 보면 비동기를 지원한다고 나와있지만 실제로 해보면 문법도 맞질 않았고(물론 내가 잘못했을 수도 있다 이때는 파이썬 2주 차 쪼렙이었음) middleware를 통째로 구현을 해줘야 했었기 때문에 비동기 non-blocking을 지원하는 1, 2번으로 좁혀졌다

     

    1번 같은 경우에는 기존 middleware를 수정해서 수정하니 잘 되었는데 구조가 맘에 들지 않았다

    아래 코드는 기존 코드를 테스트해가면서 수정한 코드(물론 이것 외에 더 많았다)이고 x-log를 찍었다

    그냥 내가 잘 모르긴 하지만 그냥 뭔가 보기만 해도 코드가 맘에 들지 않았고

    def middleware_maker(
            param_app,
            skip_routes: Optional[Iterable[AbstractRoute]] = None,
            tracer_key: str = APP_AIOZIPKIN_KEY,
            request_key: str = REQUEST_AIOZIPKIN_KEY,
    ) -> None:
        s = skip_routes
        skip_routes_set: Set[AbstractRoute] = set(s) if s else set()
    
        @param_app.middleware("http")
        async def aiozipkin_middleware(
                request, callNext
        ) -> StreamResponse:
            # route is in skip list, we do not track anything with zipkin
            if len(skip_routes_set) > 0:
                if request.match_info.route in skip_routes_set:
                    resp = await callNext(request)
                    return resp
    
            tracer = request.app.aiozipkin_tracer
            span = _get_span(request, tracer)
            request.aiozipkin_span = span
            if span.is_noop:
                resp = await callNext(request)
                return resp
    
            if PY37:
                with set_context_value(zipkin_context, span.context):
                    with span:
                        _set_span_properties(span, request)
                        try:
                            resp = await callNext(request)
                        except HTTPException as e:
                            span.tag(HTTP_STATUS_CODE, str(e.status))
                            raise
                        span.tag(HTTP_STATUS_CODE, str(resp.status_code))
            else:
                with span:
                    _set_span_properties(span, request)
                    try:
                        resp = await callNext(request)
                    except HTTPException as e:
                        span.tag(HTTP_STATUS_CODE, str(e.status))
                        raise
                    span.tag(HTTP_STATUS_CODE, str(resp.status))
    
            return resp
    
         return aiozipkin_middleware

     

    class 방식으로 middlware로 구현하고 싶었던 마음이 컸기 때문이고 아래와 방식으로 사용하는게 나중에 코드 볼 때 더 편하고 다른 사람이 수정하기 더 용이할 것 같았다

     

    class ZipkinMiddleware(BaseHTTPMiddleware):
        def __init__(
                self, app: Starlette, dispatch: Callable = None, config: ZipkinConfig = None
        ):
            self.app = app
            self.dispatch_func = self.dispatch if dispatch is None else dispatch
            self.config = config or ZipkinConfig()
            self.validate_config()
            self.tracer = None

     

    aiozipkin은 소스 수정으로 scouter x-log 찍는 것을 성공했기 때문에 그것과 비교해서 왜 안 들어 가는지 보았다

    zipkin에 request하는 부분을 나름 험난한 여정을 통해 찾았고 aiozipkin에 있는 데이터를 기준으로 starlette-zipkin에 없는 것을 찾아보았다

     

    {
       "traceId":"60f285c66d365103ce55e73e74507d5d",
       "name":"GET /homepage",
       "parentId":"None",
       "id":"ca14839d282cf4f2",
       "kind":"SERVER",
       "timestamp":1626506694783555,
       "duration":439,
       "debug":false,
       "shared":false,
       "localEndpoint":{
          "serviceName":"server",
          "ipv4":"127.0.0.1",
          "port":9002
       },
       "remoteEndpoint":{
          "ipv4":"127.0.0.1"
       },
       "annotations":[
          
       ],
       "tags":{
          "http.path":"/homepage",
          "http.method":"GET",
          "http.status_code":"200"
       }
    }

     

    {
       "traceId":"60f27a6b5ae54689fe5d77de3096c1fe",
       "name":"NewParent",
       "parentId":"208e21999aee2e6f",
       "id":"a564b01cdd9b68af",
       "timestamp":1626503787152032,
       "duration":1003663,
       "debug":false,
       "shared":false,
       "localEndpoint":{
          "serviceName":"service_name",
          "ipv4":"127.0.0.1",
          "port":8000
       },
       "remoteEndpoint":"None",
       "annotations":[
          {
             "value":"Child, sleeps for 1, injects headers and becomes parent",
             "timestamp":1626503787152048
          }
       ],
       "tags":{
          
       }
    }

     

    aiozipkin에 있는 starlette-zipkin에 없는 데이터를 찾아보았고 눈에 크게 들어온 것은 아래 두 가지 데이터였다

    'kind': 'SERVER'

    'remoteEndpoint': {'ipv4': '127.0.0.1'}

     

    그래서 starlette-zipkin middleware에 해당 속성을 추가해서 보냈더니 드디어 x-log가 찍혔다

    정확하게는 kind값이 없어서 x-log에는 찍히지 않았던 것이다

     

    위와 같은 과정을 통해 결국 x-log를 찍을 수 있게 되었고 외국 사람들이 scouter를 쓸지는 모르지만 어찌되었든 간에 opensource에 기여할 수 있는 부분이라고 생각했고 해당 issue에 글을 남겨 기여할 수 있게 되었다

     

    인증샷

     

    물론 정말 작은 프로젝트인 opensource이고 아무것도 아닌 commit이었지만 뭔가 정말 뿌듯한 경험이었다

    누군가는 큰 결심을 하고 opensource contributor가 될 수도 있지만 나처럼 실무에 필요에 의해서 개선하다

    contributor도 될 수 있구나 라고 경험으로 깨달은 과정이었다

    조만간 aiozipkin도 commit을 할 예정이다

     

     

    https://github.com/mchlvl/starlette-zipkin

     

    GitHub - mchlvl/starlette-zipkin: Zipkin client for asgi. Compatible with Starlette Framework and Jaeger tracing server

    Zipkin client for asgi. Compatible with Starlette Framework and Jaeger tracing server - GitHub - mchlvl/starlette-zipkin: Zipkin client for asgi. Compatible with Starlette Framework and Jaeger trac...

    github.com

     

     

    반응형

    댓글

Designed by Tistory.