pstore_logger 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 38a6e72b650af79fb37cf2e51a2cc45023e0f9c795c2cd03dfcc25893070ecb2
4
+ data.tar.gz: 4e585f49bf52c067685f0722fd092dc1645dba7c82452cba16c31098c38a49a9
5
+ SHA512:
6
+ metadata.gz: 2855141d2c6ef01940fe32adbc2fffdd93121f23ac5930b4d8712f392f35189491ad9787867c15e2cfb63a35eb2eca081d9640a2479733d7f8193ec2f015b1ed
7
+ data.tar.gz: fcc4bdaa4ec128b3e18e10614eadc9ce7bdde3beade4daa9a95ebeaddf896c65525baa5f9ab6d4f0ae1d97c76892d93759585beabb8a29f002b3ed465f5cbc08
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Lucian Ghinda
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,200 @@
1
+ # PStore Logger
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/pstore_logger.svg)](https://badge.fury.io/rb/pstore_logger)
4
+ [![Ruby](https://img.shields.io/badge/ruby-%3E%3D3.4.4-ruby.svg)](https://www.ruby-lang.org/en/)
5
+
6
+ A simple Ruby gem for logging data (webhooks, API responses, etc.) to organized PStore files with automatic timestamping and conflict resolution.
7
+
8
+ ## Features
9
+
10
+ - ๐Ÿš€ **Simple API**: Clean, intuitive interface for saving and loading data
11
+ - ๐Ÿ“ **Organized Storage**: Automatic directory creation with tag-based organization
12
+ - โฐ **Automatic Timestamping**: YYYY-MM-DD-HH-MM-SS filename format
13
+ - ๐Ÿ”„ **Collision Handling**: Automatic conflict resolution with numbered suffixes
14
+ - ๐Ÿ’พ **Flexible Data**: Store any Ruby object that can be serialized by PStore
15
+ - ๐Ÿท๏ธ **Tagging System**: Organize logs by category/type using tags
16
+ - ๐Ÿ“Š **Last Entry Retrieval**: Easy access to the most recent log entry
17
+ - ๐Ÿงน **No dependencies**: This gem has no external dependencies.
18
+
19
+ ## Installation
20
+
21
+ Add this line to your application's Gemfile:
22
+
23
+ ```ruby
24
+ gem 'pstore_logger'
25
+ ```
26
+
27
+ And then execute:
28
+
29
+ ```bash
30
+ $ bundle install
31
+ ```
32
+
33
+ Or install it yourself as:
34
+
35
+ ```bash
36
+ $ gem install pstore_logger
37
+ ```
38
+
39
+ ## Usage
40
+
41
+ ### Basic Setup
42
+
43
+ ```ruby
44
+ require 'pstore/logger'
45
+
46
+ # Initialize with a storage path and tag
47
+ logger = PStoreLogger.new(storage_path: '/path/to/logs', tag: 'webhooks')
48
+ ```
49
+
50
+ ### Saving Data
51
+
52
+ #### With Automatic Timestamp
53
+
54
+ ```ruby
55
+ # Saves to: /path/to/logs/webhooks/2025-06-19-14-30-25.pstore
56
+ webhook_data = { event: 'user.created', user_id: 123, email: 'user@example.com' }
57
+ logger.save(webhook_data)
58
+ ```
59
+
60
+ #### With Custom File ID
61
+
62
+ ```ruby
63
+ # Saves to: /path/to/logs/webhooks/user_123.pstore
64
+ logger.save(webhook_data, file_id: 'user_123')
65
+
66
+ # If file exists, creates: user_123_1.pstore, user_123_2.pstore, etc.
67
+ logger.save(more_data, file_id: 'user_123')
68
+ ```
69
+
70
+ ### Loading Data
71
+
72
+ ```ruby
73
+ # Load the most recent entry
74
+ latest_webhook = logger.load_last
75
+ puts latest_webhook # => { event: 'user.created', user_id: 123, ... }
76
+ ```
77
+
78
+ ## Real-World Examples
79
+
80
+ ### Webhook Logger
81
+
82
+ ```ruby
83
+ require 'pstore/logger'
84
+
85
+ class WebhookHandler
86
+ def initialize
87
+ @logger = PStoreLogger.new(
88
+ storage_path: './logs/webhooks',
89
+ tag: 'stripe'
90
+ )
91
+ end
92
+
93
+ def handle_stripe_webhook(payload)
94
+ @logger.save(payload, file_id: payload[:id])
95
+
96
+ # Process the webhook
97
+ process_payment(payload)
98
+ end
99
+
100
+ def debug_last_webhook
101
+ @logger.load_last
102
+ end
103
+ end
104
+ ```
105
+
106
+ ### API Response Caching
107
+
108
+ ```ruby
109
+ require 'pstore/logger'
110
+
111
+ class ApiClient
112
+ def initialize
113
+ @cache = PStoreLogger.new(
114
+ storage_path: './cache/api_responses',
115
+ tag: 'github'
116
+ )
117
+ end
118
+
119
+ def fetch_user(username)
120
+ response = api_call("/users/#{username}")
121
+
122
+ @cache.save(response, file_id: username)
123
+
124
+ response
125
+ end
126
+ end
127
+ ```
128
+
129
+ ### Development Testing
130
+
131
+ ```ruby
132
+ require 'pstore/logger'
133
+
134
+ # Save test data during development
135
+ test_logger = PStoreLogger.new(storage_path: './tmp/test_data', tag: 'fixtures')
136
+
137
+ # Save complex test objects
138
+ user_data = { id: 1, name: 'Test User', preferences: { theme: 'dark' } }
139
+ test_logger.save(user_data, file_id: 'test_user')
140
+
141
+ # Later, load the test data
142
+ test_user = test_logger.load_last
143
+ ```
144
+
145
+ ## Data Structure
146
+
147
+ Each PStore file contains:
148
+
149
+ ```ruby
150
+ {
151
+ data: your_saved_object, # Your original data
152
+ timestamp: Time.now # When it was saved
153
+ }
154
+ ```
155
+
156
+ ## Use Cases
157
+
158
+ - **๐Ÿ”— Webhook Debugging**: Capture and inspect webhook payloads
159
+ - **๐Ÿ“ก API Response Logging**: Store API responses for offline analysis
160
+ - **๐Ÿ” Data Auditing**: Keep records of data changes over time
161
+ - **๐Ÿงช Development Testing**: Persist test data between runs
162
+ - **๐Ÿ“Š Data Analysis**: Collect data samples for analysis
163
+ - **๐Ÿšจ Error Investigation**: Log problematic data for debugging
164
+
165
+ ## Requirements
166
+
167
+ - Ruby >= 3.4.4
168
+ - No additional dependencies (uses built-in PStore)
169
+
170
+ ## Development
171
+
172
+ After checking out the repo, run:
173
+
174
+ ```bash
175
+ bundle install
176
+ ```
177
+
178
+ To run the tests:
179
+
180
+ ```bash
181
+ bundle exec ruby -Ilib:test test/test_pstore_logger.rb
182
+ ```
183
+
184
+ To run linting:
185
+
186
+ ```bash
187
+ bundle exec rubocop
188
+ ```
189
+
190
+ ## Contributing
191
+
192
+ Bug reports and pull requests are welcome on GitHub at https://github.com/lucianghinda/pstore_logger.
193
+
194
+ ## License
195
+
196
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
197
+
198
+ ## Changelog
199
+
200
+ See [CHANGELOG.md](CHANGELOG.md) for version history and changes.
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pstore'
4
+ require 'fileutils'
5
+
6
+ class PStoreLogger
7
+ FILENAME_TIMESTAMP_FORMAT = '%Y-%m-%d-%H-%M-%S'
8
+
9
+ def initialize(storage_path:, tag:)
10
+ @storage_path = storage_path
11
+ @tag = tag.downcase
12
+ @folder_path = File.join(@storage_path, @tag)
13
+ end
14
+
15
+ def save(data, file_id: nil)
16
+ filepath = file_path(file_id)
17
+ store = PStore.new(filepath)
18
+
19
+ store.transaction do
20
+ store[:data] = data
21
+ store[:timestamp] = Time.now
22
+ end
23
+
24
+ filepath
25
+ end
26
+
27
+ def load_last
28
+ return nil unless Dir.exist?(folder_path)
29
+
30
+ files = Dir.glob(File.join(folder_path, '*.pstore'))
31
+ return nil if files.empty?
32
+
33
+ latest_file = files.max_by { |file| File.mtime(file) }
34
+
35
+ store = PStore.new(latest_file)
36
+ store.transaction(true) do
37
+ store[:data]
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ attr_reader :folder_path
44
+
45
+ def file_path(file_id)
46
+ FileUtils.mkdir_p(folder_path)
47
+ filename = generate_filename(file_id)
48
+
49
+ File.join(folder_path, filename)
50
+ end
51
+
52
+ def generate_filename(file_id)
53
+ base_name = file_id.nil? ? Time.now.strftime(FILENAME_TIMESTAMP_FORMAT) : file_id.to_s
54
+
55
+ ensure_unique_filename(base_name)
56
+ end
57
+
58
+ def ensure_unique_filename(base_name)
59
+ base_filename = "#{base_name}.pstore"
60
+ filepath = File.join(folder_path, base_filename)
61
+
62
+ return base_filename unless File.exist?(filepath)
63
+
64
+ counter = 1
65
+ loop do
66
+ new_filename = "#{base_name}_#{counter}.pstore"
67
+ new_filepath = File.join(folder_path, new_filename)
68
+ break new_filename unless File.exist?(new_filepath)
69
+
70
+ counter += 1
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PStore
4
+ VERSION = '0.1.0'
5
+ end
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pstore_logger
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Lucian
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: The PStore Logger provides a simple way to log webhooksor API responses
13
+ to a file for further inspection using Ruby's PStore.
14
+ email:
15
+ - lucian@shortruby.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - LICENSE
21
+ - README.md
22
+ - lib/pstore/logger.rb
23
+ - lib/pstore/version.rb
24
+ licenses:
25
+ - MIT
26
+ metadata:
27
+ rubygems_mfa_required: 'true'
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: 3.4.4
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubygems_version: 3.6.9
43
+ specification_version: 4
44
+ summary: A simple logging gem using PStore to store data
45
+ test_files: []