lpxc 0.0.5 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/lpxc.rb +51 -33
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a9a59ea66505168840a485b178c9f805df781f4b
|
4
|
+
data.tar.gz: 1181f1e2976a3a6a0fccf4e88a006c66bca90815
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c7f0c812aa0f867262d7e178bafa9e804704d0493d5951b65334d479253c3566162cbde8a6ebd9c82f4534e0b650d5780d7bee6b721aee27d57b48d411d02ff
|
7
|
+
data.tar.gz: ef326d1790d550779e7c6e86851228d0dc16fc1da8e87b735ce7a05dab91154ba99291184212c2134b2a6a644f39f983fc757376a47c5f34ab4b2ce7f3362dde
|
data/lib/lpxc.rb
CHANGED
@@ -4,6 +4,30 @@ require 'uri'
|
|
4
4
|
require 'thread'
|
5
5
|
require 'timeout'
|
6
6
|
|
7
|
+
class LogMsgQueue
|
8
|
+
def initialize(max)
|
9
|
+
@locker = Mutex.new
|
10
|
+
@max = max
|
11
|
+
@array = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def enqueue(msg)
|
15
|
+
@locker.synchronize {@array << msg}
|
16
|
+
end
|
17
|
+
|
18
|
+
def flush
|
19
|
+
@locker.synchronize do
|
20
|
+
old = @array
|
21
|
+
@array = []
|
22
|
+
return old
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def full?
|
27
|
+
@locker.synchronize {@array.size >= @max}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
7
31
|
class Lpxc
|
8
32
|
|
9
33
|
#After parsing opts and initializing defaults, the initializer
|
@@ -50,24 +74,19 @@ class Lpxc
|
|
50
74
|
Thread.new {delay_flush} if opts[:disable_delay_flush].nil?
|
51
75
|
end
|
52
76
|
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
|
57
|
-
|
58
|
-
# was not specified in the initializer, then the user portion of the
|
59
|
-
# LOGPLEX_URL will be used.
|
60
|
-
def puts(msg, tok=nil)
|
77
|
+
#The interface to publish logs into the stream.
|
78
|
+
#This function will set the log message to the current time in UTC.
|
79
|
+
#If the buffer for this token's log messages is full, it will flush the buffer.
|
80
|
+
def puts(msg, tok=@default_token)
|
81
|
+
q = nil
|
61
82
|
@hash_lock.synchronize do
|
62
83
|
#Messages are grouped by their token since 1 http request
|
63
84
|
#to logplex must only contain log messages belonging to a single token.
|
64
|
-
q = @hash[tok] ||=
|
65
|
-
#This call will block if the queue is full.
|
66
|
-
#However this should never happen since the next command will flush
|
67
|
-
#the queue if we add the last item.
|
68
|
-
q.enq({:t => Time.now.utc, :token => (tok || default_token), :msg => msg})
|
69
|
-
flush if q.size == q.max
|
85
|
+
q = @hash[tok] ||= LogMsgQueue.new(@batch_size)
|
70
86
|
end
|
87
|
+
q.enqueue({:t => Time.now.utc, :token => tok, :msg => msg})
|
88
|
+
# Flush all of the queues if any queue is full.
|
89
|
+
flush if q.full?
|
71
90
|
end
|
72
91
|
|
73
92
|
#Wait until all of the data has been cleared from memory.
|
@@ -80,22 +99,25 @@ class Lpxc
|
|
80
99
|
@req_in_flight.zero?
|
81
100
|
end
|
82
101
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
102
|
+
# Empty all log messages into a request queue. Messages will be grouped
|
103
|
+
# by token such that each request contains messages with homogeneus tokens.
|
104
|
+
# A seperate thread will process the requests.
|
105
|
+
def flush
|
106
|
+
to_be_processed = nil
|
107
|
+
@hash_lock.synchronize do
|
108
|
+
to_be_processed = @hash
|
109
|
+
@hash = {}
|
110
|
+
end
|
111
|
+
process_hash(to_be_processed)
|
87
112
|
end
|
88
113
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
def flush
|
94
|
-
@hash.each do |tok, msgs|
|
114
|
+
private
|
115
|
+
|
116
|
+
def process_hash(h)
|
117
|
+
h.each do |tok, queue|
|
95
118
|
#Copy the messages from the queue into the payload array.
|
96
|
-
payloads =
|
97
|
-
|
98
|
-
return if payloads.nil? || payloads.empty?
|
119
|
+
payloads = queue.flush
|
120
|
+
next if payloads.nil? || payloads.empty?
|
99
121
|
|
100
122
|
#Use the payloads array to build a string that will be
|
101
123
|
#used as the http body for the logplex request.
|
@@ -107,16 +129,14 @@ class Lpxc
|
|
107
129
|
#Build a new HTTP request and place it into the queue
|
108
130
|
#to be processed by the HTTP connection.
|
109
131
|
req = Net::HTTP::Post.new(@logplex_url.path)
|
110
|
-
req.basic_auth("token",
|
132
|
+
req.basic_auth("token", tok)
|
111
133
|
req.add_field('Content-Type', 'application/logplex-1')
|
112
134
|
req.body = body
|
113
135
|
@request_queue.enq(req)
|
114
|
-
@hash.delete(tok)
|
115
136
|
@last_flush = Time.now
|
116
137
|
end
|
117
138
|
end
|
118
139
|
|
119
|
-
|
120
140
|
#This method must be called in order for the messages to be sent to Logplex.
|
121
141
|
#This method also spawns a thread that allows the messages to be batched.
|
122
142
|
#Messages are flushed from memory every 500ms or when we have 300 messages,
|
@@ -124,9 +144,7 @@ class Lpxc
|
|
124
144
|
def delay_flush
|
125
145
|
loop do
|
126
146
|
begin
|
127
|
-
if interval_ready?
|
128
|
-
@hash_lock.synchronize {flush}
|
129
|
-
end
|
147
|
+
flush if interval_ready?
|
130
148
|
sleep(0.01)
|
131
149
|
rescue => e
|
132
150
|
$stderr.puts("at=start-error error=#{e.message}") if ENV['DEBUG']
|