opentrace 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: b4a10bb3e35d7526cb02f721c1040ad9f568fa6058d17d1e7aaf1bf31d42ecd6
4
- data.tar.gz: 64f7700651c457151c9d9a961a8bba205cf88d0746265e6eebaa7f928e2c0f9b
3
+ metadata.gz: b531ffb7419d2f4eb8a6c4acafa2b6efcfa7d051cde050fd162ddaa62df18ab1
4
+ data.tar.gz: 171e500952906bcc8839ede080a280cb718b08a28bb92cef2f926f19bdbc2bc3
5
5
  SHA512:
6
- metadata.gz: fcd303032ee0ae96aeb6602ffdd3a60df2972e58cfff1c6499f5cc17ea57c89a0ffe6e5e092a9eb7c0ccb55f798afcfbce13f34ac789e70908d890a42da5699f
7
- data.tar.gz: 54f2c8bfd37f9a36b9f32aa49b76a6846335ab0063e804fb35aa491892d18d4a560c410e9204b667ebd5e57cfe522114d677f8973b788a897084a6ce12e62bb1
6
+ metadata.gz: c986dcdb9bb7d82236d2d77255f207e29df203204c49f8f6c89df3a20fc550cd0bc7f409b4738d5c0a872bac24abc160dc74f33a7c545ec0ff76f0fe2a0ac148
7
+ data.tar.gz: 7c2954dbaf1cced147e3937d7c5e610235a15469a231cf9dde619c6bb9d4f4c4ada3b28a1520a1ecc8704dc37933e8855221e8b2b156018fcea041450adfed66
data/README.md CHANGED
@@ -3,7 +3,9 @@
3
3
  [![Gem Version](https://badge.fury.io/rb/opentrace.svg)](https://rubygems.org/gems/opentrace)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
5
5
 
6
- A thin, safe Ruby client that forwards structured application logs to an [OpenTrace](https://github.com/adham90/opentrace-ruby) server over HTTP.
6
+ A thin, safe Ruby client that forwards structured application logs to an [OpenTrace](https://github.com/adham90/opentrace) server over HTTP.
7
+
8
+ > **OpenTrace Server** -- This gem requires a running [OpenTrace server](https://github.com/adham90/opentrace). OpenTrace is a self-hosted observability tool for logs, database monitoring, and intelligent alerting. See the [server repo](https://github.com/adham90/opentrace) for setup instructions.
7
9
 
8
10
  **This gem will never crash or slow down your application.** All network errors are swallowed silently. If the server is unreachable, logs are dropped -- your app continues running normally.
9
11
 
@@ -14,8 +16,11 @@ A thin, safe Ruby client that forwards structured application logs to an [OpenTr
14
16
  - **Batch sending** -- groups logs into configurable batches for efficient network usage
15
17
  - **Bounded queue** -- caps at 1,000 entries to prevent memory bloat
16
18
  - **Smart truncation** -- oversized payloads are truncated instead of silently dropped
19
+ - **Works with any server** -- Puma (threads), Unicorn (forks), Passenger, and Falcon (fibers)
20
+ - **Fork safe** -- detects forked worker processes and re-initializes cleanly
21
+ - **Fiber safe** -- uses `Fiber[]` storage for correct request isolation in fiber-based servers
17
22
  - **Rails integration** -- auto-instruments controllers, SQL queries, and ActiveJob via Railtie
18
- - **Rack middleware** -- propagates `request_id` via thread-local storage
23
+ - **Rack middleware** -- propagates `request_id` via fiber-local storage
19
24
  - **Logger wrapper** -- drop-in replacement that forwards to OpenTrace while keeping your original logger
20
25
  - **Rails 7.1+ BroadcastLogger** -- native support via `broadcast_to`
21
26
  - **TaggedLogging** -- preserves `ActiveSupport::TaggedLogging` tags in metadata
@@ -24,6 +29,7 @@ A thin, safe Ruby client that forwards structured application logs to an [OpenTr
24
29
  - **Auto-enrichment** -- every log includes `hostname`, `pid`, and `git_sha` automatically
25
30
  - **Exception helper** -- `OpenTrace.error` captures class, message, and cleaned backtrace
26
31
  - **Runtime controls** -- enable/disable logging at runtime without restarting
32
+ - **Graceful shutdown** -- pending logs are flushed automatically on process exit
27
33
 
28
34
  ## Installation
29
35
 
@@ -179,7 +185,7 @@ end
179
185
  # Dynamic context (evaluated on each log call)
180
186
  OpenTrace.configure do |c|
181
187
  # ...
182
- c.context = -> { { request_id: Thread.current[:request_id], tenant: Current.tenant&.slug } }
188
+ c.context = -> { { tenant: Current.tenant&.slug } }
183
189
  end
184
190
  ```
185
191
 
@@ -205,6 +211,8 @@ The gem auto-detects Rails and provides the following integrations automatically
205
211
 
206
212
  Automatically inserted into the middleware stack. Captures `request_id` from `action_dispatch.request_id` or `HTTP_X_REQUEST_ID` and makes it available via `OpenTrace.current_request_id`. All logs within a request automatically include the `request_id`.
207
213
 
214
+ Request IDs are stored using `Fiber[]` (fiber-local storage), which works correctly in both threaded servers (Puma) and fiber-based servers (Falcon).
215
+
208
216
  ### Logger Wrapping
209
217
 
210
218
  - **Rails 7.1+**: Uses `BroadcastLogger#broadcast_to` to register as a broadcast target (non-invasive)
@@ -299,7 +307,9 @@ OpenTrace.enable! # turn back on
299
307
 
300
308
  ## Graceful Shutdown
301
309
 
302
- If your app needs a clean shutdown (e.g. a Sidekiq worker), drain the queue before exiting:
310
+ An `at_exit` hook is registered automatically to flush pending logs (up to 2 seconds) when the process exits. No configuration needed.
311
+
312
+ For manual control (e.g. a Sidekiq worker), you can drain the queue explicitly:
303
313
 
304
314
  ```ruby
305
315
  OpenTrace.shutdown(timeout: 5)
@@ -307,6 +317,21 @@ OpenTrace.shutdown(timeout: 5)
307
317
 
308
318
  This gives the background thread up to 5 seconds to send any remaining queued logs.
309
319
 
320
+ ## Server Compatibility
321
+
322
+ OpenTrace works with any Rack-compatible Ruby web server:
323
+
324
+ | Server | Concurrency | Support |
325
+ |---|---|---|
326
+ | **Puma** | Threads | Full support |
327
+ | **Unicorn** | Forked workers | Full support (fork-safe) |
328
+ | **Passenger** | Forks + threads | Full support (fork-safe) |
329
+ | **Falcon** | Fibers | Full support (fiber-safe) |
330
+
331
+ **Fork safety**: When a process forks (Puma cluster mode, Unicorn, Passenger), the background dispatch thread from the parent is dead in the child. OpenTrace detects the fork via PID check and cleanly re-initializes the queue, mutex, and thread.
332
+
333
+ **Fiber safety**: Request IDs use `Fiber[]` storage instead of `Thread.current`, so concurrent requests on the same thread (as in Falcon) are correctly isolated.
334
+
310
335
  ## How It Works
311
336
 
312
337
  ```
@@ -315,12 +340,14 @@ Your App --log()--> [In-Memory Queue] --background thread--> POST /api/logs -->
315
340
 
316
341
  - Logs are serialized to JSON and pushed onto an in-memory queue
317
342
  - A single background thread reads from the queue and sends batches via `POST /api/logs`
343
+ - `enqueue` is non-blocking -- it uses `try_lock` so it never waits on a mutex
318
344
  - The thread is started lazily on the first log call -- no threads are created at boot
319
345
  - If the queue exceeds 1,000 items, new logs are dropped (oldest are preserved)
320
346
  - Payloads exceeding 32 KB are intelligently truncated (backtrace, params, SQL removed first)
321
347
  - If still too large after truncation, the payload is split and retried in smaller batches
322
348
  - All network errors (timeouts, connection refused, DNS failures) are swallowed silently
323
349
  - The HTTP timeout defaults to 1 second
350
+ - Pending logs are flushed on process exit via an `at_exit` hook
324
351
 
325
352
  ## Log Payload Format
326
353
 
@@ -358,7 +385,7 @@ The server accepts a single JSON object or an array of objects.
358
385
 
359
386
  ## Requirements
360
387
 
361
- - Ruby >= 3.0
388
+ - Ruby >= 3.2 (uses `Fiber[]` for fiber-local storage)
362
389
  - Rails >= 6 (optional, auto-detected)
363
390
 
364
391
  ## License
@@ -105,7 +105,7 @@ module OpenTrace
105
105
  end
106
106
 
107
107
  break if batch.size >= @config.batch_size
108
- break if Time.now >= deadline && !batch.empty?
108
+ break if Time.now >= deadline
109
109
  break if @queue.closed?
110
110
  end
111
111
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OpenTrace
4
- VERSION = "0.2.0"
4
+ VERSION = "0.2.1"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opentrace
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenTrace
@@ -52,7 +52,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - ">="
54
54
  - !ruby/object:Gem::Version
55
- version: 3.0.0
55
+ version: 3.2.0
56
56
  required_rubygems_version: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - ">="