vigilant-ruby 0.0.3 → 0.0.5

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: 598917bbfe3086a946307f7a5722b1c134aa42f17203fcbd2efc7deed68e4778
4
- data.tar.gz: 2b19671efaca0de013d2591d2a1d5f077582d5e16c77950f7fd9b52a29b4a97a
3
+ metadata.gz: a0280598c4039160580005f39571754a95907101b616c6d3c8354da14eefb5de
4
+ data.tar.gz: 9ddebfc7149b3950006c8b45c0471955b00af3f99b2b88ffbf8754ed20d2187f
5
5
  SHA512:
6
- metadata.gz: d02b1cffbe3eb6bf5cb5e343ddc6f631d712089e3e121a779163556aaf0d8e8cef75370f8a768eb71ecea85e1c3a7eb486f901bd4ea8bc791d85ba6614952895
7
- data.tar.gz: 46a052c2a4f0ae1cab9083d8c50dd5b9e1a6950f893c408af5f9440a8acb41a42fed940cae98077fcd427d2222d565dc3a10148e5138735b9e38cee332908ba9
6
+ metadata.gz: 7d97948a8d9aef93514e6caa314caa4a502a721d21bc55dbe6fabcc1a98845718b6285da5ecf967a5e4554bb8157dc6d999613399e730f96103a4a254ae336a6
7
+ data.tar.gz: c47a61a034ee4271c7de661a765ca50fddf632c56b62a29bd8225127230fe04b4c3a5f788be0b1fd13d248e405f57e16e272f0705d66ae0161d6eeeb6ddbd80b
data/README.md CHANGED
@@ -1,3 +1,57 @@
1
1
  # Vigilant Ruby SDK
2
2
 
