iron_trail 0.0.6 → 0.1.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 +4 -4
- data/lib/iron_trail/db_functions.rb +21 -0
- data/lib/iron_trail/irontrail_log_row_function.sql +21 -7
- data/lib/iron_trail/version.rb +1 -1
- data/lib/iron_trail.rb +0 -11
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0eaa9c2070ae46d7386af196b943c47c495fba0485bc1b1956691e182ad099e
|
4
|
+
data.tar.gz: 732e39b8d5edba42b54a0f6bc67f6389d89fe1d037930c10dc4dff72a1afeb18
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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,
|
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,
|
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,
|
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(),
|
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;
|
data/lib/iron_trail/version.rb
CHANGED
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.
|
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-
|
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
|