observable 0.1.0 → 0.1.4

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: c9b28e1e941ebdedee663e71a947dd92ec6e07e849092e7789cac95aa523bd80
4
- data.tar.gz: 658d6e07ac41ce13f30c14f61e69d2c9d59f79cc1008fac8d2471e040e7f028e
3
+ metadata.gz: b257d27b8a651f747109ea43b983befa02c2e10d34d13a49cf025a5f46eb7592
4
+ data.tar.gz: '068c6c31c24e4473682c9d5072842d995cd43a0fae9dee2ca2749a7313bc69a5'
5
5
  SHA512:
6
- metadata.gz: 971679e05648c3d2edf158604d1bfdff48afc68f814753b4bd452d38ed2b7fc6f623903c85dda63e65e592498fa4e541449b018b56ae7e42321329f62bd4ecb9
7
- data.tar.gz: cd8e357e76207915a044cbb38d541413d06da9548bc8f40ab0d39636f6ee49317f344f2aa95d2f0cfdcd0d37e54b2319e478b671b15767c5296e347a73119499
6
+ metadata.gz: 3d52b07648bd401f2494aa735e988a067c01bca1a443c1ee4ec609cebf582fc3eb3c59939c0b85a9880f0ad53a72b29495a249cea6bf92ee3dc8a114c674e340
7
+ data.tar.gz: eeb0349b60211293afe11f445789a3598e8ad2af6d577e53cf08958ec7237aa6c36799e047df11c0cb931ec6a960a085e14c2c96f79c5f504b6e0cf824ae03e2
@@ -0,0 +1,9 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(ruby:*)"
5
+ ],
6
+ "deny": [],
7
+ "ask": []
8
+ }
9
+ }
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.4.1
data/.standard.yml CHANGED
@@ -1,3 +1,7 @@
1
1
  # For available configuration options, see:
2
2
  # https://github.com/testdouble/standard
3
- ruby_version: 2.6
3
+ ruby_version: 3.4
4
+ fix: true
5
+ parallel: true
6
+ ignore:
7
+ - Gemfile.lock
data/CHANGELOG.md CHANGED
@@ -1,5 +1,57 @@
1
1
  ## [Unreleased]
2
2
 
3
+
4
+
5
+
6
+
7
+ ## [0.1.4] - 2025-09-08
8
+
9
+ ### Changed
10
+ - Update version bumping logic in bump script
11
+ - v0.1.3-beta
12
+ - Update gem build process and release script
13
+ - v0.1.2-beta
14
+
15
+
16
+ ## [0.1.2-beta] - 2025-09-08
17
+
18
+ ### Changed
19
+ - v0.1.2-beta
20
+
21
+
22
+ ## [0.1.2-alpha] - 2025-09-08
23
+
24
+ ### Added
25
+ - Add support for bumping alpha and beta pre-releases
26
+
27
+ ### Changed
28
+ - Update version bumping logic for bump gem
29
+ - Delegate all version bumping to bump gem
30
+ - Extract configuration into class
31
+ - Update gemspec and test setup for OTLP exporter
32
+
33
+
34
+ ## [0.1.2-alpha] - 2025-09-08
35
+
36
+ ### Added
37
+ - Add support for bumping alpha and beta pre-releases
38
+
39
+ ### Fixed
40
+ - Update version to 0.1.2
41
+
42
+ ### Changed
43
+ - Delegate all version bumping to bump gem
44
+ - v0.1.2-alpha
45
+ - Extract configuration into class
46
+ - Update gemspec and test setup for OTLP exporter
47
+ - Add 'ignore' section to configuration file
48
+
49
+
50
+ ## [0.1.2] - 2025-09-07
51
+
52
+ ### Changed
53
+ - Add Ruby 3.2.x versions to GitHub Actions matrix for better CI coverage
54
+
3
55
  ## [0.1.0] - 2024-04-22
4
56
 
5
57
  - Initial release
