Skip to content

Commit 542357b

Browse files
committed
feat: Update version to 1.0.8 and track last processed line and timestamp per stream
1 parent 9ee6a1b commit 542357b

File tree

2 files changed

+41
-7
lines changed

2 files changed

+41
-7
lines changed

charts/slaking/Chart.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ apiVersion: v2
22
name: slaking
33
description: A Kubernetes service that monitors workloads for annotations and sends filtered logs to Slack channels
44
type: application
5-
version: 1.0.7
6-
appVersion: "1.0.7"
5+
version: 1.0.8
6+
appVersion: "1.0.8"
77
keywords:
88
- kubernetes
99
- slack

src/services/logProcessor.js

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ class LogProcessor {
3232
summaryTimeout: 900000, // 15 minutes timeout for "stopped" message
3333
enableStoppedMessages: true // Whether to send "stopped" messages
3434
};
35+
this.lastProcessedLine = new Map(); // Track last processed line for each stream
36+
this.lastProcessedTimestamp = new Map(); // Track last processed timestamp for each stream
3537
}
3638

3739
async initialize() {
@@ -60,7 +62,9 @@ class LogProcessor {
6062
buffer: [],
6163
lastSent: 0,
6264
isActive: true,
63-
interval: null
65+
interval: null,
66+
lastProcessedLine: null, // Track last processed line
67+
lastProcessedTimestamp: null // Track last processed timestamp
6468
};
6569

6670
this.activeStreams.set(streamKey, logStream);
@@ -114,9 +118,31 @@ class LogProcessor {
114118
}
115119

116120
const lines = chunk.split('\n').filter(line => line.trim());
117-
118-
for (const line of lines) {
119-
if (this.shouldProcessLine(line, logStream.config)) {
121+
let newLines = lines;
122+
123+
// Deduplication: Only process new lines since last processed
124+
if (logStream.lastProcessedLine) {
125+
const lastIdx = lines.lastIndexOf(logStream.lastProcessedLine);
126+
if (lastIdx !== -1 && lastIdx < lines.length - 1) {
127+
newLines = lines.slice(lastIdx + 1);
128+
} else if (lastIdx === lines.length - 1) {
129+
newLines = [];
130+
}
131+
}
132+
133+
for (const line of newLines) {
134+
// Timestamp deduplication (if possible)
135+
let skip = false;
136+
let lineTimestamp = null;
137+
const tsMatch = line.match(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z?/);
138+
if (tsMatch) {
139+
lineTimestamp = new Date(tsMatch[0]).getTime();
140+
if (logStream.lastProcessedTimestamp && lineTimestamp <= logStream.lastProcessedTimestamp) {
141+
this.logger.debug(`[Dedup] Skipping old log line (timestamp): ${line}`);
142+
skip = true;
143+
}
144+
}
145+
if (!skip && this.shouldProcessLine(line, logStream.config)) {
120146
// Track the log pattern for consolidation
121147
const patternData = this.trackLogPattern(streamKey, line, logStream.config, logStream.slackService);
122148

@@ -135,7 +161,15 @@ class LogProcessor {
135161
this.sendLogBuffer(streamKey, logStream);
136162
}
137163
}
164+
} else if (!skip) {
165+
this.logger.debug(`[Dedup] Skipping log line (filter/level): ${line}`);
166+
}
167+
// Update last processed timestamp if available
168+
if (lineTimestamp) {
169+
logStream.lastProcessedTimestamp = lineTimestamp;
138170
}
171+
// Always update last processed line
172+
logStream.lastProcessedLine = line;
139173
}
140174

141175
// Check for stopped patterns after processing chunk
@@ -593,7 +627,7 @@ class LogProcessor {
593627
this.logger.debug(`Sent stopped message for pattern: ${patternData.pattern}`);
594628
// Remove the pattern from tracking and allow it to be reported again
595629
this.logPatterns.delete(patternKey);
596-
// (If you want to keep the object for stats, you could instead reset isSuppressed)
630+
// Clear suppression for this pattern (if any extra state is needed)
597631
} catch (error) {
598632
this.logger.error(`Failed to send stopped message for ${patternKey}`, error);
599633
}

0 commit comments

Comments
 (0)