3
- This is the Ruby SDK for Vigilant (https://vigilant.run).
3
+ This is the Ruby SDK for Vigilant (https://vigilant.run).
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ gem install vigilant-ruby
9
+ ```
10
+
11
+ ## Logging Usage (Standard)
12
+
13
+ ```ruby
14
+ require 'vigilant-ruby'
15
+
16
+ # Initialize the logger
17
+ logger = Vigilant::Logger.new(
18
+ endpoint: "ingress.vigilant.run",
19
+ token: "tk_0000000000000000",
20
+ )
21
+
22
+ # Basic logging
23
+ logger.info('User logged in')
24
+ logger.warn('Rate limit approaching')
25
+ logger.error('Database connection failed')
26
+ logger.debug('Processing request')
27
+
28
+ # Logging with attributes
29
+ logger.info('User logged in', { user_id: 123, ip_address: '192.168.1.1' })
30
+
31
+ # Shutdown the logger
32
+ logger.shutdown
33
+ ```
34
+
35
+ ## Logging Usage (Autocapture)
36
+
37
+ ```ruby
38
+ require 'vigilant-ruby'
39
+
40
+ # Initialize the logger
41
+ logger = Vigilant::Logger.new(
42
+ endpoint: "ingress.vigilant.run",
43
+ token: "tk_0000000000000000",
44
+ )
45
+
46
+ # Enable autocapture
47
+ logger.autocapture_enable
48
+
49
+ # Log with autocapture
50
+ puts "A print statement"
51
+
52
+ # Log without autocapture
53
+ logger.info("A regular log")
54
+
55
+ # Shutdown the logger
56
+ logger.shutdown
57
+ ```
@@ -21,60 +21,48 @@ module Vigilant
21
21
  # @param endpoint [String] The base endpoint for the Vigilant API (e.g. "ingress.vigilant.run").
22
22
  # @param token [String] The authentication token for the Vigilant API.
23
23
  # @param insecure [Boolean] Whether to use HTTP instead of HTTPS (optional, defaults to false).
24
- def initialize(endpoint:, token:, insecure: false)
24
+ # @param passthrough [Boolean] Whether to also print logs to stdout/stderr (optional, defaults to true).
25
+ def initialize(endpoint:, token:, insecure: false, passthrough: true)
25
26
  @token = token
27
+
26
28
  protocol = insecure ? 'http://' : 'https://'
27
- endpoint = endpoint.sub(%r{^https?://}, '') # Remove any existing protocol
29
+ endpoint = endpoint.sub(%r{^https?://}, '') # remove any existing protocol
28
30
  @endpoint = URI.parse("#{protocol}#{endpoint}/api/message")
31
+
29
32
  @insecure = insecure
33
+ @passthrough = passthrough
30
34
 
31
- @batch_size = DEFAULT_BATCH_SIZE
35
+ @batch_size = DEFAULT_BATCH_SIZE
32
36
  @flush_interval = DEFAULT_FLUSH_INTERVAL
33
37
 
34
38
  @queue = Queue.new
35
39
  @mutex = Mutex.new
36
40
  @batch = []
37
41
 
38
- start_dispatcher
39
- end
42
+ @original_stdout = $stdout
43
+ @original_stderr = $stderr
40
44
 
41
- # Logs a TRACE message.
42
- #
43
- # @param body [String] The main text of the trace message.
44
- # @param attributes [Hash] Additional attributes for the log (optional).
45
- def trace(body, attributes = {})
46
- enqueue_log(TRACE, body, attributes)
45
+ @autocapture_enabled = false
46
+
47
+ start_dispatcher
47
48
  end
48
49
 
49
- # Logs a DEBUG message.
50
- #
51
- # @param body [String] The main text of the debug message.
52
- # @param attributes [Hash] Additional attributes for the log (optional).
50
+ # Logs a debug message.
53
51
  def debug(body, attributes = {})
54
52
  enqueue_log(DEBUG, body, attributes)
55
53
  end
56
54
 
57
- # Logs an INFO message.
58
- #
59
- # @param body [String] The main text of the log message.
60
- # @param attributes [Hash] Additional attributes for the log (optional).
55
+ # Logs an info message.
61
56
  def info(body, attributes = {})
62
57
  enqueue_log(INFO, body, attributes)
63
58
  end
64
59
 
65
- # Logs a WARNING message.
66
- #
67
- # @param body [String] The main text of the warning message.
68
- # @param attributes [Hash] Additional attributes for the log (optional).
60
+ # Logs a warning message.
69
61
  def warn(body, attributes = {})
70
62
  enqueue_log(WARNING, body, attributes)
71
63
  end
72
64
 
73
- # Logs an ERROR message.
74
- #
75
- # @param body [String] The main text of the error message.
76
- # @param error [Exception] The error object.
77
- # @param attributes [Hash] Additional attributes for the log (optional).
65
+ # Logs an error message.
78
66
  def error(body, error = nil, attributes = {})
79
67
  if error.nil?
80
68
  enqueue_log(ERROR, body, attributes)
@@ -84,27 +72,48 @@ module Vigilant
84
72
  end
85
73
  end
86
74
 
87
- def shutdown
88
- flush_if_needed(true)
75
+ # Enables stdout/stderr autocapture.
76
+ def autocapture_enable
77
+ return if @autocapture_enabled
89
78
 
90
- @mutex.synchronize do
91
- @shutdown = true
92
- end
79
+ @autocapture_enabled = true
80
+ $stdout = StdoutInterceptor.new(self, @original_stdout)
81
+ $stderr = StderrInterceptor.new(self, @original_stderr)
82
+ end
83
+
84
+ # Disables stdout/stderr autocapture.
85
+ def autocapture_disable
86
+ return unless @autocapture_enabled
87
+
88
+ @autocapture_enabled = false
89
+ $stdout = @original_stdout
90
+ $stderr = @original_stderr
91
+ end
93
92
 
93
+ # Shuts down the logger, flushing any pending logs.
94
+ def shutdown
95
+ flush_if_needed(force: true)
96
+ @mutex.synchronize { @shutdown = true }
94
97
  @dispatcher_thread&.join
95
98
  end
96
99
 
97
100
  private
98
101
 
99
102
  def enqueue_log(level, body, attributes)
100
- string_attributes = attributes.transform_values(&:to_s)
103
+ autocaptured = attributes.delete(:_autocapture)
104
+
101
105
  log_msg = {
102
106
  timestamp: Time.now.utc.strftime('%Y-%m-%dT%H:%M:%S.%9NZ'),
103
107
  body: body.to_s,
104
108
  level: level.to_s,
105
- attributes: string_attributes
109
+ attributes: attributes.transform_values(&:to_s)
106
110
  }
111
+
107
112
  @queue << log_msg
113
+
114
+ return unless @passthrough && !autocaptured
115
+
116
+ @original_stdout.puts(body)
108
117
  end
109
118
 
110
119
  def start_dispatcher
@@ -114,11 +123,11 @@ module Vigilant
114
123
  flush_if_needed
115
124
  sleep @flush_interval
116
125
  end
117
- flush_if_needed(true)
126
+ flush_if_needed(force: true)
118
127
  end
119
128
  end
120
129
 
121
- def flush_if_needed(force = false)
130
+ def flush_if_needed(force: false)
122
131
  until @queue.empty?
123
132
  msg = @queue.pop
124
133
  @mutex.synchronize { @batch << msg }
@@ -157,4 +166,110 @@ module Vigilant
157
166
  http.request(request)
158
167
  end
159
168
  end
169
+
170
+ # Interceptor for capturing stdout
171
+ class StdoutInterceptor
172
+ def initialize(logger, original)
173
+ @logger = logger
174
+ @original = original
175
+ end
176
+
177
+ def write(message)
178
+ @logger.info(message.strip, _autocapture: true) unless message.strip.empty?
179
+ @original.write(message)
180
+ end
181
+
182
+ def puts(*messages)
183
+ messages.each do |m|
184
+ @logger.info(m.to_s.strip, _autocapture: true) unless m.to_s.strip.empty?
185
+ end
186
+ @original.puts(*messages)
187
+ end
188
+
189
+ def print(*messages)
190
+ messages.each do |m|
191
+ @logger.info(m.to_s.strip, _autocapture: true) unless m.to_s.strip.empty?
192
+ end
193
+ @original.print(*messages)
194
+ end
195
+
196
+ def printf(*args)
197
+ formatted = sprintf(*args)
198
+ @logger.info(formatted.strip, _autocapture: true) unless formatted.strip.empty?
199
+ @original.printf(*args)
200
+ end
201
+
202
+ def flush
203
+ @original.flush
204
+ end
205
+
206
+ def close
207
+ @original.close
208
+ end
209
+
210
+ def tty?
211
+ @original.tty?
212
+ end
213
+
214
+ def respond_to_missing?(meth, include_private = false)
215
+ @original.respond_to?(meth, include_private)
216
+ end
217
+
218
+ def method_missing(meth, *args, &blk)
219
+ @original.send(meth, *args, &blk)
220
+ end
221
+ end
222
+
223
+ # Interceptor for capturing stderr
224
+ class StderrInterceptor
225
+ def initialize(logger, original)
226
+ @logger = logger
227
+ @original = original
228
+ end
229
+
230
+ def write(message)
231
+ @logger.error(message.strip, nil, _autocapture: true) unless message.strip.empty?
232
+ @original.write(message)
233
+ end
234
+
235
+ def puts(*messages)
236
+ messages.each do |m|
237
+ @logger.error(m.to_s.strip, nil, _autocapture: true) unless m.to_s.strip.empty?
238
+ end
239
+ @original.puts(*messages)
240
+ end
241
+
242
+ def print(*messages)
243
+ messages.each do |m|
244
+ @logger.error(m.to_s.strip, nil, _autocapture: true) unless m.to_s.strip.empty?
245
+ end
246
+ @original.print(*messages)
247
+ end
248
+
249
+ def printf(*args)
250
+ formatted = sprintf(*args)
251
+ @logger.error(formatted.strip, nil, _autocapture: true) unless formatted.strip.empty?
252
+ @original.printf(*args)
253
+ end
254
+
255
+ def flush
256
+ @original.flush
257
+ end
258
+
259
+ def close
260
+ @original.close
261
+ end
262
+
263
+ def tty?
264
+ @original.tty?
265
+ end
266
+
267
+ def respond_to_missing?(meth, include_private = false)
268
+ @original.respond_to?(meth, include_private)
269
+ end
270
+
271
+ def method_missing(meth, *args, &blk)
272
+ @original.send(meth, *args, &blk)
273
+ end
274
+ end
160
275
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Vigilant
4
- VERSION = '0.0.3'
4
+ VERSION = '0.0.5'
5
5
  end
data/lib/vigilant-ruby.rb CHANGED
@@ -10,12 +10,13 @@ module Vigilant
10
10
 
11
11
  # Configuration for the Vigilant logging service.
12
12
  class Configuration
13
- attr_accessor :endpoint, :token, :insecure
13
+ attr_accessor :endpoint, :token, :insecure, :passthrough
14
14
 
15
15
  def initialize
16
16
  @endpoint = 'ingress.vigilant.run'
17
17
  @insecure = false
18
18
  @token = 'tk_1234567890'
19
+ @passthrough = true
19
20
  end
20
21
  end
21
22
 
@@ -32,7 +33,8 @@ module Vigilant
32
33
  @logger ||= Vigilant::Logger.new(
33
34
  endpoint: configuration.endpoint,
34
35
  insecure: configuration.insecure,
35
- token: configuration.token
36
+ token: configuration.token,
37
+ passthrough: configuration.passthrough
36
38
  )
37
39
  end
38
40
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vigilant-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vigilant
@@ -37,34 +37,6 @@ dependencies:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
39
  version: '2.0'
40
- - !ruby/object:Gem::Dependency
41
- name: rake
42
- requirement: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - "~>"
45
- - !ruby/object:Gem::Version
46
- version: '13.0'
47
- type: :development
48
- prerelease: false
49
- version_requirements: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - "~>"
52
- - !ruby/object:Gem::Version
53
- version: '13.0'
54
- - !ruby/object:Gem::Dependency
55
- name: rbs
56
- requirement: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - "~>"
59
- - !ruby/object:Gem::Version
60
- version: '3.1'
61
- type: :development
62
- prerelease: false
63
- version_requirements: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - "~>"
66
- - !ruby/object:Gem::Version
67
- version: '3.1'
68
40
  - !ruby/object:Gem::Dependency
69
41
  name: rspec
70
42
  requirement: !ruby/object:Gem::Requirement
@@ -118,7 +90,6 @@ files:
118
90
  - lib/vigilant-ruby.rb
119
91
  - lib/vigilant-ruby/logger.rb
120
92
  - lib/vigilant-ruby/version.rb
121
- - sig/vigilant.rbs
122
93
  homepage: https://vigilant.run
123
94
  licenses:
124
95
  - MIT
data/sig/vigilant.rbs DELETED
@@ -1,92 +0,0 @@
1
- module Vigilant
2
- DEBUG: "DEBUG"
3
-
4
- INFO: "INFO"
5
-
6
- WARNING: "WARNING"
7
-
8
- ERROR: "ERROR"
9
-
10
- DEFAULT_BATCH_SIZE: 10
11
-
12
- DEFAULT_FLUSH_INTERVAL: 5
13
-
14
- # A thread-safe logger that batches logs and sends them to Vigilant asynchronously
15
- class Logger
16
- @token: untyped
17
-
18
- @endpoint: untyped
19
-
20
- @insecure: untyped
21
-
22
- @batch_size: untyped
23
-
24
- @flush_interval: untyped
25
-
26
- @queue: untyped
27
-
28
- @mutex: untyped
29
-
30
- @batch: untyped
31
-
32
- @shutdown: untyped
33
-
34
- @dispatcher_thread: untyped
35
-
36
- # Initialize a Vigilant::Logger instance.
37
- #
38
- # @param endpoint [String] The base endpoint for the Vigilant API (e.g. "ingress.vigilant.run").
39
- # @param token [String] The authentication token for the Vigilant API.
40
- # @param insecure [Boolean] Whether to use HTTP instead of HTTPS (optional, defaults to false).
41
- def initialize: (endpoint: untyped, token: untyped, ?insecure: bool) -> void
42
-
43
- # Logs a TRACE message.
44
- #
45
- # @param body [String] The main text of the trace message.
46
- # @param attributes [Hash] Additional attributes for the log (optional).
47
- def trace: (untyped body, ?::Hash[untyped, untyped] attributes) -> untyped
48
-
49
- # Logs a DEBUG message.
50
- #
51
- # @param body [String] The main text of the debug message.
52
- # @param attributes [Hash] Additional attributes for the log (optional).
53
- def debug: (untyped body, ?::Hash[untyped, untyped] attributes) -> untyped
54
-
55
- # Logs an INFO message.
56
- #
57
- # @param body [String] The main text of the log message.
58
- # @param attributes [Hash] Additional attributes for the log (optional).
59
- def info: (untyped body, ?::Hash[untyped, untyped] attributes) -> untyped
60
-
61
- # Logs a WARNING message.
62
- #
63
- # @param body [String] The main text of the warning message.
64
- # @param attributes [Hash] Additional attributes for the log (optional).
65
- def warn: (untyped body, ?::Hash[untyped, untyped] attributes) -> untyped
66
-
67
- # Logs an ERROR message.
68
- #
69
- # @param body [String] The main text of the error message.
70
- # @param error [Exception] The error object.
71
- # @param attributes [Hash] Additional attributes for the log (optional).
72
- def error: (untyped body, ?untyped? error, ?::Hash[untyped, untyped] attributes) -> untyped
73
-
74
- def shutdown: () -> untyped
75
-
76
- private
77
-
78
- def enqueue_log: (untyped level, untyped body, untyped attributes) -> untyped
79
-
80
- def start_dispatcher: () -> untyped
81
-
82
- def flush_if_needed: (?bool force) -> untyped
83
-
84
- def flush!: () -> untyped
85
-
86
- def post_logs: (untyped batch_data) -> untyped
87
- end
88
- end
89
-
90
- module Vigilant
91
- VERSION: "0.0.2"
92
- end