event_timeline 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7f9b39a082143ef828a48c1ba89377103062e5fd2d356658d257964727402c22
|
|
4
|
+
data.tar.gz: f332374e2650e04ae7cfe4dee1ae27d98b11d268486284afbd02ddba8def7576
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c7ff33b22475ea362d891023c7fc942e9ee85878d13fba5cf113426e3aea0ba1b48e10ad9a6f0ea101b5dd740900beaacd65b021a2a0903fc70f8d51ba2bc9b1
|
|
7
|
+
data.tar.gz: 44ccc4f17fdb6e65f247a5209cec9cea0e6f458593ad113522b1da7056f9ca846db487a1f0d6cbbbcd5faca12c6be9be5ca1c917d17ae52674f23a58d43b25e3
|
|
@@ -33,9 +33,10 @@ module EventTimeline
|
|
|
33
33
|
buffer = thread_event_buffer
|
|
34
34
|
return if buffer.empty?
|
|
35
35
|
|
|
36
|
+
buffer_size = buffer.size
|
|
36
37
|
Session.insert_all(buffer)
|
|
37
38
|
|
|
38
|
-
RotationService.enforce_correlation_limit(correlation_id)
|
|
39
|
+
RotationService.enforce_correlation_limit(correlation_id, buffer_size)
|
|
39
40
|
RotationService.cleanup_if_needed
|
|
40
41
|
rescue StandardError => e
|
|
41
42
|
Rails.logger.error "EventTimeline flush failed: #{e.message}" if defined?(Rails.logger)
|
|
@@ -100,9 +101,10 @@ module EventTimeline
|
|
|
100
101
|
end
|
|
101
102
|
|
|
102
103
|
def handle_return(tp)
|
|
103
|
-
|
|
104
|
+
# Skip watched? check - if we didn't track the call, pop_from_stack returns nil
|
|
105
|
+
correlation_id = CurrentCorrelation.id
|
|
106
|
+
return unless correlation_id
|
|
104
107
|
|
|
105
|
-
correlation_id = CurrentCorrelation.id || determine_correlation_id
|
|
106
108
|
method_info = pop_from_stack(correlation_id, tp)
|
|
107
109
|
return unless method_info
|
|
108
110
|
|
|
@@ -8,6 +8,7 @@ module EventTimeline
|
|
|
8
8
|
|
|
9
9
|
def initialize
|
|
10
10
|
@watched_paths = []
|
|
11
|
+
@watched_cache = {} # Cache for watched? lookups
|
|
11
12
|
@filtered_attributes = default_filtered_attributes
|
|
12
13
|
@max_events_per_correlation = 500 # Max events per correlation_id
|
|
13
14
|
@max_total_events = 10_000 # Max total events before cleanup
|
|
@@ -23,16 +24,23 @@ module EventTimeline
|
|
|
23
24
|
|
|
24
25
|
def watch(path)
|
|
25
26
|
@watched_paths << normalize_path(path)
|
|
27
|
+
@watched_cache.clear # Invalidate cache when paths change
|
|
26
28
|
end
|
|
27
29
|
|
|
28
30
|
def watched?(file_path)
|
|
29
31
|
return false if @watched_paths.empty?
|
|
30
32
|
|
|
31
|
-
@
|
|
32
|
-
|
|
33
|
+
@watched_cache.fetch(file_path) do
|
|
34
|
+
@watched_cache[file_path] = @watched_paths.any? do |pattern|
|
|
35
|
+
File.fnmatch?(pattern, file_path, File::FNM_PATHNAME)
|
|
36
|
+
end
|
|
33
37
|
end
|
|
34
38
|
end
|
|
35
39
|
|
|
40
|
+
def clear_watched_cache!
|
|
41
|
+
@watched_cache.clear
|
|
42
|
+
end
|
|
43
|
+
|
|
36
44
|
def filter_pii(&block)
|
|
37
45
|
@pii_filter_proc = block if block_given?
|
|
38
46
|
end
|
|
@@ -2,10 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
module EventTimeline
|
|
4
4
|
class RotationService
|
|
5
|
+
CLEANUP_CHECK_INTERVAL = 100 # Only check every N flushes
|
|
6
|
+
|
|
5
7
|
class << self
|
|
6
|
-
def cleanup_if_needed
|
|
8
|
+
def cleanup_if_needed(force: false)
|
|
7
9
|
return unless EventTimeline.configuration
|
|
8
10
|
|
|
11
|
+
unless force
|
|
12
|
+
# Probabilistic check - only run expensive Session.count every N requests
|
|
13
|
+
@flush_counter ||= 0
|
|
14
|
+
@flush_counter += 1
|
|
15
|
+
return unless (@flush_counter % CLEANUP_CHECK_INTERVAL).zero?
|
|
16
|
+
end
|
|
17
|
+
|
|
9
18
|
total_count = Session.count
|
|
10
19
|
max_total = EventTimeline.configuration.max_total_events
|
|
11
20
|
threshold = (max_total * EventTimeline.configuration.cleanup_threshold).to_i
|
|
@@ -15,11 +24,23 @@ module EventTimeline
|
|
|
15
24
|
perform_cleanup(total_count, max_total)
|
|
16
25
|
end
|
|
17
26
|
|
|
18
|
-
def enforce_correlation_limit(correlation_id)
|
|
27
|
+
def enforce_correlation_limit(correlation_id, buffer_size = 0, force: false)
|
|
19
28
|
return unless EventTimeline.configuration
|
|
20
29
|
|
|
21
30
|
max_per_correlation = EventTimeline.configuration.max_events_per_correlation
|
|
31
|
+
|
|
32
|
+
unless force
|
|
33
|
+
# Track in-memory counts to avoid DB query on every flush
|
|
34
|
+
@correlation_counts ||= {}
|
|
35
|
+
@correlation_counts[correlation_id] ||= 0
|
|
36
|
+
@correlation_counts[correlation_id] += buffer_size
|
|
37
|
+
|
|
38
|
+
# Only hit DB when we think we might be near the limit
|
|
39
|
+
return unless @correlation_counts[correlation_id] >= (max_per_correlation * 0.9)
|
|
40
|
+
end
|
|
41
|
+
|
|
22
42
|
current_count = Session.where(correlation_id: correlation_id).count
|
|
43
|
+
@correlation_counts[correlation_id] = current_count if @correlation_counts # Sync with reality
|
|
23
44
|
|
|
24
45
|
return unless current_count >= max_per_correlation
|
|
25
46
|
|
|
@@ -30,10 +51,16 @@ module EventTimeline
|
|
|
30
51
|
.limit(current_count - keep_count)
|
|
31
52
|
|
|
32
53
|
Session.where(id: oldest_events.pluck(:id)).delete_all
|
|
54
|
+
@correlation_counts[correlation_id] = keep_count if @correlation_counts
|
|
33
55
|
|
|
34
56
|
Rails.logger.info "EventTimeline: Rotated #{current_count - keep_count} events for correlation #{correlation_id}" if defined?(Rails.logger)
|
|
35
57
|
end
|
|
36
58
|
|
|
59
|
+
def reset_counters!
|
|
60
|
+
@flush_counter = 0
|
|
61
|
+
@correlation_counts = {}
|
|
62
|
+
end
|
|
63
|
+
|
|
37
64
|
private
|
|
38
65
|
|
|
39
66
|
def perform_cleanup(current_count, max_count)
|