data/CLAUDE.md ADDED
@@ -0,0 +1,135 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ This is the Observable gem - a Ruby library that provides OpenTelemetry instrumentation for method calls with configurable serialization, PII filtering, and argument tracking. It automatically captures method invocation details, arguments, return values, and exceptions as OpenTelemetry spans.
8
+
9
+ ## Core Architecture
10
+
11
+ ### Main Components
12
+
13
+ - **Observable::Instrumenter** (`lib/observable/instrumenter.rb`) - The core instrumentation engine that wraps method calls with OpenTelemetry spans
14
+ - **Observable::Configuration** (`lib/observable/instrumenter.rb`) - Uses Dry::Configurable for flexible configuration management
15
+ - **ArgumentExtractor** (`lib/observable/instrumenter.rb`) - Extracts method arguments from Ruby bindings using introspection
16
+ - **CallerInformation** (`lib/observable/instrumenter.rb`) - Value object containing method metadata (name, namespace, filepath, line number, arguments)
17
+
18
+ ### Key Features
19
+
20
+ - **Automatic method instrumentation** - Wrap any method call with `instrumenter.instrument(binding) { ... }`
21
+ - **Argument tracking** - Captures method parameters with PII filtering capabilities
22
+ - **Return value serialization** - Configurable tracking of method return values
23
+ - **Exception handling** - Automatically captures and records exceptions in spans
24
+ - **Class/instance method detection** - Distinguishes between static (`.`) and instance (`#`) methods
25
+ - **Configurable serialization** - Supports custom formatters and max depth limits
26
+
27
+ ## Development Commands
28
+
29
+ ### Running Tests
30
+ ```bash
31
+ bundle exec rake test
32
+ ```
33
+
34
+ ### Running Individual Tests
35
+ ```bash
36
+ ruby -Itest test/unit/instrumenter_test.rb
37
+ ```
38
+
39
+ ### Linting
40
+ ```bash
41
+ bundle exec standardrb
42
+ ```
43
+
44
+ ### Dependencies
45
+ ```bash
46
+ bundle install
47
+ ```
48
+
49
+ ### Interactive Console
50
+ ```bash
51
+ bin/console
52
+ ```
53
+
54
+ ### Build Gem
55
+ ```bash
56
+ bundle exec rake build
57
+ ```
58
+
59
+ ### Version Management
60
+ ```bash
61
+ # Bump patch version (0.1.1 -> 0.1.2)
62
+ bin/bump
63
+
64
+ # Bump minor version (0.1.1 -> 0.2.0)
65
+ bin/bump --minor
66
+
67
+ # Bump major version (0.1.1 -> 1.0.0)
68
+ bin/bump --major
69
+ ```
70
+
71
+ ### Release Process
72
+
73
+ The project uses automated releases via GitHub Actions:
74
+
75
+ 1. **Manual Release**: Use `bin/bump` to increment version, update CHANGELOG.md, then commit and push to `main`
76
+ 2. **Automated Release**: When a version change is detected in a push to `main`, GitHub Actions will:
77
+ - Run tests across multiple Ruby versions
78
+ - Run linting checks
79
+ - Build the gem
80
+ - Create a GitHub release with changelog
81
+ - Publish to RubyGems (requires `RUBYGEMS_API_KEY` secret)
82
+
83
+ **Prerequisites for automated release:**
84
+ - Set `RUBYGEMS_API_KEY` secret in GitHub repository settings
85
+ - Ensure CHANGELOG.md is updated with meaningful changes
86
+
87
+ ## Configuration System
88
+
89
+ The gem uses Dry::Configurable with these key settings:
90
+
91
+ - `transport` - Transport mechanism (default: `:otel`)
92
+ - `app_namespace` - Application namespace for spans
93
+ - `attribute_namespace` - Attribute namespace prefix
94
+ - `tracer_names` - OpenTelemetry tracer configuration
95
+ - `formatters` - Object serialization methods (default: `:to_h`)
96
+ - `pii_filters` - Regex patterns to filter sensitive data
97
+ - `track_return_values` - Enable/disable return value capture (default: true)
98
+
99
+ ## Usage Pattern
100
+
101
+ The primary usage pattern involves:
102
+
103
+ 1. Create an instrumenter instance: `Observable::Instrumenter.new`
104
+ 2. Wrap method calls: `instrumenter.instrument(binding) { method_logic }`
105
+ 3. The instrumenter automatically:
106
+ - Extracts method name, class, and arguments from `binding`
107
+ - Creates OpenTelemetry spans with standardized naming (`Class#method` or `Class.method`)
108
+ - Serializes arguments and return values with PII filtering
109
+ - Handles exceptions and sets appropriate span status
110
+
111
+ ## Testing Structure
112
+
113
+ - **Unit tests** in `test/unit/` - Test individual components
114
+ - **Support helpers** in `test/support/` - Test utilities and mocks
115
+ - Uses Minitest framework
116
+ - Custom tracing test helpers for OpenTelemetry span verification
117
+
118
+ ## Dependencies
119
+
120
+ **Runtime:**
121
+ - `opentelemetry-sdk` ~> 1.5 - OpenTelemetry instrumentation
122
+ - `dry-configurable` >= 0.13.0, < 2.0 - Configuration management
123
+ - `dry-struct` ~> 1.4 - Value objects
124
+
125
+ **Development:**
126
+ - `minitest` ~> 5.14 - Testing framework
127
+ - `standard` ~> 1.40 - Ruby linting and formatting
128
+ - `rake` ~> 13.0 - Build automation
129
+
130
+ ## Code Style
131
+
132
+ - Uses Standard Ruby for linting and formatting
133
+ - Ruby version: 3.4+ (configured in `.ruby-version` and `.standard.yml`)
134
+ - Frozen string literals enforced
135
+ - Follows Ruby community conventions for method naming and structure
data/Gemfile CHANGED
@@ -4,9 +4,3 @@ source "https://rubygems.org"
4
4
 
