open-telemetry / open-telemetry/opentelemetry-python

BatchLogRecordProcessor emit implementation drops the logs when the queue is full

Open
#4,336 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Python
Stars
2.6k
Forks
1k
Avg merge
4d 15h
Merged PRs (30d)
19

Description

Describe your environment

OS: Windows
Python version: Python 3.8.10
SDK version: (e.g., 1.25.0)
API version: (e.g., 1.25.0)

What happened?

I am using BatchLogRecordProcessor for emitting the logs to export them to OTLP collector.
I have observed that, the BatchLogRecordProcessor is dropping some logs resulting it into data loss.

Below is the observation -

def emit(self, log_data: LogData) -> None:
        """Adds the `LogData` to queue and notifies the waiting threads
        when size of queue reaches max_export_batch_size.
        """
        if self._shutdown:
            return
        if self._pid != os.getpid():
            _BSP_RESET_ONCE.do_once(self._at_fork_reinit)

        self._queue.appendleft(log_data)
        if len(self._queue) >= self._max_export_batch_size:
            with self._condition:
                self._condition.notify()

In the above code, the line self._queue.appendleft(log_data) is dropping the oldest log_data when the queue is full.
I believe this is happening when the previous export of the batch is not yet complete and in the meanwhile queue also gets full, even when the below code

if len(self._queue) >= self._max_export_batch_size:
            with self._condition:
                self._condition.notify()

notifies the thread there is no new export happening as the locks are acquired by the previous export.
And in this process eventually the queue is full and for any new addition to the queue, as we are using appendLeft the new logs are added by discarding the oldest log to maintain the max queue size.

Steps to Reproduce
  1. Create a data array of size 10000 of any log data
  2. Register the BatchLogRecordProcessor to the LoggerProvider
logger_provider = LoggerProvider(resource=resource)

# Create an OTLPLogExporter
otlp_exporter = OTLPLogExporter(
  endpoint=endpoint, insecure=False , timeout=20 # Set to False if you want to use TLS/SSL
)

processor = BatchLogRecordProcessor(otlp_exporter, max_batch_size=MAX_EVENTS_IN_BATCH, max_queue_size=MAX_QUEUE_SIZE)

# Add a BatchLogProcessor to the LoggerProvider
logger_provider.add_log_record_processor(processor)
set_logger_provider(logger_provider)

set MAX_EVENTS_IN_BATCH = 128 and MAX_QUEUE_SIZE = 2048
3. Use the logger.emit in a for loop

logger = logger_provider.get_logger(__name__)
for event in data:
      logger.emit(event)
  1. Add some logging statements as below -
  • print("In export_batch") here
  • print(f"Queue size - {len(self._queue)}") here
  1. Run the above python code
Expected Result

All 10000 logs should be exported.
As our batch size is 128, total 10000/128 = 78 complete batches and 1 last batch of 16 logs should be created to be exported.
So there should be 79 print statements of In export_batch

Actual Result

There are only around 35 print statements of In export_batch
The queue size remains constant at 2048 after emit is called more than 2048.
Further logs when logger.emit is invoked are dropped from the queue until the notified thread starts exporting another batch of 128 logs from the queue and making space for new logs.

Additional context

No response

Would you like to implement a fix?

No

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/export/init.py at BatchLogRecordProcessor.emit and the export_batch entry point linked in the report. Reproduce with max_batch_size=128, max_queue_size=2048, and 10,000 emitted logs, then verify that queue-full behavior no longer loses records and that all expected batches are exported.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
observability-sre
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.