DefStream-RabbitMQ 0.1.4__tar.gz → 0.1.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of DefStream-RabbitMQ might be problematic. Click here for more details.

Files changed (49) hide show
  1. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5/DefStream_RabbitMQ.egg-info}/PKG-INFO +22 -2
  2. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/DefStream_RabbitMQ.egg-info/SOURCES.txt +4 -0
  3. defstream_rabbitmq-0.1.5/DefStream_RabbitMQ.egg-info/requires.txt +2 -0
  4. {defstream_rabbitmq-0.1.4/DefStream_RabbitMQ.egg-info → defstream_rabbitmq-0.1.5}/PKG-INFO +22 -2
  5. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/README.en.md +21 -0
  6. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/README.md +20 -0
  7. defstream_rabbitmq-0.1.5/issues/feature/5/IMPLEMENTS.md +83 -0
  8. defstream_rabbitmq-0.1.5/issues/feature/5/README.md +43 -0
  9. defstream_rabbitmq-0.1.5/issues/feature/5/REQUIREMENTS.md +122 -0
  10. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/sample/Sample.RPC.py +28 -8
  11. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/sample/Sample.Stream.py +24 -6
  12. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/sample/Sample.py +23 -4
  13. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/setup.py +1 -1
  14. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/src/Connection.py +158 -97
  15. defstream_rabbitmq-0.1.5/src/Consumer.py +359 -0
  16. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/src/Event.py +30 -9
  17. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/src/Exchange.py +63 -12
  18. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/src/Queue.py +87 -28
  19. defstream_rabbitmq-0.1.5/src/Stream.py +179 -0
  20. defstream_rabbitmq-0.1.5/test/test_logging.py +475 -0
  21. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/test/test_rabbitmq_integration.py +1 -1
  22. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/test/test_rpc_integration.py +1 -1
  23. defstream_rabbitmq-0.1.4/DefStream_RabbitMQ.egg-info/requires.txt +0 -2
  24. defstream_rabbitmq-0.1.4/src/Consumer.py +0 -242
  25. defstream_rabbitmq-0.1.4/src/Stream.py +0 -119
  26. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/.github/workflows/ci.yml +0 -0
  27. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/.gitignore +0 -0
  28. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/DefStream_RabbitMQ.egg-info/dependency_links.txt +0 -0
  29. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/DefStream_RabbitMQ.egg-info/top_level.txt +0 -0
  30. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/LICENSE +0 -0
  31. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/issues/feature/1/IMPLEMENTS.md +0 -0
  32. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/issues/feature/1/README.md +0 -0
  33. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/issues/feature/1/REQUIREMENTS.md +0 -0
  34. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/issues/feature/1/TASK.md +0 -0
  35. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/issues/feature/1/ci.refs.json +0 -0
  36. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/issues/fix/3/IMPLEMENTS.md +0 -0
  37. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/issues/fix/3/README.md +0 -0
  38. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/issues/fix/3/REQUIREMENTS.md +0 -0
  39. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/setup.cfg +0 -0
  40. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/src/Configuration.py +0 -0
  41. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/src/Policies.py +0 -0
  42. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/src/Serializer.py +0 -0
  43. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/src/Subscription.py +0 -0
  44. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/src/__init__.py +0 -0
  45. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/test/test_broker_methods.py +0 -0
  46. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/test/test_priorities.py +0 -0
  47. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/test/test_rabbitmq_worker.py +0 -0
  48. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/test/test_release_workflow.py +0 -0
  49. {defstream_rabbitmq-0.1.4 → defstream_rabbitmq-0.1.5}/test/test_rpc.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: DefStream-RabbitMQ
3
- Version: 0.1.4
3
+ Version: 0.1.5
4
4
  Summary: RabbitMQ broker adapter for DefStream
5
5
  Home-page: https://github.com/yong5eon/DefStream-RabbitMQ
6
6
  Author: Heo Yongseon
@@ -16,7 +16,7 @@ Classifier: Programming Language :: Python :: 3.14
16
16
  Requires-Python: >=3.9
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE
19
- Requires-Dist: DefStream>=0.1.7
19
+ Requires-Dist: DefStream>=0.1.9
20
20
  Requires-Dist: pika>=1.3.2
21
21
  Dynamic: author
22
22
  Dynamic: classifier
@@ -101,6 +101,26 @@ finally:
101
101
  일반 연결의 heartbeat는 애플리케이션 작업·유휴 시간에 맞게 설정하고 처리되도록 관리하세요.
102
102
  연결과 그 리소스는 **소유 스레드에서만 사용**해야 하며, 스레드·프로세스 사이에 공유하지 마세요.
103
103
 
104
+ ## 로깅
105
+
106
+ 여섯 클래스는 `DefStream.Broker.Implements.RabbitMQ.ClassName` 이름의 클래스 멤버
107
+ `logger`를 사용합니다(`Connection`, `Consumer`, `Queue`, `Exchange`, `Stream`, `Event`).
108
+ 하위 클래스는 같은 로거를 상속하며 필요하면 멤버를 재정의할 수 있습니다.
109
+ 라이브러리는 핸들러·`NullHandler`·레벨·필터를 설정하지 않고 루트로 전파합니다.
110
+ 미설정 시 표준 `logging.lastResort` 동작을 유지합니다.
111
+
112
+ 연결·자원 변경은 INFO, 메시지·RPC·정산 추적은 DEBUG, RPC 시간 초과·원격 오류·
113
+ 응답 라우팅 불가는 WARNING, 내부 I/O·코덱 오류는 ERROR입니다.
114
+ 본문·결과·헤더·인증정보와 예외 문자열·traceback은 기록하지 않으며 예외는 그대로 전파합니다.
115
+ 애플리케이션이 같은 예외를 다시 기록하면 중복될 수 있습니다.
116
+ 발행 API 반환은 소비자 처리 완료가 아니며, RPC 응답 시간 초과도 전달된 작업을 취소하지 않습니다.
117
+
118
+ `sample/*.py`는 실행 진입점에서만 루트 DEBUG 콘솔 출력을 구성합니다.
119
+ 핸들러의 `Filter('Sample')` 또는 `Filter('DefStream.Broker.Implements.RabbitMQ')`
120
+ 통과 조건으로 두 이름과 점으로 구분된 하위 로거만 출력하며 Pika·코어 등은 제외합니다.
121
+ 다른 애플리케이션에서는 원하는 상위 이름(`DefStream`, `DefStream.Broker` 등)이나
122
+ 클래스 이름을 선택하고 핸들러·레벨·필터를 직접 구성하세요.
123
+
104
124
  ## Worker로 작업 처리하기
