Skip to content

Commit 1282bfc

Browse files
committed
move it to doc comment
1 parent 403a412 commit 1282bfc

File tree

1 file changed

+85
-87
lines changed

1 file changed

+85
-87
lines changed

opentelemetry-sdk/src/logs/log_processor.rs

Lines changed: 85 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -264,94 +264,92 @@ type LogsData = Box<(LogRecord, InstrumentationScope)>;
264264
/// .with_log_processor(processor)
265265
/// .build();
266266
///
267+
/// **Memory Management in BatchLogProcessor**
267268
///
268-
// **Memory Management in BatchLogProcessor**
269-
//
270-
// The `BatchLogProcessor` manages memory through the following stages of log processing:
271-
//
272-
// 1. **Record Ingestion**:
273-
// - Each `LogRecord` is **cloned** upon entering the processor.
274-
// - `LogRecordAttributes` utilize a hybrid memory model:
275-
// - First 5 attributes are **stack-allocated**.
276-
// - Adding additional attribtues trigger **heap allocation** in a dynamically growing vector.
277-
// - The `LogRecord` and its associated `InstrumentationScope` are **boxed together**
278-
// to allocate them on the heap before entering the queue. This means:
279-
// - The `LogRecord`'s inline attributes (if any) are moved to the heap as part of the boxed structure.
280-
// - Any dynamically allocated data already on the heap (e.g., strings, overflow attributes) remains unaffected.
281-
// - Ownership of the boxed data is transferred to the queue, ensuring it can be processed independently of the original objects.
282-
//
283-
// 2. **Queue Management**:
284-
// - Uses **two bounded synchronous channels** (`sync_channel`):
285-
// - One for **log records** (`logs_sender` and `logs_receiver`).
286-
// - Another for **control messages** (`message_sender` and `message_receiver`).
287-
//
288-
// - **Log Record Queue**:
289-
// - Stores log records as **heap-allocated** `Box<(LogRecord, InstrumentationScope)>`.
290-
// - The queue size is configurable and defined by `max_queue_size`.
291-
// - If the queue is full:
292-
// - New log records are **dropped**, and a warning is logged the first time this happens.
293-
// - Dropped records are counted for reporting during shutdown.
294-
//
295-
// - **Control Message Queue**:
296-
// - Stores control messages (`BatchMessage`) to manage operations like exporting, force flushing, setting resources, and shutting down.
297-
// - The control message queue has a fixed size (e.g., 64 messages).
298-
// - Control messages are processed with higher priority, ensuring operational commands are handled promptly.
299-
// - The use of a separate control queue ensures that critical commands, such as `Shutdown`, are not lost even if the log record queue is full.
300-
// - Messages supported include:
301-
// - `ExportLog`: Triggers an immediate export of log records.
302-
// - `ForceFlush`: Flushes all buffered log records to the exporter.
303-
// - `SetResource`: Updates the exporter with a new resource.
304-
// - `Shutdown`: Cleans up and flushes logs before terminating the processor.
305-
//
306-
// 3. **Worker Thread Storage**:
307-
// - The worker thread maintains a pre-allocated `Vec` of boxed record pairs:
308-
// - The vector’s capacity is fixed at `max_export_batch_size`.
309-
// - Records are **moved** (not cloned) from the log record queue to the vector for processing.
310-
//
311-
// 4. **Export Process**:
312-
// - During the export process:
313-
// - The worker thread retrieves records from the log record queue until `max_export_batch_size` is reached or the queue is empty.
314-
// - The retrieved records are processed in batches and passed to the exporter.
315-
// - The exporter's `export()` method receives references to the log records and `InstrumentationScope`.
316-
// - If the exporter requires retaining the log records (e.g., for retries or asynchronous operations), it must **clone** the records inside the `export()` implementation.
317-
// - After successful export:
318-
// - The original boxed records are dropped, releasing heap memory.
319-
// - Export is triggered in the following scenarios:
320-
// - When the batch size reaches `max_export_batch_size`, resulting in `ExportLog` control message being sent to the worker thread.
321-
// - When the scheduled delay timer expires.
322-
// - When `force_flush` is called by the application, resulting in a `ForceFlush` control message being sent to the worker thread.
323-
// - During processor shutdown initiated by the application, resulting in a `Shutdown` control message being sent to the worker thread.
324-
// - Generation of `ExportLog` control message:
325-
// - The `ExportLog` control message is generated by the application thread when a new record is added to the log record queue, and the current batch size reaches `max_export_batch_size`.
326-
// - To prevent redundant messages, the `ExportLog` message is only sent if the previous one has been processed by the worker thread.
327-
// - Upon receiving this message, the worker thread immediately processes and exports the current batch, overriding any scheduled delay.
328-
//
329-
// 5. **Memory Limits**:
330-
// - **Worst-Case Memory Usage**:
331-
// - **Log Record Queue Memory** = `max_queue_size * size of boxed (LogRecord + InstrumentationScope)`.
332-
// - **Batch Memory** = `max_export_batch_size * size of boxed (LogRecord + InstrumentationScope)`.
333-
// - **Control Message Queue Memory**:
334-
// - Fixed at 64 messages, with negligible memory overhead.
335-
// - **Total Maximum Memory:**
336-
// - When both the log record queue and batch vector are full:
337-
// ```
338-
// (max_queue_size + max_export_batch_size) * size of boxed (LogRecord + InstrumentationScope)
339-
// ```
340-
// - The average size of a `LogRecord` is ~300 bytes ( assuming 4 attributes), and the `InstrumentationScope` is ~50 bytes assuming no attributes.
341-
// - For `max_queue_size = 2048` and `max_export_batch_size = 512`, the total memory usage is ~900 KB as below:
342-
// Calculation: `(2048 + 512) * (300 + 50) = 2560 * 350 = 896000 bytes = 896 KB`.
343-
//
344-
// 6. **Key Notes on Memory Behavior**:
345-
// - Boxing a `LogRecord` and `InstrumentationScope` moves the record to the heap,
346-
// including stack-allocated attributes.
347-
// - During the export process, records are moved from the log record queue to the worker thread’s vector.
348-
// - No additional cloning or copying occurs during the export process, minimizing memory overhead while ensuring efficient handling of log records.
349-
//
350-
// 7. **Control Queue Prioritization**:
351-
// - Control messages take precedence over log record processing to ensure timely execution of critical operations.
352-
// - For instance, a `Shutdown` message is processed before continuing with log exports, guaranteeing graceful cleanup.
353-
// - The use of a separate control queue ensures responsiveness to operational commands without the risk of losing critical messages, even if the log record queue is full.
354-
269+
/// The `BatchLogProcessor` manages memory through the following stages of log processing:
270+
///
271+
/// 1. **Record Ingestion**:
272+
/// - Each `LogRecord` is **cloned** upon entering the processor.
273+
/// - `LogRecordAttributes` utilize a hybrid memory model:
274+
/// - First 5 attributes are **stack-allocated**.
275+
/// - Adding additional attribtues trigger **heap allocation** in a dynamically growing vector.
276+
/// - The `LogRecord` and its associated `InstrumentationScope` are **boxed together**
277+
/// to allocate them on the heap before entering the queue. This means:
278+
/// - The `LogRecord`'s inline attributes (if any) are moved to the heap as part of the boxed structure.
279+
/// - Any dynamically allocated data already on the heap (e.g., strings, overflow attributes) remains unaffected.
280+
/// - Ownership of the boxed data is transferred to the queue, ensuring it can be processed independently of the original objects.
281+
///
282+
/// 2. **Queue Management**:
283+
/// - Uses **two bounded synchronous channels** (`sync_channel`):
284+
/// - One for **log records** (`logs_sender` and `logs_receiver`).
285+
/// - Another for **control messages** (`message_sender` and `message_receiver`).
286+
///
287+
/// - **Log Record Queue**:
288+
/// - Stores log records as **heap-allocated** `Box<(LogRecord, InstrumentationScope)>`.
289+
/// - The queue size is configurable and defined by `max_queue_size`.
290+
/// - If the queue is full:
291+
/// - New log records are **dropped**, and a warning is logged the first time this happens.
292+
/// - Dropped records are counted for reporting during shutdown.
293+
///
294+
/// - **Control Message Queue**:
295+
/// - Stores control messages (`BatchMessage`) to manage operations like exporting, force flushing, setting resources, and shutting down.
296+
/// - The control message queue has a fixed size (e.g., 64 messages).
297+
/// - Control messages are processed with higher priority, ensuring operational commands are handled promptly.
298+
/// - The use of a separate control queue ensures that critical commands, such as `Shutdown`, are not lost even if the log record queue is full.
299+
/// - Messages supported include:
300+
/// - `ExportLog`: Triggers an immediate export of log records.
301+
/// - `ForceFlush`: Flushes all buffered log records to the exporter.
302+
/// - `SetResource`: Updates the exporter with a new resource.
303+
/// - `Shutdown`: Cleans up and flushes logs before terminating the processor.
304+
///
305+
/// 3. **Worker Thread Storage**:
306+
/// - The worker thread maintains a pre-allocated `Vec` of boxed record pairs:
307+
/// - The vector’s capacity is fixed at `max_export_batch_size`.
308+
/// - Records are **moved** (not cloned) from the log record queue to the vector for processing.
309+
///
310+
/// 4. **Export Process**:
311+
/// - During the export process:
312+
/// - The worker thread retrieves records from the log record queue until `max_export_batch_size` is reached or the queue is empty.
313+
/// - The retrieved records are processed in batches and passed to the exporter.
314+
/// - The exporter's `export()` method receives references to the log records and `InstrumentationScope`.
315+
/// - If the exporter requires retaining the log records (e.g., for retries or asynchronous operations), it must **clone** the records inside the `export()` implementation.
316+
/// - After successful export:
317+
/// - The original boxed records are dropped, releasing heap memory.
318+
/// - Export is triggered in the following scenarios:
319+
/// - When the batch size reaches `max_export_batch_size`, resulting in `ExportLog` control message being sent to the worker thread.
320+
/// - When the scheduled delay timer expires.
321+
/// - When `force_flush` is called by the application, resulting in a `ForceFlush` control message being sent to the worker thread.
322+
/// - During processor shutdown initiated by the application, resulting in a `Shutdown` control message being sent to the worker thread.
323+
/// - Generation of `ExportLog` control message:
324+
/// - The `ExportLog` control message is generated by the application thread when a new record is added to the log record queue, and the current batch size reaches `max_export_batch_size`.
325+
/// - To prevent redundant messages, the `ExportLog` message is only sent if the previous one has been processed by the worker thread.
326+
/// - Upon receiving this message, the worker thread immediately processes and exports the current batch, overriding any scheduled delay.
327+
///
328+
/// 5. **Memory Limits**:
329+
/// - **Worst-Case Memory Usage**:
330+
/// - **Log Record Queue Memory** = `max_queue_size * size of boxed (LogRecord + InstrumentationScope)`.
331+
/// - **Batch Memory** = `max_export_batch_size * size of boxed (LogRecord + InstrumentationScope)`.
332+
/// - **Control Message Queue Memory**:
333+
/// - Fixed at 64 messages, with negligible memory overhead.
334+
/// - **Total Maximum Memory:**
335+
/// - When both the log record queue and batch vector are full:
336+
/// ```
337+
/// (max_queue_size + max_export_batch_size) * size of boxed (LogRecord + InstrumentationScope)
338+
/// ```
339+
/// - The average size of a `LogRecord` is ~300 bytes ( assuming 4 attributes), and the `InstrumentationScope` is ~50 bytes assuming no attributes.
340+
/// - For `max_queue_size = 2048` and `max_export_batch_size = 512`, the total memory usage is ~900 KB as below:
341+
/// Calculation: `(2048 + 512) * (300 + 50) = 2560 * 350 = 896000 bytes = 896 KB`.
342+
///
343+
/// 6. **Key Notes on Memory Behavior**:
344+
/// - Boxing a `LogRecord` and `InstrumentationScope` moves the record to the heap,
345+
/// including stack-allocated attributes.
346+
/// - During the export process, records are moved from the log record queue to the worker thread’s vector.
347+
/// - No additional cloning or copying occurs during the export process, minimizing memory overhead while ensuring efficient handling of log records.
348+
///
349+
/// 7. **Control Queue Prioritization**:
350+
/// - Control messages take precedence over log record processing to ensure timely execution of critical operations.
351+
/// - For instance, a `Shutdown` message is processed before continuing with log exports, guaranteeing graceful cleanup.
352+
/// - The use of a separate control queue ensures responsiveness to operational commands without the risk of losing critical messages, even if the log record queue is full.
355353
pub struct BatchLogProcessor {
356354
logs_sender: SyncSender<LogsData>, // Data channel to store log records and instrumentation scopes
357355
message_sender: SyncSender<BatchMessage>, // Control channel to store control messages for the worker thread

0 commit comments

Comments
 (0)