-
Notifications
You must be signed in to change notification settings - Fork 250
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixed AzureLogHandler with multiple processes. #1158
base: master
Are you sure you want to change the base?
Changes from all commits
b908aed
bfb12b2
7669223
8a0519e
bde45ff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -75,8 +75,7 @@ def __init__(self, **options): | |
def _export(self, batch, event=None): # pragma: NO COVER | ||
try: | ||
if batch: | ||
envelopes = [self.log_record_to_envelope(x) for x in batch] | ||
envelopes = self.apply_telemetry_processors(envelopes) | ||
envelopes = self.apply_telemetry_processors(batch) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't work because There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It does work; the batch is a list of |
||
result = self._transmit(envelopes) | ||
# Only store files if local storage enabled | ||
if self.storage: | ||
|
@@ -110,7 +109,11 @@ def createLock(self): | |
self.lock = None | ||
|
||
def emit(self, record): | ||
self._queue.put(record, block=False) | ||
# Convert the raw LogRecord to an envelope before putting it on the | ||
# queue as a LogRecord object is not serializable, while an Envelope | ||
# object is. | ||
envelope = self.log_record_to_envelope(record) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think there are performance implications of doing this. We don't want to be mapping every time There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is indeed a performance loss here. However it is not possible to put a raw |
||
self._queue.put(envelope, block=False) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why does object need to be serializable? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In order to share messages/resources between different processes, the multiprocessing.Queue pickles the object so that it can be piped: https://github.com/python/cpython/blob/3.10/Lib/multiprocessing/queues.py#L244 |
||
|
||
def log_record_to_envelope(self, record): | ||
raise NotImplementedError # pragma: NO COVER | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ | |
from six.moves import queue | ||
|
||
import logging | ||
import multiprocessing | ||
import threading | ||
import time | ||
|
||
|
@@ -82,7 +83,7 @@ class QueueExitEvent(QueueEvent): | |
class Queue(object): | ||
def __init__(self, capacity): | ||
self.EXIT_EVENT = QueueExitEvent('EXIT') | ||
self._queue = queue.Queue(maxsize=capacity) | ||
self._queue = multiprocessing.Queue(maxsize=capacity) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It does work with threading, however in an environment where multiple processes are being used (see linked bug reports), the queue is not being shared between the different processes. Therefore a multiprocessing.Queue is required to get this to work. |
||
|
||
def _gets(self, count, timeout): | ||
start_time = time.time() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add an entry to the CHANGELOG