105
125
 
106
126
  다음은 큐와 오류 큐를 준비한 후 작업을 소비하는 실행 파일입니다.
@@ -14,6 +14,9 @@ issues/feature/1/README.md
14
14
  issues/feature/1/REQUIREMENTS.md
15
15
  issues/feature/1/TASK.md
16
16
  issues/feature/1/ci.refs.json
17
+ issues/feature/5/IMPLEMENTS.md
18
+ issues/feature/5/README.md
19
+ issues/feature/5/REQUIREMENTS.md
17
20
  issues/fix/3/IMPLEMENTS.md
18
21
  issues/fix/3/README.md
19
22
  issues/fix/3/REQUIREMENTS.md
@@ -32,6 +35,7 @@ src/Stream.py
32
35
  src/Subscription.py
33
36
  src/__init__.py
34
37
  test/test_broker_methods.py
38
+ test/test_logging.py
35
39
  test/test_priorities.py
36
40
  test/test_rabbitmq_integration.py
37
41
  test/test_rabbitmq_worker.py
@@ -0,0 +1,2 @@
1
+ DefStream>=0.1.9
2
+ pika>=1.3.2
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: DefStream-RabbitMQ
3
- Version: 0.1.4
3
+ Version: 0.1.5
4
4
  Summary: RabbitMQ broker adapter for DefStream
5
5
  Home-page: https://github.com/yong5eon/DefStream-RabbitMQ
6
6
  Author: Heo Yongseon
@@ -16,7 +16,7 @@ Classifier: Programming Language :: Python :: 3.14
16
16
  Requires-Python: >=3.9
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE
19
- Requires-Dist: DefStream>=0.1.7
19
+ Requires-Dist: DefStream>=0.1.9
20
20
  Requires-Dist: pika>=1.3.2
21
21
  Dynamic: author
22
22
  Dynamic: classifier
@@ -101,6 +101,26 @@ finally:
101
101
  일반 연결의 heartbeat는 애플리케이션 작업·유휴 시간에 맞게 설정하고 처리되도록 관리하세요.
102
102
  연결과 그 리소스는 **소유 스레드에서만 사용**해야 하며, 스레드·프로세스 사이에 공유하지 마세요.
103
103
 
104
+ ## 로깅
105
+
106
+ 여섯 클래스는 `DefStream.Broker.Implements.RabbitMQ.ClassName` 이름의 클래스 멤버
107
+ `logger`를 사용합니다(`Connection`, `Consumer`, `Queue`, `Exchange`, `Stream`, `Event`).
108
+ 하위 클래스는 같은 로거를 상속하며 필요하면 멤버를 재정의할 수 있습니다.
109
+ 라이브러리는 핸들러·`NullHandler`·레벨·필터를 설정하지 않고 루트로 전파합니다.
110
+ 미설정 시 표준 `logging.lastResort` 동작을 유지합니다.
111
+
112
+ 연결·자원 변경은 INFO, 메시지·RPC·정산 추적은 DEBUG, RPC 시간 초과·원격 오류·
113
+ 응답 라우팅 불가는 WARNING, 내부 I/O·코덱 오류는 ERROR입니다.
114
+ 본문·결과·헤더·인증정보와 예외 문자열·traceback은 기록하지 않으며 예외는 그대로 전파합니다.
115
+ 애플리케이션이 같은 예외를 다시 기록하면 중복될 수 있습니다.
116
+ 발행 API 반환은 소비자 처리 완료가 아니며, RPC 응답 시간 초과도 전달된 작업을 취소하지 않습니다.
117
+
118
+ `sample/*.py`는 실행 진입점에서만 루트 DEBUG 콘솔 출력을 구성합니다.
119
+ 핸들러의 `Filter('Sample')` 또는 `Filter('DefStream.Broker.Implements.RabbitMQ')`
120
+ 통과 조건으로 두 이름과 점으로 구분된 하위 로거만 출력하며 Pika·코어 등은 제외합니다.
121
+ 다른 애플리케이션에서는 원하는 상위 이름(`DefStream`, `DefStream.Broker` 등)이나
122
+ 클래스 이름을 선택하고 핸들러·레벨·필터를 직접 구성하세요.
123
+
104
124
  ## Worker로 작업 처리하기
105
125
 
106
126
  다음은 큐와 오류 큐를 준비한 후 작업을 소비하는 실행 파일입니다.
@@ -54,6 +54,27 @@ Call `ack()` on success, `nack()` for redelivery, or `reject()` to reject.
54
54
  Rejected messages go to the broker-configured dead-letter destination or are
55
55
  discarded when none is configured.
56
56
 
57
+ ## Logging
58
+
59
+ `Connection`, `Consumer`, `Queue`, `Exchange`, `Stream`, and `Event` expose a class
60
+ member `logger` named `DefStream.Broker.Implements.RabbitMQ.ClassName`. Subclasses
61
+ inherit that logger unless they explicitly override it. The library adds no handlers
62
+ (including `NullHandler`), levels, or filters; propagation and `logging.lastResort`
63
+ keep their standard behavior.
64
+
65
+ Lifecycle and resource changes use INFO, per-message/RPC/settlement tracing uses DEBUG,
66
+ expected RPC anomalies use WARNING, and internal I/O or codec failures use ERROR.
67
+ Payloads, results, headers, credentials, exception text, and tracebacks are omitted.
68
+ Exceptions still propagate; application-side logging may duplicate a library record.
69
+ A publish return does not mean consumer processing completed, and an RPC response
70
+ timeout does not cancel delivered work.
71
+
72
+ The Python samples configure a root DEBUG console handler only in their main entry
73
+ points. Its filter accepts `Filter('Sample')` **or**
74
+ `Filter('DefStream.Broker.Implements.RabbitMQ')`, including dotted descendants only;
75
+ Pika and core logs are excluded. Applications configure their own handlers, levels,
76
+ and filters at a chosen ancestor (`DefStream`, `DefStream.Broker`, etc.) or class.
77
+
57
78
  ## Connection configuration
