iron_trail 0.0.6 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 34fb140276f60147f1c5d4beb71a3ba39a8f2c552a76e3b3c7e749e94ec518a2
4
- data.tar.gz: 4e7700b3f5c53090a623e1be9ed5b0e6a513869450176c58bdc8fdd1352decf1
3
+ metadata.gz: e0eaa9c2070ae46d7386af196b943c47c495fba0485bc1b1956691e182ad099e
4
+ data.tar.gz: 732e39b8d5edba42b54a0f6bc67f6389d89fe1d037930c10dc4dff72a1afeb18
5
5
  SHA512:
6
- metadata.gz: 0faa78641a209ccc88bed839b8988e1cc250465e6621e08158e38f1c68c0a4be421ab7f5346cbed7b6a25a658eeca9a51d015a1b23572ee2e91eab6aa04e29ce
7
- data.tar.gz: 563248c156fb4716cb0befa64cfcd7a81f8b98594db3008853ccc2625e5e4b2e9a2948de12dbced48d018c3e1a915536baeef65d606deb973bcc0c0afe7853e3
6
+ metadata.gz: 21577368bee6f5560d27488a4bfbc3cd064bdca3869a8538002838e10f64bcaf6c20f7ec2a0a1ce56d5690b9959adbe780e6b4d7b41e59af1a78f281f1ef413a
7
+ data.tar.gz: 7e6b3c94d40059c22aa929efb07f93fdcef8abc1ffc6ef63dfe10c7d862c31d39880cc1175ad953231675bb2dd644e23d7a0b2ba1e426544af330309c77e26bb
@@ -56,11 +56,32 @@ module IronTrail
56
56
  connection.execute(query)
57
57
  end
58
58
 
59
+ # Counting rows in Postgres is known to be a slow operation for large tables.
60
+ # Because of this, avoid using this for monitoring new errors. Instead,
61
+ # use the trigger_errors_metrics method.
59
62
  def trigger_errors_count
60
63
  stmt = 'SELECT COUNT(*) AS c FROM "irontrail_trigger_errors"'
61
64
  connection.execute(stmt).first['c']
62
65
  end
63
66
 
67
+ # This returns metrics intended to be used for monitoring. One can send
68
+ # these values to something like a Prometheus deployment and add monitoring
69
+ # on top of it.
70
+ # It should be much faster to run than trigger_errors_count.
71
+ #
72
+ # If the irontrail_trigger_errors table is empty, the resulting values
73
+ # will all be zero and never nil. This is so that data in a monitoring setup
74
+ # can tell apart a failure from a no-data scenario.
75
+ def trigger_errors_metrics
76
+ stmt = 'SELECT MAX(created_at) maxdate, MAX(id) AS maxid FROM "irontrail_trigger_errors"'
77
+ res = connection.execute(stmt).first
78
+
79
+ {
80
+ max_created_at: (res && res['maxdate'] && res['maxdate'].to_i) || 0,
81
+ max_id: (res && res['maxid']) || 0,
82
+ }
83
+ end
84
+
64
85
  def collect_all_tables(schema: 'public')
65
86
  # query pg_class rather than information schema because this way
66
87
  # we can get only regular tables and ignore partitions.
@@ -11,10 +11,12 @@ DECLARE
11
11
  new_obj JSONB;
12
12
  actor_type TEXT;
13
13
  actor_id TEXT;
14
+ created_at TIMESTAMP;
14
15
 
15
16
  err_text TEXT; err_detail TEXT; err_hint TEXT; err_ctx TEXT;
16
17
  BEGIN
17
18
  SELECT split_part(split_part(current_query(), '/*IronTrail ', 2), ' IronTrail*/', 1) INTO it_meta;
19
+
18
20
  IF (it_meta <> '') THEN
19
21
  it_meta_obj = it_meta::JSONB;
20
22
 
@@ -28,17 +30,30 @@ BEGIN
28
30
  END IF;
29
31
  END IF;
30
32
 
33
+ old_obj = row_to_json(OLD);
34
+ new_obj = row_to_json(NEW);
35
+
36
+ IF (TG_OP = 'INSERT' AND new_obj ? 'created_at') THEN
37
+ created_at = NEW.created_at;
38
+ ELSIF (TG_OP = 'UPDATE' AND new_obj ? 'updated_at') THEN
39
+ created_at = NEW.updated_at;
40
+ END IF;
41
+
42
+ IF (created_at IS NULL) THEN
43
+ created_at = STATEMENT_TIMESTAMP();
44
+ ELSE
45
+ it_meta_obj = jsonb_set(COALESCE(it_meta_obj, '{}'::jsonb), array['_db_created_at'], TO_JSONB(STATEMENT_TIMESTAMP()));
46
+ END IF;
47
+
31
48
  IF (TG_OP = 'INSERT') THEN