5
5
  # Specify your gem's dependencies in observable.gemspec
6
6
  gemspec
7
-
8
- gem "rake", "~> 13.0"
9
-
10
- gem "minitest", "~> 5.0"
11
-
12
- gem "standard", "~> 1.3"
data/Gemfile.lock ADDED
@@ -0,0 +1,178 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ observable (0.1.4)
5
+ dry-configurable (>= 0.13.0, < 2.0)
6
+ dry-struct (~> 1.4)
7
+ opentelemetry-sdk (~> 1.5)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ ast (2.4.3)
13
+ attr_extras (7.1.0)
14
+ bigdecimal (3.2.3)
15
+ bump (0.10.0)
16
+ concurrent-ruby (1.3.5)
17
+ date (3.4.1)
18
+ debug (1.11.0)
19
+ irb (~> 1.10)
20
+ reline (>= 0.3.8)
21
+ diff-lcs (1.6.2)
22
+ docile (1.4.1)
23
+ dry-configurable (1.3.0)
24
+ dry-core (~> 1.1)
25
+ zeitwerk (~> 2.6)
26
+ dry-core (1.1.0)
27
+ concurrent-ruby (~> 1.0)
28
+ logger
29
+ zeitwerk (~> 2.6)
30
+ dry-inflector (1.2.0)
31
+ dry-logic (1.6.0)
32
+ bigdecimal
33
+ concurrent-ruby (~> 1.0)
34
+ dry-core (~> 1.1)
35
+ zeitwerk (~> 2.6)
36
+ dry-struct (1.8.0)
37
+ dry-core (~> 1.1)
38
+ dry-types (~> 1.8, >= 1.8.2)
39
+ ice_nine (~> 0.11)
40
+ zeitwerk (~> 2.6)
41
+ dry-types (1.8.3)
42
+ bigdecimal (~> 3.0)
43
+ concurrent-ruby (~> 1.0)
44
+ dry-core (~> 1.0)
45
+ dry-inflector (~> 1.0)
46
+ dry-logic (~> 1.4)
47
+ zeitwerk (~> 2.6)
48
+ erb (5.0.2)
49
+ google-protobuf (4.32.0)
50
+ bigdecimal
51
+ rake (>= 13)
52
+ google-protobuf (4.32.0-arm64-darwin)
53
+ bigdecimal
54
+ rake (>= 13)
55
+ googleapis-common-protos-types (1.21.0)
56
+ google-protobuf (~> 4.26)
57
+ ice_nine (0.11.2)
58
+ io-console (0.8.1)
59
+ irb (1.15.2)
60
+ pp (>= 0.6.0)
61
+ rdoc (>= 4.0.0)
62
+ reline (>= 0.4.2)
63
+ json (2.13.2)
64
+ language_server-protocol (3.17.0.5)
65
+ lint_roller (1.1.0)
66
+ logger (1.7.0)
67
+ m (1.6.2)
68
+ method_source (>= 0.6.7)
69
+ rake (>= 0.9.2.2)
70
+ method_source (1.1.0)
71
+ minitest (5.25.5)
72
+ opentelemetry-api (1.6.0)
73
+ opentelemetry-common (0.22.0)
74
+ opentelemetry-api (~> 1.0)
75
+ opentelemetry-exporter-otlp (0.30.0)
76
+ google-protobuf (>= 3.18)
77
+ googleapis-common-protos-types (~> 1.3)
78
+ opentelemetry-api (~> 1.1)
79
+ opentelemetry-common (~> 0.20)
80
+ opentelemetry-sdk (~> 1.2)
81
+ opentelemetry-semantic_conventions
82
+ opentelemetry-registry (0.4.0)
83
+ opentelemetry-api (~> 1.1)
84
+ opentelemetry-sdk (1.8.1)
85
+ opentelemetry-api (~> 1.1)
86
+ opentelemetry-common (~> 0.20)
87
+ opentelemetry-registry (~> 0.2)
88
+ opentelemetry-semantic_conventions
89
+ opentelemetry-semantic_conventions (1.11.0)
90
+ opentelemetry-api (~> 1.0)
91
+ optimist (3.2.1)
92
+ parallel (1.27.0)
93
+ parser (3.3.9.0)
94
+ ast (~> 2.4.1)
95
+ racc
96
+ patience_diff (1.2.0)
97
+ optimist (~> 3.0)
98
+ pp (0.6.2)
99
+ prettyprint
100
+ prettyprint (0.2.0)
101
+ prism (1.4.0)
102
+ psych (5.2.6)
103
+ date
104
+ stringio
105
+ racc (1.8.1)
106
+ rainbow (3.1.1)
107
+ rake (13.3.0)
108
+ rdoc (6.14.2)
109
+ erb
110
+ psych (>= 4.0.0)
111
+ regexp_parser (2.11.2)
112
+ reline (0.6.2)
113
+ io-console (~> 0.5)
114
+ rubocop (1.75.8)
115
+ json (~> 2.3)
116
+ language_server-protocol (~> 3.17.0.2)
117
+ lint_roller (~> 1.1.0)
118
+ parallel (~> 1.10)
119
+ parser (>= 3.3.0.2)
120
+ rainbow (>= 2.2.2, < 4.0)
121
+ regexp_parser (>= 2.9.3, < 3.0)
122
+ rubocop-ast (>= 1.44.0, < 2.0)
123
+ ruby-progressbar (~> 1.7)
124
+ unicode-display_width (>= 2.4.0, < 4.0)
125
+ rubocop-ast (1.46.0)
126
+ parser (>= 3.3.7.2)
127
+ prism (~> 1.4)
128
+ rubocop-performance (1.25.0)
129
+ lint_roller (~> 1.1)
130
+ rubocop (>= 1.75.0, < 2.0)
131
+ rubocop-ast (>= 1.38.0, < 2.0)
132
+ ruby-progressbar (1.13.0)
133
+ simplecov (0.22.0)
134
+ docile (~> 1.1)
135
+ simplecov-html (~> 0.11)
136
+ simplecov_json_formatter (~> 0.1)
137
+ simplecov-html (0.13.2)
138
+ simplecov_json_formatter (0.1.4)
139
+ standard (1.50.0)
140
+ language_server-protocol (~> 3.17.0.2)
141
+ lint_roller (~> 1.0)
142
+ rubocop (~> 1.75.5)
143
+ standard-custom (~> 1.0.0)
144
+ standard-performance (~> 1.8)
145
+ standard-custom (1.0.2)
146
+ lint_roller (~> 1.0)
147
+ rubocop (~> 1.50)
148
+ standard-performance (1.8.0)
149
+ lint_roller (~> 1.1)
150
+ rubocop-performance (~> 1.25.0)
151
+ stringio (3.1.7)
152
+ super_diff (0.16.0)
153
+ attr_extras (>= 6.2.4)
154
+ diff-lcs
155
+ patience_diff
156
+ unicode-display_width (3.1.5)
157
+ unicode-emoji (~> 4.0, >= 4.0.4)
158
+ unicode-emoji (4.0.4)
159
+ zeitwerk (2.7.3)
160
+
161
+ PLATFORMS
162
+ arm64-darwin-23
163
+ ruby
164
+
165
+ DEPENDENCIES
166
+ bump (~> 0.10)
167
+ debug (~> 1.8)
168
+ m (~> 1.6)
169
+ minitest (~> 5.14)
170
+ observable!
171
+ opentelemetry-exporter-otlp (~> 0.30)
172
+ rake (~> 13.0)
173
+ simplecov (~> 0.22)
174
+ standard (~> 1.40)
175
+ super_diff (~> 0.9)
176
+
177
+ BUNDLED WITH
178
+ 2.6.3
data/README.md CHANGED
@@ -1,37 +1,168 @@
1
1
  # Observable
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/observable`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ Automatic OpenTelemetry instrumentation for Ruby methods with configurable serialization, PII filtering, and argument tracking.
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ ## Getting Started
6
6
 
7
- ## Installation
7
+ ```bash
8
+ bundle add observable
9
+ ```
8
10
 
9
- Install the gem and add to the application's Gemfile by executing:
11
+ Or
10
12
 
11
- $ bundle add observable
13
+ ```ruby
14
+ # Gemfile
15
+ gem 'observable'
16
+ ```
12
17
 
13
- If bundler is not being used to manage dependencies, install the gem by executing:
18
+ Basic usage:
14
19
 
15
- $ gem install observable
20
+ ```ruby
21
+ require 'observable'
16
22
 