58
79
 
59
80
  | Option | Meaning |
@@ -70,6 +70,26 @@ finally:
70
70
  일반 연결의 heartbeat는 애플리케이션 작업·유휴 시간에 맞게 설정하고 처리되도록 관리하세요.
71
71
  연결과 그 리소스는 **소유 스레드에서만 사용**해야 하며, 스레드·프로세스 사이에 공유하지 마세요.
72
72
 
73
+ ## 로깅
74
+
75
+ 여섯 클래스는 `DefStream.Broker.Implements.RabbitMQ.ClassName` 이름의 클래스 멤버
76
+ `logger`를 사용합니다(`Connection`, `Consumer`, `Queue`, `Exchange`, `Stream`, `Event`).
77
+ 하위 클래스는 같은 로거를 상속하며 필요하면 멤버를 재정의할 수 있습니다.
78
+ 라이브러리는 핸들러·`NullHandler`·레벨·필터를 설정하지 않고 루트로 전파합니다.
79
+ 미설정 시 표준 `logging.lastResort` 동작을 유지합니다.
80
+
81
+ 연결·자원 변경은 INFO, 메시지·RPC·정산 추적은 DEBUG, RPC 시간 초과·원격 오류·
82
+ 응답 라우팅 불가는 WARNING, 내부 I/O·코덱 오류는 ERROR입니다.
83
+ 본문·결과·헤더·인증정보와 예외 문자열·traceback은 기록하지 않으며 예외는 그대로 전파합니다.
84
+ 애플리케이션이 같은 예외를 다시 기록하면 중복될 수 있습니다.
85
+ 발행 API 반환은 소비자 처리 완료가 아니며, RPC 응답 시간 초과도 전달된 작업을 취소하지 않습니다.
86
+
87
+ `sample/*.py`는 실행 진입점에서만 루트 DEBUG 콘솔 출력을 구성합니다.
88
+ 핸들러의 `Filter('Sample')` 또는 `Filter('DefStream.Broker.Implements.RabbitMQ')`
89
+ 통과 조건으로 두 이름과 점으로 구분된 하위 로거만 출력하며 Pika·코어 등은 제외합니다.
90
+ 다른 애플리케이션에서는 원하는 상위 이름(`DefStream`, `DefStream.Broker` 등)이나
91
+ 클래스 이름을 선택하고 핸들러·레벨·필터를 직접 구성하세요.
92
+
73
93
  ## Worker로 작업 처리하기
74
94
 
75
95
  다음은 큐와 오류 큐를 준비한 후 작업을 소비하는 실행 파일입니다.