32
49
  INSERT INTO "irontrail_changes" ("actor_id", "actor_type",
33
50
  "rec_table", "operation", "rec_id", "rec_new", "metadata", "created_at")
34
51
  VALUES (actor_id, actor_type,
35
- TG_TABLE_NAME, 'i', NEW.id, row_to_json(NEW), it_meta_obj, NOW());
52
+ TG_TABLE_NAME, 'i', NEW.id, new_obj, it_meta_obj, created_at);
36
53
 
37
54
  ELSIF (TG_OP = 'UPDATE') THEN
38
55
  IF (OLD <> NEW) THEN
39
56
  u_changes = jsonb_build_object();
40
- old_obj = row_to_json(OLD);
41
- new_obj = row_to_json(NEW);
42
57
 
43
58
  FOR key IN (SELECT jsonb_object_keys(old_obj) UNION SELECT jsonb_object_keys(new_obj))
44
59
  LOOP
@@ -51,14 +66,13 @@ BEGIN
51
66
 
52
67
  INSERT INTO "irontrail_changes" ("actor_id", "actor_type", "rec_table", "operation",
53
68
  "rec_id", "rec_old", "rec_new", "rec_delta", "metadata", "created_at")
54
- VALUES (actor_id, actor_type, TG_TABLE_NAME, 'u', NEW.id, row_to_json(OLD), row_to_json(NEW),
55
- u_changes, it_meta_obj, NOW());
69
+ VALUES (actor_id, actor_type, TG_TABLE_NAME, 'u', NEW.id, old_obj, new_obj, u_changes, it_meta_obj, created_at);
56
70
 
57
71
  END IF;
58
72
  ELSIF (TG_OP = 'DELETE') THEN
59
73
  INSERT INTO "irontrail_changes" ("actor_id", "actor_type", "rec_table", "operation",
60
74
  "rec_id", "rec_old", "metadata", "created_at")
61
- VALUES (actor_id, actor_type, TG_TABLE_NAME, 'd', OLD.id, row_to_json(OLD), it_meta_obj, NOW());
75
+ VALUES (actor_id, actor_type, TG_TABLE_NAME, 'd', OLD.id, old_obj, it_meta_obj, created_at);
62
76
 
63
77
  END IF;
64
78
  RETURN NULL;
@@ -74,7 +88,7 @@ EXCEPTION
74
88
  "err_text", "ex_detail", "ex_hint", "ex_ctx", "op", "table_name",
75
89
  "old_data", "new_data", "query", "created_at")
76
90
  VALUES (SQLSTATE, SQLERRM, err_text, err_detail, err_hint, err_ctx,
77
- TG_OP, TG_TABLE_NAME, row_to_json(OLD), row_to_json(NEW), current_query(), NOW());
91
+ TG_OP, TG_TABLE_NAME, row_to_json(OLD), row_to_json(NEW), current_query(), STATEMENT_TIMESTAMP());
78
92
  RETURN NULL;
79
93
  END;
80
94
  $$ LANGUAGE plpgsql;
@@ -1,5 +1,5 @@
1
1
  # frozen_literal_string: true
2
2
 
3
3
  module IronTrail
4
- VERSION = '0.0.6'
4
+ VERSION = '0.1.1'
5
5
  end
data/lib/iron_trail.rb CHANGED
@@ -52,17 +52,6 @@ module IronTrail
52
52
  config.enable
53
53
  end
54
54
 
55
- # def test_mode!
56
- # if [ENV['RAILS_ENV'], ENV['RACK_ENV']].include?('production')
57
- # raise "IronTrail test mode cannot be enabled in production!"
58
- # end
59
- # @test_mode = true
60
- # end
61
- #
62
- # def test_mode?
63
- # @test_mode
64
- # end
65
-
66
55
  def ignore_table?(name)
67
56
  (OWN_TABLES + (config.ignored_tables || [])).include?(name)
68
57
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iron_trail
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - André Diego Piske
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-01-22 00:00:00.000000000 Z
10
+ date: 2025-02-04 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rails
@@ -153,7 +153,13 @@ files:
153
153
  homepage: https://github.com/trusted/iron_trail
154
154
  licenses:
155
155
  - MIT
156
- metadata: {}
156
+ metadata:
157
+ bug_tracker_uri: https://github.com/trusted/iron_trail/issues
158
+ changelog_uri: https://github.com/trusted/iron_trail/blob/main/CHANGELOG.md
159
+ documentation_uri: https://github.com/trusted/iron_trail/blob/main/README.md
160
+ homepage_uri: https://github.com/trusted/iron_trail
161
+ source_code_uri: https://github.com/trusted/iron_trail
162
+ wiki_uri: https://github.com/trusted/iron_trail/wiki
157
163
  rdoc_options: []
158
164
  require_paths:
159
165
  - lib