Package Functions | |
DispatchingLogQueue () | |
int | getMaxQueueSize () |
synchronized void | setMaxQueueSize (int maxQueueSize) |
synchronized boolean | log (LogRecord logRecord) |
void | flushAllAndWait () |
Future< Boolean > | flush () |
boolean | hasRemoteDispatcher () |
int | recordQueueSize () |
int | pendingFlushes () |
int | realQueueSize () |
boolean | flushesPeriodically () |
void | setPeriodicFlushing (final int periodMillisec) |
void | setRemoteLogDispatcher (RemoteLogDispatcher remoteLogDispatcher) |
void | shutDown () |
Private Member Functions | |
void | flushIfEnoughRecords (boolean conservative) |
boolean | flush (boolean isScheduled) |
boolean | flushLogRecords (final LogRecord[] logRecords) |
Private Attributes | |
volatile PriorityBlockingQueue< LogRecord > | queue |
final ReentrantLock | flushLock |
final ScheduledThreadPoolExecutor | executor |
ScheduledFuture<?> | flushScheduleFuture |
long | lastFlushFinished |
int | currentFlushPeriod |
boolean | outOfCapacity |
int | preOverflowFlushPeriod |
RemoteLogDispatcher | remoteLogDispatcher |
int | maxQueueSize |
final boolean | DEBUG = Boolean.getBoolean("alma.acs.logging.verbose") |
Static Private Attributes | |
boolean | LOSSLESS = Boolean.getBoolean("alma.acs.logging.lossless") |
LogRecord
s which takes care of dispatching them to a remote log service, using the one provided in setRemoteLogDispatcher(RemoteLogDispatcher). Technically this class is not a singleton, but it is foreseen to be used as a single instance. It is thread-safe, so multiple log handlers can submit records.
All log records to be sent remotely to the central log service must be submitted to the log(LogRecord) method. If the remote log service is not available (e.g. during startup, or later temporarily due to network problems), the log records will be cached. The cache size is given by MAX_QUEUE_SIZE. If the cache is more than 70% full, the log
method will only accept records with level INFO
or higher. If the cache is full, no records are accepted. The idea is to not jeopardize the running system, but rather stop remote logging.
The queue sorts log records by their log levels and thus dispatches the most important records first, using LogRecordComparator.
|
|
|
Internal flush method which covers straight calls to flush as well as scheduled calls.
Threading note: this method is thread safe because competing threads are blocked on a flush lock (and additionally on
|
|
Tries to send log records to the remote log service, but at most RemoteLogDispatcher#getBufferSize(). If sending fails, the log records remain in the queue (actually they may be first taken out and then get re-submitted).
This method returns immediately, since flushing is done in a separate thread. The returned future object can be used to wait for termination of the log flush and get the result, or to cancel the flush. The result is a Reimplemented in alma::acs::logging::AcsLoggingHandlerTest::TestLogQueue.
|
|
Flushes all log records if the remote log service has been made available before. Returns only when the log queue contains no more records, so execution time may be long. Should better not be called from the main thread. |
|
|
|
Flushes if we have enough records in the queue to fill up the entire buffer for sending them remotely, and if the remote log service can be assumed to be available.
Since flushing happens in a separate thread with a certain time lag, this method can avoid creating too many flush requests by only generating them if the number of queued log records is a multiple of the send buffer as opposed to larger than the buffer. This is controlled by the Note that the most important records are sent first because the queue sorts by log level, and that a successful flush() will call this method again to submit another flush; thus even a large queue will be drained fairly fast if the remote log service works, even in the absence of periodic flushing.
|
|
Extracted from flush(boolean) to improve readability of the code.
|
|
|
|
|
|
Adds a Threading note: it seems ok to make this method "synchronized". This avoids problems with stale queue size, even though the damage would be small since the treatment of queue size is somewhat arbitrary anyway. Synchronization should not block callers long at all because flushing is done in a separate thread and only gets triggered here. TODO: there is currently a minor problem with queue overflow: log records get drained from the queue, and when they can't be sent off to the log service, they are resubmitted to the queue. It could happen that in the meantime, some other record with INFO or higher level has been added to the queue, and that resubmitting some of the even more important records may fail. The solution would be to replace the 70%-filter rule with a running priority filter: any incoming record can kick out a less important record if the queue is full.
Reimplemented in alma::acs::logging::AcsLoggingHandlerTest::TestLogQueue.
|
|
Returns the number of currently waiting flush requests. This method is intended only for monitoring the logging system. Periodic flushing enabled by setPeriodicFlushing(int) is not counted as a waiting flush request. Note that not all of these requested flushes necessarily result in a flushing of log records, because some of them may find an empty log record queue when they get executed, and thus end w/o effect. |
|
Waits if necessary until a flushing thread has finished, and then returns the real number of currently queued log records.
Note that during flushing, the records are first taken out of the queue, but then get resubmitted if sending them to the central log service failed. Therefore, calling |
|
Returns the number of currently queued log messages. This method is intended only for testing and monitoring of the logging system. |
|
Sets the maximum size of the log queue. Logs will be dropped when the queue is full. The default is 1000, but gets overwritten by the value of |
|
Triggers periodic calls to flush(boolean), or terminates such automatic flushing if All control over periodic log flushing is confined in this method.
The call returns without further action if flushing is already enabled with the same period as
|
|
Sets the remote log dispatcher. Should be called once the remote log service is available. Calling this method will not flush the log queue (need to call flushAllAndWait() separately), nor will it automatically trigger periodic flushes (call setPeriodicFlushing(int) for this).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
If true, them the queue does not drop any log records, but rather blocks loggers in log(LogRecord) until their request can be processed. Default is |
|
Underlying PriorityBlockingQueue is unbounded, but we don't want logging to cause memory problems while the remote logger is unavailable and all logs must be cached. Thus a maximum queue size. The chosen value must be larger than RemoteLogDispatcher#getBufferSize() |
|
|
|
|
|
|
|
|