17
- ## Usage
18
-
19
- TODO: Write usage instructions here
20
-
21
- ## Development
22
-
23
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
24
-
25
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
26
-
27
- ## Contributing
28
-
29
- Bug reports and pull requests are welcome on GitHub at https://github.com/johngallagher/observable. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/johngallagher/observable/blob/main/CODE_OF_CONDUCT.md).
23
+ class UserService
24
+ def initialize
25
+ @instrumenter = Observable::Instrumenter.new
26
+ end
27
+
28
+ def create_user(name, email)
29
+ @instrumenter.instrument(binding) do
30
+ User.create(name: name, email: email)
31
+ end
32
+ end
33
+ end
34
+ ```
35
+
36
+ OpenTelemetry spans are automatically created with method names, arguments, return values, and exceptions.
37
+
38
+ ## Configuration
39
+
40
+ Configure globally or per-instrumenter:
41
+
42
+ ```ruby
43
+ # Global configuration
44
+ Observable::Configuration.configure do |config|
45
+ config.tracer_name = "my_app"
46
+ config.transport = :otel
47
+ config.app_namespace = "my_app"
48
+ config.attribute_namespace = "my_app"
49
+ config.track_return_values = true
50
+ config.serialization_depth = {default: 2, "MyClass" => 3}
51
+ config.formatters = {default: :to_h, "MyClass" => :to_formatted_h}
52
+ config.pii_filters = [/password/i, /secret/i]
53
+ end
54
+
55
+ # Per-instrumenter configuration
56
+ config = Observable::Configuration.new
57
+ config.track_return_values = false
58
+ instrumenter = Observable::Instrumenter.new(config: config)
59
+ ```
60
+
61
+ ### Configuration Options
62
+
63
+ - `tracer_name`: `"observable"` - Name for the OpenTelemetry tracer
64
+ - `transport`: `:otel` - Uses OpenTelemetry SDK
65
+ - `app_namespace`: `"app"` - Namespace for application-specific attributes
66
+ - `attribute_namespace`: `"app"` - Namespace for span attributes
67
+ - `track_return_values`: `true` - Captures method return values in spans
68
+ - `serialization_depth`: `{default: 2}` - Per-class serialization depth limits (Hash or Integer for backward compatibility)
69
+ - `formatters`: `{default: :to_h}` - Object serialization methods by class name
70
+ - `pii_filters`: `[]` - Regex patterns to filter sensitive data from spans
71
+
72
+ ## OpenTelemetry Integration
73
+
74
+ This library seamlessly integrates with OpenTelemetry, the industry-standard observability framework. Spans are automatically created with standardized naming (`Class#method` or `Class.method`) and include rich metadata about method invocations, making your Ruby applications immediately observable without manual instrumentation.
75
+
76
+ ## Custom Formatters
77
+
78
+ Control how domain objects are serialized in spans by configuring custom formatters.
79
+
80
+ ```ruby
81
+ Observable::Configuration.configure do |config|
82
+ config.formatters = {
83
+ default: :to_h,
84
+ 'YourCustomClass' => :to_formatted_h
85
+ }
86
+ config.serialization_depth = {
87
+ default: 2,
88
+ 'YourCustomClass' => 3
89
+ }
90
+ end
91
+ ```
92
+
93
+ ## Example
94
+
95
+ A domain object `Customer` has an `Invoice`.
96
+
97
+ ### Objective
98
+
99
+ Only send the invoice ID to the trace to save data.
100
+
101
+ ### Background
102
+
103
+ Imagine domain objects are `Dry::Struct` value objects:
104
+
105
+ ```ruby
106
+ class Customer < Dry::Struct
107
+ attribute :id, Dry.Types::String
108
+ attribute :name, Dry.Types::String
109
+ attribute :Invoice, Invoice
110
+ end
111
+
112
+ class Invoice < Dry::Struct
113
+ attribute :id, Dry.Types::String
114
+ attribute :status, Dry.Types::String
115
+ attribute :line_items, Dry.Types::Array
116
+ end
117
+ ```
118
+
119
+ ### Solution
120
+
121
+ 1. Define custom formatting method - `#to_formatted_h`
122
+
123
+ ```diff
124
+ class Customer < Dry::Struct
125
+ attribute :id, Dry.Types::String
126
+ attribute :name, Dry.Types::String
127
+ attribute :Invoice, Invoice
128
+
129
+ + def to_formatted_h
130
+ + {
131
+ + id: id,
132
+ + name: name,
133
+ + invoice: {
134
+ + id: invoice.id
135
+ + }
136
+ + }
137
+ + end
138
+ end
139
+ ```
140
+
141
+ 2. Configure observable:
142
+
143
+ ```ruby
144
+ Observable::Configuration.configure do |config|
145
+ config.formatters = {
146
+ default: :to_h,
147
+ 'Customer' => :to_formatted_h
148
+ }
149
+ config.serialization_depth = {
150
+ default: 2,
151
+ 'Customer' => 3
152
+ }
153
+ end
154
+ ```
155
+
156
+ The instrumenter tries class-specific formatters first, then falls back to the default formatter, then `to_s`.
157
+
158
+ ## Benefits
159
+
160
+ Why use this library? Why not write Otel attributes manually?
161
+
162
+ * **Zero-touch instrumentation** - Wrap any method call without modifying existing code or manually creating spans
163
+ * **Production-ready safety** - Built-in PII filtering, serialization depth limits, and exception handling prevent common observability pitfalls
164
+ * **Standardized telemetry** - Consistent span naming, attribute structure, and OpenTelemetry compliance across your entire application
30
165
 
