24
24
*/
25
25
package com .iluwatar .logaggregation ;
26
26
import java .util .concurrent .BlockingQueue ;
27
- import java .util .concurrent .ConcurrentLinkedQueue ;
28
27
import java .util .concurrent .LinkedBlockingQueue ;
29
28
import java .util .concurrent .ScheduledExecutorService ;
30
29
import java .util .concurrent .Executors ;
34
33
import java .util .ArrayList ;
35
34
import java .util .List ;
36
35
import lombok .extern .slf4j .Slf4j ;
37
-
38
36
/**
39
37
* Responsible for collecting and buffering logs from different services. Once the logs reach a
40
38
* certain threshold or after a certain time interval, they are flushed to the central log store.
@@ -47,26 +45,25 @@ public class LogAggregator {
47
45
private static final int BUFFER_THRESHOLD = 3 ;
48
46
private static final int FLUSH_INTERVAL_SECONDS = 5 ;
49
47
private static final int SHUTDOWN_TIMEOUT_SECONDS = 10 ;
50
-
48
+
51
49
private final CentralLogStore centralLogStore ;
52
- private final ConcurrentLinkedQueue <LogEntry > buffer = new ConcurrentLinkedQueue <>();
50
+ private final BlockingQueue <LogEntry > buffer = new LinkedBlockingQueue <>();
53
51
private final LogLevel minLogLevel ;
54
- private final ExecutorService executorService = Executors .newSingleThreadExecutor ( );
52
+ private final ScheduledExecutorService scheduledExecutor = Executors .newScheduledThreadPool ( 1 );
55
53
private final AtomicInteger logCount = new AtomicInteger (0 );
56
- private final ScheduledExecutorService scheduledExecutor = Executors .newScheduledThreadPool (1 );
57
54
private final CountDownLatch shutdownLatch = new CountDownLatch (1 );
58
55
private volatile boolean running = true ;
59
-
60
56
/**
61
57
* constructor of LogAggregator.
62
58
*
63
59
* @param centralLogStore central log store implement
64
60
* @param minLogLevel min log level to store log
65
61
*/
66
62
public LogAggregator (CentralLogStore centralLogStore , LogLevel minLogLevel ) {
67
- this .centralLogStore = centralLogStore ;
63
+ this .centralLogStore = centralLogStore ;
68
64
this .minLogLevel = minLogLevel ;
69
- startBufferFlusher ();
65
+ startPeriodicFlusher ();
66
+
70
67
// Add shutdown hook for graceful termination
71
68
Runtime .getRuntime ().addShutdownHook (new Thread (() -> {
72
69
try {
@@ -83,7 +80,7 @@ public LogAggregator(CentralLogStore centralLogStore, LogLevel minLogLevel) {
83
80
*
84
81
* @param logEntry The log entry to collect.
85
82
*/
86
- public void collectLog (LogEntry logEntry ) {
83
+ public void collectLog (LogEntry logEntry ) {
87
84
if (!running ) {
88
85
LOGGER .warn ("LogAggregator is shutting down. Skipping log entry." );
89
86
return ;
@@ -118,7 +115,7 @@ public void collectLog(LogEntry logEntry) {
118
115
*
119
116
* @throws InterruptedException If any thread has interrupted the current thread.
120
117
*/
121
- public void stop () throws InterruptedException {
118
+ public void stop () throws InterruptedException {
122
119
LOGGER .info ("Stopping LogAggregator..." );
123
120
running = false ;
124
121
@@ -145,19 +142,20 @@ public void stop() throws InterruptedException {
145
142
}
146
143
147
144
145
+
148
146
/**
149
147
* Waits for the LogAggregator to complete shutdown.
150
148
* Useful for testing or controlled shutdown scenarios.
151
149
*
152
150
* @throws InterruptedException If any thread has interrupted the current thread.
153
151
*/
154
- public void awaitShutdown () throws InterruptedException {
152
+ public void awaitShutdown () throws InterruptedException {
155
153
shutdownLatch .await ();
156
154
}
157
155
158
156
159
157
private void flushBuffer () {
160
- if (!running && buffer .isEmpty ()) {
158
+ if (!running && buffer .isEmpty ()) {
161
159
return ;
162
160
}
163
161
@@ -188,6 +186,7 @@ private void flushBuffer() {
188
186
}
189
187
}
190
188
189
+
191
190
/**
192
191
* Starts the periodic buffer flusher using ScheduledExecutorService.
193
192
* This eliminates the busy-waiting loop with Thread.sleep().
0 commit comments