@@ -0,0 +1,83 @@
1
+ # 로깅 지원 구현 기록
2
+
3
+ ## 1. 구현 개요
4
+
5
+ [요구사항](./REQUIREMENTS.md)에 따라 RabbitMQ I/O와 메시지 처리 경계에
6
+ 클래스별 표준 로깅을 추가했다.
7
+
8
+ - 구현·검증일: 2026-10-20
9
+ - 사용자용 안내: [변경 로그](./README.md)
10
+ - 연계 구현: [코어 로깅](../../../../DefStream/issues/feature/8/IMPLEMENTS.md)
11
+
12
+ ## 2. 로거와 기록 범위
13
+
14
+ 각 클래스에 `DefStream.Broker.Implements.RabbitMQ.<클래스 이름>`의
15
+ 클래스 멤버 `logger`를 정의했다.
16
+
17
+ | 클래스 | 구현한 관찰 지점 |
18
+ | --- | --- |
19
+ | [Connection](../../../src/Connection.py) | 연결·재사용·종료, 자원 선언·삭제·바인딩, publisher 생성, emit·RPC 위임 |
20
+ | [Consumer](../../../src/Consumer.py) | 구독·QoS·offset, 루프 시작·중지, 수신·디코딩·전달, 콜백 예약, 정책·RPC 응답 |
21
+ | [Queue](../../../src/Queue.py) | 발행·단건 수신·대기 종료, RPC 연결·응답 큐·correlation ID·시간 초과·정리 |
22
+ | [Exchange](../../../src/Exchange.py) | exchange·routing key별 발행과 RPC |
23
+ | [Stream](../../../src/Stream.py) | 발행·offset 읽기, 반복 읽기의 ack/nack·소비 취소·정리 |
24
+ | [Event](../../../src/Event.py) | ack/nack/reject 요청, 브로커 API 호출 완료와 실패 |
25
+
26
+ Connection의 `observe()`에서 해당 클래스가 소유한 I/O 작업의 성공·실패를
27
+ 기록하고 실패는 다시 전파한다. Consumer→Event 정산, Connection→Queue RPC 등
28
+ 위임 경계에서는 같은 오류를 반복 기록하지 않도록 책임을 나눴다.
29
+ Worker가 처리하는 사용자 작업 예외를 어댑터에서 다시 traceback으로 기록하지 않는다.
30
+
31
+ ## 3. 레벨과 의미 구분
32
+
33
+ - INFO: 연결·Consumer 생명주기, 자원 변경 성공.
34
+ - DEBUG: 메시지 발행·수신·정산, 설정의 안전한 항목, 정상 대기 종료·재큐잉.
35
+ - WARNING: RPC 발행 전 시간 초과, 발행 후 응답 시간 초과, 원격 작업 오류,
36
+ 응답 라우팅 불가.
37
+ - ERROR: 연결·채널·디코딩·발행·정산·응답 형식 등 담당 경계의 내부 실패.
38
+
39
+ 발행 후 RPC 응답 시간 초과는 이미 전달한 작업의 취소를 의미하지 않는다.
40
+ 응답 라우팅 불가 이후 요청을 정산하는 기존 동작도 유지했다.
41
+ 정산 완료 로그는 브로커 API 호출 반환을 뜻하며 영속화나 후속 소비 완료를 보장하지 않는다.
42
+ 빈 큐의 반복 조회는 매번 기록하지 않고 정상 `pop()` 대기 종료는 DEBUG로 처리한다.
43
+
44
+ ## 4. 출력·보안·샘플
45
+
46
+ - 라이브러리는 핸들러·NullHandler·포매터·필터·레벨을 설정하지 않고 기본 전파를 유지한다.
47
+ - 영어 메시지에 큐·exchange·routing key·message ID·correlation ID·delivery tag 등
48
+ 필요한 메타데이터만 기록한다.
49
+ - 본문·결과·헤더 전체·인증정보·설정 객체 전체·예외 문자열·traceback은 기록하지 않는다.
50
+ - [샘플](../../../sample)은 `Sample`과 `DefStream.Broker.Implements.RabbitMQ` 계층만
51
+ 출력하도록 진입점에서 핸들러를 구성한다. 단순 import로 루트 설정을 바꾸지 않는다.
52
+ - 공개 송수신 API, publisher confirm, mandatory, RPC 제한 시간·정리와
53
+ ack/nack/reject 정책을 유지했다. 자동 재연결·재시도 API는 추가하지 않았다.
54
+
55
+ ## 5. 검증
56
+
57
+ Python 3.13.16과 실제 RabbitMQ에서 관련 테스트 **52개가 건너뜀 없이 통과**했다.
58
+ [로깅 테스트](../../../test/test_logging.py) 14개는 다음을 검증한다.
59
+
60
+ - 클래스 이름·상속, 상위 계층 선택 수신·루트 전파와 라이브러리 설정 비개입.
61
+ - 모든 발행 클래스의 메타데이터·실패와 본문·헤더·인증정보 제외.
62
+ - 연결·자원·confirm·RPC 위임, 단건 대기 종료와 DEBUG 비활성.
63
+ - Consumer 실패 기록 책임, 응답 라우팅 불가 후 정산, Event 실패의 중복 기록 방지.
64
+ - RPC 성공·불일치 응답·원격 오류·형식 오류·전송 실패·발행 전후 시간 초과.
65
+ - Stream ack/nack·취소 및 실패 시 잘못된 성공 로그 방지.
66
+ - 샘플 import 비개입과 계층 경계 필터.
67
+
68
+ 기존 브로커·Worker·RPC·우선순위·실서버 통합 테스트도 함께 실행했다.
69
+ RPC 샘플도 실제 브로커로 실행했다. 영어 전환 후 소스·샘플 `compileall`과
70
+ `git diff --check`를 통과했다. 전체 정적 타입 검사와 다른 Python 버전 검증을
71
+ 완료한 것은 아니다.
72
+
73
+ ### 재검증
74
+
75
+ 개발 가상환경과 로컬 테스트 브로커를 준비한 작업공간 루트에서 실행한다.
76
+ 통합 테스트가 자원을 생성·정리하므로 운영 브로커를 사용하지 않는다.
77
+
78
+ ```powershell
79
+ $env:PYTHONIOENCODING = 'utf-8'
80
+ $env:DEFSTREAM_RABBITMQ_TESTS = '1'
81
+ Set-Location .\DefStream-RabbitMQ\test
82
+ & ..\..\.venv\Scripts\python.exe -m unittest test_logging test_broker_methods test_rabbitmq_worker test_rpc test_rabbitmq_integration test_rpc_integration test_priorities
83
+ ```
@@ -0,0 +1,43 @@
1
+ # 로깅 지원
2
+
3
+ ## 변경 요약
4
+
5
+ RabbitMQ의 연결·자원 관리·발행·소비·RPC·정산을 클래스별 표준 로거로
6
+ 추적할 수 있습니다. 런타임 메시지는 영어이며 출력 정책은 애플리케이션이 정합니다.
7
+
8
+ ## 로거 이름
9
+
10
+ 공통 접두사는 `DefStream.Broker.Implements.RabbitMQ`입니다.
11
+ 다음 여섯 클래스가 각자의 클래스 멤버 `logger`를 사용합니다.
12
+
13
+ - `Connection`
14
+ - `Consumer`
15
+ - `Queue`
16
+ - `Exchange`
17
+ - `Stream`
18
+ - `Event`
19
+
20
+ 예를 들어 `DefStream.Broker.Implements.RabbitMQ.Consumer`만 선택하거나
21
+ RabbitMQ·Broker·DefStream 상위 계층에서 함께 수신할 수 있습니다.
22
+ 기존 Consumer 모듈 경로 기반 필터는 새 이름에 맞춰 갱신하세요.
23
+
24
+ ## 레벨과 주의사항
25
+
26
+ - INFO: 연결·소비 생명주기와 자원 변경.
27
+ - DEBUG: 메시지별 발행·수신·RPC·정산과 정상 대기 종료.
28
+ - WARNING: RPC 시간 초과·원격 오류·응답 라우팅 불가.
29
+ - ERROR: 연결·전송·디코딩·정산 등 내부 실패.
30
+
31
+ 발행 후 응답 시간 초과는 작업 취소를 뜻하지 않습니다.
32
+ 발행·정산 API 호출 완료를 후속 소비나 영속화 보장으로 해석하지 마세요.
33
+ 본문·결과·헤더·인증정보·예외 문자열·traceback은 어댑터 로그에서 제외합니다.
34
+ 예외는 기존대로 전파되므로 애플리케이션에서 같은 오류를 재기록하면 중복될 수 있습니다.
35
+
36
+ ## 사용자 설정과 샘플
37
+
38
+ 라이브러리는 핸들러·NullHandler·레벨을 자동 설정하지 않습니다.
39
+ 설정이 없으면 표준 `logging.lastResort` 동작을 유지합니다.
40
+ [샘플](../../../sample)은 `print()` 대신 `Sample` 로거를 사용하며
41
+ `Sample`과 RabbitMQ 계층만 출력합니다.
42
+ 실제 설정은 [사용 설명서](../../../README.md#로깅)를 참고하세요.
43
+ 기존 공개 API와 메시지 정산·RPC 동작은 유지됩니다.
@@ -0,0 +1,122 @@
1
+ # 로깅 지원
2
+
3
+ ## 1. 목적과 범위
4
+
5
+ - RabbitMQ 연결, 자원 선언·바인딩, 발행·수신, RPC, 메시지 확인 처리의 흐름을 풍부하게 관찰할 수 있도록 한다.
6
+ - Python 표준 `logging`을 사용하며 출력 대상·형식·레벨·필터는 사용자 애플리케이션이 결정한다.
7
+ - 로깅 대상은 Connection·Consumer·Queue·Exchange·Stream·Event 여섯 클래스로 한정한다.
8
+ - 이 요구사항에 따라 소스와 샘플의 로깅을 구현하며, 기존 공개 API의 메시지 처리 계약을 유지한다.
9
+ - 코어 Worker·Inspector의 기록 책임은 [DefStream 로깅 지원](../../../../DefStream/issues/feature/8/REQUIREMENTS.md)을 따른다.
10
+
11
+ ## 2. 로거 이름과 사용자 설정
12
+
13
+ - 로거는 모듈 경로나 사용자 하위 클래스에서 자동 생성하지 않고 클래스별로 명시적 이름을 지정한다.
14
+ - 이름의 공통 형식은 `DefStream.Broker.Implements.RabbitMQ.ClassName`이다.
15
+ - DefStream과 동일하게 로거를 클래스 멤버로 보관한다. 사용자 하위 클래스는 기반 이름을 상속하며 필요하면 로거 멤버를 명시적으로 재정의할 수 있다.
16
+ - 사용자 애플리케이션은 `DefStream`, `DefStream.Broker`, `DefStream.Broker.Implements.RabbitMQ` 또는 클래스별 로거에서 선택적으로 수신할 수 있어야 한다.
17
+ - 라이브러리는 `basicConfig()`, 출력 핸들러·포매터·필터, 로그 레벨을 임의로 설정하거나 기존 설정을 제거하지 않는다. 루트까지의 기본 전파도 막지 않는다.
18
+ - 코어와 동일하게 출력 핸들러와 `NullHandler`를 추가하지 않는다. 미설정 시 Python의 `logging.lastResort` 기본 동작을 유지한다.
19
+ - 샘플은 `Sample` 로거를 사용하고 출력 핸들러를 직접 설정한다. 수신 범위는 `Sample`과 `DefStream.Broker.Implements.RabbitMQ` 계층이며, 샘플의 `print()`는 DEBUG·INFO 로그로 대체한다.
20
+
21
+ ## 3. 현재 상태
22
+
23
+ - [Consumer.respond()](../../../src/Consumer.py)는 RPC 응답의 `UnroutableError`를 WARNING으로 기록한 뒤 요청 메시지 정산을 계속한다.
24
+ - 현재 로거는 클래스별 고정 이름이 아니라 Consumer 모듈의 `getLogger(__name__)`이다.
25
+ - 나머지 클래스에는 직접적인 로깅 호출이 없다.
26
+ - Worker가 처리하는 작업 실패와 RabbitMQ I/O 실패는 구분한다. 같은 작업 예외를 어댑터에서 반복 ERROR로 기록하지 않는다.
27
+
28
+ ## 4. 클래스별 로거 이름
29
+
30
+ 다음 여섯 클래스만 독립 로거를 갖는다.
31
+
32
+ | 구분 | 클래스와 소스 | 로거 이름 | 필요한 관찰 범위 |
33
+ | --- | --- | --- | --- |
34
+ | 우선 대상 | [Connection](../../../src/Connection.py) | `DefStream.Broker.Implements.RabbitMQ.Connection` | 연결·종료, 선언·삭제·바인딩, publisher 생성, 직접 발행·RPC 위임 |
35
+ | 우선 대상 | [Consumer](../../../src/Consumer.py) | `DefStream.Broker.Implements.RabbitMQ.Consumer` | 구독·QoS·offset, 수신 루프, 콜백 예약, 완료·실패 정책, RPC 응답 |
36
+ | 우선 대상 | [Queue](../../../src/Queue.py) | `DefStream.Broker.Implements.RabbitMQ.Queue` | 발행, 단건 수신·대기, 전용 연결을 사용하는 RPC |
37
+ | 우선 대상 | [Exchange](../../../src/Exchange.py) | `DefStream.Broker.Implements.RabbitMQ.Exchange` | routing key 기반 발행과 RPC |
38
+ | 우선 대상 | [Stream](../../../src/Stream.py) | `DefStream.Broker.Implements.RabbitMQ.Stream` | offset 기반 읽기, 발행, 반복 읽기의 확인·재큐잉·정리 |
39
+ | 우선 대상 | [Event](../../../src/Event.py) | `DefStream.Broker.Implements.RabbitMQ.Event` | 개별 메시지의 ack/nack/reject 요청·완료 |
40
+
41
+ ### 4.1. 독립 로거를 추가하지 않을 대상
42
+
43
+ | 대상 | 판단 근거와 기록 책임 |
44
+ | --- | --- |
45
+ | [Callback·FailedRequest](../../../src/Consumer.py) | 독립 로거를 추가하지 않는다. 필요한 수신·실패 응답 문맥은 Consumer 로거에 귀속하고 실제 정산은 Event에서 기록한다. |
46
+ | [JavaScriptObjectNotationEncoder·JavaScriptObjectNotationDecoder](../../../src/Serializer.py) | 독립 로깅에서 제외한다. 직렬화·역직렬화 실패는 송수신 호출 경계에서 관찰한다. |
47
+ | [Configuration](../../../src/Configuration.py) | 설정·TLS 옵션 보관 객체이다. Connection에서 허용한 항목만 요약하며 설정 객체 전체를 출력하지 않는다. |
48
+ | [Subscription](../../../src/Subscription.py) | 파싱·검증 데이터 클래스이다. 검증 결과와 적용 설정은 Connection·Consumer에서 기록한다. |
49
+ | [ExchangeType·Parameters·All·Any](../../../src/Connection.py) | 열거형과 바인딩 인자 객체이다. 실제 자원 변경은 Connection에서 기록한다. |
50
+ | [Encoder·Decoder](../../../src/Serializer.py), [EventHandler](../../../src/Event.py) | 사용자 구현용 추상 계약이다. 구체 구현 또는 호출 경계의 로그로 관찰한다. |
51
+ | [Policies](../../../src/Policies.py)의 Requeue·Reject | 코어 정책을 재노출하며 RabbitMQ 전용 구현 클래스가 아니다. 정책 선택은 Consumer, 실제 처리는 Event에서 기록한다. |
52
+
53
+ - 보조 클래스에서 필요한 사건을 기록하더라도 Consumer 로거를 사용하며 새로운 이름을 만들지 않는다.
54
+
55
+ ## 5. 레벨별 기록 요구사항
56
+
57
+ ### 5.1. Connection
58
+
59
+ - INFO: 연결 시도·성공·종료, 자원 선언·삭제·바인딩·해제의 성공.
60
+ - DEBUG: 이미 열린 연결의 재사용, publisher 채널 생성·재사용, QoS 등 객체 생성 인자 중 안전한 항목, 선언 옵션의 허용 목록.
61
+ - DEBUG: 직접 `emit()`한 작업의 발행 시작·완료, 대상 큐·message ID·priority, `request()`의 Queue 위임 경계.
62
+ - ERROR: 연결·채널·자원 변경·발행 실패 중 어댑터가 최종 기록 책임을 갖는 경계. 예외는 기존대로 호출자에게 전파한다.
63
+ - `emit()`의 publisher confirm 사용 여부를 다른 발행 API와 구분하여 기록한다.
64
+
65
+ ### 5.2. Consumer
66
+
67
+ - INFO: 구독 적용, 수신 루프 시작·중지·채널 종료.
68
+ - DEBUG: 큐·consumer tag·delivery tag, 적용 QoS·offset, 수신·디코딩·핸들러 전달, 연결 소유 스레드 콜백 예약.
69
+ - DEBUG: 완료·실패 정책 선택, RPC 성공·실패 응답 시도, 응답 채널 생성·재사용, correlation ID.
70
+ - WARNING: 라우팅 불가능한 RPC 응답. 기존처럼 요청을 정산하는 동작과 응답 전달 실패를 명확히 구분한다.
71
+ - ERROR: 수신 루프·채널·콜백 예약·디코딩·응답 발행의 내부 실패 중 해당 경계가 담당하는 오류.
72
+ - FailedRequest는 오류 응답이 Consumer에서 생성되고 실제 정산은 Event에서 수행되는 흐름을 구분한다. 같은 결과를 세 클래스에서 반복 출력하지 않는다.
73
+ - Worker가 처리한 사용자 작업 예외는 Consumer에서 다시 ERROR·traceback으로 출력하지 않는다.
74
+
75
+ ### 5.3. Queue·Exchange
76
+
77
+ - DEBUG: 발행 시작·완료, 큐 또는 exchange·routing key, message ID, priority·지속성 옵션.
78
+ - DEBUG: Queue의 단건 수신 시작·성공·대기 종료. 빈 큐의 매 조회를 출력하지 않는다.
79
+ - DEBUG: RPC 전용 연결·응답 큐 생성·정리, 요청 발행, correlation ID, 응답 수신·검증, 소요 시간.
80
+ - DEBUG: correlation ID가 일치하지 않아 무시한 응답. 응답 본문은 출력하지 않는다.
81
+ - WARNING: RPC 시간 초과와 원격 작업 오류. 발행 전 시간 초과와 발행 후 응답 시간 초과를 구분하며 이미 전달된 작업이 취소된 것으로 표현하지 않는다.
82
+ - ERROR: RPC 응답 형식 오류, 전송·연결·역직렬화 실패 중 이 경계가 최종 기록하는 오류.
83
+ - 정상적인 `pop()` 대기 종료는 DEBUG이며 WARNING으로 처리하지 않는다.
84
+ - `send()` 호출 반환만으로 publisher confirm 또는 소비자 처리가 완료됐다고 기록하지 않는다.
85
+
86
+ ### 5.4. Stream·Event
87
+
88
+ - DEBUG: Stream 발행, 읽기 시작·offset·대기 조건, 수신 메타데이터, 반복 읽기 종료와 Consumer 취소.
89
+ - DEBUG: Event의 ack/nack/reject 요청과 브로커 API 호출 완료. 큐·delivery tag·안전한 메시지 식별자를 함께 남긴다.
90
+ - DEBUG: Stream 읽기 루프에서 직접 수행하는 ack/nack도 Stream 로거에서 관찰 가능해야 한다.
91
+ - WARNING: Stream 처리 예외로 재큐잉하는 사건은 원인 로그와 중복되지 않게 기록한다. 정상 재큐잉 정책의 모든 호출을 경고로 취급하지 않는다.
92
+ - ERROR: 확인 처리·재큐잉·취소·채널 정리의 실패. 실패했는데 성공 로그를 먼저 남기지 않는다.
93
+ - 로깅을 추가하면서 Stream의 기존 자동 ack/nack 동작이나 Event 확인 처리 횟수를 바꾸지 않는다.
94
+
95
+ ## 6. 기록 품질과 호환성
96
+
97
+ - 공개 라이브러리와 샘플의 런타임 로그 메시지는 영어로 작성한다. 한국어 문서·주석은 유지하고 클래스·API·메시지 식별자는 원문을 유지한다.
98
+ - 사용자 인증정보, 전체 ConnectionParameters·Configuration, 연결 URI의 자격 증명, 메시지 본문·결과, 헤더 전체를 기록하지 않는다.
99
+ - Event의 `repr()`에는 본문과 헤더가 포함되므로 로그 인자로 그대로 사용하지 않는다.
100
+ - 허용 문맥은 사건·단계, 안전한 접속 주소·vhost, 큐·exchange·routing key, 메시지·correlation·delivery 식별자, QoS·offset·priority 등으로 제한한다.
101
+ - 예외 문자열에도 접속 정보나 메시지 값이 들어갈 수 있으므로 traceback의 민감정보 노출을 검토한다.
102
+ - 어댑터 내 동일 예외의 ERROR·traceback은 한 경계에서 기록한다. Connection→Queue RPC 위임과 Consumer→Event 정산에서 중복을 피한다.
103
+ - DEBUG 비활성 시 로그용 추가 I/O·직렬화·헤더 순회를 하지 않고 지연 메시지 치환을 활용한다.
104
+ - 기존 예외 전파, 연결·채널 소유권, RPC 제한 시간, 라우팅 불가 응답 처리, ack/nack/reject 정책을 보존한다.
105
+ - 자동 재연결·재시도·새 핸들러 주입 API는 이번 로깅 요구사항에 포함하지 않는다.
106
+
107
+ ## 7. 확정 사항과 구현 원칙
108
+
109
+ 1. 독립 로깅 대상과 이름은 4장의 여섯 클래스로 한정하고 로거는 클래스 멤버로 보관한다.
110
+ 2. 핸들러 설정은 사용자 책임이며 라이브러리는 출력 핸들러·NullHandler를 추가하지 않는다.
111
+ 3. 연결·생명주기·자원 변경은 INFO, 메시지별 정상 흐름은 DEBUG, 예상 가능한 RPC 이상은 WARNING, 내부 장애는 ERROR로 구분한다.
112
+ 4. 반복 호출의 출력량과 상세 문맥 필드는 5·6장의 원칙에 따라 구현 시 구체화한다. 별도 설정 API를 미리 추가하지 않는다.
113
+ 5. 사용자 애플리케이션이 상위 경계에서도 같은 예외를 기록할 수 있다는 점을 안내한다. 사용자의 로깅을 억제하거나 예외 전파를 변경하지 않는다.
114
+
115
+ ## 8. 구현 후 수용 기준
116
+
117
+ - 확정한 클래스별 로거와 상위 RabbitMQ·Broker·DefStream 로거에서 선택 수신 및 루트 전파가 가능하다.
118
+ - 연결·발행·구독·단건 수신·Stream 읽기·RPC·정산의 정상·실패 로그를 검증한다.
119
+ - RPC 발행 전·후 시간 초과, 원격 오류, 응답 라우팅 불가, 정산 실패의 레벨과 문맥이 구분된다.
120
+ - DEBUG 비활성 시 메시지별 추적이 출력되지 않고 빈 큐·정상 대기·재큐잉으로 경고가 반복되지 않는다.
121
+ - 본문·자격 증명·헤더가 노출되지 않고, 동일 실패의 traceback이 어댑터 내부에서 중복되지 않는다.
122
+ - 기존 브로커·Worker 연동·RPC·통합 테스트가 보장하는 예외와 메시지 처리 동작을 유지한다.
@@ -1,5 +1,11 @@
1
1
  from concurrent.futures import ThreadPoolExecutor
2
- from sys import stderr
2
+ from logging import (
3
+ DEBUG,
4
+ Filter,
5
+ Formatter,
6
+ StreamHandler,
7
+ getLogger,
8
+ )
3
9
  from threading import Event as PyEvent
4
10
  from uuid import uuid4
5
11
 
@@ -14,6 +20,8 @@ from DefStream.Broker.Implements.RabbitMQ import (
14
20
  Reject,
15
21
  )
16
22
 
23
+ logger = getLogger('Sample')
24
+
17
25
 
18
26
  class Calculate(EventHandler):
19
27
  def __init__(
@@ -21,6 +29,7 @@ class Calculate(EventHandler):
21
29
  consumer: Consumer,
22
30
  ):
23
31
  self.consumer = consumer
32
+ return
24
33
 
25
34
  def __call__(
26
35
  self,
@@ -38,6 +47,7 @@ class Calculate(EventHandler):
38
47
  event,
39
48
  result,
40
49
  )
50
+ return
41
51
 
42
52
 
43
53
  def serve(
@@ -65,6 +75,7 @@ def serve(
65
75
  0.1,
66
76
  check_stop,
67
77
  )
78
+ return
68
79
 
69
80
  broker.connection.call_later(
70
81
  0.1,
@@ -76,9 +87,20 @@ def serve(
76
87
  finally:
77
88
  broker.close()
78
89
  ready.set()
90
+ return
79
91
 
80
92
 
81
93
  if __name__ == '__main__':
94
+ root = getLogger()
95
+ root.setLevel(DEBUG)
96
+ console = StreamHandler()
97
+ console.setLevel(DEBUG)
98
+ sample_filter = Filter('Sample')
99
+ rabbitmq_filter = Filter('DefStream.Broker.Implements.RabbitMQ')
100
+ console.addFilter(lambda record: sample_filter.filter(record) or rabbitmq_filter.filter(record))
101
+ console.setFormatter(Formatter('%(asctime)s %(levelname)s %(name)s %(message)s'))
102
+ root.addHandler(console)
103
+ logger.info('Starting RabbitMQ RPC sample')
82
104
  configuration = Configuration(
83
105
  host='127.0.0.1',
84
106
  port=5672,
@@ -130,7 +152,7 @@ if __name__ == '__main__':
130
152
  },
131
153
  timeout=5,
132
154
  )
133
- print(f'Queue RPC: 20 / 4 = {result}')
155
+ logger.info('Queue RPC calculation completed')
134
156
  result = broker.exchange(name).call(
135
157
  {
136
158
  'a': 30,
@@ -139,7 +161,7 @@ if __name__ == '__main__':
139
161
  timeout=5,
140
162
  event='divide',
141
163
  )
142
- print(f'Exchange RPC: 30 / 5 = {result}')
164
+ logger.info('Exchange RPC calculation completed')
143
165
  try:
144
166
  broker.queue(name).call(
145
167
  {
@@ -148,11 +170,8 @@ if __name__ == '__main__':
148
170
  },
149
171
  timeout=5,
150
172
  )
151
- except RemoteError as error:
152
- print(
153
- f'RPC rejected: {error}',
154
- file=stderr,
155
- )
173
+ except RemoteError:
174
+ logger.warning('RPC remote calculation rejection confirmed')
156
175
  finally:
157
176
  stopping.set()
158
177
  server.result(timeout=10)
@@ -166,3 +185,4 @@ if __name__ == '__main__':
166
185
  broker.delete_exchange(name)
167
186
  finally:
168
187
  broker.close()
188
+ logger.info('RabbitMQ RPC sample finished')
@@ -8,8 +8,27 @@ from DefStream.Broker.Implements.RabbitMQ import (
8
8
  )
9
9
  from threading import Timer
10
10
  from random import randint
11
+ from logging import (
12
+ DEBUG,
13
+ Filter,
14
+ Formatter,
15
+ StreamHandler,
16
+ getLogger,
17
+ )
18
+
19
+ logger = getLogger('Sample')
11
20
 
12
21
  if __name__ == '__main__':
22
+ root = getLogger()
23
+ root.setLevel(DEBUG)
24
+ console = StreamHandler()
25
+ console.setLevel(DEBUG)
26
+ sample_filter = Filter('Sample')
27
+ rabbitmq_filter = Filter('DefStream.Broker.Implements.RabbitMQ')
28
+ console.addFilter(lambda record: sample_filter.filter(record) or rabbitmq_filter.filter(record))
29
+ console.setFormatter(Formatter('%(asctime)s %(levelname)s %(name)s %(message)s'))
30
+ root.addHandler(console)
31
+ logger.info('Starting RabbitMQ Stream sample')
13
32
 
14
33
  con = RabbitConnection(
15
34
  Configuration(
@@ -39,7 +58,7 @@ if __name__ == '__main__':
39
58
  event: Event,
40
59
  ):
41
60
  try:
42
- print(event.body)
61
+ logger.debug('Processing Stream message: message_id=%s', event.id)
43
62
  event.ack()
44
63
  except RuntimeError:
45
64
  event.nack() # if you want requeue message
@@ -51,8 +70,7 @@ if __name__ == '__main__':
51
70
  2,
52
71
  5,
53
72
  )):
54
- print('Consuming Events from Stream Queue: {}'.format(i + 1))
55
- print('-' * 20)
73
+ logger.info('Starting Stream subscription: iteration=%s', i + 1)
56
74
  consumer = con.consumer(
57
75
  handler=SampleEventHandler(),
58
76
  qos=1,
@@ -71,14 +89,14 @@ if __name__ == '__main__':
71
89
  consumer.subs('stream')
72
90
  consumer.run()
73
91
 
74
- print('Read Events from Stream Queue:')
75
- print('-' * 20)
92
+ logger.info('Starting Stream read loop')
76
93
  stream = con.stream('stream')
77
94
  try:
78
95
  for event in stream.read(timeout=1000):
79
- print(event.body)
96
+ logger.debug('Reading Stream message: message_id=%s', event.id)
80
97
  except KeyboardInterrupt:
81
98
  pass
82
99
 
83
100
  con.delete_stream('stream')
84
101
  con.close()
102
+ logger.info('RabbitMQ Stream sample finished')
@@ -8,8 +8,27 @@ from DefStream.Broker.Implements.RabbitMQ import (
8
8
  EventHandler,
9
9
  )
10
10
  from threading import Timer
11
+ from logging import (
12
+ DEBUG,
13
+ Filter,
14
+ Formatter,
15
+ StreamHandler,
16
+ getLogger,
17
+ )
18
+
19
+ logger = getLogger('Sample')
11
20
 
12
21
  if __name__ == '__main__':
22
+ root = getLogger()
23
+ root.setLevel(DEBUG)
24
+ console = StreamHandler()
25
+ console.setLevel(DEBUG)
26
+ sample_filter = Filter('Sample')
27
+ rabbitmq_filter = Filter('DefStream.Broker.Implements.RabbitMQ')
28
+ console.addFilter(lambda record: sample_filter.filter(record) or rabbitmq_filter.filter(record))
29
+ console.setFormatter(Formatter('%(asctime)s %(levelname)s %(name)s %(message)s'))
30
+ root.addHandler(console)
31
+ logger.info('Starting RabbitMQ queue and exchange sample')
13
32
 
14
33
  con = RabbitConnection(
15
34
  Configuration(
@@ -54,10 +73,10 @@ if __name__ == '__main__':
54
73
 
55
74
  reader = con.queue('queue')
56
75
  e = reader.pop()
57
- print(e)
76
+ logger.debug('Single message received: queue=%s message_id=%s', e.src, e.id)
58
77
  e.ack()
59
78
  e = reader.pop()
60
- print(e)
79
+ logger.debug('Single message received: queue=%s message_id=%s', e.src, e.id)
61
80
  e.ack()
62
81
 
63
82
  exchange.send(
@@ -97,8 +116,7 @@ if __name__ == '__main__':
97
116
  event: Event,
98
117
  ):
99
118
  try:
100
- print(event.body)
101
- print(event.priority)
119
+ logger.debug('Processing message: message_id=%s priority=%s', event.id, event.priority)
102
120
  event.ack()
103
121
  except RuntimeError:
104
122
  event.nack() # if you want requeue message
@@ -125,3 +143,4 @@ if __name__ == '__main__':
125
143
  con.delete_queue('queue')
126
144
  con.delete_exchange('topic')
127
145
  con.close()
146
+ logger.info('RabbitMQ queue and exchange sample finished')
@@ -50,7 +50,7 @@ setup(
50
50
  package_dir=PACKAGE_DIR,
51
51
  include_package_data=False,
52
52
  install_requires=[
53
- 'DefStream>=0.1.7',
53
+ 'DefStream>=0.1.9',
54
54
  'pika>=1.3.2',
55
55
  ],
56
56
  classifiers=[