31
166
  ## License
32
167
 
33
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
34
-
35
- ## Code of Conduct
36
-
37
- Everyone interacting in the Observable project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/johngallagher/observable/blob/main/CODE_OF_CONDUCT.md).
168
+ MIT License. See LICENSE file for details.
data/Rakefile CHANGED
@@ -6,9 +6,7 @@ require "rake/testtask"
6
6
  Rake::TestTask.new(:test) do |t|
7
7
  t.libs << "test"
8
8
  t.libs << "lib"
9
- t.test_files = FileList["test/**/test_*.rb"]
9
+ t.test_files = FileList["test/**/*_test.rb"]
10
10
  end
11
11
 
12
- require "standard/rake"
13
-
14
- task default: %i[test standard]
12
+ task default: %i[test]
data/example.rb ADDED
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "lib/observable"
4
+
5
+ # Configure the instrumenter
6
+ Observable::Configuration.configure do |config|
7
+ config.app_namespace = "example_app"
8
+ config.track_return_values = true
9
+ config.pii_filters = [/password/, /token/, /secret/]
10
+ end
11
+
12
+ class ExampleService
13
+ def initialize
14
+ @instrumenter = Observable::Instrumenter.new
15
+ end
16
+
17
+ def process_order(order_id, customer_email, amount)
18
+ @instrumenter.instrument(binding) do
19
+ # Simulate some processing
20
+ puts "Processing order #{order_id} for #{customer_email}, amount: #{amount}"
21
+
22
+ # Return a result hash
23
+ {
24
+ order_id: order_id,
25
+ status: "processed",
26
+ processed_at: Time.now.to_i,
27
+ amount: amount
28
+ }
29
+ end
30
+ end
31
+
32
+ def self.static_method(data)
33
+ instrumenter = Observable::Instrumenter.new
34
+ instrumenter.instrument(binding) do
35
+ puts "Processing data: #{data.inspect}"
36
+ data.transform_values(&:upcase) if data.is_a?(Hash)
37
+ end
38
+ end
39
+ end
40
+
41
+ # Example usage
42
+ puts "=== Observable Example ==="
43
+ puts
44
+
45
+ service = ExampleService.new
46
+ result = service.process_order("ORD-123", "customer@example.com", 99.99)
47
+ puts "Result: #{result}"
48
+
49
+ puts
50
+
51
+ static_result = ExampleService.static_method({name: "john", city: "nyc"})
52
+ puts "Static result: #{static_result}"
53
+
54
+ puts "\n=== Check OpenTelemetry spans were created ==="
55
+ # In a real application, these spans would be exported to your observability platform
@@ -0,0 +1,17 @@
1
+ require "dry/configurable"
2
+
3
+ module Observable
4
+ class Configuration
5
+ extend Dry::Configurable
6
+
7
+ setting :tracer_name, default: "observable"
8
+ setting :transport, default: :otel
9
+ setting :app_namespace, default: "app"
10
+ setting :attribute_namespace, default: "app"
11
+ setting :formatters, default: {default: :to_h}
12
+ setting :pii_filters, default: []
13
+ setting :serialization_depth, default: {default: 2}
14
+ setting :track_return_values, default: true
15
+ setting :custom_error_converters, default: {}
16
+ end
17
+ end