|
| 1 | +from __future__ import annotations |
| 2 | + |
| 3 | +import ctypes |
| 4 | +import sys |
| 5 | +import uuid |
| 6 | +<<<<<<< HEAD |
| 7 | +======= |
| 8 | +from typing import TYPE_CHECKING |
| 9 | +>>>>>>> 714eda9 (service: Enable type checking for tracelogging (#1123)) |
| 10 | + |
| 11 | +if sys.platform == "win32": |
| 12 | + try: |
| 13 | + import traceloggingdynamic |
| 14 | + |
| 15 | + _event_provider: traceloggingdynamic.Provider | None = traceloggingdynamic.Provider( |
| 16 | + b"NI-Measurement-Plug-In-Python" |
| 17 | + ) |
| 18 | + except ImportError: |
| 19 | + _event_provider = None |
| 20 | +else: |
| 21 | + if TYPE_CHECKING: |
| 22 | + import traceloggingdynamic |
| 23 | + |
| 24 | + _event_provider = None |
| 25 | + |
| 26 | +_LEVEL_LOG_ALWAYS = 0 |
| 27 | +_LEVEL_CRITICAL = 1 |
| 28 | +_LEVEL_ERROR = 3 |
| 29 | +_LEVEL_WARNING = 3 |
| 30 | +_LEVEL_INFO = 4 |
| 31 | +_LEVEL_VERBOSE = 5 |
| 32 | + |
| 33 | +_OPCODE_INFO = 0 |
| 34 | +_OPCODE_START = 1 |
| 35 | +_OPCODE_STOP = 2 |
| 36 | + |
| 37 | +_KEYWORD_NONE = 0 |
| 38 | +_KEYWORD_GRPC = 1 << 0 |
| 39 | + |
| 40 | +_TASK_GRPC_CLIENT_CALL = 1 |
| 41 | +_TASK_GRPC_SERVER_CALL = 2 |
| 42 | + |
| 43 | + |
| 44 | +if sys.platform == "win32": |
| 45 | + # 0x00000800 = LOAD_LIBRARY_SEARCH_SYSTEM32 (Win8 or later) |
| 46 | + _eventing_dll = ctypes.WinDLL("api-ms-win-eventing-provider-l1-1-0.dll", mode=0x00000800) |
| 47 | + |
| 48 | + _EventActivityIdControl = _eventing_dll.EventActivityIdControl |
| 49 | + _EventActivityIdControl.restype = ctypes.c_uint32 |
| 50 | + _EventActivityIdControl.argtypes = (ctypes.c_uint32, ctypes.c_void_p) |
| 51 | + |
| 52 | + _EVENT_ACTIVITY_CTRL_GET_ID = 1 |
| 53 | + _EVENT_ACTIVITY_CTRL_SET_ID = 2 |
| 54 | + _EVENT_ACTIVITY_CTRL_CREATE_ID = 3 |
| 55 | + _EVENT_ACTIVITY_CTRL_GET_SET_ID = 4 |
| 56 | + _EVENT_ACTIVITY_CTRL_CREATE_SET_ID = 5 |
| 57 | + |
| 58 | + def _create_activity_id() -> uuid.UUID: |
| 59 | + activity_bytes = (ctypes.c_byte * 16)() |
| 60 | + status = _EventActivityIdControl( |
| 61 | + _EVENT_ACTIVITY_CTRL_CREATE_ID, ctypes.pointer(activity_bytes) |
| 62 | + ) |
| 63 | + if status != 0: |
| 64 | + raise OSError("EventActivityIdControl error", status) |
| 65 | + return uuid.UUID(bytes_le=bytes(activity_bytes)) |
| 66 | + |
| 67 | + def _get_current_thread_activity_id() -> uuid.UUID: |
| 68 | + activity_bytes = (ctypes.c_byte * 16)() |
| 69 | + status = _EventActivityIdControl( |
| 70 | + _EVENT_ACTIVITY_CTRL_GET_ID, ctypes.pointer(activity_bytes) |
| 71 | + ) |
| 72 | + if status != 0: |
| 73 | + raise OSError("EventActivityIdControl error", status) |
| 74 | + return uuid.UUID(bytes_le=bytes(activity_bytes)) |
| 75 | + |
| 76 | +else: |
| 77 | + |
| 78 | + def _create_activity_id() -> uuid.UUID: |
| 79 | + return uuid.uuid4() |
| 80 | + |
| 81 | + def _get_current_thread_activity_id() -> uuid.UUID: |
| 82 | + return uuid.UUID() |
| 83 | + |
| 84 | + |
| 85 | +def is_enabled() -> bool: |
| 86 | + """Queries whether the event provider is enabled.""" |
| 87 | + return _event_provider is not None and _event_provider.is_enabled() |
| 88 | + |
| 89 | + |
| 90 | +def log_grpc_client_call_start(method_name: str) -> uuid.UUID | None: |
| 91 | + """Log when starting a gRPC client call.""" |
| 92 | + if _event_provider and _event_provider.is_enabled(level=_LEVEL_INFO, keyword=_KEYWORD_GRPC): |
| 93 | + eb = traceloggingdynamic.EventBuilder() |
| 94 | + eb.reset( |
| 95 | + b"GrpcClientCall", |
| 96 | + level=_LEVEL_INFO, |
| 97 | + keyword=_KEYWORD_GRPC, |
| 98 | + opcode=_OPCODE_START, |
| 99 | + task=_TASK_GRPC_CLIENT_CALL, |
| 100 | + ) |
| 101 | + eb.add_str8(b"FormattedMessage", "gRPC client call starting: " + method_name) |
| 102 | + activity_id = _create_activity_id() |
| 103 | + related_activity_id = _get_current_thread_activity_id() |
| 104 | + _event_provider.write(eb, activity_id, related_activity_id) |
| 105 | + return activity_id |
| 106 | + else: |
| 107 | + return None |
| 108 | + |
| 109 | + |
| 110 | +def log_grpc_client_call_stop(method_name: str, activity_id: uuid.UUID | None = None) -> None: |
| 111 | + """Log when a gRPC client call has completed.""" |
| 112 | + if _event_provider and _event_provider.is_enabled(level=_LEVEL_INFO, keyword=_KEYWORD_GRPC): |
| 113 | + eb = traceloggingdynamic.EventBuilder() |
| 114 | + eb.reset( |
| 115 | + b"GrpcClientCall", |
| 116 | + level=_LEVEL_INFO, |
| 117 | + keyword=_KEYWORD_GRPC, |
| 118 | + opcode=_OPCODE_STOP, |
| 119 | + task=_TASK_GRPC_CLIENT_CALL, |
| 120 | + ) |
| 121 | + eb.add_str8(b"FormattedMessage", "gRPC client call complete: " + method_name) |
| 122 | + _event_provider.write(eb, activity_id) |
| 123 | + |
| 124 | + |
| 125 | +def log_grpc_client_call_streaming_request(method_name: str) -> None: |
| 126 | + """Log when a gRPC client call is sending a client-streaming request.""" |
| 127 | + if _event_provider and _event_provider.is_enabled(level=_LEVEL_INFO, keyword=_KEYWORD_GRPC): |
| 128 | + eb = traceloggingdynamic.EventBuilder() |
| 129 | + eb.reset( |
| 130 | + b"GrpcClientCallStreamingRequest", |
| 131 | + level=_LEVEL_INFO, |
| 132 | + keyword=_KEYWORD_GRPC, |
| 133 | + opcode=_OPCODE_INFO, |
| 134 | + ) |
| 135 | + eb.add_str8(b"FormattedMessage", "gRPC client call streaming request: " + method_name) |
| 136 | + _event_provider.write(eb) |
| 137 | + |
| 138 | + |
| 139 | +def log_grpc_client_call_streaming_response(method_name: str) -> None: |
| 140 | + """Log when a gRPC client call has received a server-streaming response.""" |
| 141 | + if _event_provider and _event_provider.is_enabled(level=_LEVEL_INFO, keyword=_KEYWORD_GRPC): |
| 142 | + eb = traceloggingdynamic.EventBuilder() |
| 143 | + eb.reset( |
| 144 | + b"GrpcClientCallStreamingResponse", |
| 145 | + level=_LEVEL_INFO, |
| 146 | + keyword=_KEYWORD_GRPC, |
| 147 | + opcode=_OPCODE_INFO, |
| 148 | + ) |
| 149 | + eb.add_str8(b"FormattedMessage", "gRPC client call streaming response: " + method_name) |
| 150 | + _event_provider.write(eb) |
| 151 | + |
| 152 | + |
| 153 | +def log_grpc_server_call_start(method_name: str) -> uuid.UUID | None: |
| 154 | + """Log when starting a gRPC server call.""" |
| 155 | + if _event_provider and _event_provider.is_enabled(level=_LEVEL_INFO, keyword=_KEYWORD_GRPC): |
| 156 | + eb = traceloggingdynamic.EventBuilder() |
| 157 | + eb.reset( |
| 158 | + b"GrpcServerCall", |
| 159 | + level=_LEVEL_INFO, |
| 160 | + keyword=_KEYWORD_GRPC, |
| 161 | + opcode=_OPCODE_START, |
| 162 | + task=_TASK_GRPC_SERVER_CALL, |
| 163 | + ) |
| 164 | + eb.add_str8(b"FormattedMessage", "gRPC server call starting: " + method_name) |
| 165 | + activity_id = _create_activity_id() |
| 166 | + related_activity_id = _get_current_thread_activity_id() |
| 167 | + _event_provider.write(eb, activity_id, related_activity_id) |
| 168 | + return activity_id |
| 169 | + else: |
| 170 | + return None |
| 171 | + |
| 172 | + |
| 173 | +def log_grpc_server_call_stop(method_name: str, activity_id: uuid.UUID | None = None) -> None: |
| 174 | + """Log when a gRPC server call has completed.""" |
| 175 | + if _event_provider and _event_provider.is_enabled(level=_LEVEL_INFO, keyword=_KEYWORD_GRPC): |
| 176 | + eb = traceloggingdynamic.EventBuilder() |
| 177 | + eb.reset( |
| 178 | + b"GrpcServerCall", |
| 179 | + level=_LEVEL_INFO, |
| 180 | + keyword=_KEYWORD_GRPC, |
| 181 | + opcode=_OPCODE_STOP, |
| 182 | + task=_TASK_GRPC_SERVER_CALL, |
| 183 | + ) |
| 184 | + eb.add_str8(b"FormattedMessage", "gRPC server call complete: " + method_name) |
| 185 | + _event_provider.write(eb, activity_id) |
| 186 | + |
| 187 | + |
| 188 | +def log_grpc_server_call_streaming_request(method_name: str) -> None: |
| 189 | + """Log when a gRPC server call is sending a server-streaming request.""" |
| 190 | + if _event_provider and _event_provider.is_enabled(level=_LEVEL_INFO, keyword=_KEYWORD_GRPC): |
| 191 | + eb = traceloggingdynamic.EventBuilder() |
| 192 | + eb.reset( |
| 193 | + b"GrpcServerCallStreamingRequest", |
| 194 | + level=_LEVEL_INFO, |
| 195 | + keyword=_KEYWORD_GRPC, |
| 196 | + opcode=_OPCODE_INFO, |
| 197 | + ) |
| 198 | + eb.add_str8(b"FormattedMessage", "gRPC server call streaming request: " + method_name) |
| 199 | + _event_provider.write(eb) |
| 200 | + |
| 201 | + |
| 202 | +def log_grpc_server_call_streaming_response(method_name: str) -> None: |
| 203 | + """Log when a gRPC server call has received a server-streaming response.""" |
| 204 | + if _event_provider and _event_provider.is_enabled(level=_LEVEL_INFO, keyword=_KEYWORD_GRPC): |
| 205 | + eb = traceloggingdynamic.EventBuilder() |
| 206 | + eb.reset( |
| 207 | + b"GrpcServerCallStreamingResponse", |
| 208 | + level=_LEVEL_INFO, |
| 209 | + keyword=_KEYWORD_GRPC, |
| 210 | + opcode=_OPCODE_INFO, |
| 211 | + ) |
| 212 | + eb.add_str8(b"FormattedMessage", "gRPC server call streaming response: " + method_name) |
| 213 | + _event_provider.write(eb) |
0 commit comments